Browse Source

compression routine for cartridge version, temporarily deprecates tape version

compression
giomba 2 years ago
parent
commit
fa2269afb8
  1. 3
      .gitmodules
  2. 24
      Makefile
  3. 32
      README.md
  4. 1
      liblzg
  5. BIN
      res.org/unlzg.bin
  6. 65
      src/cart.asm
  7. 76
      src/main.asm

3
.gitmodules

@ -0,0 +1,3 @@
[submodule "liblzg"]
path = liblzg
url = https://github.com/mbitsnbites/liblzg.git

24
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

32
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.

1
liblzg

@ -0,0 +1 @@
Subproject commit 182b56cb36843720f38eff2ec30db1deac4e85bd

BIN
res.org/unlzg.bin

Binary file not shown.

65
src/cart.asm

@ -1,15 +1,21 @@
#if VERBOSE = 1
LASTINIT SET .
#endif
processor 6502
cartridge SUBROUTINE
SEG cartridgeSegment
org $8000
WORD #$8009
WORD #$801a
cartridge SUBROUTINE
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
jmp start
; 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
#if VERBOSE = 1
ECHO "cart.asm @ ",LASTINIT,"len:",(. - LASTINIT)
#endif
ECHO "8k CARTRIDGE SIZE:",(. - $8000),"=",[(. - $8000)d]
ECHO "SPACE LEFT:",($9fff - .),"=",[($9fff - .)d]
#endif
; force filler for the *PROM
. = $9fff
BYTE #$ff

76
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
; ----------------------------------------------------------------------
#if VERBOSE = 1
ECHO "End of High Program Segment at: ",.,"Space left:",($cd00 - .)
#endif
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
#if CARTRIDGE = 0
; +2 because of PRG header
ECHO "PRG size:",([. - $801 + 2]d),"dec"
#else
ECHO "BIN size:",([. - $800]d),"dec"
#endif
ECHO "End of program segment at:",.
ECHO "PACK SIZE:",(. - $1000),"=",[(. - $1000)d]
#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:

Loading…
Cancel
Save