Videopac G7000 BIOS
Last changed: 2007-02-02

Bank switching

In this chapter I describe both bank switching methods for normal carts: the one to access the full address space of 4K of the 8048 and the one to switch between 4 different address spaces implemented by the G7000. I also talk about more methods which use additional logic in the carts.

8048 switching: MB0 and MB1

To access the upper 2K of the 8048 address space you have to use the command SEL MB1. The next JMP or CALL command jumps to the address with the address bit A11 set. If you used CALL you return as normal with RET, but the next JMP and CALL commands have still bit 11 set. To reset it use SEL MB0. You need this mechanisms if your program is bigger than 1K, because the lower 1K is occupied by the BIOS.

Be careful if you use ASL, it automatically inserts switch commands if it thinks they are needed, see the documentation to ASL for details. This automatic fails before a CALL to a routine inside the other bank, the banks are switched, but stay switched afterwards. To disable this automatic clear bit 11 on all CALL addresses in MB0 and set it on all CALL addresses in MB1 and switch banks as needed by hand.

If the 8048 is executing an interrupt routine it is always in MB0, it is not possible to switch to MB1, SEL MB1 is ignored.

If you want to use the full free address space of 3K remember that nearly all commercial carts don't use A10, so the upper and lower 1K of every bank are identical, which is no problem for MB0 since the lower 1K is ROM. But for MB1 pages 8-0Bh and pages 0Ch-0Fh are identical. This means that including version 0.70 the emulator o2em can't emulate your programs if you use the full 3K. Later versions do support 3K per bank, so this is no longer a problem any more.

G7000 bank switching: P1.0 and P1.1

The G7000 cart slot has 2 pins which can be used to switch the full address space of the 8048, they are connected to P1 of the processor. When using both pins you have 4 times the address space of the 8048. Since the lower 1K is always the BIOS your programs can use up to 12K with G7000RAM or 8K with o2em.

When switching banks using this method everything is switched including the code that triggered the bank switch and the IRQ routines. To make switching easier the BIOS contains 4 routines for bank switching. After switching all routines jump to 0408h, this is the same address selectgame jumps to. The G7000 always starts in bank 3. There are routines to reset one of the bank switch bits called bank01 and bank02, one to reset both bits called bank0 and one to set both bits, this is called bank3. This means you can't switch from bank 1 to bank 2 or vice versa using the BIOS routines. In most cases you need to build your own routine dispatcher at 0408h in every bank to be able to call different routines. Be careful with the IRQ routines, either put them in every bank or disable the IRQ before using banks which don't contain the IRQ routines.

XROM: Musician and 4 in 1 Row: 1 KByte data and 3 KByte code

The Videopac games 31 and 40 use a 4K ROM connected 1:1 to the address lines A0-A11, including A10. So there is code from 0400h-0fffh. The range from 0000h-03ffh can't be used for code as the BIOS has preference there. But the cart also contains a 7400 chip which enables the ROM for read accesses if P11 is 1. This allows data access to the whole ROM from any code position with movx. The upper 4 address lines A8-A11 can be set by writing to P2. Both games only read from 0000h-03ffh, but it is possible to read all 4K of the ROM.

Both games do not work on the Videopac+. At reset P11 is already 1, so the XROM circuit is active. On the normal machines this does not matter as the BIOS jumps into the cart code before initialisation, so the program can clear P11. On the Videopac+ the additional graphics chip gets initialised before any code from the cart gets executed, so there is a bus collision when checking if the VPP is busy.

12/16 KBytes Videopac+ games

Videopac+ graphics data can get quite big, so there are some games which need more ROM space. The games Videopac 55 and 58 are 12K, the games Videopac 59 and 60 are 16K. All four use the same bankswitch method. There are two ROM chips, one 7432, one 7404 and one 74374 inside the cart. The address lines A0-A9 and A11 from the Videopac are connected to the address lines A0-A10 of the ROM chips which results in 2K per bank as usual for commercial carts. The range from 0c00h-0fffh is just a copy of 0800h-0bffh. Any write access to external RAM (P1.4=0, P1.6=0) at address 080h-0ffh stores D0-D2 in the 74374 latch. This is the bank number. The latch gets activated by setting P1.0 to 0. The lower 2 bits of the bank number are the address lines A11 and A12 of the ROM chips, bit 2 decides which ROM chip is used. The 4K ROM in the 12K carts is selected by a 0 in bit 2.

The MegaCART and FlashCART

Both bank switch methods with additional logic can be combined and easily extended to allow up to 1 Mbyte of ROM space. I use this in my MegaCART design. The lower address lines A0-A11 are connected 1:1, this gives 3K code from 0400h-0fffh. You can set a bank number for code by writing to ereg_codebank = 080h in external RAM (P1.4=0, P1.6=0). Another bank number for the data bank can be written into ereg_databank = 081h. The bank numbers contain the address lines A12-A19. Which bank number is used depends on the type of ROM access. The code bank switching is activated by setting P1.0 to 0. Program code is then fetched from the code bank. The XROM read is activated by setting P1.1 to 0. Any movx read then fetches its data from the data bank. Additionally P20-P23 have to be set to A8-A11 of the read address. Usually the interrupts are disabled while the XROM read is active (P1.1=0), because the standard interrupt routines try access the VDC but fail because they don't know about the active XROM.

There are two more registers, one for data output ereg_io_out = 082h and one for data input ereg_io_in = 083h. They are connected to an 93CX6 serial EEPROM. On the FlashCART one of the output bits is used as TX line for the serial port to the PC. The RX line is connected to T0 like on the G7000RAM.

A read to any of the 3 output registers returns the last value written to it. All 4 registers are mirrored every 4 bytes on the current MegaCART/FlashCART hardware, but I have vague plans for other expansion hardware there in the future, so only use 080h-083h for access.

The activation of the XROM read with P1.1=0 is incompatible to Videopac 31 and 40, but allows to use the XROM read on Videopac+ machines. As a result you have 768 KByte for program code and 1 Mbyte for data which includes the code space. On the MegaCART all this is implemented by a single CPLD besides one 27C080 EPROM.

Here is a small code example from a slide show program for the Videopac+. It shows how easy it is to handle big data (the uncompressed char and attribute data) using the XROM read. First some useful macros to enable and disable the XROM. The explicit disable is needed, because the BIOS routines extramenable, vdcenable and plusenable don't know about XROM read and don't turn it off. Here I use another macro as replacement for call plusenable.


; Enable XROM (read and write)
;  P16=0 (enable cart signal), P11=0 (enable XROM), P15=1, P14=1, P13=1, P12=1
m_xromenable macro
        orl     P1,#03ch
        anl     P1,#0bdh
        endm

; Disable XROM reading: P11=1
m_xromdisable macro
        orl     P1,#002h
        endm

; Enable VPP chip
;  P16=0, P15=0, P14=1, P13=1, P12=1, P11=1
m_plusenable macro
        orl     P1,#01eh
        anl     P1,#09fh
        endm

This code copies the char and attribute data directly from XROM uncompressed to the screen. It assumes that the ereg_databank register is already set. The 25th line in ROM is mapped to the service row.


	dis	i		; XROM reading used here
        anl     P2,#0f0h        ; char data starts at X000h
        mov     r2,#0           ; rom pointer
        mov     r3,#0           ; line number
.draws  mov     a,r3
        mov     r6,a
        ; map 24 into service row
        xrl     a,#24
        jnz     .setrow
        mov     r6,#31
.setrow mov     r7,#plus_cmd_brow
        call    pluscmd
        mov     r4,#40
.drawl  m_xromenable
        mov     a,r2
        mov     r0,a
        movx    a,@r0           ; read char from XROM
        mov     r7,a
        inc     r0
        movx    a,@r0           ; read attribute from XROM
        mov     r6,a
        m_plusenable
        call    plusdata
        ; advance ROM pointer
        inc     r2
        inc     r2
        mov     a,r2
        jnz     .skipp2
        in      a,P2
        inc     a
        outl    P2,a
.skipp2 djnz    r4,.drawl       ; loop until line complete
        inc     r3
        mov     a,r3
        xrl     a,#25
        jnz     .draws          ; loop until service row (mapped to 24)
	en	i