WonderSwan - Sacred Tech Scroll

Overview
Memory Map
I/O Map
Open Bus
Cartridge
ROM Header
Hardware Architecture
System Reset
About
Change Colors

System Components
CPU - V30MZ/V Series Microprocessor
DMA - Direct Memory Access
LCD Panel
Sound
Keypad
Serial EEPROM
RTC - Real-Time Clock


Memory Map

The WonderSwan memory bus is 20 bits wide and is organized by memory type:

0x00000 - 0x0FFFF WRAM
0x10000 - 0x1FFFF Cartridge SRAM
0x20000 - 0x2FFFF Cartridge ROM bank 0
0x30000 - 0x3FFFF Cartridge ROM bank 1
0x40000 - 0xFFFFF Cartridge ROM bank EX

Physical Addresses

Because the CPU registers are 16-bit and the bus is 20-bit, multiple registers are needed to represent a complete physical address. This is achieved through the use of the segment registers.

When constructing a physical address, one register is used normally as a 16-bit value called the offset. A second value called the segment is then produced by taking the value in the appropriate segment register and shifting it left 4 bits. This shifted segment value is then added to the offset to produce the final 20-bit physical address.

Physical addresses are a maximum of 20 bits wide. If the computation of a physical address exceeds 0xFFFFF, the value will wrap back around to 0x00000 and continue up from there.

Unaligned Accesses

If a 16-bit memory access is performed on an odd offset (the lowest bit is set), it is silently converted into two 8-bit accesses instead. In this situation, one additional CPU cycle is spent. The physical address is computed independently for each byte, with the offset being incremented for the second byte before incorporating the bits from the segment. For this reason, any 16-bit access with an offset of 0xFFFF will access two non-consecutive bytes in memory.

WRAM

WRAM is built-in, general-purpose working memory. The size of WRAM varies depending on whether or not color mode is enabled:

• Disabled16 KiB
• Enabled64 KiB

WRAM is further organized as follows:

0x00000 - 0x003FF Exception vectors
0x00400 - 0x01FFF Scratch memory
0x02000 - 0x03FFF Characters
0x04000 - 0x0BFFF [color] Characters
0x0C000 - 0x0FDFF [color] Scratch memory
0x0FE00 - 0x0FFFF [color] Color palettes

[color] These addresses are only available in color mode. When accessed on the monochrome model or on a color model with color mode disabled, they function as open bus.

Cartridge SRAM

Some cartridges contain save RAM (SRAM), which is volatile memory that is typically made persistent via a battery for use with games requiring save functionality. SRAM is partitioned into 64 KiB banks, one of which is mapped onto the memory bus at any given time in the SRAM address range 0x10000 - 0x1FFFF.

Memory mapping for SRAM is managed through the following I/O ports:

0xC1 Byte RAM_BANK RAM bank (shadow of lower byte)
0xD0 Byte RAM_BANK_L [2003] RAM bank (lower byte)
0xD1 Byte RAM_BANK_H [2003] RAM bank (upper byte)

[2003] These ports are only available on the 2003 mapper.

All 8 bits of RAM_BANK and RAM_BANK_L, and the lowest 2 bits of RAM_BANK_H, can be managed by the program. The upper 6 bits of RAM_BANK_H are clear when read.

On the 2001 mapper, the bank setting is 8-bit and is taken from RAM_BANK. On the 2003 mapper, RAM_BANK is a mirror of RAM_BANK_L, and the bank setting is 10-bit and is formed by the combination of RAM_BANK_H for the high bits and RAM_BANK_L for the low bits.

When accessing SRAM, the 20-bit physical address is transformed into a 32-bit offset into the cartridge memory. The lower 16 bits of the cartridge offset are taken from the lower 16 bits of the physical address. The upper 16 bits of the cartridge offset are taken from RAM_BANK or RAM_BANK_H and RAM_BANK_L as described above.

The implementation silently converts word accesses in the cartridge SRAM range into consecutive pairs of byte accesses, adding one additional CPU cycle in the process. The SRAM interface is 8-bit, so it cannot be used with the DMA feature.

During system reset, these ports are initialized with 0xFF. After mirroring, this corresponds to the last bank of SRAM data.

Cartridge ROM

Read-only memory (ROM) is non-volatile cartridge memory that serves as the source for data assets and program code. ROM is partitioned into 64 KiB banks, up to 14 of which are mapped onto the memory bus at any given time in the ROM address ranges 0x20000 - 0xFFFF.

Memory mapping for the 0x20000 - 0x2FFFF and 0x30000 - 0x3FFFF address ranges is managed through the following I/O ports:

0xC2 Byte ROM_BANK_0 ROM bank #0 (shadow of lower byte)
0xC3 Byte ROM_BANK_1 ROM bank #1 (shadow of lower byte)
0xD2 Byte ROM_BANK_0_L [2003] ROM bank #0 (lower byte)
0xD3 Byte ROM_BANK_0_H [2003] ROM bank #0 (upper byte)
0xD4 Byte ROM_BANK_1_L [2003] ROM bank #1 (lower byte)
0xD5 Byte ROM_BANK_1_H [2003] ROM bank #1 (upper byte)

[2003] These ports are only available on the 2003 mapper.

All 8 bits of all six ports can be managed by the program. The "_0" ports control which ROM bank is mapped to the 0x20000 - 0x2FFFF address range and the "_1" ports control which ROM bank is mapped to the 0x30000 - 0x3FFFF address range.

On the 2001 mapper, the bank setting is 8-bit and is taken from ROM_BANK_0 or ROM_BANK_1. On the 2003 mapper, ROM_BANK_0 and ROM_BANK_1 are mirrors of ROM_BANK_0_L and ROM_BANK_1_L respectively, and the bank setting is 16-bit and is formed by the combination of the appropriate "_H" port for the high bits and the "_L" port for the low bits.

When accessing ROM in these ranges, the 20-bit physical address is transformed into a 32-bit offset into the cartridge memory. The lower 16 bits of the cartridge offset are taken from the lower 16 bits of the physical address. The upper 16 bits of the cartridge offset are taken from the corresponding "ROM_BANK_" or "_H" and "_L" ports as described above.

During system reset, these ports are initialized with 0xFF. After mirroring, this corresponds to the last bank of ROM data.

Memory mapping for the 0x40000 - 0xFFFFF address range is managed through the following port:

0xC0 Byte LINEAR_ADDR_OFF Linear address offset
7 0
Bank
8
Bank R/W The high-order bits of the active bank indexes.

All 20 bits of the physical address contribute to the memory offset into cartridge ROM for this address range. Additional offset bits beginning with bit 20 are taken from LINEAR_ADDR_OFF for a total of 28 bits.

During system reset, this port is initialized with 0xFF. After mirroring, this corresponds to the last 12 banks of ROM data.


I/O Map

The WonderSwan I/O bus is 8 bits wide. The program accesses it through the IN and OUT instructions.

Unaligned Accesses

If a 16-bit port access is performed on an odd address (the lowest bit is set), it is silently converted into two 8-bit accesses instead. In this situation, one additional CPU cycle is spent.

Ports

The following I/O ports are available:

0x00 Word DISPLAY_CTRL Display control
0x02 Byte LCD_LINE Drawing line position
0x03 Byte LCD_INTERRUPT Drawing line interrupt
0x04 Byte SPR_AREA SPR character definition area specification
0x05 Byte SPR_START_NO SPR drawing first character number
0x06 Byte SPR_CNT Number of SPR characters
0x07 Byte SCR_AREA SCR character definition area specification
0x08 Byte SCR2_WIN_X1 SCR2 Window upper left (X axis)
0x09 Byte SCR2_WIN_Y1 SCR2 Window upper left (Y axis)
0x0A Byte SCR2_WIN_X2 SCR2 lower right of window (X axis)
0x0B Byte SCR2_WIN_Y2 SCR2 lower right of window (Y axis)
0x0C Byte SPR_WIN_X1 SPR window upper left (X axis)
0x0D Byte SPR_WIN_Y1 SPR window upper left (Y axis)
0x0E Byte SPR_WIN_X2 SPR window bottom right (X axis)
0x0F Byte SPR_WIN_Y2 SPR window bottom right (Y axis)
0x10 Byte SCR1_SCRL_X SCR1 scroll (X axis)
0x11 Byte SCR1_SCRL_Y SCR1 scroll (Y axis)
0x12 Byte SCR2_SCRL_X SCR2 scroll (X axis)
0x13 Byte SCR2_SCRL_Y SCR2 scroll (Y axis)
0x14 Byte LCD_IF_CTRL LCD interface control
0x15 Byte LCD_SEG_DATA Segment display data
0x16 Byte LCD_VTOTAL [note] LCD total line count
0x17 Byte LCD_VSYNC [note] LCD back porch line count
0x1A Byte LCD_VOLUME [note] LCD volume status
0x1C Byte LCD_GRAY_01 LCD LUT #0/#1
0x1D Byte LCD_GRAY_23 LCD LUT #2/#3
0x1E Byte LCD_GRAY_45 LCD LUT #4/#5
0x1F Byte LCD_GRAY_67 LCD LUT #6/#7
0x20 Word SCR_LUT_0 SCR character LUT #0
0x22 Word SCR_LUT_1 SCR character LUT #1
0x24 Word SCR_LUT_2 SCR character LUT #2
0x26 Word SCR_LUT_3 SCR character LUT #3
0x28 Word SCR_LUT_4 SCR character LUT #4
0x2A Word SCR_LUT_5 SCR character LUT #5
0x2C Word SCR_LUT_6 SCR character LUT #6
0x2E Word SCR_LUT_7 SCR character LUT #7
0x30 Word SPR_LUT_0 SPR character LUT #0
0x32 Word SPR_LUT_1 SPR character LUT #1
0x34 Word SPR_LUT_2 SPR character LUT #2
0x36 Word SPR_LUT_3 SPR character LUT #3
0x38 Word SPR_LUT_4 SPR character LUT #4
0x3A Word SPR_LUT_5 SPR character LUT #5
0x3C Word SPR_LUT_6 SPR character LUT #6
0x3E Word SPR_LUT_7 SPR character LUT #7
0x40 Word GDMA_SOURCE_L [color] General-purpose DMA source address (lower 16 bits)
0x42 Word GDMA_SOURCE_H [color] General-purpose DMA source address (upper 4 bits)
0x44 Word GDMA_DESTINATION [color] General-purpose DMA destination address
0x46 Word GDMA_COUNTER [color] General-purpose DMA data transfer amount
0x48 Byte GDMA_CTRL [color] General purpose DMA control
0x4A Word SDMA_SOURCE_L [color] Sound DMA source address (lower 16 bits)
0x4C Word SDMA_SOURCE_H [color] Sound DMA source address (upper 4 bits)
0x4E Word SDMA_COUNTER_L [color] Sound DMA data transfer amount (lower 16 bits)
0x50 Word SDMA_COUNTER_H [color] Sound DMA data transfer amount (upper 4 bits)
0x52 Byte SDMA_CTRL [color] Sound DMA control
0x60 Byte SYSTEM_CTRL2 [color] System control 2
0x62 Byte SYSTEM_CTRL3 [color] System control 3
0x64 Word HYPERV_L [color, note] Left channel Hyper Voice
0x66 Word HYPERV_R [color, note] Right channel Hyper Voice
0x68 Byte HYPERV_SL [color, note] Left channel Hyper Voice input
0x69 Byte HYPERV_SR [color, note] Right channel Hyper Voice input
0x6A Word HYPERV_CTRL [color] Hyper Voice Control
0x80 Word SND_FREQ_1 Sound channel 1 frequency
0x82 Word SND_FREQ_2 Sound channel 2 frequency
0x84 Word SND_FREQ_3 Sound channel 3 frequency
0x86 Word SND_FREQ_4 Sound channel 4 frequency
0x88 Byte SND_VOL_1 Sound channel 1 volume
0x89 Byte SND_VOL_2 Sound channel 2 volume
0x8A Byte SND_VOL_3 Sound channel 3 volume
0x8B Byte SND_VOL_4 Sound channel 4 volume
0x8C Byte SND_SWEEP Sound channel 3 sweep amount
0x8D Byte SND_SWEEP_TIME Sound channel 3 sweep step time
0x8E Byte SND_NOISE_CTRL Sound channel 4 noise control
0x8F Byte SND_WAVERAM Sound waveform definition area specification
0x90 Byte SND_CH_CTRL Sound channel control
0x91 Byte SND_OUT_CTRL Sound output control
0x92 Word SND_RANDOM Pseudo-random number
0x94 Byte SND_VOL_CH2 Sound channel 2 voice volume
0x96 Word SND_OUT_R [note] Right channel sound output
0x98 Word SND_OUT_L [note] Left channel sound output
0x9A Word SND_OUT_M [note] Internal speaker sound output
0xA0 Byte SYSTEM_CTRL1 System control 1
0xA2 Word TIMER_CTRL Timer control
0xA4 Word H_BLANK_TIMER H-Blank timer reload
0xA6 Word V_BLANK_TIMER V-Blank timer reload
0xA8 Word H_BLANK_COUNTER H-Blank timer count
0xAA Word V_BLANK_COUNTER V-Blank timer count
0xB0 Byte INT_VECTOR Interrupt vector
0xB1 Byte SERIAL_DATA Send/receive data
0xB2 Byte INT_ENABLE Interrupt enable
0xB3 Byte SERIAL_STATUS Serial communication status
0xB4 Byte INT_CAUSE Interrupt status
0xB5 Byte KEY_SCAN Key scan
0xB6 Byte INT_CAUSE_CLEAR Interrupt acknowledge
0xB7 Byte INT_NMI_CTRL NMI control
0xBA Word IN_SERIAL_DATA Internal serial ROM data
0xBC Word IN_SERIAL_COM Internal serial ROM command address
0xBE Word IN_SERIAL_CTRL Internal serial ROM control
0xC0 Byte LINEAR_ADDR_OFF Linear address offset
0xC1 Byte RAM_BANK RAM bank (shadow of lower byte)
0xC2 Byte ROM_BANK_0 ROM bank #0 (shadow of lower byte)
0xC3 Byte ROM_BANK_1 ROM bank #1 (shadow of lower byte)
0xC4 Word CART_SERIAL_DATA [2001, note] Cartridge serial ROM data
0xC6 Word CART_SERIAL_COM [2001, note] Cartridge serial ROM command address
0xC8 Byte CART_SERIAL_CTRL [2001, note] Cartridge serial ROM status
0xCA Byte RTC_CTRL [2003] RTC control
0xCB Byte RTC_DATA [2003] RTC data
0xCC Byte IO_CTRL [2003] I/O port control
0xCD Byte IO_SCAN [2003] I/O port scan
0xCE Byte MEMORY_CTRL [2003] Memory control
0xCF Byte LINEAR_ADDR_OFF [2003] (Mirror of linear address offset)
0xD0 Byte RAM_BANK_L [2003] RAM bank (lower byte)
0xD1 Byte RAM_BANK_H [2003] RAM bank (upper byte)
0xD2 Byte ROM_BANK_0_L [2003] ROM bank #0 (lower byte)
0xD3 Byte ROM_BANK_0_H [2003] ROM bank #0 (upper byte)
0xD4 Byte ROM_BANK_1_L [2003] ROM bank #1 (lower byte)
0xD5 Byte ROM_BANK_1_H [2003] ROM bank #1 (upper byte)

[note] These ports' official names are not known.
[color] These ports are only available in color mode.
[2001] These ports are only available on the 2001 mapper.
[2003] These ports are only available on the 2003 mapper.

If a port that is not available on the monochrome model is accessed on a color model with color mode disabled, no action will be taken when written and the value 0x90 is always read, simulating the open bus behavior of the monochrome model.

The following port address ranges are handled by the following components:

0x00 - 0xB7 Console SoC
0xB8 - 0xBF Internal EEPROM
0xC0 - 0xFF Cartridge

In most cases, word-size ports can be used with multiple byte accesses. The exception is the internal EEPROM on the monochrome model. Accessing odd internal EEPROM port addresses as bytes will function as open bus, while even port addresses function normally. On color models, byte accesses on odd port addresses function normally even when color mode is disabled.

The implementation silently converts word accesses in the cartridge range into consecutive pairs of byte accesses, adding one additional CPU cycle in the process.

Although the I/O bus is 8 bits wide, the CPU is capable of specifying 16-bit port addresses. Accessing port addresses greater than 0xFF has the following behaviors:

If bit 8 of the port address is set, the access functions as open bus.
If the lowest 8 bits of the port address are 0x00B8 or greater, the access functions as open bus.
If the access is not filtered as open bus by one of the above conditions, it functions as a mirror of the lowest 8 bits of the port address.

Editor's Note: Port addresses not listed above have no known significance. They are assumed to function as open bus.


Open Bus

When a memory or I/O access is attempted on an address that has no corresponding functionality, nothing happens and the default response of the applicable bus takes effect. This occurrence is known as "open bus".

Open bus occurs in the following situations:

The extended WRAM region at memory addresses 0x04000 - 0x0FFFF is accessed by the monochrome model or a color model with color mode disabled.
An unmapped I/O port is accessed.
An I/O port introduced in WonderSwan Color is accessed by the monochrome model or a color model with color mode disabled.

Writing or outputting to open bus has no effect. Reading or inputting from open bus returns a predetermined value. The open bus value is always 0x90 on the monochrome model, and undefined on color models.

On color models with color mode disabled, memory and I/O addresses that are available only when color mode is enabled will simulate the open bus behavior of the monochrome model: they will not respond to writes and they will always read the value 0x90.

Editor's Note: Research is needed to determine the exact open bus values for color models. It is known that they tend to read as 0x00 unless color mode is disabled and the port address is 0x4000 or greater, when they tend to return 0x90 instead. There may be other circumstances that influence the open bus value.


Cartridge

The cartridge inserts into the back of the WonderSwan unit and provides the program and save data for a software title.

Pinout

The following diagram depicts the pin configuration of the cartridge as seen looking at the face of the cartridge with the label upright:



1
24
25
48

The pins have the following significance:

1.Ground 17.Data 6 33.Address 16
2.Address 15 18.Data 5 34.Data 8
3.Address 10 19.Data 4 35.Data 9
4.Address 11 20.Data 3 36.Data 10
5.Address 9 21.Data 2 37.Data 11
6.Address 8 22.Data 1 38.Data 12
7.Address 13 23.Data 0 39.Data 13
8.Address 14 24.+3V DC 40.Reset
9.Address 12 25.+3V DC 41.MBC
10.Address 7 26.Address 0 42.Memory/IO
11.Address 6 27.Address 1 43.Read enable
12.Address 5 28.Address 2 44.Write enable
13.Address 4 29.Address 3 45.Cartridge select
14.Data 15 30.Address 19 46.Interrupt request
15.Data 14 31.Address 18 47.Serial clock
16.Data 7 32.Address 17 48.Ground

Pin signals are +3V DC.

The MBC pin is used to authenticate the cartridge's mapper chip on reset using serial communication. The serial clock pin provides a 384 KHz reference signal for this communication as well as communication with an EEPROM if present.

When accessing memory, the Memory/IO pin is +3V and all 20 address pins specify the memory address. When accessing I/O, the Memory/IO pin is 0V, address pins 0 through 7 specify the lower 8 bits of the port address, address pins 8 through 15 are 0V, and address pins 16 through 19 contain a copy of port address bits 4 through 7 respectively.

Reads and writes will only be accepted while both the the cartridge select pin and the corresponding "enable" pin are 0V.

Editor's Note: Research is needed to determine the authentication protocol on pin 41.

Interrupt

The cartridge supports an interrupt that the program can use to respond to cartridge activity. For information regarding software setup, see Managing Interrupts. The cartridge interrupt is called CASETTE and has the relative vector index +2.

Mappers

All WonderSwan cartridges contain a logic circuit that is responsible for selecting banks of cartridge memory to make available to the CPU, and to perform ancillary I/O tasks. These chips are called mappers and two versions were distributed called "2001" and "2003" after their model numbers.

I/O ports with address 0xC0 and greater are handled by the cartridge mapper. Accessing a port address not supported by a mapper results in open bus behavior.

The 2001 mapper supports the following I/O ports:

0xC0 Byte LINEAR_ADDR_OFF Linear address offset
0xC1 Byte RAM_BANK RAM bank
0xC2 Byte ROM_BANK_0 ROM bank #0
0xC3 Byte ROM_BANK_1 ROM bank #1
0xC4 Word CART_SERIAL_DATA Cartridge serial ROM data
0xC6 Word CART_SERIAL_COM Cartridge serial ROM command address
0xC8 Byte CART_SERIAL_CTRL Cartridge serial ROM status

The 2003 mapper supports the following I/O ports:

0xC0 Byte LINEAR_ADDR_OFF Linear address offset
0xC1 Byte RAM_BANK RAM bank (shadow of lower byte)
0xC2 Byte ROM_BANK_0 ROM bank #0 (shadow of lower byte)
0xC3 Byte ROM_BANK_1 ROM bank #1 (shadow of lower byte)
0xCA Byte RTC_CTRL RTC control
0xCB Byte RTC_DATA RTC data
0xCC Byte IO_CTRL I/O port control
0xCD Byte IO_SCAN I/O port scan
0xCE Byte MEMORY_CTRL Memory control
0xCF Byte LINEAR_ADDR_OFF (Mirror of linear address offset)
0xD0 Byte RAM_BANK_L RAM bank (lower byte)
0xD1 Byte RAM_BANK_H RAM bank (upper byte)
0xD2 Byte ROM_BANK_0_L ROM bank #0 (lower byte)
0xD3 Byte ROM_BANK_0_H ROM bank #0 (upper byte)
0xD4 Byte ROM_BANK_1_L ROM bank #1 (lower byte)
0xD5 Byte ROM_BANK_1_H ROM bank #1 (upper byte)


ROM Header

At reset, memory addresses FFFF:0000 - FFFF:000F must contain specific kinds of data. Due to the banking behavior of the cartridge mapper, these addresses correspond to the last 16 bytes in cartridge ROM. The significance of these addresses is described below.

FFFF:0000 - FFFF:0004 Entry point
FFFF:0005 Maintenance
FFFF:0006 Publisher ID
FFFF:0007 Color
FFFF:0008 Game ID
FFFF:0009 Game version
FFFF:000A ROM size
FFFF:000B Save type
FFFF:000C - FFFF:000D Flags
FFFF:000E - FFFF:000F Checksum

The entry point is the address of the first instruction executed by the CPU. The console boot program requires this to be a 32-bit immediate BR instruction with an 0xEA opcode or else the system will not boot.

The maintenance byte has the following format:

7 6 4 3 0
Boot
? Unknown
1 3 4
? The significance of these bits is not known.
Boot If set on a color model, the boot program will bypass any custom boot screen in internal EEPROM and supply a default boot screen instead.
Unknown If any of these bits is set, the console will not boot. Their purpose is not known.

BANDAI maintains a list of publisher IDs that is beyond the scope of this document.

The color field may be one of the following values:

0x00 Software is monochrome
0x01 Software supports color

The game ID is the binary-coded decimal representation of the last two digits of the product's SKU.

The game version byte has the following format:

7 6 0
NP
Version
1 7
NP If set, the boot program will not set the internal EEPROM into write-protected mode.
Version Software minor version number.

ROM size indicates read-only memory present in the cartridge. It has the following known values:

0x02 4 Mbit 512 KiB
0x03 8 Mbit 1 MiB
0x04 16 Mbit 2 MiB
0x05 24 Mbit 3 MiB
0x06 32 Mbit 4 MiB
0x07 48 Mbit 6 MiB
0x08 64 Mbit 8 MiB
0x09 128 Mbit 16 MiB

Save type indicates persistent memory present in the cartridge. It has the following known values:

0x00 None
0x01 SRAM 64 Kbit 8 KiB
0x02 SRAM 256 Kbit 32 KiB
0x03 SRAM 1 Mbit 128 KiB
0x04 SRAM 2 Mbit 256 KiB
0x05 SRAM 4 Mbit 512 KiB
0x10 EEPROM 1 Kbit 128 B
0x20 EEPROM 16 Kbit 2 KiB
0x50 EEPROM 8 Kbit 1 KiB

The following flags are known:

15 9 8 7 3 2 1 0
?
RTC
?
Spd
Bus
Vert
7 1 5 1 1 1
? The significance of these bits is not known.
RTC RTC availability: absent if clear, present if set.
Spd ROM access speed: 3 cycles if clear, 1 cycle if set.
Bus ROM bus size: 16-bit if clear, 8-bit if set.
Vert Orientation of boot screen: horizontal if clear, vertical if set.

The checksum is the cumulative sum of all 8-bit bytes in the ROM‐including the ROM header‐except for the two bytes of the checksum field. This field is not required to be set correctly.

Editor's Note: It is assumed that all bits in the game version byte other than bit 7 belong to the version number, but this has not been verified.


Hardware Architecture

Information about the current hardware is avaiable through the following I/O port:

0xA0 Byte SYSTEM_CTRL1 System control 1
7 4 3 2 1 0
-
cwait
cbus
WSC
-
4 1 1 1 1
- These bits have unknown significance.
cwait R Cartridge accesses take 3 CPU cycles when clear, or 1 when set.
cbus R/W The cartridge bus is 8-bit when clear, or 16-bit when set.
WSC R Color mode is unavailable when clear, or available when set.

Inspecting WSC is the preferred way to detect hardware features.

Editor's Note: The program should not change cbus. This bit's writeable status may only be intended for use by the boot ROM.

Editor's Note: Certain bits in this port may be writeable depending on the exact model and color mode configuration, and this may be a side-effect of exposing certain features to the boot ROM. It's apparent that the only intended use of this port by programs is to check for the availability of color mode.

Color Mode

On color models, various features not present in the monochrome model can be activated or deactivated.

Color features are managed through the following port:

0x60 Byte SYSTEM_CTRL2 System control 2
7 6 5 4 0
Color
FourBpp
Packed
-
1 1 1 5
- These bits have unknown significance.
Color R/W When set, color mode is enabled.
FourBpp R/W When set, 4bpp mode is enabled.
Packed R/W When set, packed mode is enabled.

This port has no function on the monochrome model, and reading from it on a monochrome model returns undefined data.

If Color is set and FourBpp is clear, characters are treated as 2 bits per pixel.

If Color and FourBpp are both set, characters are treated as 4 bits per pixel. FourBpp has no effect when Color is clear.

If Color, FourBpp and Packed are all set, characters are treated as 4 bits per pixel packed. Packed has no effect when either Color or FourBpp is clear.

Setting Color will enable color mode on color models. The following system features are available only while Color is set:

Color image features
WRAM expanded to 64 KiB
Internal EEPROM expanded to 2 KiB
DMA features
Hyper Voice

Some features behave differently depending on whether color mode is enabled or disabled. In all cases, such features will behave the way they do on the monochrome model whenever color mode is disabled. In particular, certain I/O ports have different formats in color mode, and will use the monochrome model's formats whenever color mode is disabled. If color mode is disabled, writes into the expanded WRAM are ignored and reads in expanded WRAM are undefined.

Editor's Note: The WonderWitch API preserves the lowest 5 bits when accessing SYSTEM_CTRL2. No significance has been observed in these bits, so this decision may have been made in the interest of future-proofing it.

Color System

When color mode is available according to SYSTEM_CTRL1, an additional I/O port becomes available:

0x62 Byte SYSTEM_CTRL3 System control 3
7 6 1 0
sc
-
off
1 6 1
- These bits have unknown significance and are clear when read.
sc R The system is a SwanCrystal when set, or a WonderSwan Color when clear.
off W When 1 is written to this bit, the system will power off.


CPU - V30MZ/V Series Microprocessor

Overview
Specifications
Register Set
Operands
Prefixes

Exceptions
Exceptions and Interrupts
List of Exceptions

Instruction Set
Memory and Register
Arithmetic
Bitwise
CPU Control
Branch
Block
Segment Override

Appendix
Opcode Map
8086 Translation Map


Specifications

WonderSwan uses an NEC V30 CPU:

Name: V30MZ
Address bus: 20 bits
Data bus: 16 bits
Clock speed: 3.072 MHz
Instruction cache: None
Instruction set: CISC
Manufacturer: Renesas Electronics Corporation
Word size: 16 bits
Year: 1998

The V Series microprocessors were designed as pin-compatible alternatives to the Intel 8086. The V30MZ in particular is a later model providing limited compatibility with the 8086 and has reduced capabilities when compared to other V Series products, but offers improved power efficiency and execution time.


Register Set

All registers on the V30MZ are 16-bit. The following registers are present:

AW General-purpose
BP Base pointer
BW General-purpose
CW General-purpose
DS0 Data segment 0
DS1 Data segment 1
DW General-purpose
IX Index
IY Index
PC Program counter
PS Program segment
PSW Program status word
SP Stack pointer
SS Stack segment

AW, BW, CW, DW - General Purpose Registers

Most operations on data, such as arithmetic operations, are performed on these registers. They can also be used as sources and destinations for data transfers.

For 16-bit operations, these registers are used directly as AW, BW, CW and DW.

For 8-bit operations, these registers may be used as two 8-bit registers each. The low-byte registers are used as AL, BL, CL and DL. The high-byte registers are used as AH, BH, CH and DH.

DS0, DS1, PS, SS - Segment Registers

Provide the segment portion of a physical address. The value in the segment register is shifted left 4 bits, and the resulting value is added to the 16-bit offset value of another register to compute the final physical address.

Operations that produce physical addresses have a default segment register assigned to them. In most of these cases, the actual segment register used in the physical address calculation can be changed by using a segment override prefix.

The following are the various memory-access scenarios and how they interact with segment registers:

Default Override Scenario
DS0 Yes 16-bit direct memory
DS0 Yes Memory operand, not BP base
SS Yes Memory operand, BP base
DS0 Yes Block instruction, IX value
DS1 No Block instruction, IY value
DS0 Yes CHKIND instruction
DS0 Yes TRANS instruction
PS No Instruction fetch
SS No Stack operation

SP - Stack Pointer

Points to the most recent data added to the stack.

When constructing a physical address, SP provides the offset portion and SS provides the segment portion.

BP - Base Pointer

Serves as a data offset for memory operations, and is used as part of the operation of select stack instructions.

IX, IY - Index Registers

Used as relative offsets during memory operations: one register is used as the base value for the offset, then an index register is added to that value. For instance, if the offset of a data struct is stored in one register, the individual members of that struct could be accessed using an index register.

PC - Program Counter

Holds the offset of the instruction about to be executed. PC is automatically incremented as instruction bytes are fetched from memory. When an instruction is fully fetched, PC will hold the offset of the first byte of the next instruction.

When constructing a physical address, PC provides the offset portion and PS provides the segment portion.

After PC reaches 0xFFFF, it will roll over to 0x0000 without modifying PS.

PSW - Program Status Word

Holds status and configuraiton flags. During the operation of instructions, flags in PSW are used to control some operations and reflect information about the results of other operations.

This register has the following format:

15 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 1 1 V
DIR
IE
BRK
S Z 0
AC
0 P 1
CY
4 1 1 1 1 1 1 1 1 1 1 1 1
0 R These bits have a fixed value and are clear.
1 R These bits have a fixed value and are set.
V R/W Overflow Set when the result of an operation is too large.
DIR R/W Direction Specifies the direction of a memory or block operation.
IE R/W Interrupt enable When set, interrupts will be processed.
BRK R/W Break When set, after each instruction executed, an exception is raised with vector 1.
S R/W Sign Set when the result of an operation is negative.
Z R/W Zero Set when the result of an operation is zero.
AC R/W Auxiliary Carry Similar to CY, but applies with respect to the lowest 4 bits of the operation.
P R/W Parity Set when the number of set bits in the lower 8 bits of an operation is even, or cleared if odd.
CY R/W Carry Set when an operation produces a carry or borrows.

During the operation of the branch instructions, certain flag state combinations are checked in PSW.

DIR and CY can be modified by the CLR1 and SET1 instructions.

IE can be modified by the DI and EI instructions.

There is no instruction that can directly modify BRK. To change it, the "POP PSW" instruction must be used. The exception will be raised after executing the instruction that follows POP PSW.

Editor's Note: On other V Series CPUs, bit 15 of PSW is a flag called "mode" (MD), used to control an 8-bit emulation mode. While set, the CPU would run in native mode, and while clear, it would run in emulation mode. Emulation mode provides a different set of instructions and was intended for backwards compatibility with older processors.


Operands

CPU instructions are encoded using various different binary formats. Depending on the instruction, data for different kinds of operands may be present, encoded directly into the instruction's machine code.

Operands
Operation Size
Operation Direction
Accumulator
Immediate
Memory
Register
Segment Register

Operation Size

Many instructions can operate as either 8-bit or 16-bit. This affects the width of the registers being accessed as well as how many bytes need to be read from memory for operand values. The data size of an operation is often specified in the first byte of instruction code in one of two ways:

0 7 1 0
- W
7 1
0 7 4 3 2 0
- W -
4 1 3
- These bits do not pertain to the operation size.
W If present, specifies 8-bit when clear and 16-bit when set.

When writing instructions, the size of the operation is not explicitly specified: is typically evident from the register name used for a register operand. If a register operand is not present, distinct mnemonics are provided for each operation size.

Operation Direction

Some instructions specify multiple operands as well as the direction in which to perform the operation. The direction of such instructions is specified in the first byte of instruction code:

0 7 2 1 0
- D -
6 1 1
- These bits do not pertain to the operation direction.
D If present, specifies the operands are in the default order when clear or in reverse order when set.

The operands of an instruction have a default order. Typically, the left operand is the operation's destination and the right operand is a source. If D is present and set, the operands' order and therefore roles are reversed, causing what would normally be the destination to act as the source and vice-versa.

Accumulator

Some instructions implicitly use an "accumulator" register as one of their operands. If the operation is 8-bit, the register is AL, and if the operation is 16-bit, the register is AW.

Immediate

When an instruction's operand is stored directly in the machine code, it is called an immediate operand. Normally, the size of an immediate operand matches the size of the operation. Some specific instructions may have a special bit in the first byte of machine code that influences the format of the immediate operand:

0 7 2 1 0
- s -
6 1 1
- These bits do not pertain to the immediate operand.
s See below.

If s is present and clear, the size of the immediate value is the same as that of the operation: either 8 bits or 16 bits.

If s is present and set, the immediate value is always 8 bits. If the operation is 16-bit, the immediate value is sign-extended to 16 bits.

The data for immediate operands appears as additional instruction bytes. 16-bit immediate values are stored with the low byte first.

If the instruction also contains a memory operand, the bytes of the memory operand appear before the bytes of the immediate operand.

Memory

Instructions may specify an operand using fields called Mod and Mem. The operand's value may come from a CPU register, or may be loaded from memory using one of a variety of offset expressions. Mod and Mem collectively describe how to access the operand's value.

Instructions with memory operands begin with 2 bytes, the second of which has the following structure:

Notation: aa---mmm

1 7 6 5 3 2 0
Mod - Mem
2 3 3
- These bits do not pertain to the memory operand.
Mod Indicates the presence of a displacement offset or CPU register.
Mem Specifies the offset expression base or a CPU register's index.

When Mod is 3, Mem specifies the index of the register containing the operand's value. For more information, see Register.

When Mod is not 3, Mem specifies the base of the expression to use to calculate a memory offset. The value of the operand is then read from this offset. The following expression bases are available:

Mem Expression base
0 BW + IX
1 BW + IY
2 BP + IX
3 BP + IY
4 IX
5 IY
6 BP [note]
7 BW

[note] When Mod is 0 and Mem is 6, the operand's memory offset is not given by an expression. Instead, the literal 16-bit offset is present as two additional bytes of program code (low byte first).

The offset portion of the operand's physical address is calculated by evaluating the expression base and optionally adding a signed displacement offset to it. The value of Mod determines how this is done:

Mod Offset Note
0 No displacement offset is present.
1 + disp8 An 8-bit, signed displacement offset is present as one additional byte of instruction code.
2 + disp16 A 16-bit, signed displacement offset is present as two additional bytes of instruction code (low byte first).
3 No value is read from memory. The operand's value comes directly from the register whose index is specified by Mem.

The default segment register to use when calculating the physical address depends on whether or not BP is present in the offset expression. If BP is present, the default segment register is SS. If BP is not present, the defaut segment register is DS0. The actual segment regsiter used can be specified with a segment override prefix.

If the instruction also contains an immediate operand, the bytes of the memory operand appear before the bytes of the immediate operand.

Editor's Note: Research is needed to determine whether offset expressions contain signed components, or if it even matters. It may be the case that the offset portion of the physical address is entirely computed as 16 bits before incorporating the value of the segment register.

Register

Most instructions specify at least one register as a source or destination operand. The register is identified with a 3-bit index, depending on whether the operation is 8-bit or 16-bit:

Index 8-bit 16-bit
0 AL AW
1 CL CW
2 DL DW
3 BL BW
4 AH SP
5 CH BP
6 DH IX
7 BH IY

If a memory operand has a Mod field of 3, its Mem field will be a register index. In this way, specific instructions can specify two register operands.

Instructions with a register operand usually also have a memory operand, and the register index is encoded into the bits of the second byte not occupied by the memory operand:

Notation: --rrr---

1 7 6 5 3 2 0
Mod Reg Mem
2 3 3
Mod This field pertains to the memory operand.
Reg The register's index.
Mem This field pertains to the memory operand.

Specific instructions with register operands may instead specify the register index in the first byte of instruction code:

Notation: -----rrr

0 7 3 2 0
- Reg
5 3
- These bits do not pertain to the register operand.
Reg The register's index.

Segment Register

Some instructions specify a segment register as the source or destination of a data transfer. The segment register is identified with a 2-bit index:

0DS1
1PS
2SS
3DS0

In all cases where a segment register operand is encoded into an instruction's bits, the register index occupies the middle two bits of the byte in which it appears:

Notation: ---rr---

7 5 4 3 2 0
- Reg -
3 2 3
- These bits do not pertain to the segment register operand.
Reg The segment register's index.

The POP and PUSH instructions may encode the segment register index into the first byte of instruction code.

The MOV instruction may encode the segment register index into the second byte of instruction code, shared with the bits of a memory operand. In this situation, bit 5 of that byte is not used.

Editor's Note: Research is needed to verify that bit 5 is not used in an instance of MOV with a segment register operand.


Prefixes

The behavior of CPU instructions can be modified by prepending prefixes to the instruction. Prefixes are one-byte codes that specify alternative instruction functionality, and appear in the program code immediately prior to the bytes of the prefixed instruction.

There are three general categories of prefixes. All prefixes within each category are mutually exclusive with one another:

Segment override
REP (Only applies to block instructions.)
BUSLOCK

There is no hard limit on how many prefixes may be attached to an instruction. However, since there are three total categories of prefixes, there can be at most three effective prefixes on one instruction. If multiple prefixes from the same category are attached to the same instruction, only the last one (the one immediately preceding the regular instruction data) will take effect.

After fetching a prefix byte and prior to executing the prefixed instruction, interrupts will not be accepted and the break flag (BRK) will not function.


Exceptions and Interrupts

Certain events can cause the CPU to break its current execution, save its status to the stack and begin execution somewhere else according to what happened. The general term for such an occurrence is exception. When the exception is triggered by another hardware component, it is called an interrupt.

On V30MZ, all exceptions are formally referred to as interrupts. Exceptions that result from CPU operations are referred to as software interrupts.

Exception

Processing of CPU instructions can raise exceptions on their own, known as software interrupts. This can happen in the following situations:

The operation cannot be performed with the given operands.
The BRK or BRKV instruction was executed.
The BRK flag in PSW can be used to raise an exception after each instruction executed.

Attempting to execute an instruction with an undefined opcode or sub-opcode does not result in an exception. There is no associated operation, so any bytes used to supply their prefixes, opcode, sub-opcode, memory operand or immediate operand are skipped over.

Editor's Note: Research is needed to determine the number of CPU cycles consumed by an illegal opcode.

Interrupt

Hardware components other than the CPU are allowed to request interrupts. This provides a mechanism to synchronize all system operations as well as a way for a hardware component to signal the program when certain conditions are met.

Interrupts can be disabled by clearing the IE flag in PSW. The EI and DI instructions manipulate this flag directly, and modifications to PSW through other instructions can also be used to configure it.

When an interrupt is requested, it will be processed after the current CPU instruction finishes and before the next instruction begins. There are certain situations in which interrupt requests are not processed between instructions, and in which the break flag (BRK) will not function:

Immediately following a prefix.
Immediately following a MOV or POP instruction where the destination is a segment register.
Immediately following an EI, POP or RETI instruction that changes IE from clear to set. The BRK flag still functions in this case.

The HALT instruction will stop all CPU activity until an interrupt request occurs, at which point it will resume with exception processing if IE is set, or the next instruction if IE is clear. If no interrupt requests are enabled in any hardware component, the CPU will be suspended until reset.

Vectors

When any exception occurs, the program code responsible for handling it is located by reading the address corresponding to its vector. An exception's vector is an unsigned 8-bit index into a global list of handler addresses.

Exception vectors are located in WRAM at the following addresses:

0x00000 - 0x003FF Exception vectors

Up to 256 exception vectors are supported, mostly to be used from software via the BRK instruction.

Each vector is 4 bytes with the following format:

31 16 15 0
Segment Offset
16 16
Segment The value to load into PS.
Offset The value to load into PC.

Raising Exceptions

When an exception is raised, the following process takes place:

Push PSW
IE = 0
BRK = 0
Push PS
Push PC

Since PC is incremented for each byte of instruction code fetched from memory, the value of PC that gets pushed to the stack will be the offset of the first byte of the instruction that follows either the instruction that raised the exception or the instruction that was executing when the interrupt was requested.

Editor's Note: On V Series CPUs that have an MD flag in PSW, it is set when an exception is raised.

Returning from Exceptions

When all of the processing for an exception has completed, the program can return to the main code with the RETI instruction. This instruction performs the following operations:

Pop PC
Pop PS
Pop PSW

If an interrupt is not acknowledged before returning from an instruction, the interrupt request will remain active and the CPU will immediately raise another exception for it.

Editor's Note: Research is needed to determine whether all IRQ lines remain in effect if an interrupt is not acknowledged. The WonderWitch documentation explicitly identifies some interrupts as being edge-driven and others level-driven, but given interrupt requests need to be held during instruction execution, it's not clear exactly how the IRQ state reflects what the hardware is doing.


List of Exceptions

The following exceptions result from CPU operations (software interrupts) and have fixed vectors:

Vector Description
0 CVTBD, DIV or DIVU error
1 Single-step via BRK flag
2 NMI
3 BRK 3 instruction
4 BRKV instruction
5 CHKIND error
6 Unused [note 1]
7 Unused [note 2]

[note 1] Vector 6 is typically used by other CPUs to handle undefined opcodes. V30MZ silently ignores undefined opcodes and continues execution at the next byte as the start of a new instruction.
[note 2] Vector 7 is reserved for errors that occur during execution of an instruction called POLL, which places the CPU in a wait state until woken by a coprocessor. V30MZ has no coprocessor and treats the POLL opcode as undefined.

Any exception raised by the CPU in the list above will be processed before any interrupt requests in the list below.

The following exceptions are interrupts raised by components other than the CPU. Their vectors are not fixed: their number is added to the base vector specified by INT_BASE (see below):

Vector Name Type Description
+0 SENDREADY Level [note]
+1 KEY Edge A button was pressed.
+2 CASETTE Level Requested by cartridge, usually for RTC alarm.
+3 RECEIVEREADY Level [note]
+4 DISPLINE Edge A specific row of pixels is being displayed.
+5 VBLANK_COUNTUP Edge A configurable number of images have been dispalyed.
+6 VBLANK Edge The image has finished being displayed.
+7 HBLANK_COUNTUP Edge A configurable number of rows of pixels have been displayed.

[note] Editor's Note: These interrupts need research.

A "level" interrupt will constantly issue its request until acknowledged. Returning from the handler routine without acknowledging the request will immediately cause the handler to run again.

An "edge" interrupt will only issue its request once as a pulse. Returning from the handler routine without acknolweding the request will not cause the handler to run again, but no further interrupts with the same vector can be requested until the previous one is acknowledged.

In the event two or more interrupts are requested simultaneously, the one with the greatest vector will be processed first.

Hardware interrupts cause pending HALT instructions to complete, even if interrupts are otherwise masked by the IE flag in PSW.

Editor's Note: Research is needed to verify the mechanics of "level" and "edge".

Managing Interrupts

Hardware interrupts do not have fixed vectors. Instead, their effective vector is calculated by taking a global base vector and adding to it the interrupt's vector number as shown in the list above.

The base interrupt vector is configured through the following I/O port:

This port is ostensibly an unsigned 8-bit value directly representing the hardware interrupt base vector number. However, the lowest 3 bits are ignored (limiting the base vector to multiples of 8) and are undefined when read.

Interrupt requests are managed through the following I/O ports, all of which have the same format:

0xB2 Byte INT_ENABLE Interrupt enable
0xB4 Byte INT_CAUSE Interrupt status
0xB6 Byte INT_CAUSE_CLEAR Interrupt acknowledge

Each bit in these ports corresponds to one of the hardware interrupts, with the position of each bit matching the interrupt's relative vector index.

The bits in INT_ENABLE specify which hardware interrupt situations are permitted. INT_ENABLE can be both read and written.

When an interrupt situation occurs while the corresponding bit is set in INT_ENABLE, the corresponding bit in INT_CAUSE becomes set. While INT_CAUSE is non-zero, a CPU interrupt will be requested (the processing of which can be masked by the IE flag in PSW). Clearing bits in INT_ENABLE has no effect on INT_CAUSE. INT_CAUSE is read-only and writes have no effect.

When a 1 is written to a bit in INT_CAUSE_CLEAR, the corresponding interrupt is acknowledged and the corresponding bit in INT_CAUSE is cleared, causing any active request for that interrupt to be canceled. When a 0 is written to a bit in INT_CAUSE_CLEAR, no action is taken for that interrupt. INT_CAUSE_CLEAR is write-only and its contents are undefined when read.

NMI - Non-Maskable Interrupt

The non-maskable interrupt (NMI) is a hardware interrupt that cannot be ignored by the CPU: it will invoke its handler routine regardless of the state of the IE flag in PSW, even if another interrupt is already being handled. The NMI is automatically acknowledged as soon as it is triggered, before its handler routine is invoked.

The NMI is configured through the following I/O port:

0xB7 INT_NMI_CTRL NMI control
7 5 4 3 0
-
BAT
-
3 1 4
- R These bits have no significance and are clear when read.
BAT R/W When set, enable NMI to detect low battery.

When the system battery gets low on voltage, a dedicated LCD segment activates. If BAT is set when this occurs, an NMI will be triggered. If BAT becomes set while the battery voltage is already low, an NMI will be triggered immediately. While the battery voltage is low, BAT must be cleared then set again in order to trigger another NMI.


Memory and Register

Instructions

NEC Intel Z S V CY P AC Name Operation
CVTBW CBW - - - - - - Convert Byte to Word AH = 0x00 if AL ≥ 0, 0xFF if AL < 0
CVTWL CWD - - - - - - Convert Word to Long DW = 0x0000 if AW ≥ 0, 0xFFFF if AW < 0
IN IN - - - - - - Input acc = (I/O) [src]
LDEA LEA - - - - - - Load Effective Address dest = offset of src
MOV
MOV, LAHF, LDS,
LES, SAHF
- - - - - - Move dest = src
OUT OUT - - - - - - Output (I/O) [acc] = src
POP POP, POPA, POPF * * * * * * Pop Remove from stack
PUSH PUSH, PUSHA
PUSHF
- - - - - - Push Add to stack
SALC SALC - - - - - - Set AL on Carry AL = 0x00 if CY = 0, 0xFF if CY = 1
TRANS XLAT - - - - - - Translate AL = [BW + AL]
XCH XCHG - - - - - - Exchange (temp) = dest, dest = src, src = (temp)

CVTBW - Convert Byte to Word

NEC Intel Z S V CY P AC Name Operation
CVTBW CBW - - - - - - Convert Byte to Word AH = 0x00 if AL ≥ 0, 0xFF if AL < 0

Sign-extends AL into AW. If the highest bit of AL is clear, stores 0x00 into AH. Otherwise, stores 0xFF into AH.

Code Cycles Operands
10011000 1 None

CVTWL - Convert Word to Long

NEC Intel Z S V CY P AC Name Operation
CVTWL CWD - - - - - - Convert Word to Long DW = 0x0000 if AW ≥ 0, 0xFFFF if AW < 0

Sign-extends AW into DW,AW. If the highest bit of AW is clear, stores 0x0000 into DW. Otherwise, stores 0xFFFF into DW.

Code Cycles Operands
10011001 1 None

IN - Input

NEC Intel Z S V CY P AC Name Operation
IN IN - - - - - - Input acc = (I/O) [src]

Inputs the value from the I/O port pointed to by src and stores it into AL. If 16-bit, inputs the value from the I/O port pointed to by src + 1 and stores it into AH.

Code Cycles Operands
1110010W 6 Accumulator, Immediate
1110110W 6 Accumulator, DW

The Accumulator/Immediate variant of this instruction provides the lower 8 bits of an I/O port as one additional byte of program code. The upper 8 bits of the port are zero.

LDEA - Load Effective Address

NEC Intel Z S V CY P AC Name Operation
LDEA LEA - - - - - - Load Effective Address dest = offset of src

Calculates the offset of a memory operand and stores the result into a 16-bit register.

Code Cycles Operands
10001101 aarrrmmm 1 Register, Memory

If the memory operand specifies a register, the value in that register is stored to the destination as though the instruction were MOV.

If the memory operand specifies an offset, the value at that offset is not read from memory. Instead, the offset itself is stored to the destination.

MOV - Move

NEC Intel Z S V CY P AC Name Operation
MOV
MOV, LAHF, LDS,
LES, SAHF
- - - - - - Move dest = src

Takes the value from src and stores it into dest.

Code Cycles Operands
100010DW aarrrmmm 1 Register, Memory
100011D0 aa-rrmmm 1-3 Memory, Segment Register [note 1]
10011110 4 PSW, AH [note 2]
10011111 2 AH, PSW [note 3]
101000DW 1 Accumulator, Direct Memory
1011Wrrr 1 Register, Immediate
11000100 aarrrmmm 6 DS1, Register, Memory [note 4]
11000101 aarrrmmm 6 DS0, Register, Memory [note 5]
1100011W aa---mmm 1 Memory, Immediate

[note 1] If PS is specified as the destination of the Memory/Segment Register variant of this instruction, the operation will not be performed.
[note 2] The Intel notation for the PSW, AH variant of this instruction has the mnemonic SAHF and has zero operands.
[note 3] The Intel notation for the AH, PSW variant of this instruction has the mnemonic LAHF and has zero operands.
[note 4] The Intel notation for the DS1, … variant of this instruction has the mnemonic LES and does not include the segment register operand.
[note 5] The Intel notation for the DS0, … variant of this instruction has the mnemonic LDS and does not include the segment register operand.

After executing the Memory/Segment Register variant of this instruction and prior to executing the following instruction, interrupts will not be accepted and the break flag (BRK) will not function.

When transferring between AH and PSW, only the lower 8 bits of PSW are relevant.

The Accumulator/Direct Memory variant of this instruction provides a 16-bit memory offset as two additional bytes of program code (low byte first). The memory at this offset is accessed by the operation.

The three-operand variants of this instruction load 32 bits from the memory pointed to by the memory operand. The lower 16 bits (low byte first) are stored into the 16-bit register operand and the upper 16 bits (low byte first) are stored into the segment register operand.

If a three-operand variant of this instruction specifies a register for the memory operand, the offset accessed in memory will be undefined.

The number of cycles taken by the Memory/Segment Register variant of this instruction depends on the memory operand:

1 The memory operand is the destination and a register.
2 The memory operand is the source and a register.
3 The memory operand is an offset.

OUT - Output

NEC Intel Z S V CY P AC Name Operation
OUT OUT - - - - - - Output (I/O) [dest] = acc

Outputs the value of AL to the I/O port pointed to by dest. If 16-bit, outputs the value of AH to the I/O port pointed to by dest + 1.

Code Cycles Operands
1110011W 6 Immediate, Accumulator
1110111W 6 DW, Accumulator

The Immediate/Accumulator variant of this instruction provides the lower 8 bits of an I/O port as one additional byte of program code. The upper 8 bits of the port are zero.

POP - Pop

NEC Intel Z S V CY P AC Name Operation
POP POP, POPA, POPF * * * * * * Pop Remove from stack

Retrieves a 16-bit value from the stack and stores it in the operand. During a pop operation, the value is loaded from the memory pointed to by SS:SP (low byte first), then SP is incremented by 2.

Code Cycles Operands
000rr111 3 Segment Register [note 1]
01011rrr 1 Register
01100001 8 R [note 2]
10001111 aa---mmm 1-3 Memory
10011101 3 PSW [note 3]

[note 1] The instruction code 00001111 does not correspond to "POP PS". It is an undefined opcode.
[note 2] The Intel notation for the R variant of this instruction has the mnemonic POPA and has zero operands.
[note 3] The Intel notation for the PSW variant of this instruction has the mnemonic POPF and has zero operands.

After executing the Segment Register variant of this instruction and prior to executing the following instruction, interrupts will not be accepted and the break flag (BRK) will not function.

The Register and Memory variants of this instruction are 16-bit operations.

The R variant of this instruction performs the following algorithm:

Pop IY
Pop IX
Pop BP
SP = SP + 2
Pop BW
Pop DW
Pop CW
Pop AW

Status flags in PSW will only be modified when PSW is the operand. If the PSW variant of this instruction causes the interrupt enable flag (IE) to transition from clear to set, then prior to executing the following instruction, interrupts will not be accepted, but the break flag (BRK) will continue to function.

The number of cycles taken by the Memory variant of this instruction depends on the operand:

1 The operand is a register.
3 The operand is an offset.

Editor's Note: The instruction set documentation indicates anomalous behavior when using PUSH SP followed by POP SP. This needs to be investigated.

PUSH - Push

NEC Intel Z S V CY P AC Name Operation
PUSH PUSH, PUSHA
PUSHF
- - - - - - Push Add to stack

Stores a 16-bit value on the stack. During a push operation, SP is decremented by 2, then the value is stored into memory at the offset pointed to by SP (low byte first).

Code Cycles Operands
000rr110 2 Segment Register
01010rrr 1 Register
01100000 9 R [note 1]
011010s0 1 Immediate
10011100 2 PSW [note 2]
1111111- aa110mmm 1-2 Memory

[note 1] The Intel notation for the R variant of this instruction has the mnemonic PUSHA and has zero operands.
[note 2] The Intel notation for the PSW variant of this instruction has the mnemonic PUSHF and has zero operands.

All push operations are 16-bit. This affects which data is accessed by the Register and Memory variants of this instruction, and the size of the immediate operand.

The R variant of this instruction performs the following algorithm:

(temp) = SP
Push AW
Push CW
Push DW
Push BW
Push (temp)
Push BP
Push IX
Push IY

The Memory variant of this instruction is a 16-bit operation.

The number of cycles taken by the Memory variant of this instruction depends on the operand:

1 The operand is a register.
2 The operand is an offset.

SALC - Set AL on Carry

NEC Intel Z S V CY P AC Name Operation
SALC SALC - - - - - - Set AL on Carry AL = 0x00 if CY = 0, 0xFF if CY = 1

Sets AL according to the status of CY. If CY is clear, stores 0x00 into AL. Otherwise, stores 0xFF into AL.

Code Cycles Operands
11010110 8 None

Editor's Note: This instruction is historically undocumented, even by Intel. It was first documented in the instruction set for the Pentium Pro (P6/i686) in 1995, but has been confirmed to be present in all of Intel's x86 CPUs all the way back to the 8086. Its purpose is to assist compilers by succinctly transferring boolean results into AL (for use as function return values) without affecting any of the status flags, and it is provided by V30MZ for compatibility reasons.

TRANS - Translate

NEC Intel Z S V CY P AC Name Operation
TRANS XLAT - - - - - - Translate AL = [BW + AL]

Calculates a memory offset as the unsigned sum of BW and AL, and loads the byte at that offset into AL.

Code Cycles Operands
11010111 5 [BW]

This instruction's operands are implicit and may be written in other ways:

The operand may be omitted.
The instruction may be written as "TRANSB" with zero operands.

The default segment register for this instruction is DS0. The segment register to use can be selected with a segment override prefix.

XCH - Exchange

NEC Intel Z S V CY P AC Name Operation
XCH XCHG - - - - - - Exchange (temp) = dest, dest = src, src = (temp)

Exchanges the values stored in the operands.

Code Cycles Operands
1000011W aarrrmmm 3-5 Register, Memory
10010rrr 3 Accumulator, Register

The Accumulator/Register variant of this instruction is a 16-bit operation.

This instruction may be written with its operands reversed, as the operation will be unchanged.

When the Accumulator/Register variant of this instruction is used to exchange AW with itself, it is regarded as its own instruction:

Code Mnemonic Name Cycles Operands
10010000 NOP No Operation 3 None

The number of cycles taken by the Register/Memory variant of this instruction depends on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

Arithmetic

Instructions

NEC Intel Z S V CY P AC Name Operation
ADD ADD Add dest = dest + src
ADDC ADC Add with Carry dest = dest + src + CY
ADJ4A DAA ? Adjust Nibble Add See instruction for details.
ADJ4S DAS ? Adjust Nibble Subtract See instruction for details.
ADJBA AAA Adjust Byte Add See instruction for details.
ADJBS AAS Adjust Byte Subtract See instruction for details.
CMP CMP Compare (discard) = dest - src
CVTBD AAM ? ? ? Convert Binary to Decimal AH = AL / src, AL = AL MOD src
CVTDB AAD Convert Decimal to Binary AL = AH * src + AL, AH = 0
DEC DEC - Decrement dest = dest - 1
DIV IDIV ? ? ? ? ? ? Divide Signed See instruction for details.
DIVU DIV ? ? ? ? ? ? Divide Unsigned See instruction for details.
FPO1 ESC - - - - - - Floating Point Operation 1 No operation.
INC INC - Increment dest = dest + 1
MUL IMUL Multiply Signed See instruction for details.
MULU MUL Multiply Unsigned See instruction for details.
NEG NEG Negate dest = 0 - dest
SUB SUB Subtract dest = dest - src
SUBC SBB Subtract with Carry dest = dest - src - CY

ADD - Add

NEC Intel Z S V CY P AC Name Operation
ADD ADD Add dest = dest + src

Adds the two operands. The result is stored in the left operand.

Code Cycles Operands
000000DW aarrrmmm 1-3 Memory, Register
0000010W 1 Accumulator, Immediate
100000sW aa000mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the addition is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the operands have the same sign and the result has the opposite sign, or is cleared otherwise.

The carry flag (CY) is set when the unsigned sum exceeds 0xFF for byte or 0xFFFF for word, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set when the unsigned sum of the lowest 4 bits of the operands exceeds 0xF, or is cleared otherwise.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

ADDC - Add with Carry

NEC Intel Z S V CY P AC Name Operation
ADDC ADC Add with Carry dest = dest + src + CY

Adds the two operands, plus 1 more if the carry flag (CY) was set. The result is stored in the left operand.

Code Cycles Operands
000100DW aarrrmmm 1-3 Memory, Register
0001010W 1 Accumulator, Immediate
100000sW aa010mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the addition is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the operands have the same sign and the result has the opposite sign, or is cleared otherwise.

The carry flag (CY) is set when the unsigned sum exceeds 0xFF for byte or 0xFFFF for word, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set when the unsigned sum of the lowest 4 bits of the operands exceeds 0xF, or is cleared otherwise.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

ADJ4A - Adjust Nibble Add

NEC Intel Z S V CY P AC Name Operation
ADJ4A DAA ? Adjust Nibble Add See below.

When ADD or ADDC is used on two-digit binary-coded decimal numbers, ADJ4A can be used to adjust the result in the AL register in order to produce the correct two-digit binary-coded decimal result.

Code Cycles Operands
00100111 10 None

The adjustment performs the following algorithm:

If (AL AND 0x0F) > 0x09, or AC = 1
AL = AL + 0x06
AC = 1
If AL > 0x9F, or CY = 1
AL = AL + 0x60
CY = 1

If the operands of the original addition were not two-digit binary-coded decimal, the result of the adjustment will be nonsense.

The zero flag (Z) is set when the result of the adjustment is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the adjustment is set, or is cleared otherwise.

The overflow flag (V) has an unspecified state after this instruction completes.

The carry (CY) and auxiliary carry (AC) flags are updated according to the above algorithm.

The parity flag (P) is set when the number of set bits in the result is even, or is cleared otherwise.

ADJ4S - Adjust Nibble Subtract

NEC Intel Z S V CY P AC Name Operation
ADJ4S DAS ? Adjust Nibble Subtract See below.

When SUB or SUBC is used on two-digit binary-coded decimal numbers, ADJ4S can be used to adjust the result in the AL register in order to produce the correct two-digit binary-coded decimal result.

Code Cycles Operands
00101111 10 None

The adjustment performs the following algorithm:

If (AL AND 0x0F) > 0x09, or AC = 1
AL = AL - 0x06
AC = 1
If AL > 0x9F, or CY = 1
AL = AL - 0x60
CY = 1

If the operands of the original subtraction were not two-digit binary-coded decimal, the result of the adjustment will be nonsense.

The zero flag (Z) is set when the result of the adjustment is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the adjustment is set, or is cleared otherwise.

The overflow flag (V) has an unspecified state after this instruction completes.

The carry (CY) and auxiliary carry (AC) flags are updated according to the above algorithm.

The parity flag (P) is set when the number of set bits in the result is even, or is cleared otherwise.

ADJBA - Adjust Byte Add

NEC Intel Z S V CY P AC Name Operation
ADJBA AAA Adjust Byte Add See below.

When ADD or ADDC is used on one-digit binary-coded decimal numbers, ADJBA can be used to adjust the values in the AL and AH registers in order to produce the correct two-digit binary-coded decimal result.

Code Cycles Operands
00110111 9 None

The adjustment performs the following algorithm:

If (AL AND 0x0F) > 0x09, or AC = 1
AL = (AL + 0x06) AND 0x0F
AH = AH + 0x01
AC = 1
CY = 1
S = 0
Z = 1
Otherwise
AL = AL AND 0x0F
AC = 0
CY = 0
S = 1
Z = 0

If the operands of the original addition were not one-digit binary-coded decimal, the result of the adjustment will be nonsense.

The zero (Z), sign (S), carry (CY) and auxiliary carry (AC) flags are updated according to the above algorithm.

The overflow (V) flag is always cleared.

The parity (P) flag is always set.

★ In the V Series specification, the zero (Z), sign (S), overflow (V) and parity (P) flags have unspecified states after this instruction completes.

ADJBS - Adjust Byte Subtract

NEC Intel Z S V CY P AC Name Operation
ADJBS AAS Adjust Byte Subtract See below.

When SUB or SUBC is used on one-digit binary-coded decimal numbers, ADJBS can be used to adjust the result in the AL and AH registers in order to produce the correct two-digit binary-coded decimal output.

Code Cycles Operands
00111111 9 None

The adjustment performs the following algorithm:

If (AL AND 0x0F) > 0x09, or AC = 1
AL = (AL - 0x06) AND 0x0F
AH = AH - 0x01
AC = 1
CY = 1
S = 0
Z = 1
Otherwise
AL = AL AND 0x0F
AC = 0
CY = 0
S = 1
Z = 0

If the operands of the original subtraction were not 4-bit binary-coded decimal, the result of the adjustment will be nonsense.

The zero (Z), sign (S), carry (CY) and auxiliary carry (AC) flags are updated according to the above algorithm.

The overflow (V) flag is always cleared.

The parity (P) flag is always set.

★ In the V Series specification, the zero (Z), sign (S), overflow (V) and parity (P) flags have unspecified states after this instruction completes.

CMP - Compare

NEC Intel Z S V CY P AC Name Operation
CMP CMP Compare (discard) = dest - src

Subtracts the operands, updating the status flags in the process, and discards the result.

Code Cycles Operands
001110DW aarrrmmm 1-2 Memory, Register
0011110W 1 Accumulator, Immediate
100000sW aa111mmm 1-2 Memory, Immediate

The zero flag (Z) is set when the result of the subtraction is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the operands have opposite signs and the left operand and result have opposite signs, or is cleared otherwise.

The carry flag (CY) is set when the unsigned difference passes zero, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set when the unsigned difference of the lowest 4 bits of the operands passes zero, or is cleared otherwise.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 One of the operands is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
2 The destination operand is an offset.

CVTBD - Convert Binary to Decimal

NEC Intel Z S V CY P AC Name Operation
CVTBD AAM ? ? ? Convert Binary to Decimal AH = AL / src, AL = AL MOD src

An 8-bit, unsigned division is performed as AL / src, the quotient is stored into AH, and the remainder is stored into AL.

Code Cycles Operands
11010100 17 Immediate

If the divisor is zero, an exception is raised with vector 0. The value of AW is undefined in this situation.

The zero flag (Z) is set when the resulting value of AL is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the resulting value of AL is set, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the resulting value of AL is even, or is cleared otherwise.

The overflow (V), carry (CY) and auxiliary carry (AC) flags have unspecified states after this instruction completes.

Editor's Note: The intended use of this instruction is to use an operand of 10 to adjust the result of two multiplied binary-coded decimal values after using MULU.

Editor's Note: Formally, the V Series specification does not include an operand for this instruction, but provides a second byte 0x0A as a sort of 16-bit opcode. The V30MZ treats this byte as an operand in accordance with the 8086 family specification.

CVTDB - Convert Decimal to Binary

NEC Intel Z S V CY P AC Name Operation
CVTDB AAD Convert Decimal to Binary AL = AH * src + AL, AH = 0

An 8-bit, unsigned multiplication is performed as AH * src, the value in AL is added, the lower 8 bits of the result are stored into AL, and zero is stored into AH.

Code Cycles Operands
11010101 00001010 6 Immediate

V30MZ processes this instruction by performing MULU followed by ADD. All flags—including overflow (V), carry (CY) and auxiliary carry (AC)—are updated according to the usual operations of ADD.

★ In the V Series specification, the overflow (V), carry (CY) and auxiliary carry (AC) flags have unspecified states after this instruction completes.

Editor's Note: The intended use of this instruction is to use an operand of 10 to prepare a binary-coded decimal value to be subsequently divided using DIVU, such that it will produce the correct binary-coded decimal result.

Editor's Note: Formally, the V Series specification does not include an operand for this instruction, but provides a second byte 0x0A as a sort of 16-bit opcode. The V30MZ treats this byte as an operand in accordance with the 8086 family specification.

DEC - Decrement

NEC Intel Z S V CY P AC Name Operation
DEC DEC - Decrement dest = dest - 1

Subtracts 1 from the operand and stores the result back into the operand.

Code Cycles Operands
01001rrr 1 Register
1111111W aa001mmm 1-3 Memory

The Register variant of this instruction is a 16-bit operation.

The zero flag (Z) is set when the result of the subtraction is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the original value was -128 for byte or -32,768 for word, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set if the lowest 4 bits of the original value were all clear, or is cleared otherwise.

The number of cycles taken by the Memory variant of this instruction depends on the operand:

1 The operand is a register.
3 The operand is an offset.

DIV - Divide Signed

NEC Intel Z S V CY P AC Name Operation
DIV IDIV ? ? ? ? ? ? Divide Signed See below.

As an 8-bit operation, a signed division is performed as AW / mem, the remainder is stored into AH and the quotient is stored into AL.

As a 16-bit operation, a 32-bit value is produced with DW as the upper bits and AW as the lower bits, a signed division is performed as this value / mem, the remainder is stored into DW and the quotient is stored into AW.

The quotient is truncated to an integer (towards zero), and the remainder has the same sign as the dividend.

Code Cycles Operands
1111011W aa111mmm 17-25 Memory

If the divisor is zero or the magnitude of the quotient (after truncation) exceeds ±0x7F for 8-bit or ±0x7FFF for 16-bit, an exception is raised with vector 0. The values of AW and DW (if 16-bit) are undefined in this situation.

The zero (Z), sign (S), overflow, (V), carry (CY), parity (P) and auxiliary carry (AC) flags have unspecified states after this instruction completes.

The number of cycles taken by this instruction depends on the operation size and operand:

17 8-bit Register
18 8-bit Offset
24 16-bit Register
25 16-bit Offset

Editor's Note: Most x86 CPUs after the Intel 8089 include the maximum negative value (-128 and -32,768) in the range of valid quotients. The V Series specification matches the range defined in the original 8086 family specification, which excludes the maximum negative value.

Editor's Note: Although the values in DW (if 16-bit) and AW are formally undefined in the event of an exception, hardware testing suggests that these registers are simply not modified.

DIVU - Divide Unsigned

NEC Intel Z S V CY P AC Name Operation
DIVU DIV ? ? ? ? ? ? Divide Unsigned See below.

As an 8-bit operation, an unsigned division is performed as AW / mem, the remainder is stored into AH and the quotient is stored into AL.

As a 16-bit operation, a 32-bit value is produced with DW as the upper bits and AW as the lower bits, an unsigned division is performed as this value / mem, the remainder is stored into DW and the quotient is stored into AW.

The quotient is truncated to an integer (towards zero).

Code Cycles Operands
1111011W aa110mmm 15-24 Memory

If the divisor is zero or the quotient (after truncation) exceeds 0xFF for 8-bit or 0xFFFF for 16-bit, an exception is raised with vector 0. The values of AW and DW (if 16-bit) are undefined in this situation.

The zero (Z), sign (S), overflow, (V), carry (CY), parity (P) and auxiliary carry (AC) flags have unspecified states after this instruction completes.

The number of cycles taken by this instruction depends on the operation size and operand:

Cycles Size Operand
15 8-bit Register
16 8-bit Offset
23 16-bit Register
24 16-bit Offset

Editor's Note: Although the values in DW (if 16-bit) and AW are formally undefined in the event of an exception, hardware testing suggests that these registers are simply not modified.

FPO1 - Floating Point Operation 1

NEC Intel Z S V CY P AC Name Operation
FPO1 ESC - - - - - - Floating Point Operation 1 No operation.

Performs no operation.

Code Cycles Format
11011--- aa---mmm 1 Memory

Although this instruction performs no operation, additional bytes of instruction code may still be present depending on the memory operand. If the memory operand specifies an offset, no memory is actually accessed.

Editor's Note: This instruction was carried over from the base V Series instruction set. Its original function was to control a floating-point coprocessor, but the coprocessor feature is not supported on V30MZ.

INC - Increment

NEC Intel Z S V CY P AC Name Operation
INC INC - Increment dest = dest + 1

Adds 1 to the operand and stores the result back into the operand.

Code Cycles Operands
01000rrr 1 Register
1111111W aa000mmm 1-3 Memory

The Register variant of this instruction is a 16-bit operation.

The zero flag (Z) is set when the result of the addition is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the original value was 127 for byte or 32,767 for word, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) will be set if the lowest 4 bits of the original value were all set, or is cleared otherwise.

The number of cycles taken by the Memory variant of this instruction depends on the operand:

1 The operand is a register.
3 The operand is an offset.

MUL - Multiply Signed

NEC Intel Z S V CY P AC Name Operation
MUL IMUL Multiply Signed See below.

Performs a signed multiplication of the operands. The exact operation depends on which variant of the instruction is being executed.

Code Cycles Operands
011010S1 aarrrmmm 3-4 Register, Memory, Immediate
1111011W aa101mmm 3-4 Memory

The three-operand variant of this instruction performs a signed 16-bit multiplication. The memory and immediate operands are multiplied together, and the lower 16 bits of the product are stored into the register operand.

If the three-operand variant of this instruction specifies a memory operand that matches the register operand, the register can optionally be written only once, forming a two-operand instruction with it and the immediate operand.

The Memory variant of this instruction performs a signed 8- or 16-bit multiplication with the accumulator and the operand. As an 8-bit operation, the upper 8 bits of the product are stored into AH and the lower 8 bits of the result are stored into AL. As a 16-bit operation, the upper 16 bits of the result are stored into DW and the lower 16 bits of the result are stored into AW.

The overflow (V) and carry (CY) flags are set if the full product is not a sign-extension of the lowest 8 or 16 bits of the product (depending on the size of the operation), or are cleared otherwise.

The zero (Z) flag is always set.

The sign (S), parity (P) and auxiliary carry (AC) flags are always cleared.

The number of cycles taken by either variant of this instruction depends on the memory operand:

3 The memory operand is a register.
4 The memory operand is an offset.

★ In the V Series specification, the zero (Z), sign (S), parity (P) and auxiliary carry (AC) flags have unspecified states after this instruction completes.

MULU - Multiply Unsigned

NEC Intel Z S V CY P AC Name Operation
MULU MUL Multiply Unsigned See below.

Performs an unsigned multiplication of the accumulator and the operand. As an 8-bit operation, the upper 8 bits of the product are stored into AH and the lower 8 bits of the product are stored into AL. As a 16-bit operation, the upper 16 bits of the result are stored into DW and the lower 16 bits of the result are stored into AW.

Code Cycles Operands
1111011W aa100mmm 3-4 Memory

The overflow (V) and carry (CY) flags will be set if the upper half of the product is not zero, or are cleared otherwise.

The zero (Z) flag is always set.

The sign (S), parity (P) and auxiliary carry (AC) flags are always cleared.

The number of cycles taken by this instruction depends on the operand:

3 The operand is a register.
4 The operand is an offset.

★ In the V Series specification, the zero (Z), sign (S), parity (P) and auxiliary carry (AC) flags have unspecified states after this instruction completes.

NEG - Negate

NEC Intel Z S V CY P AC Name Operation
NEG NEG Negate dest = 0 - dest

Calculates the additive inverse of dest by subtracting dest from zero, and stores the result back into dest.

Code Cycles Operands
1111011W aa011mmm 1-3 Memory

The zero flag (Z) is set when the result of the negation is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set if the original value was -128 for byte or -32,768 for word, or is cleared otherwise.

The carry flag (CY) is set if the original value was not zero, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set if any of the lowest 4 bits of the original value were set, or is cleared otherwise.

The number of cycles taken by this instruction depends on the operand:

1 The operand is a register.
3 The operand is an offset.

SUB - Subtract

NEC Intel Z S V CY P AC Name Operation
SUB SUB Subtract dest = dest - src

Subtracts the two operands. The result is stored in the left operand.

Code Cycles Operands
001010DW aarrrmmm 1-3 Memory, Register
0010110W 1 Accumulator, Immediate
100000sW aa101mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the subtraction is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the operands have opposite signs and the left operand and result have opposite signs, or is cleared otherwise.

The carry flag (CY) is set when the unsigned difference passes zero, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set when the unsigned difference of the lowest 4 bits of the operands passes zero, or is cleared otherwise.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

SUBC - Subtract with Carry

NEC Intel Z S V CY P AC Name Operation
SUBC SBC Subtract dest = dest - src - CY

Subtracts the two operands, minus 1 more if the carry flag (CY) was set. The result is stored in the left operand.

Code Cycles Operands
000110DW aarrrmmm 1-3 Memory, Register
0001110W 1 Accumulator, Immediate
100000sW aa011mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the subtraction is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the operands have opposite signs and the left operand and result have opposite signs, or is cleared otherwise.

The carry flag (CY) is set when the unsigned difference passes zero, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set when the unsigned difference of the lowest 4 bits of the operands passes zero, or is cleared otherwise.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

Bitwise

Instructions

NEC Intel Z S V CY P AC Name Operation
AND AND 0 0 ? And dest = dest AND src
NOT NOT - - - - - - Not dest = NOT dest
OR OR 0 0 ? Or dest = dest OR src
ROL ROL - - - - Rotate Left dest = dest rotate left by src
ROLC RCL - - - - Rotate Left with Carry (CY,dest) = (CY,dest) rotate left by src
ROR ROR - - - - Rotate Right dest = dest rotate right by src
RORC RCR - - - - Rotate Right with Carry (CY,dest) = (CY,dest) rotate right by src
SHL SHL * ? Shift Left dest = dest << src
SHR SHR * ? Shift Right dest = dest >> src (zero-filling)
SHRA SAR * ? Shift Right Arithmetic dest = dest >> src (sign-propagating)
TEST TEST 0 0 ? Test (discard) = dest AND src
XOR XOR 0 0 ? Exclusive Or dest = dest XOR src

AND - And

NEC Intel Z S V CY P AC Name Operation
AND AND 0 0 ? And dest = dest AND src

Computes the bitwise AND of the operands. The result is stored in the left operand.

Code Cycles Operands
001000DW aarrrmmm 1-3 Memory, Register
0010010W 1 Accumulator, Immediate
100000sW aa100mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the operation is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow (V) and carry (CY) flags are cleared.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

NOT - Not

NEC Intel Z S V CY P AC Name Operation
NOT NOT - - - - - - Not dest = NOT dest

Inverts the bits of the operand.

Code Cycles Operands
1111011W aa010mmm 1-3 Memory

The number of cycles taken by this instruction depends on the operand:

1 The operand is a register.
3 The operand is an offset.

OR - Or

NEC Intel Z S V CY P AC Name Operation
OR OR 0 0 ? Or dest = dest OR src

Computes the bitwise OR of the operands. The result is stored in the left operand.

Code Cycles Operands
000010DW aarrrmmm 1-3 Memory, Register
0000110W 1 Accumulator, Immediate
100000sW aa001mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the operation is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow (V) and carry (CY) flags are cleared.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

ROL - Rotate Left

NEC Intel Z S V CY P AC Name Operation
ROL ROL - - - - Rotate Left dest = dest rotate left by src

Performs a left bitwise rotation on the value of the destination by the number of bits given by the source, and stores the result into the destination.

For each bit of rotation, a left shift is performed on dest, and the previous highest bit becomes the new lowest bit.

Code Cycles Operands
1100000W aa000mmm 3-5 Memory, Immediate
1101000W aa000mmm 1-3 Memory, 1
1101001W aa000mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

If src is zero, the carry flag (CY) is not modified. Otherwise, it becomes a copy of the lowest bit of the result of the operation.

The overflow flag (V) is set if the highest bit of dest changes during the final bit of rotation, or is cleared otherwise.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

★ In the V Series specification, the overflow (V) flag has unspecified state after the Memory/Immediate and Memory/CL variants of this instruction complete.

ROLC - Rotate Left with Carry

NEC Intel Z S V CY P AC Name Operation
ROLC RCL - - - - Rotate Left with Carry (CY,dest) = (CY,dest) rotate left by src

Performs a left bitwise rotation on a value formed by treating CY as an additional bit one place higher than the highest bit of the destination. The number of bits to rotate is given by the source, and the result is stored into CY and the destination.

For each bit of rotation, a left shift is performed on dest, CY is used as the new lowest bit of dest, and the previous highest bit of dest becomes the new CY.

Code Cycles Operands
1100000W aa010mmm 3-5 Memory, Immediate
1101000W aa010mmm 1-3 Memory, 1
1101001W aa010mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

If src is zero, the carry flag (CY) is not modified. Otherwise, it is modified as described above.

The overflow flag (V) is set if the highest bit of dest changes during the final bit of rotation, or is cleared otherwise.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

★ In the V Series specification, the overflow (V) flag has unspecified state after the Memory/Immediate and Memory/CL variants of this instruction complete.

ROR - Rotate Right

NEC Intel Z S V CY P AC Name Operation
ROR ROR - - - - Rotate Right dest = dest rotate right by src

Performs a right bitwise rotation on the value of the destination by the number of bits given by the source, and stores the result into the destination.

For each bit of rotation, a right shift is performed on dest, and the previous lowest bit becomes the new highest bit.

Code Cycles Operands
1100000W aa001mmm 3-5 Memory, Immediate
1101000W aa001mmm 1-3 Memory, 1
1101001W aa001mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

If src is zero, the carry flag (CY) is not modified. Otherwise, it becomes a copy of the highest bit of the result of the operation.

The overflow flag (V) is set if the highest bit of dest changes during the final bit of rotation, or is cleared otherwise.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

★ In the V Series specification, the overflow (V) flag has unspecified state after the Memory/Immediate and Memory/CL variants of this instruction complete.

RORC - Rotate Right with Carry

NEC Intel Z S V CY P AC Name Operation
ROLC RCL - - - - Rotate Left with Carry (CY,dest) = (CY,dest) rotate right by src

Performs a right bitwise rotation on a value formed by treating CY as an additional bit one place higher than the highest bit of the destination. The number of bits to rotate is given by the source, and the result is stored into CY and the destination.

For each bit of rotation, a right shift is performed on dest, CY is used as the new highest bit of dest, and the previous lowest bit of dest becomes the new CY.

Code Cycles Operands
1100000W aa011mmm 3-5 Memory, Immediate
1101000W aa011mmm 1-3 Memory, 1
1101001W aa011mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

If src is zero, the carry flag (CY) is not modified. Otherwise, it is modified as described above.

The overflow flag (V) is set if the highest bit of dest changes during the final bit of rotation, or is cleared otherwise.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

★ In the V Series specification, the overflow (V) flag has unspecified state after the Memory/Immediate and Memory/CL variants of this instruction complete.

SHL - Shift Left

NEC Intel Z S V CY P AC Name Operation
SHL SHL * ? Shift Left dest = dest << src

Performs a left bitwise shift on the value of the destination by the number of bits given by the source, and stores the result into the destination. Bits shifted in on the right are zeroes.

Code Cycles Operands
1100000W aa100mmm 3-5 Memory, Immediate
1101000W aa100mmm 1-3 Memory, 1
1101001W aa100mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

The zero flag (Z) is set when the result of the shift is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

If src is zero, the carry flag (CY) is not modified. Otherwise, it becomes a copy of the last bit that was shifted out of the left side of the register.

For the Memory/1 variant of this instruction, the overflow flag (V) is set if the highest bit of dest changes, or is cleared otherwise. For other variants of this instruction, the overflow flag has an unspecified state after the instruction completes.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

SHR - Shift Right

NEC Intel Z S V CY P AC Name Operation
SHR SHR * ? Shift Right dest = dest >> src (zero-filling)

Performs a right bitwise shift on the value of the destination by the number of bits given by the source, and stores the result into the destination. Bits shifted in on the left are zeroes.

Code Cycles Operands
1100000W aa101mmm 3-5 Memory, Immediate
1101000W aa101mmm 1-3 Memory, 1
1101001W aa101mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

The zero flag (Z) is set when the result of the shift is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

If src is zero, the carry flag (CY) is not modified. Otherwise, it becomes a copy of the last bit that was shifted out of the right side of the register.

For the Memory/1 variant of this instruction, the overflow flag (V) is set if the highest bit of dest changes, or is cleared otherwise. For other variants of this instruction, the overflow flag has an unspecified state after the instruction completes.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

SHRA - Shift Right Arithmetic

NEC Intel Z S V CY P AC Name Operation
SHRA SAR * ? Shift Right Arithmetic dest = dest >> src (sign-propagating)

Performs a right bitwise shift on the value of the destination by the number of bits given by the source, and stores the result into the destination. Bits shifted in on the left are copies of the highest bit of the original value.

Code Cycles Operands
1100000W aa111mmm 3-5 Memory, Immediate
1101000W aa111mmm 1-3 Memory, 1
1101001W aa111mmm 3-5 Memory, CL

Only the lowest 5 bits of src are used in the operation.

If dest is an offset, the read and write memory accesses are performed even when src is zero.

The size of the immediate operand in the Memory/Immediate variant of this instruction is always one byte.

The zero flag (Z) is set when the result of the shift is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

If src is zero, the carry flag (CY) is not modified. Otherwise, becomes a copy of the last bit that was shifted out of the right side of the register.

For the Memory/1 variant of this instruction, the overflow flag (V) is set if the highest bit of dest changes, or is cleared otherwise. For other variants of this instruction, the overflow flag has an unspecified state after the instruction completes.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The numbers of cycles taken by the Memory/Immediate and Memory/CL variants of this instruction depend on the memory operand:

3 The memory operand is a register.
5 The memory operand is an offset.

The number of cycles taken by the Memory/1 variant of this instruction depends on the memory operand:

1 The memory operand is a register.
3 The memory operand is an offset.

TEST - Test

NEC Intel Z S V CY P AC Name Operation
TEST TEST 0 0 ? Test (discard) = dest AND src

Computes the bitwise AND of the operands, updates the status flags accordingly, and discards the result.

Code Cycles Operands
1000010W aarrrmmm 1-2 Register, Memory
1010100W 1 Accumulator, Immediate
1111011W aa000mmm 1-2 Memory, Immediate

The zero flag (Z) is set when the result of the operation is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow (V) and carry (CY) flags are cleared.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The numbers of cycles taken by the Register/Memory and Memory/Immediate variants of this instruction depend on the memory operand:

1 The memory operand is a register.
2 The memory operand is an offset.

XOR - Exclusive Or

NEC Intel Z S V CY P AC Name Operation
XOR XOR 0 0 ? Exclusive Or dest = dest XOR src

Computes the bitwise exclusive OR of the operands. The result is stored in the left operand.

Code Cycles Operands
001100DW aarrrmmm 1-3 Memory, Register
0011010W 1 Accumulator, Immediate
100000sW aa110mmm 1-3 Memory, Immediate

The zero flag (Z) is set when the result of the operation is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow (V) and carry (CY) flags are cleared.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) has an unspecified state after this instruction completes.

The number of cycles taken by the Memory/Register variant of this instruction depends on the operands:

1 Both operands are registers.
2 The source operand is an offset.
3 The destination operand is an offset.

The number of cycles taken by the Memory/Immediate variant of this instruction depends on the operands:

1 The destination operand is a register.
3 The destination operand is an offset.

CPU Control

Prefixes

NEC Intel Name Operation
BUSLOCK LOCK Bus Lock Execute instruction with full control of the bus

Instructions

NEC Intel Z S V CY P AC Name Operation
BR JMP - - - - - - Branch Unconditional jump
BRK INT, INT3 - - - - - - Break Raise exception vector
BRKV INTO - - - - - - Break if Overflow If V = 1, raise exception 4
CALL CALL - - - - - - Call Call subroutine
CHKIND BOUND - - - - - - Check Index Array bounds check
CLR1 CLC, CLD - - - * - - Clear Bit dest = 0
DI CLI - - - - - - Disable Interrupt IE = 0
DISPOSE LEAVE - - - - - - Dispose a Stack Frame SP = BP, pop BP
EI STI - - - - - - Enable Interrupt IE = 1
HALT HLT - - - - - - Halt Wait for interrupt
NOT1 CMC - - - - - Not Bit CY = NOT CY
POLL WAIT - - - - - - Poll and Wait No operation.
PREPARE ENTER - - - - - - Prepare New Stack Frame See instruction for details.
RET RET - - - - - - Return from Procedure Return from subroutine
RETI IRET * * * * * * Return from Interrupt Return from exception handling
SET1 STC, STD - - - * - - Set Bit dest = 1

BUSLOCK - Bus Lock Prefix

NEC Intel Name Operation
BUSLOCK LOCK Bus Lock Prefix Execute instruction with full control of the bus

This is a prefix that applies to all instructions.

When the instruction prefixed by BUSLOCK executes, the CPU has full control of the memory bus until the instruction completes. Any other component that attempts to access the bus during this time will be stalled, and any interrupts will be held, until the lock is released.

Code Cycles
11110000 1

If the prefixed instruction is a block instruction that is also prefixed by REP, the bus will remain locked until all repetitions are fully processed.

BR - Branch

NEC Intel Z S V CY P AC Name Operation
BR JMP - - - - - - Branch Unconditional jump

Unconditionally redirects the program to another address:

If 32-bit:
PS = Destination PS
PC = Destination PC

Code Cycles Operands
11101001 4 16-bit Displacement
11101010 7 32-bit Immediate
11101011 4 8-bit Displacement
1111111- aa100mmm 4-5 16-bit Memory
1111111- aa101mmm 10 32-bit Memory

Displacement values are signed values that appear as additional bytes of program code and are added to PC to produce the destination offset. A 16-bit displacement value is stored with the low byte first. The value of PC to which the displacement is added is the offset of the first byte of the instruction following the BR instruction.

The 32-bit variants of this instruction load 4 consecutive bytes as the destination. The first two bytes are the new value for PC (low byte first), and the second two bytes are the new value for PS (low byte first).

For the 32-bit Immediate variant of this instruction, the 4 destination bytes are present as additional bytes of program code.

If the 32-bit Memory variant of this instruction specifies a register for the memory operand, the segment and offset of the branch are undefined.

The number of cycles taken by the 16-bit Memory variant of this instruction depends on the operand:

4 The operand is a register.
5 The operand is an offset.

There is no distinction in assembly notation to differentiate between the in-segment and out-of-segment variants of this instruction. It is intended that the assembler selects the appropriate variant depending on how the procedure's scope is defined (such as "near" for in-segment or "far" for out-of-segment). Common assemblers have introduced distinct mnemonics to denote which instruction is being used:

NASM AT&T
JMP NEAR jmp In segment
JMP FAR ljmp Out of segment

BRK - Break

NEC Intel Z S V CY P AC Name Operation
BRK INT, INT3 - - - - - - Break Raise exception vector

Raises an exception with the vector given by the operand.

Code Cycles Operands
11001100 9 3 [note]
11001101 9-10 Immediate

[note] The Intel notation for the 3 variant of this instruction has the mnemonic INT3 and has zero operands.

The immediate value is 8-bit and unsigned.

The number of cycles taken by the Immediate variant of this instruction depends on the operand:

9 The vector is 3.
10 The vector is not 3.

Editor's Note: On other 8086-style CPUs, the single-byte BRK 3 instruction is given special significance: it can apply in situations where the operand variant can't, and can process the handler with an elevated privilege mode. It is intended for software debugging.

BRKV - Break if Overflow

NEC Intel Z S V CY P AC Name Operation
BRKV INTO - - - - - - Break if Overflow If V = 1, raise exception 4

If the overflow flag (V) is set, raises an exception with vector 4.

Code Cycles Operands
11001110 6-13 None

The number of cycles taken by BRKV depends on V:

6 V is clear.
13 V is set.

CALL - Call

NEC Intel Z S V CY P AC Name Operation
CALL CALL - - - - - - Call Call subroutine

Calls a subroutine, saving the return address on the stack according to the following algorithm:

If 32-bit:
Push PS
PS = Destination PS
Push PC
PC = Destination PC

The value of PC to which the subroutine will return is the offset of the first byte of the instruction following the CALL instruction.

Code Cycles Operands
10011010 10 32-bit Immediate
11101000 5 16-bit Displacement
1111111- aa010mmm 5-6 16-bit Memory
1111111- aa011mmm 12 32-bit Memory

The 32-bit variants of this instruction load 4 consecutive bytes as the destination. The first two bytes are the new value for PC (low byte first), and the second two bytes are the new value for PS (low byte first).

For the 32-bit Immediate variant of this instruction, the 4 destination bytes are present as additional bytes of program code.

For the 16-bit Displacement variant of this instruction, the displacement value is a signed value that appears as additional bytes of program code and are added to PC to produce the destination offset. It is stored with the low byte first. The value of PC to which the displacement is added is the offset of the first byte of the instruction following the CALL instruction.

If the 32-bit Memory variant of this instruction specifies a register for the memory operand, the segment and offset of the call are undefined.

The number of cycles taken by the 16-bit Memory variant of this instruction depends on the operand:

5 The operand is a register.
6 The operand is an offset.

There is no distinction in assembly notation to differentiate between the in-segment and out-of-segment variants of this instruction. It is intended that the assembler selects the appropriate variant depending on how the procedure's scope is defined (such as "near" for in-segment or "far" for out-of-segment). Common assemblers have introduced distinct mnemonics to denote which instruction is being used:

NASM AT&T
CALL NEAR call In segment
CALL FAR lcall Out of segment

CHKIND - Check Index

NEC Intel Z S V CY P AC Name Operation
CHKIND BOUND - - - - - - Check Index Array bounds check

Performs an array bounds check by loading two consecutive 16-bit values from the memory operand (low byte first). The first value is the lower bound of the array and the second value is the upper bound of the array. If the value in the register operand is not greater than or equal to the lower bound and less than or equal to the upper bound, an exception is raised with vector 5.

Code Cycles Operands
01100010 aarrrmmm 13-20 Register, Memory

This operation performs signed comparisons.

If a register is specified for the memory operand, the offset accessed in memory will be undefined.

The default segment register for this instruction is DS0. The segment register to use can be selected with a segment override prefix.

The number of cycles taken by this instruction depends on whether or not an exception is raised:

13 An exception is not raised.
20 An exception is raised.

CLR1 - Clear Bit

NEC Intel Z S V CY P AC Name Operation
CLR1 CLC, CLD - - - * - - Clear Bit dest = 0

Clears the bit specified by the operand.

Code Cycles Operands
11111000 4 CY [note 1]
11111100 4 DIR [note 2]

[note 1] The Intel notation for the CY variant of this instruction has the mnemonic CLC and has zero operands.
[note 2] The Intel notation for the DIR variant of this instruction has the mnemonic CLD and has zero operands.

This instruction will only modify the flag in PSW specified by its operand.

DI - Disable Interrupt

NEC Intel Z S V CY P AC Name Operation
DI CLI - - - - - - Disable Interrupt IE = 0

The interrupt enable flag (IE) is cleared.

Code Cycles Operands
11111010 4 None

DISPOSE - Dispose a Stack Frame

NEC Intel Z S V CY P AC Name Operation
DISPOSE LEAVE - - - - - - Dispose a Stack Frame SP = BP, pop BP

Stores the value in BP into SP, then pops BP from the new stack location.

This instruction is the counterpart to PREPARE.

Code Cycles Operands
11001001 2 None

EI - Enable Interrupt

NEC Intel Z S V CY P AC Name Operation
EI STI - - - - - - Enable Interrupt IE = 1

The interrupt enable flag (IE) is set.

Code Cycles Operands
11111011 4 None

If IE was clear prior to executing this instruction, then prior to executing the following instruction, interrupts will not be accepted.

HALT - Halt

NEC Intel Z S V CY P AC Name Operation
HALT HLT - - - - - - Halt Wait for interrupt

Suspends the CPU until an interrupt is requested. After an interrupt is requested (which may result in a handler routine ending with RETI), execution will continue at the instruction following the HALT instruction.

Code Cycles Operands
11110100 9 None

HALT will always complete when an interrupt is requested. If the IE flag in PSW is clear, exception processing will be prevented, but the program will nonetheless still resume.

NOT1 - Not Bit

NEC Intel Z S V CY P AC Name Operation
NOT1 CMC - - - - - Not Bit CY = NOT CY

Inverts the carry flag (CY).

Code Cycles Operands
11110101 4 CY

POLL - Poll and Wait

NEC Intel Z S V CY P AC Name Operation
POLL WAIT - - - - - - Poll and Wait No operation.

Suspends the CPU pending any coprocessor operations. V30MZ has no coprocessor, so this instruction has no useful function other than to spend CPU cycles.

Code Cycles Operands
10011011 10 None

Editor's Note: The V Series specification cautions against using this instruction with BUSLOCK. No problematic operations have been observed on V30MZ.

PREPARE - Prepare New Stack Frame

NEC Intel Z S V CY P AC Name Operation
PREPARE ENTER - - - - - - Prepare New Stack Frame See below.

This instruction contains an 8-bit immediate operand of which only the lowest 5 bits are significant. This section refers to the operand as "the 5-bit immediate value" and "imm5".

Prepares a lexical stack frame by performing the following algorithm:

Push BP
temp = SP
If imm5 > 0:
Perform the following (imm5 - 1) times:
BP = BP - 2
Push [BP] (read a word value)
Push temp
BP = temp
SP = SP - imm16

This instruction is the counterpart to DISPOSE.

Code Cycles Operands
11001000 8+ 16-bit Immediate, 8-bit Immediate

The opcode byte is followed by the 16-bit immediate operand's bytes, which are in turn followed by the 8-bit immediate operand's byte.

This instruction's operands are unsigned.

The number of cycles taken by this instruction depends on the 5-bit immediate value:

8 The 5-bit immediate value is 0.
14 The 5-bit immediate value is 1.
15 + 4 * imm5 The 5-bit immediate value is greater than 1.

RET - Return from Procedure

NEC Intel Z S V CY P AC Name Operation
RET RET - - - - - - Return from Procedure Return from subroutine

Returns from a subroutine, restoring PC (and PS where applicable) to the location when the subroutine was first called, plus some number of additional stack bytes, according to the following algorithm:

Pop PC
If out of segment:
Pop PS
SP = SP + dest

Code Cycles Scope Operands
11000010 6 In segment Immediate
11000011 6 In segment None
11001010 9 Out of segment Immediate
11001011 8 Out of segment None

The immediate value is 16-bit and is added to SP after restoring PC/PS. This allows function input arguments to be automatically released from the stack.

There is no distinction in assembly notation to differentiate between the in-segment and out-of-segment variants of this instruction. It is intended that the assembler selects the appropriate variant depending on how the procedure's scope is defined (such as "near" for in-segment or "far" for out-of-segment). Common assemblers have introduced distinct mnemonics to denote which instruction is being used:

NASM AT&T
RETN ret In segment
RETF lret Out of segment

RETI - Return from Interrupt

NEC Intel Z S V CY P AC Name Operation
RETI IRET * * * * * * Return from Interrupt Return from exception handling

Returns from an exception or interrupt handler. The program will resume from wherever it left off: either the instruction following the instruction that raised the exception, or the instruction that would have been executed had an interrupt not occurred.

Performs the following algorithm:

Pop PC
Pop PS
Pop PSW

Code Cycles Operands
11001111 10 None

The status flags in PSW are restored from the stack. If this instruction causes the interrupt enable flag (IE) to transition from clear to set, then prior to executing the following instruction, interrupts will not be accepted.

SET1 - Set Bit

NEC Intel Z S V CY P AC Name Operation
SET1 STC, STD - - - * - - Set Bit dest = 1

Sets the bit specified by the operand.

Code Cycles Operands
11111001 4 CY [note 1]
11111101 4 DIR [note 2]

[note 1] The Intel notation for the CY variant of this instruction has the mnemonic STC and has zero operands.
[note 2] The Intel notation for the DIR variant of this instruction has the mnemonic STD and has zero operands.

This instruction will only modify the flag in PSW specified by its operand.


Branch

These branch instructions conditionally redirect the program to another location. PC is modified if the condition is met, or the program will continue to the next instruction if the condition is not met. The condition typically tests various combinations of status flags in PSW.

Branch instructions are 2 bytes in size: the first byte is the opcode, and the second byte is a signed displacement offset that is added to PC if the condition is true. The value of PC to which the displacement is added is the offset of the first byte of the instruction following the branch instruction.

The number of cycles taken by branch instructions depends on whether or not the condition is true. If the branch is not taken, the number of cycles is given in the lists below. If the branch is taken, add 3 to that number of cycles.

Instructions

Opcode NEC Intel Branch if ... Condition Cycles Note
01110010 BC, BL JC, JB, JNAE Carry, Lower if CY = 1 1+ Unsigned
11100011 BCWZ JCXZ CW Equals Zero if CW = 0 1+
01110100 BE, BZ JE, JZ Equal, Zero if Z = 1 1+
01111101 BGE JGE, JNL Greater Than or Equal if (S XOR V) = 0 1+ Signed
01111111 BGT JG, JNLE Greater Than if ((S XOR V) OR Z) = 0 1+ Signed
01110111 BH JA, JNBE Higher if (CY OR Z) = 0 1+ Unsigned
01111110 BLE JLE, JNG Less Than or Equal if ((S XOR V) OR Z) = 1 1+ Signed
01111100 BLT JL, JNGE Less Than if (S XOR V) = 1 1+ Signed
01111000 BN JS Negative if S = 1 1+
01110011 BNC, BNL JNC, JAE, JNB Not Carry, Not Lower if CY = 0 1+ Unsigned
01110101 BNE, BNZ JNE, JNZ Not Equal, Not Zero if Z = 0 1+
01110110 BNH JBE, JNA Not Higher if (CY OR Z) = 1 1+ Unsigned
01110001 BNV JNO Not Overflow if V = 0 1+
01111001 BP JNS Positive if S = 0 1+
01111010 BPE JPE Parity Even if P = 1 1+
01111011 BPO JNP, JPO Parity Odd if P = 0 1+
01110000 BV JO Overflow if V = 1 1+

Decrementing Instructions

These instructions decrement CW by 1 before testing the condition. In this list, the decrement operation is omitted.

Opcode NEC Intel Decrement and Branch if ... Condition Cycles
11100010 DBNZ LOOP Not Zero if CW ≠ 0 2+
11100001 DBNZE LOOPE, LOOPZ Not Zero and Equal if (CW ≠ 0) AND (Z = 1) 3+
11100000 DBNZNE LOOPNE, LOOPNZ Not Zero and Not Equal if (CW ≠ 0) AND (Z = 0) 3+

Block

Block instructions are designed to be executed repeatedly by being used in conjunction with the REP prefix. They share a common behavior in that they will increment or decrement the IX and IY registers as applicable, allowing multiple units of memory to be processed with one instruction.

IX and IY are only updated if they are used in an operation. The amount by which they are modified is 1 for 8-bit operations and 2 for 16-bit operations. The sign of the modification depends on the direction flag (DIR): positive if DIR is clear, or negative if DIR is set. In the list below, this operation is omitted.

Mechanically, block instructions do not have any operands: they access specific registers as part of their normal operation. However, block instructions in assembly are still presented with operands describing the data being accessed. These operands are written in the following way:

The destination operand is always on the left.
IX and IY operands specify either "BYTE PTR" for 8-bit or "WORD PTR" for 16-bit, optionally specify a segment register with a colon, then finally the register name is written in [] square brackets.
If an accumulator is involved, it is not written as an operand.
If DW is involved, it is written as only the register name, without any brackets.

Some block instructions have multiple mneomincs. The extra mnemonics specify the size of the operation and are written with zero operands. If one of these alternate mnemonics is used, there is no notation for specifying a segment override.

For examples of how any given block instruction may be written, see the documentation for each individual instruction.

Prefixes

NEC Intel Name Operation
REP REP Repeat Repeat instruction according to CW and Z.

Instructions

NEC Intel Z S V CY P AC Name Operation
CMPBK CMPS Compare Block (discard) = [IX] - [IY]
CMPM SCAS Compare Multiple (discard) = acc - [IY]
INM INS - - - - - - Input Multiple (memory) [IY] = (I/O) [DW]
LDM LODS - - - - - - Load Multiple acc = [IX]
MOVBK MOVS - - - - - - Move Block [IY] = [IX]
OUTM OUTS - - - - - - Output Multiple (I/O) [DW] = (memory) [IX]
STM STOS - - - - - - Store Multiple [IY] = acc

REP - Repeat

NEC Intel Name Operation
REP REP Repeat Repeat instruction according to CW and Z.

This is a prefix that applies to block instructions. Performs the following algorithm:

While CW ≠ 0:
Execute the instruction
CW = CW - 1
If the instruction is CMPBK or CMPM and the condition is false:
× Exit the loop
Continue with next loop iteration
Proceed to the next instruction

Code Cycles
1111001Z 5+

If the prefixed instruction is not a block instruction, REP has no effect. If the prefixed instruction is not CMPBK or CMPM, it will always be repeated until CW becomes zero.

For CMPBK and CMPM, Z specifies the state of the zero flag (Z) in PSW in order for the repetition to occur. The condition is true when the bit in the opcode and the bit in PSW match.

The zero flag is not modified by the decrement operation performed by this prefix: it can only change if the prefixed instruction modifies it.

This prefix and its field are used with the following mnemonics:

NEC Intel Name Condition
REP REP Repeat if Z = 1
REPE REPE Repeat while Equal if Z = 1
REPNE REPNE Repeat while Not Equal if Z = 0
REPNZ REPNZ Repeat while Not Zero if Z = 0
REPZ REPZ Repeat while Zero if Z = 1

The number of cycles taken by an instruction with this prefix differs from the number of cycles taken by a stanalone execution of that instruction. There are always 5 cycles consumed by the prefix itself, as well as an additional number of cycles for each repetition depending on the instruction being repeated:

NEC Intel Name Cycles Note
CMPBK CMPS Compare Block 5 + 9× Z = 0
CMPBK CMPS Compare Block 5 + 10× Z = 1
CMPM SCAS Compare Multiple 5 + 9×
INM INS Input Multiple 5 + 6×
LDM LODS Load Multiple 5 + 6×
MOVBK MOVS Move Block 5 + 7×
OUTM OUTS Output Multiple 5 + 6×
STM STOS Store Multiple 5 + 6×

CMPBK - Compare Block

NEC Intel Z S V CY P AC Name Operation
CMPBK CMPS Compare Block (discard) = [IX] - [IY]

Takes the value in memory pointed to by IX and subtracts the value in memory pointed to by IY, updates the status flags accordingly, discards the result, and updates IX and IY according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
1010011W 6 [IX], [IY]

This instruction's operands are implicit and may be written in other ways:

"DS1:" may be included in the "[IY]" operand.
The mnemonic may be used to denote the size of the operation: "CMPBKB" for byte and "CMPBKW" for word.
If the mnemonic denotes the size of the operation, the operands may be omitted.

IX and IY are modified after accessing a value. If the DIR flag is clear, the registers are incremented, and if the DIR flag is set, the registers are decremented. The amount by which the registers are modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.

The zero flag (Z) is set when the result of the subtraction is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the operands of the subtraction have opposite signs and the left operand and result have opposite signs, or is cleared otherwise.

The carry flag (CY) is set when the unsigned difference passes zero, or is cleared otherwise.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set when the unsigned difference of the lowest 4 bits of the operands passes zero, or is cleared otherwise.

CMPM - Compare Multiple

NEC Intel Z S V CY P AC Name Operation
CMPM SCAS Compare Multiple (discard) = acc - [IY]

Takes the value in AL (if 8-bit) or AW (if 16-bit) and subtracts the value in memory pointed to by IY, updates the status flags accordingly, discards the result, and updates IY according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
1010111W 4 [IY]

This instruction's operands are implicit and may be written in other ways:

An accumulator operand may be present as the first operand.
"DS1:" may be included in the "[IY]" operand.
The mnemonic may be used to denote the size of the operation: "CMPMB" for byte and "CMPMW" for word.
If the mnemonic denotes the size of the operation, the operands may be omitted.

IY is modified after accessing a value. If the DIR flag is clear, IY is incremented, and if the DIR flag is set, IY is decremented. The amount by which IY is modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.

The zero flag (Z) is set when the result of the subtraction is zero, or is cleared otherwise.

The sign flag (S) is set when the highest bit of the result is set, or is cleared otherwise.

The overflow flag (V) is set when the subtraction results in signed wrap-around, or is cleared otherwise. For example, overflow will be set when subtracting a positive number from a negative number produces a positive result.

The carry flag (CY) is set when the subtraction results in unsigned wrap-around, or is cleared otherwise. For example, carry will be set when subtracting a number from a lesser number.

The parity flag (P) is set when the number of set bits in the lower 8 bits of the result is even, or is cleared otherwise.

The auxiliary carry flag (AC) is set or cleared through the same conditions as CY, but applies to the lowest 4 bits of the operation.

INM - Input Multiple

NEC Intel Z S V CY P AC Name Operation
INM INS - - - - - - Input Multiple (memory) [IY] = (I/O) [DW]

Inputs the value from the I/O port pointed to by DW, stores the it in the memory pointed to by IY, and updates IY according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
0110110W 6 [IY], DW

This instruction's operands are implicit and may be written in other ways:

"DS1:" may be included in the "[IY]" operand.
The mnemonic may be used to denote the size of the operation: "INMB" for byte and "INMW" for word.

IY is modified after accessing a value. If the DIR flag is clear, IY is incremented, and if the DIR flag is set, IY is decremented. The amount by which IY is modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.

LDM - Load Multiple

NEC Intel Z S V CY P AC Name Operation
LDM LODS - - - - - - Load Multiple acc = [IX]

Loads the value in the memory pointed to by IX, stores the value into AL (if 8-bit) or AW (if 16-bit), and updates IX according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
1010110W 3 [IX]

This instruction's operands are implicit and may be written in other ways:

An accumulator operand may be present as the first operand.
The mnemonic may be used to denote the size of the operation: "LDMB" for byte and "LDMW" for word.
If the mnemonic denotes the size of the operation, the operands may be omitted.

IX is modified after accessing a value. If the DIR flag is clear, IX is incremented, and if the DIR flag is set, IX is decremented. The amount by which IX is modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.

MOVBK - Move Block

NEC Intel Z S V CY P AC Name Operation
MOVBK MOVS - - - - - - Move Block [IY] = [IX]

Loads the value in the memory pointed to by IX, stores it into the memory pointed to by IY, and updates IX and IY according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
1010010W 5 [IY], [IX]

This instruction's operands are implicit and may be written in other ways:

"DS1:" may be included in the "[IY]" operand.
The mnemonic may be used to denote the size of the operation: "MOVBKB" for byte and "MOVBKW" for word.
If the mnemonic denotes the size of the operation, the operands may be omitted.

IX and IY are modified after accessing a value. If the DIR flag is clear, the registers are incremented, and if the DIR flag is set, the register are decremented. The amount by which the registers are modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.

OUTM - Output Multiple

NEC Intel Z S V CY P AC Name Operation
OUTM OUTS - - - - - - Output Multiple (I/O) [DW] = (memory) [IX]

Loads the value in the memory pointed to by IX, outputs it to the I/O port pointed to by DW, and updates IX according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
0110111W 7 DW, [IX]

This instruction's operands are implicit and may be written in other ways:

The mnemonic may be used to denote the size of the operation: "OUTMB" for byte and "OUTMW" for word.

IX is modified after accessing a value. If the DIR flag is clear, IX is incremented, and if the DIR flag is set, IX is decremented. The amount by which IX is modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.

STM - Store Multiple

NEC Intel Z S V CY P AC Name Operation
STM STOS - - - - - - Load Multiple [IY] = acc

Stores the value in AL (if 8-bit) or AW (if 16-bit) into the memory pointed to by IY, and updates IY according to the size of the operation and the direction flag (DIR).

This instruction was designed to be used in conjunction with REP, but is valid as a standalone operation.

Code Cycles Operands
1010101W 3 [IY]

This instruction's operands are implicit and may be written in other ways:

An accumulator operand may be present as a second operand.
"DS1:" may be included in the "[IY]" operand.
The mnemonic may be used to denote the size of the operation: "STMB" for byte and "STMW" for word.
If the mnemonic denotes the size of the operation, the operands may be omitted.

IY is modified after accessing a value. If the DIR flag is clear, IY is incremented, and if the DIR flag is set, IY is decremented. The amount by which IY is modified depends on the size of the operation: 1 when 8-bit and 2 when 16-bit.


Segment Override

Whenever memory is accessed, a segment register is used in the calculation of the physical address. The default segment register to use is implicit depending on context, and in many cases can be explicitly selected using a one-byte segment override prefix that immediately precedes the program code of the instruction accessing memory.

The following are the various memory-access scenarios and how they interact with segment registers:

Default Override Scenario
DS0 Yes 16-bit direct memory
DS0 Yes Memory operand, not BP base
SS Yes Memory operand, BP base
DS0 Yes Block instruction, IX value
DS1 No Block instruction, IY value
DS0 Yes CHKIND instruction
DS0 Yes TRANS instruction
PS No Instruction fetch
SS No Stack operation

Prefixes

Code NEC Intel Cycles
00111110 DS0: DS: 1
00100110 DS1: ES: 1
00101110 PS: CS: 1
00110110 SS: SS: 1

When a segment override prefix is used, the corresponding memory operation will use the segment register specified by the prefix instead of the operation's default segment register.


Opcode Map

Opcode Mnemonic Operands
00000000 ADD Memory (byte), Register (byte)
00000001 ADD Memory (word), Register (word)
00000010 ADD Register (byte), Memory (byte)
00000011 ADD Register (word), Memory (word)
00000100 ADD AL, Immediate (byte)
00000101 ADD AW, Immediate (word)
00000110 PUSH DS1
00000111 POP DS1
00001000 OR Memory (byte), Register (byte)
00001001 OR Memory (word), Register (word)
00001010 OR Register (byte), Memory (byte)
00001011 OR Register (word), Memory (word)
00001100 OR AL, Immediate (byte)
00001101 OR AW, Immediate (word)
00001110 PUSH PS
00001111 Invalid [note 1]
00010000 ADDC Memory (byte), Register (byte)
00010001 ADDC Memory (word), Register (word)
00010010 ADDC Register (byte), Memory (byte)
00010011 ADDC Register (word), Memory (word)
00010100 ADDC AL, Immediate (byte)
00010101 ADDC AW, Immediate (word)
00010110 PUSH SS
00010111 POP SS
00011000 SUBC Memory (byte), Register (byte)
00011001 SUBC Memory (word), Register (word)
00011010 SUBC Register (byte), Memory (byte)
00011011 SUBC Register (word), Memory (word)
00011100 SUBC AL, Immediate (byte)
00011101 SUBC AW, Immediate (word)
00011110 PUSH DS0
00011111 POP DS0
00100000 AND Memory (byte), Register (byte)
00100001 AND Memory (word), Register (word)
00100010 AND Register (byte), Memory (byte)
00100011 AND Register (word), Memory (word)
00100100 AND AL, Immediate (byte)
00100101 AND AW, Immediate (word)
00100110 DS1:
00100111 ADJ4A
00101000 SUB Memory (byte), Register (byte)
00101001 SUB Memory (word), Register (word)
00101010 SUB Register (byte), Memory (byte)
00101011 SUB Register (word), Memory (word)
00101100 SUB AL, Immediate (byte)
00101101 SUB AW, Immediate (word)
00101110 PS:
00101111 ADJ4S
00110000 XOR Memory (byte), Register (byte)
00110001 XOR Memory (word), Register (word)
00110010 XOR Register (byte), Memory (byte)
00110011 XOR Register (word), Memory (word)
00110100 XOR AL, Immediate (byte)
00110101 XOR AW, Immediate (word)
00110110 SS:
00110111 ADJBA
00111000 CMP Memory (byte), Register (byte)
00111001 CMP Memory (word), Register (word)
00111010 CMP Register (byte), Memory (byte)
00111011 CMP Register (word), Memory (word)
00111100 CMP AL, Immediate (byte)
00111101 CMP AW, Immediate (word)
00111110 DS0:
00111111 ADJBS
01000000 INC AW
01000001 INC CW
01000010 INC DW
01000011 INC BW
01000100 INC SP
01000101 INC BP
01000110 INC IX
01000111 INC IY
01001000 DEC AW
01001001 DEC CW
01001010 DEC DW
01001011 DEC BW
01001100 DEC SP
01001101 DEC BP
01001110 DEC IX
01001111 DEC IY
01010000 PUSH AW
01010001 PUSH CW
01010010 PUSH DW
01010011 PUSH BW
01010100 PUSH SP
01010101 PUSH BP
01010110 PUSH IX
01010111 PUSH IY
01011000 POP AW
01011001 POP CW
01011010 POP DW
01011011 POP BW
01011100 POP SP
01011101 POP BP
01011110 POP IX
01011111 POP IY
01100000 PUSH R
01100001 POP R
01100010 CHKIND Register (word), Memory (double word)
01100011 Invalid
01100100 Invalid [note 2]
01100101 Invalid [note 2]
01100110 Invalid [note 3]
01100111 Invalid [note 3]
01101000 PUSH Immediate (word)
01101001 MUL Register (word), Memory (word), Immediate (word)
01101010 PUSH Immediate (byte, sign-extended)
01101011 MUL Register (word), Memory (word), Immediate (byte, sign-extended)
01101100 INMB [IY], DW
01101101 INMW [IY], DW
01101110 OUTMB DW, [IX]
01101111 OUTMW DW, [IX]
01110000 BV Displacement (byte, sign-extended)
01110001 BNV Displacement (byte, sign-extended)
01110010 BC, BL Displacement (byte, sign-extended)
01110011 BNC, BNL Displacement (byte, sign-extended)
01110100 BE, BZ Displacement (byte, sign-extended)
01110101 BNE, BNZ Displacement (byte, sign-extended)
01110110 BNH Displacement (byte, sign-extended)
01110111 BH Displacement (byte, sign-extended)
01111000 BN Displacement (byte, sign-extended)
01111001 BP Displacement (byte, sign-extended)
01111010 BPE Displacement (byte, sign-extended)
01111011 BPO Displacement (byte, sign-extended)
01111100 BLT Displacement (byte, sign-extended)
01111101 BGE Displacement (byte, sign-extended)
01111110 BLE Displacement (byte, sign-extended)
01111111 BGT Displacement (byte, sign-extended)
10000000 Immediate group: see below Memory (byte), Immediate (byte)
10000001 Immediate group: see below Memory (word), Immediate (word)
10000010 Immediate group: see below Memory (byte), Immediate (byte)
10000011 Immediate group: see below Memory (word), Immediate (byte, sign-extended)
10000100 TEST Memory (byte), Register (byte)
10000101 TEST Memory (word), Register (word)
10000110 XCH Memory (byte), Register (byte)
10000111 XCH Memory (word), Register (word)
10001000 MOV Memory (byte), Register (byte)
10001001 MOV Memory (word), Register (word)
10001010 MOV Register (byte), Memory (byte)
10001011 MOV Register (word), Memory (word)
10001100 MOV Memory (word), Segment Register
10001011 LDEA Register (word), Memory (word)
10001110 MOV Segment Register, Memory (word)
10001111 POP Memory (word)
10010000 NOP
10010001 XCH AW, CW
10010010 XCH AW, DW
10010011 XCH AW, BW
10010100 XCH AW, SP
10010101 XCH AW, BP
10010110 XCH AW, IX
10010111 XCH AW, IY
10011000 CVTBW
10011001 CVTWL
10011010 CALL Immediate (double word)
10011011 POLL
10011100 PUSH PSW
10011101 POP PSW
10011110 MOV PSW, AH
10011111 MOV AH, PSW
10100000 MOV AL, Direct Memory (byte)
10100001 MOV AW, Direct Memory (word)
10100010 MOV Direct Memory (byte), AL
10100011 MOV Direct Memory (word), AW
10100100 MOVBKB [IY], [IX]
10100101 MOVBKW [IY], [IX]
10100110 CMPBKB [IX], [IY]
10100111 CMPBKW [IX], [IY]
10101000 TEST AL, Immediate (byte)
10101001 TEST AW, Immediate (word)
10101010 STMB [IY]
10101011 STMW [IY]
10101100 LDMB [IX]
10101101 LDMW [IX]
10101110 CMPMB [IY]
10101111 CMPMW [IY]
10110000 MOV Register (byte), Immediate (byte)
10110001 MOV Register (byte), Immediate (byte)
10110010 MOV Register (byte), Immediate (byte)
10110011 MOV Register (byte), Immediate (byte)
10110100 MOV Register (byte), Immediate (byte)
10110101 MOV Register (byte), Immediate (byte)
10110110 MOV Register (byte), Immediate (byte)
10110111 MOV Register (byte), Immediate (byte)
10111000 MOV Register (word), Immediate (word)
10111001 MOV Register (word), Immediate (word)
10111010 MOV Register (word), Immediate (word)
10111011 MOV Register (word), Immediate (word)
10111100 MOV Register (word), Immediate (word)
10111101 MOV Register (word), Immediate (word)
10111110 MOV Register (word), Immediate (word)
10111111 MOV Register (word), Immediate (word)
11000000 Shift group: see below Memory (byte), Immediate (byte)
11000001 Shift group: see below Memory (word), Immediate (byte)
11000010 RETN Immediate (word)
11000011 RETN
11000100 MOV DS1, Register (word), Memory (double word)
11000101 MOV DS0, Register (word), Memory (double word)
11000110 MOV Memory (byte), Immediate (byte)
11000111 MOV Memory (word), Immediate (word)
11001000 PREPARE Immediate (word), Immediate (byte)
11001001 DISPOSE
11001010 RETF Immediate (word)
11001011 RETF
11001100 BRK 3
11001101 BRK Immediate (byte)
11001110 BRKV
11001111 RETI
11010000 Shift group: see below Memory (byte), 1
11010001 Shift group: see below Memory (word), 1
11010010 Shift group: see below Memory (byte), CL
11010011 Shift group: see below Memory (word), CL
11010100 CVTBD Immediate (byte)
11010101 CVTDB Immediate (byte)
11010110 SALC
11010111 TRANS [BW]
11011000 FPO1 Memory
11011001 FPO1 Memory
11011010 FPO1 Memory
11011011 FPO1 Memory
11011100 FPO1 Memory
11011101 FPO1 Memory
11011110 FPO1 Memory
11011111 FPO1 Memory
11100000 DBNZNE Displacement (byte, sign-extended)
11100001 DBNZE Displacement (byte, sign-extended)
11100010 DBNZ Displacement (byte, sign-extended)
11100011 BCWZ Displacement (byte, sign-extended)
11100100 IN AL, Immediate (byte)
11100101 IN AW, Immediate (byte)
11100110 OUT Immediate (byte), AL
11100111 OUT Immediate (byte), AW
11101000 CALL Displacement (word)
11101001 BR Displacement (word)
11101010 BR Immediate (double word)
11101011 BR Displacement (byte, sign-extended)
11101100 IN AL, DW
11101101 IN AW, DW
11101110 OUT DW, AL
11101111 OUT DW, AW
11110000 BUSLOCK
11110001 Invalid
11110010 REPNE, REPNZ
11110011 REP, REPE, REPZ
11110100 HALT
11110101 NOT1 CY
11110110 Group 1: see below * (byte)
11110111 Group 1: see below * (word)
11111000 CLR1 CY
11111001 SET1 CY
11111010 DI
11111011 EI
11111100 CLR1 DIR
11111101 SET1 DIR
11111110 Group 2: see below * (byte)
11111111 Group 2: see below * (word)

[note 1] On other V Series CPUs, opcode 00001111 is the first byte of a "group 3" set of instructions. None of the instructions in group 3 are available on V30MZ, and this opcode is undefined.
[note 2] On other V Series CPUs, opcodes 01100100 and 01100101 are for REPNC and REPC prefixes respectively that control repetition of block instructions depending on the state of the CY flag. On V30MZ, they are treated as regular undefined opcodes and do not function as prefixes.
[note 3] On other V Series CPUs, opcodes 01100110 and 01100111 belong to an FPO2 instruction that provides additional commands to a floating-point coprocessor. On V30MZ, they are treated as regular undefined opcodes and do not have a memory operand.

Instructions in the immediate group always have a memory operand. Bits 3-5 of the memory operand byte contain a sub-opcode that identifies the operation of an instruction in the immediate group. The operands for instructions in the immediate group are shown in the list above.

Sub-Opcode Name Mnemonic
000 Add ADD
001 Or OR
010 Add with Carry ADDC
011 Subtract with Carry SUBC
100 And AND
101 Subtract SUB
110 Exclusive Or XOR
111 Compare CMP

Instructions in the shift group always have a memory operand. Bits 3-5 of the memory operand byte contain a sub-opcode that identifies the operation of an instruction in the shift group. The operands for instructions in the shift group are shown in the list above.

Sub-Opcode Name Mnemonic
000 Rotate Left ROL
001 Rotate Right ROR
010 Rotate Left with Carry ROLC
011 Rotate Right with Carry RORC
100 Shift Left SHL
101 Shift Right SHR
110 - Invalid, has a side effect [note]
111 Shift Right Arithmetic SHRA

[note] Even though sub-opcode 110 is undefined and has no intended operation, it still has a memory operand and produces a result of zero, which is stored to either the memory offset or the register as applicable.

Instructions in group 1 always have a memory operand. Bits 3-5 of the memory operand byte contain a sub-opcode that identifies the operation of an instruction in group 1. The operands for instructions in group 1 depend on the operation, given in the list below. The size of the operands depends on bit 0 of the opcode byte and is given in the list above.

Sub-Opcode Name Mnemonic Operands
000 Test TEST Memory (byte or word), Immediate (byte or word)
001 - Invalid Memory [note]
010 Not NOT Memory (byte or word)
011 Negate NEG Memory (byte or word)
100 Multiply Unsigned MULU Memory (byte or word)
101 Multiply Signed MUL Memory (byte or word)
110 Divide Unsigned DIVU Memory (byte or word)
111 Divide Signed DIV Memory (byte or word)

[note] Even though sub-opcode 001 is undefined and has no corresponding operation, it has a memory operand and any additional bytes of instruction code required by it are present. If the memory operand specifies an offset, no memory is actually accessed.

Instructions in group 2 always have a memory operand. Bits 3-5 of the memory operand byte contain a sub-opcode that identifies the operation of an instruction in group 2. The operands for instructions in group 2 depend on the operation, given in the list below. The size of the operands may depend on bit 0 of the opcode byte and, if so, is given in the list above.

Sub-Opcode Name Mnemonic Operands
000 Increment INC Memory (byte or word)
001 Decrement DEC Memory (byte or word)
010 Call CALL Memory (word)
011 Call CALL Memory (double word)
100 Branch BR Memory (word)
101 Branch BR Memory (double word)
110 Push PUSH Memory (word)
111 - Invalid Memory [note]

[note] Even though sub-opcode 111 is undefined and has no corresponding operation, it has a memory operand and any additional bytes of instruction code required by it are present. If the memory operand specifies an offset, no memory is actually accessed.


8086 Translation Map

V30MZ is largely similar to the Intel 8086, but many registers and instructions underwent name changes. The lists below contain the corresponding names for each processor.

V30MZ to 8086

Registers

ByteWordOtherFlags
V30MZ8086
AHAH
ALAL
BHBH
BLBL
CHCH
CLCL
DHDH
DLDL
V30MZ8086
AWAX
BPBP
BWBX
CWCX
DWDX
IXSI
IYDI
SPSP
V30MZ8086
DS0DS
DS1ES
PCIP
PSCS
PSWFLAGS
SSSS
V30MZ8086
ACAC
BRKT
CYCY
DIRD
IEI
PP
SS
VO
ZZ

Instructions

V30MZ8086
ADDADD
ADDCADC
ADJ4ADAA
ADJ4SDAS
ADJBAAAA
ADJBSAAS
ANDAND
BCJC
BCWZJCXZ
BEJE
BGEJGE
BGEJNL
BGTJG
BGTJNLE
BHJA
BHJNBE
BLJB
BLJNAE
BLEJLE
BLEJNG
BLTJL
BLTJNGE
BNJS
BNCJNC
BNEJNE
BNHJBE
BNHJNA
BNLJAE
V30MZ8086
BNLJNB
BNVJNO
BNZJNZ
BPJNS
BPEJPE
BPOJNP
BPOJPO
BRJMP
BRKINT
BRK 3INT3
BRKVINTO
BUSLOCKLOCK
BVJO
BZJZ
CALLCALL
CHKINDBOUND
CLR1 CYCLC
CLR1 DIRCLD
CMPCMP
CMPBKCMPS
CMPBKBCMPSB
CMPBKWCMPSW
CMPMSCAS
CMPMBSCASB
CMPMWSCASW
CVTBDAAM
CVTBWCBW
CVTDBAAD
V30MZ8086
CVTWLCWD
DBNZLOOP
DBNZELOOPE
DBNZELOOPZ
DBNZNELOOPNE
DBNZNELOOPNZ
DECDEC
DICLI
DISPOSELEAVE
DIVIDIV
DIVUDIV
DS0:DS:
DS1:ES:
EISTI
FPO1ESC
HALTHLT
ININ
INCINC
INMINS
INMBINSB
INMWINSW
LDEALEA
LDMLODS
LDMBLODSB
LDMWLODSW
MOVMOV
MOV AH, PSWLAHF
MOV DS0, …LDS
V30MZ8086
MOV DS1, …LES
MOV PSW, AHSAHF
MOVBKMOVS
MOVBKBMOVSB
MOVBKWMOVSW
MULIMUL
MULUMUL
NEGNEG
NOPNOP
NOTNOT
NOT1 CYCMC
OROR
OUTOUT
OUTMOUTS
OUTMBOUTSB
OUTMWOUTSW
POLLWAIT
POPPOP
POP PSWPOPF
POP RPOPA
PREPAREENTER
PS:CS:
PUSHPUSH
PUSH PSWPUSHF
PUSH RPUSHA
REPREP
REPEREPE
REPNEREPNE
V30MZ8086
REPNZREPNZ
REPZREPZ
RETRET
RETFRETF
RETIIRET
RETNRETN
ROLROL
ROLCRCL
RORROR
RORCRCR
SALCSALC
SET1 CYSTC
SET1 DIRSTD
SHLSAL
SHLSHL
SHRSHR
SHRASAR
SS:SS:
STMSTOS
STMBSTOSB
STMWSTOSW
SUBSUB
SUBCSBB
TESTTEST
TRANSXLAT
TRANSBXLATB
XCHXCHG
XORXOR

8086 to V30MZ

Registers

ByteWordOtherFlags
8086V30MZ
AHAH
ALAL
BHBH
BLBL
CHCH
CLCL
DHDH
DLDL
8086V30MZ
AXAW
BPBP
BXBW
CXCW
DIIY
DXDW
SIIX
SPSP
8086V30MZ
CSPS
DSDS0
ESDS1
SSSS
FLAGSPSW
IPPC
8086V30MZ
ACAC
CYCY
DDIR
IIE
OV
PP
SS
TBRK
ZZ

Instructions

8086V30MZ
AAAADJBA
AADCVTDB
AAMCVTBD
AASADJBS
ADCADDC
ADDADD
ANDAND
BOUNDCHKIND
CALLCALL
CBWCVTBW
CLCCLR1 CY
CLDCLR1 DIR
CLIDI
CMCNOT1 CY
CMPCMP
CMPSCMPBK
CMPSBCMPBKB
CMPSWCMPBKW
CS:PS:
CWDCVTWL
DAAADJ4A
DASADJ4S
DECDEC
DIVDIVU
DS:DS0:
ENTERPREPARE
ES:DS1:
ESCFPO1
8086V30MZ
HLTHALT
IDIVDIV
IMULMUL
ININ
INCINC
INSINM
INSBINMB
INSWINMW
INTBRK
INT3BRK 3
INTOBRKV
IRETRETI
JABH
JAEBNL
JBBL
JBEBNH
JCBC
JCXZBCWZ
JEBE
JGBGT
JGEBGE
JLBLT
JLEBLE
JMPBR
JNABNH
JNAEBL
JNBBNL
JNBEBH
8086V30MZ
JNCBNC
JNEBNE
JNGBLE
JNGEBLT
JNLBGE
JNLEBGT
JNOBNV
JNPBPO
JNSBP
JNZBNZ
JOBV
JPEBPE
JPOBPO
JSBN
JZBZ
LAHFMOV AH, PSW
LDSMOV DS0, …
LEALDEA
LEAVEDISPOSE
LESMOV DS1, …
LOCKBUSLOCK
LODSLDM
LODSBLDMB
LODSWLDMW
LOOPDBNZ
LOOPEDBNZE
LOOPNEDBNZNE
LOOPNZDBNZNE
8086V30MZ
LOOPZDBNZE
MOVMOV
MOVSMOVBK
MOVSBMOVBKB
MOVSWMOVBKW
MULMULU
NEGNEG
NOPNOP
NOTNOT
OROR
OUTOUT
OUTSOUTM
OUTSBOUTMB
OUTSWOUTMW
POPPOP
POPAPOP R
POPFPOP PSW
PUSHPUSH
PUSHAPUSH R
PUSHFPUSH PSW
RCLROLC
RCRRORC
REPREP
REPEREPE
REPNEREPNE
REPNZREPNZ
REPZREPZ
RETRET
8086V30MZ
RETFRETF
RETNRETN
ROLROL
RORROR
SAHFMOV PSW, AH
SALSHL
SALCSALC
SARSHRA
SBBSUBC
SCASCMPM
SCASBCMPMB
SCASWCMPMW
SHLSHL
SHRSHR
SS:SS:
STCSET1 CY
STDSET1 DIR
STIEI
STOSSTM
STOSBSTMB
STOSWSTMW
SUBSUB
TESTTEST
WAITPOLL
XCHGXCH
XLATTRANS
XLATBTRANSB
XORXOR

V30MZ to 8086 to AT&T

Instructions

V30MZ 8086 AT&T
CALL 32-bit immediate CALL 32-bit immediate LCALL32-bit immediate
CVTBW CBW CBTW
CVTWL CWD CWTD
BR32-bit immediate JMP32-bit immediate LJMP32-bit immediate
RETF RETF LRET


DMA - Direct Memory Access

Color models provide a DMA feature to quickly transfer data from the bus into WRAM. On the monochrome model, or a color model with color mode disabled, none of the DMA features are available: its I/O ports do nothing when written and are undefined when read.

DMA transfers are in word units and both the source and destination addresses are word-aligned. Transfers cannot read from cartridge SRAM as the source because its data interface is 8-bit, and the DMA controller explicitly prohibits attempting any transfers there.

The DMA feature is intended to be used by the program to perform memory transfers. The CPU is paused during a DMA operation and resumes after the DMA operation completes.

Memory

The memory source for DMA transfers is configured through the following I/O ports:

0x40 Word GDMA_SOURCE_L General-purpose DMA source address (lower 16 bits)
0x42 Word GDMA_SOURCE_H General-purpose DMA source address (upper 4 bits)

The lowest bit of GDMA_SOURCE_L is read-only and is always clear. Bits 4-15 of GDMA_SOURCE_H have no significance and are undefined when read.

GDMA_SOURCE_L and GDMA_SOURCE_H together form the full 20-bit physical address used as the memory source for DMA transfers.

The memory destination for DMA transfers is always into WRAM (0x00000 - 0x0FFFF). The 16-bit destination address is configured through the following I/O port:

0x44 Word GDMA_DESTINATION General-purpose DMA destination address

The lowest bit of GDMA_DESTINATION is read-only and is always clear.

The size of the data to transfer with DMA is configured through the following I/O port:

0x46 Word GDMA_COUNTER General-purpose DMA data transfer amount

GDMA_COUNTER specifies the total size of the transfer in bytes. The lowest bit is read-only and is always clear.

Control

The DMA transfer operation is configured through the following I/O port:

0x48 Byte GDMA_CTRL General purpose DMA control
7 6 5 0
Enb
Dir
-
1 1 6
- R These bits have no significance and are undefined when read.
Enb W When set, the DMA operation is initiated. When clear, no action is taken. Clear when read.
Dir R/W When clear, the source and destination addresses are incremented after each transfer. When set, they are decremented after each transfer.

GDMA_SOURCE_L, GDMA_SOURCE_H, GDMA_DESTINATION and GDMA_COUNTER are all modified during the DMA operation. The source and destination addresses are modified by the counter amount in the direction specified by Dir, and GDMA_COUNTER becomes zero.

Upon initiating the DMA operation, the CPU is suspended until it completes. The total number of CPU cycles taken by the DMA operation is given with the following formula:

TotalCycles = 5 + 2 * GDMA_COUNTER

If GDMA_COUNTER is already zero or the source address is within cartridge SRAM (0x10000 - 0x1FFFF), no DMA operation is performed and the program resumes immediately.

Editor's Note: Research is needed to determine the behavior when the source and/or destination addresses reach the end of the allowed range. Do they roll over and keep going?

Editor's Note: Research is needed to determine what happens if a DMA operation that began outside of SRAM reaches SRAM. Does it terminate prematurely?


LCD Panel

WonderSwan contains an LCD panel for image output that is 224×144 pixels with a 13.25 ms (≈ 75.47 Hz) configurable refresh rate. The monochrome model can produce 16 activation levels, and color models can produce 12-bit RGB.

Contents
Display Control
Characters
Screens
Sprites
Palettes
Windows
Segments
Interrupts

Pixel patterns are 8×8 units called characters. Two layers of background maps called screens present tiled grids of characters that can be scrolled around within the viewport. Sprites are individual character objects that can be positioned at any arbitrary position in the image. A window feature can be used to mask a region of the image where sprites and one of the screens are able to be drawn.

A number of interrupts are available for monitoring LCD events. This includes counting lines of output and finishing the display of an entire image.

The display unit is always active and cannot be turned on or off. Individual graphical features can be enabled or disabled.


Display Control

Top-level display features are configured through the following I/O port:

0x00 Word DISPLAY_CTRL Display control
Monochrome
15 11 10 8 7 6 5 4 3 2 1 0
- Border -
S2WC
S2WE
SPRWE
SPR
SCR2
SCR1
5 3 2 1 1 1 1 1 1
Color
15 12 11 8 7 6 5 4 3 2 1 0
Palette Color -
S2WC
S2WE
SPRWE
SPR
SCR2
SCR1
4 4 2 1 1 1 1 1 1
- R These bits have no function and are undefined when read.
Border R/W The index into the monochrome color map of the backdrop color.
Palette R/W The index of the color palette containing the backdrop color. Values 8 through 15 are sprite palettes 0 through 7 respectively.
Color R/W The index of the color within the above palette of the backdrop color.
S2WC R/W While S2WE is set, draws screen 2 pixels only outside the window bounds when clear or only inside the window bounds when set.
S2WE R/W When set, the screen 2 window is enabled.
SPRWE R/W When set, the sprite window is enabled.
SPR R/W When set sprites are enabled.
SCR2 R/W When set, screen 2 is enabled.
SCR1 R/W When set, screen 1 is enabled.

If color mode is disabled, this port uses the "Monochrome" format. If color mode is enabled, this port uses the "Color" format.

The backdrop color is used when drawing the image if no graphics occupy a given pixel.

If color mode is not enabled, Border specifies the index into the color map of the gradation level to use as the backdrop color. If color mode is enabled, Palette is the index of the color palette containing the backdrop color, and Color is the index of the color within that palette of the backdrop color. When running in 2bpp mode, the highest two bits of Color are ignored.

Ancillary Control

Additional LCD panel operations are configured through the following I/O port:

0x14 Byte LCD_IF_CTRL LCD interface control
7 2 1 0
-
Cont
Slp
6 1 1
- R These bits have no significance and are undefined when read.
Cont R Using low contrast when clear or high contrast when set. Undefined on monochrome and SwanCrystal.
Slp R/W Put the LCD into sleep mode when clear or normal operation when set.

Cont is available on WonderSwan Color even while color mode is disabled.

While in sleep mode, the LCD is disabled and will not display an image. On the monochrome model and SwanCrystal, it will display white pixels. On WonderSwan Color, it will display black pixels. Slp has significance regarding the corresponding Slp field in LCD_VOLUME. If either or both ports specify a sleep state, the display will be blanked.

VBlank interrupts are still processed while in sleep mode.

Editor's Note: Research is needed to determine whether other video interrupts continue to function while in sleep mode.

Refresh Rate

Although the LCD unit has 144 rows of pixels, the video component processes 159 rows by default, with the extras not being visible in the display. The number of extra rows can be configured by the program, thereby affecting the refresh rate of the image.

The refresh rate can be configured through the following I/O ports:

0x16 Byte LCD_VTOTAL LCD total line count
0x17 Byte LCD_VSYNC LCD back porch line count

All 8 bits of both ports are read/write.

LCD_VTOTAL specifies the total number of rows of pixels per frame, minus 1. Its initial value at system reset is 0x9E, which corresponds to 159 lines.

LCD_VSYNC specifies the number of lines in the image following the "back porch" phase of the timing process. Its initial value at system reset is 0x9B, which corresponds to 155 lines.

In order to synchronize the image properly with the display, these ports should be configured such that there are 4 "back porch" lines in the video signal. When configured properly, the value in LCD_VSYNC should be 3 less than the value in LCD_VTOTAL.

If the number of lines specfied by LCD_VTOTAL is less than 144, fewer lines will be processed each frame than there are physical rows of pixels on the LCD unit. In this situation, only the top LCD_VTOTAL + 1 lines are displayed, and all remaining lines are white pixels. Since the frame never reaches the bottom of the image, VBLANK interrupts are not requested and the VBLANK_COUNTUP timer never updates.

If LCD_VTOTAL is 255, no image is displayed and the LCD unit displays white pixels.

Every row of pixels takes ≈ 83.33 µs (= 12,000 Hz) to process. The initial number of 159 lines works out to 12,000 Hz / 159 ≈ 75.47 frames per second.

Caution: Supplying an odd value for LCD_VTOTAL produces anomlous behavior on SwanCrystal and may damage the LCD unit. The behavior on the monochrome model is the same as when using even values. As a precaution, only use even values for LCD_VTOTAL.

Editor's Note: These ports are undocumented and are not intended for developer use. The names LCD_VTOTAL and LCD_VSYNC are conjectural and have been produced by the WonderSwan community.

Editor's Note: Need to check if odd values are problematic on WonderSwan Color.


Characters

The fundamental graphical element on WonderSwan is the character, or "tile", which is an 8×8 pixel image with 2 or 4 bits per pixel. The monochrome model only supports 2bpp, while color models additionally support 4bpp. Characters are located at fixed addresses in WRAM:

0x02000 - 0x03FFF Characters
0x04000 - 0x0BFFF [color] Characters

[color] These addresses are only available in color mode. When accessed on the monochrome model or on a color model with color mode disabled, they function as open bus.

Each 2bpp character occupies 16 bytes and each 4bpp character occupies 32 bytes.

The bit depth and color capability of characters is specified with the SYSTEM_CTRL2 I/O port. 4bpp character modes are only available while color mode is enabled. When color mode is disabled, there is memory for 512 characters. When color mode is enabled, there is memory for 1,024 characters of either bit depth.

The base address for 2bpp character memory is 0x02000, and the base address for 4bpp character memory is 0x04000. The WRAM organization for each color depth is as follows:

Address 2bpp modes 4bpp modes
0x02000 - 0x03FFF 2bpp characters 0 - 511 Scratch memory
0x04000 - 0x05FFF 2bpp characters 512 - 1,023 4bpp characters 0 - 255
0x06000 - 0x0BFFF Scratch memory 4bpp characters 256 - 1,023

Planar

Characters may be encoded as planes, where each byte represents a single bit for each of the 8 pixels on a particular row within the character. The bits from multiple bytes are used to determine the value for any given pixel.

Regardless of bit depth, planar characters are encoded as rows of pixels from top to bottom. For each row of pixels, all of the bit planes appear as consecutive bytes in order from least significant to most significant: the first byte of the row contains the least significant bit for each pixel in that row, and the last byte of the row contains the most significant pixel bit. Within each byte, pixels are ordered with the highest bit on the left and the lowest bit on the right.

Packed

4bpp characters may be encoded linearly, where all of the bits for each pixel are located within the same byte.

Packed characters are encoded as rows of pixels from top to bottom. For each row of pixels, the four bytes represent adjacent pairs of pixels in order from left to right: the first byte of the row contains the left-most two pixels in the row, and the fourth byte contains the right-most two pixels. Within each byte, pixels are ordered with the high nibble on the left and the low nibble on the right.


Screens

WonderSwan features two scrollable background layers called screens. Each screen is a 32×32 character grid (256×256 pixels). Screen 1 is always the back-most element in the image, whereas screen 2 may appear in front of or behind various sprites. Screen 2 may interact with the window feature.

Control

The DISPLAY_CTRL I/O port is used in part to configure screens:

0x00 Word DISPLAY_CTRL Display control
15 2 1 0
-
SCR2
SCR1
14 1 1
- These bits do not pertain to screens.
SCR2 R/W When set, screen 2 is enabled.
SCR1 R/W When set, screen 1 is enabled.

When both screens are enabled, screen 2 will appear in front of screen 1.

Memory for screens is located in WRAM. Screens have a 15-bit base address, with bits 0-10 being clear and bits 11-14 being configurable through the following I/O port:

0x07 Byte SCR_AREA SCR character definition area specification
7 4 3 0
S2_VRAM S1_VRAM
4 4
S2_VRAM R/W Bits 11-14 of the base address for screen 2.
S1_VRAM R/W Bits 11-14 of the base address for screen 1.

When color mode is disabled, the highest bit of each field is clear and read-only, yielding a maximum screen base address of 0x03800. When color mode is enabled, all 4 bits are available, yielding a maximum screen base address of 0x07800.

Memory

Each screen occupies 0x800 bytes. It is comprised of 1,024 elements, arranged as a 32×32-element grid, left-to-right then top-to-bottom.

Screen elements are 16 bits in the following format:

15 14 13 12 9 8 0
Vm
Hm
Bank
palette character
1 1 1 4 9
Vm When set, the character is flipped vertically.
Hm When set, the character is flipped horizontally.
Bank When color mode is enabled, serves as a bit 9 for character. Ignored otherwise.
palette The index of the palette to use when drawing the character.
character The index of the character to draw.

Scrolling

The default position of a screen places it such that the top-left pixel of the display is occupied by the top-left pixel of the first element in the screen. The position within the screen that corresponds to the top-left pixel of the display can be configured through the following I/O ports:

0x10 Byte SCR1_SCRL_X SCR1 scroll (X axis)
0x11 Byte SCR1_SCRL_Y SCR1 scroll (Y axis)
0x12 Byte SCR2_SCRL_X SCR2 scroll (X axis)
0x13 Byte SCR2_SCRL_Y SCR2 scroll (Y axis)

The format of all four ports is the same:

7 0
Scroll
8
Scroll R/W Scrolling offset

As Y increases, the screen will appear to move "up" relative to the display. As X increases, the screen will appear to move "left" relative to the display.

If the right or bottom edge of the screen is reached before the image has finished drawing, the screen will repeat by continuing at the left or top edge respectively.

Since a screen is exactly 256 pixels in both dimensions, the signedness of these ports is not relevant.


Sprites

Individual characters can appear anywhere in the scene by using them as sprites, or "objects". Up to 128 sprites may be used at once.

Control

The DISPLAY_CTRL I/O port is used in part to configure sprites:

0x00 Word DISPLAY_CTRL Display control
15 3 2 1 0
-
SPR
-
13 1 2
- These bits do not pertain to sprites.
SPR R/W When set, sprites are enabled.

Memory for sprites is located in WRAM. Sprites have a 15-bit base address, with bits 0-8 being clear and bits 9-14 being configurable through the following I/O port:

0x04 Byte SPR_AREA SPR character definition area specification
7 6 5 0
- SPR_VRAM
2 6
- R These bits have no significance and are undefined when read.
SPR_VRAM R/W Bits 9-14 of the base address for sprites.

When color mode is disabled, the highest bit of SPR_VRAM is clear and read-only, yielding a maximum sprite base address of 0x03E00. When color mode is enabled, all 6 bits are available, yielding a maximum sprite base address of 0x07E00.

The range of sprites to draw in the scene is configured through the following I/O ports:

0x05 Byte SPR_START_NO SPR drawing first character number
7 6 0
- start
1 7
- R This bit has no significance and is undefined when read.
start R/W Index of the first sprite to include

0x06 Byte SPR_CNT Number of SPR characters
7 0
count
8
count R/W Number of sprites to include.

When the image is being drawn, sprites indexed start through start + count - 1 will be included in the image. If the range specifies sprite indexes greater than 127, the next sprite after sprite 127 will be sprite 0 and the sequence will continue from there. Values greater than 128 in count have undefined behavior.

Memory

Sprite elements are 4 bytes in size, organized into 2 words with the following format:

0
15 14 13 12 11 9 8 0
Vm
Hm
Pr
Ct
palette character
1 1 1 1 3 9
1
15 8 7 0
x y
8 8
Vm If set, the character graphic will be reversed vertically.
Hm If set, the character graphic will be reversed horizontally.
Pr When clear, the sprite appears behind screen 2. When set, it appears in front of screen 2.
Ct While the sprite window is enabled, draws sprite pixels only inside the window bounds when clear or only outside the window bounds when set.
palette Index of the sprite palette defining the sprite's colors.
character Index of the character to draw.
x The horizontal coordinate of the left edge of the sprite from the left edge of the image.
y The vertical coordinate of the top edge of the sprite from the top edge of the image.

x and y are ostensibly unsigned, although values 248 through 255 will place the sprite to the left of/above the left/top edges of the image as though the values were signed. They can be conceptualized as the lowest 8 bits of a signed number in the range of -8 to +247.

When color mode is enabled, only the first 512 characters are available for use in sprites. These are the same 512 that can be used with color mode disabled.

Priority

When multiple sprites occupy the same pixel, only one will be visible in the output. For each applicable sprite for a given position in the output, in the order given by SPR_START_NO and SPR_CNT, the first sprite whose pixel is both opaque and not obscured by screen 2 will be used in the output.

Only the first 32 sprites positioned over a given row of pixels, in the order given by SPR_START_NO and SPR_CNT, can be used in the output. The 33rd and all subsequent sprites for that row of pixels will be skipped. This remains the case regardless of whether or not any of the first 32 sprites on the row are entirely off-screen or obscured by screen 2.


Palettes

A palette is a mapping between pixel values and colors. Palettes work differently depending on whether or not color mode is enabled. In monochrome mode, palettes are configured through I/O ports and the entire image consists of 8 shades of gray from a selection of 16 possible shades. In color mode, palettes are configured in memory and color elements are 12-bit RGB.

Regardless of whether color mode is enabled, there are 16 palettes total: 8 for screens and 8 for sprites, numbered 0 through 7 for each type. While operating in 2bpp modes, palettes 0 through 3 treat pixel value zero as opaque, while palettes 4 through 7 treat pixel value zero as transparent (invisible). While operating in 4bpp modes, all palettes treat pixel value zero as transparent.

Backdrop Color

A global backdrop color is used when drawing the image if no graphics occupy a given pixel. It is configured through the DISPLAY_CTRL I/O register:

0x00 Word DISPLAY_CTRL Display control
Monochrome
15 11 10 8 7 0
- Border -
5 3 8
Color
15 12 11 8 7 0
Palette Color -
4 4 8
- These bits do not pertain to the backdrop color.
Border R/W The index into the monochrome color map of the backdrop color.
Palette R/W The index of the color palette containing the backdrop color.
Color R/W The index of the color within the above palette of the backdrop color.

If color mode is not enabled, Border specifies the index into the color map of the gradation level to use as the backdrop color.

If color mode is enabled, Palette is the index of the color palette containing the backdrop color, and Color is the index of the color within that palette of the backdrop color. When running in 2bpp mode, the highest two bits of Color are ignored.

Color Map (Monochrome)

In monochrome mode, the display is capable of displaying 16 distinct shades of gray. However, only 8 of these shades can be used within a single image. The exact 8 shades to use are specified in the color map, which serves as a sort of master palette for the entire image.

The 8 values in the color map represent the specific gradation levels‐or shades of gray‐for each corresponding palette value. Gradation level 0 represents white (the LCD segment is fully "off") and gradation level 15 represents black (the LCD segment is fully "on"). The intensity of intermediate gradation levels transitions linearly from one extreme to the other.

The color map is configured through the following I/O ports:

0x1C Byte LCD_GRAY_01 LCD LUT #0/#1
0x1D Byte LCD_GRAY_23 LCD LUT #2/#3
0x1E Byte LCD_GRAY_45 LCD LUT #4/#5
0x1F Byte LCD_GRAY_67 LCD LUT #6/#7

The format of all four ports is the same:

7 4 3 0
Color1 Color0
4 4
Color1 R/W Gradation level for high-order color index.
Color0 R/W Gradation level for low-order color index.

Each port supplies the gradation levels for two palette values. Color0 supplies the gradation level for the lesser palette value and Color1 supplies the gradation level for the greater palette value. For example, Color1 in LCD_GRAY_23 supplies the gradation level for palette value 3.

Palettes (monochrome)

There are 16 4-color palettes in monochrome mode. Each color value refers to one of the entries in the color map.

Palettes are configured through the following I/O ports:

0x20 Word SCR_LUT_0 SCR character LUT #0
0x22 Word SCR_LUT_1 SCR character LUT #1
0x24 Word SCR_LUT_2 SCR character LUT #2
0x26 Word SCR_LUT_3 SCR character LUT #3
0x28 Word SCR_LUT_4 SCR character LUT #4
0x2A Word SCR_LUT_5 SCR character LUT #5
0x2C Word SCR_LUT_6 SCR character LUT #6
0x2E Word SCR_LUT_7 SCR character LUT #7
0x30 Word SPR_LUT_0 SPR character LUT #0
0x32 Word SPR_LUT_1 SPR character LUT #1
0x34 Word SPR_LUT_2 SPR character LUT #2
0x36 Word SPR_LUT_3 SPR character LUT #3
0x38 Word SPR_LUT_4 SPR character LUT #4
0x3A Word SPR_LUT_5 SPR character LUT #5
0x3C Word SPR_LUT_6 SPR character LUT #6
0x3E Word SPR_LUT_7 SPR character LUT #7

The format of all sixteen ports is the same:

15 14 12 11 10 8 7 6 4 3 2 0
- c3 - c2 - c1 - c0
1 3 1 3 1 3 1 3
- R These bits have no function and are undefined when read.
c3 R/W The value for color 3
c2 R/W The value for color 2
c1 R/W The value for color 1
c0 R/W The value for color 0

Palettes (Color)

When color mode is enabled, palettes are configured in WRAM. There are 16 16-color palettes defined with RGB triplets.

Palette memory is located in WRAM at the following addresses:

0x0FE00 - 0x0FE1F Screen color palette 0
0x0FE20 - 0x0FE3F Screen color palette 1
0x0FE40 - 0x0FE5F Screen color palette 2
0x0FE60 - 0x0FE7F Screen color palette 3
0x0FE80 - 0x0FE9F Screen color palette 4
0x0FEA0 - 0x0FEBF Screen color palette 5
0x0FEC0 - 0x0FEDF Screen color palette 6
0x0FEE0 - 0x0FEFF Screen color palette 7
0x0FF00 - 0x0FF1F Sprite color palette 0
0x0FF20 - 0x0FF3F Sprite color palette 1
0x0FF40 - 0x0FF5F Sprite color palette 2
0x0FF60 - 0x0FF7F Sprite color palette 3
0x0FF80 - 0x0FF9F Sprite color palette 4
0x0FFA0 - 0x0FFBF Sprite color palette 5
0x0FFC0 - 0x0FFDF Sprite color palette 6
0x0FFE0 - 0x0FFFF Sprite color palette 7

Each of the 16 palettes defines 16 color entries at 2 bytes per entry for a total of 32 bytes per palette. Each color entry is a word with the following format:

15 12 11 8 7 4 3 0
- R G B
4 4 4 4
- These bits are not used by palettes.
R The color's red intensity.
G The color's green intensity.
B The color's blue intensity.

Palette colors are RGB triplets with 4 bits per channel. The color 0x000 is black and the color 0xFFF is white.

In 2bpp mode, only color entries 0 through 3 are used from each palette, with the remaining 12 entries being unused.


Windows

Windows can be used to configure clipping regions within the image that can apply to screen 2 and sprites. The region is a rectangle that can be positioned arbitrarily, and can either mask the corresponding pixels from appearing inside the rectangle, or only allow them to appear inside the rectangle.

The DISPLAY_CTRL I/O port is used in part to configure windows:

0x00 Word DISPLAY_CTRL Diplay control
15 6 5 4 3 2 0
-
S2WE
S2WC
SPRWE
-
10 1 1 1 3
- These bits do not pertain to windows.
S2WE R/W When set, the screen 2 window is enabled.
S2WC R/W While S2WE is set, draws screen 2 pixels only inside the window bounds when clear or only outside the window bounds when set.
SPRWE R/W When set, the sprite window is enabled.

The window clipping behavior for sprites is configured for each sprite individually. For more information, see Sprites § Memory.

Windows are positioned through the following I/O ports:

0x08 Byte SCR2_WIN_X1 SCR2 Window upper left (X axis)
0x09 Byte SCR2_WIN_Y1 SCR2 Window upper left (Y axis)
0x0A Byte SCR2_WIN_X2 SCR2 lower right of window (X axis)
0x0B Byte SCR2_WIN_Y2 SCR2 lower right of window (Y axis)
0x0C Byte SPR_WIN_X1 SPR window upper left (X axis)
0x0D Byte SPR_WIN_Y1 SPR window upper left (Y axis)
0x0E Byte SPR_WIN_X2 SPR window bottom right (X axis)
0x0F Byte SPR_WIN_Y2 SPR window bottom right (Y axis)

The "SCR2_" ports apply to the screen 2 window and the "SPR_" ports apply to the sprite window.

All eight of these ports are 8-bit unsigned numbers. For each window, the corresponding ports have the following significance:

X1 Index of the left-most column of pixels of the window from the left edge of the image.
X2 Index of the right-most column of pixels of the window from the left edge of the image.
Y1 Index of the top-most row of pixels of the window from the top edge of the image.
Y2 Index of the bottom-most row of pixels of the window from the top edge of the image.

X2 and Y2 specify the last column and row of pixels to include in the window, respectively. Consequently, the width of the window in pixels is X2 - X1 + 1 and the height is Y2 - Y1 + 1.

For each window, if X2 is less than X1 or Y2 is less than Y1, then the entire image is considered to be outside of the window's bounds.


Segments

Ancillary to the main pixels of the LCD display, additional segments are available along one of the edges for use as status indicators. The program can turn these on and off as needed.

Segments are configured through the following I/O port:

0x15 Byte LCD_SEG_DATA Segment display data
7 6 5 4 3 2 1 0
-
A3
A2
A1
Hr
Vt
Sl
2 1 1 1 1 1 1
- R These bits have no significance and are undefined when read.
A3 R/W Aux 3, large circle.
A2 R/W Aux 2, medium circle.
A1 R/W Aux 1, small circle.
Hr R/W Horizontal orientation.
Vt R/W Vertical orientation.
Sl R/W Sleep, shooting star.

When the bit for a segment is set, that segment will be turned on. When the bit is clear, the segment will be turned off.

Additional information regarding segments is available through the following I/O port:

0x1A Byte LCD_VOLUME LCD volume status
7 4 3 2 1 0
-
On
Vol -
Slp
3 1 2 1 1
- R These bits have no significance and are clear when read.
On R Set when the LCD volume icon is being displayed, or cleared otherwise.
Vol R Indicates the current state of the LCD volume icon.
Slp R/W Put the LCD into sleep mode when set or normal operation when clear.

The individual bits in Vol are used to enable or disable the literal LCD segments. Has the following significance:

0 Sound disabled
1 Medium volume (color models only)
2 Low volume
3 High volume

While in sleep mode, the LCD is disabled and will not display an image. On the monochrome model and SwanCrystal, it will display white pixels. On WonderSwan Color, it will display black pixels. Slp has significance regarding the corresponding Slp field in LCD_IF_CTRL. If either or both ports specify a sleep state, the display will be blanked.

VBlank interrupts are still processed while in sleep mode.

Editor's Note: This port is undocumented and is not intended for developer use. The name LCD_VOLUME is conjectural and has been produced by the WonderSwan community.


Interrupts

The video unit supports four different interrupts that the program can use during image processing. For information regarding software setup, see Managing Interrupts.

DISPLINE

Requests an interrupt when a specific row of pixels is being displayed. This interrupt has the relative vector index +4 and is configured through the following I/O ports:

0x02 Byte LCD_LINE Drawing line position
0x03 Byte LCD_INTERRUPT Drawing line interrupt

Both ports are 8-bit, unsigned numbers. Each represents a specific row of pixels, with zero being the top row and increasing values moving down the image. LCD_LINE is read-only and returns the index of the row of pixels currently being displayed. LCD_INTERRUPT is read/write and is used to specify the index of the row of pixels to use with the interrupt.

When LCD_LINE is updated by the video unit and the value matches LCD_INTERRUPT, the interrupt will be requested.

VBLANK

Requests an interrupt every time a full frame is displayed. This interrupt has the relative vector index +6 and is always active: it needs not be configured.

This interrupt is requested at the end of pixel row 143, when incrementing LCD_LINE. The number of rows of pixels to display is configured through LCD_VTOTAL: if fewer than 144 rows are specified, this interrupt will never be requested.

Timers: HBLANK_COUNTUP and VBLANK_COUNTUP

HBLANK_COUNTUP requests an interrupt after a configurable number of rows of pixels are displayed and has the relative vector index +7. VBLANK_COUNTUP requests an interrupt after a configurable number of full frames are displayed and has the relative vector index +5.

These interrupts are collectively known as the timers. Each one has a counter value that is decremented each time the corresponding video action (H-blank or V-blank) occurs. When the counter reaches zero, the interrupt is requested. The counter can then optionally reset to a configurable value.

Timer functionality is configured through the following I/O port:

0xA2 Word TIMER_CTRL Timer control
15 4 3 2 1 0
-
VAuto
VEnb
HAuto
HEnb
12 1 1 1 1
- R These bits have no significance and are undefined when read.
VAuto R/W When set, the V-blank counter is reloaded once it reaches zero.
VEnb R/W When set, the V-blank counter is enabled.
HAuto R/W When set, the H-blank counter is reloaded once it reaches zero.
HEnb R/W When set, the H-blank counter is enabled.

The timer counters are configured through the following I/O ports:

0xA4 Word H_BLANK_TIMER H-Blank timer reload
0xA6 Word V_BLANK_TIMER V-Blank timer reload
0xA8 Word H_BLANK_COUNTER H-Blank timer count
0xAA Word V_BLANK_COUNTER V-Blank timer count

All four counter ports are 16-bit, unsigned numbers. The "H_BLANK_" ports pertain to HBLANK_COUNTUP and the "V_BLANK_" ports pertain to VBLANK_COUNTUP. Each represents the number of blanking periods (and therefore counter updates) until the interrupt fires. The "_TIMER" ports are read/write and supply the reload value when HAuto and/or VAuto is set. The "_COUNTER" ports are read-only and return the current counter values.

Writing to a "_TIMER" port will immediately initialize the corresponding "_COUNTER" port to the same value. If the reload value is zero, the interrupt will never occur because it specifically watches for the value to be decremented from 1 to 0.

If a timer is configured to repeat through HAuto or VAuto as appropriate, the current counter value will reset to the reload value once the counter reaches zero. In this situation, the counter will never actually return the value zero when read.

H-blank occurs after processing all 224 visible pixels for each row in the display. It continues to occur for non-visible rows that are processed during the vertical blanking interval as specified by LCD_VTOTAL.

V-blank occurs after processing all 144 visible rows of pixels. The counter is decremented at the end of pixel row 143, when incrementing LCD_LINE. The number of rows of pixels to display is configured through LCD_VTOTAL: if fewer than 144 rows are specified, the counter will never decrement.

While enabled, H-blank counts always occur every ≈ 83.33 µs (= 12,000 Hz). When used with the value 1 in H_BLANK_TIMER, this interrupt is useful as a PCM audio timer. For more information, see Voice.

Editor's Note: WonderWitch refers to a non-repeating timer as "one-shot" and a repeating timer as "auto preset".

Editor's Note: Research is needed to determine how long H-blank lasts. It might process 256 pixels' worth of time in order to give the program a moment to implement a raster effect.


Sound

Overview
Overview
Output Procedure

Features
PCM Waveforms
Output
Sound DMA

Channels
Stereo Levels
Frequency
Voice
Sweep
Noise
Hyper Voice


Overview

WonderSwan's sound unit has 4 channels, all of which can produce tones by sampling from PCM waveform memory and three of which have additional operating modes. Color models also support a sound DMA feature and an additional streaming PCM channel called Hyper Voice.

Channels are named 1 through 4 and have the following features:

Channels 1-4
Sampling from PCM wave memory
Stereo output levels/balance
Sampling frequency
Channel 2
Raw 8-bit voice output
(Color mode only) Destination of sound DMA
Channel 3
Frequency sweep
Channel 4
Sampling from pseudorandom noise generator
(Color mode only) Hyper Voice
Destination of sound DMA

Peripherals include a built-in monaural speaker, a volume button and a separate 3.5 mm headphone adapter that connects through the external port on the console. Audio output from the mixer is 24,000 Hz, 8-bit digital mono for the internal speaker and 16-bit digital stereo for the headphone adapter.


Output Procedure

Digital Output

An input sample is produced for each of the audio channels. Wave samples come directly from wave memory, and noise samples are generated according to the noise generation algorithm. If a channel is not active, 0 is used for its input sample. This section refers to the left and right channel output streams in singular, but the algorithm applies to each stream independently.

For each active channel:

If the channel is neither channel 2 in voice mode nor Hyper Voice
The 4-bit stereo level is multiplied with the 4-bit sample taken from either PCM waveform memory or from the pseudorandom noise generator to produce an unsigned 8-bit channel output sample.
Otherwise, if the channel is channel 2 in voice mode
The unsigned 8-bit sample is taken from the channel state and potentially shifted right to reduce its amplitude.
Otherwise, if the channel is Hyper Voice and the destination is a headphone adapter
The signed 16-bit sample(s) is/are taken from the channel state.
Otherwise, if the channel is Hyper Voice and the destination is the internal speaker
The channel is silent.

The outputs for all channels are then added together to produce the preliminary combined output sample.

If the destination is the internal speaker, the left and right preliminary combined outputs are added together. The resulting 11-bit value is then shifted right by the number of bits specified in SND_OUT_CTRL and the lowest 8 bits are used as the final output value.

If the destination is a connected headphone adapater, the left and right preliminary combined outputs are taken directly. The signed 16-bit values are shifted left 5 bits and the lowest 16 bits are used as the final output values.

Regardless of destination, output is sampled at 24,000 Hz. Upon receiving the output from the WonderSwan, the headphone adapter will use linear interpolation to double the sampling rate to 48,000 Hz prior to converting to analog.

Editor's Note: Research is needed to verify masking with large outputs from Hyper Voice used in conjunction with the other channels.

Analog Output

When converting to analog, the VSU implements an RC circuit to block the DC bias, effectively producing a first-order high-pass filter with a very low cutoff frequency. This prevents the output voltage from being exclusively non-negative without affecting the audible significance of the stream.

The RC circuit is implemented with a 10 kΩ resistor and a 1 µF capacitor, resulting in a cutoff frequency of 1 / (2π × 10000 × 0.000001) ≈ 15.915 Hz. It can be discretized with an arbitrary sampling rate using the following formulas:

RC = 10000 × 0.000001 = 0.01
α = RC / (RC + 1 / SamplingRateHz)

Then, for each sample:

Output[n] = α × ( Output[n - 1] + Input[n] - Input[n - 1] )

SamplingRateHz is 24,000 for the internal speaker and 48,000 for the headphone adapter.

Editor's Note: The RC circuit components shown above are known to be present in the headphone adapter. Research is needed to determine the sepcifics of the DAC process used for the internal speaker.


PCM Waveforms

Wave generation is performed by reading samples from PCM wave memory. Sound channels 1-4 are capable of producing tones as waves. PCM wave memory is located in WRAM at the address specified by the following I/O port:

0x8F Byte SND_WAVERAM Sound waveform definition area specification
7 0
wave_p
8
wave_p R/W Memory address of PCM wave samples, shifted right 6 bits.

To determine the address in WRAM of the PCM wave samples, shift the value of wave_p left 6 bits.

PCM wave memory is 64 bytes, organized as 4 consecutive groups of 16 bytes. Each group applies to one of the sound channels 1 through 4, with the first group applying to channel 1 and so-forth.

Each group of 16 bytes defines 32 PCM samples. All 32 samples taken together represent one period of a tone's waveform. Samples are 4 bits in size and unsigned. Two samples are packed into each byte, with the low bits of the byte specifying the value of the earlier sample and the high bits specifying the later sample.


Output

Sound generation is controlled through the following I/O port:

0x90 Byte SND_CH_CTRL Sound channel control
7 6 5 4 3 2 1 0
N S V -
Enb4
Enb3
Enb2
Enb1
1 1 1 1 1 1 1 1
- R This bit has no significance and is undefined when read.
N R/W When set, channel 4 operates in noise mode. When clear, channel 4 operates in wave mode.
S R/W When set, the sweep function is enabled for channel 3.
V R/W When set, channel 2 operates in voice mode. When clear, channel 2 operates in wave mode.
Enb4 R/W When set, channel 4 is enabled and will produce sound. When clear, channel 4 is silent.
Enb3 R/W When set, channel 3 is enabled and will produce sound. When clear, channel 3 is silent.
Enb2 R/W When set, channel 2 is enabled and will produce sound. When clear, channel 2 is silent.
Enb1 R/W When set, channel 1 is enabled and will produce sound. When clear, channel 1 is silent.

If V is set (channel 2 is operating in voice mode), channel 2 will always prodouce output even if Enb2 is clear.

While a channel is enabled, all timing states associated with it are updated according to its configuration. This includes the PCM waveform sampling position, the sweep feature and the pseudorandom number generator. While a channel is disabled, none of its timing states are updated.

Even when channel 2 is operating in voice mode or channel 4 is operating in noise mode, their PCM waveform sampling positions continue to be updated according to their frequency settings.

There is no way to specify or reset a channel's PCM waveform sampling position. It will only be updated by the sound subsystem while the channel is active.

Hardware output is configured through the following I/O port:

0x91 Byte SND_OUT_CTRL Sound output control
7 6 4 3 2 1 0
ConH
-
EnbH
RngS
EnbS
1 3 1 2 1
- R These bits have no significance and are undefined when read.
ConH R Set when a headphone cable is connected, or clear otherwise.
EnbH R/W When set, output is sent to the headphone adapter.
RngS R/W Specifies the range of bits to use for internal speaker output (see below).
EnbS R/W When set, output is sent to the internal speaker.

ConH indicates that a headphone adapter is present and a 3.5 mm audio cable is plugged into it. If connected, audio is only delivered to the headphone adapter; if disconnected, audio is only delivered to the internal speaker.

The internal speaker processes 8-bit output, but the digital mixer produces 11-bit samples after mixing all 4 channels. RngS specifies which 8 of these 11 bits to use as the output: the 11-bit sample is shifted right by the number of bits given by RngS, and the lowest 8 bits of the result are used as the output. See also: Output Procedure.

Data

The mixer's output data (not including Hyper Voice) is available through the following I/O registers:

0x96 Word SND_OUT_R Right channel sound output
0x98 Word SND_OUT_L Left channel sound output
0x9A Word SND_OUT_M Internal speaker sound output

All three ports are read-only.

SND_OUT_R and SND_OUT_L are the final 10-bit mixer values for the right and left headphone outputs respectively. The highest 6 bits of both ports are always clear.

SND_OUT_M is the final 11-bit mixer value for the internal speaker output. The highest 5 bits of this port are always clear.

Editor's Note: These ports are undocumented and are not intended for developer use. The names SND_OUT_R, SND_OUT_L and SND_OUT_M are conjectural and have been produced by the WonderSwan community.

Editor's Note: Research is needed to determine whether these ports are present on the monochrome model.


Sound DMA

Color models provide a DMA feature for streaming PCM output automatically. On the monochrome model, or a color model with color mode disabled, none of the sound DMA features are available: its I/O ports do nothing when written and are undefined when read.

Sound DMA transfers are in byte units.

Memory

The memory source for sound DMA transfers is configured through the following I/O ports:

0x4A Word SDMA_SOURCE_L Sound DMA source address (lower 16 bits)
0x4C Word SDMA_SOURCE_H Sound DMA source address (upper 4 bits)

Bits 4-15 of SDMA_SOURCE_H have no significance and are undefined when read.

SDMA_SOURCE_L and SDMA_SOURCE_H together form the full 20-bit physical address used as the memory source for DMA transfers. Each time a byte is transferred, it is read from the memory pointed to by these ports, then the pointer in these ports is updated in preparation of the next transfer.

The size of the data to transfer with sound DMA transfers is configured through the following I/O ports:

0x4E Word SDMA_COUNTER_L Sound DMA data transfer amount (lower 16 bits)
0x50 Word SDMA_COUNTER_H Sound DMA data transfer amount (upper 4 bits)

Bits 4-15 of SDMA_COUNTER_H have no significance and are undefined when read.

SDMA_COUNTER_L and SDMA_COUNTER_H together form the number of bytes remaining to be transferred using DMA transfers. Each time a byte is transferred, the counter in these ports is decremented in preparation of the next transfer. When the value reaches zero, the DMA operation completes.

Control

The DMA transfer operation is configured through the following I/O port:

0x52 Byte SDMA_CTRL Sound DMA control
7 6 5 4 3 2 1 0
Enb
Dir
-
Dest
Rep
? Rate
1 1 1 1 1 1 1 1
- R This bit has no significance and is undefined when read.
Enb R/W When set, transfers are enabled. When clear, transfers are disabled.
Dir R/W When clear, the source address is incremented after each transfer. When set, the source address is decremented after each transfer.
Dest R/W When clear, the transfer destination is SND_VOL_2. When set, the transfer destination is Hyper Voice.
Rep R/W When set, the transfer operation will repeat (see below).
? R/W The significance of this bit is not known. When set, the DMA feature doesn't appear to function.
Rate R/W The amount of time between transfers (see below).

When Rep is set, the current values in SDMA_SOURCE_L, SDMA_SOURCE_H, SDMA_COUNTER_L and SDMA_COUNTER_H are remembered in the DMA controller. Once the counter reaches zero while Rep is set, all four ports are replaced with the previously remembered values, thereby repeating the operation from the beginning.

Rate determines the interval between DMA transfers:

0 4,000 Hz = 250.00 µs
1 6,000 Hz 166.67 µs
2 12,000 Hz 83.33 µs
3 24,000 Hz 41.67 µs

If color mode is disabled while sound DMA is active, sound DMA will be paused until color mode is re-enabled. Once color mode is active again, sound DMA will continue to operate where it left off.


Stereo Levels

Sound channels 1 through 4 have volume settings for each of the left and right stereo outputs. Stereo levels are configured through the following I/O ports:

0x88 Byte SND_VOL_1 Sound channel 1 volume
0x89 Byte SND_VOL_2 Sound channel 2 volume
0x8A Byte SND_VOL_3 Sound channel 3 volume
0x8B Byte SND_VOL_4 Sound channel 4 volume
7 4 3 0
Left Right
4 4
Left R/W Left stereo level.
Right R/W Right stereo level.

Each field controls the output level of the corresponding stereo stream. The level scales linearly with 0 being silence and 15 being maximum amplitude.

Because the built-in speaker is monaural, the stereo levels ports are primarily intended for use with a headphone adapter.


Frequency

A channel's frequency specifies the interval at which it produces new PCM waveform or pseudorandom noise samples. Frequencies are configured through the following I/O ports:

0x80 Word SND_FREQ_1 Sound channel 1 frequency
0x82 Word SND_FREQ_2 Sound channel 2 frequency
0x84 Word SND_FREQ_3 Sound channel 3 frequency
0x86 Word SND_FREQ_4 Sound channel 4 frequency
15 11 10 0
- freq
5 11
- R These bits have no significance and are clear when read.
freq R/W The unsigned frequency divider setting.

The sound unit is clocked at 3.072 MHz. freq subtracted from 2,048 gives the number of clocks per sample within a sound channel's PCM wave memory or between pseudorandom noise samples. For this reason, higher values for freq correspond to higher-pitched audible frequencies. In effect, freq divides the main clock rate through the following formula:

SampleRateHz = 3072000 Hz / (2048 - freq)

Because there are 32 PCM samples in one period of a waveform, the effective audible tone of a wave channel is given with the following formulas:

ToneHz = SampleRateHz / 32
ToneHz = 96000 Hz / (2048 - freq)


Voice

Sound channel 2 is capable of outputting 8-bit raw PCM samples. This involves a mode of operation distinct from the one that processes PCM waveform memory. Channel 2's mode of operation is configured through the SND_CH_CTRL I/O port:

0x90 Byte SND_CH_CTRL Sound channel control
7 6 5 4 0
- V -
2 1 5
- R/W These bits do not pertain to voice mode.
V R/W When set, channel 2 operates in voice mode. When clear, channel 2 operates in wave mode.

While voice mode is enabled, the SND_VOL_2 I/O port has a different format:

0x89 Byte SND_VOL_2 Sound channel 2 volume
7 0
Sample
8
Sample R/W The raw PCM output sample. Unsigned.

While voice mode is enabled, channel 2's volume is controlled through the following I/O port:

0x94 Byte SND_VOL_CH2 Sound channel 2 voice volume
7 4 3 2 1 0
-
LH
LF
RH
RF
4 1 1 1 1
- R These bits have no significance and are undefined when read.
LH R/W Left channel half volume when set. Has no effect when LF is set.
LF R/W Left channel full volume when set.
RH R/W Right channel half volume when set. Has no effect when RF is set.
RF R/W Right channel full volume when set.

Half volume takes the sample value in SND_VOL_2 and shifts it right 1 bit. If neither the "half" nor "full" bit is set for a stereo level, the output for that level will be silent.

When output is being sent to the internal speaker, the left and right voice samples are added together. This may produce a sample value in excess of 8 bits, which can be corrected for by using the half-volume settings LH and RH.

On the monochrome model, voice mode is intended to be used in conjunction with the HBLANK_COUNTUP interrupt. On color models, it may also be used with sound DMA.


Sweep

Sound channel 3 is capable of modifying its frequency automatically. Channel 3's sweep feature is configured through the SND_CH_CTRL I/O port:

0x90 Byte SND_CH_CTRL Sound channel control
7 6 5 0
- S -
1 1 6
- R/W These bits do not pertain to the sweep feature.
S R/W When set, the sweep function is enabled for channel 3.

While the sweep feature is enabled, channel 3's frequency setting is updated automatically over time. Modifications are defined with the amount by which to change the frequency setting and the time between updates. These are configured through the following I/O ports:

0x8C Byte SND_SWEEP Sound channel 3 sweep amount
7 0
sweep
8
sweep R/W The signed amount to add to the frequency setting.

Each time a frequency modification occurs, the signed value in sweep is added to SND_FREQ_3. When the frequency setting reaches the minimum of zero or the maximum of 2,047, the next modification will cause the setting to "wrap around" and continue counting from the other extreme. Reading from SND_FREQ_3 yields the current effective frequency setting after modification.

0x8D Byte SND_SWEEP_TIME Sound channel 3 sweep step time
7 5 4 0
- steptime
3 5
- R These bits have no significance and are undefined when read.
steptime R/W The amount of time between frequency modifications, in units of ≈ 2.67 ms, minus 1. Unsigned.

The sweep feature is clocked at 375 Hz. steptime plus 1 gives the number of clocks per frequency modification.


Noise

Sound channel 4 is capable of outputting pseudorandom noise. This involves a mode of operation distinct from the one that processes PCM waveform memory. Channel 4's mode of operation is configured through the SND_CH_CTRL I/O port:

0x90 Byte SND_CH_CTRL Sound channel control
7 6 0
N -
1 7
- R/W These bits do not pertain to noise mode.
N R/W When set, channel 4 operates in noise mode. When clear, channel 4 operates in wave mode.

While noise mode is enabled, channel 4's samples are produced using a pseudorandom noise generator instead of being read from PCM waveform memory. The noise generator is a 15-bit linear feedback shift register with a configurable tap location. Output is binary: noise is only either high or low. The noise generator is configured through the following I/O port:

0x8E Byte SND_NOISE_CTRL Sound channel 4 noise control
7 5 4 3 2 0
-
Enable
Reset
Tap
3 1 1 3
- R These bits have no significance and are undefined when read.
Enable R/W When set, the pseudorandom function is enabled. When clear, it is disabled.
Reset W When set, the shift register is cleared to all zeroes. Clear when read.
Tap R/W Specifies the bit to use in noise generation (see below).

While both channel 4 and the noise feature are enabled, the noise feature will be active and will update the shift register at the frequency specified by SND_FREQ_4, even if channel 4 is in wave mode.

Tap specifies the bit within the shift register to use as the feedback source in noise generation. Different bits will produce pseudorandom bit sequences of different lengths before the sequences repeat:

0 Bit 14 Sequence length of 32,767
1 Bit 10 Sequence length of 1,953
2 Bit 13 Sequence length of 254
3 Bit 4 Sequence length of 217
4 Bit 8 Sequence length of 73
5 Bit 6 Sequence length of 63
6 Bit 9 Sequence length of 42
7 Bit 11 Sequence length of 28

Bit positions listed above are zero-based. That is, bit 0 is the bit at position 0x0001 and bit 14 is the bit at position 0x4000.

The current value in the sift register can be retrieved through the following I/O port:

0x92 Word SND_RANDOM Pseudo-random number
15 14 0
0 Random
1 15
0 R This bit is always zero.
Random R The current value of the pseudorandom shift register.

If the sound noise is to be used as a source of randomness but channel 4 is not needed for producing audio, it can be silenced by setting its stereo levels to zero in SND_VOL_4.

Noise Procedure

Noise generation begins by initializing the 15-bit shift register to all zeroes. This happens when setting Reset in SND_NOISE_CONTROL.

For each pseudorandom sample, the following algorithm takes place:

From the shift register, bit 7 (0x0080) is XORed with the bit at Tap and the result inverted to produce a pseudorandom bit.
The value in the register is shifted left one bit.
The pseudorandom bit is used as the new bit 0 of the shift register.
The pseudorandom bit is scaled to 15 to produce the output sample.


Hyper Voice

Color models provide a fifth, 16-bit sound channel to stream PCM output to a headphone adapter. On the monochrome model, or a color model with color mode disabled, Hyper Voice is not available: its I/O ports do nothing when written and are undefined when read.

If no headphone cable is connected (and output is being directed to the internal speaker), Hyper Voice will not produce any audio: it is exclusively available for use with headphones.

Hyper Voice is intended to be used via sound DMA. As such, it accepts sample inputs as 8-bit units, which are converted to 16-bit through a configurable function.

Control

Hyper Voice is configured through the following I/O port:

0x6A Word HYPERV_CTRL Hyper Voice Control
15 14 13 12 11 8 7 6 4 3 2 1 0
- Mode
Pty
-
Enb
Rate Fmt Shift
1 2 1 4 1 3 2 2
- R These bits have no significance and are undefined when read.
Mode R/W Specifies the output mode (see below).
Pty W When set, the output is reset to the left channel (see below). Undefined when read.
Enb R/W When set, the channel is enabled. When clear, it is disabled.
Rate R/W The internal sampling rate (see below).
Fmt R/W Specifies how to convert 8-bit sample inputs to 16-bit (see below).
Shift R/W Number of bits to shift during 8-bit to 16-bit sample conversion (see below).

Mode specifies the Hyper Voice output mode:

0 Stereo
1 Mono, left only
2 Mono, right only
3 Mono, both sides

When Mode is 0 (stereo) and an 8-bit sample is delivered to Hyper Voice, the stereo channel it is assigned to alternates between left and right. When Pty is set, Hyper Voice is explicitly reset to receive the next 8-bit sample into the left channel.

Rate determines how often the Hyper Voice channel output updates using its most recent input:

0 24,000 Hz 41.67 µs
1 12,000 Hz = 83.33 µs
2 8,000 Hz = 125.00 µs
3 6,000 Hz 166.67 µs
4 4,800 Hz 208.33 µs
5 4,000 Hz = 250.00 µs
6 3,000 Hz 333.33 µs
7 2,000 Hz = 500.00 µs

Fmt specifies how to convert 8-bit sample inputs to 16-bit:

0 Unsigned, shift
1 Unsigned, subtract 256, shift
2 Signed, shift
3 Signed, do not shift

Shift specifies the number of bits to shift the 16-bit sample value to the right prior to sending it to the mixer. When Fmt is not 3, a sign-propagating right shift is performed on the sample value.

Direct Access

The following I/O ports directly specify 16-bit sample outputs to Hyper Voice:

0x64 Word HYPERV_L Left channel Hyper Voice
0x66 Word HYPERV_R Right channel Hyper Voice

These ports are write-only and are undefined when read. They exactly specify the 16-bit sample values that will be used as the output.

HYPERV_L and HYPERV_R must be used with word accesses. Byte accesses have indeterminate operation and generally don't change the Hyper Voice state.

The following I/O ports directly specify 8-bit sample inputs into Hyper Voice:

0x68 Byte HYPERV_SL Left channel Hyper Voice input
0x69 Byte HYPERV_SR Right channel Hyper Voice input

These ports specify the 8-bit sample values that are converted to 16-bit according to the value of Fmt in HYPERV_CTRL.

Editor's Note: One source denotes the names and formats of these ports as follows:

0x64 Byte HYPERV_LL Left channel Hyper Voice (lower byte)
0x65 Byte HYPERV_LH Left channel Hyper Voice (upper byte)
0x66 Byte HYPERV_RL Right channel Hyper Voice (lower byte)
0x67 Byte HYPERV_RH Right channel Hyper Voice (upper byte)
0x68 Byte HYPERV_SL Hyper Voice shadow (lower byte)
0x69 Byte HYPERV_SH Hyper Voice shadow (upper byte)

These may have been from an intermediate specification during development that was changed prior to the finalization of WonderSwan Color.

Editor's Note: Research is needed to determine whether values can be read from HYPERV_SL and HYPERV_SR.

Editor's Note: Research is needed to determine whether values written to HYPERV_SL and HYPERV_SR are immediately transformed to 16-bit or if that happens the next time Hyper Voice updates according to HYPERV_CTRL.Rate.


Keypad

WonderSwan has 11 input buttons: two quartets of directional buttons called X and Y, a Start button, and two independent buttons called A and B. The four buttons of each of the X and Y groups are numbered 1 through 4, such as X1 or Y2.

The device is designed to operate in two orientations: horizontal with the WonderSwan logo upright, or vertical rotated 90° couter-clockwise relative to the horizontal orientation. In the horizontal orientation, the X buttons are used as directional input and the A and B buttons are used for actions. In the vertical orientation, the Y buttons are used for directional input and the X buttons are used for actions.

Generally speaking, the Y buttons are less accessible in the horizontal orientation, and the A and B buttons are less accessible in the vertical orientation. Both orientations use the Start button for menu navigation and pausing.

State

The current state of the buttons can be inspected with the following port:

0xB5 Byte KEY_SCAN Key scan
7 6 5 4 3 0
-
Action
X Y Keys
1 1 1 1 4
- This bit has no significance and is undefined when read.
Action R/W When set, action keys are polled.
X R/W When set, the X buttons are polled.
Y R/W When set, the Y buttons are polled.
Keys R Significance depends on Action, X and Y (see below).

Action, X and Y select which buttons have their state loaded into Keys when subsequently reading from this port. When the bit is set, the corresponding buttons are loaded into Keys, and when the bit is clear, the corresponding buttons are masked and will not be loaded into Keys.

The following chart lists which buttons are loaded into the individual bits of Keys for each of the control bits written to the port:

Keys Action X Y
1000 B X4 Y4
0100 A X3 Y3
0010 Start X2 Y2
0001 - X1 Y1

The bit marked - does not correspond to any button and is undefined when read.

When a button is pressed, its corresponding bit in Keys is set. If more than one of Action, X and Y are set simultaneously, the value of Keys is the bitwise OR of the corresponding button bits.

The program should wait a few CPU cycles between writing to KEY and reading from it, in order for the hardware state to stabilize. The recommended implementation is to use the ADJ4A instruction, which takes 10 cycles while using only one byte.

Setting all three of Action, X and Y while keys are not being read will minimize power consumption by the keypad component.

The de facto standard bit mask of the full key state is provided by the WonderWith API. It specifies a 16-bit value with the following format:

15 12 11 10 9 8 7 6 5 4 3 2 1 0
-
Y4
Y3
Y2
Y1
X4
X3
X2
X1
B A
Start
-
4 1 1 1 1 1 1 1 1 1 1 1 1

Interrupt

The keypad supports an interrupt that the program can use to respond to button presses. For information regarding software setup, see Managing Interrupts. The keypad interrupt is called KEY and has the relative vector index +1.

There are no configuration settings for the keypad interrupt: it is enabled or disabled through INT_ENABLE directly.

Key interrupts are requested whenever any bit in the Keys field of KEY_SCAN transitions from clear to set. Depending on which sets of buttons are selected by the Action, X or Y fields, interrupts can be restricted to a subset of the buttons. Due to the bitwise-OR behavior when activating multiple sets this way, the key interrupt can also be requested whenever any button is pressed.



Serial EEPROM

Overview
Overview
Ports
Contents

Instructions
ERAL - Erase All
ERASE - Erase
EWDS - Erase/Write Disable
EWEN - Erase/Write Enable
READ - Read
WRAL - Write All
WRITE - Write


Overview

The console contains a small EEPROM chip that is used to store system-wide settings, such as owner profile information, power-on states for volume and contrast, and the programmable logo startup screen. The EEPROM contained in the WonderSwan itself is known as the internal EEPROM (IEEPROM). Additionally, some WonderSwan games contain an EEPROM chip to store save data.

Mechanically, these EEPROM components have a serial interface with a set of instructions for accessing its data, using a protocol called Microwire. WonderSwan provides designated I/O ports for use by the CPU that stage values to send to, and to hold values received from, the EEPROM components.

The capacity of the memory depends on the use case: 64 words for internal EEPROM on the monochrome model and color models with color mode disabled, 1,024 words for internal EEPROM on color models with color mode enabled, and may be absent or any size within cartridges. Memory addresses are indexed by word: address 1 represents the second 16-bit data unit in memory.

If color mode is disabled on a color model, all internal EEPROM interactions behave as they do on the monochrome model.

The EEPROM components have a write-enabled state that must be activated prior to modifying the contents of their memory. If a write or erase instruction is attempted while writes are disabled, the instruction will be ignored. During system reset, writes are disabled in order to prevent accidental modification of EEPROM contents. However, the boot programs in all WonderSwan models activate write enable mode for the internal EEPROM and leave it active when launching the program on the cartridge.

Warning: Since the BANDAI logo startup screen is processed from internal EEPROM data on color models, it is possible to produce an internal EEPROM configuration that cannot advance past the boot procedure, and which persists after power-off. Specific fields in the ROM header can be configured to allow the system to supply a default boot screen and allow all of internal EEPROM to be updated by the program in the event a corruption needs to be repaired. For more information, see ROM Header.


Ports

When accessing internal EEPROM I/O ports on the monochrome model, byte accesses to odd port addresses function as open bus. Odd byte accesses on color models, even byte accesses on all models, and all accesses to cartridge EEPROM I/O ports all function normally.

Data

The following I/O ports are used to stage and receive data used in EEPROM communications:

0xBA Word IN_SERIAL_DATA Internal serial ROM data
0xC4 Word CART_SERIAL_DATA Cartridge serial ROM data
15 0
Data
16
Data R/W Bits used during an internal EEPROM communication.

For read operations, this port contains the data received from the EEPROM. For write operations, the contents of this port are sent to the EEPROM for storage.

Editor's Note: The name CART_SERIAL_DATA is conjectural and has been produced by the WonderSwan community.

Instruction

The following I/O ports configures the instruction to send in an EEPROM communication:

0xBC Word IN_SERIAL_COM Internal serial ROM command address
0xC6 Word CART_SERIAL_COM Cartridge serial ROM command address

The exact binary format of these ports depend on the number of address bits in the EEPROM being accessed:

6 bits Internal EEPROM on monochrome model or color model with color mode disabled.
6 bits 1 Kbit cartridge EEPROM
8 bits 2 Kbit and 4 Kbit cartridge EEPROM
10 bits Internal EEPROM on color model with color mode enabled.
10 bits 8 Kbit and 16 Kbit cartridge EEPROM

The size of the cartridge EEPROM, if any, can be determined by inspecting the save type field in the ROM header.

Given the number of address bits as n, the format of these ports is as follows:

Opcode ≠ 0
15
n + 3
n + 2
n + 1
n
n - 1
0
Z
SB
Op
code
Address
13 - n 1 2 n
Opcode = 0
15
n + 3
n + 2
n + 1
n
n - 1
n - 2
n - 3
0
Z
SB
0 0 Sub
op
X
13 - n 1 2 2 n - 2
Z W See below.
SB R/W Start bit. Must be set in order for an instruction to be initiated.
Opcode R/W The instruction to perform (see below).
Address R/W The word address to access in EEPROM memory. Absent when Opcode is 0.
Subop R/W Extended opcode. Present when Opcode is 0.
X R/W These bits are ignored, but hold state when written.

The conents of these ports are sent verbatim to the respective EEPROM components, and must match the expected format. All 16 bits are clocked, and if the first bit that is set is not in the SB position, the EEPROM component will not process the instruction. Ensure that all of the bits in Z are clear.

Opcode specifies which operation to perform during execution of the instruction:

0Extended opcode (see below)
1WRITE
2READ
3ERASE

If Opcode is 0, the highest 2 bits of Address are used as a sub-opcode field, and all lower-order bits of Address have no significance. The sub-opcode specifies which of the additional operations to perform:

0 EWDS Erase/Write Disable
1 WRAL Write All
2 ERAL Erase All
3 EWEN Erase/Write Enable

The instruction will be sent to the EEPROM component when the appropriate bit is sent in IN_SERIAL_CTRL or CART_SERIAL_CTRL as appropriate.

Editor's Note: The name CART_SERIAL_COM is conjectural and has been produced by the WonderSwan community.

Editor's Note: Not all original cartridges have been exhaustively inspected regarding the number of address bits in the EEPROM commands. It is possible that the list above is not comprehensive.

Editor's Note: Research is needed to determine whether Z is handled automatically by the internal EEPROM controller, and whether its state is retained when switching back and forth between color mode.

Control

The following I/O ports manage communication with the EEPROM components:

0xBE Word IN_SERIAL_CTRL Internal serial ROM status
0xC8 Byte CART_SERIAL_CTRL Cartridge serial ROM status
15 8 7 6 5 4 3 2 1 0
- P E W R -
Ready
Done
8 1 1 1 1 2 1 1
- R These bits have no significance and are clear when read. Not present in CART_SERIAL_CTRL, which is a byte port.
P R/W When set in IN_SERIAL_CTRL, enters write-protected mode (see below). Not present in CART_SERIAL_CTRL, where it is clear when read.
E W When set, intended to initiate an ERAL, ERASE, EWDS or EWEN instruction. Clear when read.
W W When set, intended to initiate a WRAL or WRITE instruction. Clear when read.
R W When set, intended to initiate a READ instruction. Clear when read.
Ready R Clear when the EEPROM component is busy, or is set when it is idle.
Done R Set when a read operation is completes (see below).

Once write-protected mode is activated on the internal EEPROM, it cannot be cleared and will remain active until the next system reset. While active, all words in the internal EEPROM from address 0x30 and above cannot be written by the program.

The boot program will set P unless bit 7 of byte 9 (game version) in the ROM header is set. If this bit is set, the cartridge program will be able to modify the entire contents of internal EEPROM as long as it itself does not set P.

The E, W and R bits all initiate communication with the EEPROM component. Each has a different behavior depending on the exact instructions that they are intended to be used with, and will still function this way even if the contents of IN_SERIAL_COM or CART_SERIAL_COM specify a different instruction. The following behaviors correspond to each bit:

E Sends the bits in IN_SERIAL_COM or CART_SERIAL_COM and takes no further action.
W Sends the bits in IN_SERIAL_COM or CART_SERIAL_COM followed by the bits in IN_SERIAL_DATA or CART_SERIAL_DATA.
R Sends the bits in IN_SERIAL_COM or CART_SERIAL_COM then receives bits into IN_SERIAL_DATA or CART_SERIAL_DATA.

Only one of E, W or R may be set in order for any action to take place. If more than one is set (or if none are set), nothing will happen.

After P is set on the internal EEPROM to activate write-protected mode, the console will prevent the W action whenever Address in IN_SERIAL_COM is ≥ 0x30. This coincides with the start of the user profile data and extends through any custom boot startup screen data. In this situation, Ready will remain set.

Done is cleared when R is set in IN_SERIAL_CTRL or when E or W is set in CART_SERIAL_CTRL.

Editor's Note: The name CART_SERIAL_CTRL is conjectural and has been produced by the WonderSwan community.

Editor's Note: Need to verify that only one control bit can be set at once.


Contents

The contents of cartridge EEPROM depend on the cartridge and the program it contains.

The contents of internal EEPROM are as follows. Although EEPROM addresses index 16-bit words, the contents are organized as a byte stream. This document describes the contents of internal EEPROM as a byte buffer with the low byte of each word coming before the high byte. For each field, the byte offset, word address and size in bytes are provided.

On the monochrome model or a color model with color mode disabled, the internal EEPROM only exposes the first 128 bytes to the program. All remaining data beginning at word address 0x040 are only accessible when color mode is enabled.

System Settings

Internal EEPROM contents in the word address range 0x000 - 0x041 pertain to system settings:

Offset Address Size Description
0x000 0x000 96 Program data
0x060 0x030 16 Owner name
0x070 0x038 2 Owner birthday year (high byte first)
0x072 0x039.L 1 Owner birthday month
0x073 0x039.H 1 Owner birthday day
0x074 0x03A.L 1 Owner sex
0x075 0x03A.H 1 Owner blood type
0x076 0x03B.L 1 Copy of ROM header field Publisher ID from the previous boot
0x077 0x03B.H 1 Copy of ROM header field Color from the previous boot
0x078 0x03C.L 1 Copy of ROM header field Game ID from the previous boot
0x079 0x03C.H 3 (Unknown)
0x07C 0x03E.L 1 Number of times the cartridge has been changed (see below)
0x07D 0x03E.H 1 Number of times the owner name has been changed
0x07E 0x03F 2 Number of times the system has booted
0x080 0x040 3 (Unknown)
0x083 0x041.H 1 Extra system settings

Program data may be written by the cartridge program even when write-protected mode is active. The exact purpose of this region is not known, but it is likely that developers needed to receive authorization from BANDAI before storing data here.

The owner name encodes 16 characters as one-byte units with the following character set:

-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F
0-   0 1 2 3 4 5 6 7 8 9 A B C D E
1- F G H I J K L M N O P Q R S T U
2- V W X Y Z + - ? .

Byte value 0x00 is the space character. If the name is less than 16 characters, all remaining characters should be spaces. The convention for reading the owner name from internal EEPROM trims spaces from the right.

Byte values 0x2B and greater are not intended to be used as characters in the owner name and will have unspecified significance in any program that processes them.

The owner birthday is encoded as binary-coded decimal for all three fields. The bytes of the year are exchanged within its word: the low 8 bits are the higher 2 digits and the high 8 bits are the lower 2 digits.

Owner sex may be one of the following values:

0x00 ?
0x01 Male
0x02 Female

Owner blood type may be one of the following values:

0x00 ?
0x01 A
0x02 B
0x03 O
0x04 AB

The ROM header fields for the current cartridge are compared against the values in internal EEPROM from the previous boot prior to updating the values in internal EEPROM. Unless all three bytes match, the value in the low byte of 0x3E is incremented.

The values in the low and high bytes of 0x3E and the word in 0x3F will not be incremented if they are already the maximum unsigned value (0xFF for the bytes and 0xFFFF for the word).

The extra system settings byte has the following structure:

7 6 5 2 1 0
Enb
Cont
- Vol
1 1 4 2
- These bits have no significance and are ignored.
Enb When set, the boot screen is processed from internal EEPROM. When clear, a default boot screen is used.
Cont For WonderSwan Color, set when the "high contrast" setting is on, or clear otherwise.
Vol The initial volume setting, with 0=silent and 3=max volume.

Boot Screen

Color models can present a custom boot screen when the device is powered on. Internal EEPROM contents in the word address range 0x042 - 0x3FF pertain to the boot screen:

Offset Address Size Description
0x084 0x042.L 1 Boot screen name color
0x085 0x042.H 1 (Unknown)
0x086 0x043.L 1 Boot screen data size setting
0x087 0x043.H 1 Boot screen start frame number
0x088 0x044.L 1 Boot screen end frame number
0x089 0x044.H 1 Boot screen sprite count
0x08A 0x045.L 1 Boot screen color settings
0x08B 0x045.H 1 Boot screen character count
0x08C 0x046 2 Boot screen palette offset
0x08E 0x047 2 Boot screen character offset
0x090 0x048 2 Boot screen map offset
0x092 0x049 2 Boot screen map destination (horizontal)
0x094 0x04A 2 Boot screen map destination (vertical)
0x096 0x04B.L 1 Boot screen map character width
0x097 0x04B.H 1 Boot screen map character height
0x098 0x04C 4 Boot screen VBlank vector (segment and offset)
0x09C 0x04E.L 1 Boot screen name X (horizontal)
0x09D 0x04E.H 1 Boot screen name Y (horizontal)
0x09E 0x04F.L 1 Boot screen name X (vertical)
0x09F 0x04F.H 1 Boot screen name Y (vertical)
0x0A0 0x050 2 (Unknown)
0x0A2 0x052 2 Boot screen sound sample offset
0x0A4 0x053 * Boot screen sound data offsets (see below)
Remainder Boot screen program and data

The console boot program sets up WRAM in the following way:

0x00000 - 0x007FF Working memory
0x00800 - 0x00FFF Screen 1 map
0x01000 - 0x017FF Screen 2 map
0x01800 - 0x01FFF Sprites
0x02000 - 0x03FFF Characters
0x04000 - 0x05FFF (Not used)
0x06000 - 0x0677F Copy of internal EEPROM data beginning from byte offset 0x080
0x06780 - 0x07FFF (Unknown)
0x08000 - 0x0FDFF (Not used)
0x0FE00 - 0x0FFFF Palettes

"Offset" fields in EEPROM data are relative to WRAM address 0x06000.

The boot screen name color may be one of the following RGB values as described in Palettes (Color):

0x00
0x000
0x08
0x07F
0x01
0xF00
0x09
0x00F
0x02
0xF70
0x0A
0x70F
0x03
0xFF0
0x0B
0xF0F
0x04
0x7F0
0x0C
0xF07
0x05
0x0F0
0x0D
0xFFF
0x06
0x0F7
0x0E
0x777
0x07
0x0FF
0x0F
0x777

The boot screen data size setting specifies the number of bytes to copy from internal EEPROM beginning at byte offset 0x080 into WRAM at address 0x06000. May be one of the following values:

0x00 0x380 bytes
0x01 0x780 bytes

The boot screen color settings byte has the following structure:

7 6 5 4 0
Bpp
- Palettes
1 2 5
- These bits have no significance and are ignored.
Bpp Characters are processed as 1 bit per pixel when clear and 2 bits per pixel planar when set.
Palettes The number of palettes to load from EEPROM data.

The console boot program will supply an empty second bit plane for 1bpp characters when loading them into WRAM. The character memory beginning at WRAM address 0x02000 is always in 2bpp planar format.

The boot screen map destination fields depend on whether the boot screen is being displayed with horizontal or vertical orientation according to the orientation flag in the ROM header. They are offsets relative to WRAM address 0x00800, to be copied into the map for screen 1.

The boot screen VBlank vector is a formal 32-bit segment/offset pair that is used by the console boot program to run code defind in internal EEPROM data during VBlank. The VBlank code in the EEPROM is expected to be located in segment 0x0600 and return with an out-of-segment RET instruction with a 0xCB opcode. When it returns, the following register configuration is required:

PS 0x0600
DS0 0x0600
SS 0x0000

Boot screen sound data offsets are a list of 16-bit offsets into WRAM address 0x06000. One offset may be provided for each sound channel used by the custom boot screen, and the list is terminated by specifying the offset 0xFFFF.

Editor's Note: Research is needed to determine the behavior of invalid name color values.

Editor's Note: Research is needed to determine the behavior of invalid size setting values.

Editor's Note: Need to verify the memory map. The console boot program itself needs to be mapped somewhere.

Editor's Note: Research is needed to determine how sprites are initialized. Perhaps it loads them from an offset located at byte offset 0x0A0?

Editor's Note: Need to verify the significance of the data size setting.

Editor's Note: Research is needed to determine the exact significance of the start and end frame fields.

Editor's Note: Research is needed to determine exactly how map contents are processed in the vertical orientation.

Editor's Note: Research is needed to determine exactly how the name is positioned in the vertical orientation.

Editor's Note: Research is needed to determine how many sound channels are to be used by the custom boot screen.

Editor's Note: Research is needed to determine how many sound samples are loaded.

Editor's Note: Research is needed to determine the significance of the sound data.


ERAL - Erase All

Erases the entire contents of EEPROM such that every bit of every word becomes set.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 0
Subop 2
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
E 1

While the instruction is underway, Ready will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Ready will be set.

If writes are not enabled via EWEN, this instruction will be ignored.

Editor's Note: This instruction is not guaranteed to be supported on all cartridges with EEPROM.

Editor's Note: Need to verify whether the implementation prohibits this instruction from being used on internal EEPROM.


ERASE - Erase

Erases the contents of the specified word in internal EEPROM such that every bit in the word becomes set.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 3
Address The word address to erase.
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
E 1

While the instruction is underway, Ready will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Ready will be set.

If writes are not enabled via EWEN, this instruction will be ignored.

Editor's Note: Need to verify whether the implementation prohibits this instruction from being used on internal EEPROM.


EWDS - Erase/Write Disable

Deactivates write-enable status. While writes are disabled, ERAL, ERASE, WRAL and WRITE instructions will be ignored.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 0
Subop 0
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
E 1

While the instruction is underway, Ready will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Ready will be set.


EWEN - Erase/Write Enable

Activates write-enable status. While writes are enabled, ERAL, ERASE, WRAL and WRITE instructions can be used.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 0
Subop 3
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
E 1

While the instruction is underway, Ready will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Ready will be set.


READ - Read

Reads the value of the specified word in EEPROM and stores it in IN_SERIAL_DATA or CART_SERIAL_DATA.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 2
Address The word address to read.
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
R 1

While the instruction is underway, Done will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Done will be set and the value can be input from IN_SERIAL_DATA or CART_SERIAL_DATA.

Editor's Note: When reading from internal EEPROM, the boot program and WonderWitch API poll Done in a loop and abort if it stays clear for 32 consecutive iterations.


WRAL - Write All

Writes the specified value to the entire contents of EEPROM.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 0
Subop 1
 
IN_SERIAL_DATA
CART_SERIAL_DATA
Data The word value to write.
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
W 1

While the instruction is underway, Ready will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Ready will be set.

If writes are not enabled via EWEN, this instruction will be ignored.

Editor's Note: This instruction is not guaranteed to be supported on all cartridges with EEPROM.

Editor's Note: Need to verify whether the implementation prohibits this instruction from being used on internal EEPROM.


WRITE - Write

Writes the specified value to the specified word in EEPROM.

This instruction is issued with the following port confuguration:

IN_SERIAL_COM
CART_SERIAL_COM
SB 1
Opcode 1
Address The word address to write.
 
IN_SERIAL_DATA
CART_SERIAL_DATA
Data The word value to write.
 
IN_SERIAL_CTRL
CART_SERIAL_CTRL
W 1

While the instruction is underway, Ready will be clear in IN_SERIAL_CTRL or CART_SERIAL_CTRL. When the instruction completes, Ready will be set.

If writes are not enabled via EWEN, or if P has been set in IN_SERIAL_CTRL and Address in IN_SERIAL_COM0x30, this instruction will be ignored.

Editor's Note: The boot program polls Ready in a loop and aborts if it stays clear for 0x1600 consecutive iterations.

Editor's Note: Even if write-protected mode is in effect for internal EEPROM, it is possible to write the value 0x0000 to any word address by setting R in IN_SERIAL_CTRL instead of W and monitoring Done in IN_SERIAL_CTRL. The reason this works is because the console clocks another 16 bits in anticipation of receiving a value from the EEPROM, but since Opcode = 1, the EEPROM is also expecting a value and interprets the quiet pin state as 16 zeroes.


RTC - Real-Time Clock

A cartridge with a 2003 mapper may contain a real-time clock (RTC) component for keeping track of time using only power from a battery inside the cartridge itself. The 2003 mapper is responsible for communicating with both the program and the RTC.

Contents
Registers
Ports
Commands
Interrupts


Registers

The RTC component holds its state in a small set of registers.

Real-Time Data Register

A 56-bit register that holds the current real date and time information. Organized into 7 bytes with the following format:

0
7 0
Year
8
4
7 6 5 0
AMPM
- Hour
1 1 6
1
7 5 4 0
- Month
3 5
5
7 6 0
- Minute
1 7
2
7 6 5 0
- Date
2 6
6
7 6 0
- Second
1 7
3
7 3 2 0
- Day
5 3
- R These bits have no significance and are clear when read.
Year R/W The last two digits of the calendar year.
Month R/W The 1-based index of the calendar month.
Date R/W The 1-based day of the calendar month.
Day R/W The zero-based day of the calendar week.
AMPM R/W Specifies time in AM when clear and PM when set.
Hour R/W The hour of the time.
Minute R/W The minute of the time.
Second R/W The second of the time.

All fields except AMPM express numbers in binary-coded decimal (BCD) format.

When writing date and time information, each field has a valid BCD range. If the value being written is not within this range, a default value is substituted for that field:

Field Range Default
Year 00 to 99 00
Month 01 to 12 01
Date 01 to 31 [note] 01
Day 0 to 6 0
Hour (12-hour) 00 to 11 00
Hour (24-hour) 00 to 23 00
Minute 00 to 59 00
Second 00 to 59 00

[note] If the specified day of the month is not valid for the specified month (accounting for leap years), the date will be advanced to the first day of the following month.

The RTC component does not specify which day of the week corresponds to each numeric value in Day.

While in 24-hour mode, the value read from AMPM will be clear if Hour is 11 or less, or will be set otherwise. While in 24-hour mode, writes to AMPM are ignored.

Editor's Note: The highest-order bit of the seconds byte will indicate when the RTC component is in test mode, but the 2003 mapper cannot activate test mode. This bit will always be clear when read.

Status Register

An 8-bit register that holds processing state and accepts commands. Has the following format:

7 6 5 4 3 2 1 0
POWER
1224
INTAE
-
INTME
-
INTFE
-
1 1 1 1 1 1 1 1
- R These bits have no significance and are clear when read.
POWER R Set if a power cycle occurred, or clear otherwise (see below).
1224 R/W Specifies 12-hour mode when clear or 24-hour mode when set.
INTAE R/W Used to configure the interrupt mode (see below).
INTME R/W Used to configure the interrupt mode.
INTFE R/W Used to configure the interrupt mode.

If the RTC component loses power, POWER will become set. The most likely cause for this is if the battery in the cartridge dies, meaning POWER also signals a loss of RTC data. POWER is cleared whenever the status register is read or a reset command is issued.

The value of 1224 influences the range of values read from and written to the Hour field in the real-time data register.

INTAE, INTME and INTFE jointly specify the RTC's interrupt mode:

INTAE INTME INTFE Mode
0 0 0 Disabled
(Any) 0 1 Selected frequency steady
(Any) 1 0 Per-minute edge
(Any) 1 1 Per-minute steady
1 0 0 Alarm

Alarm Time/Frequency Duty Setting Register

Supplies additional configuration when the RTC's interrupt mode is either alarm or selected frequency steady.

This register holds 16 bits of data and is organized into two bytes. It is intended to by write-only: reads will give the byte values 0xFF, 0xFF and set the contents of the register to 0xFF, 0xFF.

When the RTC's interrupt mode is alarm, this register has the following format:

0
7 6 5 0
AMPM
- Hour
1 1 6
1
7 6 0
- Minute
1 7
- W These bits are not used in alarm mode.
AMPM W The AM/PM state to match for the alarm.
Hour W The hour to match for the alarm.
Minute W The minute to match for the alarm.

For information regarding interrupt opearation, see Alarm.

When the RTC's interrupt mode is selected frequency steady, this register has the following format:

0
7 6 5 4 3 2 1 0
256 Hz
512 Hz
1024 Hz
2048 Hz
4096 Hz
8192 Hz
16384 Hz
32768 Hz
1 1 1 1 1 1 1 1
1
7 6 5 4 3 2 1 0
1 Hz
2 Hz
4 Hz
8 Hz
16 Hz
32 Hz
64 Hz
128 Hz
1 1 1 1 1 1 1 1

Each bit corresponds to a square wave signal with a duty cycle of 50% high followed by low with a period of the specified frequency. When the bit is set, the signal is enabled; when the bit is clear, the signal is disabled.

For information regarding interrupt opearation, see Selected Frequency Steady.


Ports

RTC data is output to and input from the following I/O port:

0xCB Byte RTC_DATA RTC data
7 0
Data
8
Data R/W Bits used during an RTC communication.

For read operations, this port contains data received from the RTC. For write operations, the contents of this port are sent to the RTC for processing.

RTC communications are managed through the following port:

0xCA Byte RTC_CTRL RTC control
7 6 5 4 3 1 0
Ready
-
Active
Cmd
WR
1 2 1 3 1
- R These bits have no significance and are clear when read.
Ready R Set when the program should access RTC_DATA, or clear otherwise.
Active R/W When set, a communication with the RTC is underway.
Cmd R/W The RTC command code to process.
WR R/W Performs a write operation when clear or a read operation when set.

Any output to RTC_CTRL will reset the 2003 mapper's RTC handling to the start of the specified command. If the program outputs to RTC_CTRL before processing for the previous command completes, the states of the 2003 mapper and the RTC will become desynchronized and produce undefined behavior until such a time they fall into sync with one another again.

During command processing, the program should not access RTC_DATA while Ready is clear. When the 2003 mapper is ready for the program to manage more data, Ready will be set automatically.

When a valid RTC command completes, Active will be cleared automatically.

Cmd specifies what kind of RTC command is being initiated:

0 Reset
1 Status register access
2 Real-time data register access, begin at byte 0
3 Real-time data register access, begin at byte 4
4 Alarm time/frequency duty setting register access
5 No operation
6 Invalid
7 Invalid

When WR is clear, the command is a write command. When WR is set, the command is a read command. For information regarding communications, see Commands.

Editor's Note: Outputs to RTC_CTRL will send a control byte to the RTC. The value of the control byte is 0x60 ORed with the lower 4 bits of RTC_CTRL. If RTC_CTRL is outputted to in the middle of an incomplete write command, it is possible for the bits of the control byte to be stored in an RTC register.


Commands

Outputting to RTC_CTRL will initiate a read or a write command. Data will either be transfered into RTC_DATA for reads or out of RTC_DATA for writes.

When multiple bytes are being transferred, the program will need to access RTC_DATA multiple times. When the 2003 mapper has finished processing a byte and is ready for the program to handle data, Ready will be set in RTC_CTRL, which the program can check before performing an access to RTC_DATA. As soon as RTC_DATA is accessed as required, command processing resumes.

When the program outputs to RTC_CTRL, the 2003 mapper performs an algorithm equivalent to the following:

If an invalid command was specified:
× Abort command processing
For each byte to be processed:
Clear Ready in RTC_CTRL
If performing a read operation:
Retrieve a byte from the RTC into RTC_DATA
Otherwise (performing a write operation):
Send a byte from RTC_DATA to the RTC
If the last byte was just processed:
× Exit the loop
Set Ready in RTC_CTRL
If performing a read operation:
Wait for the program to input from RTC_DATA
Otherwise (performing a write operation):
Wait for the program to output to RTC_DATA
Advance to the next byte
Set Ready in RTC_CTRL
Clear Active in RTC_CTRL

Note that this algorithm begins as soon as RTC_CTRL is outputted to, meaning a value should be staged in RTC_DATA in advance of write operations.

If Ready is set after command processing terminates, it will be cleared the next time the program accesses RTC_DATA. This is the case regardless of whether that access is an input or an output, and regardless of whether the RTC operation was a read or a write.

Editor's note: During a read operation, outputs to RTC_DATA are ignored if both Ready and Active are set in RTC_CTRL. Research is needed to determine whether outputs to RTC_DATA are always ignored during read operations while Active is set.

Reset

Erases the contents of the registers so that all the fields have their default values.

This command is initiated by outputting the following to RTC_CTRL:

Active 1
Cmd 0
WR (Any)

This command does not transfer any bytes with the RTC. After this command completes, the contents of the registers will be as follows:

Real-time data register:
Year 00
Month 01
Date 01
Day 0
AMPM 0
Hour 00
Minute 00
Second 00
Status register:
POWER 0
1224 0
INTAE 0
INTME 0
INTFE 0
Alarm time/frequency duty setting register:
0x00, 0x00

Status Register Access

Performs a read or write operation on the status register.

This command is initiated by outputting the following to RTC_CTRL:

Active 1
Cmd 1
WR (As appropriate)

This command transfers 1 byte that exactly matches the format of the status register.

Real-Time Data Register Access

Performs a read or write operation on the real-time data register.

This command is initiated by outputting the following to RTC_CTRL:

Active 1
Cmd 2 (begin at byte 0), or 3 (begin at byte 4)
WR (As appropriate)

The real-time data register contains 7 bytes of data: 4 date fields followed by 3 time fields. Cmd 2 transfers all 7 bytes beginning with byte 0 (Year), and Cmd 3 transfers 3 bytes and only accesses the time fields beginning with byte 4 (Hour).

Alarm Time/Frequency Duty Setting Register Access

Performs a read or write operation on the alarm time/frequency duty setting register.

This command is initiated by outputting the following to RTC_CTRL:

Active 1
Cmd 4
WR (As appropriate) [note]

[note] The alarm time/frequency duty setting register is not intended to be read. Attempting to read from it has anomalous behavior described below.

This command transfers 2 bytes. When performing a write operation, the bytes exactly match the format of the alarm time/frequency duty setting register. The register is intended to be write-only: performing a read operation on it will return the bytes 0xFF, 0xFF and replace the contents of the register with 0xFF, 0xFF.

No Operation

Performs no meaningful operation.

This command is initiated by outputting the following to RTC_CTRL:

Active 1
Cmd 5
WR (As appropriate)

This command transfers 2 bytes, but otherwise doesn't do anything. Performing a read operation will return the bytes 0xFF, 0xFF.

Invalid

Does not initiate any command. This condition applies when either of the following is outputted to RTC_CTRL:

Active 0
Cmd (Any)
WR (Any)

or:

Active 1
Cmd 6 or 7
WR (Any)

After issuing an invalid command, the 2003 mapper will immediately await another command.


Interrupts

The 2003 mapper can use the RTC to request a cartridge interrupt. RTC interrupts are managed through the status register.

Changing interrupt modes affects the request state according to the behavior of the new mode.

Disabled

The RTC will not request an interrupt.

This interrupt mode is set when the following is configured in the status register:

INTAE 0
INTME 0
INTFE 0

When switching to this mode, any ongoing interrupt request will stop being requested.

Selected Frequency Steady

The RTC will request an interrupt according to a signal configured through the alarm time/frequency duty setting register.

This interrupt mode is set when the following is configured in the status register:

INTAE (Any)
INTME 0
INTFE 1

The alarm time/frequency duty setting register specifies the enabled state of 16 signals, each with a different frequency. All signals have a 50% duty cycle where the start of the high phase is aligned with the edge of the real-time seconds counter. Whenever one or more of the enabled signals is high, an interrupt will be requested.

Per-Minute Edge

The RTC will request an interrupt at the start of every real-time minute.

This interrupt mode is set when the following is configured in the status register:

INTAE (Any)
INTME 1
INTFE 0

Once an interrupt request begins in this mode, it will continue to be requested until the interrupt mode is changed to disabled. If the interrupt mode is subsequently changed to per-minute edge during the first 10 ms of the minute, another interrupt request will occur.

Per-Minute Steady

The RTC will request an interrupt at the start of every real-time minute.

This interrupt mode is set when the following is configured in the status register:

INTAE (Any)
INTME 1
INTFE 1

Once an interrupt request begins in this mode, it will continue to be requested until 30 seconds have gone by or the interrupt mode is changed to disabled. If the interrupt mode is subsequently changed to per-minute steady during the first 10 ms of the minute, another interrupt request will occur.

Alarm

The RTC will request an interrupt whenever the contents of the alarm time/frequency duty setting register exactly match bytes 4 and 5 of the real-time data register.

This interrupt mode is set when the following is configured in the status register:

INTAE 1
INTME 0
INTFE 0

Bytes 4 and 5 of the real-time data register specify the AMPM/Hour fields and the Minute field respectively. Bit 6 of the first byte and bit 7 of the second byte are not considered, but otherwise an interrupt will be requested whenever the alarm time exactly matches the current hour and minute.

The alarm time/frequency duty setting register can store any bits in the time fields, even those that the real-time data register can never contain. This includes invalid combinations of AMPM and Hour, and out-of-range digits for Hour and Minute. If the alarm time bits do not exactly match the current time bits, the RTC will not request an interrupt.


System Reset

System components are initialized in the following ways when the WonderSwan is powered on.

CPU

The following registers are initialized on reset:

DS0 0x0000
DS1 0x0000
PC 0x0000
PS 0xFFFF
PSW 0xF002 [note]
SS 0x0000

[note] All fields in PSW are cleared on reset. The only bits that are set are among those with fixed state.

All other registers are undefined on reset.

Memory Map

The following cartridge ports are initialized on reset:

LINEAR_ADDR_OFF 0xFF
RAM_BANK 0xFF
RAM_BANK_L 0xFF
RAM_BANK_H 0xFF
ROM_BANK_0 0xFF
ROM_BANK_0_L 0xFF
ROM_BANK_0_H 0xFF
ROM_BANK_1 0xFF
ROM_BANK_1_L 0xFF
ROM_BANK_1_H 0xFF

Internal EEPROM

Writes are disabled on reset, but the boot program always enables them before launching the cartridge program.

Write-protected mode is disabled on reset. Unless bit 7 of byte 9 (game version) in the ROM header is set, the boot program will activate write-protected mode.

LCD Panel

The following ports are initialized on reset:

LCD_VTOTAL 0x9E
LCD_VSYNC 0x9B

Editor's Note: Research is needed to determine exactly what state the video features are in upon reset, and what parts of it are initialized by the boot program. For all intents and purposes, it appears that after the boot program runs, all features are is disabled.


About

WonderSwan - Sacred Tech Scroll
March 17, 2023
Written by Guy Perfect

Special thanks to the following individuals:

asie
Bzeep
Flash Masta Developments
FluBBaOfWard
Fredrik Ahlström
Generic
GermanDarkness
Godzil
Kresna
lidnariq
mellott124
The Beesh-Spweesh!
vinheim3
zwenergy

References

WSMan
August 19, 2016
Revision 7
Written by Alex "trap15" Marshall
Link

WonderSwan SplashBuilder
October 10, 2019
GitHub project
Written by Godzil
Link

Everything You Never Wanted to Know about the WonderSwan RTC
December 18, 2020
NesDev.org forum post
Written by lidnariq
Link

WStech
Version 2.1
Written by Judge and Dox
Link

16-Bit V Series™ Instruction User's Manual
September 2000
Document No. U11301EJ5V0UMJ1 (5th edition)
Written by Renesas Technology Corporation
Download

The 8086 Family User's Manual
October 1979
Document No. 9800722-03
Written by Intel Corporation
Link

V30MZ™ Preliminary User's Manual
January 2002
Document No. A13761EJ1V1UM00 (1st edition)
Written by Renesas Technology Corporation
Download

Real-Time Clock S-3511A
Revision 1.4_00
Written by Seiko Epson Corporation
Download

x86 instruction listings
Wikipedia page
Link

And countless hours of original research.


March 17, 2023