mirror of https://gitlab.com/camelot/kickc.git
2127 lines
38 KiB
NASM
2127 lines
38 KiB
NASM
/// @file
|
||
/// Functions for performing input and output.
|
||
// Commodore 64 PRG executable file
|
||
.file [name="ducks-total.prg", type="prg", segments="Program"]
|
||
.segmentdef Program [segments="Basic, Code, Data"]
|
||
.segmentdef Basic [start=$0801]
|
||
.segmentdef Code [start=$80d]
|
||
.segmentdef Data [startAfter="Code"]
|
||
.segment Basic
|
||
:BasicUpstart(__start)
|
||
.const LIGHT_BLUE = $e
|
||
.const down = $11
|
||
.const right = $1d
|
||
.const lock = 8
|
||
.const lower = $e
|
||
.const home = $13
|
||
.const reverse_on = $12
|
||
.const brick = $e6
|
||
.const green = $1e
|
||
.const yellow = $9e
|
||
.const red = $1c
|
||
.const c = $7800
|
||
/// Color Ram
|
||
.label COLORRAM = $d800
|
||
/// Default address of screen character matrix
|
||
.label DEFAULT_SCREEN = $400
|
||
// The number of bytes on the screen
|
||
// The current cursor x-position
|
||
.label conio_cursor_x = $27
|
||
// The current cursor y-position
|
||
.label conio_cursor_y = $1d
|
||
// The current text cursor line start
|
||
.label conio_line_text = $20
|
||
// The current color cursor line start
|
||
.label conio_line_color = $1e
|
||
// The current text color
|
||
.label conio_textcolor = $22
|
||
.label l = $6b
|
||
.label m = 4
|
||
.label z = $25
|
||
.label z_1 = $14
|
||
.label n = $33
|
||
.label k = $63
|
||
.label j = $32
|
||
.label j_1 = $55
|
||
.label j_2 = $56
|
||
.label duck = $16
|
||
// [0..255] 8-bit
|
||
.label tu = $6e
|
||
// Volume to max
|
||
.label score = $2a
|
||
.label y = $28
|
||
.label time = $30
|
||
.label j_3 = $68
|
||
// Remainder after signed 8 bit division
|
||
.label rem8u = $f
|
||
.label peephole = $34
|
||
.label y_1 = $34
|
||
.label hiscore = $2a
|
||
.label hiscore_1 = $6c
|
||
.segment Code
|
||
__start: {
|
||
// __ma char conio_cursor_x = 0
|
||
lda #0
|
||
sta.z conio_cursor_x
|
||
// __ma char conio_cursor_y = 0
|
||
sta.z conio_cursor_y
|
||
// __ma char *conio_line_text = CONIO_SCREEN_TEXT
|
||
lda #<DEFAULT_SCREEN
|
||
sta.z conio_line_text
|
||
lda #>DEFAULT_SCREEN
|
||
sta.z conio_line_text+1
|
||
// __ma char *conio_line_color = CONIO_SCREEN_COLORS
|
||
lda #<COLORRAM
|
||
sta.z conio_line_color
|
||
lda #>COLORRAM
|
||
sta.z conio_line_color+1
|
||
// __ma char conio_textcolor = CONIO_TEXTCOLOR_DEFAULT
|
||
lda #LIGHT_BLUE
|
||
sta.z conio_textcolor
|
||
// j,k,l,m
|
||
lda #0
|
||
sta.z l
|
||
// j,k,l,m,n=0
|
||
sta.z m
|
||
// #pragma constructor_for(conio_c64_init, cputc, clrscr, cscroll)
|
||
jsr conio_c64_init
|
||
jsr main
|
||
rts
|
||
}
|
||
// Set initial cursor position
|
||
conio_c64_init: {
|
||
// Position cursor at current line
|
||
.label BASIC_CURSOR_LINE = $d6
|
||
.label line = $4c
|
||
// char line = *BASIC_CURSOR_LINE
|
||
lda.z BASIC_CURSOR_LINE
|
||
sta.z line
|
||
// if(line>=CONIO_HEIGHT)
|
||
cmp #$19
|
||
bcc __b1
|
||
lda #$19-1
|
||
sta.z line
|
||
__b1:
|
||
// gotoxy(0, line)
|
||
jsr gotoxy
|
||
// }
|
||
rts
|
||
}
|
||
main: {
|
||
.label __3 = $70
|
||
.label __26 = 8
|
||
.label __29 = 5
|
||
.label __35 = $66
|
||
.label __57 = $64
|
||
.label __61 = $d
|
||
.label __66 = $b
|
||
.label __69 = $19
|
||
.label __72 = $1b
|
||
.label __78 = $10
|
||
.label __81 = 7
|
||
.label __84 = 3
|
||
.label __88 = $36
|
||
.label __92 = $37
|
||
.label __96 = $2e
|
||
.label __97 = $2e
|
||
.label __104 = $5d
|
||
.label __107 = $5f
|
||
.label __110 = $61
|
||
.label __119 = $4a
|
||
.label __120 = $51
|
||
.label __122 = $53
|
||
.label __124 = $4a
|
||
.label __125 = $4d
|
||
.label __127 = $3a
|
||
.label __128 = $3a
|
||
.label __130 = $3c
|
||
.label __131 = $3c
|
||
.label __133 = $3e
|
||
.label __134 = $3e
|
||
.label __136 = $4f
|
||
.label __138 = $40
|
||
.label __139 = $40
|
||
.label __141 = $42
|
||
.label __142 = $42
|
||
.label __144 = $44
|
||
.label __145 = $44
|
||
.label __150 = $69
|
||
.label __151 = $57
|
||
.label __152 = $57
|
||
.label __153 = $59
|
||
.label __154 = $59
|
||
.label __155 = $5b
|
||
.label __156 = $5b
|
||
.label __177 = 8
|
||
.label __179 = $38
|
||
.label __180 = $2e
|
||
// POKE
|
||
lda #8
|
||
sta $900f
|
||
// chrout(lock)
|
||
lda #lock
|
||
sta.z chrout.petscii
|
||
// border and black paper
|
||
jsr chrout
|
||
// chrout(lower)
|
||
lda #lower
|
||
sta.z chrout.petscii
|
||
//Lock UpperCase to Lowercase key
|
||
jsr chrout
|
||
// m=0
|
||
lda #0
|
||
sta.z m
|
||
//Put text in Lowercase set
|
||
__b1:
|
||
// for (m=0; m<40; m++)
|
||
lda.z m
|
||
cmp #$28
|
||
bcs !__b2+
|
||
jmp __b2
|
||
!__b2:
|
||
lda #0
|
||
sta.z n
|
||
sta.z hiscore_1
|
||
sta.z hiscore_1+1
|
||
sta.z y
|
||
sta.z y+1
|
||
sta.z rem8u
|
||
// Load udgs. From 0-->39;
|
||
__b3:
|
||
// clear_screen(32,0)
|
||
lda #$20
|
||
sta.z clear_screen.n
|
||
jsr clear_screen
|
||
// textcolor(7)
|
||
// Clear Screen with spaces & black ink
|
||
lda #7
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(intro)
|
||
lda #<intro
|
||
sta.z cputs.s
|
||
lda #>intro
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// textcolor(1)
|
||
// Yellow ink
|
||
lda #1
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(levels)
|
||
lda #<levels
|
||
sta.z cputs.s
|
||
lda #>levels
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// textcolor(2)
|
||
// White
|
||
lda #2
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(foot)
|
||
lda #<foot
|
||
sta.z cputs.s
|
||
lda #>foot
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// Red
|
||
__b4:
|
||
// l=PEEK
|
||
lda.z $c5
|
||
sta.z l
|
||
// ++l;
|
||
inc.z l
|
||
// while (l>5)
|
||
lda.z l
|
||
cmp #5+1
|
||
bcs __b4
|
||
// clear_screen(4,0)
|
||
// wait for 1-3-5-7-9 keys only
|
||
lda #4
|
||
sta.z clear_screen.n
|
||
jsr clear_screen
|
||
// POKE
|
||
lda #$ff
|
||
sta $9005
|
||
// chrout(reverse_on)
|
||
lda #reverse_on
|
||
sta.z chrout.petscii
|
||
// Graphic mode
|
||
jsr chrout
|
||
// chrout(red)
|
||
lda #red
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(down)
|
||
lda #down
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
lda #1
|
||
sta.z k
|
||
//for (z=1;z<23;z++) { POKE(7680+z*22,230);POKE(c+7680+z*22,2); POKE(7679+z*22,230); POKE(c+7679+z*22,2); } // 23 rows * 22 columns (7680 to 8185). 506 positions.
|
||
//k=1; do { chrout(brick); POKE(211,20); chrout(brick); ++k; } while (k<23);
|
||
//for (k=1;k<22;k++) { chrout(brick); POKE(211,22); chrout(brick); }; // 23 rows * 22 columns (7680 to 8185). 506 positions.
|
||
__b6:
|
||
// for (k=1;k<22;k++)
|
||
lda.z k
|
||
cmp #$16
|
||
bcs !__b7+
|
||
jmp __b7
|
||
!__b7:
|
||
// chrout(brick)
|
||
lda #brick
|
||
sta.z chrout.petscii
|
||
// 23 rows * 22 columns (7680 to 8185). 506 positions.
|
||
jsr chrout
|
||
// POKE
|
||
lda #brick
|
||
sta $1ff9
|
||
lda #2
|
||
sta $1ff9+c
|
||
// chrout(home)
|
||
lda #home
|
||
sta.z chrout.petscii
|
||
//last brick from last line (#23) to avoid scrolling
|
||
jsr chrout
|
||
// if (l>1)
|
||
lda.z l
|
||
cmp #1+1
|
||
bcc __b8
|
||
lda #<1
|
||
sta.z z_1
|
||
lda #>1
|
||
sta.z z_1+1
|
||
__b13:
|
||
// random((7-l),26-(3*l))
|
||
lda #7
|
||
sec
|
||
sbc.z l
|
||
sta.z random.k
|
||
// 3*l
|
||
lda.z l
|
||
asl
|
||
sta.z __177
|
||
lda.z __26
|
||
clc
|
||
adc.z l
|
||
sta.z __26
|
||
// random((7-l),26-(3*l))
|
||
lda #$1a
|
||
sec
|
||
sbc.z random.n
|
||
sta.z random.n
|
||
// Write differential random bricks depending on 'l' level choosen
|
||
jsr random
|
||
// z+m
|
||
lda.z m
|
||
clc
|
||
adc.z z_1
|
||
sta.z __29
|
||
lda #0
|
||
adc.z z_1+1
|
||
sta.z __29+1
|
||
// if (z+m>505)
|
||
cmp #>$1f9
|
||
bne !+
|
||
lda.z __29
|
||
cmp #<$1f9
|
||
!:
|
||
bcs !__b24+
|
||
jmp __b24
|
||
!__b24:
|
||
bne !__b24+
|
||
jmp __b24
|
||
!__b24:
|
||
jmp __b12
|
||
__b8:
|
||
lda #<1
|
||
sta.z z_1
|
||
lda #>1
|
||
sta.z z_1+1
|
||
__b12:
|
||
// POKE
|
||
lda #$f
|
||
sta $900e
|
||
// chrout(home)
|
||
lda #home
|
||
sta.z chrout.petscii
|
||
// Duck #1
|
||
jsr chrout
|
||
// chrout(yellow)
|
||
lda #yellow
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(80)
|
||
lda #$50
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(84)
|
||
lda #$54
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(83)
|
||
lda #$53
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(58)
|
||
lda #$3a
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// POKE
|
||
lda #$12
|
||
sta.z $d3
|
||
lda #0
|
||
sta.z j_1
|
||
// jump to Column 18
|
||
__b17:
|
||
// for (j=0; j<4; ++j)
|
||
lda.z j_1
|
||
cmp #4
|
||
bcs !__b18+
|
||
jmp __b18
|
||
!__b18:
|
||
// write_score()
|
||
// Write 'TM:9', yellow
|
||
lda #<0
|
||
sta.z score
|
||
sta.z score+1
|
||
jsr write_score
|
||
// chrout(home)
|
||
lda #home
|
||
sta.z chrout.petscii
|
||
// Write Score (yellow)
|
||
jsr chrout
|
||
// chrout(green)
|
||
lda #green
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// POKE
|
||
lda #$a
|
||
sta.z $d3
|
||
lda #0
|
||
sta.z j_2
|
||
// Jump to column 10
|
||
__b20:
|
||
// for (j=0; j<5; j++)
|
||
lda.z j_2
|
||
cmp #5
|
||
bcs !__b21+
|
||
jmp __b21
|
||
!__b21:
|
||
lda #<$1f1f
|
||
sta.z peephole
|
||
lda #>$1f1f
|
||
sta.z peephole+1
|
||
lda #<1
|
||
sta.z tu
|
||
lda #>1
|
||
sta.z tu+1
|
||
// Write 'DUCK', green
|
||
__b22:
|
||
// chrout(home)
|
||
lda #home
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(green)
|
||
lda #green
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(reverse_on)
|
||
lda #reverse_on
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// POKE
|
||
lda #$f
|
||
sta.z $d3
|
||
// if (tu<10)
|
||
// Jump to column 15
|
||
lda.z tu+1
|
||
bne !+
|
||
lda.z tu
|
||
cmp #$a
|
||
bcs !__b23+
|
||
jmp __b23
|
||
!__b23:
|
||
!:
|
||
// chrout(49)
|
||
lda #$31
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(48)
|
||
lda #$30
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
__b11:
|
||
// Write duck number
|
||
// random(0,255)
|
||
lda #$ff
|
||
sta.z random.n
|
||
lda #0
|
||
sta.z random.k
|
||
jsr random
|
||
// duck=m
|
||
lda.z m
|
||
sta.z duck
|
||
lda #0
|
||
sta.z duck+1
|
||
// random(0,255)
|
||
lda #$ff
|
||
sta.z random.n
|
||
lda #0
|
||
sta.z random.k
|
||
jsr random
|
||
// m+7701
|
||
lda.z m
|
||
clc
|
||
adc #<$1e15
|
||
sta.z __61
|
||
lda #>$1e15
|
||
adc #0
|
||
sta.z __61+1
|
||
// duck=m+7701+duck
|
||
clc
|
||
lda.z duck
|
||
adc.z __61
|
||
sta.z duck
|
||
lda.z duck+1
|
||
adc.z __61+1
|
||
sta.z duck+1
|
||
// PEEK
|
||
clc
|
||
lda.z duck
|
||
adc #1
|
||
sta.z __66
|
||
lda.z duck+1
|
||
adc #0
|
||
sta.z __66+1
|
||
lda #$16
|
||
clc
|
||
adc.z duck
|
||
sta.z __69
|
||
lda #0
|
||
adc.z duck+1
|
||
sta.z __69+1
|
||
lda #$17
|
||
clc
|
||
adc.z duck
|
||
sta.z __72
|
||
lda #0
|
||
adc.z duck+1
|
||
sta.z __72+1
|
||
// while ((duck>8163) || PEEK(duck)==brick || PEEK(duck+1)==brick || PEEK(duck+22)==brick || PEEK(duck+23)==brick)
|
||
lda #>$1fe3
|
||
cmp.z duck+1
|
||
bcc __b11
|
||
bne !+
|
||
lda #<$1fe3
|
||
cmp.z duck
|
||
bcc __b11
|
||
!:
|
||
lda #brick
|
||
ldy #0
|
||
cmp (duck),y
|
||
beq __b11
|
||
cmp (__66),y
|
||
beq __b11
|
||
cmp (__69),y
|
||
beq __b11
|
||
cmp (__72),y
|
||
bne !__b11+
|
||
jmp __b11
|
||
!__b11:
|
||
// chrono_restart()
|
||
jsr chrono_restart
|
||
lda #<0
|
||
sta.z time
|
||
sta.z time+1
|
||
__b26:
|
||
// while (time<10)
|
||
lda.z time+1
|
||
bne !+
|
||
lda.z time
|
||
cmp #$a
|
||
bcs !__b27+
|
||
jmp __b27
|
||
!__b27:
|
||
!:
|
||
// tu++;
|
||
inc.z tu
|
||
bne !+
|
||
inc.z tu+1
|
||
!:
|
||
// score=score-10
|
||
sec
|
||
lda.z score
|
||
sbc #$a
|
||
sta.z score
|
||
lda.z score+1
|
||
sbc #0
|
||
sta.z score+1
|
||
// write_score()
|
||
jsr write_score
|
||
// POKE
|
||
lda #$82
|
||
sta $900d
|
||
// wait(20)
|
||
lda #$14
|
||
sta.z wait.n
|
||
jsr wait
|
||
// POKE
|
||
lda #0
|
||
sta $900d
|
||
lda.z duck
|
||
clc
|
||
adc #<c
|
||
sta.z __150
|
||
lda.z duck+1
|
||
adc #>c
|
||
sta.z __150+1
|
||
lda #0
|
||
tay
|
||
sta (__150),y
|
||
lda.z duck
|
||
sta.z __151
|
||
lda.z duck+1
|
||
sta.z __151+1
|
||
lda.z __152
|
||
clc
|
||
adc #<1+c
|
||
sta.z __152
|
||
lda.z __152+1
|
||
adc #>1+c
|
||
sta.z __152+1
|
||
tya
|
||
sta (__152),y
|
||
lda.z duck
|
||
sta.z __153
|
||
lda.z duck+1
|
||
sta.z __153+1
|
||
lda.z __154
|
||
clc
|
||
adc #<$16+c
|
||
sta.z __154
|
||
lda.z __154+1
|
||
adc #>$16+c
|
||
sta.z __154+1
|
||
tya
|
||
sta (__154),y
|
||
lda.z duck
|
||
sta.z __155
|
||
lda.z duck+1
|
||
sta.z __155+1
|
||
lda.z __156
|
||
clc
|
||
adc #<$17+c
|
||
sta.z __156
|
||
lda.z __156+1
|
||
adc #>$17+c
|
||
sta.z __156+1
|
||
tya
|
||
sta (__156),y
|
||
// while (tu<11)
|
||
lda.z tu+1
|
||
bne !+
|
||
lda.z tu
|
||
cmp #$b
|
||
bcs !__b22+
|
||
jmp __b22
|
||
!__b22:
|
||
!:
|
||
// clear_screen(4,0)
|
||
// 10 ducks
|
||
lda #4
|
||
sta.z clear_screen.n
|
||
jsr clear_screen
|
||
// POKE
|
||
lda #$f0
|
||
sta $9005
|
||
// chrout(lower)
|
||
lda #lower
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// textcolor(7)
|
||
// Return to text mode, lowcase
|
||
lda #7
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(game_over)
|
||
lda #<game_over
|
||
sta.z cputs.s
|
||
lda #>game_over
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// textcolor(2)
|
||
// Yellow
|
||
lda #2
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(your_score)
|
||
lda #<your_score
|
||
sta.z cputs.s
|
||
lda #>your_score
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// cputs(buffer)
|
||
lda #<buffer
|
||
sta.z cputs.s
|
||
lda #>buffer
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// textcolor(3)
|
||
// Red
|
||
lda #3
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(high_score)
|
||
lda #<high_score
|
||
sta.z cputs.s
|
||
lda #>high_score
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// if (score>hiscore)
|
||
lda.z score+1
|
||
cmp.z hiscore_1+1
|
||
bne !+
|
||
lda.z score
|
||
cmp.z hiscore_1
|
||
beq __b114
|
||
!:
|
||
bcc __b114
|
||
jmp __b46
|
||
__b114:
|
||
lda.z hiscore_1
|
||
sta.z hiscore
|
||
lda.z hiscore_1+1
|
||
sta.z hiscore+1
|
||
__b46:
|
||
// utoa(hiscore,buffer,10)
|
||
lda.z hiscore
|
||
sta.z utoa.value
|
||
lda.z hiscore+1
|
||
sta.z utoa.value+1
|
||
jsr utoa
|
||
// cputs(buffer)
|
||
lda #<buffer
|
||
sta.z cputs.s
|
||
lda #>buffer
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// textcolor(1)
|
||
// Cyan
|
||
lda #1
|
||
sta.z textcolor.color
|
||
jsr textcolor
|
||
// cputs(play_again)
|
||
lda #<play_again
|
||
sta.z cputs.s
|
||
lda #>play_again
|
||
sta.z cputs.s+1
|
||
jsr cputs
|
||
// white
|
||
__b47:
|
||
// j=PEEK
|
||
lda.z $c5
|
||
sta.z j_3
|
||
// while (j!= 11 && j!=28 )
|
||
lda #$b
|
||
cmp.z j_3
|
||
beq __b48
|
||
lda #$1c
|
||
cmp.z j_3
|
||
bne __b47
|
||
__b48:
|
||
// while (j==11)
|
||
lda #$b
|
||
cmp.z j_3
|
||
beq __b113
|
||
// asm
|
||
// N pressed. Exit game
|
||
jsr $fd22
|
||
// }
|
||
rts
|
||
__b113:
|
||
lda.z hiscore
|
||
sta.z hiscore_1
|
||
lda.z hiscore+1
|
||
sta.z hiscore_1+1
|
||
jmp __b3
|
||
__b27:
|
||
// read_chrono()
|
||
jsr read_chrono
|
||
// m=PEEK
|
||
// Joystick routine
|
||
lda $911f
|
||
sta.z m
|
||
// POKE
|
||
lda #$7f
|
||
sta $9122
|
||
// n=PEEK
|
||
lda $9120
|
||
sta.z n
|
||
// POKE
|
||
lda #$ff
|
||
sta $9122
|
||
// 16&m
|
||
lda #$10
|
||
and.z m
|
||
sta.z __78
|
||
// if ((16&m)==0)
|
||
bne __b29
|
||
// y--;
|
||
lda.z y
|
||
bne !+
|
||
dec.z y+1
|
||
!:
|
||
dec.z y
|
||
__b29:
|
||
// 128&n
|
||
lda #$80
|
||
and.z n
|
||
sta.z __81
|
||
// if ((128&n)==0)
|
||
bne __b30
|
||
// y++;
|
||
inc.z y
|
||
bne !+
|
||
inc.z y+1
|
||
!:
|
||
__b30:
|
||
// 4&m
|
||
lda #4
|
||
and.z m
|
||
sta.z __84
|
||
// if ((4&m)==0)
|
||
bne __b31
|
||
// y=y-22
|
||
sec
|
||
lda.z y
|
||
sbc #$16
|
||
sta.z y
|
||
lda.z y+1
|
||
sbc #0
|
||
sta.z y+1
|
||
__b31:
|
||
// 8&m
|
||
lda #8
|
||
and.z m
|
||
sta.z __88
|
||
// if ((8&m)==0)
|
||
bne __b32
|
||
// y=y+22
|
||
lda #$16
|
||
clc
|
||
adc.z y
|
||
sta.z y
|
||
bcc !+
|
||
inc.z y+1
|
||
!:
|
||
__b32:
|
||
// 32&m
|
||
lda #$20
|
||
and.z m
|
||
sta.z __92
|
||
// if ((32&m)==0)
|
||
bne __b33
|
||
// POKE
|
||
lda #$82
|
||
sta $900d
|
||
// if (peephole!=duck)
|
||
lda.z peephole+1
|
||
cmp.z duck+1
|
||
beq !__b34+
|
||
jmp __b34
|
||
!__b34:
|
||
lda.z peephole
|
||
cmp.z duck
|
||
beq !__b34+
|
||
jmp __b34
|
||
!__b34:
|
||
// 12-time
|
||
sec
|
||
lda #<$c
|
||
sbc.z div16u8u.return_1
|
||
sta.z __96
|
||
lda #>$c
|
||
sbc.z div16u8u.return_1+1
|
||
sta.z __96+1
|
||
// (12-time)*10
|
||
lda.z __96
|
||
asl
|
||
sta.z __179
|
||
lda.z __96+1
|
||
rol
|
||
sta.z __179+1
|
||
asl.z __179
|
||
rol.z __179+1
|
||
clc
|
||
lda.z __180
|
||
adc.z __179
|
||
sta.z __180
|
||
lda.z __180+1
|
||
adc.z __179+1
|
||
sta.z __180+1
|
||
asl.z __97
|
||
rol.z __97+1
|
||
// score=score+(12-time)*10
|
||
clc
|
||
lda.z score
|
||
adc.z __97
|
||
sta.z score
|
||
lda.z score+1
|
||
adc.z __97+1
|
||
sta.z score+1
|
||
// wait(10)
|
||
lda #$a
|
||
sta.z wait.n
|
||
jsr wait
|
||
lda #<$a
|
||
sta.z time
|
||
lda #>$a
|
||
sta.z time+1
|
||
__b35:
|
||
// POKE
|
||
lda #0
|
||
sta $900d
|
||
__b33:
|
||
// PEEK
|
||
clc
|
||
lda.z y
|
||
adc #1
|
||
sta.z __104
|
||
lda.z y+1
|
||
adc #0
|
||
sta.z __104+1
|
||
lda #$16
|
||
clc
|
||
adc.z y
|
||
sta.z __107
|
||
lda #0
|
||
adc.z y+1
|
||
sta.z __107+1
|
||
lda #$17
|
||
clc
|
||
adc.z y
|
||
sta.z __110
|
||
lda #0
|
||
adc.z y+1
|
||
sta.z __110+1
|
||
// if (PEEK(y)!=brick && PEEK(y+1)!=brick && PEEK(y+22)!=brick && PEEK(y+23)!=brick && y>7702 && y<8163)
|
||
lda #brick
|
||
ldy #0
|
||
cmp (y),y
|
||
beq __b36
|
||
cmp (__104),y
|
||
beq __b36
|
||
lda (__107),y
|
||
cmp #brick
|
||
beq !__b109+
|
||
jmp __b109
|
||
!__b109:
|
||
__b36:
|
||
// POKE
|
||
lda #$fd
|
||
ldy #0
|
||
sta (y_1),y
|
||
lda.z y_1
|
||
clc
|
||
adc #<c
|
||
sta.z __125
|
||
lda.z y_1+1
|
||
adc #>c
|
||
sta.z __125+1
|
||
lda #1
|
||
sta (__125),y
|
||
clc
|
||
lda.z y_1
|
||
adc #1
|
||
sta.z __127
|
||
lda.z y_1+1
|
||
adc #0
|
||
sta.z __127+1
|
||
lda #$ed
|
||
sta (__127),y
|
||
lda.z __128
|
||
clc
|
||
adc #<c
|
||
sta.z __128
|
||
lda.z __128+1
|
||
adc #>c
|
||
sta.z __128+1
|
||
lda #1
|
||
sta (__128),y
|
||
lda #$16
|
||
clc
|
||
adc.z y_1
|
||
sta.z __130
|
||
tya
|
||
adc.z y_1+1
|
||
sta.z __130+1
|
||
lda #$ee
|
||
sta (__130),y
|
||
lda.z __131
|
||
clc
|
||
adc #<c
|
||
sta.z __131
|
||
lda.z __131+1
|
||
adc #>c
|
||
sta.z __131+1
|
||
lda #1
|
||
sta (__131),y
|
||
lda #$17
|
||
clc
|
||
adc.z y_1
|
||
sta.z __133
|
||
tya
|
||
adc.z y_1+1
|
||
sta.z __133+1
|
||
lda #$f0
|
||
sta (__133),y
|
||
lda.z __134
|
||
clc
|
||
adc #<c
|
||
sta.z __134
|
||
lda.z __134+1
|
||
adc #>c
|
||
sta.z __134+1
|
||
lda #1
|
||
sta (__134),y
|
||
// wait(5)
|
||
// Clear peephole if there is not bricks contact
|
||
lda #5
|
||
sta.z wait.n
|
||
jsr wait
|
||
// POKE
|
||
lda #0
|
||
tay
|
||
sta (duck),y
|
||
lda.z duck
|
||
clc
|
||
adc #<c
|
||
sta.z __136
|
||
lda.z duck+1
|
||
adc #>c
|
||
sta.z __136+1
|
||
lda #7
|
||
sta (__136),y
|
||
clc
|
||
lda.z duck
|
||
adc #1
|
||
sta.z __138
|
||
lda.z duck+1
|
||
adc #0
|
||
sta.z __138+1
|
||
lda #1
|
||
sta (__138),y
|
||
lda.z __139
|
||
clc
|
||
adc #<c
|
||
sta.z __139
|
||
lda.z __139+1
|
||
adc #>c
|
||
sta.z __139+1
|
||
lda #7
|
||
sta (__139),y
|
||
lda #$16
|
||
clc
|
||
adc.z duck
|
||
sta.z __141
|
||
tya
|
||
adc.z duck+1
|
||
sta.z __141+1
|
||
lda #2
|
||
sta (__141),y
|
||
lda.z __142
|
||
clc
|
||
adc #<c
|
||
sta.z __142
|
||
lda.z __142+1
|
||
adc #>c
|
||
sta.z __142+1
|
||
lda #7
|
||
sta (__142),y
|
||
lda #$17
|
||
clc
|
||
adc.z duck
|
||
sta.z __144
|
||
tya
|
||
adc.z duck+1
|
||
sta.z __144+1
|
||
lda #3
|
||
sta (__144),y
|
||
lda.z __145
|
||
clc
|
||
adc #<c
|
||
sta.z __145
|
||
lda.z __145+1
|
||
adc #>c
|
||
sta.z __145+1
|
||
lda #7
|
||
sta (__145),y
|
||
// wait(5)
|
||
lda #5
|
||
sta.z wait.n
|
||
jsr wait
|
||
lda.z y_1
|
||
sta.z y
|
||
lda.z y_1+1
|
||
sta.z y+1
|
||
jmp __b26
|
||
__b109:
|
||
// if (PEEK(y)!=brick && PEEK(y+1)!=brick && PEEK(y+22)!=brick && PEEK(y+23)!=brick && y>7702 && y<8163)
|
||
lda #brick
|
||
ldy #0
|
||
cmp (__110),y
|
||
bne !__b36+
|
||
jmp __b36
|
||
!__b36:
|
||
lda #>$1e16
|
||
cmp.z y+1
|
||
bcc __b107
|
||
bne !+
|
||
lda #<$1e16
|
||
cmp.z y
|
||
bcc __b107
|
||
!:
|
||
jmp __b36
|
||
__b107:
|
||
lda.z y+1
|
||
cmp #>$1fe3
|
||
bcc !+
|
||
beq !__b36+
|
||
jmp __b36
|
||
!__b36:
|
||
lda.z y
|
||
cmp #<$1fe3
|
||
bcc !__b36+
|
||
jmp __b36
|
||
!__b36:
|
||
!:
|
||
// POKE
|
||
lda.z peephole
|
||
clc
|
||
adc #<c
|
||
sta.z __119
|
||
lda.z peephole+1
|
||
adc #>c
|
||
sta.z __119+1
|
||
lda #0
|
||
tay
|
||
sta (__119),y
|
||
clc
|
||
lda.z __119
|
||
adc #1
|
||
sta.z __120
|
||
lda.z __119+1
|
||
adc #0
|
||
sta.z __120+1
|
||
tya
|
||
sta (__120),y
|
||
lda #$16
|
||
clc
|
||
adc.z __119
|
||
sta.z __122
|
||
tya
|
||
adc.z __119+1
|
||
sta.z __122+1
|
||
tya
|
||
sta (__122),y
|
||
lda #$17
|
||
clc
|
||
adc.z __124
|
||
sta.z __124
|
||
bcc !+
|
||
inc.z __124+1
|
||
!:
|
||
lda #0
|
||
tay
|
||
sta (__124),y
|
||
lda.z y
|
||
sta.z y_1
|
||
lda.z y+1
|
||
sta.z y_1+1
|
||
jmp __b36
|
||
__b34:
|
||
// score=score-10
|
||
sec
|
||
lda.z score
|
||
sbc #$a
|
||
sta.z score
|
||
lda.z score+1
|
||
sbc #0
|
||
sta.z score+1
|
||
// write_score()
|
||
jsr write_score
|
||
// wait(10)
|
||
lda #$a
|
||
sta.z wait.n
|
||
jsr wait
|
||
jmp __b35
|
||
__b23:
|
||
// 48+tu
|
||
lda #$30
|
||
clc
|
||
adc.z tu
|
||
sta.z __57
|
||
lda #0
|
||
adc.z tu+1
|
||
sta.z __57+1
|
||
// chrout(48+tu)
|
||
lda.z __57
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
jmp __b11
|
||
__b21:
|
||
// chrout(ducknumber[j])
|
||
ldy.z j_2
|
||
lda ducknumber,y
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// for (j=0; j<5; j++)
|
||
inc.z j_2
|
||
jmp __b20
|
||
__b18:
|
||
// chrout(chrono[j])
|
||
ldy.z j_1
|
||
lda chrono,y
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// for (j=0; j<4; ++j)
|
||
inc.z j_1
|
||
jmp __b17
|
||
__b24:
|
||
lda #1
|
||
sta.z j
|
||
__b14:
|
||
// for (j=1; j<=m; ++j)
|
||
lda.z m
|
||
cmp.z j
|
||
bcs __b15
|
||
// chrout(brick)
|
||
lda #brick
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// z+m
|
||
lda.z m
|
||
clc
|
||
adc.z z_1
|
||
sta.z __35
|
||
lda #0
|
||
adc.z z_1+1
|
||
sta.z __35+1
|
||
// z=z+m+1
|
||
clc
|
||
lda.z __35
|
||
adc #1
|
||
sta.z z_1
|
||
lda.z __35+1
|
||
adc #0
|
||
sta.z z_1+1
|
||
// while (z<506)
|
||
cmp #>$1fa
|
||
bcs !__b13+
|
||
jmp __b13
|
||
!__b13:
|
||
bne !+
|
||
lda.z z_1
|
||
cmp #<$1fa
|
||
bcs !__b13+
|
||
jmp __b13
|
||
!__b13:
|
||
!:
|
||
jmp __b12
|
||
__b15:
|
||
// chrout(right)
|
||
lda #right
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// for (j=1; j<=m; ++j)
|
||
inc.z j
|
||
jmp __b14
|
||
__b7:
|
||
// chrout(brick)
|
||
lda #brick
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
lda #2
|
||
sta.z n
|
||
__b9:
|
||
// for(n=2;n<22;++n)
|
||
lda.z n
|
||
cmp #$16
|
||
bcc __b10
|
||
// chrout(brick)
|
||
lda #brick
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// for (k=1;k<22;k++)
|
||
inc.z k
|
||
jmp __b6
|
||
__b10:
|
||
// chrout(right)
|
||
lda #right
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// for(n=2;n<22;++n)
|
||
inc.z n
|
||
jmp __b9
|
||
__b2:
|
||
// POKE
|
||
lda.z m
|
||
clc
|
||
adc #<$1c00
|
||
sta.z __3
|
||
lda #>$1c00
|
||
adc #0
|
||
sta.z __3+1
|
||
ldy.z m
|
||
lda duck_udg,y
|
||
ldy #0
|
||
sta (__3),y
|
||
// for (m=0; m<40; m++)
|
||
inc.z m
|
||
jmp __b1
|
||
}
|
||
// Set the cursor to the specified position
|
||
// void gotoxy(char x, __zp($4c) char y)
|
||
gotoxy: {
|
||
.label __5 = $48
|
||
.label __6 = $2c
|
||
.label __7 = $2c
|
||
.label line_offset = $2c
|
||
.label y = $4c
|
||
.label __8 = $46
|
||
.label __9 = $2c
|
||
// if(y>CONIO_HEIGHT)
|
||
lda.z y
|
||
cmp #$19+1
|
||
bcc __b2
|
||
lda #0
|
||
sta.z y
|
||
__b2:
|
||
// conio_cursor_x = x
|
||
lda #0
|
||
sta.z conio_cursor_x
|
||
// conio_cursor_y = y
|
||
lda.z y
|
||
sta.z conio_cursor_y
|
||
// unsigned int line_offset = (unsigned int)y*CONIO_WIDTH
|
||
lda.z y
|
||
sta.z __7
|
||
lda #0
|
||
sta.z __7+1
|
||
lda.z __7
|
||
asl
|
||
sta.z __8
|
||
lda.z __7+1
|
||
rol
|
||
sta.z __8+1
|
||
asl.z __8
|
||
rol.z __8+1
|
||
clc
|
||
lda.z __9
|
||
adc.z __8
|
||
sta.z __9
|
||
lda.z __9+1
|
||
adc.z __8+1
|
||
sta.z __9+1
|
||
asl.z line_offset
|
||
rol.z line_offset+1
|
||
asl.z line_offset
|
||
rol.z line_offset+1
|
||
asl.z line_offset
|
||
rol.z line_offset+1
|
||
// CONIO_SCREEN_TEXT + line_offset
|
||
lda.z line_offset
|
||
clc
|
||
adc #<DEFAULT_SCREEN
|
||
sta.z __5
|
||
lda.z line_offset+1
|
||
adc #>DEFAULT_SCREEN
|
||
sta.z __5+1
|
||
// conio_line_text = CONIO_SCREEN_TEXT + line_offset
|
||
lda.z __5
|
||
sta.z conio_line_text
|
||
lda.z __5+1
|
||
sta.z conio_line_text+1
|
||
// CONIO_SCREEN_COLORS + line_offset
|
||
lda.z __6
|
||
clc
|
||
adc #<COLORRAM
|
||
sta.z __6
|
||
lda.z __6+1
|
||
adc #>COLORRAM
|
||
sta.z __6+1
|
||
// conio_line_color = CONIO_SCREEN_COLORS + line_offset
|
||
lda.z __6
|
||
sta.z conio_line_color
|
||
lda.z __6+1
|
||
sta.z conio_line_color+1
|
||
// }
|
||
rts
|
||
}
|
||
// void chrout(__zp($18) volatile char petscii)
|
||
chrout: {
|
||
.label petscii = $18
|
||
// asm
|
||
lda petscii
|
||
jsr $ffd2
|
||
// }
|
||
rts
|
||
}
|
||
// void clear_screen(__zp(8) char n, char m)
|
||
clear_screen: {
|
||
.label __4 = $23
|
||
.label __5 = 9
|
||
.label n = 8
|
||
lda #<0
|
||
sta.z z
|
||
sta.z z+1
|
||
__b1:
|
||
// for (z=0; z<506; ++z)
|
||
lda.z z+1
|
||
cmp #>$1fa
|
||
bcc __b2
|
||
bne !+
|
||
lda.z z
|
||
cmp #<$1fa
|
||
bcc __b2
|
||
!:
|
||
// gotoxy(0,0)
|
||
// From 0-->505 (506 bytes). ClearScreen with byte 'n' with color 'm'
|
||
lda #0
|
||
sta.z gotoxy.y
|
||
jsr gotoxy
|
||
// chrout(home)
|
||
lda #home
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// }
|
||
rts
|
||
__b2:
|
||
// POKE
|
||
lda.z z
|
||
clc
|
||
adc #<$1e00
|
||
sta.z __5
|
||
lda.z z+1
|
||
adc #>$1e00
|
||
sta.z __5+1
|
||
lda.z __5
|
||
clc
|
||
adc #<c
|
||
sta.z __4
|
||
lda.z __5+1
|
||
adc #>c
|
||
sta.z __4+1
|
||
lda #0
|
||
tay
|
||
sta (__4),y
|
||
lda.z n
|
||
sta (__5),y
|
||
// for (z=0; z<506; ++z)
|
||
inc.z z
|
||
bne !+
|
||
inc.z z+1
|
||
!:
|
||
jmp __b1
|
||
}
|
||
// Set the color for text output. The old color setting is returned.
|
||
// char textcolor(__zp(8) char color)
|
||
textcolor: {
|
||
.label color = 8
|
||
// conio_textcolor = color
|
||
lda.z color
|
||
sta.z conio_textcolor
|
||
// }
|
||
rts
|
||
}
|
||
// Output a NUL-terminated string at the current cursor position
|
||
// void cputs(__zp(5) const char *s)
|
||
cputs: {
|
||
.label c = 2
|
||
.label s = 5
|
||
__b1:
|
||
// while(c=*s++)
|
||
ldy #0
|
||
lda (s),y
|
||
sta.z c
|
||
inc.z s
|
||
bne !+
|
||
inc.z s+1
|
||
!:
|
||
lda.z c
|
||
bne __b2
|
||
// }
|
||
rts
|
||
__b2:
|
||
// cputc(c)
|
||
jsr cputc
|
||
jmp __b1
|
||
}
|
||
// Return to home position
|
||
// void random(__zp(3) char k, __zp(8) char n)
|
||
random: {
|
||
.label k = 3
|
||
.label n = 8
|
||
.label __3 = 2
|
||
__b1:
|
||
// m=PEEK
|
||
lda $9114
|
||
sta.z m
|
||
// m>n
|
||
sta.z __3
|
||
// while (m<k || m>n)
|
||
lda.z m
|
||
cmp.z k
|
||
bcc __b1
|
||
lda.z n
|
||
cmp.z __3
|
||
bcc __b1
|
||
// }
|
||
rts
|
||
}
|
||
write_score: {
|
||
// if (score>65000)
|
||
lda.z score+1
|
||
cmp #>$fde8
|
||
bne !+
|
||
lda.z score
|
||
cmp #<$fde8
|
||
!:
|
||
bcc __b1
|
||
beq __b1
|
||
lda #<0
|
||
sta.z score
|
||
sta.z score+1
|
||
__b1:
|
||
// m=0
|
||
lda #0
|
||
sta.z m
|
||
__b5:
|
||
// for (m=0;m<4;m++)
|
||
lda.z m
|
||
cmp #4
|
||
bcc __b6
|
||
// utoa(score,buffer,10)
|
||
lda.z score
|
||
sta.z utoa.value
|
||
lda.z score+1
|
||
sta.z utoa.value+1
|
||
// (!!) Needed. Possibly a bug
|
||
jsr utoa
|
||
// if (score>9)
|
||
lda.z score+1
|
||
bne !+
|
||
lda.z score
|
||
cmp #9+1
|
||
bcc __b2
|
||
!:
|
||
// points[2]=buffer[0]
|
||
lda buffer
|
||
sta points+2
|
||
// points[3]=buffer[1]
|
||
lda buffer+1
|
||
sta points+3
|
||
__b2:
|
||
// if (score>99)
|
||
lda.z score+1
|
||
bne !+
|
||
lda.z score
|
||
cmp #$63+1
|
||
bcc __b3
|
||
!:
|
||
// points[1]=buffer[0]
|
||
lda buffer
|
||
sta points+1
|
||
// points[2]=buffer[1]
|
||
lda buffer+1
|
||
sta points+2
|
||
// points[3]=buffer[2]
|
||
lda buffer+2
|
||
sta points+3
|
||
__b3:
|
||
// chrout(yellow)
|
||
lda #yellow
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// chrout(home)
|
||
lda #home
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// POKE
|
||
lda #4
|
||
sta.z $d3
|
||
// m=0
|
||
lda #0
|
||
sta.z m
|
||
__b9:
|
||
// for (m=0;m<4;m++)
|
||
lda.z m
|
||
cmp #4
|
||
bcc __b10
|
||
// }
|
||
rts
|
||
__b10:
|
||
// chrout(points[m])
|
||
ldy.z m
|
||
lda points,y
|
||
sta.z chrout.petscii
|
||
jsr chrout
|
||
// for (m=0;m<4;m++)
|
||
inc.z m
|
||
jmp __b9
|
||
__b6:
|
||
// points[m]='0'
|
||
lda #'0'
|
||
ldy.z m
|
||
sta points,y
|
||
// for (m=0;m<4;m++)
|
||
inc.z m
|
||
jmp __b5
|
||
}
|
||
chrono_restart: {
|
||
// asm
|
||
lda #0
|
||
tay
|
||
tax
|
||
jsr $ffdb
|
||
// }
|
||
rts
|
||
}
|
||
// void wait(__zp(3) char n)
|
||
wait: {
|
||
.label n = 3
|
||
// m=0
|
||
lda #0
|
||
sta.z m
|
||
__b1:
|
||
// for (m=0;m<n;++m)
|
||
lda.z m
|
||
cmp.z n
|
||
bcc __b4
|
||
// }
|
||
rts
|
||
__b4:
|
||
lda #<0
|
||
sta.z z_1
|
||
sta.z z_1+1
|
||
__b2:
|
||
// for (z=0;z<540;++z)
|
||
lda.z z_1+1
|
||
cmp #>$21c
|
||
bcc __b3
|
||
bne !+
|
||
lda.z z_1
|
||
cmp #<$21c
|
||
bcc __b3
|
||
!:
|
||
// for (m=0;m<n;++m)
|
||
inc.z m
|
||
jmp __b1
|
||
__b3:
|
||
// for (z=0;z<540;++z)
|
||
inc.z z_1
|
||
bne !+
|
||
inc.z z_1+1
|
||
!:
|
||
jmp __b2
|
||
}
|
||
// Converts unsigned number value to a string representing it in RADIX format.
|
||
// If the leading digits are zero they are not included in the string.
|
||
// - value : The number to be converted to RADIX
|
||
// - buffer : receives the string representing the number and zero-termination.
|
||
// - radix : The radix to convert the number to (from the enum RADIX)
|
||
// void utoa(__zp(5) unsigned int value, __zp($d) char *buffer, char radix)
|
||
utoa: {
|
||
.label __10 = $11
|
||
.label __11 = 2
|
||
.label digit_value = 9
|
||
.label buffer = $d
|
||
.label digit = 3
|
||
.label value = 5
|
||
.label started = $10
|
||
lda #<@buffer
|
||
sta.z buffer
|
||
lda #>@buffer
|
||
sta.z buffer+1
|
||
lda #0
|
||
sta.z started
|
||
sta.z digit
|
||
__b1:
|
||
// for( char digit=0; digit<max_digits-1; digit++ )
|
||
lda.z digit
|
||
cmp #5-1
|
||
bcc __b2
|
||
// *buffer++ = DIGITS[(char)value]
|
||
lda.z value
|
||
sta.z __11
|
||
tay
|
||
lda DIGITS,y
|
||
ldy #0
|
||
sta (buffer),y
|
||
// *buffer++ = DIGITS[(char)value];
|
||
inc.z buffer
|
||
bne !+
|
||
inc.z buffer+1
|
||
!:
|
||
// *buffer = 0
|
||
lda #0
|
||
tay
|
||
sta (buffer),y
|
||
// }
|
||
rts
|
||
__b2:
|
||
// unsigned int digit_value = digit_values[digit]
|
||
lda.z digit
|
||
asl
|
||
sta.z __10
|
||
tay
|
||
lda RADIX_DECIMAL_VALUES,y
|
||
sta.z digit_value
|
||
lda RADIX_DECIMAL_VALUES+1,y
|
||
sta.z digit_value+1
|
||
// if (started || value >= digit_value)
|
||
lda.z started
|
||
bne __b5
|
||
lda.z digit_value+1
|
||
cmp.z value+1
|
||
bne !+
|
||
lda.z digit_value
|
||
cmp.z value
|
||
beq __b5
|
||
!:
|
||
bcc __b5
|
||
__b4:
|
||
// for( char digit=0; digit<max_digits-1; digit++ )
|
||
inc.z digit
|
||
jmp __b1
|
||
__b5:
|
||
// utoa_append(buffer++, value, digit_value)
|
||
jsr utoa_append
|
||
// utoa_append(buffer++, value, digit_value)
|
||
// value = utoa_append(buffer++, value, digit_value)
|
||
// value = utoa_append(buffer++, value, digit_value);
|
||
inc.z buffer
|
||
bne !+
|
||
inc.z buffer+1
|
||
!:
|
||
lda #1
|
||
sta.z started
|
||
jmp __b4
|
||
}
|
||
read_chrono: {
|
||
.label __0 = $23
|
||
.label __5 = 9
|
||
// asm
|
||
jsr $ffde
|
||
sta l
|
||
stx m
|
||
// m*256
|
||
txa
|
||
sta.z __0+1
|
||
lda #0
|
||
sta.z __0
|
||
// div16u8u((m*256)+l,60)
|
||
lda.z l
|
||
clc
|
||
adc.z div16u8u.dividend
|
||
sta.z div16u8u.dividend
|
||
bcc !+
|
||
inc.z div16u8u.dividend+1
|
||
!:
|
||
jsr div16u8u
|
||
lda.z div16u8u.return
|
||
sta.z div16u8u.return_1
|
||
lda.z div16u8u.return+1
|
||
sta.z div16u8u.return_1+1
|
||
// POKE
|
||
lda #7
|
||
sta $1e15+c
|
||
lda #$b9
|
||
sta $1e15
|
||
// if (time<10)
|
||
lda.z div16u8u.return_1+1
|
||
bne __breturn
|
||
lda.z div16u8u.return_1
|
||
cmp #$a
|
||
bcs __breturn
|
||
!:
|
||
// POKE
|
||
sec
|
||
lda #<$b9
|
||
sbc.z div16u8u.return_1
|
||
sta.z __5
|
||
lda #>$b9
|
||
sbc.z div16u8u.return_1+1
|
||
sta.z __5+1
|
||
lda.z __5
|
||
sta $1e15
|
||
__breturn:
|
||
// }
|
||
rts
|
||
}
|
||
// Output one character at the current cursor position
|
||
// Moves the cursor forward. Scrolls the entire screen if needed
|
||
// void cputc(__zp(2) char c)
|
||
cputc: {
|
||
.label c = 2
|
||
// if(c=='\n')
|
||
lda #'\n'
|
||
cmp.z c
|
||
beq __b1
|
||
// conio_line_text[conio_cursor_x] = c
|
||
lda.z c
|
||
ldy.z conio_cursor_x
|
||
sta (conio_line_text),y
|
||
// conio_line_color[conio_cursor_x] = conio_textcolor
|
||
lda.z conio_textcolor
|
||
sta (conio_line_color),y
|
||
// if(++conio_cursor_x==CONIO_WIDTH)
|
||
inc.z conio_cursor_x
|
||
lda #$28
|
||
cmp.z conio_cursor_x
|
||
bne __breturn
|
||
// cputln()
|
||
jsr cputln
|
||
__breturn:
|
||
// }
|
||
rts
|
||
__b1:
|
||
// cputln()
|
||
jsr cputln
|
||
rts
|
||
}
|
||
// Used to convert a single digit of an unsigned number value to a string representation
|
||
// Counts a single digit up from '0' as long as the value is larger than sub.
|
||
// Each time the digit is increased sub is subtracted from value.
|
||
// - buffer : pointer to the char that receives the digit
|
||
// - value : The value where the digit will be derived from
|
||
// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased.
|
||
// (For decimal the subs used are 10000, 1000, 100, 10, 1)
|
||
// returns : the value reduced by sub * digit so that it is less than sub.
|
||
// __zp(5) unsigned int utoa_append(__zp($d) char *buffer, __zp(5) unsigned int value, __zp(9) unsigned int sub)
|
||
utoa_append: {
|
||
.label buffer = $d
|
||
.label value = 5
|
||
.label sub = 9
|
||
.label return = 5
|
||
.label digit = 7
|
||
lda #0
|
||
sta.z digit
|
||
__b1:
|
||
// while (value >= sub)
|
||
lda.z sub+1
|
||
cmp.z value+1
|
||
bne !+
|
||
lda.z sub
|
||
cmp.z value
|
||
beq __b2
|
||
!:
|
||
bcc __b2
|
||
// *buffer = DIGITS[digit]
|
||
ldy.z digit
|
||
lda DIGITS,y
|
||
ldy #0
|
||
sta (buffer),y
|
||
// }
|
||
rts
|
||
__b2:
|
||
// digit++;
|
||
inc.z digit
|
||
// value -= sub
|
||
lda.z value
|
||
sec
|
||
sbc.z sub
|
||
sta.z value
|
||
lda.z value+1
|
||
sbc.z sub+1
|
||
sta.z value+1
|
||
jmp __b1
|
||
}
|
||
// Divide unsigned 16-bit unsigned long dividend with a 8-bit unsigned char divisor
|
||
// The 8-bit unsigned char remainder can be found in rem8u after the division
|
||
// __zp($30) unsigned int div16u8u(__zp($23) unsigned int dividend, char divisor)
|
||
div16u8u: {
|
||
.label divisor = $3c
|
||
.label quotient_hi = 2
|
||
.label quotient_lo = $10
|
||
.label return = $12
|
||
.label dividend = $23
|
||
.label return_1 = $30
|
||
// unsigned char quotient_hi = divr8u(BYTE1(dividend), divisor, 0)
|
||
lda.z dividend+1
|
||
sta.z divr8u.dividend
|
||
lda #0
|
||
sta.z divr8u.rem
|
||
jsr divr8u
|
||
// unsigned char quotient_hi = divr8u(BYTE1(dividend), divisor, 0)
|
||
lda.z divr8u.return
|
||
sta.z quotient_hi
|
||
// unsigned char quotient_lo = divr8u(BYTE0(dividend), divisor, rem8u)
|
||
lda.z dividend
|
||
sta.z divr8u.dividend
|
||
jsr divr8u
|
||
// unsigned char quotient_lo = divr8u(BYTE0(dividend), divisor, rem8u)
|
||
// unsigned int quotient = MAKEWORD( quotient_hi, quotient_lo )
|
||
lda.z quotient_hi
|
||
sta.z return+1
|
||
lda.z quotient_lo
|
||
sta.z return
|
||
// }
|
||
rts
|
||
}
|
||
// Print a newline
|
||
cputln: {
|
||
// conio_line_text += CONIO_WIDTH
|
||
lda #$28
|
||
clc
|
||
adc.z conio_line_text
|
||
sta.z conio_line_text
|
||
bcc !+
|
||
inc.z conio_line_text+1
|
||
!:
|
||
// conio_line_color += CONIO_WIDTH
|
||
lda #$28
|
||
clc
|
||
adc.z conio_line_color
|
||
sta.z conio_line_color
|
||
bcc !+
|
||
inc.z conio_line_color+1
|
||
!:
|
||
// conio_cursor_x = 0
|
||
lda #0
|
||
sta.z conio_cursor_x
|
||
// conio_cursor_y++;
|
||
inc.z conio_cursor_y
|
||
// cscroll()
|
||
jsr cscroll
|
||
// }
|
||
rts
|
||
}
|
||
// Performs division on two 8 bit unsigned chars and an initial remainder
|
||
// Returns dividend/divisor.
|
||
// The final remainder will be set into the global variable rem8u
|
||
// Implemented using simple binary division
|
||
// __zp($10) char divr8u(__zp(3) char dividend, char divisor, __zp($f) char rem)
|
||
divr8u: {
|
||
.label __1 = $11
|
||
.label rem = $f
|
||
.label dividend = 3
|
||
.label quotient = $10
|
||
.label i = 7
|
||
.label return = $10
|
||
lda #0
|
||
sta.z i
|
||
sta.z quotient
|
||
__b1:
|
||
// rem = rem << 1
|
||
asl.z rem
|
||
// dividend & 0x80
|
||
lda #$80
|
||
and.z dividend
|
||
sta.z __1
|
||
// if( (dividend & 0x80) != 0 )
|
||
beq __b2
|
||
// rem = rem | 1
|
||
lda #1
|
||
ora.z rem
|
||
sta.z rem
|
||
__b2:
|
||
// dividend = dividend << 1
|
||
asl.z dividend
|
||
// quotient = quotient << 1
|
||
asl.z quotient
|
||
// if(rem>=divisor)
|
||
lda.z rem
|
||
cmp #div16u8u.divisor
|
||
bcc __b3
|
||
// quotient++;
|
||
inc.z quotient
|
||
// rem = rem - divisor
|
||
lax.z rem
|
||
axs #div16u8u.divisor
|
||
stx.z rem
|
||
__b3:
|
||
// for( char i : 0..7)
|
||
inc.z i
|
||
lda #8
|
||
cmp.z i
|
||
bne __b1
|
||
// }
|
||
rts
|
||
}
|
||
// Scroll the entire screen if the cursor is beyond the last line
|
||
cscroll: {
|
||
// if(conio_cursor_y==CONIO_HEIGHT)
|
||
lda #$19
|
||
cmp.z conio_cursor_y
|
||
bne __breturn
|
||
// memcpy(CONIO_SCREEN_TEXT, CONIO_SCREEN_TEXT+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH)
|
||
lda #<DEFAULT_SCREEN
|
||
sta.z memcpy.destination
|
||
lda #>DEFAULT_SCREEN
|
||
sta.z memcpy.destination+1
|
||
lda #<DEFAULT_SCREEN+$28
|
||
sta.z memcpy.source
|
||
lda #>DEFAULT_SCREEN+$28
|
||
sta.z memcpy.source+1
|
||
jsr memcpy
|
||
// memcpy(CONIO_SCREEN_COLORS, CONIO_SCREEN_COLORS+CONIO_WIDTH, CONIO_BYTES-CONIO_WIDTH)
|
||
lda #<COLORRAM
|
||
sta.z memcpy.destination
|
||
lda #>COLORRAM
|
||
sta.z memcpy.destination+1
|
||
lda #<COLORRAM+$28
|
||
sta.z memcpy.source
|
||
lda #>COLORRAM+$28
|
||
sta.z memcpy.source+1
|
||
jsr memcpy
|
||
// memset(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH)
|
||
lda #' '
|
||
sta.z memset.c
|
||
lda #<DEFAULT_SCREEN+$19*$28-$28
|
||
sta.z memset.str
|
||
lda #>DEFAULT_SCREEN+$19*$28-$28
|
||
sta.z memset.str+1
|
||
jsr memset
|
||
// memset(CONIO_SCREEN_COLORS+CONIO_BYTES-CONIO_WIDTH, conio_textcolor, CONIO_WIDTH)
|
||
lda.z conio_textcolor
|
||
sta.z memset.c
|
||
lda #<COLORRAM+$19*$28-$28
|
||
sta.z memset.str
|
||
lda #>COLORRAM+$19*$28-$28
|
||
sta.z memset.str+1
|
||
jsr memset
|
||
// conio_line_text -= CONIO_WIDTH
|
||
sec
|
||
lda.z conio_line_text
|
||
sbc #$28
|
||
sta.z conio_line_text
|
||
lda.z conio_line_text+1
|
||
sbc #0
|
||
sta.z conio_line_text+1
|
||
// conio_line_color -= CONIO_WIDTH
|
||
sec
|
||
lda.z conio_line_color
|
||
sbc #$28
|
||
sta.z conio_line_color
|
||
lda.z conio_line_color+1
|
||
sbc #0
|
||
sta.z conio_line_color+1
|
||
// conio_cursor_y--;
|
||
dec.z conio_cursor_y
|
||
__breturn:
|
||
// }
|
||
rts
|
||
}
|
||
// Copy block of memory (forwards)
|
||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||
// void * memcpy(__zp($b) void *destination, __zp($d) void *source, unsigned int num)
|
||
memcpy: {
|
||
.label src_end = 9
|
||
.label dst = $b
|
||
.label src = $d
|
||
.label source = $d
|
||
.label destination = $b
|
||
// char* src_end = (char*)source+num
|
||
lda.z source
|
||
clc
|
||
adc #<$19*$28-$28
|
||
sta.z src_end
|
||
lda.z source+1
|
||
adc #>$19*$28-$28
|
||
sta.z src_end+1
|
||
__b1:
|
||
// while(src!=src_end)
|
||
lda.z src+1
|
||
cmp.z src_end+1
|
||
bne __b2
|
||
lda.z src
|
||
cmp.z src_end
|
||
bne __b2
|
||
// }
|
||
rts
|
||
__b2:
|
||
// *dst++ = *src++
|
||
ldy #0
|
||
lda (src),y
|
||
sta (dst),y
|
||
// *dst++ = *src++;
|
||
inc.z dst
|
||
bne !+
|
||
inc.z dst+1
|
||
!:
|
||
inc.z src
|
||
bne !+
|
||
inc.z src+1
|
||
!:
|
||
jmp __b1
|
||
}
|
||
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
|
||
// void * memset(__zp($b) void *str, __zp($10) char c, unsigned int num)
|
||
memset: {
|
||
.label end = $12
|
||
.label dst = $b
|
||
.label c = $10
|
||
.label str = $b
|
||
// char* end = (char*)str + num
|
||
lda #$28
|
||
clc
|
||
adc.z str
|
||
sta.z end
|
||
lda #0
|
||
adc.z str+1
|
||
sta.z end+1
|
||
__b2:
|
||
// for(char* dst = str; dst!=end; dst++)
|
||
lda.z dst+1
|
||
cmp.z end+1
|
||
bne __b3
|
||
lda.z dst
|
||
cmp.z end
|
||
bne __b3
|
||
// }
|
||
rts
|
||
__b3:
|
||
// *dst = c
|
||
lda.z c
|
||
ldy #0
|
||
sta (dst),y
|
||
// for(char* dst = str; dst!=end; dst++)
|
||
inc.z dst
|
||
bne !+
|
||
inc.z dst+1
|
||
!:
|
||
jmp __b2
|
||
}
|
||
.segment Data
|
||
// The digits used for numbers
|
||
DIGITS: .text "0123456789abcdef"
|
||
// Values of decimal digits
|
||
RADIX_DECIMAL_VALUES: .word $2710, $3e8, $64, $a
|
||
// [0..65536] 16-bit
|
||
points: .byte 0, 0, 0, 0
|
||
buffer: .byte 0, 0, 0, 0
|
||
// for unexpanded. 37888-4096 color for expanded
|
||
ducknumber: .byte $44, $55, $43, $4b, $3a
|
||
// DUCK:
|
||
chrono: .byte $54, $4d, $3a, $39
|
||
// TM:9
|
||
duck_udg: .byte $e, $1b, $3f, $1f, $f, 7, $f, $1f, 0, 0, 0, 0, 0, $c0, $70, $bc, $1f, $1d, $1e, $f, 3, 1, 1, 3, $ce, $1e, $7c, $f8, $e0, $40, $40, $e0, 0, 0, 0, 0, 0, 0, 0, 0
|
||
// POKE CODES = 0,1,2,3,4; CHROUT CODES = 64, 65, 66, 67, 68 (with previous reverse_off "chrout(146)")
|
||
intro: .text @"\n\n\nDIFFICULTY\n----------\n\n\n"
|
||
.byte 0
|
||
levels: .text @"1.EASIEST\n\n3.EASY\n\n5.MEDIUM\n\n7.HARD\n\n9.EXPERT\n\n\n\n\n"
|
||
.byte 0
|
||
foot: .text @"PRESS: 1,3,5,7 or 9\n\n"
|
||
.byte 0
|
||
game_over: .text @"\n\n\n\nGAME OVER"
|
||
.byte 0
|
||
play_again: .text @"\n\n\nPlay Again (Y/N)?"
|
||
.byte 0
|
||
your_score: .text @"\n\n\nYour Score: "
|
||
.byte 0
|
||
high_score: .text @"\n\nHi-Score: "
|
||
.byte 0
|