|
|
 One limitation of the Odyssey 2, and the 8048 in general, is that there are only 8 lines of address latched on the bus and another 4 lines on the lower half of P2 for addressing. Normally, that means 4K would be available; however, on the Odyssey 2 one of those lines is taken up, so only 11 of these lines are used. With the Odyssey 2, memory above 2K is bank selected using P10, P11, and P14. My idea regarding this is to bank switch using a counter and use P10 to increment the counter. At startup, the counter is cleared. This means that the normal 2K bank would be selected. Within the 2K bank, just toggle the clock on the binary counter, and the next instruction will be pulled from the next 2K bank. Now, you could store the desired counter state somewhere, and on every bank you would check if you were there yet, and increment appropriately. I'm using a 27C010 128K X 8-bit EPROM for this. It has 17 lines, so I need to use 6 lines for counting the banks. 2^6=64 banks of 2K each. Really, I've got 2 bits left, so I could use a 27C040, and get 512K bytes of program running on an Odyssey 2, or the equivalent of 256 times the usual program cartridge. I'm not going to get too hung up on the specifics of this. There are many EPROM sizes out there, and many ways to do binary counters. I happen to be using 2 74ls93s, because I have a bunch, but any counter would work.
Here is a picture of how this looks:
The card in the back is an extender card from a "The Voice" module. The devices in the front are TIL-311s. The current 2K page is 0x03D. To test this, I need to create a few banks and see if I can switch between them manually. I can then do this with software. Here is slightly improved, "Hello World" program from this article. Well, "Hello-World1":
cpu 8048
org 0400h
jmp 02C3h ;system start or reset - select game
jmp 0009h ;external IRQ - vblank routine
jmp timer ;timer IRQ
jmp 001Ah ;vblank service - vblank (collision and clock)
jmp start
jmp 0044h ;continuation of vblank service - vblank (tune)
timer retr ; we don't do anything with timer IRQs
start
call 011ch ; stop display
mov r1,#0f4h ; pointer to string "hello world"
mov r0,#10h ; starting character pointer for VDC
mov r2,#0ch ; 12 characters
mov r3,#28h ; x position
mov r4,#70h ; y position
mov r6,#08h ; color blue
putc mov a,r1 ; grab current pointer to string
movp a,@a ; move mem at r1 to accumulator
mov r5,a ; set r5 to character
inc r1 ; increment pointer to character
call 03eah ; print character BIOS routine
djnz r2, putc ; continue for 12 characters
call 0127h ; start display
sixnen jmp sixnen ; while 6 ne 9 (loop forever, i don't mind)
org 04f4h ; force the location of hello world
db 1Dh,12h,0eh,0eh
db 17h,28h,11h,17h
db 13h,0eh,1ah,01h
|
A hex view of this binary:
00000000 44 C3 04 09 84 0C 04 1A 84 0D 04 44 93 34 1C B9 D..........D.4..
00000010 F4 B8 10 BA 0C BB 28 BC 70 BE 08 F9 A3 AD 19 74 ......(.p......t
00000020 EA EA 1B 34 27 84 25 FF FF FF FF FF FF FF FF FF ...4'.%.........
00000030 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000040 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000050 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000060 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000070 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000080 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000090 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
000000A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
000000B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
000000C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
000000D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
000000E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
000000F0 FF FF FF FF 1D 12 0E 0E 17 28 11 17 13 0E 1A 01 .........(......
|
All I have to do to create banks that are identifiable is to change the 01 at the end, there, to different numbers and cat a bunch of them together. Here is how I edit the t2.bin file:
000000F0 FF FF FF FF 1D 12 0E 0E 17 28 11 17 13 0E 1A 02 .........(......
00000100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000120 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000130 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000140 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000150 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00000160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
:w t2.bin
|
Now, just cat the files together for my test EPROM, and copy the binary to a floppy:
usr-1@wrk-1 o2 $ cat /dev/null > tall.bin
usr-1@wrk-1 o2 $ cat t1.bin >> tall.bin
usr-1@wrk-1 o2 $ cat t2.bin >> tall.bin
usr-1@wrk-1 o2 $ cat t3.bin >> tall.bin
usr-1@wrk-1 o2 $ cat t4.bin >> tall.bin
usr-1@wrk-1 o2 $ mcopy tall.bin a:
|
Here is how this looks with the third bank selected:
The display on the breadboard says 02, which is the third bank. You can see that hello-world3 shows up on the screen.
One tricky part is how to trigger P10. It turns out that internal routines step on this line, so what you have to do is change the state of a flip-flop at the rising edge of PSEN. I ran P10 into pin 2 (data) of a 74ls74, PSEN into pin 3 (clock), and ran pin 6 (not q) into the clock input of the 74ls93 (pin 14). The 74ls74 sets Q to D on the rising edge.
Here is a program that will iterate through the banks in software:
cpu 8048
org 0400h
jmp 02C3h ;system start or reset - select game
jmp 0009h ;external IRQ - vblank routine
jmp timer ;timer IRQ
jmp 001Ah ;vblank service - vblank (collision and clock)
jmp start
jmp 0044h ;continuation of vblank service - vblank (tune)
timer retr ; we don't do anything with timer IRQs
start
call 011ch
mov r1,#0f4h ; pointer to string "hello world"
mov r0,#10h ; starting character pointer for VDC
mov r2,#0ch ; 12 characters
mov r3,#28h ; x position
mov r4,#70h ; y position
mov r6,#08h ; color start with grey
putc mov a,r1 ; grab current pointer to string
movp a,@a ; move mem at r1 to accumulator
mov r5,a ; set r5 to character
inc r1 ; increment pointer to character
call 03eah ; print character BIOS routine
djnz r2, putc ; continue for 11 characters
call 0127h ; start display
mov r1,#0ffh
lpo mov r7,#0ffh
lpi djnz r7,lpi
djnz r1,lpo
anl P1,#0feh
mov r1,#0ffh
lpoo mov r7,#0ffh
lpii djnz r7,lpii
djnz r1,lpoo
orl P1,#001h
jmp 0408h
org 04f4h ; force the location of hello world
db 1Dh,12h,0eh,0eh
db 17h,28h,11h,17h
db 13h,0eh,1ah,01h
|
If you create a binary like I did above, and concatenate a bunch of them together, changing the number at the end, this program will display the current bank.
|
|