; last modif 1/12/99 ;porter's note: ;I left most of the comments unchanged from the 82 version (in the code there will be a 16 ;and in the comment there will be a 12, etc) try not to get confused by this #include ti86asm.inc #include asm86.h #include ti86abs.inc #include ram86.inc #include ti86und.inc alock equ $4078 ballx = TEXT_MEM bally = TEXT_MEM+1 blockcnt = TEXT_MEM+2 score = TEXT_MEM+3 tmpx = TEXT_MEM+5 ; used in movelt/rt data = TEXT_MEM+6 ; for converting SOS stuff string = TEXT_MEM+9 count = TEXT_MEM+30 .org _asm_exec_ram nop jp main .dw 0000 .dw title HighS: .dw 0 Highname: .db "----------",0 title: .db "* FallDown 1.4 *",0 ;------------------------------------------- main: call _clrLCD call _runindicoff ; Title Screen ; ; call CR_GRBCopy ; set 3,(iy+$05) ld e,c ;c is 0 from clrLCD ld d,e ld hl,title call DispText ; res 3,(iy+$05) ld de,0900h ld hl,AuthorStr call DispText ld de,0f00h ld hl,AuthorWeb call DispText ld de,1500h ld hl,port call DispText ld de,1b00h ld hl,HighScr call DispText ld de,1b25h ld hl,(HighS) call SdispHL ld de,1b37h ld hl,Highname call DispText ld de,2400h ld hl,choosespeed call DispText titleloop: call GET_KEY cp K_EXIT jp z,endloop2 cp K_F5 jr c,titleloop cp K_F1+1 jr nc,titleloop sub K_F5 ld b,a add a,a add a,a add a,b ld hl,count ld (hl),a inc (hl) inc (hl) sub 20 neg ld e,a add a,a add a,a add a,e ld l,a ld h,0 ld (score),hl ;------------- call _clrLCD ld hl,$fc00 ld de,$ca06 ld bc,1024 ldir ld hl, ballx ld (hl), 44 inc hl ld (hl), c ;c is 0, from the ldir Initialize: call RandomBlocks ld hl, (score) add hl, hl ; hl=score*2 ld a, 24 sub h ; a=0 if sc<128, 1 if 128<=sc<256, ... ld b, a ScrollDLoop: push bc ; 11 c, 1 b call Scroll_U call check_coll ; check collisions & gravity stuff call put_ball ; put ball (xor) ld de,$fc00 ld hl,$ca06 ld bc,1024 ldir ld de,0 ld hl,(score) call SdispHL call put_ball ; remove ball (xor) HALT ; one halt, try to go always at same speed Continue: ld a,%10111111 out ($01),a in a,($01) bit 6,a pop bc jp z,show_sc push bc bit 7,a jr nz,nopause pause: call GET_KEY or a jr z,pause nopause: ld a, $fe out (1), a in a, (1) rra rra jr nc, moveleft rra jr nc, moveright ld a,(count) jr nomove donemv: ld a,(count) dec a nomove: ld b,a slowouter: push bc ld b,255 slowinner: nop djnz slowinner pop bc djnz slowouter pop bc djnz ScrollDLoop jr Initialize moveleft: ld a, (ballx) sub 2 jr c, donemv ; exit if we're already at left side ld (tmpx), a jr x_check moveright: ld hl, ballx ld a, (hl) add a,2 cp 128-4 jr nc, donemv ; exit if we're already at right side ld (tmpx), a add a, 5 ; we check right side x_check: push af ld a, (bally) ld e, a pop af call getphysaddr ld a, (hl) or a jr nz, donemv ; don't move if there is something in the way ld de, 5*16 add hl, de ; same stuff if there's something a bit lower ld a, (hl) or a jr nz, donemv ld a, (tmpx) ld (ballx), a ; else move the ball jr donemv RandomBlocks: ld b, 16 ; 12 blocks max to put ld hl, $ca06h+(60*16) ; where to put blocks rb_loop: push bc push hl ld b, 5 call vector1 ; one luck on 5 to have a hole pop hl or a ; put a space ? jr z, rb_djnz ; yeah, so skip it ; else put the brick ld ix, block ld de, 16 ld b, 4 ; 4 lines to put push hl rb_putloop: ld a, (ix+0) ld (hl), a inc ix add hl, de djnz rb_putloop pop hl rb_djnz: inc hl pop bc djnz rb_loop ; now, check there is at least one hole ;; ld hl, $fc00h+(60*16) ; not needed : works as well with second row ld b, 16 xor a ; c used as number of bricks counter rb_cloop: ; check loop ld c,(hl) rrc c adc a, 0 djnz rb_cloop cp 16 ; if less than 12 brick ( so at least one hole) ret c ; then exit ld b, a ; a was 12 if we didn't exit call vector1 ; put a hole somewhere ld hl, $ca06h+(60*16) ld d, 0 ld e, a add hl, de ; find where to put the hole ld b, 4 ; 4 rows to clear ld e, 16 ; d = 0 rb_cl_loop: ; clear loop ld (hl), d ; d = 0 add hl, de ; next row djnz rb_cl_loop ret Scroll_U: ; [?16228? Clock Cycles] LD HL, $ca06h+16 ; Copy from one row below top LD DE, $ca06h ; to top row LD BC, 1008 ; 756 bytes LDIR LD H, D ; Fill Blanks LD L, E INC E LD (HL), B LD C, 15 LDIR RET check_coll: ; gravity and collision stuff : ld a, (bally) add a, 6 ld e,a ld a, (ballx) call getphysaddr ; check left ld a, (hl) or a ; can move down ? jr nz, cc_downno ; no ==> move it up ld a, (ballx) and 7 cp 3 ; if < 3, then same block lt&rt jr c, cc_movedn ; so skip this check inc hl ; check right ld a, (hl) dec hl or a ; can move down ? jr nz, cc_downno ; no ==> move it up cc_movedn: ld hl,(score) ; increase the score inc hl ld (score),hl ld hl, bally ; move the ball down inc (hl) ld a, (hl) cp 60-5 ; is it too far down ? ret c ; no : ok dec (hl) ; else stay where it was ret cc_downno: ; if the ball can't move down ; a short check to see it it must really go up, or if it can stay where it is ld de, -16 add hl, de ; go one line upper ld a, (hl) ; check left or a ; something down ? jr nz, cc_mvup ; yeah ==> move up ld a, (ballx) and 7 cp 3 ; if < 3, then same block lt&rt ret c ; so skip this check inc hl ; check right ld a, (hl) ret z cc_mvup: ld hl, bally dec (hl) ld a, (hl) and $80 ; check if y<0 ret z ; if ball is out of the screen, you've loose loose: ld hl, loostxt pop de ; don't return to the main loop pop de ; bc has been pushed in the main loop ld de, $0002 call DispText show_sc: ld de, $0602 ld hl,scoretxt call DispText ld de,0618h ld hl,(score) call SdispHL call GET_KEY ; flush keypress buffer CheckHigh: ld hl,(HighS) ld de,(score) ;---------= High Score =--------- ; Input: hl=previous high score ; de=current score ; Output: hl=high score ; c set if new high score, c reset if not ; Registers destroyed: af, de, hl scorechk: sbc hl,de ex de,hl jr nc,EndLoop ld (HighS),hl ld hl,1002h ld (_penCol),hl ld hl,$fc00+(16*16) ld de,$fc00+(16*16)+1 ld bc,16*18-1 ld (hl),0 ldir ld hl,NHSMsg call _vputs ld hl,$0003 ld (_curRow),hl ld hl,Highname call textinput ld hl,varname-1 rst 20h rst 10h ld a,b ex de,hl call _load_ram_ahl ld de,HighS-$d744 add hl,de ex de,hl ld hl,HighS ld bc,12 ldir jr endloop2 EndLoop: call GET_KEY or a jr z,EndLoop sub 2 ; wait 4 a key except arrows jr z,EndLoop dec a jr z,EndLoop endloop2: call _homeup call _clrScrn ret getphysaddr: ; get physic address from x/y ; input : e=y, a=x ; output : hl = addr ld h,0 ld d,h ld l,e add hl,hl add hl,hl rra add hl,hl rra add hl,hl rra ld e,a ; do x/8 add hl,de ; d was already 0 ld de, $ca06 add hl, de ret DispText: ld (_penCol), de jp _vputs SdispHL: ld (_penCol),de ld de,-1 ;routine by Matthew Scepcar ld (_curRow),de xor a call $4a33 dec hl jp _vputs put_ball: ld a, (bally) ld l, a ld a, (ballx) ld ix, ballspr ld b,6 jp vector0 loostxt: .db "* Game Over *",0 HighScr: .db "High " scoretxt: .db "Score: ",0 AuthorStr: .db "By Ahmed E. and Florent Dh.",0 AuthorWeb: .db "Idea: Thomas FERNIQUE ",0 port: .db "TI-86 port by Aaron Curtis",0 NHSMsg: .db "New High Score! Enter Your Name:",0 choosespeed .db "Choose Speed [F1-F5]",0 block: .db %11111111 .db %10000001 .db %10111111 .db %11111111 ballspr: .db %01111000 .db %10110100 .db %11001100 .db %11001100 .db %10110100 .db %01111000 ;---------= Random number generator =--------- ; input b=upper bound ; ouput a=answer 0<=a