#include "TI-82.h" .org 0 .db "Tunnel",0 randvar = TEXT_MEM ;used by 'rand' subroutine x1 = TEXT_MEM+2 ;x coordinate of the left side of the tunnel x2 = TEXT_MEM+4 ;x coordinate of the right side of the tunnel SHIPX = TEXT_MEM+5 ;x coordinate of the ship SCORE = TEXT_MEM+6 ;the score FIND_PIXEL = $4166 LD A,$8C ;set the rom page so that FIND_PIXEL works OUT (2),A Start: di ;disable interrupts, just speeds it up a bit CALL_(CLR_GBU) ;clear GRAPH_MEM ld hl,0 ;Initialize Variables ld (SCORE),hl ; | ld a,44 ; | ld (SHIPX),a ; | ld a,26 ; | ld (x1),a ; | ld a,70 ; | ld (x2),a ; \ / keyloop: ld hl,(SCORE) ;add 1 to the score each turn through the loop inc hl ld (SCORE),hl CALL_(clr_top_line) ;clear top line of GRAPH_MEM ld a,(x1) ld b,0 ld c,a ld d,0 CALL_(BlackLine) ;Draw a line from (0,0) to (x1,0) ld a,(x2) ld b,a ld c,95 ld d,0 CALL_(BlackLine) ;Draw a line from (x2,0) to (95,0) CALL_(scroll) ;scroll the screen down (2 times which makes it faster!) CALL_(scroll) CALL_(PutShip) ;Put the ship onto the screen CALL_(CopyGraphMem) ;copy GRAPH_MEM to LCD, could be replaced by a call to _GRBUFCPY_V, but this is faster CALL_(rand) ;get a 7 bit random number (0-127) cp 63 jr c,add ;if the carry flag is set by the above compare, jump to 'add' sub: ld a,(x1) cp 2 jr z,add ;can't go off the screen ld a,(x1) sub 4 ld (x1),a ld a,(x2) sub 4 ld (x2),a ;subtract 4 from both x1 and x2 jr past_update ;jump past the add part add: ld a,(x2) cp 94 jr z,sub ;we don't want to go off the screen ld a,(x1) add a,4 ld (x1),a ld a,(x2) add a,4 ld (x2),a ;add 4 to x1 and x2 past_update: ld a,0ffh ;this keyscanning routine was yanked from Spaze Invaders 83 by movax out (1),a ld a,0feh ;mask out some things out (1),a in a,(1) cp 253 ;unless you get 253 back, Left isn't down JUMP_NZ(NOLEFT) ld hl,SHIPX ld a,(hl) cp 0 ;ship can't go off the screen JUMP_Z(NOLEFT) ld hl,SHIPX dec (hl) ;decrement Ship's X coordinate NOLEFT: cp 251 JUMP_NZ(NORIGHT) ;Right isn't down if it's not 251 ld hl,SHIPX ld a,(hl) cp 88 ;can't go off the screen to the right either JUMP_Z(NORIGHT) ld hl,SHIPX inc (hl) ;increment Ship's X coordinate NORIGHT: ld a,0ffh ;reset the port out (1),a ld a,0fdh ;mask out some different things out (1),a in a,(1) cp 191 ;check for Clear's Status JUMP_NZ(NOCLR) jr EXIT NOCLR: ld c,0 ;see if the ship has hit anything ld a,(SHIPX) ;goes on for a while... dec a ; [ ld b,a ; ] CALL_(GetPixel) ; [ cp 1 ; ] jr z,EXIT ; [ ld c,0 ; ] ld a,(SHIPX) ; [ add a,8 ; ] ld b,a ; [ CALL_(GetPixel) ; ] cp 1 ; [ jr z,EXIT ; ] ld c,1 ; [ ld a,(SHIPX) ; ] ld b,a ; [ CALL_(GetPixel) ; ] cp 1 ; [ jr z,EXIT ; ] ld c,1 ; [ ld a,(SHIPX) ; [ add a,7 ; ] ld b,a ; [ CALL_(GetPixel) ; ] cp 1 ; [ jr z,EXIT ; ] ld c,2 ; [ ld a,(SHIPX) ; ] add a,1 ; [ ld b,a ; ] CALL_(GetPixel) ; [ cp 1 ; ] jr z,EXIT ; [ ld c,2 ; ] ld a,(SHIPX) ; [ add a,6 ; ] ld b,a ; [ CALL_(GetPixel) ; \/ cp 1 jr z,EXIT ;all done checking for hit JUMP_(keyloop) EXIT: LD HL,$0803 ;set up the coords for displaying the score LD ($800C),HL ld hl,(SCORE) ROM_CALL(D_HL_DECI) ;display score LD HL,$0303 ;set up coords for displaying "Score:" LD ($800C),HL ld hl,(PROGRAM_ADDR) ld de,scorestr add hl,de ROM_CALL(D_ZT_STR) ;write "Score:" ei ;enable interrupts again wait_for_key: ROM_CALL(_GETKEY) cp L_ARROW ;if this weren't here, you probably wouldn't see the score screen jr z,wait_for_key ;take them out to see what I mean cp R_ARROW jr z,wait_for_key ; cp K_CLEAR ;these can be uncommented if you want to see the score when you hit clear ; jr z,wait_for_key ret scroll: ld hl,GRAPH_MEM+756 ;start copying from 1 row up from the bottom of the graph_mem ld de,GRAPH_MEM+768 ;start copying to the end of GRAPH_MEM ld bc,757 ;copy 756 bytes lddr ;load decrement, repeat ret PutShip: ld hl,(PROGRAM_ADDR) ld de,ship add hl,de ;get actual address to ship sprite ld a,(SHIPX) ;x coord is SHIPX ld e,61 ;y coord is always 61 DRWSPR: ;Another great routine by movax push hl ; sprite in hl, coords in a,e 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,$88B8 add hl,de ; Add address to graphbuf ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is this sprite aligned to 8*n,y? jr z,ALIGN pop ix ; ix->sprite ld d,a ; d=how many bits to shift each line ld e,3 ; Line loop LILOP: ld b,(ix+0) ; 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 jr DONE1 ALIGN: ; Blit an aligned sprite to graphbuf pop de ; de->sprite ld b,3 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 DONE1: ret ;The following routine copies the GRAPH_MEM to the LCD much quicker than the internal routine ;you could replace this with ROM_CALL(_GRBUFCPY_V) to cut down on the size, but ;this would also cut down on speed =) CopyGraphMem: ;a fine routine from Showpic by Dines J. ld hl,GRAPH_MEM LD A,7 CALL $7F3 OUT ($10),A ;wacky port stuff, read 82-ports.txt for more info LD A,$80 LineLoop: LD D,A ; Save currect coloum CALL $7F3 OUT ($10),A LD A,$20 ; Goto top CALL $7F3 OUT ($10),A LD BC,$0C11 ; 40 bytes to port 10 WriteLoop: ; Write them NEG NEG NEG NEG OUTI JR NZ,WriteLoop LD A,D INC A CP $C0 JR NZ,LineLoop RET clr_top_line: ;clear first 12 bytes (top row) of GRAPH_MEM ld hl,GRAPH_MEM ld de,GRAPH_MEM+1 ld bc,11 ld a,0 ld (hl),a ldir ret CLR_GBU: ;Clear GRAPH_MEM LD HL,$88B8 LD DE,$88B9 LD BC,$2FF LD A,0 LD (HL),A LDIR RET rand: ;by Chris Busch from rand.asm ld a,(randvar) ld b,a ld a,0 add a,b sla b sla b add a,b sla b sla b add a,b inc a ld (randvar),a srl a ret GetPixel: ;returns 0 only if the pixel is off, otherwise you get a non-zero value push BC call FIND_PIXEL ld b,a push hl pop de ld hl,GRAPH_MEM add hl,de ld a,(hl) and b cp 0 jr z,no_pixel ld a,1 pop bc ret no_pixel: ld a,0 pop bc ret ;Inputs: DE, HL ;Outputs: draws a horizontal black line BlackLine: ;from Plain Jump by Andreas Ess push hl push de ld h, 0 ld l, d add hl, hl ;multiply a by 2 add hl, hl ; * 4 add hl, hl ; * 8 add hl, hl ; * 16 push bc srl b ;divide b by 8 srl b srl b ld d, 0 ld e, b add hl, de ld de, GRAPH_MEM add hl, de pop bc ;HL now contains video-offset ld a, b ;load real x1-pos into a ld d, a ;d=real x1-pos is needed later... and 7 ;and make the mask ld b, 128 ;b is the video-mask jr z, BLoop ;mod(a,7) = 0->no mask-shift needed ld e, 128 ld b, a ;times to shift ShiftBLoop: srl e djnz ShiftBLoop ld b, e BLoop: ;ready-go! ld a, (hl) ;load byte from vid-ram or b ;set it to black ld (hl), a ;and save it back to vid-ram dec c ;decrement X2 if X2 = X1 -> end ld a, c cp d ;now know for what d was needed? jr z, EndBlack srl b ;shift mask jr nz, BLoop ld b, 128 inc hl jr BLoop EndBlack: pop de pop hl ret ship: .db %00011000 .db %00111100 .db %01111110 scorestr: .db "Score:",0 .end END