This is an old post, preserved for reference.
The products and services mentioned within are no longer available.
The tap file version of this game is essentially a digital copy of the data on the tape. This tap file can be used by emulators, but on real hardware it's not as easy, ideally there would be a prg file that could be loaded. I like a challenge, so I got the tap file for that game and tried it out.
This was probably done to get around the limitations of the machine, the game was designed for an unexpanded VIC20, so there was only 4K to play with, so the code is split in two.
The first part is in BASIC, which shows the introduction screen and loads the second part from tape, with is 4K of machine code.
This code at the start checks where the screen RAM is located (address 0x288 or 648 in decimal), and moves it if necessary. The next few pokes are in the 0x900x range, which is writing directly to the VIC video chip. Writing those values to 36866 (0x9002) and 36869 (0x9005) puts it in 22 column mode, sets the video memory address to to 0x1E00 and selects character set 1. The Poke to 36875 (0x900F) sets the border and background colours to white.
The data at the end of the loader is a small bit of machine code which does the actual loading. The loop at line 200 pokes this into a spare location in RAM and then line 300 runs it.
(C:$0301) d 2a1This is from the monitor in the Vice emulator, which is handy for this sort of thing. The command 'd 2a1' disassembled code starting a 0x02A1 (or 673 in decimal as it was in the BASIC program). The code can be broken into three calls to kernal routines and a jump to run the start of code memory.
.C:02a1 A9 01 LDA #$01
.C:02a3 A2 01 LDX #$01
.C:02a5 A0 01 LDY #$01
.C:02a7 20 BA FF JSR $FFBA
.C:02aa A9 00 LDA #$00
.C:02ac A2 00 LDX #$00
.C:02ae A0 1E LDY #$1E
.C:02b0 20 BD FF JSR $FFBD
.C:02b3 A9 00 LDA #$00
.C:02b5 A2 CE LDX #$CE
.C:02b7 A0 1F LDY #$1F
.C:02b9 20 D5 FF JSR $FFD5
.C:02bc 4C 00 12 JMP $1200
.C:02bf 00 BRK
.C:02a1 A9 01 LDA #$01The three calls all follow the same pattern, load the three registers, A, X and Y with values then call a kernal routine. In this case, this is setting up a load operation, and sets the logical, first and second addresses. Here, they are all set to 1, so loads from cassette.
.C:02a3 A2 01 LDX #$01
.C:02a5 A0 01 LDY #$01
.C:02a7 20 BA FF JSR $FFBA
.C:02b2 A9 07 LDA #$07The second kernal routine is setting the load filename, in this case, A is 0, so X and Y are ignored, no filename is used, so just LOAD "".
.C:02b4 A2 A1 LDX #$A1
.C:02b6 A0 02 LDY #$02
.C:02b8 20 BD FF JSR $FFBD
.C:02b3 A9 00 LDA #$00The third routine uses the previously set information to load from file into RAM. A load address is actually specified (0x1FCE) but it isn't used as the secondary address is set to 1 above, so it uses the load address from the file (just like LOAD"*",8,1 does).
.C:02b5 A2 CE LDX #$CE
.C:02b7 A0 1F LDY #$1F
.C:02b9 20 D5 FF JSR $FFD5
.C:02bc 4C 00 12 JMP $1200Finally, with the game code loaded, it jumps to the start of that code and runs the game. The address of 0x1200 is the start of the 4K internal RAM of the VIC20, so loading there has actually overwritten the BASIC loader program, which is why these few instructions were placed in a spare area of RAM (02A1-02FF) outside of the main 4K to avoid being overwritten.
The next step was to extract the loaded information. I went back to the .tap file and loaded the loader program into the Vice emulator. This time, I changed the number of bytes to poke from 29 to 26, so it didn't have the JMP $1200 instruction at the end. That meant it loaded the file, then stopped. I then entered the Vice monitor and saved the block of memory it had loaded.
s "tornado" 0 1000 1DFFThis writes the file "tornado" to device 0 (the host file system - use 8 for a disk image if you prefer), from 0x1000 to 0x1DFF, a 3.5K block that is available on both unexpanded and expanded VIC20s, all of which appears to be used. The s command adds the load address prefix to the file in the correct way, so to test this, you can use the following.
That appears to work, but ideally I want to modify the loader to load the data from disk. The loader code specifies device 1, so will still try to load from tape, even if the loader itself is loaded from disk. It's not just a case of changing the device number, a file name needs to be specified, so I have added that to the start of the data statements, so it appears at 0x02A1.
(C:$02d2) m 02a1>C:02a1 54 4f 52 4e 41 44 4f 00 TORNADO.The code then starts at 0x02A9.
(C:$02d9) d 2a9The first function parameters need to be altered, this time to device 8.
.C:02a9 A9 01 LDA #$01
.C:02ab A2 08 LDX #$08
.C:02ad A0 01 LDY #$01
.C:02af 20 BA FF JSR $FFBA
.C:02b2 A9 07 LDA #$07The second function now sets the filename length as 7 characters, and says it is stored at 0x02A1.
.C:02b4 A2 A1 LDX #$A1
.C:02b6 A0 02 LDY #$02
.C:02b8 20 BD FF JSR $FFBD
.C:02bb A9 00 LDA #$00The third function is unchanged, and still has the unused load address.
.C:02bd A2 CE LDX #$CE
.C:02bf A0 1F LDY #$1F
.C:02c1 20 D5 FF JSR $FFD5
.C:02c4 A9 01 LDA #$01I have added a forth function call, this one closes the file after it has been loaded. Those four together are the equivalent of LOAD "TORNADO",8,1.
.C:02c6 20 C3 FF JSR $FFC3
This modified code was hand assembled and converted into decimal and added to the data statements. What fun I had doing that. The final change was line 300 now runs the code at 0x02A9 (681 in decimal).
The final step was to make a D64 image. I used CBM Transfer to create a new empty D64 and copied the files in, loader first so it would be the default file, then the tornado program itself.
I tested that out in Vice and all was well, so time to try it on some real hardware, loading from an SD2IEC (via the Penultimate Cartridge menu).
I have sent the file to The Future Was 8 Bit (who originally requested it), here is his video of playing it on a real VIC20.