Compare commits
21 Commits
compressio
...
master
Author | SHA1 | Date | |
---|---|---|---|
6054d97cf6 | |||
9c902abb59 | |||
a8319e9fb7 | |||
6e0d335b83 | |||
157c8598e6 | |||
db8707bebf | |||
f67017c9a6 | |||
85ac2cf971 | |||
51477cff9d | |||
b19754f3d5 | |||
61515025a5 | |||
d13e88b0fd | |||
493d69f669 | |||
a41ae70993 | |||
05ed319d93 | |||
2c4130899c | |||
c8199e7144 | |||
a82c9e94fe | |||
2f6a4e6735 | |||
f81f087a13 | |||
55e0a550ea |
31
Makefile
31
Makefile
@ -1,19 +1,36 @@
|
||||
.POSIX:
|
||||
|
||||
ASM=$(wildcard src/*.asm)
|
||||
RES=res.bin/amour.sid res.bin/levels.bin res.bin/unlzg.bin
|
||||
RES=res.bin/amour2.sid res.bin/levels.bin res.bin/unlzg.bin
|
||||
|
||||
.PHONY: debug env clean
|
||||
.PHONY: debug env clean all
|
||||
|
||||
bin/snake.bin: bin/snake.pack.lz
|
||||
dasm src/cart.asm -Isrc/ -DVERBOSE=$(VERBOSE) -f3 -sbuild/cart.symbols.txt -obin/snake.bin
|
||||
all: bin/snake6502.bin bin/snake6502.d64
|
||||
|
||||
bin/snake6502.bin: bin/snake.pack.lz
|
||||
dasm src/cart.asm -Isrc/ -f3 -T1 -sbuild/cart.symbols.txt -obin/snake6502.bin
|
||||
|
||||
bin/snake6502.d64: bin/loader.prg
|
||||
c1541 -format "snake6502,01" d64 bin/snake6502.d64
|
||||
c1541 -attach bin/snake6502.d64 -write bin/loader.prg loader
|
||||
c1541 -attach bin/snake6502.d64 -write bin/snake.pack.lz.prg packlz
|
||||
|
||||
bin/loader.prg: bin/snake.pack.lz.prg
|
||||
dasm src/loader.asm -Isrc/ -f1 -sbuild/loader.sybols.txt -obin/loader.prg
|
||||
|
||||
bin/snake.prg: bin/snake.pack
|
||||
dasm src/prg.asm -Isrc/ -f1 -T1 -sbuild/prg.symbols.txt -obin/snake.prg
|
||||
|
||||
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
|
||||
dasm src/main.asm -Isrc/ -DSYSTEM=64 -DDEBUG=$(DEBUG) -f3 -T1 -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
|
||||
|
||||
bin/snake.pack.lz.prg: bin/snake.pack.lz
|
||||
echo -n -e "\x00\x80" > bin/snake.pack.lz.prg
|
||||
cat bin/snake.pack.lz >> bin/snake.pack.lz.prg
|
||||
|
||||
liblzg/src/tools/lzg:
|
||||
cd liblzg/src && make
|
||||
|
||||
@ -26,8 +43,8 @@ env:
|
||||
bin/explodefont: util/explodefont.cpp
|
||||
g++ -o bin/explodefont util/explodefont.cpp
|
||||
|
||||
res.bin/amour.sid:
|
||||
cp res.org/amour.sid res.bin/amour.sid
|
||||
res.bin/amour2.sid:
|
||||
cp res.org/amour2.sid res.bin/amour2.sid
|
||||
|
||||
res.bin/levels.bin: bin/level res.org/levels.txt
|
||||
bin/level < res.org/levels.txt > res.bin/levels.bin
|
||||
|
69
README.md
69
README.md
@ -1,23 +1,35 @@
|
||||
# snake6502
|
||||
|
||||
![Intro screenshot](scrot/intro.png)
|
||||
![Gameplay screenshot](scrot/gameplay.png)
|
||||
|
||||
*snake6502* is a snake-like game clone for Commodore home computers, written for fun because «I always wanted to code something for a computer of my retrocomputers collection – actually, this is the main reason I collect them: to write programs».
|
||||
|
||||
Download the [binary .prg](dist/snake.prg).
|
||||
|
||||
Current development status [here](https://git.giomba.it/giomba/snake6502).
|
||||
|
||||
## Download
|
||||
* [.d64](dist/snake6502.d64) for floppy disks
|
||||
* [.bin](dist/snake6502.bin) for 8KiB cartridges
|
||||
|
||||
## Compile
|
||||
You need the GNU compiler collection and the [dasm](https://dasm-assembler.github.io/) macro assembler, then:
|
||||
```
|
||||
$ git submodule init
|
||||
$ git submodule update
|
||||
$ make
|
||||
```
|
||||
Interesting targets:
|
||||
|
||||
* ```make bin/snake6502.bin``` produces .bin, ready to be burnt on an 8K EEPROM for making a cartridge
|
||||
* ```make bin/snake6502.d64``` produces .d64, ready to be used for floppy disks
|
||||
|
||||
You can also define the following environment variables:
|
||||
|
||||
```$ DEBUG=1 make``` build with debugging artifacts
|
||||
|
||||
```$ VERBOSE=1 make``` output useful info during compilation
|
||||
## Tape
|
||||
Copy ```loader.prg``` and ```packlz``` from disk to tape.
|
||||
On a physical machine, you can use [disk2tape](https://git.giomba.it/giomba/cbmutil).
|
||||
|
||||
## Developer docs
|
||||
### Package
|
||||
@ -34,30 +46,55 @@ Address | PRG | Description
|
||||
```$0000 - $0001``` | no | hardware
|
||||
```$0002 - $00FF``` | no | zero page pointers
|
||||
```$0100 - $01FF``` | no | stack page
|
||||
```$0200 - $07FF``` | no | *free ram*
|
||||
```$1000 - $1FFF``` | yes | SID tune
|
||||
```$2000 - $27FF``` | yes | custom char
|
||||
```$0200 - $03FF``` | no | operating system variables
|
||||
```$0400 - $07FF``` | no | video memory
|
||||
```$1000 - $1FFF``` | yes | SID tune, may overlap charset
|
||||
```$2000 - $23FF``` | yes | custom char, unused, allow SID overlap
|
||||
```$2400 - $27FF``` | yes | custom char (actual 0x80+)
|
||||
```$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
|
||||
```$CF00 - $CFFF``` | no | list Y
|
||||
```$CD00 - $CFFF``` | no | data segment (not-initialized vars)
|
||||
```$D000 - $DFFF``` | no | I/O
|
||||
```$E000 - $FFFF``` | no | Kernal
|
||||
|
||||
### 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.
|
||||
```snake.pack``` is compressed into ```snake.pack.lz``` using [liblzg](https://github.com/mbitsnbites/liblzg), to save space, mainly in order to fit the game in a *PROM.
|
||||
Decompression occurs with one of the following loaders.
|
||||
|
||||
### Decompression
|
||||
### Loader
|
||||
#### Cartridge
|
||||
```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```.
|
||||
#### Disk
|
||||
```loader.asm``` loads at ```$801```, like any other BASIC automatic runner, and contains the decompression routine.
|
||||
```snake.pack.lz``` is loaded at ```$8000``` from disk drive, then decompressed back to ```$1000```, and finally the loader jumps to the program entry point at ```$2800```.
|
||||
|
||||
### Miscellanea
|
||||
#### Custom charset
|
||||
Index | Description
|
||||
----------------|-------------
|
||||
```$00 - $1F``` | A-Z (space first)
|
||||
```$20 - $3F``` | A-Z, reversed (space first)
|
||||
```$40 - $4F``` | hex digits
|
||||
```$50 - $5F``` | hex digits, reversed
|
||||
```$60 - ``` | game tiles
|
||||
```$00 - $7F``` | unused (space for SID)
|
||||
```$80 - $9F``` | A-Z (space first)
|
||||
```$A0 - $BF``` | A-Z, reversed (space first)
|
||||
```$C0 - $CF``` | hex digits
|
||||
```$D0 - $DF``` | hex digits, reversed
|
||||
```$E0 - $EF``` | game tiles
|
||||
```$F0 - $FF``` | semigraphic tiles
|
||||
|
||||
##### Semigrahic Tiles
|
||||
Char | Output
|
||||
----------|--------
|
||||
```$F0``` | ```◜```
|
||||
```$F1``` | ```◝```
|
||||
```$F2``` | ```◟```
|
||||
```$F3``` | ```◞```
|
||||
```$F4``` | ```-```
|
||||
```$F5``` | ```|```
|
||||
```$F6``` | ```◢```
|
||||
```$F7``` | ```◣```
|
||||
```$F8``` | ```◥```
|
||||
```$F9``` | ```◤```
|
||||
```$FA``` | ```┴```
|
||||
```$FB``` | ```┬```
|
||||
```$FC``` | ```┤```
|
||||
```$FD``` | ```├```
|
||||
|
||||
|
BIN
dist/snake.prg
vendored
BIN
dist/snake.prg
vendored
Binary file not shown.
BIN
dist/snake6502.bin
vendored
Normal file
BIN
dist/snake6502.bin
vendored
Normal file
Binary file not shown.
BIN
dist/snake6502.d64
vendored
Normal file
BIN
dist/snake6502.d64
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
res.org/amour2.sid
Normal file
BIN
res.org/amour2.sid
Normal file
Binary file not shown.
BIN
scrot/intro.png
Normal file
BIN
scrot/intro.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
10
src/cart.asm
10
src/cart.asm
@ -1,12 +1,13 @@
|
||||
processor 6502
|
||||
|
||||
; SEGMENTS
|
||||
SEG.U zeropageSegment
|
||||
org $02
|
||||
INCLUDE "zeropage.asm"
|
||||
|
||||
SEG cartridgeSegment
|
||||
SEG loaderSegment
|
||||
org $8000
|
||||
|
||||
; LOADER
|
||||
SEG loaderSegment
|
||||
cartridge SUBROUTINE
|
||||
WORD .coldstart
|
||||
WORD .warmstart
|
||||
@ -47,12 +48,9 @@ cartridge SUBROUTINE
|
||||
; decompression util
|
||||
INCLUDE "lzgmini.asm"
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "8k CARTRIDGE SIZE:",(. - $8000),"=",[(. - $8000)d]
|
||||
ECHO "SPACE LEFT:",($9fff - .),"=",[($9fff - .)d]
|
||||
#endif
|
||||
|
||||
; force filler for the *PROM
|
||||
. = $9fff
|
||||
BYTE #$ff
|
||||
|
||||
|
29
src/data.asm
29
src/data.asm
@ -1,9 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
; Data section - Not initialized variables ($CD00 - $CDFF)
|
||||
; ----------------------------------------------------------------------
|
||||
SEG.U dataSegment
|
||||
; Number of interrupt
|
||||
; Used as counter to be decremented to do some things less frequently
|
||||
irqn:
|
||||
@ -54,6 +49,22 @@ delayStatus:
|
||||
score:
|
||||
WORD
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "data.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
||||
; vertical scroll intro
|
||||
introYscroll:
|
||||
BYTE
|
||||
|
||||
; interrupt raster line to draw moustache
|
||||
moustacheLine:
|
||||
BYTE
|
||||
|
||||
; horizontal intro scroll
|
||||
XScrollOffset:
|
||||
BYTE
|
||||
XScrollDirection:
|
||||
BYTE
|
||||
XCharOffset:
|
||||
BYTE
|
||||
|
||||
; Lists for snake head and tail
|
||||
listX DS 256
|
||||
listY DS 256
|
||||
|
1287
src/font.asm
Normal file
1287
src/font.asm
Normal file
File diff suppressed because it is too large
Load Diff
10
src/game.asm
10
src/game.asm
@ -1,7 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
SEG programSegment
|
||||
statusPlay: ; do Game
|
||||
; Check counter
|
||||
ldx irqn
|
||||
@ -335,9 +332,4 @@ checkEndWallHit:
|
||||
sta (tileMem),y
|
||||
|
||||
skipPauseTests:
|
||||
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "game.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
@ -1,7 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
SEG programSegment
|
||||
; Game is over
|
||||
; ----------------------------------------------------------------------
|
||||
gameover:
|
||||
@ -24,7 +21,3 @@ gameover:
|
||||
lda #ST_DELAY
|
||||
sta status
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "gameover.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
@ -1,7 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
SEG programSegment
|
||||
; Initialized variables
|
||||
; ----------------------------------------------------------------------
|
||||
|
||||
@ -25,11 +22,20 @@ delay:
|
||||
; Status of the game (costants pre-processor defined, sort of enum)
|
||||
ST_INTRO0 = 0
|
||||
ST_INTRO1 = 1
|
||||
ST_LEVEL_TITLE = 2
|
||||
ST_LEVEL_LOAD = 3
|
||||
ST_PLAY = 4
|
||||
ST_DELAY = 5
|
||||
ST_END = 6
|
||||
ST_INTRO2 = 2
|
||||
ST_INTRO3 = 3
|
||||
ST_INTRO4 = 4
|
||||
ST_INTRO5 = 5
|
||||
ST_INTRO6 = 6
|
||||
ST_INTRO7 = 7
|
||||
ST_INTRO8 = 8
|
||||
ST_MENURESET = 64
|
||||
ST_MENU = 65
|
||||
ST_LEVEL_TITLE = 128
|
||||
ST_LEVEL_LOAD = 129
|
||||
ST_PLAY = 130
|
||||
ST_DELAY = 131
|
||||
ST_END = 132
|
||||
ST_PAUSE = 255
|
||||
|
||||
; Screen features
|
||||
@ -38,10 +44,10 @@ SCREEN_H = 24
|
||||
|
||||
; Tiles
|
||||
; -----
|
||||
EMPTY_TILE = $60
|
||||
SNAKE_TILE = $61
|
||||
FOOD_TILE = $62
|
||||
WALL_TILE = $63
|
||||
EMPTY_TILE = $e0
|
||||
SNAKE_TILE = $e1
|
||||
FOOD_TILE = $e2
|
||||
WALL_TILE = $e3
|
||||
|
||||
; Tiles colors
|
||||
; Note: these colors will be picked by the level select routine
|
||||
@ -62,16 +68,6 @@ WALL_COLOR:
|
||||
gameoverString:
|
||||
BYTE "GAME IS OVER"
|
||||
BYTE #0
|
||||
intro0string:
|
||||
#if SYSTEM = 64
|
||||
BYTE " SNAKE BY GIOMBA "
|
||||
#else
|
||||
BYTE " SNAKE16 BY GIOMBA "
|
||||
#endif
|
||||
BYTE #0
|
||||
intro1string:
|
||||
BYTE " PRESS SPACE TO PLAY "
|
||||
BYTE #0
|
||||
intro2string:
|
||||
BYTE "RETROFFICINA.GLGPROGRAMS.IT"
|
||||
BYTE #0
|
||||
@ -79,26 +75,38 @@ intro3string:
|
||||
#if DEBUG = 1
|
||||
BYTE "DBG RELS"
|
||||
#else
|
||||
BYTE "(C) 2018"
|
||||
BYTE "2017 (C) 2021"
|
||||
#endif
|
||||
BYTE #0
|
||||
levelIntroString:
|
||||
BYTE "NEXT LEVEL"
|
||||
BYTE #0
|
||||
colorshade: ; a gradient of dark-bright-dark (40 columns)
|
||||
HEX 0b 0b 0b 0b 0b 0c 0c 0c 0c 0c 05 05 05 0d 0d 0d 0d 07 07 07 07 07 07 0d 0d 0d 0d 05 05 05 0c 0c 0c 0c 0c 0b 0b 0b 0b 0b
|
||||
scoreString:
|
||||
BYTE "SCORE PART"
|
||||
BYTE #0
|
||||
noMoreLevelsString:
|
||||
BYTE "NO MORE LEVELS"
|
||||
BYTE #0
|
||||
introStringA1:
|
||||
BYTE "RETROFFICINA"
|
||||
BYTE #$0
|
||||
introStringA2:
|
||||
BYTE "AND"
|
||||
BYTE #$0
|
||||
introStringA3:
|
||||
BYTE "GIOMBA"
|
||||
BYTE #$0
|
||||
introStringA4:
|
||||
BYTE "PRESENT"
|
||||
BYTE #$0
|
||||
introStringA5:
|
||||
BYTE "A COMMODORE 64"
|
||||
BYTE #$0
|
||||
introStringA6:
|
||||
BYTE "VIDEOGAME"
|
||||
BYTE #$0
|
||||
|
||||
; Levels
|
||||
; ----------------------------------------------------------------------
|
||||
levelsList:
|
||||
INCBIN "../res.bin/levels.bin"
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "initdata.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
728
src/intro1.asm
728
src/intro1.asm
@ -1,86 +1,656 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
SEG zeropageSegment
|
||||
introDestPtr WORD
|
||||
|
||||
; Currently statusIntro0 is the same as statusIntro1
|
||||
; statusIntro1 has just been reserved for future use
|
||||
statusIntro0:
|
||||
statusIntro1:
|
||||
; Decrement interrupt divider for the intro
|
||||
ldx introCounter
|
||||
dex
|
||||
stx introCounter
|
||||
cpx #0
|
||||
beq status1do ; if divider is 0, then do status1do ...
|
||||
rts ; ... else just do nothing and return
|
||||
status1do:
|
||||
; Reset introCounter
|
||||
ldx #5
|
||||
stx introCounter
|
||||
SEG programSegment
|
||||
introreset SUBROUTINE
|
||||
jsr multicolorOff
|
||||
|
||||
; I want to print strings at different columns to make them
|
||||
; bounce across the screen, so take last introX and add introXinc,
|
||||
; then print string at that point. If introX is too far right, then
|
||||
; set introXinc as #$ff (equals -1) so next time introX will be
|
||||
; decremented by 1. And then, if introX is too far left, then
|
||||
; set introXinc as #$01 so next time will be moved to right again.
|
||||
lda introX
|
||||
clc
|
||||
adc introXinc ; this is #$01 or #$0ff, so actually it is +1 or -1
|
||||
sta introX
|
||||
cmp #19 ; am I too far right?
|
||||
beq status1setSX ; if yes, set SX (left)
|
||||
cmp #0 ; am I too far left?
|
||||
beq status1setDX ; if yes, set DX (right)
|
||||
jmp status1okset ; else do nothing (aka, next time re-use current
|
||||
; increment value)
|
||||
status1setDX:
|
||||
lda #$01 ; set introXinc as +1
|
||||
sta introXinc
|
||||
jmp status1okset
|
||||
status1setSX:
|
||||
lda #$ff ; set introXinc as -1
|
||||
sta introXinc
|
||||
jmp status1okset
|
||||
jsr clearScreen
|
||||
|
||||
status1okset:
|
||||
; Print "SNAKE BY GIOMBA" (see above for pointer details)
|
||||
lda #<intro0string
|
||||
sta srcStringPointer
|
||||
lda #>intro0string
|
||||
sta srcStringPointer + 1
|
||||
; $0428 is 2nd line (previously filled with color shades by reset routine)
|
||||
lda #$28
|
||||
clc
|
||||
adc introX ; just add X, to make it look like it has moved
|
||||
sta dstScreenPointer
|
||||
lda #$04
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
; Set screen colors
|
||||
lda #0
|
||||
sta $d020 ; overscan
|
||||
sta $d021 ; center
|
||||
|
||||
; Print "PRESS SPACE TO PLAY"
|
||||
lda #<intro1string
|
||||
sta srcStringPointer
|
||||
lda #>intro1string
|
||||
sta srcStringPointer + 1
|
||||
; $0478 is 4th line (previously filled with color shades by reset routine)
|
||||
; add #19, then sub introX will make it move to other way of 2nd line
|
||||
lda #$78
|
||||
clc
|
||||
adc #19 ; add #19
|
||||
sec
|
||||
sbc introX ; sub introX
|
||||
sta dstScreenPointer
|
||||
lda #$04
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
lda #14
|
||||
sta introYscroll
|
||||
|
||||
; for "GLGPROGRAMS" at the beginning
|
||||
ldx #$78
|
||||
stx introDestPtr
|
||||
ldy #$04
|
||||
sty introDestPtr + 1
|
||||
|
||||
; GLGPROGRAMS color
|
||||
ldy #$00
|
||||
lda #$02
|
||||
.colorLoop:
|
||||
sta $d800,y
|
||||
sta $d900,y
|
||||
sta $da00,y
|
||||
sta $db00,y
|
||||
dey
|
||||
bne .colorLoop
|
||||
|
||||
; first raster interrupt line, for moustaches
|
||||
lda #68+18
|
||||
sta moustacheLine
|
||||
|
||||
; Some considerations on speed:
|
||||
; yes, maybe I should have put the string chars once in screen text memory
|
||||
; and then move it left and right. Should re-think about this.
|
||||
; For now, just return.
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "intro1.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
||||
statusIntro0 SUBROUTINE
|
||||
; arrives raster interrupt, move moustache one line below
|
||||
inc moustacheLine
|
||||
|
||||
lda $d011 ; load current vertical offset from VIC-II
|
||||
and #$07
|
||||
cmp #$07
|
||||
beq .nextline ; if 7, then it is next text line
|
||||
inc $d011 ; else setup moustache interrupt to trigger next raster line...
|
||||
jsr setupMoustacheInterrupt
|
||||
rts ; ...and return: my job here is done
|
||||
|
||||
.nextline:
|
||||
lda $d011 ; reset raster offset to 0...
|
||||
and #$f8
|
||||
sta $d011
|
||||
|
||||
MOV_WORD_MEM dstPointer, introDestPtr
|
||||
MEMSET "D", #$80, #40
|
||||
|
||||
clc ; ... move introDestPtr to next text line ...
|
||||
lda introDestPtr
|
||||
adc #40
|
||||
sta introDestPtr
|
||||
lda introDestPtr + 1
|
||||
adc #0
|
||||
sta introDestPtr + 1
|
||||
|
||||
MOV_WORD_MEM dstPointer, introDestPtr
|
||||
MEMCPY "D", #GLGProgramsText, #200 ; ... and copy "GLG Programs" text to next text line
|
||||
|
||||
dec introYscroll ; remember that we are one line below
|
||||
beq .next ; if we reached the end of the vertical scroll, advance status
|
||||
|
||||
jsr setupMoustacheInterrupt ; else just continue with the moustache
|
||||
rts
|
||||
|
||||
.next:
|
||||
lda #ST_INTRO1
|
||||
sta status
|
||||
rts
|
||||
|
||||
setupMoustacheInterrupt SUBROUTINE
|
||||
; Store in $314 address of our custom interrupt handler
|
||||
ldx #<.moustacheInterruptH
|
||||
ldy #>.moustacheInterruptH
|
||||
stx $314
|
||||
sty $315
|
||||
|
||||
; Set raster beam to trigger interrupt at row
|
||||
lda moustacheLine
|
||||
sta $d012
|
||||
|
||||
rts
|
||||
|
||||
.moustacheInterruptH:
|
||||
; "higher" moustache interrupt (on the right of the screen)
|
||||
; +36
|
||||
dec $d019 ; +42, EOI
|
||||
lda #$02 ; +44, color
|
||||
sta $d020 ; +48, color
|
||||
nop ; +50, timing
|
||||
nop ; +52, timing
|
||||
nop ; +54, timing
|
||||
bit $02 ; +57, timing
|
||||
lda #$00 ; +59, color
|
||||
sta $d020 ; +63, color
|
||||
|
||||
; second line, +0
|
||||
inc $0800 ; + 6, timing
|
||||
inc $0800 ; +12, timing
|
||||
inc $0800 ; +18, timing
|
||||
inc $0800 ; +24, timing
|
||||
inc $0800 ; +30, timing
|
||||
inc $0800 ; +36, timing
|
||||
inc $0800 ; +42, timing
|
||||
lda #$02 ; +44, color
|
||||
sta $d020 ; +48, color
|
||||
inc $0800 ; +54, timing
|
||||
bit $02 ; +57, timing
|
||||
lda #$00 ; +59, color
|
||||
sta $d020 ; +63, color
|
||||
|
||||
; set raster beam low
|
||||
ldx #<.moustacheInterruptL
|
||||
ldy #>.moustacheInterruptL
|
||||
stx $314
|
||||
sty $315
|
||||
clc
|
||||
lda moustacheLine
|
||||
adc #23 ; "lower" moustache is 23 raster lines below higher one
|
||||
sta $d012
|
||||
|
||||
jmp $ea31
|
||||
|
||||
.moustacheInterruptL:
|
||||
; "lower" moustache interrupt (on the left of the screen)
|
||||
; +36
|
||||
dec $d019 ; +42, EOI
|
||||
inc $0800 ; +48, timing
|
||||
inc $0800 ; +54, timing
|
||||
lda #$02 ; +56, color
|
||||
bit $0800 ; +60, timing
|
||||
bit $02 ; +63, timing
|
||||
|
||||
; newline
|
||||
sta $d020 ; + 4, color
|
||||
lda #$00 ; + 6, timing
|
||||
inc $0800 ; +12, timing
|
||||
inc $0800 ; +18, timing
|
||||
nop ; +20, timing
|
||||
sta $d020 ; +24, color
|
||||
lda #$02 ; +26, color
|
||||
bit $0800 ; +30, timing
|
||||
inc $0800 ; +36, timing
|
||||
inc $0800 ; +42, timing
|
||||
inc $0800 ; +48, timing
|
||||
inc $0800 ; +54, timing
|
||||
inc $0800 ; +60, timing
|
||||
bit $02 ; +63, timing
|
||||
|
||||
; newline
|
||||
sta $d020 ; + 4, color
|
||||
lda #$00 ; + 6, color
|
||||
inc $0800 ; +12, timing
|
||||
inc $0800 ; +18, timing
|
||||
sta $d020 ; +22, color
|
||||
|
||||
ldx #<irq ; restore main raster interrupt handler
|
||||
ldy #>irq
|
||||
stx $314
|
||||
sty $315
|
||||
lda #$00
|
||||
sta $d012
|
||||
|
||||
jmp $ea31
|
||||
|
||||
GLGProgramsText: ; fancy PETSCII-looking brand name
|
||||
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f0,#$f4,#$80,#$80,#$80,#$f0,#$f4,#$80,#$80,#$f0,#$f4,#$f1,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
||||
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f5,#$80,#$80,#$f5,#$80,#$f5,#$80,#$80,#$80,#$f5,#$80,#$f5,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f1,#$80,#$80,#$80,#$f0,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4
|
||||
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f5,#$80,#$f5,#$f5,#$80,#$f5,#$80,#$f5,#$80,#$fd,#$f4,#$f3,#$f0,#$f0,#$f1,#$f0,#$f1,#$f0,#$f0,#$fc,#$f0,#$fb,#$f1,#$f2,#$f1,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
||||
BYTE #$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f2,#$f4,#$fc,#$f2,#$f4,#$f2,#$f4,#$fc,#$80,#$f5,#$80,#$80,#$f5,#$f2,#$f3,#$f2,#$fc,#$f5,#$f2,#$f3,#$f5,#$f5,#$f5,#$f4,#$f3,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
||||
BYTE #$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$f4,#$fa,#$f4,#$f4,#$f4,#$f4,#$f3,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$f3,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80,#$80
|
||||
|
||||
statusIntro1 SUBROUTINE
|
||||
; continue moving moustaches down, up to 4 raster lines (middle of text)
|
||||
lda $d011
|
||||
and #$07
|
||||
cmp #$04
|
||||
beq .next ; if interrupt is in the middle, don't move it anymore, and...
|
||||
inc $d011
|
||||
inc moustacheLine
|
||||
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
rts
|
||||
|
||||
.next:
|
||||
jsr setupMoustacheInterrupt ; ... always remember to display moustache, anyhow ...
|
||||
|
||||
lda counter ; wait for song synchronization up to interrupt $0080
|
||||
cmp #$80
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$00
|
||||
bne .end
|
||||
|
||||
ldy #$0
|
||||
lda #$07
|
||||
.colorLoop:
|
||||
sta $d940,y
|
||||
iny
|
||||
cpy #200
|
||||
bne .colorLoop
|
||||
|
||||
lda #ST_INTRO2
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro2 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; "RETROFFICINA"
|
||||
lda #<introStringA1
|
||||
sta srcStringPointer
|
||||
lda #>introStringA1
|
||||
sta srcStringPointer + 1
|
||||
lda #$48
|
||||
sta dstScreenPointer
|
||||
lda #$05
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
lda counter
|
||||
cmp #$08
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$01
|
||||
bne .end
|
||||
lda #ST_INTRO3
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro3 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; "AND"
|
||||
lda #<introStringA2
|
||||
sta srcStringPointer
|
||||
lda #>introStringA2
|
||||
sta srcStringPointer + 1
|
||||
lda #$a5
|
||||
sta dstScreenPointer
|
||||
lda #$05
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
lda counter
|
||||
cmp #$86
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$01
|
||||
bne .end
|
||||
lda #ST_INTRO4
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro4 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; "GIOMBA"
|
||||
lda #<introStringA3
|
||||
sta srcStringPointer
|
||||
lda #>introStringA3
|
||||
sta srcStringPointer + 1
|
||||
lda #$f9
|
||||
sta dstScreenPointer
|
||||
lda #$05
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
lda counter
|
||||
cmp #$08
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$02
|
||||
bne .end
|
||||
|
||||
MEMSET #$540, #$80, #200
|
||||
|
||||
lda #ST_INTRO5
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro5 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; "PRESENT"
|
||||
lda #<introStringA4
|
||||
sta srcStringPointer
|
||||
lda #>introStringA4
|
||||
sta srcStringPointer + 1
|
||||
lda #$50
|
||||
sta dstScreenPointer
|
||||
lda #$05
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
lda counter
|
||||
cmp #$80
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$02
|
||||
bne .end
|
||||
|
||||
lda #ST_INTRO6
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro6 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; "A COMMODORE 64"
|
||||
lda #<introStringA5
|
||||
sta srcStringPointer
|
||||
lda #>introStringA5
|
||||
sta srcStringPointer + 1
|
||||
lda #$9d
|
||||
sta dstScreenPointer
|
||||
lda #$05
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
lda counter
|
||||
cmp #$08
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$03
|
||||
bne .end
|
||||
|
||||
lda #ST_INTRO7
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro7 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; "VIDEOGAME"
|
||||
lda #<introStringA6
|
||||
sta srcStringPointer
|
||||
lda #>introStringA6
|
||||
sta srcStringPointer + 1
|
||||
lda #$ef
|
||||
sta dstScreenPointer
|
||||
lda #$05
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
lda counter
|
||||
cmp #$80
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$03
|
||||
bne .end
|
||||
|
||||
lda #ST_INTRO8
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusIntro8 SUBROUTINE
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
; blank wait
|
||||
lda counter
|
||||
cmp #$16
|
||||
bne .end
|
||||
lda counter + 1
|
||||
cmp #$04
|
||||
bne .end
|
||||
|
||||
lda #ST_MENURESET
|
||||
sta status
|
||||
|
||||
.end:
|
||||
rts
|
||||
|
||||
statusMenuReset SUBROUTINE
|
||||
lda #$05
|
||||
ldy #$0
|
||||
.lastlineColorLoop:
|
||||
sta $db98,y
|
||||
iny
|
||||
cpy #80
|
||||
bne .lastlineColorLoop
|
||||
|
||||
; Print Game Title: big "SNAKE"
|
||||
MEMSET #$d800, #$02, #280 ; color
|
||||
MEMCPY #$400, #SnakeText, #280 ; text
|
||||
|
||||
; Print PETSCII GLG Programs
|
||||
MEMSET #($6a8 + $d800 - $400), #$02, #200 ; color
|
||||
MEMCPY #$6a8, #GLGProgramsText, #200 ; text
|
||||
|
||||
; Print website
|
||||
lda #<intro2string ; lsb of string address
|
||||
sta srcStringPointer ; put into lsb of source pointer
|
||||
lda #>intro2string ; do the same for msb of string address
|
||||
sta srcStringPointer + 1 ; put into msb of source pointer
|
||||
lda #$9e ; this is lsb of address of 23th line
|
||||
sta dstScreenPointer ; put into lsb of dest pointer
|
||||
lda #$07 ; do the same for msb of adress of 20th line
|
||||
sta dstScreenPointer + 1 ; put into msb of dest pointer
|
||||
jsr printString ; print
|
||||
|
||||
; Print Copyright
|
||||
lda #<intro3string ; the assembly is the same as above,
|
||||
sta srcStringPointer ; just change string to be printed
|
||||
lda #>intro3string ; and line (24th line)
|
||||
sta srcStringPointer + 1
|
||||
lda #$ce
|
||||
sta dstScreenPointer
|
||||
lda #$07
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
; boat-shaped horizontal line (rounded edges toward the top)
|
||||
; this overwrites the "present" word from the intro
|
||||
lda #$f2 ; 3rd quadrant
|
||||
sta $540
|
||||
lda #$f3 ; 4th quadrant
|
||||
sta $567
|
||||
lda #$07 ; color for edges
|
||||
sta $540+$d800-$400
|
||||
sta $567+$d800-$400
|
||||
ldy #$1
|
||||
.boatLineLoop:
|
||||
lda #$f4 ; horizontal line
|
||||
sta $540,y
|
||||
lda #$07
|
||||
sta $540+$d800-$400,y
|
||||
iny
|
||||
cpy #39
|
||||
bne .boatLineLoop
|
||||
|
||||
lda #$05
|
||||
sta XCharOffset
|
||||
|
||||
jsr setupMoustacheInterrupt ; never forget the magic moustaches
|
||||
|
||||
lda #ST_MENU
|
||||
sta status
|
||||
rts
|
||||
|
||||
SnakeText:
|
||||
HEX 80 80 80 80 80 80 80 80 f6 a0 a0 f9 80 f7 80 80 f6 80 f6 a0 a0 f7 80 f7 80 80 80 f6 a0 a0 f9 80 80 80 80 80 80 80 80 80
|
||||
HEX 80 80 80 80 80 80 80 80 a0 80 80 80 80 a0 f7 80 a0 80 a0 80 80 a0 80 a0 f6 f7 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
||||
HEX 80 80 80 80 80 80 80 80 a0 80 80 80 80 a0 a0 f7 a0 80 a0 80 80 a0 80 a0 a0 f9 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
||||
HEX 80 80 80 80 80 80 80 80 f8 a0 a0 f7 80 a0 f8 a0 a0 80 a0 a0 a0 a0 80 a0 f9 80 80 a0 a0 80 80 80 80 80 80 80 80 80 80 80
|
||||
HEX 80 80 80 80 80 80 80 80 80 80 80 a0 80 a0 80 f8 a0 80 a0 80 80 a0 80 a0 f7 80 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
||||
HEX 80 80 80 80 80 80 80 80 80 80 80 a0 80 a0 80 80 a0 80 a0 80 80 a0 80 a0 a0 f7 80 a0 80 80 80 80 80 80 80 80 80 80 80 80
|
||||
HEX 80 80 80 80 80 80 80 80 f6 a0 a0 f9 80 f8 80 80 f8 80 f9 80 80 f8 80 a0 f8 f9 80 f8 a0 a0 f7 80 80 80 80 80 80 80 80 80
|
||||
|
||||
;ParabolicSpaceChars:
|
||||
; HEX 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;ParabolicSpaceScroll:
|
||||
; HEX 00 01 01 01 01 01 01 01 02 02 02 03 03 04 04 05 06 06 07 00 00 01 02 03 04 05 06 07 00 01 02 04 05 06 00 01 02 04 05 07 00 02 04 05 07 00 01 03 04 06 00 01 03 04 06 07 00 02 03 04 06 07 00 01 02 03 04 05 06 07 00 01 02 02 03 04 04 05 05 06 06 06 07 06 07 07 07 07 07 07 07
|
||||
|
||||
setupXScrollInterrupt SUBROUTINE
|
||||
ldx #<XScrollInterruptH
|
||||
ldy #>XScrollInterruptH
|
||||
stx $314
|
||||
sty $315
|
||||
|
||||
; Set raster beam to trigger interrupt at row
|
||||
lda #42
|
||||
sta $d012
|
||||
|
||||
rts
|
||||
|
||||
XScrollInterruptH SUBROUTINE
|
||||
|
||||
lda $d016
|
||||
and #$f8
|
||||
ora XScrollOffset
|
||||
sta $d016
|
||||
|
||||
dec $d019
|
||||
|
||||
ldx #<XScrollInterruptL
|
||||
ldy #>XScrollInterruptL
|
||||
stx $314
|
||||
sty $315
|
||||
lda #110
|
||||
sta $d012
|
||||
|
||||
jmp $ea31
|
||||
|
||||
XScrollInterruptL SUBROUTINE
|
||||
lda $d016
|
||||
and #$f8
|
||||
sta $d016
|
||||
|
||||
dec $d019
|
||||
|
||||
ldx #<XScrollInterruptMoveAll
|
||||
ldy #>XScrollInterruptMoveAll
|
||||
stx $314
|
||||
sty $315
|
||||
lda #120
|
||||
sta $d012
|
||||
|
||||
jmp $ea31
|
||||
|
||||
XScrollInterruptMoveAll SUBROUTINE
|
||||
dec $d019 ; EOI
|
||||
|
||||
tsx
|
||||
dex
|
||||
|
||||
lda XCharOffset
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta $100,x
|
||||
lda $d016
|
||||
and #$07
|
||||
ora $100,x
|
||||
|
||||
inx
|
||||
txs
|
||||
|
||||
cmp #78
|
||||
bcs .isEdge
|
||||
cmp #3
|
||||
bcc .isEdge
|
||||
cmp #70
|
||||
bcs .isMiddle
|
||||
cmp #10
|
||||
bcc .isMiddle
|
||||
jmp .enter
|
||||
|
||||
.isMiddle:
|
||||
lda counter
|
||||
and #$01
|
||||
beq .enter
|
||||
jmp .next
|
||||
|
||||
.isEdge:
|
||||
lda counter
|
||||
and #$03
|
||||
beq .enter ; ah, some good spaghetti code to accomodate for far branch
|
||||
jmp .next ; bounce slower
|
||||
|
||||
.isCenter:
|
||||
.enter:
|
||||
lda XScrollDirection
|
||||
and #$01
|
||||
bne .goRight
|
||||
.goLeft:
|
||||
dec XScrollOffset
|
||||
lda XScrollOffset
|
||||
and #$07
|
||||
cmp #$07
|
||||
beq .continue1
|
||||
jmp .next
|
||||
.continue1:
|
||||
lda #$07
|
||||
sta XScrollOffset
|
||||
.moveEverythingLeft:
|
||||
dec XCharOffset
|
||||
ldy #0
|
||||
.loop1:
|
||||
lda $401,y
|
||||
sta $400,y
|
||||
lda $429,y
|
||||
sta $428,y
|
||||
lda $451,y
|
||||
sta $450,y
|
||||
lda $479,y
|
||||
sta $478,y
|
||||
lda $4a1,y
|
||||
sta $4a0,y
|
||||
lda $4c9,y
|
||||
sta $4c8,y
|
||||
lda $4f1,y
|
||||
sta $4f0,y
|
||||
iny
|
||||
cpy #38
|
||||
bne .loop1
|
||||
|
||||
lda XCharOffset
|
||||
cmp #0
|
||||
bne .next
|
||||
lda #$01
|
||||
sta XScrollDirection
|
||||
jmp .next
|
||||
|
||||
.goRight:
|
||||
inc XScrollOffset
|
||||
lda XScrollOffset
|
||||
and #$07
|
||||
cmp #$00
|
||||
bne .next
|
||||
lda #$00
|
||||
sta XScrollOffset
|
||||
.moveEverythingRight:
|
||||
inc XCharOffset
|
||||
ldy #38
|
||||
.loop2:
|
||||
lda $400,y
|
||||
sta $401,y
|
||||
lda $428,y
|
||||
sta $429,y
|
||||
lda $450,y
|
||||
sta $451,y
|
||||
lda $478,y
|
||||
sta $479,y
|
||||
lda $4a0,y
|
||||
sta $4a1,y
|
||||
lda $4c8,y
|
||||
sta $4c9,y
|
||||
lda $4f0,y
|
||||
sta $4f1,y
|
||||
dey
|
||||
bne .loop2
|
||||
|
||||
lda XCharOffset
|
||||
cmp #10
|
||||
bne .next
|
||||
lda #$00
|
||||
sta XScrollOffset
|
||||
lda #$00
|
||||
sta XScrollDirection
|
||||
|
||||
.next:
|
||||
jsr setupMoustacheInterrupt
|
||||
|
||||
jmp $ea31
|
||||
|
||||
statusMenu SUBROUTINE
|
||||
jsr setupXScrollInterrupt
|
||||
rts
|
||||
|
@ -1,53 +0,0 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
; Intro reset
|
||||
; ----------------------------------------------------------------------
|
||||
introreset:
|
||||
jsr multicolorOff
|
||||
|
||||
jsr clearScreen
|
||||
|
||||
; Copy shade colors from costant table to color RAM for 2nd and 4th line of text
|
||||
ldx #39
|
||||
introresetColorShade
|
||||
lda colorshade,x
|
||||
sta $d828,x ; 2nd line
|
||||
sta $d878,x ; 4th line
|
||||
dex
|
||||
cpx #$ff
|
||||
bne introresetColorShade
|
||||
|
||||
; Set screen colors
|
||||
lda #0
|
||||
sta $d020 ; overscan
|
||||
sta $d021 ; center
|
||||
|
||||
; Print website
|
||||
lda #<intro2string ; lsb of string address
|
||||
sta srcStringPointer ; put into lsb of source pointer
|
||||
lda #>intro2string ; do the same for msb of string address
|
||||
sta srcStringPointer + 1 ; put into msb of source pointer
|
||||
lda #$26 ; this is lsb of address of 20th line
|
||||
sta dstScreenPointer ; put into lsb of dest pointer
|
||||
lda #$07 ; do the same for msb of adress of 20th line
|
||||
sta dstScreenPointer + 1 ; put into msb of dest pointer
|
||||
jsr printString ; print
|
||||
|
||||
; Print Copyright
|
||||
lda #<intro3string ; the assembly is the same as above,
|
||||
sta srcStringPointer ; just change string to be printed
|
||||
lda #>intro3string ; and line (21th line)
|
||||
sta srcStringPointer + 1
|
||||
lda #$58
|
||||
sta dstScreenPointer
|
||||
lda #$07
|
||||
sta dstScreenPointer + 1
|
||||
jsr printString
|
||||
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "introreset.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
@ -1,7 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
SEG programSegment
|
||||
; Reset variables for a new level
|
||||
; ----------------------------------------------------------------------
|
||||
levelresetvar:
|
||||
@ -35,7 +32,3 @@ clearListLoop:
|
||||
bne clearListLoop
|
||||
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "levelreset.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
@ -1,9 +1,14 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
SEG zeropageSegment
|
||||
; Pointer to video memory used in the level loading routine
|
||||
levelVideoPointer WORD
|
||||
levelColorPointer WORD
|
||||
; Pointer to level struct
|
||||
levelPointer WORD
|
||||
|
||||
SEG programSegment
|
||||
; load new level on the screen
|
||||
statusLevelTitle SUBROUTINE
|
||||
jsr multicolorOff
|
||||
jsr clearScreen
|
||||
|
||||
; Print "Next Level"
|
||||
@ -57,10 +62,11 @@ statusLevelTitle SUBROUTINE
|
||||
rts
|
||||
|
||||
statusLevelLoad SUBROUTINE
|
||||
jsr multicolorOn
|
||||
; Upper bar -- fill with spaces, color yellow
|
||||
ldx #39
|
||||
.loop:
|
||||
lda #$0
|
||||
lda #$80
|
||||
sta $400,x
|
||||
lda #7
|
||||
sta $d800,x
|
||||
@ -139,9 +145,9 @@ writeLevelElement:
|
||||
lda levelT
|
||||
sta (levelVideoPointer),y
|
||||
; tiles colors can be found in an array
|
||||
; position in array = tile value - $60
|
||||
; position in array = tile value - $e0
|
||||
sec
|
||||
sbc #$60
|
||||
sbc #$e0
|
||||
tax
|
||||
lda tilesColors,x
|
||||
sta (levelColorPointer),y
|
||||
@ -165,7 +171,3 @@ writeLevelEnd:
|
||||
lda #ST_PLAY
|
||||
sta status
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "levels.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
57
src/loader.asm
Normal file
57
src/loader.asm
Normal file
@ -0,0 +1,57 @@
|
||||
processor 6502
|
||||
|
||||
SEG.U zeropageSegment
|
||||
org $02
|
||||
|
||||
SEG loaderSegment
|
||||
org $801
|
||||
autostartRoutine SUBROUTINE
|
||||
; this is at $801
|
||||
; and it MUST be exactly at this location in order to autostart
|
||||
; 10 SYS2060 ($80c) BASIC autostart
|
||||
BYTE #$0b,#$08,#$0a,#$00,#$9e,#$32,#$30,#$36,#$31,#$00,#$00,#$00
|
||||
|
||||
; this is at (2061 dec)=($80d)
|
||||
; and it MUST be exactly after the above BASIC statement
|
||||
. = $80d
|
||||
; load pack from tape
|
||||
lda #(packFileNameEnd - packFileName) ; filename length
|
||||
ldx #<packFileName ; filename string address
|
||||
ldy #>packFileName
|
||||
jsr $ffbd ; setnam
|
||||
|
||||
lda #$01 ; file nr
|
||||
ldx $ba ; last used device nr
|
||||
ldy #$01 ; load to address stored in file
|
||||
jsr $ffba ; setlfs
|
||||
|
||||
lda #$0 ; load to memory
|
||||
jsr $ffd5 ; load
|
||||
|
||||
; address of input compressed data
|
||||
lda #$00
|
||||
sta srcPointer
|
||||
lda #$80
|
||||
sta srcPointer + 1
|
||||
|
||||
; address of output decompressed data
|
||||
lda #$00
|
||||
sta dstPointer
|
||||
lda #$10
|
||||
sta dstPointer + 1
|
||||
|
||||
jsr inflate
|
||||
|
||||
jmp $2800
|
||||
|
||||
; decompression util
|
||||
INCLUDE "lzgmini.asm"
|
||||
|
||||
; DATA
|
||||
; -------------------------------------
|
||||
SEG loaderSegment
|
||||
packFileName:
|
||||
BYTE "PACKLZ"
|
||||
packFileNameEnd:
|
||||
|
||||
|
106
src/lzgmini.asm
106
src/lzgmini.asm
@ -1,44 +1,48 @@
|
||||
inflate SUBROUTINE
|
||||
.inEnd EQU 2
|
||||
.offset EQU 4
|
||||
.length EQU 6
|
||||
.symbol EQU 25
|
||||
.marker1 EQU 30
|
||||
.marker2 EQU 31
|
||||
.marker3 EQU 32
|
||||
.marker4 EQU 33
|
||||
.copy EQU 34
|
||||
SEG zeropageSegment
|
||||
srcPointer WORD
|
||||
dstPointer WORD
|
||||
inEnd WORD
|
||||
offset WORD
|
||||
length BYTE
|
||||
symbol BYTE
|
||||
marker1 BYTE
|
||||
marker2 BYTE
|
||||
marker3 BYTE
|
||||
marker4 BYTE
|
||||
copy WORD
|
||||
|
||||
SEG loaderSegment
|
||||
inflate SUBROUTINE
|
||||
clc
|
||||
ldy #10
|
||||
lda (srcPointer),y
|
||||
adc srcPointer
|
||||
sta .inEnd
|
||||
sta inEnd
|
||||
dey
|
||||
lda (srcPointer),y
|
||||
adc srcPointer + 1
|
||||
sta .inEnd + 1
|
||||
sta inEnd + 1
|
||||
clc
|
||||
lda .inEnd
|
||||
lda inEnd
|
||||
adc #16
|
||||
sta .inEnd
|
||||
lda .inEnd + 1
|
||||
sta inEnd
|
||||
lda inEnd + 1
|
||||
adc #0
|
||||
sta .inEnd + 1
|
||||
sta inEnd + 1
|
||||
|
||||
; Get the marker symbols
|
||||
ldy #16
|
||||
lda (srcPointer),y
|
||||
sta .marker1
|
||||
sta marker1
|
||||
iny
|
||||
lda (srcPointer),y
|
||||
sta .marker2
|
||||
sta marker2
|
||||
iny
|
||||
lda (srcPointer),y
|
||||
sta .marker3
|
||||
sta marker3
|
||||
iny
|
||||
lda (srcPointer),y
|
||||
sta .marker4
|
||||
sta marker4
|
||||
|
||||
; Skip header + marker symbols (16 + 4 bytes)
|
||||
clc
|
||||
@ -53,30 +57,30 @@ inflate SUBROUTINE
|
||||
ldy #0 ; Make sure that Y is zero
|
||||
.mainloop:
|
||||
lda srcPointer ; done?
|
||||
cmp .inEnd
|
||||
cmp inEnd
|
||||
bne .notdone
|
||||
lda srcPointer + 1
|
||||
cmp .inEnd + 1
|
||||
cmp inEnd + 1
|
||||
bne .notdone
|
||||
rts
|
||||
.notdone:
|
||||
lda (srcPointer),y ; A = symbol
|
||||
sta .symbol
|
||||
sta symbol
|
||||
sta $d020
|
||||
inc srcPointer
|
||||
bne .noinc1
|
||||
inc srcPointer + 1
|
||||
.noinc1:
|
||||
cmp .marker1 ; Marker1?
|
||||
cmp marker1 ; Marker1?
|
||||
beq .domarker1
|
||||
cmp .marker2 ; Marker2?
|
||||
cmp marker2 ; Marker2?
|
||||
beq .domarker2
|
||||
cmp .marker3 ; Marker3?
|
||||
cmp marker3 ; Marker3?
|
||||
beq .domarker3
|
||||
cmp .marker4 ; Marker4?
|
||||
cmp marker4 ; Marker4?
|
||||
beq .domarker4
|
||||
.literal:
|
||||
lda .symbol
|
||||
lda symbol
|
||||
sta (dstPointer),y ; Plain copy
|
||||
inc dstPointer
|
||||
bne .mainloop
|
||||
@ -101,15 +105,15 @@ inflate SUBROUTINE
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
sta .offset
|
||||
inc .offset
|
||||
sta offset
|
||||
inc offset
|
||||
lda #0
|
||||
sta .offset + 1 ; offset = (b >> 5) + 1
|
||||
sta offset + 1 ; offset = (b >> 5) + 1
|
||||
txa
|
||||
and #$1f
|
||||
tax
|
||||
lda .LZG_LENGTH_DECODE_LUT,x
|
||||
sta .length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
|
||||
sta length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
|
||||
jmp .docopy
|
||||
|
||||
; marker3 - "Short copy"
|
||||
@ -130,13 +134,13 @@ inflate SUBROUTINE
|
||||
lsr
|
||||
clc
|
||||
adc #3
|
||||
sta .length ; length = (b >> 6) + 3
|
||||
sta length ; length = (b >> 6) + 3
|
||||
txa
|
||||
and #$3f
|
||||
adc #8
|
||||
sta .offset
|
||||
sta offset
|
||||
lda #0
|
||||
sta .offset + 1 ; offset = (b & 0x3f) + 8
|
||||
sta offset + 1 ; offset = (b & 0x3f) + 8
|
||||
beq .docopy
|
||||
|
||||
; marker2 - "Medium copy"
|
||||
@ -154,7 +158,7 @@ inflate SUBROUTINE
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
sta .offset + 1
|
||||
sta offset + 1
|
||||
lda (srcPointer),y
|
||||
inc srcPointer
|
||||
bne .noinc6
|
||||
@ -162,15 +166,15 @@ inflate SUBROUTINE
|
||||
.noinc6:
|
||||
clc
|
||||
adc #8
|
||||
sta .offset
|
||||
sta offset
|
||||
bcc .noinc7
|
||||
inc .offset + 1 ; offset = (((b & 0xe0) << 3) | b2) + 8
|
||||
inc offset + 1 ; offset = (((b & 0xe0) << 3) | b2) + 8
|
||||
.noinc7:
|
||||
txa
|
||||
and #$1f
|
||||
tax
|
||||
lda .LZG_LENGTH_DECODE_LUT,x
|
||||
sta .length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
|
||||
sta length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
|
||||
bne .docopy
|
||||
|
||||
.literal2:
|
||||
@ -188,13 +192,13 @@ inflate SUBROUTINE
|
||||
and #$1f
|
||||
tax
|
||||
lda .LZG_LENGTH_DECODE_LUT,x
|
||||
sta .length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
|
||||
sta length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
|
||||
lda (srcPointer),y
|
||||
inc srcPointer
|
||||
bne .noinc9
|
||||
inc srcPointer + 1
|
||||
.noinc9:
|
||||
sta .offset + 1
|
||||
sta offset + 1
|
||||
lda (srcPointer),y
|
||||
inc srcPointer
|
||||
bne .noinc10
|
||||
@ -202,31 +206,31 @@ inflate SUBROUTINE
|
||||
.noinc10:
|
||||
clc
|
||||
adc #$08
|
||||
sta .offset
|
||||
lda .offset + 1
|
||||
sta offset
|
||||
lda offset + 1
|
||||
adc #$08
|
||||
sta .offset + 1 ; offset = ((b2 << 8) | (*src++)) + 2056
|
||||
sta offset + 1 ; offset = ((b2 << 8) | (*src++)) + 2056
|
||||
|
||||
; Copy corresponding data from history window
|
||||
.docopy:
|
||||
sec
|
||||
lda dstPointer
|
||||
sbc .offset
|
||||
sta .copy
|
||||
sbc offset
|
||||
sta copy
|
||||
lda dstPointer + 1
|
||||
sbc .offset + 1
|
||||
sta .copy + 1
|
||||
sbc offset + 1
|
||||
sta copy + 1
|
||||
.loop1:
|
||||
lda (.copy),y
|
||||
lda (copy),y
|
||||
sta (dstPointer),y
|
||||
iny
|
||||
cpy .length
|
||||
cpy length
|
||||
bne .loop1
|
||||
ldy #0 ; Make sure that Y is zero
|
||||
|
||||
clc
|
||||
lda dstPointer
|
||||
adc .length
|
||||
adc length
|
||||
sta dstPointer
|
||||
bcc .noinc11
|
||||
inc dstPointer + 1
|
||||
|
101
src/macro.asm
Normal file
101
src/macro.asm
Normal file
@ -0,0 +1,101 @@
|
||||
SEG zeropageSegment
|
||||
; Generic src/dst copy pointers
|
||||
srcPointer WORD
|
||||
dstPointer WORD
|
||||
dstPointerEnd WORD
|
||||
|
||||
SEG programSegment
|
||||
MACRO MEMSET
|
||||
IF {1} != "D"
|
||||
clc
|
||||
lda <{1}
|
||||
sta dstPointer
|
||||
adc <{3}
|
||||
sta dstPointerEnd
|
||||
lda >{1}
|
||||
sta dstPointer + 1
|
||||
adc >{3}
|
||||
sta dstPointerEnd + 1
|
||||
ELSE
|
||||
clc
|
||||
lda dstPointer
|
||||
adc <{3}
|
||||
sta dstPointerEnd
|
||||
lda dstPointer + 1
|
||||
adc >{3}
|
||||
sta dstPointerEnd + 1
|
||||
ENDIF
|
||||
lda {2}
|
||||
ldy #0
|
||||
.loop:
|
||||
sta (dstPointer),y
|
||||
inc dstPointer
|
||||
bne .skipInc
|
||||
inc dstPointer + 1
|
||||
.skipInc:
|
||||
ldx dstPointer
|
||||
cpx dstPointerEnd
|
||||
bne .loop
|
||||
ldx dstPointer + 1
|
||||
cpx dstPointerEnd + 1
|
||||
bne .loop
|
||||
ENDM
|
||||
|
||||
SEG zeroPageSegment
|
||||
|
||||
SEG programSegment
|
||||
MACRO MEMCPY
|
||||
IF {1} != "D"
|
||||
clc
|
||||
lda <{1}
|
||||
sta dstPointer
|
||||
adc <{3}
|
||||
sta dstPointerEnd
|
||||
lda >{1}
|
||||
sta dstPointer + 1
|
||||
adc >{3}
|
||||
sta dstPointerEnd + 1
|
||||
ELSE
|
||||
clc
|
||||
lda dstPointer
|
||||
adc <{3}
|
||||
sta dstPointerEnd
|
||||
lda dstPointer + 1
|
||||
adc >{3}
|
||||
sta dstPointerEnd + 1
|
||||
ENDIF
|
||||
|
||||
lda <{2}
|
||||
sta srcPointer
|
||||
lda >{2}
|
||||
sta srcPointer + 1
|
||||
|
||||
ldy #$0
|
||||
.loop:
|
||||
lda (srcPointer),y
|
||||
sta (dstPointer),y
|
||||
|
||||
inc dstPointer
|
||||
bne .skipIncDst
|
||||
inc dstPointer + 1
|
||||
.skipIncDst:
|
||||
inc srcPointer
|
||||
bne .skipIncSrc
|
||||
inc srcPointer + 1
|
||||
.skipIncSrc:
|
||||
|
||||
ldx dstPointer
|
||||
cpx dstPointerEnd
|
||||
bne .loop
|
||||
ldx dstPointer + 1
|
||||
cpx dstPointerEnd + 1
|
||||
bne .loop
|
||||
ENDM
|
||||
|
||||
SEG programSegment
|
||||
MACRO MOV_WORD_MEM
|
||||
lda {2}
|
||||
sta {1}
|
||||
lda {2} + 1
|
||||
sta {1} + 1
|
||||
ENDM
|
87
src/main.asm
87
src/main.asm
@ -1,81 +1,50 @@
|
||||
processor 6502
|
||||
|
||||
; Platform specific code
|
||||
; Code yet to be developed, example to use:
|
||||
; ----------------------------------------------------------------------
|
||||
#if SYSTEM = 64
|
||||
; Commodore64 specific code
|
||||
#else
|
||||
; Commodore16 specific code
|
||||
#endif
|
||||
|
||||
; Uninitialized zeropage segment
|
||||
; ----------------------------------------------------------------------
|
||||
SEG.U zeropageSegment
|
||||
org $02
|
||||
INCLUDE "zeropage.asm"
|
||||
ORG_ZEROPAGE EQU $02
|
||||
org ORG_ZEROPAGE
|
||||
|
||||
#if VERBOSE = 1
|
||||
; Locations $90-$FF in zeropage are used by kernal
|
||||
ECHO "End of zeropage variables. Space left: ",($90 - .)
|
||||
#endif
|
||||
|
||||
; SID tune (previously properly cleaned, see HVSC)
|
||||
; ----------------------------------------------------------------------
|
||||
SEG sidSegment
|
||||
org $1000
|
||||
sidtune:
|
||||
INCBIN "../res.bin/amour.sid"
|
||||
#if VERBOSE = 1
|
||||
ECHO "End of SIDtune at ",.,"Space left:",($2000 - .)
|
||||
#endif
|
||||
|
||||
; Font Data
|
||||
; ----------------------------------------------------------------------
|
||||
SEG tggsSegment
|
||||
org $2000
|
||||
; This binary data that defines the font is exactly 2kB long ($800)
|
||||
tggsFont:
|
||||
INCLUDE "tggs.asm"
|
||||
|
||||
; Program Segment
|
||||
; ----------------------------------------------------------------------
|
||||
ORG_SID EQU $1000
|
||||
org ORG_SID
|
||||
ORG_FONT EQU $2400
|
||||
SEG fontSegment
|
||||
org ORG_FONT
|
||||
ORG_PROGRAM EQU $2800
|
||||
SEG programSegment
|
||||
org $2800
|
||||
org ORG_PROGRAM
|
||||
|
||||
ORG_DATA EQU $cd00
|
||||
SEG.U dataSegment
|
||||
org ORG_DATA
|
||||
|
||||
; INCLUDE
|
||||
; -----------------------------------------------------------------------------
|
||||
LASTINIT SET ORG_SID
|
||||
INCLUDE "sidtune.asm"
|
||||
ECHO "sidtune : start ",LASTINIT," end ",.," size ",(. - LASTINIT)
|
||||
|
||||
LASTINIT SET ORG_FONT
|
||||
INCLUDE "font.asm"
|
||||
ECHO "font : start ",LASTINIT," end ",.," size ",(. - LASTINIT)
|
||||
|
||||
LASTINIT SET ORG_PROGRAM
|
||||
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 program segment at:",.
|
||||
ECHO "PACK SIZE:",(. - $1000),"=",[(. - $1000)d]
|
||||
#endif
|
||||
|
||||
; Data variables
|
||||
; -----------------
|
||||
SEG.U dataSegment
|
||||
org $cd00
|
||||
INCLUDE "data.asm"
|
||||
#if VERBOSE = 1
|
||||
ECHO "End of Data segment. Space left:",($ce00 - .)
|
||||
#endif
|
||||
|
||||
; Lists
|
||||
; -----------------
|
||||
SEG.U listSegment
|
||||
org $ce00
|
||||
listX DS 256
|
||||
listY DS 256
|
||||
INCLUDE "macro.asm"
|
||||
ECHO "program : start ",LASTINIT," end ",.," size ",(. - LASTINIT)
|
||||
|
||||
;
|
||||
; coded 2017, 2018, 2019, 2020
|
||||
; coded 2017, 2018, 2019, 2020, 2021
|
||||
; by giomba -- giomba at glgprograms.it
|
||||
; this software is free software and is distributed
|
||||
; under the terms of GNU GPL v3 license
|
||||
|
@ -1,9 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
processor 6502
|
||||
|
||||
SEG programSegment
|
||||
multicolor SUBROUTINE
|
||||
|
||||
; Prepare data struct for MultiColor mode
|
||||
@ -43,7 +38,3 @@ multicolorOff:
|
||||
and #$ef
|
||||
sta $d016
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "multicolor.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
@ -1,7 +1,4 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
SEG programSegment
|
||||
; Wait for some delay
|
||||
statusDelay SUBROUTINE
|
||||
ldy delay ; load outroDelay and decrement
|
||||
@ -14,7 +11,3 @@ statusDelay SUBROUTINE
|
||||
lda delayStatus
|
||||
sta status
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "outro.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
144
src/program.asm
144
src/program.asm
@ -1,9 +1,10 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
SEG zeropageSegment
|
||||
; Interrupt counter
|
||||
counter DS 2
|
||||
|
||||
; ENTRY OF PROGRAM
|
||||
; ----------------------------------------------------------------------
|
||||
SEG programSegment
|
||||
; this is the entry point of the program and must stay at this address
|
||||
org $2800
|
||||
start:
|
||||
; Clear screen, initialize keyboard, restore interrupts
|
||||
jsr $ff81
|
||||
@ -57,22 +58,45 @@ zeroFillZeroPage:
|
||||
lda #ST_INTRO0
|
||||
sta status
|
||||
|
||||
; Enable interrupts
|
||||
cli
|
||||
|
||||
; Reset screen (and other parameters) to play intro
|
||||
jsr introreset
|
||||
|
||||
intro0running: ; Cycle here until SPACE or `Q` is pressed
|
||||
; Enable interrupts
|
||||
cli
|
||||
|
||||
menu SUBROUTINE
|
||||
.menu: ; Cycle here until SPACE or `Q` is pressed
|
||||
jsr $ffe4 ; GETIN
|
||||
cmp #$20 ; Is it SPACE?
|
||||
beq intro0end ; if yes, go to intro0end and start game (see)
|
||||
beq .intro0end ; if yes, go to intro0end and start game (see)
|
||||
#if DEBUG = 1
|
||||
cmp #$41 ; Is it A?
|
||||
beq .printCounter ; if yes, print current counter
|
||||
#endif
|
||||
cmp #$51 ; Is it Q?
|
||||
bne intro0running ; If not, keep looping here,
|
||||
bne .menu ; If not, keep looping here,
|
||||
jmp $fce2 ; else, reset the computer
|
||||
|
||||
#if DEBUG = 1
|
||||
.printCounter
|
||||
lda counter + 1
|
||||
ldy #2
|
||||
jsr printByte
|
||||
lda counter
|
||||
ldy #4
|
||||
jsr printByte
|
||||
jmp .menu
|
||||
#endif
|
||||
|
||||
; Intro is finished, now it's time to start the proper game
|
||||
intro0end:
|
||||
.intro0end:
|
||||
; Are you sure? Maybe the demo-intro is not finished, yet
|
||||
; We do not want to actually start unless the demo is finished,
|
||||
; otherwise vertical raster line offset may be != 0
|
||||
lda status
|
||||
cmp #ST_MENU
|
||||
bne .menu
|
||||
|
||||
; Set current level pointer to list start
|
||||
lda #<levelsList
|
||||
sta levelPointer
|
||||
@ -92,20 +116,21 @@ intro0end:
|
||||
lda #ST_LEVEL_TITLE
|
||||
sta status
|
||||
|
||||
endless:
|
||||
.endless:
|
||||
; Loop waiting for gameover
|
||||
lda status
|
||||
cmp #ST_END ; is status equal to end ?
|
||||
bne endless ; if not, just wait looping here, else...
|
||||
bne .endless ; if not, just wait looping here, else...
|
||||
|
||||
jsr introreset ; reset variables for intro
|
||||
lda #ST_INTRO0
|
||||
sta status ; put machine into play intro status
|
||||
jmp intro0running ; and go there waiting for keypress
|
||||
jsr clearScreen
|
||||
|
||||
; Interrupt Handler
|
||||
lda #ST_MENURESET
|
||||
sta status ; put machine into menu status
|
||||
jmp .menu ; and go there waiting for keypress
|
||||
|
||||
; Main Raster Interrupt Handler
|
||||
; ----------------------------------------------------------------------
|
||||
irq:
|
||||
irq SUBROUTINE
|
||||
; Things that must be done every interrupt (50Hz)
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
; Acknoweledge IRQ
|
||||
@ -118,24 +143,84 @@ irq:
|
||||
tya
|
||||
pha
|
||||
|
||||
#if DEBUG = 1
|
||||
; Change background to show how much time does music take for each interrupt
|
||||
lda #1
|
||||
sta $d020
|
||||
#endif
|
||||
|
||||
; Play music first -> no audio skew if computations are slow
|
||||
jsr sidtune + 3
|
||||
|
||||
#if DEBUG = 1
|
||||
; Change background to visually see the ISR timing
|
||||
lda #2
|
||||
sta $d020
|
||||
#endif
|
||||
|
||||
inc counter
|
||||
bne .noIncCounter
|
||||
inc counter + 1
|
||||
.noIncCounter
|
||||
|
||||
; Check status and call appropriate sub-routine
|
||||
; Sort of switch-case
|
||||
lda status
|
||||
checkStatusIntro0:
|
||||
cmp #ST_INTRO0
|
||||
bne checkStatusIntro1
|
||||
jsr statusIntro0
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro1:
|
||||
cmp #ST_INTRO1
|
||||
bne checkStatusPlay
|
||||
bne checkStatusIntro2
|
||||
jsr statusIntro1
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro2:
|
||||
cmp #ST_INTRO2
|
||||
bne checkStatusIntro3
|
||||
jsr statusIntro2
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro3:
|
||||
cmp #ST_INTRO3
|
||||
bne checkStatusIntro4
|
||||
jsr statusIntro3
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro4:
|
||||
cmp #ST_INTRO4
|
||||
bne checkStatusIntro5
|
||||
jsr statusIntro4
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro5:
|
||||
cmp #ST_INTRO5
|
||||
bne checkStatusIntro6
|
||||
jsr statusIntro5
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro6:
|
||||
cmp #ST_INTRO6
|
||||
bne checkStatusIntro7
|
||||
jsr statusIntro6
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro7:
|
||||
cmp #ST_INTRO7
|
||||
bne checkStatusIntro8
|
||||
jsr statusIntro7
|
||||
jmp checkEndStatus
|
||||
checkStatusIntro8:
|
||||
cmp #ST_INTRO8
|
||||
bne checkStatusMenuReset
|
||||
jsr statusIntro8
|
||||
jmp checkEndStatus
|
||||
checkStatusMenuReset:
|
||||
cmp #ST_MENURESET
|
||||
bne checkStatusMenu
|
||||
jsr statusMenuReset
|
||||
jmp checkEndStatus
|
||||
checkStatusMenu:
|
||||
cmp #ST_MENU
|
||||
bne checkStatusPlay
|
||||
jsr statusMenu
|
||||
jmp checkEndStatus
|
||||
checkStatusPlay:
|
||||
cmp #ST_PLAY
|
||||
bne checkStatusDelay
|
||||
@ -158,19 +243,6 @@ checkStatusLevelLoad:
|
||||
jmp checkEndStatus
|
||||
checkEndStatus:
|
||||
|
||||
#if DEBUG = 1
|
||||
; Change background to show how much time does music take for each interrupt
|
||||
lda #1
|
||||
sta $d020
|
||||
#endif
|
||||
|
||||
; Play music
|
||||
jsr sidtune + 3
|
||||
jsr sidtune + 3
|
||||
jsr sidtune + 3
|
||||
jsr sidtune + 3
|
||||
jsr sidtune + 3
|
||||
|
||||
; Increase random value
|
||||
inc random
|
||||
|
||||
@ -189,7 +261,3 @@ checkEndStatus:
|
||||
|
||||
; Go to original system routine
|
||||
jmp $ea31
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "program.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
6
src/sidtune.asm
Normal file
6
src/sidtune.asm
Normal file
@ -0,0 +1,6 @@
|
||||
SEG sidSegment
|
||||
sidtune:
|
||||
INCBIN "../res.bin/amour2.sid"
|
||||
|
||||
; Note: the SID tune must be properly cleaned (eg. header removed)
|
||||
; See HVSC for .sid music format
|
@ -1,15 +1,14 @@
|
||||
#if VERBOSE = 1
|
||||
LASTINIT SET .
|
||||
#endif
|
||||
|
||||
; Subroutines
|
||||
; ----------------------------------------------------------------------
|
||||
SEG zeropageSegment
|
||||
; Where is the snake head in video memory? Do math to calculate address
|
||||
; using pointer at tileMem
|
||||
tileMem WORD
|
||||
|
||||
SEG programSegment
|
||||
; Clear screen -- easy
|
||||
clearScreen SUBROUTINE
|
||||
ldx #$ff
|
||||
.loop:
|
||||
lda #$00
|
||||
lda #$80
|
||||
sta $400,x
|
||||
sta $500,x
|
||||
sta $600,x
|
||||
@ -81,16 +80,23 @@ printByte SUBROUTINE
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #$40 ; add 64 (see font)
|
||||
ora #$c0 ; add 192 (see font)
|
||||
sta $400,y ; print msb char
|
||||
|
||||
txa ; Take least significant nibble (use previous copy)
|
||||
and #$0f
|
||||
ora #$40 ; add 64 (see font)
|
||||
ora #$c0 ; add 192 (see font)
|
||||
sta $401,y ; print lsb char
|
||||
|
||||
rts
|
||||
|
||||
SEG zeropageSegment
|
||||
; Pointer to string
|
||||
srcStringPointer WORD
|
||||
; Pointer to screen position where to print intro string
|
||||
dstScreenPointer DS 2
|
||||
|
||||
SEG programSegment
|
||||
printString SUBROUTINE
|
||||
; Print string
|
||||
; Input parameters:
|
||||
@ -104,22 +110,22 @@ printString SUBROUTINE
|
||||
beq .end ; if zero, then end (string must be null-terminated)
|
||||
cmp #$20 ; is space?
|
||||
bne .checkP1
|
||||
lda #$0
|
||||
lda #$80
|
||||
jmp .print
|
||||
.checkP1:
|
||||
cmp #$28 ; is char '(' ?
|
||||
bne .checkP2
|
||||
lda #$1b
|
||||
lda #$9b
|
||||
jmp .print
|
||||
.checkP2:
|
||||
cmp #$29 ; is char ')' ?
|
||||
bne .checkP3
|
||||
lda #$1c
|
||||
lda #$9c
|
||||
jmp .print
|
||||
.checkP3
|
||||
cmp #$2e ; is char '.' ?
|
||||
bne .checkNumber
|
||||
lda #$1d
|
||||
lda #$9d
|
||||
jmp .print
|
||||
.checkNumber: ; is char a number?
|
||||
cmp #$2f
|
||||
@ -129,14 +135,14 @@ printString SUBROUTINE
|
||||
sec
|
||||
sbc #$30
|
||||
clc
|
||||
adc #$40
|
||||
adc #$c0
|
||||
jmp .print
|
||||
.nextCheck:
|
||||
|
||||
.isLetter:
|
||||
; defaults to an uppercase letter of ASCII set
|
||||
sec
|
||||
sbc #$40
|
||||
clc
|
||||
adc #$40
|
||||
.print:
|
||||
sta (dstScreenPointer),y ; put screen code to screen
|
||||
iny ; next char in string
|
||||
@ -144,6 +150,11 @@ printString SUBROUTINE
|
||||
.end:
|
||||
rts
|
||||
|
||||
SEG zeropageSegment
|
||||
; Pointer for Pointer in the NextPointer routine
|
||||
nextPointerPointer DS 2
|
||||
|
||||
SEG programSegment
|
||||
; Increment a pointer in the zeropage
|
||||
; Input parameters:
|
||||
; nextPointerPointer pointer to the pointer in zeropage
|
||||
@ -164,7 +175,3 @@ nextPointer:
|
||||
sta (nextPointerPointer),y
|
||||
|
||||
rts
|
||||
|
||||
#if VERBOSE = 1
|
||||
ECHO "subroutines.asm @ ",LASTINIT,"len:",(. - LASTINIT)
|
||||
#endif
|
2568
src/tggs.asm
2568
src/tggs.asm
File diff suppressed because it is too large
Load Diff
@ -1,31 +0,0 @@
|
||||
; Zero page utility pointers
|
||||
; ----------------------------------------------------------------------
|
||||
; Where is the snake head in video memory? Do math to calculate address
|
||||
; using pointer at tileMem,tileMem+1
|
||||
tileMem DS 2
|
||||
|
||||
; Pointer to string
|
||||
srcStringPointer DS 2
|
||||
; Pointer to screen position where to print intro string
|
||||
dstScreenPointer DS 2
|
||||
|
||||
; Pointer to level struct
|
||||
levelPointer DS 2
|
||||
|
||||
; Pointer to video memory used in the level loading routine
|
||||
levelVideoPointer DS 2
|
||||
levelColorPointer DS 2
|
||||
|
||||
; Pointer for Pointer in the NextPointer routine
|
||||
nextPointerPointer DS 2
|
||||
|
||||
; Pointer to string for strlen routine
|
||||
strlenString DS 2
|
||||
|
||||
; Generic src/dst copy pointers
|
||||
srcPointer DS 2
|
||||
dstPointer DS 2
|
||||
|
||||
; Note: Locations $90-$FF in zeropage are used by kernal
|
||||
|
||||
|
@ -7,11 +7,11 @@ void flush(char last, int count) {
|
||||
char tile, color;
|
||||
switch(last) {
|
||||
case 'x':
|
||||
tile = (char)0x63; break;
|
||||
tile = (char)0xe3; break;
|
||||
case 'f':
|
||||
tile = (char)0x62; break;
|
||||
tile = (char)0xe2; break;
|
||||
default:
|
||||
tile = (char)0x60; break;
|
||||
tile = (char)0xe0; break;
|
||||
}
|
||||
cout << tile << (char)count;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user