80186 programming for the Wonderswan and Wonderswan Color

The Wonderswan was never released outside of Japan, released in 1999, it was released to compete with the Gameboy Color and NeoGeo...

It was upgraded just one year later with an upgraded color model, there was also a Wonderswan Crystal, however this was technically the same as the Wonderswan Color, just with a better screen...

Despite being a commercial failure, the Wonderswan was a powerful system, and impressively, it's V30MZ CPU is x86 compatible! (80186)... this means we can write games and programs for it with UASM!




Specs:

Wonderswan Wonderswan color
Cpu 3.072mhz 186 compatible 3.072mhz 186 compatible
Ram 16k 64k
Resolution 224x144 (28x18 tiles) 224x144 (28x18 tiles)
Colors 16 Greyscale 4096  (256 onscreen)
Tile Layers 2 tilemaps (32x32) 2bpp planar
2 tilemaps (32x32) 4bpp / 2bpp... planar / linear
Sprites 128 (8x8 px 32 per line) 2bpp planar 128 (8x8 px 32 per line) 4bpp/2bpp... planar / linear
Sound 4 x 4 bit PCM 4 x 4 bit PCM


WonderSwan, Wonderswan Color, Womderswan Crystal


If you want to learn 8086 get the Cheatsheet! it has all the 8086 commands, It will help you get started with ASM programming, and let you quickly look up commands when you get confused!


Resources
WSMAN - The only real documentation on the wonderswan out there

ChibiAkumas Tutorials

8086 Hello World Series

Lesson H2 - Hello World on the WonderSwan / Wonderswan Color

8086 Simple Samples

Lesson S2 - Sprite drawing and Simple key movement on the Wonderswan

8086 Platform Specific Lessons

Lesson P4 - Bitmap graphics on the Wonderswan / Wonderswan Color [WSW]
Lesson P10 - Bitmap graphics on the Wonderswan / Wonderswan Color [WSW]
Lesson P11 - Sound on the Wonderswan

8086 SuckHunt Series

Lesson SuckShoot1 - Suck Shoot on the 8086 [DOS]
Lesson SuckShoot2 - Suck Shoot on the Wonderswan 1/2 - Sprites!
Lesson SuckShoot3 - Suck Shoot on the Wonderswan 2/2!

Memory Map

Address Size Purpose Bits Details
$00000
IVT Interrupt Table

$00100
Wonderwan RAM

$00E00 $200 Sprite settings XXXXXXXX YYYYYYYY VHPWpppn nnnnnnnn N=tile Number V=Vflip H=Hflip P=Priority W=Window p=Palette(8+) Y=(-8 to 144) X=(-8 to 224)
$01000 $800 Tilemap 1 (SCR1) VHBPPPPT TTTTTTT Tile / Palette / wsc Bank / Hflip / Vflip
$01800 $800 Tilemap 2 (SCR2) VHBPPPPT TTTTTTT Tile / Palette / wsc Bank / Hflip / Vflip
$02000 $2000 2bpp tiles / Sprites

$04000 $4000/2000 4bpp Sprites / WSC extra 2bpp tiles)

$08000 $4000 4bpp tiles

$0FE00 $100 Palettes 0-7 -RGB
$0FF00 $100 Palettes 8-15 -RGB
$10000 $10000 Cartridge SRAM

$20000
ROM 0

$30000
ROM 1

$40000
ROM 2

Note: Address of Tilemap 1,2 set by port 07h (value for these settings 32h) and Sprites set by port 04h (value for these settings 07h)

Ports

Port    
RW  
Purpose Bits Details
000h RW REG_DISP_CTRL --EMWS21 1=Scr 1 2=Scr2 S=Sprite on / W=SprWin on / M=Scr2 Win Mode / E=Scr2 Win Enable
001h RW REG_BACK_COLOR CCCCCCCC
C=Color
002h R REG_LINE_CUR YYYYYYYY Y=Current Y line being drawn
003h RW REG_LINE_CMP YYYYYYYY Interrupt Ypos
004h RW REG_SPR_BASE --AAAAAA A=Sprite Address>>9 (04h=0E00h)
005h RW REG_SPR_FIRST SSSSSSSS First Sprite to show (128 total)
006h RW REG_SPR_COUNT SSSSSSSS Sprite Count to show (128 total)
007h RW REG_MAP_BASE 22221111 Tilemap Bases>>11 (32h= 1000h / 1800h)
008h RW REG_SCR2_WIN_X0 XXXXXXXX Window - Min X
009h RW REG_SCR2_WIN_Y0 YYYYYYYY Window - Min Y
00Ah RW REG_SCR2_WIN_X1 XXXXXXXX Window - Max X
00Bh RW REG_SCR2_WIN_Y1 YYYYYYYY Window - Max Y
00Ch RW REG_SPR_WIN_X0 XXXXXXXX Sprite Window - Min X
00Dh RW REG_SPR_WIN_Y0 YYYYYYYY Sprite Window - Min Y
00Eh RW REG_SPR_WIN_X1 XXXXXXXX Sprite Window - Max X
00Fh RW REG_SPR_WIN_Y1 YYYYYYYY Sprite Window - Max Y
010h RW REG_SCR1_X XXXXXXXX
011h RW REG_SCR1_Y YYYYYYYY
012h RW REG_SCR2_X XXXXXXXX
013h RW REG_SCR2_Y YYYYYYYY
014h RW REG_LCD_CTRL -------C
1=WSC High Contrast
015h RW REG_LCD_ICON DDDDDDDD

016h RW REG_LCD_VTOTAL DDDDDDDD
017h RW REG_LCD_VSYNC DDDDDDDD
01Ch RW REG_PALMONO_POOL_0 11110000
01Dh RW REG_PALMONO_POOL_1 33332222
01Eh RW REG_PALMONO_POOL_2 55554444
01Fh RW REG_PALMONO_POOL_3 77776666
020h RW REG_PALMONO_0 L 11110000 Tilemap Palette 0
021h RW REG_PALMONO_0 H 33332222
022h RW REG_PALMONO_1 L 11110000 Tilemap Palette 1
023h RW REG_PALMONO_1 H 33332222
024h RW REG_PALMONO_2 L 11110000 Tilemap Palette 2
025h RW REG_PALMONO_2 H 33332222
026h RW REG_PALMONO_3 L 11110000 Tilemap Palette 3
027h RW REG_PALMONO_3 H 33332222
028h RW REG_PALMONO_4 L 11110000 Tilemap Palette 4 (Color 0 Transp on Mono System)
029h RW REG_PALMONO_4 H 33332222
02Ah RW REG_PALMONO_5 L 11110000 Tilemap Palette 5 (Color 0 Transp on Mono System)
02Bh RW REG_PALMONO_5 H 33332222
02Ch RW REG_PALMONO_6 L 11110000 Tilemap Palette 6 (Color 0 Transp on Mono System)
02Dh RW REG_PALMONO_6 H 33332222
02Eh RW REG_PALMONO_7 L 11110000 Tilemap Palette 7 (Color 0 Transp on Mono System)
02Fh RW REG_PALMONO_7 H 33332222
030h RW REG_PALMONO_8 L 11110000 Sprite Palette 1
031h RW REG_PALMONO_8 H 33332222
032h RW REG_PALMONO_9 L 11110000 Sprite Palette 2
033h RW REG_PALMONO_9 H 33332222
034h RW REG_PALMONO_A L 11110000 Sprite Palette 3
035h RW REG_PALMONO_A H 33332222
036h RW REG_PALMONO_B L 11110000 Sprite Palette 4
037h RW REG_PALMONO_B H 33332222
038h RW REG_PALMONO_C L 11110000 Sprite Palette 5 (Color 0 Transp on Mono System)
039h RW REG_PALMONO_C H 33332222
03Ah RW REG_PALMONO_D L 11110000 Sprite Palette 6 (Color 0 Transp on Mono System)
03Bh RW REG_PALMONO_D H 33332222
03Ch RW REG_PALMONO_E L 11110000 Sprite Palette 7 (Color 0 Transp on Mono System)
03Dh RW REG_PALMONO_E H 33332222
03Eh RW REG_PALMONO_F L 11110000 Sprite Palette 8 (Color 0 Transp on Mono System)
03Fh RW REG_PALMONO_F H 33332222

Sprites

Sprites are controlled by a set of registers, and 4 bytes per entry in the table at address defined by port 04h. There are 128 in total.

Each sprite uses 4 bytes in the format: %XXXXXXXXYYYYYYYYVHPWpppnnnnnnnnn    N=tile Number V=Vflip H=Hflip P=Priority W=Window p=Palette(8+) Y=(-8 to 144) X=(-8 to 224)

The window can be enabled or disabled by port 00h, and how the window affects the sprites is defined by bit 12 of the sprite definitions in ram.

If we set the base of the tile ram to 0E00h, the memory addresses that define each sprite will be as shown below.

Sprite palette uses palettes 8+... on mono systems color 0 is not transparent for palette 8-11, and transparent for 12-15.

Address Sprite Bits Details
0E00 0 NNNNNNNN N=tile Number
0E01 0 VHPWpppN N=tile Number V=Vflip H=Hflip P=Priority W=Window (0=in 1=out) p=Palette(8+)
0E02 0 YYYYYYYY Y=(-8 to 144)
0E03 0 XXXXXXXX X=(-8 to 224)
0E04 1 NNNNNNNN N=tile Number
0E05 1 VHPWpppN N=tile Number V=Vflip H=Hflip P=Priority W=Window (0=in 1=out) p=Palette(8+)
0E06 1 YYYYYYYY Y=(-8 to 144)
0E07 1 XXXXXXXX X=(-8 to 224)
0E08 2 NNNNNNNN N=tile Number
0E09 2 VHPWpppN N=tile Number V=Vflip H=Hflip P=Priority W=Window (0=in 1=out) p=Palette(8+)
0E0A 2 YYYYYYYY Y=(-8 to 144)
0E0B 2 XXXXXXXX X=(-8 to 224)
0FFC 127 NNNNNNNN N=tile Number
0FFD 127 VHPWpppN N=tile Number V=Vflip H=Hflip P=Priority W=Window (0=in 1=out) p=Palette(8+)
0FFE 127 YYYYYYYY Y=(-8 to 144)
0FFF 127 XXXXXXXX X=(-8 to 224)

Sound Ports

The sound processor uses wave samples at the address defined by port 08Fh. Each channel uses 16 bytes (32 4 bit samples) If we define the base as being 0D00h (by writing 34h to port 08Fh) the following addresses will define the samples used by the sound processor:
Channel Address
1 0D00h
2 0D10h
3 0D20h
4 0D30h

Port Direction Function Bits Details
080h RW REG_SND_CH1_PITCH L LLLLLLLL Pitch (Higher number=Higher pitch)
081h RW REG_SND_CH1_PITCH H -----HHH
082h RW REG_SND_CH2_PITCH L LLLLLLLL Pitch (Higher number=Higher pitch)
083h RW REG_SND_CH2_PITCH H -----HHH
084h RW REG_SND_CH3_PITCH L LLLLLLLL Pitch (Higher number=Higher pitch)
085h RW REG_SND_CH3_PITCH H -----HHH
086h RW REG_SND_CH4_PITCH L LLLLLLLL Pitch (Higher number=Higher pitch)
087h RW REG_SND_CH4_PITCH H -----HHH
088h RW REG_SND_CH1_VOL LLLLRRRR L=Left R=Right (15=loud)
089h RW REG_SND_CH2_VOL LLLLRRRR L=Left R=Right (15=loud)
08Ah RW REG_SND_CH3_VOL LLLLRRRR L=Left R=Right (15=loud)
08Bh RW REG_SND_CH4_VOL LLLLRRRR L=Left R=Right (15=loud)
08Ch RW REG_SND_SWEEP_VALUE SSSSSSSS
08Dh RW REG_SND_SWEEP_TIME ---TTTTT
08Eh RW REG_SND_NOISE ---ERMMM E=Enable / R=Reset / M=Mode
08Fh RW REG_SND_WAVE_BASE AAAAAAAA Wave address >>6 (34h= 0D00h)
090h RW REG_SND_CTRL NSV-4321 N= ch4 Noise / S= ch3 Sweep / V= ch2 Voice / M=Channel Modes / 4321 - Channel enable
091h RW REG_SND_OUTPUT

092h R REG_SND_RANDOM L

093h R REG_SND_RANDOM H

094h RW REG_SND_VOICE_CTRL

095h RW REG_SND_HYPERVOICE

096h RW REG_SND_9697 L

097h RW REG_SND_9697 H

098h RW REG_SND_9899 L

099h RW REG_SND_9899 H

09Ah R REG_SND_9A

09Bh R REG_SND_9B

09Ch R REG_SND_9C

09Dh R REG_SND_9D

09Eh R REG_SND_9E