;This is Diamonds v1.3 converted for work on the 82. ;By: Ilya Winham (ilyamojo@geocities.com) ;I will try to fully convert this when I have more time ;83 version by Joe Wingbuermule ;Enjoy! This game should work with no bugs #INCLUDE "Ti82.h" xc = TEXT_MEM ; x coordinate yc = TEXT_MEM+1 ; y coordinate loc = TEXT_MEM+2 ; memory address mloc = TEXT_MEM+4 ; matrix address ssz = TEXT_MEM+6 ; sprite size dir = TEXT_MEM+8 ; direction (up/down) tmp = TEXT_MEM+10 ; temp variable ovrflag = TEXT_MEM+13 ; game over flag cblk = TEXT_MEM+14 ; current block ta = TEXT_MEM+15 ; temp a tb = TEXT_MEM+16 ; temp b blks = TEXT_MEM+17 ; number of regular blocks left lblks = TEXT_MEM+18 ; number of last blocks left winflag = TEXT_MEM+19 ; winner flag lvs = TEXT_MEM+20 ; lives left lev = TEXT_MEM+21 ; current level level = APD_BUF ; current level matrix (84 bytes) score = TEXT_MEM+25 ; score tickc = TEXT_MEM+27 ; count between ticks tick = TEXT_MEM+28 ; how many ticks left xc2 = TEXT_MEM+30 yc2 = TEXT_MEM+31 startlev = TEXT_MEM+32 ; Start level string = TEXT_MEM+40 ;for disphl .org START_ADDR .db "Diamonds v1.3 (beta)",0 ;------------ Beginning of ASM code ------------ ;------------ Main Menu ------------ ld a,$01 ld (startlev),a menu: call settop ld hl,$1714 ld (CURSOR_X),hl ld hl,opt1 ROM_CALL(D_ZM_STR) ld hl,$1E14 ld (CURSOR_X),hl ld hl,opt2 ROM_CALL(D_ZM_STR) ld hl,$2514 ld (CURSOR_X),hl ld hl,opt3 ROM_CALL(D_ZM_STR) menulp: call GET_KEY cp 54 ;2nd Key jp z,strtgm cp 48 ;alpha key jr z,sslev cp 56 ;delete key jr nz,menulp ret ;---------- Setup the top of the screen ---------- settop: ROM_CALL(CLEARLCD) ld hl,512 ld (CURSOR_POS),hl ld hl,name ROM_CALL(D_ZT_STR) ld hl,$0901 ld (CURSOR_X),hl ld hl,abt ROM_CALL(D_ZM_STR) ld hl,$3801 ld (CURSOR_X),hl ld hl,hscr ROM_CALL(D_ZM_STR) ld hl,56*256+40 ld (CURSOR_X),hl ld hl,(HI_SCORE) call disphl ret ;---------- Set Start Level ---------- sslev: call settop ld a,(startlev) ld (ta),a ld hl,$1714 ld (CURSOR_X),hl ld hl,sls ROM_CALL(D_ZM_STR) ld hl,$1E14 ld (CURSOR_X),hl ld hl,phlp1 ROM_CALL(D_ZM_STR) ld hl,$2514 ld (CURSOR_X),hl ld hl,phlp2 ROM_CALL(D_ZM_STR) ld hl,$2C14 ld (CURSOR_X),hl ld hl,phlp3 ROM_CALL(D_ZM_STR) sllp: ld a,(ta) sub 10 jr nc,nopei ld hl,$1730 ;was 1730 ld (CURSOR_X),hl ld hl,blank ROM_CALL(D_ZM_STR) nopei: ld hl,$1730-4 ld (CURSOR_X),hl ;ld a,$2A ;ld (CURSOR_X),a ld a,(ta) LD H,0 LD L,A call disphl ;display value in a at current position call GET_KEY cp 54 ;2nd key, set level jr z,ssl cp $04 ;up arrow, inc level jr z,adslv cp $01 ;down arrow, dec level jr z,sbslv cp 56 ;delete key, exit to main menu jp z,menu jr sllp sbslv: ld a,(ta) dec a jr nz,adslvc ld a,27 jr adslvc adslv: ld a,(ta) inc a cp 28 jr nz,adslvc ld a,$01 adslvc: ld (ta),a jr sllp ssl: ld a,(ta) ld (startlev),a jp menu ;------------ Set up the game ------------ strtgm: ld a,(startlev) ld (lev),a ld a,$05 ld (lvs),a ld hl,$0000 ld (score),hl slev: ld hl,level1-$002C ld a,(lev) ld b,a ld de,$002C lslp: add hl,de djnz lslp ld a,$00 ld (cblk),a ld de,level ; decompress/load a level ld b,$29 lllp: ld a,(hl) and %11110000 rra rra rra rra ld (de),a inc de ld a,(hl) and %00001111 ld (de),a inc de inc hl djnz lllp dec hl ld bc,$0004 ld de,level+$0050 ldir ld hl,level+$0052 ld a,(hl) ld (blks),a inc hl ld a,(hl) ld (lblks),a ld a,$28 ld (tickc),a ld hl,$003C ld (tick),hl start: call clrgbuf ROM_CALL(CLEARLCD) call drwlev dlp6: ld hl,$1C53 ld (CURSOR_X),hl ld hl,scr ROM_CALL(D_ZM_STR) ld hl,$0E53 ld (CURSOR_X),hl ld hl,levl ROM_CALL(D_ZM_STR) ld hl,$0053 ld (CURSOR_X),hl ld hl,tcks ROM_CALL(D_ZM_STR) ld hl,$2A5A ld (CURSOR_X),hl ld a,(lvs) LD H,0 LD L,A call disphl ;display value in a at current position ld hl,$1455 ld (CURSOR_X),hl ld a,(lev) LD H,0 LD L,A call disphl ld a,$05 ld (ssz),a ;ld hl,$2B52 ;ld (xc),hl ;ld hl,lives ;ld (loc),hl call dispsc ;call sprite call sbtck ld a,$00 ld (ovrflag),a ld (winflag),a ld a,(cblk) cp $06 jr z,sblks ld a,$01 ld (cblk),a sblks: call update ld hl,level+$0050 ld a,(hl) ld (xc),a inc hl ld a,(hl) ld (yc),a ld a,$04 ld (ssz),a ld hl,ball ld (loc),hl call sprite ld a,$00 ld (dir),a ;------------ MAIN GAME LOOP ------------ main: ROM_CALL(DISP_GRAPH) ld a,(tickc) dec a call z,sbtck ld (tickc),a ld a,(ovrflag) cp $07 jr z,exit ld a,(winflag) cp $01 jr z,won call mvball ld a,0ffh out (1),a ld a,0fdh out (1),a in a,(1) cp 191 jp z,gmovr ld a,0ffh out (1),a ld a,0feh out (1),a in a,(1) cp 251 jp z,mright cp 253 jp z,mleft jr main ;cp $02 ;left arrow key ;jp z,mleft ;cp $03 ;right arrow key ;jp z,mright ;cp 55 ;mode key ;jp z,pause ;cp 56 ;delete key, to exit ;jr nz,main exit: call clrgbuf ROM_CALL(CLEARLCD) ld a,(lvs) dec a jr z,gmovr ld (lvs),a jp start gmovr: ROM_CALL(CLEARLCD) ld hl,770 ld (CURSOR_POS),hl ld hl,losser ROM_CALL(D_ZT_STR) call shwscr call tsths call wkey jp menu won: ld a,(tick) cp $00 jr z,nobon ld b,a bonus: ld hl,(score) inc hl ld (score),hl push bc call sbtck call dispsc ROM_CALL(DISP_GRAPH) pop bc djnz bonus nobon: call clrgbuf ROM_CALL(CLEARLCD) ld a,(lev) inc a ld (lev),a cp 28 jp nz,slev ld hl,1026 ld (CURSOR_POS),hl ld hl,winner ROM_CALL(D_ZT_STR) call shwscr call tsths call wkey jp menu tsths: ; test for a high score ld hl,(score) ;current score ld de,(HI_SCORE) ;high score ld bc,HI_SCORE ;it is just needed call CP_HL_DE ret c ret z newhs: ; set current score to the high score ld hl,(score) ld (HI_SCORE),hl ld hl,261 ld (CURSOR_POS),hl ld hl,dnhs ROM_CALL(D_ZT_STR) ;call wkey ret shwscr: ; show the score (game over version) ld hl,515 ld (CURSOR_POS),hl ld hl,dscr ROM_CALL(D_ZT_STR) ld hl,(score) ROM_CALL(D_HL_DECI) ret ;------------ Pause ------------ pause: call wkey pausex: jp main ;------------ Subtract number of ticks ------------ sbtck: ld a,(tick) cp $00 jr z,sbts dec a ld (tick),a sbts: ld hl,$065B ld (CURSOR_X),hl ld hl,blank ROM_CALL(D_ZM_STR) ld a,$55 ld (CURSOR_X),a ld a,(tick) LD H,0 LD L,A call disphl ld a,$28 ret ;------------ Move the ball left ------------ mleft: ld a,(xc) cp $01 jr z,mls call mball ld a,(xc) dec a ld (xc),a call tstblk cp $00 jr z,mlc ld a,(xc) inc a ld (xc),a mlc: call mball mls: jp main ;------------ Move the ball right ------------ mright: ld a,(xc) cp 77 jr z,mrs call mball ld a,(xc) inc a ld (xc),a call tstblk cp $00 jr z,mrc ld a,(xc) dec a ld (xc),a mrc: call mball mrs: jp main ;------------ Update on-screen status ------------ update: call pshc ld a,$06 ld (ssz),a ld hl,50*256+84 ;was ld hl,$3645 ld (xc),hl ld hl,blocks-$000C ld a,(cblk) ld b,a ld de,$000C udl1: add hl,de djnz udl1 ld (loc),hl call sprite ld a,92 ld (xc),a ld hl,(loc) ld bc,$06 add hl,bc ld (loc),hl call sprite call popc ret ;------------ Check which block the ball is at ------------ ;------------ and do whatever is necessary ------------ tstblk: ld hl,$0000 ld (tmp),hl ld a,(xc) ld d,a ld e,$0A call div ld a,d ld (xc2),a ld (tmp),a ld a,(yc) ld d,a ld e,$06 call div ld a,d ld (yc2),a cp $00 jr z,tbs1 ld b,d tblp1: push bc ld bc,$08 add hl,bc pop bc djnz tblp1 tbs1: ld bc,(tmp) add hl,bc ld bc,level add hl,bc ld a,(hl) tbs2: ld (ovrflag),a cp $03 jp z,chg2 cp $05 jp z,chg4 cp $09 jp z,chg8 push af ld b,a ld a,(cblk) cp b jp nz,tbx ;------------ Eliminate a Block ------------ call pshc ld a,$00 ld (hl),a ld a,(xc2) cp $00 jr z,els1 ld b,a ell1: add a,$09 djnz ell1 els1: inc a ld (xc),a ld a,(yc2) cp $00 jr z,els2 ld b,a ell2: add a,$05 djnz ell2 els2: inc a inc a ld (yc),a ld a,$06 ld (ssz),a ld hl,blocks ld a,(cblk) dec a jr z,els3 ld b,a ld de,$000C ell3: add hl,de djnz ell3 els3: ld (loc),hl push hl call sprite pop hl ld de,$0006 add hl,de ld (loc),hl ld a,(xc) add a,$0008 ld (xc),a call sprite call popc ld de,(score) inc de ld (score),de call dispsc ld a,(blks) cp $00 jr z,sb1 dec a call z,chg6 ld (blks),a jr tbx sb1: ld a,(lblks) dec a ld (lblks),a jr nz,tbx ld a,$01 ld (winflag),a tbx: pop af tbxx: ret chg2: ; set the block type to 2 push af ld a,(cblk) cp $06 jr z,c2x call update ld a,2 ld (cblk),a call update c2x: pop af jr tbxx chg4: ; set the block type to 4 push af ld a,(cblk) cp 6 jr z,c4x call update ld a,4 ld (cblk),a call update c4x: pop af jr tbxx chg8: ; set the block type to 8 push af ld a,(cblk) cp 6 jr z,c8x call update ld a,8 ld (cblk),a call update c8x: pop af jr tbxx chg6: ; set the block type to 6 push af call update ld a,$06 ld (cblk),a call update pop af ret ;----------- Save/Recall xc and yc ------------ pshc: ; save xc in ta and yc in tb ld a,(xc) ld (ta),a ld a,(yc) ld (tb),a ret popc: ; return ta to xc and tb to yc ld a,(ta) ld (xc),a ld a,(tb) ld (yc),a ret ;------------ Divide D by E ------------ div: ; divide d by e and return d=answer e=remainder (d mod e) ld a,d ld c,0 dv1: ld b,e inc a dv2: cp b jr z,dv3 djnz dv2 dec a sub e inc c jr dv1 dv3: ld d,c ld e,a dec e ret ;------------ Turn on/off the ball ------------ mball: ld a,$04 ld (ssz),a ld hl,ball ld (loc),hl call sprite ret ;------------ Move the ball vertically ------------ mvball: call mball ld a,(yc) cp $02 jr nz,mn2 ld a,$00 ld (dir),a mn2: ld a,(yc) cp 57 jr nz,mn57 ld a,$01 ld (dir),a jr mup mn57: ld a,(dir) cp $00 jr nz,mup ld a,(yc) inc a ld (yc),a jr cmx mup: ld a,(yc) dec a ld (yc),a cmx: call tstblk cp $00 jr z,cmxx ld a,(dir) inc a cp $02 jr nz,cmxc ld a,$00 cmxc: ld (dir),a cmxx: call mball ret ;------------ Display the Score ------------ dispsc: ld hl,6*258+85 ld (CURSOR_X),hl ld hl,(score) call disphl ret ;------------ Draw the level (on/off) ------------ drwlev: ld a,$06 ld (ssz),a ld hl,513 ld (xc),hl ld hl,level ld (mloc),hl ld b,$0A dlp1: push bc ld b,$08 dlp2: push bc ld hl,(mloc) ld a,(hl) cp $00 jr z,dskp ld hl,blocks ld (loc),hl cp $01 jr z,dcn dlp3: ld bc,12 add hl,bc dec a cp $01 jr nz,dlp3 ld (loc),hl dcn: call sprite ld hl,(loc) ld bc,$0006 add hl,bc ld (loc),hl ld a,(xc) add a,$08 ld (xc),a call sprite ld a,(xc) sub $08 ld (xc),a dskp: ld a,(xc) add a,10 ld (xc),a ld hl,(mloc) inc hl ld (mloc),hl pop bc djnz dlp2 ld a,(yc) add a,$06 ld (yc),a ld a,$01 ld (xc),a pop bc djnz dlp1 ret ; This sprite routine was origionally by Movax. ; input: ssz = height of the sprite ; loc = location of the sprite in ram ; yc = y coordinate of the sprite ; xc = x coordinate of the sprite ; output: puts a sprite on the graph buffer sprite: ld a,(yc) ld l,a ld e,a ld h,$00 ld d,h add hl,de add hl,de add hl,hl add hl,hl ld a,(xc) ld e,a srl e srl e srl e add hl,de ld de,$88B8 add hl,de ld b,$07 and b jr z,align ; shift sprite if necessary ld ix,(loc) ld d,a ld a,(ssz) ld e,a snal1: ld b,(ix+$00) ld c,$00 push de snal2: srl b rr c dec d jr nz,snal2 pop de ld a,b xor (hl) ld (hl),a inc hl ld a,c xor (hl) ld (hl),a ld bc,$000B add hl,bc inc ix dec e jr nz,snal1 jp sprtx align: ld de,(loc) ld a,(ssz) ld b,a salp: ld a,(de) xor (hl) ld (hl),a inc de push bc ld bc,$000C add hl,bc pop bc djnz salp sprtx: ret disphl: push de push hl ld de,string+5 xor a ld (de),a Repeat: call UNPACK_HL add a,'0' dec de ld (de),a ld a,h or l jr nz,Repeat ex de,hl ROM_CALL(D_ZM_STR) pop hl pop de ret clrgbuf: ld hl,$88B8 ld de,$88B9 ld bc,$2FF ld (hl),0 ldir ret ;------------ Wait for a key press ------------ ; I use this method instead of GetKey to prevent ; apd which would mess up all the variables. wkey: call GET_KEY cp 56 jp z,gmovr cp $09 ret z jr wkey ;------------ Sprites ------------ ball: .db 01100000b .db 11110000b .db 11110000b .db 01100000b blocks: ; each block is 12 bytes block1: .db 01111111b ; width=10 .db 10000000b ; height=6 .db 10000000b ; clear .db 10000000b .db 10000000b .db 01111111b blk1b: .db 10000000b .db 01000000b .db 01000000b .db 01000000b .db 01000000b .db 10000000b block2: .db 01111111b ; spotted .db 11010101b .db 10101010b .db 11010101b .db 10101010b .db 01111111b .db 10000000b .db 01000000b .db 11000000b .db 01000000b .db 11000000b .db 10000000b block3: .db 01111111b ; change to spotted .db 11010111b .db 10101111b .db 11010111b .db 10101111b .db 01111111b .db 10000000b .db 11000000b .db 11000000b .db 11000000b .db 11000000b .db 10000000b block4: .db 01111111b ; bordered .db 10000000b .db 10111111b .db 10111111b .db 10000000b .db 01111111b .db 10000000b .db 01000000b .db 01000000b .db 01000000b .db 01000000b .db 10000000b block5: .db 01111111b ; change to bordered .db 10000111b .db 10110111b .db 10110111b .db 10000111b .db 01111111b .db 10000000b .db 11000000b .db 11000000b .db 11000000b .db 11000000b .db 10000000b block6: .db 01111111b ; last (thick border) .db 11111111b .db 11000000b .db 11000000b .db 11111111b .db 01111111b .db 10000000b .db 11000000b .db 11000000b .db 11000000b .db 11000000b .db 10000000b block7: .db 01111111b ; killer .db 11100111b .db 10000000b .db 10000000b .db 11100111b .db 01111111b .db 10000000b .db 11000000b .db 01000000b .db 01000000b .db 11000000b .db 10000000b block8: .db 01111111b ; spotted 2 .db 11100110b .db 10011001b .db 11100110b .db 10011001b .db 01111111b .db 10000000b .db 01000000b .db 11000000b .db 01000000b .db 11000000b .db 10000000b block9: .db 01111111b ; change to spotted 2 .db 11100111b .db 10011111b .db 11100111b .db 10011111b .db 01111111b .db 10000000b .db 11000000b .db 11000000b .db 11000000b .db 11000000b .db 10000000b blockA: .db 01111111b ; blocker .db 10111101b .db 11110111b .db 11011111b .db 11111011b .db 01111111b .db 10000000b .db 11000000b .db 11000000b .db 01000000b .db 11000000b .db 10000000b lives: .db 00101000b ; heart (for lives) .db 01111100b .db 01111100b .db 00111000b .db 00010000b ;------------ Dialog ------------ name: .db "Diamonds v1.3",0 opt1: .db "2nd - Start Game",0 opt2: .db "ALPHA - Set Level",0 opt3: .db "DEL - Exit",0 hscr: .db "High Score: ",0 abt: .db "by Joe W./Ilya W.",0 sls: .db "Level:",0 phlp1: .db "UP/DOWN - Select",0 phlp2: .db "2nd - Set",0 phlp3: .db "DEL - Cancel",0 winner: .db "You Won!",0 losser: .db "Game Over",0 dscr: .db "Score:",0 dnhs: .db "New High Score",0 scr: .db "Scr",0 levl: .db "Lev",0 tcks: .db "Bon",0 blank: .db " ",0 HI_SCORE: .db $00, $00 #include "levs.asm" .end END