spo/ass1/bonus-snake.asm
2025-11-03 19:17:22 +01:00

170 lines
3.9 KiB
NASM

. graphical screen settings:
. Address: 0x00A000
. Columns: 16
. Rows: 16
. Pixel size: 24
.
. keyboard settings:
. Address: 0x00C000
.
. frequency: 4000
SNAKE START 0
FIRST LDA #0x44
STA DIREC
LOOP JSUB RENDER
JSUB WAIT
.if (food was eaten) temp = snake[LEN - 1], generate new food:
.propagate position through the snake
.for (i = LEN - 2, i >= 0 ) snakex/y[i + 1] = snakex/y[i]
.if (eaten) LEN++, snake[LEN - 1] = temp
CLEAR A
LDCH @KEY_IN
L10 COMP #0x41 .A
JEQ L3
COMP #0x57 .W
JEQ L4
COMP #0x44 .D
JEQ L5
COMP #0x53 .S
JEQ L6
LDCH DIREC
J L10
L3 STCH DIREC
LDA @SNAKEX .move left
SUB #1
STA @SNAKEX
J L7
L4 STCH DIREC
LDA @SNAKEY .move up
SUB #1
STA @SNAKEY
J L7
L5 STCH DIREC
LDA @SNAKEX .move right
ADD #1
STA @SNAKEX
J L7
L6 STCH DIREC
LDA @SNAKEY .move down
ADD #1
STA @SNAKEY
L7 .check bounds
.for (pos : snakex/y) assert x/y >= 0 && x/y <= 15
J LOOP
HALT J HALT
.waits some time before reading input so it doesnt feel laggy
.no arguements, no return
.changes A, X
WAIT LDA #0
LDX #0xA0
L8 ADD #1
COMPR A, X
JEQ L9
J L8
L9 RSUB
.draws the snake
.no arguements, no return
.changes A
RENDER RMO L, A
JSUB PUSH .prolouge
RMO X, A
JSUB PUSH
RMO T, A
JSUB PUSH
CLEAR X .draw head
JSUB OFFSET
ADD SCREEN
STA ADR
CLEAR A
LDCH #240
STCH @ADR
L1 RMO X, A .draw others
ADD #1
RMO A, X
COMP LEN
JEQ L2
JSUB OFFSET
ADD SCREEN
STA ADR
CLEAR A
LDCH #255
STA @ADR
J L1
L2 JSUB POP .epilouge
RMO A, T
JSUB POP
RMO A, X
JSUB POP
RMO A, L
RSUB
.calculates the offset of the snake cell at index X for rendering
.offset = 16 * snakey[index] + snakex[index]
.arguements: X - index
.return: A - offset
.changes A, T
OFFSET RMO X, A
MUL #3
ADD SNAKEY
STA ADR
LDA @ADR
MUL #16
RMO A, T
RMO X, A
MUL #3
ADD SNAKEX
STA ADR
LDA @ADR
ADDR T, A
RSUB
.pushes A to stack
.changes A
PUSH STA @ST_PTR
LDA ST_PTR
ADD #3
STA ST_PTR
RSUB
.pops top of stack into A
POP LDA ST_PTR
SUB #3
STA ST_PTR
LDA @ST_PTR
RSUB
LEN WORD 1 .snake length
SCREEN WORD X'00A000' .screen pointer
KEY_IN WORD X'00C000' .input pointer
ST_PTR WORD X'000200' .stack pointer, 2kB of space
SNAKEX WORD X'000A00' .pointer to an array of snake x coords, first input is head, SNAKEX + LEN is tail, 3 byte elements, upper left corner is 0, 0
SNAKEY WORD X'000C00' .pointer to an array of snake y coords, offset 0x200 from SNAKEX
ADR WORD 0 .actual address of the x / y coord since sic/xe doesnt support indirect and indexed addressing
DIREC WORD 0 .movement direction, gets added to snake's head
END FIRST