#INCLUDE "Header.h" .db "Avalanche v1.2",0 temp EQU TEXT_MEM ;temp variable + death check y1 EQU TEXT_MEM+1 ;icicles y-coordinats y2 EQU TEXT_MEM+2 y3 EQU TEXT_MEM+3 y4 EQU TEXT_MEM+4 y5 EQU TEXT_MEM+5 y6 EQU TEXT_MEM+6 y7 EQU TEXT_MEM+7 y8 EQU TEXT_MEM+8 y9 EQU TEXT_MEM+9 y10 EQU TEXT_MEM+10 y11 EQU TEXT_MEM+11 y12 EQU TEXT_MEM+12 x EQU TEXT_MEM+13 ;icicle's x-coordinate you EQU TEXT_MEM+14 ;your x-coordinate score EQU TEXT_MEM+16 ;score -duh! COUNT EQU TEXT_MEM+28 ;used in INPUT string EQU TEXT_MEM+32 ;used in DM_HL_DECI noLet EQU TEXT_MEM+43 ;max number of letters in INPUT speed EQU TEXT_MEM+44 ;the speed ld a,5 ;set speed to 5 which is normal ld (speed),a call SPEED ;My speed routine call DTL ;display title ld bc,16*256+19 ;text position yEQU16 x=19 ld hl,nat ;get string to disp call DMX ;display menu string ld bc,23*256+21 ;text position y=23 x=21 ld hl,ilya ;load author string call DMX ;display menu string ld bc,58*256+10 ;text position y=58 x=10 ld hl,hitxt ;load string call DMX ;run routine to display it ld hl,HI_SCORE ;load the high score to be displayed call PUT_SCORE ;display the score introwait: ld b,255 loop: push bc ld b,255 call delay ;delay routine pop bc call GET_KEY ;get key press cp 15 ;was clear hit? jp z,quit ;if so quit cp 54 ;was 2nd hit? jp z,start ;if so start djnz loop ;keep waiting for 2nd or clear SET 3,(IY+05) ;set to reverse text ;-------erase reverse line to left of "Press 2nd" ld bc,16*256+15 ld de,16*256+8 ld hl,0 call iline ;-----end erase line---------- ld a,(temp) ;1=norm,0=reverse inc a ;a+1->a ld (temp),a ;a->temp cp 2 ;is it at 2 (when we only want 1 or 0) jr nz,not2 xor a ;0->a ld (temp),a ;a->temp RES 3,(IY+05) ;reset to normal text not2: ld bc,0x0306 ;0xCR = 0xcolumnrow = save mem!! ld hl,secnd ;load Press 2nd text call DTX ;run routine to display normal text SET 3,(IY+05) ;reset to normal text jp introwait ;keep looping randstart: ld a,r ;get random number srl a ;shift right logically-hey, why not? and 63 ;mask out bits so it is between 0-63 ret ;return to caller start: ld hl,0 ;sets score to 0 ld (score),hl ld a,2 ;man starts two pixels in from the left ld (you),a ;load x-coord call BUFCLR ;clear Graph Buffer ld b,12 ;loop 12 times ld hl,TEXT_MEM ;get mem location randlop: push bc ;save loop# inc hl ;get next mem location push hl ;save new location call randstart ;get random# pop hl ;recall location ld (hl),a ;store rand# in the mem location pop bc ;recall counter djnz randlop ;decrement counter+check if it is at 0 xor a ;0->temp ld (temp),a icelop: ld hl,(score) ;score ->hl inc hl ;add 1 to score ld (score),hl ;hl ->score ld b,12 ;loop 12 times ld hl,TEXT_MEM ;get mem location xor a ;0->a ld (x),a ;load a to x ilop: push bc ;store counter inc hl ;get next mem location ld a,(hl) ;load value into a ld e,a ;a->e push hl ;store new mem location call drawice ;draw icicle pop hl ;recall mem location ld a,(x) ;load x-position into a add a,8 ;a+8->a ld (x),a ;store new x-position pop bc ;recall counter djnz ilop ;see if it is done, then keep looping ld a,(you) ;set man up and display sprite ld e,55 ld hl,man call SPRITE CALL ROM_CALL .DW DISP_GRAPH ld a,0ffh ;reset keyport out (1),a ;necessary code ld a,0fdh ;enable row with clear out (1),a ;necessary code in a,(1) ;get # of any key pressed->a cp 191 ;clear??? jp z,quit ;if clear quit ld a,0ffh ;reset keyport out (1),a ;necessary code ld a,0bfh ;enable row with mode out (1),a ;necessary code in a,(1) ;get # of any key pressed->a cp 191 ;check for mode call z,pause ;if mode pause ld a,0ffh ;reset keyport out (1),a ;necessary code ld a,0feh ;enable row with clear out (1),a ;necessary code in a,(1) ;get # of any key pressed->a cp 251 ;check for right jp z,right ;if right move right cp 253 ;check for left jp z,left ;if left move left lop2: ld a,(speed) ;get speed value into a ld b,a ;a->b = length of delay call delay2 ;run delay call BUFCLR ;see how easy speed is!!! ld a,(temp) ;are you dead? cp 1 ;if 1 you are! jp z,youdie ;jump to youdie ld a,(y1) cp 104 call nc,chg1 add a,2 ;sprite falls by 2 ld (y1),a ld a,(y2) cp 104 call nc,chg2 add a,3 ;sprite falls by 3 ld (y2),a ld a,(y3) cp 104 call nc,chg3 add a,4 ;sprite falls by 4 ld (y3),a ld a,(y4) cp 104 call nc,chg4 add a,3 ;sprite falls by 3 ld (y4),a ld a,(y5) cp 104 call nc,chg5 add a,2 ;sprite falls by 2 ld (y5),a ld a,(y6) cp 104 call nc,chg6 add a,3 ;sprite falls by 3 ld (y6),a ld a,(y7) cp 104 call nc,chg7 add a,4 ;sprite falls by 4 = fast! ld (y7),a ld a,(y8) cp 104 call nc,chg8 add a,3 ;sprite falls by 3 ld (y8),a ld a,(y9) cp 104 call nc,chg9 add a,2 ;sprite falls by 2 ld (y9),a ld a,(y10) cp 104 call nc,chg10 add a,3 ;sprite falls by 3 ld (y10),a ld a,(y11) cp 104 call nc,chg11 add a,2 ;sprite falls by 2 ld (y11),a ld a,(y12) cp 104 call nc,chg12 add a,3 ;sprite falls by 3 ld (y12),a jp icelop left: ld a,(you) ;get your x-coordinate or a ;see if you are already at the far left jr z,jplft ;if so jump to the right side dec a ;move left two pixels dec a ld (you),a jp lop2 jplft: ld a,88 ;set man up at the far right ld (you),a ;store new value jr left ;return right: ld a,(you) ;get your x-coordinat cp 88 ;see if you are at the far right jr z,jprt ;if so move to the far left inc a ;move right two pixels inc a ld (you),a jp lop2 jprt: xor a ;set coordinate for far left ld (you),a ;store new value jr right ; you can use "jr" instead of "jp" for little jumps chkhit: ; check to see if the icicle is at the same xposition as you ld a,(x) ; icicle x-pos +6 -> b add a,4 ;a+4 ->a ld b,a ;a->b ld a,(you) ; your x-pos ->a cp b ; IF a=>b goto di2 jp nc,di2 ld a,(x) ; icicle x-pos ->b ld b,a ;a->b ld a,(you) ; your x-pos +6 ->a add a,4 ;a+4 ->a cp b jp c,di2 ; IF a a - your dead remember ld (temp),a ;a -> temp ret ;return to caller drawice: ld a,e cp 24 jr c,ldrop cp 50 jr c,bdrop cp 98 ;if icicle is at bottom of screen jp nc,chkhit ;check to see if you are hit di2: ld a,e ld hl,icicle sub 50 ld e,a ld a,(x) call SPRITE ;erase/draw sprite ret ldrop: ld hl,drop1 ld e,0 ld a,(x) call SPRITE ret bdrop: ld hl,drop2 ld e,0 ld a,(x) call SPRITE ret chg1: xor a ;set sprite back to top of screen ld (y1),a RET chg2: xor a ld (y2),a RET chg3: xor a ld (y3),a RET chg4: xor a ld (y4),a RET chg5: xor a ld (y5),a RET chg6: xor a ld (y6),a RET chg7: xor a ld (y7),a RET chg8: xor a ld (y8),a RET chg9: xor a ld (y9),a RET chg10: xor a ld (y10),a RET chg11: xor a ld (y11),a RET chg12: xor a ld (y12),a RET youdie: call INVERTD ;make the screen flash call INVERTD call INVERTD call INVERTD RES 3,(IY+05) ;set to normal text call DTL ;display title ld bc,0x0404 ld hl,die call DTX ;display normal text ld bc,0x0206 ld hl,scii call DTX ld hl,0x0806 ld (CURSOR_POS),hl ld hl,(score) CALL ROM_CALL .dw D_HL_DECI ld hl, (score) ;final score ld de, (HI_SCORE) ;load high score ld bc, HI_SCORE ;load high score addr call CP_HL_DE ;compare score w/ hi score jr c,wlp1 ;if score is less jr z,wlp1 ;or equal return ld bc,0x0404 ld hl,dieclr call DTX ld bc,0x0102 ;load coords ;| ld hl,HISCORE_TEXT ;1,2 call DTX ;display "A new HiScore!" ld de, 0x1810 ;24,17 ld (0x8215), de CALL ROM_CALL .DW D_ZM_STR ;display " Enter Your Initials:" ld de, 0x0604 ;initials entered at 6,4 ld (0x800C), de ;load location ld hl,(score) ;score->hl ld (HI_SCORE),hl ;store high score ld hl, HI_SCORE+3 ;hl points to initials ld a, 3 ;max chars = 3 call INPUT ;input initials jp quit wlp1: call GET_KEY ;get the key press cp 09h ; check for enter jr nz,wlp1 ;if not keep looping jp quit ;goto quit pause: call DTL ;display title SET 3,(IY+05) ;set to inverse text ld bc,0x0403 ;load coordinates c=4 r=3 ld hl,ptxt ;load paused text call DTX ;display it wlp2: call GET_KEY ;get key press cp 09h ;check for enter jr nz,wlp2 ;if not keep looping RES 3,(IY+05) ;reset to normal text CALL ROM_CALL .DW CLEARLCD ;clear lcd not memory call BUFCLR ;clear graph buffer ret ;return to game delay2: push bc ;temp storage of bc ld b,255 ;255->b call delay ;run first delay pop bc ;recall bc djnz delay2 ;b-l->b, if b=0 return else do it again ret delay: push bc ;temp storage of bc pop bc ;recall bc djnz delay ;b-l->b if b=0 return else do it again ret quit: RES 3,(IY+05) ;set text back to normal CALL ROM_CALL .DW CLEARLCD ;clear screen call BUFCLR ;clear graph buffer ret ;return to Ash3.0 menu BUFCLR: LD HL, 0x88B8 ;clears the graph buffer fast! LD DE, 0x88B9 LD BC, 0x2FF ;768 bytes to copy LD (HL), 0 ;store 0->graphbuffer ldir ;do it ret ;return to caller iline: CALL ROM_CALL .dw 0x2E60-0x1A .dw 0x4025 .db 0x04 SPEED: call DTL ;display title ld bc,0x0502 ;set coords c=5 r=2 ld hl,speedtxt ;load string call DTX ;display it ld bc,25*256+12 ;set coords y=25 x=12 ld hl,spdtxt ;load string call DMX ;display menu string ld hl,25*256+7 ld (CURSOR_X),hl ld a,0xCF ;load left arrow # CALL ROM_CALL .dw M_CHARPUT ;display it ld hl,25*256+83 ld (CURSOR_X),hl ld a,0x05 ;load right arrow # CALL ROM_CALL .dw M_CHARPUT;display it ld bc,0x0306 ld hl,secnd call DTX SPDLP: ld hl,32*256+44 ld (CURSOR_X),hl ld h,0 ld a,(speed) ;load speed to l ld l,a call DM_HL_DECI ;display l in menu text call GET_KEY ;get key press cp 0x02 ;was left pressed? jr z,faster ;if so jump to faster cp 0x03 ;was right pressed? jr z,slower ;if so jump to slower cp 54 ;was 2nd pressed? jr z,spddone ;if so your done jr SPDLP ;keep looping faster: ld a,(speed) ;decrement speed or a jr z,SPDLP dec a ld (speed),a jr SPDLP slower: ;increment speed ld a,(speed) cp 9 jr z,SPDLP inc a ld (speed),a jr SPDLP spddone: ;set up right speed number ld a,(speed) ;speed ->a ld b,a ;a->b inc a ;speed +1->speed add a,b ;add speed +original value add a,b ;do it again ld (speed),a ;store new speed ret ;return to caller DTL: ;routine to display title pic call BUFCLR ;clear graph buffer CALL ROM_CALL .DW CLEARLCD ;clear lcd not memory ld hl,title ;load title ld de,0x88B8 ;de->graph mem ld bc,132 ;132 bytes to copy ldir ;do it CALL ROM_CALL .DW DISP_GRAPH ;display graph RET DTX: ;display normal text strings ld (CURSOR_POS),bc ;set position CALL ROM_CALL .DW D_ZT_STR ;display string RET ;return DMX: ;display menu text strings ld (CURSOR_X),bc ;set position CALL ROM_CALL .DW D_ZM_STR ;display string RET ;return INVERTD: ;delay the flashes ld b,36 call delay2 INVERT: ;inverts screen ld bc,768 ld hl,0x88B8 invloop: ;xor's all data in graph mem ld a,(hl) cpl ld (hl),a inc hl dec bc ld a,b or c jr nz,invloop CALL ROM_CALL .DW DISP_GRAPH RET PUT_SCORE: ;taken from SAMEGAME push de push hl ld de, 0x3A30 ;cursor pos for the score is y=58, x=48 ld (0x8215), de ;load cursor position call LD_HL_MHL ;hl=(hl) call DM_HL_DECI ;display the score ld hl,58*256+70 ;cursor pos is y=58, x=70 ld (0x8215), hl ;load cursor position pop hl ;recall hl inc hl ;assumes that the name is 2 bytes inc hl ;after the start of the score CALL ROM_CALL .DW D_ZM_STR ;display the name of the hiscoree pop de ;recall de ret ;return to caller ; Input routine - made by Jimmy Mårdell 97-03-05 ; Also taken from SAMEGAME ; Reads a sentence entered from the keyboard. Only uppercase letters ; and space are allowed. Left arrowkey = backspace. ; ; When calling, HL should point to where the string should be stored ; and A should hold the maximum length of the string. Be sure there ; are enough space (A+1) to store the nullterminated string at HL! ; (0x800C) should hold the screen position where the string starts. ; ; This input routine will also have a flashing cursor. If you don't like ; it, remove all rows where the explanation starts with a *. ; ; IMPORTANT: The input must NOT wrap to a new row! Then it will not work ; properly. The last char on a row should not be used either (if cursorcol=0 ; when calling, the maximum char length is 20). If you have a cursor, the ; two last chars should not be used (max length 19 if the screen location ; starts to the far left). ; ; The routine requires one temporary variable, noLet. ; largely indented stuff added by Adamman INPUT: ; push bc ; push de ; push hl ; ei ; set 2,(iy+12) ; * Turn cursor blinking on (interrupts must be enabled) ld (noLet),a ; Store the maximum lenght of the string ld e,0 ; E = numbers of letters written so far WaK: ; ld a,32 ; ld (0x800E),a ; * Set "character under cursor" to space push hl ; Save HL since GET_KEY destroys it's content ld a, 217 CALL ROM_CALL .dw TX_CHARPUT ld hl, 0x800D dec (hl) call GET_KEY ;get key press cp 0x02 ; 0x02 = left key jr z,BackSpace cp 0x09 ; 0x09 = enter jr z,NameDone ;if enter then your done or a jr nz,CheckLetter pop hl jr WaK CheckLetter: ld hl,Letters ld bc,26 ; 26 letters to check cpir ; Compare A with each letter until a match is found ld d,c ; Then C = the letter. Store in D pop hl ; HL -> current position in string jr nz,WaK ; If not valid keystroke, wait for new key ld a,65 ; 65 = ascii char for A add a,d ; A now holds the ascii char for the letter pressed PutLetter: ld c,a ld a,(noLet) ; A = max letters cp e ; Check if max size is reached jr z,WaK ; If so, wait for a new key ld (hl),c ; If not, store the key entered inc hl ; Point to the next byte in the string inc e ; And increase the letter counter ld a,c CALL ROM_CALL .dw TX_CHARPUT ; Show the chars pressed on the screen jr WaK ; And jump back and wait for a new key BackSpace: pop hl ; HL -> current position in string ld a,e or a ; Check if string size = 0 jr z,WaK ; If so, backspace is impossible. Check for new key. ; res 2,(iy+12) ; * Stopp cursor blinking dec e ; Decrease string size dec hl ; And string pointer push hl ;temporary storage of hl ld hl,0x800D ; HL -> x cursor position dec (hl) ; Decrease it ld a,32 ; Overwrite the last letter with a space CALL ROM_CALL .dw TX_CHARPUT ; Put the space over the chars CALL ROM_CALL .dw TX_CHARPUT ; * And over the (non) blinking cursor dec (hl) ; * Decrease the x coordinate twice dec (hl) ;decrease hl by 1 pop hl ;recall hl ; set 2,(iy+12) ; * Stopp cursor blinking jr WaK ; Wait for a key NameDone: pop hl ; HL -> current position in string ld (hl),0 ; Put a terminating zero at the end of the string ; res 2,(iy+12) ; * Stopp cursor blinking ; pop hl ; pop de ; pop bc ret ; The keycodes of the letters A-Z stored backways Letters: .db 0x1A,0x22,0x2A ;ZYX .db 0x0B,0x13,0x1B,0x23,0x2B ;WVUTS .db 0x0C,0x14,0x1C,0x24,0x2C ;RQPON .db 0x0D,0x15,0x1D,0x25,0x2D ;MLKJI .db 0x0E,0x16,0x1E,0x26,0x2E ;HGFED .db 0x1F,0x27,0x2F ;CBA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; DM_HL_DECI by Jimmy Mårdell ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DM_HL_DECI: push de push hl ld de,string+5 ;start at the end xor a ;ld a, 0 ld (de),a ;zero terminated string Repeat: call UNPACK_HL ;unpack one digit of hl to a add a,'0' ;add it with ASCII char 0 dec de ;previous byte ld (de),a ;load the char ld a,h ;is hl 0? or l ;| jr nz,Repeat ;loop ex de,hl ;exchange so hl points to string CALL ROM_CALL .DW D_ZM_STR ;display string pop hl ;recall hl pop de ;recall de ret ;return to caller SPRITE: ;xor's data to erase/draw sprite! push hl ld hl,0 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,0x88B8 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? jp z,ALIGN pop ix ; ix->sprite ld d,a ; d=how many bits to shift each line ld e,8 ; Line loop LILOP: ld b,(ix+0) ; Get sprite data ld c,0 ; Shift loop push de SHLOP: srl b rr c dec d jp nz,SHLOP pop de ld a,b ; Write line to graphbuf xor (hl) ld (hl),a inc hl ld a,c xor (hl) ld (hl),a ld bc,11 ; Calculate next line address add hl,bc inc ix ; Inc spritepointer dec e jp nz,LILOP ; Next line jp DONE1 ALIGN: ; Blit an aligned sprite to graphbuf pop de ; de->sprite ld b,8 ALOP1: ld a,(de) xor (hl) ; xor=erase/blit ld (hl),a inc de push bc ld bc,12 add hl,bc pop bc djnz ALOP1 DONE1: ret title: .db 0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,7,0,0,0,0,96,0,0,0,112,0,0,7,0,0 .db 0,0,224,0,0,0,112,0,0,7,0,0,0,0,224,0,0,0,120,241,195,135,7,15,240,126,255,15,192,0,252 .db 113,199,199,15,207,249,254,255,159,224,1,220,115,193,231,3,206,121,196,243,156,240,3,220,63,31,231,63,204,59,128 .db 227,159,240,3,254,63,158,231,61,206,59,128,243,191,240,3,191,30,57,231,115,206,57,204,243,191,0,7,7,142,63 .db 247,191,238,56,254,115,159,224,7,7,140,15,118,30,110,56,56,67,131,192,0,0,0,0,0,0,0,0,0,0,0 secnd: .db "Press 2nd",0 nat: .db "By: Powell/Maddox",0 ilya: .db "and Ilya Winham",0 die: .db "You Died",0 scii: .db "Score: ",0 ptxt: .db "*Paused*",0 dieclr: .db " ",0 hitxt: .db "Hiscore:",0 speedtxt: .db "SPEED",0 spdtxt: .db "FASTER (0-9) SLOWER",0 HISCORE_TEXT: .db "A new HiScore!", 0 ;2,3 .db " Enter Your Initials:", 0;24,17 HI_SCORE: .db 0x00, 0x00 ;first two are the actual score (58,48) .db " IPW", 0 ;the next three are for the name (58,76) icicle: .db 01111100b .db 01100100b .db 01000100b .db 00101000b .db 00101000b .db 00111000b .db 00010000b .db 00010000b drop1: .db 01111100b .db 00111000b .db 00000000b .db 00000000b .db 00000000b .db 00000000b .db 00000000b .db 00000000b drop2: .db 11111110b .db 11000110b .db 01000100b .db 00111000b .db 00000000b .db 00000000b .db 00000000b .db 00000000b man: .db 01110000b .db 10101000b .db 01110000b .db 00100000b .db 11111000b .db 00100000b .db 01110000b .db 11011000b