diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..45a2cfc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "liblzg"] + path = liblzg + url = https://github.com/mbitsnbites/liblzg.git diff --git a/Makefile b/Makefile index f9fc98b..19040d8 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,21 @@ .POSIX: ASM=$(wildcard src/*.asm) -RES=res.bin/amour.sid res.bin/levels.bin - -ifeq "$(CARTRIDGE)" "1" - FORMAT:=3 -else - FORMAT:=1 -endif +RES=res.bin/amour.sid res.bin/levels.bin res.bin/unlzg.bin .PHONY: debug env clean -bin/snake.prg: env $(ASM) $(RES) bin/explodefont - dasm src/main.asm -Isrc/ -DSYSTEM=64 -DDEBUG=$(DEBUG) -DVERBOSE=$(VERBOSE) -DCARTRIDGE=$(CARTRIDGE) -f$(FORMAT) -sbuild/symbols.txt -obin/snake.prg +bin/snake.bin: bin/snake.pack.lz + dasm src/cart.asm -DVERBOSE=$(VERBOSE) -f3 -sbuild/cart.symbols.txt -obin/snake.bin + +bin/snake.pack: env $(ASM) $(RES) bin/explodefont + dasm src/main.asm -Isrc/ -DSYSTEM=64 -DDEBUG=$(DEBUG) -DVERBOSE=$(VERBOSE) -DCARTRIDGE=$(CARTRIDGE) -f3 -sbuild/pack.symbols.txt -obin/snake.pack + +bin/snake.pack.lz: bin/snake.pack liblzg/src/tools/lzg + liblzg/src/tools/lzg bin/snake.pack > bin/snake.pack.lz + +liblzg/src/tools/lzg: + cd liblzg/src && make clean: rm -rf {build,bin,res.bin} @@ -29,6 +32,9 @@ res.bin/amour.sid: res.bin/levels.bin: bin/level res.org/levels.txt bin/level < res.org/levels.txt > res.bin/levels.bin +res.bin/unlzg.bin: + cp res.org/unlzg.bin res.bin/unlzg.bin + bin/level: util/rlevel.cpp g++ -o bin/level util/rlevel.cpp diff --git a/README.md b/README.md index 7d42f23..039b6a7 100644 --- a/README.md +++ b/README.md @@ -19,19 +19,25 @@ You can also define the following environment variables: ```$ VERBOSE=1 make``` output useful info during compilation -```$ CARTRIDGE=1 make``` produces an 8K bin ready to be burnt to an *PROM - ## Developer docs +### Package +The whole program is assembled into a ```snake.pack``` binary blob with the following structure. + +Absolute | Offset | Description +------------|-------------|------------ +```$1000``` | ```$0000``` | load address +```$2800``` | ```$1800``` | entry point (start address) + ### Memory map Address | PRG | Description ----------------------|-------|------------ ```$0000 - $0001``` | no | hardware ```$0002 - $00FF``` | no | zero page pointers -```$0100 - $07FF``` | no | *free ram* -```$0800 - $0FFF``` | yes | autostart (BASIC or cartridge) + Low Program Segment -```$1000 - $1FFF``` | yes | SID tune + Middle Program Segment +```$0100 - $01FF``` | no | stack page +```$0200 - $07FF``` | no | *free ram* +```$1000 - $1FFF``` | yes | SID tune ```$2000 - $27FF``` | yes | custom char -```$2800 - $xxxx``` | yes | High Program Segment (only needed part used) +```$2800 - $xxxx``` | yes | Program segment (only needed part used) ```$xxxx - $CCFF``` | no | *free ram* ```$CD00 - $CDFF``` | no | data segment (not-initialized vars) ```$CE00 - $CEFF``` | no | list X @@ -39,9 +45,14 @@ Address | PRG | Description ```$D000 - $DFFF``` | no | I/O ```$E000 - $FFFF``` | no | Kernal -Note: program (code) segments have been put in all possible free spots in order to squeeze the game into an 8K cartridge. +### Compression +```snake.pack``` is compressed into ```snake.pack.lz``` using [liblzg](https://github.com/mbitsnbites/liblzg), to save space in order to fit the game in a *PROM. -### Custom charset +### Decompression +```cart.asm``` is located at ```$8000``` (standard org address for C64 cartridges), and contains the decompression routine and the ```snake.pack.lz```. It decompresses ```snake.pack.lz``` back to ```$1000```, and jumps to its entry point at ```$2800```. + +### Miscellanea +#### Custom charset Index | Description ----------------|------------- ```$00 - $1F``` | A-Z (space first) @@ -50,8 +61,3 @@ Index | Description ```$50 - $5F``` | hex digits, reversed ```$60 - ``` | game tiles -### Cartridge -Cartridge version is at $8000 and simply copies itself back at $800. - -Cartridge version can not be built with DEBUG=1 flag due to size constraints. - diff --git a/liblzg b/liblzg new file mode 160000 index 0000000..182b56c --- /dev/null +++ b/liblzg @@ -0,0 +1 @@ +Subproject commit 182b56cb36843720f38eff2ec30db1deac4e85bd diff --git a/res.org/unlzg.bin b/res.org/unlzg.bin new file mode 100644 index 0000000..b6a6bda Binary files /dev/null and b/res.org/unlzg.bin differ diff --git a/src/cart.asm b/src/cart.asm index 8126107..8e3e92c 100644 --- a/src/cart.asm +++ b/src/cart.asm @@ -1,15 +1,21 @@ -#if VERBOSE = 1 -LASTINIT SET . -#endif + processor 6502 + + SEG cartridgeSegment + org $8000 cartridge SUBROUTINE - - WORD #$8009 - WORD #$801a + WORD .coldstart + WORD .warmstart ; CBM80 in PETSCII (cartridge signature for autostart) BYTE #$c3,#$c2,#$cd,#$38,#$30 +.unlzg: + INCBIN "res.bin/unlzg.bin" + +.lzpack: + INCBIN "bin/snake.pack.lz" + .coldstart: sei stx $d016 @@ -20,28 +26,29 @@ cartridge SUBROUTINE cli .warmstart: - ; Copy cartridge content into proper memory location - ldx #$20 - lda #$0 - tay - sta srcPointer - sta dstPointer - lda #>cartridgeStart - sta srcPointer + 1 - lda #$08 - sta dstPointer + 1 -.loop: - lda (srcPointer),y - sta (dstPointer),y - iny - bne .loop - inc srcPointer + 1 - inc dstPointer + 1 - dex - bne .loop + ; address of input compressed data + lda #<.lzpack + sta 26 + lda #>.lzpack + sta 27 + + ; address of output decompressed data + lda #$00 + sta 28 + lda #$10 + sta 29 + jsr .unlzg + + ; jump to program entry + jmp $2800 - jmp start #if VERBOSE = 1 - ECHO "cart.asm @ ",LASTINIT,"len:",(. - LASTINIT) -#endif \ No newline at end of file + ECHO "8k CARTRIDGE SIZE:",(. - $8000),"=",[(. - $8000)d] + ECHO "SPACE LEFT:",($9fff - .),"=",[($9fff - .)d] +#endif + + ; force filler for the *PROM +. = $9fff + BYTE #$ff + diff --git a/src/main.asm b/src/main.asm index e8daa60..6269d38 100644 --- a/src/main.asm +++ b/src/main.asm @@ -20,34 +20,6 @@ ECHO "End of zeropage variables. Space left: ",($90 - .) #endif -; Initialized segments -; ---------------------------------------------------------------------- - SEG autostartSegment -#if CARTRIDGE = 0 - org $801 - INCLUDE "basic.asm" ; BASIC _MUST_ stay at this address -#else - org $800 - INCLUDE "cart.asm" -#endif - INCLUDE "initdata.asm" - -; Program "Segment" Low -; ---------------------------------------------------------------------- -; You just have to fill this empty space, don't you think so? ;-) - INCLUDE "game.asm" - INCLUDE "gameover.asm" - INCLUDE "introreset.asm" - INCLUDE "program.asm" - INCLUDE "subroutines.asm" - INCLUDE "levels.asm" - INCLUDE "intro1.asm" -; Note: some code had to be included at an higher address - -#if VERBOSE = 1 - ECHO "End of Low Program Segment. Space left:",($1000 - .) -#endif - ; SID tune (previously properly cleaned, see HVSC) ; ---------------------------------------------------------------------- SEG sidSegment @@ -55,13 +27,7 @@ sidtune: INCBIN "../res.bin/amour.sid" #if VERBOSE = 1 - ECHO "End of SIDtune at ",. -#endif - INCLUDE "multicolor.asm" - INCLUDE "levelreset.asm" - INCLUDE "outro.asm" -#if VERBOSE = 1 - ECHO "End of Middle Program Segment. Space left:",($2000 - .) + ECHO "End of SIDtune at ",.,"Space left:",($2000 - .) #endif ; Font Data @@ -72,30 +38,26 @@ sidtune: tggsFont: INCLUDE "tggs.asm" -; Program Segment High +; Program Segment ; ---------------------------------------------------------------------- - + SEG programSegment + org $2800 + INCLUDE "program.asm" + INCLUDE "initdata.asm" + INCLUDE "game.asm" + INCLUDE "gameover.asm" + INCLUDE "introreset.asm" + INCLUDE "subroutines.asm" + INCLUDE "levels.asm" + INCLUDE "intro1.asm" + INCLUDE "multicolor.asm" + INCLUDE "levelreset.asm" + INCLUDE "outro.asm" #if VERBOSE = 1 - ECHO "End of High Program Segment at: ",.,"Space left:",($cd00 - .) + ECHO "End of program segment at:",. + ECHO "PACK SIZE:",(. - $1000),"=",[(. - $1000)d] #endif -#if VERBOSE = 1 -#if CARTRIDGE = 0 - ; +2 because of PRG header - ECHO "PRG size:",([. - $801 + 2]d),"dec" -#else - ECHO "BIN size:",([. - $800]d),"dec" -#endif -#endif - -; Uninitialized segments -; ---------------------------------------------------------------------- -; Cartridge locations -; ------------------- - SEG.U cartridgeSegment - org $8000 -cartridgeStart: - ; Data variables ; ----------------- SEG.U dataSegment @@ -113,10 +75,8 @@ listX DS 256 listY DS 256 ; -; coded during december 2017 +; coded 2017, 2018, 2019, 2020 ; by giomba -- giomba at glgprograms.it ; this software is free software and is distributed ; under the terms of GNU GPL v3 license ; - -; vim: set expandtab tabstop=4 shiftwidth=4: