home *** CD-ROM | disk | FTP | other *** search
- .NOLIST
- #define equ .equ
- #define EQU .equ
- #define end .end
- #include "ti83asm.inc"
- #include "tokens.inc"
- .LIST
-
- ; variables
-
- #define temp 8265h ; temporary
- #define levelname 8266h ; name of current level
- #define level 826Ah ; pointer to symbol table entry of current level
- #define row 826Ch ; level offset
- #define col 826Eh ; skier position
- #define score 826Fh ; score
- #define flakes 8271h ; begining of snowflake x's and y's
-
- ; direct input key equates
-
- kLeft .equ 253
- kRight .equ 251
- kMode .equ 191
- kClear .equ 191
-
- ; program and list object type equates
-
- progobj .equ 05h ; program
- protprogobj .equ 06h ; protected program
- listobj .equ 01h ; list
- clistobj .equ 0Dh ; complex list
-
- lcddata .equ 11h ; lcd data port
-
- .org 9327h
-
- init:
-
- call _runindicoff
- call load ; load y coords of snow flakes
-
- look_up_level:
-
- ld a,0 ; temp holds the number of levels
- ld (temp),a ; if temp is 0 at the end there aren't any levels
- ld hl,(progptr) ; start of program/list symbol table
-
- level_loop:
-
- ld a,(hl) ; get object type
- and $1F ; mask off bits 5-7
- cp progobj ; is it a program?
- jr z,program ;
- cp protprogobj ; is it a protected program?
- jr z,program ;
- cp listobj ; is it a list?
- jp z,list ;
- cp clistobj ; is it a complex list?
- jp z,list ;
- ld a,(temp) ; see if count is zero
- cp 0 ;
- ret z ;
- jr look_up_level ; end of program/list symbol table. start over
-
- program:
-
- dec hl ; skip T
- dec hl ; skip DAL
- dec hl ; skip DAH
- ld b,(hl) ; get length of name
- ld a,b ;
- cp 8 ; is the name 8 chars long?
- jr z,good_prog ; if it is then it could be a valid level
-
- program_loop:
-
- dec hl ; get past name
- djnz program_loop ;
- dec hl ; next pointer
- jr level_loop ;
-
- good_prog:
-
- ld (level),hl ; save program address
- ld b,5 ; five chars to test
- ld de,defaultprog ; name to test against
-
- cploop:
-
- dec hl ; compare name to base name
- ld a,(de) ;
- cp (hl) ; are they the same?
- jp nz,nextprog ; if not move on to the next program
- inc de ;
- djnz cploop ;
- ld de,levelname ;
- ld b,3 ;
-
- cpyloop:
-
- dec hl ; copy last 3 chars of name
- ld a,(hl) ;
- ld (de),a ;
- inc de ;
- djnz cpyloop ;
- ld a,0 ; add 0 terminator
- ld (de),a ;
-
- ld a,(temp) ; increment count
- inc a ;
- ld (temp),a ;
-
- snow:
-
- call _grbufclr ; clear buffer
- ld hl,title ; copy title pic
- ld de,plotsscreen+60 ;
- ld bc,300 ;
- ldir ;
- set textwrite,(iy+sgrflags) ; write to buffer
- ld hl,$221E ; write "By Ian Graf"
- ld (pencol),hl ;
- ld hl,creatorstr ;
- call _vputs ;
- ld hl,$2D2A ; write level name
- ld (pencol),hl ;
- ld hl,levelname ;
- call _vputs ;
- ld hl,$3422 ; write "High"
- ld (pencol),hl ;
- ld hl,highstr ;
- call _vputs ;
- ld hl,$3432 ; write high score
- ld (pencol),hl ;
- call getscore ;
- call _setxxxxop2 ;
- call _op1exop2 ;
- ld a,3 ;
- call _dispop1a ;
- res textwrite,(iy+sgrflags) ; write to display
-
- ld hl,flakes ; draw out snow flakes
- ld b,15 ;
-
- snow_loop:
-
- call set_flake_y ; move flake down
- call set_flake_x ; move flake across
- ld a,(hl) ; get x
- inc hl ; get y
- ld e,(hl) ;
- inc hl ;
- push hl ;
- push bc ;
- ld hl,flake ; flake image
- push af ;
- ld a,e ; draw flake if it is on screen
- cp 0 ;
- pop af ;
- call p,drwspr ;
- pop bc ;
- pop hl ;
- djnz snow_loop ;
- call bufcpy ; redraw screen
- call _getk ;
- ld a,21 ; was 2nd pressed?
- call _setxxop1 ;
- call _cpop1op2 ;
- jr z,game_start ; start game
- ld a,31 ; was Alpha pressed?
- call _setxxop1 ;
- call _cpop1op2 ;
- jr z,nextprog ; next level
- ld a,45 ; was Clear pressed?
- call _setxxop1 ;
- call _cpop1op2 ;
- jr z,quit ; quit
- jp snow
-
- nextprog:
-
- ld hl,(level) ; restore program address
- ld b,8 ; 8 chars in name
- jp program_loop ; next pointer
-
- list:
-
- dec hl ; skip T
- dec hl ; skip DAL
- dec hl ; skip DAH
- ld b,(hl) ; get length
-
- list_loop:
-
- dec hl ; skip over name
- djnz list_loop ;
- dec hl ; next pointer
- jp level_loop ;
-
- set_flake_y:
-
- inc hl ; get flake y
- ld a,(hl) ; is it at the bottom
- cp 61 ;
- jr z,flakeup ; move it to the top
- inc a ; move it down
- ld (hl),a ;
- dec hl ;
- ret
-
- flakeup:
-
- ld a,0 ; move flake to the top
- ld (hl),a ;
- dec hl ;
- ret
-
- set_flake_x:
-
- inc hl ; get flake y
- ld a,(hl) ;
- cp 0 ; is it 0
- dec hl ;
- ret nz ; don't chang x then
- call rand ; get random number
- ld (hl),a ;
- ret
-
- ; my own random routine to generate a number between 0 and 88
- ; i used it because it is fast and small
-
- rand:
-
- ld a,r
- and %01111111
- cp 110
- jr nc,rand
- cp 17
- jr c,rand
- sub 18
- ret
-
- load:
-
- ld hl,flakes ; load offscreen coords into flake y's
- ld a,-1 ;
- ld b,15 ;
-
- load_loop:
-
- inc hl ;
- ld (hl),a ;
- sub 4 ;
- inc hl ;
- djnz load_loop ;
- ret
-
- ; when someone quits at the title screen
-
- quit:
-
- call _clrlcdfull ; clear screen
- call _clrtxtshd ; clear text shadow
- call _homeup ; place cursor at top
- ret
-
- ; rest of the game
-
- game_start:
-
- ld hl,0 ; reset score
- ld (score),hl ;
- ld hl,(level) ; restore address to level
- inc hl ; move to DAL
- ld d,(hl) ; copy data address to de
- inc hl ;
- ld e,(hl) ;
- ld hl,4 ;
- add hl,de ;
- ld (row),hl ; store level offset
- ld a,5 ; position skier
- ld (col),a ;
- ld b,250 ; loop 250 times
-
- scroll_loop:
-
- push bc
-
- ld a,$FF ; reset key port
- out (1),a ;
- ld a,$FE ; enable arrow pad
- out (1),a ;
- in a,(1) ;
- cp kRight ; check for right arrow
- call z,move_right ; move skier right
- cp kLeft ; check for left arrow
- call z,move_left ; move skier left
-
- ld a,$FF ; reset key port
- out (1),a ;
- ld a,$FD ; enable row with clear
- out (1),a ;
- in a,(1) ;
- cp kClear ; check Clear
- jp z,skiquit ; move skier right
-
- ld a,$FF ; reset key port
- out (1),a ;
- ld a,$BF ; enable row with mode
- out (1),a ;
- in a,(1) ;
- cp kMode ; check Mode
- call z,pause ; move skier right
-
- call _grbufclr ; clear buffer
- call drawlevel ; draw level
- call drawskier ; draw skier
- call bufcpy ; copy to screen
- call getitem ; get the item at the skier's position
- cp 0 ; check for collision
- jp nz,hit ;
- call delay ; delay for a little bit
-
- ld hl,(row) ; move to next row in level
- ld de,6 ;
- add hl,de ;
- ld (row),hl ;
-
- ld hl,(score) ; increment score
- inc hl ;
- inc hl ;
- ld (score),hl ;
-
- pop bc ; reloop
- djnz scroll_loop ;
-
- done:
-
- call load ; reset flakes
- call _grbufclr ; clear buffer
- ld hl,title ; draw title
- ld de,plotsscreen+60 ;
- ld bc,300 ;
- ldir ;
- call bufcpy ; copy to screen
- ld hl,$0305 ; write "Score:"
- ld (currow),hl ;
- ld hl,scorestr ;
- call _puts ;
- ld hl,(score) ; write the score
- call _disphl ;
- ld hl,$0306 ; write "High:"
- ld (currow),hl ;
- ld hl,highstr ;
- call _puts ;
- call getscore ; write high score
- call _disphl ;
- call waitfor2nd ; wait for press of 2nd
- call getscore ; check for new high score
- ld de,(score) ;
- call _cphlde ;
- jp nc,snow ; return to title screen
- call getdata ; load new score
- ld hl,(score) ;
- ex de,hl ;
- ld (hl),d ;
- inc hl ;
- ld (hl),e ;
- call bufcpy ; clear bottom of screen
- ld hl,$0405 ; write "New High"
- ld (currow),hl ;
- ld hl,newstr1 ;
- call _puts ;
- ld hl,$0506 ; write "Score"
- ld (currow),hl ;
- ld hl,newstr2 ;
- call _puts ;
- call waitfor2nd ; wait for press of 2nd
- jp snow ; return to title screen
-
- skiquit:
-
- pop bc ; clear stack
- call _getk ; catch last key press
- call load ; reset flakes
- jp snow ; return to title screen
-
- hit:
-
- pop bc ; clear stack
- call reverse_screen ; invert screen
- call shake_screen ; give it a shake
- jp done ; return to title screen
-
- pause:
-
- call _getk ; catch last key press
- ld hl,$0503 ; write "Paused"
- ld (currow),hl ;
- ld hl,pausestr ;
- call _puts ;
-
- pause_loop:
-
- call _getk ; wait for press of mode
- ld a,22 ;
- call _setxxop1 ;
- call _cpop1op2 ;
- jr nz,pause_loop ;
- call delay ; delay to allow key to be released
- ret
-
- waitfor2nd:
-
- call _getk ; wait for press of 2nd
- ld a,21 ;
- call _setxxop1 ;
- call _cpop1op2 ;
- jr nz,waitfor2nd ;
- ret
-
- ; draw out the level data compared to current row offset
-
- drawlevel:
-
- ld hl,(row) ; start at current level offset
- ld de,plotsscreen ; draw to buffer
- ld b,8 ; 8 rows
-
- draw_loop1:
-
- push bc
- ld b,6 ; 6 bytes per row
-
- draw_loop2:
-
- push bc
- ld a,(hl) ; get data
- push hl ; save address to current level byte
- srl a ; shift right 4
- srl a ;
- srl a ;
- srl a ;
- call cpitem ; draw item
- inc de ; move to next byte in buffer
- pop hl ; restore address to current level byte
- ld a,(hl) ; get data
- push hl ; save address to current level byte
- and $0F ; mask off first 4 bits
- call cpitem ; draw item
- inc de ; move to next byte in buffer
- pop hl ; restore address to current level byte
- inc hl ; move to next byte in level
- pop bc
- djnz draw_loop2
-
- next_row:
-
- push hl
- ld hl,84 ; move to next row down in plotsscreen
- add hl,de ;
- ex de,hl ;
- pop hl ;
- pop bc ;
- djnz draw_loop1 ;
- ret ; all done
-
- cpitem:
-
- cp 1 ; is it grass
- call z,drawgrass ;
- cp 2 ; is it a tree
- call z,drawtree ;
- cp 3 ; is it a small rock
- call z,drawrock1 ;
- cp 4 ; is it a large rock
- call z,drawrock2 ;
- cp 5 ; is it a gate
- call z,drawgate ;
- ret
-
- ; draws out item
-
- draw_item:
-
- push de ; save current address in plotsscreen
- ld b,8
-
- draw_item_loop:
-
- push bc
- push hl
- ld a,(hl)
- ld (de),a
- ld hl,12
- add hl,de
- ex de,hl
- pop hl
- inc hl
- pop bc
- djnz draw_item_loop
- pop de ; restore current address in plotsscreen
- ret
-
- ; sets up drawing for each item
-
- drawgrass:
-
- ld hl,grass
- call draw_item
- ret
-
- drawtree:
-
- ld hl,tree
- call draw_item
- ret
-
- drawrock1:
-
- ld hl,rock1
- call draw_item
- ret
-
- drawrock2:
-
- ld hl,rock2
- call draw_item
- ret
-
- drawgate:
-
- ld hl,gate
- call draw_item
- ret
-
- ; draw the skier
- ; uses the same draw_item routine
-
- drawskier:
-
- ld hl,plotsscreen
- ld d,0
- ld a,(col)
- ld e,a
- add hl,de
- ex de,hl
- ld hl,skier
- call draw_item
- ret
-
- ; move skier to the right
-
- move_right:
-
- ld a,(col)
- cp 11 ; is it at the right edge ?
- ret z
- inc a
- ld (col),a
- ret
-
- ; move skier to the left
-
- move_left:
-
- ld a,(col)
- cp 0 ; is it at the left edge ?
- ret z
- dec a
- ld (col),a
- ret
-
- ; input: hl points symbol table entry
- ; output: de points data of symbol table entry
-
- getdata:
-
- ld hl,(level)
- inc hl ; move to DAL
- ld d,(hl) ; copy data address to de
- inc hl ;
- ld e,(hl) ;
- inc de ; skip 1st length byte
- inc de ; skip 2nd length byte
- ret
-
- ; output: hl coutains high score of level
-
- getscore:
-
- call getdata
- ex de,hl ; exchange de and hl
- ld d,(hl)
- inc hl
- ld e,(hl)
- ex de,hl
- ret
-
- ; get the item at the skier's current position
- ; so you can check to see if the skier hit anything
- ; a->item
-
- getitem:
-
- ld a,(col) ; to get skier offset you have to
- bit 0,a
- jr nz,odd ; 1 means it is odd
-
- even:
-
- srl a ; divide skier offset by 2
- ld d,0 ; add 6
- ld e,a
- ld hl,(row) ; add skiercol/2+6 to the level row offset
- add hl,de
- ld a,(hl)
- srl a ; shift to the right 4 times to get first 4 bits
- srl a
- srl a
- srl a
- ret ; return: a = item at skiers position
-
- odd:
-
- srl a ; divide skier offset by 2
- ld d,0 ; add 6
- ld e,a
- ld hl,(row) ; add skiercol/2+6 to the level row offset
- add hl,de
- ld a,(hl)
- and $0F ; mask off first 4 bits
- ret ; return: a = item at skiers position
-
- ; produces a delay
- ; make bc a larger number to produce a longer delay
- ; make bc a smaller number to produce a shorter delay
-
- large_delay:
-
- push af
- push bc
- ld bc,$5500
- jr delay_loop
-
- delay:
-
- push af
- push bc
- ld bc,$4600
-
- delay_loop:
-
- dec bc
- ld a,b
- or c
- jr nz,delay_loop
- pop bc
- pop af
- ret
-
- ; inverts screen
-
- reverse_screen:
-
- ld hl,plotsscreen
- ld de,plotsscreen+768
-
- reverse_loop:
-
- ld a,(hl)
- cpl
- ld (hl),a
- inc hl
- call _cphlde
- jr nz,reverse_loop
- call bufcpy
- ret
-
- ; shakes screen when you hit something
-
- shake_screen:
-
- ld b,2
-
- shake_loop:
-
- call large_delay ; delay
- ld a,42h ; set screen offset to 2
- out (lcdinstport),a
- call large_delay ; delay
- ld a,40h ; set screen offset to 0
- out (lcdinstport),a
- djnz shake_loop
- ret
-
- ;▄████████████▀ DRWSPR ▀███████████████████████████████████████████████████████
- ;┌────────────────────────────────────────────────────────────────────────────┐
- ;│ Draw 8x8 sprite ■ a=x, e=y, hl=sprite address │
- ;└────────────────────────────────────────────────────────────────────────────┘
-
- drwspr:
-
- push hl ; Save sprite address
-
- ;████ Calculate the address in graphbuf ████
-
- ld hl,0 ; Do y*12
- ld d,0
- add hl,de
- add hl,de
- add hl,de
- add hl,hl
- add hl,hl
-
- ld d,0 ; Do x/8
- ld e,a
- srl e
- srl e
- srl e
- add hl,de
-
- ld de,plotsscreen
- add hl,de ; Add address to graphbuf
-
- and %00000111 ; Get the remainder of x/8
- cp 0 ; Is this sprite aligned to 8*n,y?
- jr z,align
-
-
- ;████ Non aligned sprite blit starts here ████
-
- pop ix ; ix->sprite
- ld d,a ; d=how many bits to shift each line
-
- ld e,8 ; Line loop
-
- lilop:
-
- ld b,(ix) ; Get sprite data
-
- ld c,0 ; Shift loop
- push de
-
- shlop:
-
- srl b
- rr c
- dec d
- jr nz,shlop
- pop de
-
- ld a,b ; Write line to graphbuf
- or (hl)
- ld (hl),a
- inc hl
- ld a,c
- or (hl)
- ld (hl),a
-
- ld bc,11 ; Calculate next line address
- add hl,bc
- inc ix ; inc spritepointer
-
- dec e
- jr nz,lilop ; Next line
- ret
-
- ;████ Aligned sprite blit starts here ████
-
- align: ; Blit an aligned sprite to graphbuf
-
- pop de ; de->sprite
- ld b,8
-
- alop1:
-
- ld a,(de)
- or (hl) ; xor=erase/blit
- ld (hl),a
- inc de
- push bc
- ld bc,12
- add hl,bc
- pop bc
- djnz alop1
- ret
-
- ;▄████████████▄ DRWSPR ▄███████████████████████████████████████████████████████
-
- ; copy plotsscreen to lcd
- ; faster than _grbufcpy_v
-
- bufcpy:
-
- ld hl,plotsscreen
- ld b,40h
- di
- ld a,7
- call LCDBusy
- out (lcdinstport),a
- ld a,127
-
- bclcpy:
-
- push bc
- inc a
- ld (8012h),a
- call s7port10
- call lcdbusy
- out (lcdinstport),a
-
- ld a,20h
- call lcdbusy
- out (lcdinstport),a
- ld b,12
-
- bcl2cpy:
-
- ld a,(hl)
- inc hl
- call lcdbusy
- out (lcddata),a
- djnz bcl2cpy
- pop bc
- ld a,(8012h)
- djnz bclcpy
- ld a,5
- call lcdbusy
- out (lcdinstport),a
- ei
- ret
-
- lcdbusy:
-
- push af
- inc hl
- dec hl
- pop af
- ret
-
- s7port10:
-
- push af
- ld a,7
- call lcdbusy
- out (lcdinstport),a
- pop af
- ret
-
- ; title image
-
- title:
-
- .db $01,252,$03,$E0,$00,$00,$00,$00,$00,$00,$00,$00
- .db $07,$06,$02,$20,$00,$00,$00,$00,$00,$00,$00,$00
- .db $0C,$02,$02,$20,$00,$00,$00,$00,$00,$00,$00,$00
- .db $18,$02,$06,$20,$00,$00,$00,$00,$00,$00,$00,$00
- .db $11,$F6,$04,$60,$1F,$C0,$1F,$F8,$01,$FC,$01,$FF
- .db $11,$FC,$04,$40,$70,$60,$10,$0C,$07,$06,$07,$01
- .db $10,$38,$0D,$40,$C0,$30,$30,$04,$0C,$02,$0C,$01
- .db $10,$0C,$0A,$C1,$8F,$10,$23,$C4,$18,$E2,$08,$7B
- .db $19,$04,$0D,$81,$19,$50,$62,$44,$11,$E2,$08,$7E
- .db $0E,$54,$1B,$83,$19,$B0,$E2,$C6,$70,$02,$08,$0C
- .db $7B,$0C,$21,$86,$92,$51,$46,$8D,$A4,$06,$04,$04
- .db $4F,$AC,$20,$C9,$36,$2E,$45,$88,$33,$FD,$1F,$D4
- .db $C1,$DC,$40,$B2,$5C,$60,$47,$00,$29,$E6,$F3,$EC
- .db $80,$B2,$41,$02,$00,$C0,$80,$24,$30,$04,$00,$3C
- .db $C0,$61,$80,$00,$03,$88,$00,$61,$78,$01,$20,$18
- .db $60,$00,$29,$00,$E6,$02,$8F,$DA,$8F,$44,$10,$08
- .db $1E,$04,$10,$00,$01,$C8,$88,$05,$06,$28,$25,$10
- .db $0C,$11,$26,$08,$E1,$41,$98,$02,$01,$82,$18,$20
- .db $02,$86,$99,$23,$16,$23,$10,$00,$00,$44,$37,$C0
- .db $01,$29,$B0,$94,$0A,$18,$F0,$02,$00,$30,$E0,$00
- .db $01,$D8,$C0,$48,$08,$0D,$80,$07,$00,$09,$00,$00
- .db $01,$60,$80,$50,$00,$07,$00,$05,$00,$09,$00,$00
- .db $00,$E0,$00,$50,$00,$04,$00,$08,$80,$06,$00,$00
- .db $00,$C0,$00,$30,$00,$00,$00,$09,$80,$04,$00,$00
- .db $00,$80,$00,$20,$00,$00,$00,$07,$00,$00,$00,$00
-
- ; different sprites
-
- skier:
-
- .db %00100100
- .db %00100100
- .db %01111110
- .db %01100110
- .db %01111110
- .db %00111100
- .db %00100100
- .db %00100100
-
- grass:
-
- .db %00101010
- .db %10100000
- .db %00010101
- .db %01001000
- .db %00100010
- .db %00001100
- .db %01010001
- .db %01000010
-
- tree:
-
- .db %00011000
- .db %00011000
- .db %00111100
- .db %00111100
- .db %01111110
- .db %01111110
- .db %11111111
- .db %00011000
-
- rock1:
-
- .db %00000000
- .db %00000000
- .db %00001100
- .db %00010010
- .db %00100010
- .db %00100010
- .db %00011100
- .db %00000000
-
- rock2:
-
- .db %00000000
- .db %00111000
- .db %01000100
- .db %01010010
- .db %10100001
- .db %10000001
- .db %01000011
- .db %00111100
-
- gate:
-
- .db %00000000
- .db %01000010
- .db %01111110
- .db %01111110
- .db %01000010
- .db %01000010
- .db %01000010
- .db %01000010
-
- flake:
-
- .db %01100000
- .db %11110000
- .db %01100000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
- .db %00000000
-
- creatorstr:
-
- .db "By Ian Graf",0
-
- pausestr:
-
- .db "Paused",0
-
- scorestr:
-
- .db "Score",0
-
- highstr:
-
- .db "High ",0
-
- newstr1:
-
- .db "New High",0
-
- newstr2:
-
- .db "Score!",0
-
- defaultprog:
-
- .db "ZSKIL"
-
- .end
- END
-