Potato
Special Function Registers & Hardware
Documentation















Memory Map

The memory map of the VMU is so complicated that I've created a separate page describing it.
 

Special Function Registers:

Most of these names and address of these registers were provided by Alexander of Sega; the ones not provided have been marked as such because they are probably are of interest only to the BIOS (yeah, right!) and future compatibility may not be guaranteed. The unnamed registers that are marked as "not used" probably are not. The actual usage of these bits have been derived from reading other LC processor documentation, analyzing the code of working programs, by Marcus's experimentation, or by guessing. I've tried to keep guessing to a minimum. Also, please note that this document will not be that detailed if more complete documentation already exists in the LC104/108 documentation (see my main vmu page).
 
 

0x100 ACC Accumulator
 

0x101 PSW Program Status Word
 
7
6
5
4
3
2
1
0
CY
AC
-
IRBK1
IRBK0
OV
BNK
-
Carry
Auxiliary Carry (Half carry for BCD)
 
Indirect Register Bank
Indirect Register Bank
Overflow
RAM bank select
 

BNK selects between two memory banks; BNK=1 is the default bank for user programs, and seems generally free for use. BNK=0 is used for system variables and contains the system stack.

There are a lot of system variables, they are listed here (some I don't have good descriptions of yet).  Marcus has some better descriptions, but the last time I cheked he didn't cover as many variables. Here's a quick summary of some interesting ones:

000-00F: Index registers (banks 0-3)
017-01E: Time (year_high, year_low, month, day, hour, minute, second, halfsecond) in BCD format. Updated by a BIOS ISR.
080-0FF: Stack
 

0x102 B B Register

0x103 C C Register

Used for multiplication and division, or can be used as general purpose registers. Here is Marcus’s description:

MUL: Perform a multiplication. The ACC and C registers together form a 16-bit operand (ACC being the high 8 bits, and C being the low 8 bits) which is multiplied by the contents of the B register. The result is a 24-bit number that is stored in the ACC, C and B registers (the high 8 bits are stored in B, the middle 8 bits in ACC, and the low 8 bits in C). CY and OV are set according to the result. AC is not affected.

DIV: Perform a division. The ACC and C registers together form a 16-bit operand (ACC being the high 8 bits, and C being the low 8 bits) which is divided by the contents of the B register. The result is a 16-bit quotient that is stored in ACC and C (the high 8 bits in ACC, and the low 8 bits in C), and an 8-bit remainder that is stored in B. CY and OV are set according to the result. AC is not affected.
 
 

0x104,0x105 TRL,TRH

Table Reference bytes – used by LDC instruction to read from ROM.
 
 

0x106 SP Stack pointer

The Stack Pointer points to the topmost element on the stack. The initial value is $7F, and the stack grows upward from $80 to $FF. The stack is always stored in bank 0, regardless of the BNK setting in the PSW. [marcus]
 
 

0x107 PCON Power Control register

Bit 2: 1=INT0 HOLD

Bit 1: 1=HOLD mode – oscillators stop until RESET (or INT0 if bit 2 is set)

Bit 0: 1=HALT mode – oscillators continue to run, but no code does. Exited by reset or interrupt.

Note: only bit 0 used by VMS code
 
 

0x108 IE Interrupt Enable Control Register

Bit 7: 0=Disable all interrupts requests

These bits may be wrong:
    Bit 4: Enable interrupt from divider circuit / port 1 / port 3 (vector 0x0023)
    Bit 3: Enable interrupt from timer/counter 1 interrupt (vector 0x001b)
    Bit 2: Enable interrupt from external interrupt 1 (vector 0x0013)
    Bit 1: Enable interrupt from timer/counter 0 interrupt (vector 0x000b)
    Bit 0: Enable interrupt from external interrupt 0 (vector 0x0003)
And these are probably right:
    Bit 1,0: controls interrupt priority
                00: INT1 high priority, INT0 low priority
                x1: INT1 low priority, INT0 low priority
                10: INT1 low priority, INT0 high priority
 
 

0x109 IP Interrupt Priority Ranking Control Register

Sets the priority of individual interrupts. 1=high, 0=low
Bit 7: Port 3
Bit 6: VSIO
Bit 5: SIO1
Bit 4: SIO0
Bit 3: T1
Bit 2: T0H
Bit 1: INT3/BT
Bit 0: INT2/T0L
 

0x10A-0x10C Not Used
 

0x10D EXT External Memory Control Register

Bit zero controls memory page and allows execution of firmware. Typically modified with the instruction NOT1 EXT, 0. Because it’s always modified with a NOT instruction, we don’t know the sense of it (whether 1 means user code or firmware). This NOT1 is typically followed with a JMPF instruction to the desired address. It isn't known if the NOT1 takes effect after exactly one instruction, or if the JMPF instruction activates it.

For an example, see code at $1F0, which is the main exit vector

The BIOS clears bit 1 and sets bit 3, but the usage of these bits is unknown.
 
 

0x10e OCR Oscillation Control Register

Normally games run at 32kHz, but two other speeds are available: 600 kHz (used for flash programming, updates to the LCD, and during VMU-VMU communication) and 5 MHz (for use when the Dreamcast is connected). There are two frequency references in the VMU – a 32kHz watch-style crystal and a surface mounted 600 kHz (RC?). I'm not sure where the 5 MHz (or 6 MHz?) oscillator comes from, or its accuracy.

Marcus has a nice description of the individual bits, so rather than plagiarize, I'll just list the most common settings:
$81 – 600 kHz
$A1 – 32 kHz ("subclock mode")
$A3 – 32 kHz ("subclock mode") mode with 600kHz oscillator off. Used in football program.

Sega recommended these settings:
$4d osc_rc Specifies internal RC oscillation for the system clock
$ef osc_xt Specifies crystal oscillation for the system clock
 

Normally the firmware toggles bit 5 to switch between $81 and $A1.

Sören measured the power consumption at different speeds.
 
watch: 0.25mA sleep watch: 0.1mA
getkeys 6MHz: 8.6mA sleep 6MHz: 3.0mA
getkeys 3MHz: 5.4mA sleep 3MHz: 1.65mA
getkeys 600Khz: 2.9mA sleep 600Khz game: 0.55mA
getkeys 300Khz: 2.4mA sleep 300Khz game: 0.35mA
getkeys 32kHz: 0.65mA sleep 32kHz game: 0.15mA
getkeys 16kHz: 0.65mA sleep 16kHz game: 0.15mA

As you can see, the 600kHz mode requires 4.5 times the power of the 32kHz mode. However, since it will run 18 times the instructions of the slower speed, it is more power efficient. The batteries don't last very long as it is, so you can't afford to waste power.

0x10f Not Used
 

0x110-0x115 Timer 0 Registers

0x110 T0CON Timer/Counter 0 Control Register

0x111 T0PRR Timer 0 Prescaler Data Register

0x112 T0L Timer 0 value, low

0x113 T0LR Timer 0 Low Reload Register

0x114 T0H Timer 0 value, high

0x115 T0HR Timer 0 High Reload Register
 
 

0x116-0x117 Not Used
 
 

0x118-0x11D Timer 1 Registers

Timer 1 is primarily used for sound -- it seems to be permanently connected to the piezo buzzer, so if you were to use it for something else it might make some noise. This timer is driven by the CPU's clock, which means that if you change the CPU speed (via OCR), you'll also change the frequency of the tone you are generating. That's usually a bad thing.

I haven't tried generating sounds yet, but the quality of the sound generated isn't -- how should I put it -- quite symphonic.

0x118 T1CNT Timer 1 Control Register

0x119 Not Used

0x11A T1LC Timer 1 Low Compare Data Register

0x11B T1L Timer 1 Low Register

0x11B T1LR Timer 1 Low Reload Register

0x11C T1HC Timer 1 High Compare Data Register

0x11D T1H Timer 1 High Register

0x11D T1HR Timer 1 High Reload Register
 

Alessandro contributed a sound routine to the vmu-dev list (cut and paste into your program):

* ------------------------------------------------------
* Play sound (turns on sound)
*
* ACC = Frequency (can be taken from frequency list below)

playsound:
       ;
       ; ACC = 256 - timer_period
       ;
       ; Timer counts at 32768/6 Hz, so one timer period is
       ; 32768 / (frequency * 6).
       ;
       ; Frequency range is from 21.34 Hz (ACC=0) to 5461.33 Hz (ACC=255)
       ;
       push acc
       ;
       mov #0,t1cnt            ; stop Timer 1 high/low
       ;
       st t1lr                 ; set Timer 1 Low Reload
       ror
       or #$80
       st t1lc                 ; set Timer 1 Low Compare
       ;
       mov #$50,t1cnt          ; start Timer 1 Low
       ;
       pop acc
       ;
       ret
 

* ------------------------------------------------------
* No sound (turns off sound)

nosound:
       mov #0,t1cnt
       ;
       ret
 

frequency_list:
   ;
   ;     Oct. 0  Oct. 1  Oct. 2  Oct. 3  Oct. 4  Oct. 5  Oct. 6   Oct. 7
   ;
   ; C    16,35   32,70   65,41  130,81  261,63  523,25  1046,50  2093,00
   ; C#   17,32   34,65   69,30  138,59  277,18  554,37  1108,74  2217,46
   ; D    18,35   36,71   73,42  146,83  293,66  587,33  1174,66  2349,32
   ; D#   19,45   38,89   77,78  155,56  311,13  622,25  1244,51  2489,02
   ; E    20,60   41,20   82,41  164,81  329,63  659,26  1328,51  2637,02
   ; F    21,83   43,65   87,31  174,61  349,23  698,46  1396,91  2793,83
   ; F#   23,12   46,25   92,50  185,00  369,99  739,99  1479,98  2959,96
   ; G    24,50   49,00   98,00  196,00  392,00  783,99  1567,98  3135,96
   ; G#   25,96   51,91  103,83  207,65  415,30  830,61  1661,22  3322,44
   ; A    27,50   55,00  110,00  220,00  440,00  880,00  1760,00  3520,00
   ; A#   29,14   58,27  116,54  233,08  466,16  923,33  1864,66  3729,31
   ; H    30,87   61,74  123,47  246,94  493,88  987,77  1975,53  3951,07
   ;
   .byte $00,$00,$00,$00,$00,$06,$14,$21,$2E,$39,$45,$4F     ; Octave 0
   .byte $59,$62,$6B,$74,$7B,$83,$8A,$91,$97,$9D,$A2,$A8     ; Octave 1
   .byte $AD,$B1,$B6,$BA,$BE,$C1,$C5,$C8,$CB,$CE,$D1,$D4     ; Octave 2
   .byte $D6,$D9,$DB,$DD,$DF,$E1,$E2,$E4,$E6,$E7,$E9,$EA     ; Octave 3
   .byte $EB,$EC,$ED,$EE,$EF,$F0,$F1,$F2,$F3,$F4,$F4,$F5     ; Octave 4
   .byte $F6,$F6,$F7,$F7,$F8,$F8,$F9,$F9,$F9,$FA,$FA,$FA     ; Octave 5
   .byte $FB,$FB,$FB,$FC,$FC,$FC,$FC,$FD,$FD,$FD,$FD,$FD     ; Octave 6
   .byte $FD,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FE,$FF,$FF     ; Octave 7
 

0x11E-0x11F Not used
 
 

0x120 MCR Mode Control Register

Only set to 9 (%1001) or 0 by VMS code and BIOS.

Bits 5-7: Frequency divide ratio (000=1:1)
Bit 4: Refresh rate: 1=166 Hz, 0=83 Hz
Bit 3: 1=LCD on
Bit 2-1: Display cursor mode. Only initialized to 00, which is cursor off. This probably isn't supported by the VMS.
Bit 0: 0=Character display mode [probably not supported by VMS], 1=graphic display mode
 

0x121 Not Used
 
 

0x122 STAD Start Address Register

Not used by existing VMS code. Initialized to $00 by Chao and Bios code.
 
 

0x123 CNR Character Number Register

Not used by existing VMS code. Bios initializes to $05.
 
 

0x124 TDR Time Division Register

Not used by existing VMS code. Bios initializes to $20.
 
 

0x125 XBNK Bank Address Register

Selects LCD memory bank:

$00= top of LCD screen
$01= bottom of LCD screen
$02= Icon bank (not used by most VMS code, set automatically by the BIOS)
 
 

0x126 Not Used
 
 

0x127 VCCR LCD Contrast Control Register

This seems to go beyond contrast and instead control if the LCD is powered on or not. It’s the only LCD register written before entering during sleep.

mov #%10000000,VCCR ; Turn on LCD Display, and allow writing to the display

Values used: 0, 40, 80, C0

Value $80 is typically used to turn the LCD on, $00 is used to turn it off.

Bit 6 ($40) may be a write-inhibit bit.
 
 

0x128-0x12f Not Used
 
 

0x130-0x135 Serial I/O

0x130 SCON0 SIO0 Control Register. Seems to control the output. Sega describes writing a $00 as 'LSB first'.
Bit 7 controls the clock output SCK0
Bit 6 indicates an overrun (not sure how this is possible on a transmit)
Bit 4 selects 8 bit transfer (0) or 7 bit transfer (1)
Bit 3 controls sending a character - setting it starts transmission of a character. It remains high until the hardware has completed sending the character, and then automatically returns low.
Bit 2 controls the bit order. This bit is set to 1 by the BIOS and it transmits most significant bit first. Their demo code (below) clears this bit and describes itself as least significant bit first.
Bit 1 may indicate end of transfer (1), but it's use isn't totally clear.
Bit 0 controls the interrupt request enable.

0x131 SBUF0 SIO0 Buffer. Writing to this register transmits a byte.

0x132 SBR SIO Baud Rate Generator Register. The demo code below writes a $dd, the chao game writes $F0, and the BIOS writes $FF. Note that since the serial port is synchronous (meaning that both a clock and a data signal are sent), the rate only affects the output. The input rate is determined by a clock that is provided along with the output data.

0x133 Not Used

0x134 SCON1 SIO1 Control Register. Seems to control the input.  Sega describes writing a $00 as 'LSB first'. See the example code for a receive character routine.
Bit 6 indicates an overrun
Bit 4 selects 8 bit transfer (0) or 7 bit transfer (1)
Bit 3 should be set to begin receiving data. It stays high until all bits of the character are received.
Bit 2 seems to control the bit order. This bit is set to 1 by the BIOS and it transmits most significant bit first. Their demo code (below) clears this bit and describes itself as least significant bit first.
Bit 1 gets set to indicate a character has been received. It should be cleared once SBUF1 is read.
Bit 0 controls the interrupt request enable.

0x135 SBUF1 SIO1 Buffer. This register contains the received byte.

Sega provided some code to illustrate serial port communications. sio1 sends an incrementing byte pattern and sio2 receives & displays it. It's intended for the Sega's tools, so it won't work with Marcus's assembler. The three programs are ghead.asm, sio1.asm, and sio2.asm.
 
 

0x136-0x143 Not Used

0x140 Not used, but could be P0.
0x141 Not used, but could be P0DDR

0x144 P1 Port 1

Bit 7 is an output that is only cleared by most VMS code.

The Chao game only clears bits 0,2,3,4 and 7.

Bit 7 - PWM output (0=generate tone from timer 1, 1=don't generate tone)
Bit 6 - buzzer output (manual PIO)
Bit 5 - SCK1 output
Bit 4 - SB1 in/out
Bit 3 - SO1 output. serial output 1 bit. Clear this bit to allow the SIO unit to function.
Bit 2 - SCK0 output. (aka CSCK0) serial output clock. Clear this bit to allow the SIO unit to function.
Bit 1 - SB0 in/out
Bit 0 - SO0 output. serial output 0 bit. Clear this bit to allow the SIO unit to function.
 
 

0x145 P1DDR Port 1 Data Direction Register
Each bit specifies if each wire is is either an input (0) or and output (1).

Not used by most VMS code.

The Chao game writes $85 or $A4 to this port. This would indicate that bits 5 and 0 are messed with:

The BIOS writes $AD, $80, $8D, and $FF to this register. The demo serial code writes a $05 at the beginning of communications and $A4 at the end.
 
 

value
7
6
5
4
3
2
1
0
$85
out
in
in
in
in
out
in
out
$A4
out
in
out
in
in
out
in
in
use ? ? ? ? SO1 SCK0 ? SO0

 
 

0x146 P1FCR Port 1 Function Control Register

Not used by most VMS code.

Described as "P1INT" by LC86104 code, where it controls interrupts.

The Chao game writes $95 or $bf to this port. The Bios writes $BF, $8D, or $00. The demo serial code writes a $05 at the beginning of communications and $BF at the end.
 
 

0x147-0x14b Not (officially) Used

0x148 Unknown BIOS Use
A $00 is written to this location.  This is probably the P2 register controlling a port.

0x149 Not used, but could be P2DDR
 

0x14c P3 Port 3

This port controls the reading of the buttons. Output a $FF to enable the pull-up resistors on these inputs so that you can read them.

Bit
Button
7
Sleep
6
Mode
5
B button
4
A button
3
right
2
left
1
down
0
up

 

0x14d P3DDR

Not used by VMS code.

Since these are dedicated to inputs, you’d think that this would be initialized with a $00.
 
 

0x14e P3INT

Bit 0: Port 3 interrupt control bit: 1=Enable port 3 interrupts, 0=disable port 3 interrupts

Bit 1: Port 3 source flag: Set when a low-level signal is received in port 3.

Bit 2: Port 3 interrupt occur enable
 

0x14F-0x15B Not (officially) Used

0x150 Not used, but could be P4

0x151 Unknown BIOS use,  could be P4DDR

Bit 5 is set by the BIOS. It is probably the P4DDR register.
 

0x154 FLASH programming register

Bit 0 contains the 17th address bit used when programming FLASH. Needed only if you are doing low-level write to the hardware; otherwise let the built-in BIOS FLASH routines manipulate this for you.

Bit 1 contains the flash write enable bit. 1=Allow write, 0=don't.

To write to the flash, follow these steps:
0. Seriously consider the built-in routines. This procedure is not portable. We don't want to upset Sega's release of a 400+ block VMU. [update 9/7/00- there are rumors of sega-produced 4x VMU. We don't know where the extra address bits will be]
1. Set bit 1 of SFR 0x154
2. Perform the following writes (using STF):
    $5555 <- $AA
    $2aaa <- $55
    $5555 <- $a0
3. Clear bit 1 of SFR 0x154
4. Set bit 0 of SFR 0x154 according to address
5. Write out your 128 bytes to the desired address (using STF)
6. If you want to wait for the write to finish:
6a. Read flash status register (use LDF)
6b. Check bit 7 against what you last wrote. If it doesn't match, then go to 6a.
6c. Write is done.
7. Read flash status register (use LDF)
8. Read flash status register again. If bit 6 toggled (from previous read), then repeat step 8
9. Bit 6 has stopped toggling; write is complete
 
 

0x155 Unknown BIOS Use

A $FF is written to this register by the BIOS. This could be a data direction register enabling the control of 0x154 (as if it were P5). This would make sense since a high bit indicates an output.
 

0x15C P7 Port 7 Latch

Bit 0 indicates if the unit is docked to the Dreamcast. A "1" indicates it is and the VMU program should quit.
Bit 1 is used to check if the battery is low. A "1" indicates normal voltage, and a "0" indicates low voltage.
Bits 2 and 3 are also used in conjunction, but their exact function is unknown. Bit 2 is called "ID0" and can be used to generate external interrupt 2. Bit 3 is called "ID1" and can be used to generate external interrrupt 3.

A vmu is connected to another VMU if bit 0=0, bit 2=0, and bit 3=1.

The chao game provides a not-so-helpful example:
c547- 03 5c    | LC547: LD P7
c549- e1 0d    | AND #$0d ;%00001101
c54b- 41 08 ef | BNE #$08,LC53D
c55a- 03 5c    | LD P7
c55c- e1 0d    | AND #$0d ;%00001101
c55e- 90 f7    | BNZ LC557
 
 
 

0x15D I01CR External Interrupt 0, 1 Control Register

Bit 7&6: INT1:
   00=negative edge detected
   01 Low level detected
   10 Positive edge detected
   11 High level detected
Bit 5: INT1 source
Bit 4: INT1 enabled
Bit 3&2: INT0:
   00=negative edge detected
   01 Low level detected
   10 Positive edge detected
   11 High level detected
Bit 1: INT0 source
Bit 0: INT0 enabled
 

0x15E I23CR External Interrupt 2, 3 Control Register
Bit 7: INT3 Positive edge detected
Bit 6: INT3 Negative edge detected
Bit 5: INT3 Interrupt source
Bit 4: INT3 Interrupt enable
Bit 3: INT2 Positive edge detected
Bit 2: INT2 Negative edge detected
Bit 1: INT2 Interrupt source
Bit 0: INT2 Interrupt enable
 

0x15F ISL Input Signal Selection Register

Not used by existing VMS code. (yet)

Bits 5,4:
     x0 Subclock mode (crystal oscillator)
     01 Cycle Clock
     11 Timer T0 Prescaler
Bit 3: 1=fBSR/8, 0=fBSR/16
Bits 2,1: Noise reduction filter
     x0 1 Tcyc
     01 64 Tcyc
     11 16 Tcyc
Bit 0: 1=P7.3/INT3, 0=P7.2/INT2
 

0x160-0x162 Not (officially) Used
The BIOS clears bits 2 and 4, and sets bits 0 and 1.

These registers seem to write data to the Maple bus from the Work RAM.
One little routine does this series of operations:

1. Write 3 to VLREG
2. Clears VSEL.0
3. sets VRMAD1 to 0 (zeros address)
4. writes 32 bytes to VTRBF
5. Sets VSEL.0
6. Sets SFR161.1
7.Waits for SFR161.0 to be set
8. loop lines 2-7
 
 

0x160 VCFLG0? Unknown BIOS Use

The BIOS clears bits 2 and 4, and sets bits 0 and 1.
Related to work RAM.
 

0x161 VCFLG1? Unknown BIOS Use

The BIOS reads this value and also clears bit 2.
Occasionally it waits for bit 0 to be set. Probably related to Maple bus.
 

0x162 VCFLG2? Unknown BIOS Use

Bit 7 is manipulated by the BIOS. It is labeled "SRES".
 

0x163-0x167 VMS section

[actually, marcus has a much better description of this section]

This 512 bytes of RAM is only accessible indirectly through registers.

Example initialization code:

0676- 23 63 10 | MOV #$10,VSEL
0679- 23 64 00 | MOV #$00,VRMAD1
067c- 23 65 00 | MOV #$00,VRMAD2

Once it is initialized, data can be written to it by writing to the send/receive buffer (VTRBF, below). This stores the data in memory and increments the pointer(s) [probably VRMAD1 and/or 2- I’m not sure of the purpose of two separate registers]. The data can be retrieved later by re-initializing (using the code above) and then reading from VTRBF.
 
 

0x163 VSEL VMS Control Register

Bit 0 use unknown. Seems to be 0 is a normal mode, 1 is Maple bus output? Labeled "ASEL: 1=OTAMA, 0=CPU"
Bit 1 use unknown. Labeled "SIOVSEL: 1=Maple, 0=SIO"
Bit 4 is INCE - VRMAD Auto Increment
     If this bit is set, the VRMAD1/VRMAD2 register is automatically incremented after a load or store to VTRBF.
 

0x164 VRMAD1 Work RAM Access Address 1
0x165 VRMAD2 Work RAM Access Address 2

This 9 bit register holds the address of the Work RAM location that can be accessed through VTRBF.
VRMAD1 ($164) holds the 8 least significant bits, VRMAD2 ($165) holds the most significant bit.
 

0x166 VTRBF Send/Receive Buffer

Reads or writes data from the work memory and (optionally) auto-increments a pointer so that the next access of this register will read/write to the next byte in work memory.

0x167 VLREG Length registration

Contains the number of 4-byte words written to the work RAM, minus one.
 
 

0x168-0x17E Not Used

0x168 VADRR?
0x169 VLTMP?
0x16A VPREG?
0x16B VTMP?
 

0x17F BTCR Base Timer Control Register

Bit 1 is cleared by the Chao ISR code. Not used by any other existing VMS code.

Bit 7: 0=16384/fBST, 1=64/fBST
Bit 6: Base timer start
Bit 7,5,4:
     000= 32/fBST
     001=128/fBST
     010=512/fBST
     011=2048/fBST
     100= 32/fBST
     101=128/fBST
     110=2/fBST
     111=8/fBST
Bit 3: Base timer 1 (BT1) interrupt source
Bit 2: Base timer 1 (BT1) interrupt enable
Bit 1: Base timer 1 (BT0) interrupt source
Bit 0: Base timer 1 (BT0) interrupt enable
 
 

0x180-0x1FB SCREEN XRAM

The screen is 48x32 pixels. Each half of this screen is mapped into one of two banks, controlled by XBNK at 0x125. A third bank controls the icons at the bottom of the screen.

0x180-0x1FB - XRAM (Bank 0)[Lines 0 -> 15]
0x180-0x1FB - XRAM (Bank 1)[Lines 16 -> 31]
0x180-0x185 - XRAM (Bank 2)
    File Icon: 0x181, bit 6
    Game Icon: 0x182, bit 4
    Clock Icon: 0x183, bit 2
    Flash access icon: 0x184, bit 0

Accessing these registers requires that the CPU be running at 600 kHz or faster. (See the OCR register, above)

The memory isn’t contiguous; 4 bytes are skipped at the end of every other line:
 
 
col 0-7
8-15
16-23
24-31
32-39
40-47
 
Line 0
$80
81
82
83
84
85
 
1
86
87
88
89
8A
8B
 
2
90
91
92
93
94
95
 
3
96
97
98
99
9A
9B
 
4
A0
A1
A2
A3
A4
A5
 
5
A6
A7
A8
A9
AA
AB
 
6
B0
B1
B2
B3
B4
B5
 
7
B6
B7
B8
B9
BA
BB
 
8
C0
C1
C2
C3
C4
C5
 
9
C6
C7
C8
C9
CA
CB
 
10
D0
D1
D2
D3
D4
D5
 
11
D6
D7
D8
D9
DA
DB
 
12
E0
E1
E2
E3
E4
E5
.
13
E6
E7
E8
E9
EA
EB
.
14
F0
F1
F2
F3
F4
F5
.
15
F6
F7
F8
F9
FA
FB
Bank 0
16
80
81
82
83
84
85
Bank 1
17
86
87
88
89
8A
8B
.
18
90
91
92
93
94
95
.
19
96
97
98
99
9A
9B
.
20
A0
A1
A2
A3
A4
A5
 
21
A6
A7
A8
A9
AA
AB
 
22
B0
B1
B2
B3
B4
B5
 
23
B6
B7
B8
B9
BA
BB
 
24
C0
C1
C2
C3
C4
C5
 
25
C6
C7
C8
C9
CA
CB
 
26
D0
D1
D2
D3
D4
D5
 
27
D6
D7
D8
D9
DA
DB
 
28
E0
E1
E2
E3
E4
E5
 
29
E6
E7
E8
E9
EA
EB
 
30
F0
F1
F2
F3
F4
F5
 
31
F6
F7
F8
F9
FA
FB
 

 

0x1FB-0x1FF Not Used
 
 
 
 

Interrupt Entry Points:

These are interrupt vectors used by the processor and are defined by the hardware. But sure to also check out the BIOS interface.

0x0000 reset/start
    Contains a jump to the start of code.

0x0003 external interrupt 0

0x000b timer/counter 0 interrupt and/or interrupt 1 (unknown)

0x0013 external interrupt 2 or T0 low byte overflow

0x001b External interrupt 3 or Base timer (timer 1) overflow. This timer is used to run the time-of-day clock, so control should be passed to the OS code (see vector below). The user can do other things with this interrupt, too.

0x0023 Timer 0 high byte overflow

0x002b Timer 1 high byte overflow or Timer 1 low byte overflow.

0x0033 SIO 0 interrupt

0x003b RFB interrupt

0x0043 Unknown interrupt.

0x004b P3 interrupt (used to wake the processor when a button is pressed)

0x004f interrupt - BIOS firmware does a "CLR1 IO1CR, 1" and a RETI

0x0052 interrupt - BIOS firmware does a "CLR1 IO1CR, 5" and a RETI

0x0055 interrupt - BIOS firmware does a "CLR1 T0CON, 1" and a "CLR1 I23CR, 5", then a RETI.

0x005a interrupt - BIOS firmware does a "CLR1 T0CON, 3" and a RETI

0x005d interrupt - BIOS firmware does a "CLR1 T1CNT, 1" and a "CLR1 T1CNT, 3", then a RETI.
 
 

Football 0x001b timer/counter 1 interrupt example

Here is some sample interrupt code from VMU football:

L001B: JMP L0130    Upon getting the interrupt, go execute OS hook
L0130: PUSH IE      Save current IE mask
       CLR1 IE, 7   Disable all interrupts
       NOT1 EXT, 0  External Memory Control Register – prepare to switch banks
       JMPF L0130   Jump to the BIOS and let it keep time.
L0139: CALLF $216A  Do football-specific stuff
       POP IE       Return interrupt enables to previous state
       RETI         Return from the interrupt
 
 

back to my vmu page
revised 5/13/00 - added power consumption and tone generation and a few other things.
revised 6/31/00 - added serial I/O stuff.