Changing the game
The last post hasn’t been that long but already I’ve made a big change: the source in the GIT repository is no longer in ACME format but KickAssembler. The difference isn’t that big at the moment (mostly changing !byte to .byte and comment start with // in stead of ;), but KickAssembler offers a lot more possibilities which I know will come in handy later on.
If you don’t have KickAssembler it may be more of a hassle to set up. It’s build in JAVA, so have to have Java installed on your machine (there is not yet an executable).
In the readme of the repository I’ve included the script I use to build and run the code. I run it from Relaunch64.
I’ve made a tag in git for this part so you can always find the source that fits the part of the blog you’re reading: https://gitlab.com/sipke/willow-recracked/tags/part_7
One of the things I do in the code is generate an additional text file that generates breakpoints when be passed to vice emulator.
you can then set a breakpoint in your code and vice will stop and show the monitor at that point.
java -jar [pathtoKickass]\KickAss.jar RSOURCEFILE -afo x64 -moncommands vice.txt -8 karate.d64 OUTFILE
The game’s format
The game is made up of 64 screens in a 8×8 grid. The playfield in a screen is 256×192 pixels.
That 256×192 playfield is build up from graphic blocks of 32×32 pixels as shown here (lines drawn by eye, so not exact).
A screen is made up of 8×6=48 tiles.
The way the game works is that in memory location $5F the number of the current screen is kept. Zero is top left and $3f is bottom right. In the source I’ve replaced all uses of this address with the variable ‘current_screen’:
L0A00: lda current_screen //
You can use the address above to change a screen from the monitor.
> 5f 00 goto 0a00
This will change the screen to location 0
You can also see that there are no hardcoded addresses any more only labels, except for addresses outside of the loading memory.
In theory this would make all parts easily relocatable, but I’m not yet at that point. Some memory locations are written by self modifying code and those are hard to find. Also if I insert a few lines between the start and the bitmap (residing at $6000) the bitmap data will shift which will corrupt the graphics (but not crash the game!).
But I can swap sprite backups and music data without problems:
hero_princess_sprites_backup: .import binary "sprites_backup.bin" MusicData: .import binary "music_data_and_more.bin"
As you can see I’ve also exported that data to separate files that are imported compile time. Music data and the starting bitmap are also imports now.
At several locations in memory different properties of the screens are kept. For instance there are 64 bytes (1 for every screen) in memory that indicate if and if so what treasure is available in a screen (coin, key, tomato).
Another 64 bytes are used for the screen position of that treasure (higher 4 bits are translated to the X position and lower 4 bits are translated to the Y position).
Some of these things I have documented in the source code, so you can find it and change it yourself.
/*location definitions 64 bytes bit 7: enemy on screen? bit 6: enemy has sword? bit 3: sword */ D42C0: .byte $CB, $90, $C0, $C0, $C0, $9A, $E0, $E0 // .byte $C0, $CC, $E0, $E0, $ED, $9D, $CC, $90 // .byte $99, $ED, $EB, $C8, $9D, $90, $E0, $90 // .byte $E0, $EC, $C0, $EA, $90, $9D, $EB, $C0 // .byte $0D, $E0, $C9, $E0, $CD, $9C, $ED, $90 // .byte $90, $EC, $CD, $90, $9D, $C0, $90, $90 // .byte $C0, $90, $ED, $90, $90, $ED, $CB, $00 // .byte $90, $E0, $0D, $CA, $0D, $C0, $E0, $C0 //
A new beginning
The tile definitions per screen are stored from memory $8000. Each screen definition consists of 48 bytes, 1 byte for each tile (byte 0 is the top left tile, byte 47 is the bottom right tile).
There are 65 screen tile definitions, because the opening screen is also build like this (but with added sprites and some added text).
This gave me an idea. I noticed that the Spectrum (booh!) version has a different opening screen and in some ways a better opening screen. You can see a nice temple and not just some fences.
The Commodore version. Because the Commodore has a higher resolution (320×200, not 256×192) this version adds some swallow to the right.
This was my first version:
A friend of mine said he missed the fences so I added them as well:
The text was interfering too much with the graphics so I moved them down (2) (the texts on the opening screen are added seperately after the tiles).
This is what I changed to the source to change the tile map (original is commented out). The last part (L4160) is how I moved the text, just by adding a value to the writing address of the bitmap and the color memory.
//opening screen definition .byte $2A, $2B, $2C, $2D, $2B, $2C, $2D, $38 .byte $31, $00, $00, $00, $00, $00, $00, $34 .byte $32, $00, $09, $05, $06, $00, $00, $35 .byte $32, $00, $0a, $07, $08, $4f, $00, $35 .byte $33, $3c, $0c, $0b, $0c, $0b, $3d, $36 .byte $39, $2E, $2F, $30, $2E, $2F, $30, $3A /* .byte $2A, $2B, $2C, $2D // .byte $2B, $2C, $2D, $38, $31, $00, $00, $00 // .byte $00, $00, $00, $34, $32, $00, $00, $00 // .byte $00, $00, $00, $35, $32, $3C, $0C, $0B // .byte $0C, $0B, $3D, $35, $33, $00, $00, $00 // .byte $00, $00, $00, $36, $39, $2E, $2F, $30 // .byte $2E, $2F, $30, $3A */ //write copyright text on bitmap, 5 chars lower .eval down = 5 L4160: ldx #$4F // L4162: lda D8A0,X // sta start_bitmap_mem + $1848 + (down*320),X // dex // bpl L4162 // ldx #$0A // lda #$03 // L416F: sta D4708 + (down*40),X //
PS: Don’t worry, I’ll put all graphics and sound back to the orginal formats in the final version.
After cleaning up some empty memory and moving some parts I thought I had enough memory to add some diferent music. I chose the music from Samurai Warrior, because it also has an eastern theme and there is a hyped music when attacking.
To use a different music, you’ll have to have the music-data and the play routine as well, preferably as source because you might want to relocate or change it. I didn’t have the source, but I did have the SID file.
All SID files contain the 6510 code for the music and data. You just have to strip the headers of the file and save as binary.
I imported the binary into my disassembler and created the source like that (it’s included in the repository in the folder alt music). I found out that the code is not easily relocatable, because it’s full of self modyfing code based on hard coded data. So in stead of relocating I copied the music after loading to the original memory location: $E000-$F000 + a few bytes. I still had to change a few zero page references because they overlapped with the game.
This does mean bank switching (1), because the main game had Kernal switched in but the music can’t have that because Kernal is situated in $E000- $FFFF.
This is now the routine the IRQ calls:
start: sei lda #$35 //KERNAL AND BASIC turned off sta $01 jsr music //the original ripped music routine from Samurai lda #$36 //Only BASIC turned off sta $01 jmp $ea31 //continue with standard interrupt
The music is running at the wrong speed at the moment, but it doesn’t matter that much.
I think I have fooled around enough with the game. I’ll take out the changed graphics and music (you can always check out that tag for this part if you want revisit it).
I still have the trainer functions lying around that haven’t been build in yet (and some to write as well).
I’ll leave with this image that is the current intro, which I plan to use as trainer option screen. At the moment it’s not functional, just press space to continue.
(1)Bank switching is the main (only?) difference between a 6502 and a 6510 processor. By changing the value of memory location $01 the processor can read ‘see’ parts of the 64K memory or ROM chips. That way almost all of 64K memory can be used while still having KERNAL, BASIC, standard characters sets.
(2) It later turned out not to be such a good idea: the text at the bottom is seen as a border of the playing field by the game, which blocks some exits, which makes the game impossible.