#INCLUDE ti-85.h ; Information about the current cave curCave = $80DF ; Current cave difLevel = $80E0 ; Difficulty level mwatime = $80E1 ; Magic wall milling time & max amoeba time at 3% growth dmscore1 = $80E2 ; Initial Jewel value dmscore2 = $80E3 ; Extra Jewel value randseed1 = $80E4 ; Randomiser seed 1 randseed2 = $80E5 ; Randomiser seed 2 dmneeded = $80E6 ; Jewels needed timeLeft = $80E7 ; Time left on current level randobj = $80E8 ; Random objects (4 BYTE) probobj = $80EC ; Probability of random objects (4 BYTE) animcnt1 = $80F0 ; Animation counter 1 (0-255) animcnt2 = $80F1 ; Animation counter 2 (0-2) flashcnt = $80F2 ; Flash inbox counter. When reach 0, Rockford appears dmtaken = $80F3 ; Jewels taken rockford = $80F4 ; Rockfords position (x,y) (WORD) flags = $80F6 ; 0-RF found, 1-RF moved, 2-updated score, 3-screen flash ; 4-Amoeba can grow, 5-Remove Extra Life text score = $80F7 ; Score (WORD) lives = $80F9 ; Lives left finished = $80FA ; 0-Diamons left to take, 1-Cave done timecnt = $80FB ; Time counter (0-4) amTurn = $80FC ; Next scan, amoeba will become... (0 - no change) nrAmoeba = $80FD ; Number of amoebas found amTime = $80FE ; Amobea time at 3% growth mwactive = $80FF ; Magic Wall Active nextEL = $8100 ; Next extra life (WORD) ELTimer = $8102 ; Extra life timer RFMove = $8103 ; 0-Blinking, 1-Tapping, 3-Moved, 4-Facing right cave = $8641 ; The cave data (960 BYTE) cavestart = $8691 ; Here the actually cave starts (there are 2 empty rows) caveend = $8A01 ; And here the cave ends ; Temporary storage xy = $8A6B ; (WORD) tmp = $8A6D ; string = $8A6E ; Temporary string storage (8 BYTES) keystat = $8A76 ; Keys pressed since last time .org 0 .db "BoulderDash 1.0 ",0 StartMenu: CALL_(ChooseLevel) cp $37 ret z ld hl,0 ld (score),hl ld a,3 ld (lives),a ld hl,500 ld (nextEL),hl JUMP_(StartLevel) GameOver: call GET_KEY ld hl,GameOverText ld de,(PROGRAM_ADDR) add hl,de ld de,$0403 ld ($800C),de set 3,(iy+5) ROM_CALL(D_ZT_STR) res 3,(iy+5) ld bc,2000 WaitKey3: call GET_KEY or a jr nz,CheckHiscore halt dec bc ld a,b or c jr nz,WaitKey3 CheckHiscore: ld hl,hiscore ld de,(PROGRAM_ADDR) add hl,de push hl call LD_HL_MHL ld de,(score) CALL_(CCP_HL_DE) pop hl CALL_C(NewHiscore) jr StartMenu RestartLevel: ld a,(curCave) cp 16 jr nc,IMOver ld hl,lives dec (hl) ld a,(hl) or a JUMP_Z(GameOver) jr StartLevel IMOver: ld a,(curCave) sub 15 add a,a add a,a ld (curCave),a cp 16 jr nz,StartLevel xor a ld (curCave),a ld hl,difLevel ld a,(hl) cp 4 jr z,StartLevel inc (hl) StartLevel: ld a,r srl a ld (randseed2),a ROM_CALL(CLEARLCD) ld hl,0 ld ($800C),hl ld hl,(PROGRAM_ADDR) set 3,(iy+5) ROM_CALL(D_ZT_STR) res 3,(iy+5) ld a,(curCave) cp 16 jr nc,ShowIM ld de,$0602 ld ($800C),de ld hl,InfoText2 ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZT_STR) ld hl,string push hl ld a,(curCave) add a,65 ld (hl),a inc hl ld (hl),47 inc hl ld a,(difLevel) add a,49 ld (hl),a inc hl ld (hl),0 pop hl ROM_CALL(D_ZT_STR) ld hl,CaveDesc ld de,(PROGRAM_ADDR) add hl,de ld a,(curCave) or a jr z,DescFound ld b,a SearchDesc: ld a,(hl) ld d,0 ld e,a add hl,de inc hl djnz SearchDesc DescFound: ld a,21 sub (hl) srl a ld d,a ld e,4 ld ($800C),de ROM_CALL(D_LT_STR) jr ShowLives ShowIM: ld hl,IMText ld de,(PROGRAM_ADDR) add hl,de ld de,$0303 ld ($800C),de ROM_CALL(D_ZT_STR) add a,33 ROM_CALL(TX_CHARPUT) ShowLives: ld hl,InfoText3 ld de,(PROGRAM_ADDR) add hl,de ld de,$0406 ld ($800C),de ROM_CALL(D_ZT_STR) ld a,(lives) add a,48 ROM_CALL(TX_CHARPUT) call GET_KEY WaitKey: call GET_KEY or a jr z,WaitKey ROM_CALL(CLEARLCD) ld a,10 ld (flashcnt),a CALL_(InitLevel) call GET_KEY ld b,60 RemoveAgain: push bc ld hl,(rockford) CALL_(ShowScreen) ld hl,cavestart RandAgain: CALL_(NextRandom) ld a,(randseed1) and %00111111 cp 40 jr nc,RandAgain ld d,0 ld e,a push hl add hl,de res 7,(hl) pop hl ld de,40 add hl,de ld de,caveend ld a,(KEY_0) or a jr nz,SkipRemove call CP_HL_DE jr nz,RandAgain pop bc djnz RemoveAgain push bc SkipRemove: pop bc call GET_KEY ld hl,cavestart ld de,caveend RemoveAll: res 7,(hl) inc hl call CP_HL_DE jr nz,RemoveAll CALL_(ShowInfoText) MainLoop: xor a ld (LAST_KEY),a ld (flags),a ld (keystat),a CALL_(UpdateCounters) di CALL_(ScanFrame) ei ld hl,Flags bit 4,(hl) jr nz,CheckBigAm ld a,$15 ld (amTurn),a jr Show CheckBigAm: ld a,(nrAmoeba) cp 200 jr c,Show ld a,$11 ld (amTurn),a Show: ld hl,(rockford) CALL_(ShowScreen) ld hl,flags bit 2,(hl) CALL_NZ(UpdateInfo) bit 3,(hl) CALL_NZ(FlashScreen) ld a,(timeLeft) or a JUMP_Z(TimeOut) ld a,(LAST_KEY) cp K_EXIT jr z,QuitGame cp K_MORE JUMP_Z(RestartLevel) cp K_ALPHA CALL_Z(Pause) ld a,(finished) bit 1,a jr nz,LevelDone bit 2,a jr z,MainLoop QuitGame: call GET_KEY JUMP_(GameOver) Pause: ROM_CALL(CLEARLCD) call GET_KEY ld hl,$0803 ld ($800C),hl ld hl,PauseText ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZT_STR) ld de,$2C17 ld ($8333),de ROM_CALL(D_ZM_STR) WaitKey5: call GET_KEY or a jr z,WaitKey5 ROM_CALL(CLEARLCD) ld hl,(Rockford) CALL_(ShowScreen) CALL_(ShowInfoText) ret ShowInfoText: ld b,4 ld hl,InfoText ld de,(PROGRAM_ADDR) add hl,de WriteNextRow: push hl call LD_HL_MHL ld ($8333),hl pop hl inc hl inc hl ROM_CALL(D_ZM_STR) djnz WriteNextRow CALL_(UpdateInfo) ret LevelDone: ld hl,timeLeft ld a,(hl) or a jr z,EnterNextCave dec (hl) ld hl,(score) inc hl ld (score),hl bit 1,l CALL_Z(UpdateCounters) ld hl,(rockford) CALL_(ShowScreen) CALL_(UpdateInfo) halt halt jr LevelDone EnterNextCave: ld hl,curCave ld a,(hl) cp 16 jr c,NoIM ld hl,Lives inc (hl) ld hl,ELText2 ld de,(PROGRAM_ADDR) add hl,de ld de,$0303 ld ($800C),de set 3,(iy+5) ROM_CALL(D_ZT_STR) res 3,(iy+5) call GET_KEY ld bc,1000 WaitKey2: call GET_KEY or a JUMP_NZ(IMOver) halt dec bc ld a,b or c jr nz,WaitKey2 JUMP_(IMOver) NoIM: inc (hl) ld a,(hl) and $03 jr z,InterMission JUMP_(StartLevel) InterMission: ld a,(hl) srl a srl a add a,15 ld (curCave),a JUMP_(StartLevel) TimeOut: call GET_KEY ld a,(iy+5) xor 8 ld (iy+5),a ld hl,TimeOutText ld de,(PROGRAM_ADDR) add hl,de ld de,$0403 ld ($800C),de ROM_CALL(D_ZT_STR) ld b,32 TOWait: halt djnz TOWait call GET_KEY or a jr z,TimeOut res 3,(iy+5) JUMP_(RestartLevel) ; ---=== UPDATES THE ANIMATION COUNTERS AND THE FLASH COUNTER ===--- UpdateCounters: ld hl,flashcnt ld a,(hl) or a jr z,UpdateELTimer dec (hl) UpdateELTimer: ld hl,ELTimer ld a,(hl) or a jr z,UpdateAnimCnt dec (hl) jr nz,UpdateAnimCnt ld hl,Flags set 2,(hl) set 5,(hl) UpdateAnimCnt: ld hl,animcnt1 inc (hl) ld hl,animcnt2 inc (hl) ld a,(hl) srl a cp $03 jr nz,UpdateTimeCnt ld (hl),0 UpdateTimeCnt: ld hl,finished bit 1,(hl) ret nz ld hl,timecnt inc (hl) ld a,(hl) cp $0A ret nz ld a,r srl a ld (RandSeed2),a ld (hl),0 ld hl,TimeLeft dec (hl) ld hl,Flags set 2,(hl) ld hl,amTime ld a,(hl) or a jr z,UpdateMW dec (hl) UpdateMW: ld a,(mwactive) or a ret z ld hl,mwatime dec (hl) ld a,(hl) or a ret nz ld (mwactive),a ret ; ---=== COMPARE HL,DE (CHANGES CARRY FLAG) ===--- CCP_HL_DE: ld a,h cp d ret c ret nz ld a,l cp e ret ; ---=== UPDATES THE NUMBERS TO THE RIGHT ===--- UpdateInfo: push hl ld hl,(score) ld de,(nextEL) CALL_(CCP_HL_DE) jr c,NoExtraLife ld hl,500 add hl,de ld (nextEL),hl ld hl,lives inc (hl) ld a,20 ld (ELTimer),a NoExtraLife: ld hl,$0378 ld ($8333),hl ld a,(curCave) cp 16 jr nc,ShowIMNo add a,65 ROM_CALL(M_CHARPUT) jr ShowDM ShowIMNo: push af ld a,73 ROM_CALL(M_CHARPUT) pop af add a,33 ROM_CALL(M_CHARPUT) ShowDM: ld a,(dmneeded) ld h,0 ld l,a ld de,string+7 CALL_(UnpDigits) dec de ld a,47 ld (de),a ld a,(dmtaken) ld h,0 ld l,a ld b,3 CALL_(Unpack) ld hl,$1563 ld ($8333),hl ex de,hl ROM_CALL(D_ZM_STR) ld a,(ELTimer) or a jr nz,ShowExtraText set 3,(iy+5) ld hl,Flags bit 5,(hl) CALL_NZ(ShowET) res 3,(iy+5) ld hl,$2067 ld ($8333),hl ld hl,ScoreText ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZM_STR) ld de,string+7 ld hl,(score) ld b,5 CALL_(UnpDigits2) ld hl,$2767 ld ($8333),hl ex de,hl ROM_CALL(D_ZM_STR) jr ShowTimeLeft ShowExtraText: CALL_(ShowET) ShowTimeLeft: ld a,(timeLeft) ld h,0 ld l,a ld de,string+7 CALL_(UnpDigits) ld hl,$396B ld ($8333),hl ex de,hl ROM_CALL(D_ZM_STR) pop hl ret ShowET: ld hl,$2067 ld ($8333),hl ld hl,ExtraLifeText ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZM_STR) ld de,$2767 ld ($8333),de ROM_CALL(D_ZM_STR) ret ; ---=== UNPACKS hl INTO de ===--- UnpDigits: ld b,3 UnpDigits2: xor a ld (de),a Unpack: call UNPACK_HL add a,48 dec de ld (de),a djnz Unpack ret ; ---=== CHECKS IF ANY KEYS ARE PRESSED ===--- CheckKeys: push hl ld hl,KeyStat ld a,$3E out (1),a in a,(1) or (hl) ld (hl),a pop hl ret ; ---=== SCANS THIS FRAME ===--- ScanFrame: xor a ld (nrAmoeba),a push hl ld hl,CaveStart NextTile: ld a,(hl) ; Loads a with the tile ($00-$1F, 6 bits) cp $07 JUMP_Z(IncTile2) res 0,a or a jr z,IncTile2 ; Check if dirt or space, then skip all push hl push hl or a ld de,41 sbc hl,de push hl pop ix ; Chg ix to hl-41 so it's easy to check in each dir pop hl ld a,(hl) ; Reloads a and %11111001 ; Check unscanned boulders and jewels cp $10 JUMP_Z(F_Falling) ld a,(hl) cp $3A ; Check if unscanned amoeba JUMP_Z(Amoeba) cp $04 ; Check if Pre Outbox jr nz,CheckFinExp ld a,(finished) bit 0,a ; Check if enough jewels been collected jr z,IncTile ld a,$05 ld (hl),a ; If so, change the pre outbox to flashing outbox jr IncTile CheckFinExp: cp $1F ; Check explosion to space stage 4 jr nz,CheckFinExp2 ld (hl),$00 jr IncTile CheckFinExp2: cp $24 ; Check explosion to jewel stage 4 jr nz,CheckRockford ld (hl),$15 jr IncTile CheckRockford: cp $38 ; Check if Rockford CALL_Z(MoveRockford) ld a,(flashcnt) or a ; Check if Rockford haven't been borned jr nz,Chk1 ld a,(hl) ; If so, check if there are any Pre Rockford stages cp $25 jr c,Chk1 cp $29 jr nc,Chk1 inc (hl) ; If so, go to next stage cp $28 jr nz,Chk1 ; Check if Rockford have been born ld (hl),$38 ; If so then change to Rockford Chk1: ld a,(hl) and %1111100 cp $08 ; Check if unscanned firefly CALL_Z(FireFly) ld a,(hl) and %1111100 cp $30 ; Check if unscanned butterfly CALL_Z(ButterFly) ld a,(hl) ; Check for explosions, middle stages cp $1B jr c,IncTile cp $24 jr nc,IncTile IncExplosion: inc (hl) ; Go to next explosion step jr IncTile IncTile: pop hl IncTile2: inc hl ld de,CaveEnd call CP_HL_DE ; Check if end of cave is reached JUMP_NZ(NextTile) ld hl,CaveStart ; Now remove all scanned frames NextTile2: ld a,(hl) and %11111000 cp $10 jr nz,NoFallObj res 0,(hl) NoFallObj: ld a,(hl) cp $39 jr nz,NotRF res 0,(hl) NotRF: cp $3B jr z,ScanAm cp $1B jr z,ExpStage0 cp $20 jr z,ExpStage0 and %11111100 cp $0C jr z,Res2 cp $34 jr nz,SFDone Res2: res 2,(hl) SFDone: inc hl ld de,CaveEnd call CP_HL_DE jr nz,NextTile2 pop hl ret ExpStage0: inc (hl) jr SFDone ScanAm: dec (hl) jr SFDone F_Falling: ; Found a boulder or a jewel (stationary or falling) ld b,(hl) ld de,40 add hl,de ld a,(hl) or a jr nz,NoFall ld a,b or $03 ld (hl),a pop hl ld (hl),0 jr IncTile2 NoFall: push af cp $03 jr z,FTMagicWall cp $02 jr z,CheckDiagFall and %11111010 cp $10 jr z,CheckDiagFall pop af res 0,a cp $38 jr nz,FFCF bit 1,b jr z,IncTile MakeSpcExp: ld a,$1B MakeExp: CALL_(MakeExplosion) jr IncTile FFCF: and %11111000 cp $08 jr z,MakeSpcExp cp $30 jr nz,MakeStationary ld a,$20 jr MakeExp MakeStationary: res 1,b pop hl ld (hl),b JUMP_(IncTile2) CheckDiagFall: pop af pop hl push hl dec hl ld a,(hl) or a jr nz,CheckDiagFallR push hl add hl,de ld a,(hl) or a pop hl jr nz,CheckDiagFallR FillInDiag: ld a,b or %00000011 ld (hl),a pop hl ld (hl),0 JUMP_(IncTile2) CheckDiagFallR: inc hl inc hl ld a,(hl) or a jr nz,MakeStationary push hl add hl,de ld a,(hl) or a pop hl jr nz,MakeStationary jr FillInDiag FTMagicWall: pop af bit 1,b JUMP_Z(IncTile) ld a,(mwatime) or a jr z,ClearAbove ld a,1 ld (mwactive),a add hl,de ld a,(hl) or a jr nz,ClearAbove ld a,b or $03 xor $04 ld (hl),a ClearAbove: pop hl xor a ld (hl),0 JUMP_(IncTile2) ; ---=== CHECK THE SURROUNDINGS FOR ROCKFORD OR AMOEBA ===-- ChkSur: push ix ld hl,DirDat1 ld de,(PROGRAM_ADDR) add hl,de ld b,4 ld d,0 RepCS: ld e,(hl) inc hl add ix,de ld a,(ix+0) cp $3A jr z,CSARF res 0,a cp $38 jr z,CSARF djnz RepCS CSARF: pop ix ret ; ---=== MOVE FIREFLY ===--- FireFly: push hl CALL_(ChkSur) jr z,FFExpl pop hl push hl ld a,(hl) and $03 ld hl,DirDat2 ld de,(PROGRAM_ADDR) add hl,de ld d,0 ld e,a add hl,de ld d,0 ld e,(hl) inc hl ld c,(hl) dec a ld b,a push ix pop hl add hl,de ld a,(hl) or a jr z,MoveFF sbc hl,de inc b ld e,c add hl,de ld a,(hl) or a jr z,MoveFF inc b ld a,b and $03 set 3,a set 2,a pop hl ld (hl),a ret MoveFF: ld a,b and $03 set 3,a set 2,a ld (hl),a pop hl ld (hl),0 ret FFExpl: pop hl ld a,$1B CALL_(MakeExplosion) ret ; ---=== MOVE BUTTERFLY ===--- ButterFly: push hl CALL_(ChkSur) jr z,BFExpl pop hl push hl ld a,(hl) and $03 ld hl,DirDat2+1 ld de,(PROGRAM_ADDR) add hl,de ld d,0 ld e,a add hl,de ld d,0 ld e,(hl) dec hl ld c,(hl) inc a ld b,a push ix pop hl add hl,de ld a,(hl) or a jr z,MoveBF sbc hl,de dec b ld e,c add hl,de ld a,(hl) or a jr z,MoveBF dec b ld a,b and $03 or %00110100 pop hl ld (hl),a ret MoveBF: ld a,b and $03 or %00110100 ld (hl),a pop hl ld (hl),0 ret BFExpl: pop hl ld a,$20 CALL_(MakeExplosion) ret ; ---=== CHECK IF AMOEBA SHOULD GROW ===--- Amoeba: ld a,(amTurn) or a jr z,NoAmTurning ld (hl),a JUMP_(IncTile) NoAmTurning: push hl ld hl,nrAmoeba inc (hl) ld hl,Flags bit 4,(hl) pop hl jr nz,DirsChecked xor a CheckDirs: ; Check if its possible to grow push af push hl CALL_(CheckDir) jr nz,NextDir ld hl,Flags set 4,(hl) NextDir: pop hl pop af inc a cp $04 jr nz,CheckDirs DirsChecked: ld a,(amTime) ld c,32 or a jr z,CheckGrowTry ld c,4 CheckGrowTry: CALL_(NextRandom) ld a,(RandSeed1) and $7F cp c JUMP_NC(IncTile) and $03 push hl CALL_(CheckDir) jr nz,GrowNotPoss ld (hl),$3B GrowNotPoss: pop hl JUMP_(IncTile) CheckDir: ld hl,DirDat2 ld de,(PROGRAM_ADDR) add hl,de ld d,0 ld e,a add hl,de ld d,0 ld e,(hl) push ix pop hl add hl,de ld a,(hl) and $FE or a ret ; ---=== CHECK IF PLAYER HAS MOVED ROCKFORD ===--- MoveRockford: push hl ld hl,RFMove res 3,(hl) ld hl,flags set 0,(hl) ; Rockford found! pop hl ld d,h ld e,l xor a ld (tmp),a CALL_(CheckKeys) bit 5,a jr nz,NoButtonPres push af ld a,1 ld (tmp),a pop af NoButtonPres: bit 1,a jr z,MoveLeft bit 2,a jr z,MoveRight bit 0,a jr z,MoveDown bit 3,a jr z,MoveUp ld a,(LAST_KEY) dec a jr z,MoveDown dec a jr z,MoveLeft dec a jr z,MoveRight dec a jr z,MoveUp ret MoveLeft: push hl ld hl,RFMove set 3,(hl) res 4,(hl) pop hl ld bc,$FF00 dec de dec de ld (xy),de inc de jr HorzMove MoveRight: push hl ld hl,RFMove set 3,(hl) set 4,(hl) pop hl ld bc,$0100 inc de inc de ld (xy),de dec de HorzMove: push hl ld hl,flags set 1,(hl) ; Rockford is moving pop hl ld a,(de) res 0,a cp $10 jr nz,CheckMove push de ld de,(xy) ld a,(de) or a jr nz,NoPushing CALL_(NextRandom) ld a,(RandSeed1) and $03 jr nz,NoPushing ; Only 1/4 chance that the boulder will be pushed ld a,$11 ld (de),a pop de xor a ld (de),a jr MoveOK NoPushing: pop de ret MoveDown: ld bc,$0001 push hl push hl ld hl,RFMove set 3,(hl) pop hl ld de,40 add hl,de ex de,hl pop hl jr CheckMove MoveUp: push hl ld hl,RFMove set 3,(hl) pop hl ld bc,$00FF push ix pop de inc de CheckMove: push hl ld hl,flags set 1,(hl) ; Rockford is moving pop hl ld a,(de) cp $05 ; Check if exit is reached jr z,MoveToOutBox res 0,a or a jr z,MoveOK and %11111100 cp $14 ; A jewel? ret nz xor a ; Yes! Then update scores and taken jewels ld (de),a push bc push hl ld a,(finished) bit 0,a ; Check if enough jewels have been taken ld a,(dmscore1) jr z,NoBonus ld a,(dmscore2) ; Yes, you got bonus points NoBonus: ld b,0 ld c,a ld hl,(score) add hl,bc ld (score),hl ld hl,dmtaken inc (hl) ld a,(hl) ld hl,dmneeded cp (hl) ld hl,flags jr nz,NotEqual ; Check if the last needed jewel was taken ld a,1 ld (finished),a set 3,(hl) ; The screen will flash NotEqual: set 2,(hl) ; The score has been updated pop hl pop bc MoveOK: xor a ld (de),a ld a,(tmp) ; Check if button was pressed or a ret nz ; It was, then don't move push hl ld (hl),0 ex de,hl ld (hl),$39 ld hl,(rockford) ld a,h add a,b ld h,a ld a,l add a,c ld l,a ld (rockford),hl pop hl ret MoveToOutBox: push hl ld hl,finished set 1,(hl) pop hl jr MoveOK ; ---=== CREATES EXPLOSION a WITH CENTRE AT hl ===--- MakeExplosion: push bc push de push hl ld c,a or a ld de,41 sbc hl,de ld de,38 ld b,3 MakeExpRep: CALL_(CheckSq) inc hl CALL_(CheckSq) inc hl CALL_(CheckSq) add hl,de djnz MakeExpRep pop hl pop de pop bc ret CheckSq: ld a,(hl) cp $07 ret z ld (hl),c ret ; ---=== FLASHES THE SCREEN A SHORT WHILE ===-- FlashScreen: ld b,2 FlashAgain: push bc ld hl,$FC00 ld bc,1024 F_NextByte: ld a,(hl) xor $FF ld (hl),a inc hl dec bc ld a,b or c jr nz,F_NextByte ld b,20 Wait: halt djnz Wait pop bc djnz FlashAgain ret ; ---=== SHOWS THE SCREEN WITH h, l AS MIDDLE POINT ===--- ShowScreen: ld bc,$2114 ld a,(curCave) cp 16 jr c,CheckEdges ld bc,$0D0A CheckEdges: push hl ld a,h cp $05 jr nc,LeftEdgeOK ld h,5 LeftEdgeOK: cp b jr c,RightEdgeOK ld h,b RightEdgeOK: ld a,l cp $06 jr nc,TopEdgeOK ld l,$06 TopEdgeOK: cp c jr c,BotEdgeOK ld l,c BotEdgeOK: or a ld de,$0504 sbc hl,de ld a,h ld (tmp),a ld de,0 ld b,8 S_NextRow: push bc ld b,12 S_NextCol: push de push hl CALL_(GetObject) bit 7,a jr z,Uncovered ld a,$07 Uncovered: cp $25 jr nz,CheckOutbox ld a,(flashcnt) or a ld a,$25 jr z,ConvertImage FlashBox: ld a,(animcnt1) bit 2,a ld a,$04 jr nz,PutIt ld a,$11 jr PutIt CheckOutbox: cp $05 jr nz,ConvertImage jr z,FlashBox ConvertImage: ld hl,Object_Table ld de,(PROGRAM_ADDR) add hl,de ld d,0 ld e,a add hl,de ld a,(hl) or a jr z,RFAnim cp $05 ; Check if Jewel jr nz,ChFF ld hl,animcnt2 ld d,(hl) srl d add a,d ; Choose image depending on AnimCnt2 jr PutIt ChFF: cp $12 ; Check if Firefly jr nz,ChBF ld hl,animcnt1 ld d,(hl) ; Choose image depending on AnimCnt1 bit 1,d jr z,PutIt inc a jr PutIt ChBF: cp $14 ; Check if Butterfly jr nz,ChAM ld hl,animcnt1 ld d,a ld a,(hl) and %00000111 add a,d ; Choose image depending on AnimCnt1 jr PutIt ChAM: cp $1C jr nz,ChMW ; Check if Amoeba ld hl,animcnt1 ld d,a ld a,(hl) srl a and $03 add a,d jr PutIt ChMW: cp $2E jr nz,PutIt ld a,(mwactive) or a ld a,$2E jr z,PutIt inc a ld hl,animcnt1 ld d,a ld a,(hl) and $03 add a,d PutIt: pop hl pop de ex de,hl CALL_(PutSprite) ex de,hl inc d inc h dec b JUMP_NZ(S_NextCol) ld a,(tmp) ld h,a inc l ld d,0 inc e pop bc dec b JUMP_NZ(S_NextRow) pop hl ret RFAnim: ld a,(animcnt1) and $03 ld hl,RFMove jr nz,SameAnim CALL_(NextRandom) ld a,(RandSeed1) and $07 jr nz,NoTapChange ld a,(hl) xor 2 ld (hl),a NoTapChange: res 0,(hl) CALL_(NextRandom) ld a,(RandSeed1) and $03 jr nz,NoBlinking set 0,(hl) NoBlinking: xor a SameAnim: bit 3,(hl) jr z,RFForward bit 4,(hl) jr nz,RF_Right add a,$26 StopTapBlink: res 0,(hl) res 1,(hl) jr PutIt RF_Right: add a,$2A jr StopTapBlink RFForward: ld a,(animcnt1) and $03 srl a ld d,a ld a,(RFMove) and $03 jr z,PutIt add a,a add a,$1E add a,d jr PutIt ; ---=== PUT GRAPHIC IMAGE a AT h, l ===--- PutSprite: push bc push de push hl ld d,l ld e,0 or a rr d rr e ; Multiplying l with 128 ld l,h ld h,0 add hl,de ld de,$FC00 add hl,de ; hl now points to the upper left corner of the image ex de,hl ld h,0 ld l,a add hl,hl add hl,hl add hl,hl ld bc,(PROGRAM_ADDR) add hl,bc ld bc,G_Rockford add hl,bc ld b,8 PutRow: ldi push hl ex de,hl ld de,15 add hl,de ex de,hl pop hl djnz PutRow pop hl pop de pop bc ret ; ---=== DECOMPRESS CURRENT LEVEL INTO GRAPHMEM ===--- InitLevel: xor a ld (timecnt),a ld (finished),a ld (dmtaken),a ld (amTurn),a ld (mwactive),a ld (ELTimer),a ld hl,CavePointers ld d,0 ld a,(curCave) ld e,a sla e add hl,de ld de,(PROGRAM_ADDR) add hl,de call LD_HL_MHL add hl,de ; HL now points to the current cave inc hl ; The first information is unimportant (cave nr) ld de,mwatime ldi ldi ldi ld a,(mwatime) ld (amTime),a ld a,(difLevel) push af ld d,0 ld e,a add hl,de ; Find the right seeds depending on difficulty ld a,(hl) ld (randseed2),a ld de,5 add hl,de ld a,(hl) ld (dmneeded),a add hl,de ld a,(hl) ld (timeLeft),a pop af sub 10 neg ld d,0 ld e,a add hl,de ; and jump to the scattered objects ld de,randobj ld bc,8 ldir ; Move the next 8 byte into their right positions push hl xor a ld (randseed1),a ld bc,$0003 ; Start scattering objects. B = x, C = y ScatNext: ld (xy),bc push bc CALL_(NextRandom) ld c,1 ; If no object chosen, then dirt ld hl,probobj ld b,4 ld a,(randseed1) CheckProb: cp (hl) jr nc,NotLesser push hl dec hl dec hl dec hl dec hl ld c,(hl) pop hl NotLesser: inc hl djnz CheckProb ld a,c ld hl,(xy) CALL_(StoreObject) pop bc inc b ld a,b cp 40 jr c,ScatNext ld b,0 inc c ld a,c cp $18 jr c,ScatNext ld hl,$0002 ld bc,$2816 ld a,7 CALL_(DrawRect) pop ix GetNext: ld a,(ix) cp $FF ret z and $3F ld e,a ld a,(ix) rlca rlca and $03 ld h,(ix+1) ld l,(ix+2) ld b,(ix+3) ld c,(ix+4) ld d,(ix+5) jr z,StoObj dec a jr z,DrLine dec a jr z,FillRec DrRec: ld a,e CALL_(DrawRect) ld de,5 add ix,de jr GetNext StoObj: ld a,e cp $25 jr nz,NotRockford ld (rockford),hl NotRockford: cp $04 jr nz,NotOutBox NotOutBox: CALL_(StoreObject) inc ix inc ix inc ix jr GetNext DrLine: ld a,e CALL_(DrawLine) ld de,5 add ix,de jr GetNext FillRec: ld a,e CALL_(DrawFillRect) ld de,6 add ix,de jr GetNext ; ---=== DRAW LINE FROM h, l WITH LENGTH b, DIRECTION c, OBJECT a ===--- DrawLine: push bc push de push hl push ix ld ix,ldx ld de,(PROGRAM_ADDR) add ix,de ld d,0 ld e,c add ix,de PlotObj: CALL_(StoreObject) push af ld a,h add a,(ix+0) ld h,a ld a,l add a,(ix+8) ld l,a pop af djnz PlotObj pop ix pop hl pop de pop bc ret ; ---=== DRAW RECTANGLE FROM h,l WITH THE DIM b,c BORDER a FILL d ===-- DrawFillRect: CALL_(DrawRect) ld a,d RepDFR: inc h inc l dec b ret z dec b ret z dec c ret z dec c ret z CALL_(DrawRect) jr RepDFR ; ---=== DRAW RECTANGLE FROM h,l WITH THE DIM b, c BORDER a ===--- DrawRect: push bc push de push hl ld d,b ld e,c ld c,2 CALL_(DrawLine) ld b,e ld c,4 CALL_(DrawLine) push hl push af ld a,l add a,e ld l,a dec l pop af ld b,d ld c,2 CALL_(DrawLine) pop hl push af ld a,h add a,d ld h,a dec h pop af ld b,e ld c,4 CALL_(DrawLine) pop hl pop de pop bc ret ; ---=== STORE OBJECT a AT h,l IN CAVE ===--- StoreObject: push bc push de push hl ld c,h ld h,0 add hl,hl add hl,hl add hl,hl ld d,0 ld e,l add hl,hl add hl,hl add hl,de ; Now hl = l * 40 ld e,c add hl,de ; Adding the x-position ld de,Cave add hl,de ; And finally the offset to the cavedata or $80 ; Set a bit that this object hasn't been uncovered ld (hl),a ; And store the object pop hl pop de pop bc ret ; ---=== GET OBJECT a AT h,l IN CAVE ===--- GetObject: push bc push de push hl ld c,h ld h,0 add hl,hl add hl,hl add hl,hl ld d,0 ld e,l add hl,hl add hl,hl add hl,de ; Now hl = l * 40 ld e,c add hl,de ; Adding the x-position ld de,Cave add hl,de ; And finally the offset to the cavedata ld a,(hl) ; And get the object pop hl pop de pop bc ret ; ---=== GETS THE NEXT "RANDOM" NUMBER ===--- NextRandom: push af push bc push de ld a,(randseed1) rrca and $80 ld b,a ld a,(randseed2) ld d,a rrca and $7F ld c,a ld a,d rrca and $80 add a,d adc a,$13 ld (randseed2),a ld a,(randseed1) adc a,b adc a,c ld (randseed1),a pop de pop bc pop af ret ; ---=== CHOOSE CAVE AND DIFFICULTY ===--- ChooseLevel: ROM_CALL(CLEARLCD) ld hl,TitlePic ld de,(PROGRAM_ADDR) add hl,de ld de,$FC40 ld bc,272 ldir ld de,$FE00 ld bc,112 ldir ld hl,$3804 ld ($8333),hl ld hl,AuthorText ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZM_STR) xor a ld (curCave),a ld (difLevel),a C_Wait: ld a,(difLevel) cp 3 jr c,LowLevel xor a ld (curCave),a LowLevel: ld hl,$0804 ld ($800C),hl ld a,(curCave) add a,65 ROM_CALL(TX_CHARPUT) ld hl,$1104 ld ($800C),hl ld a,(difLevel) add a,49 ROM_CALL(TX_CHARPUT) ld hl,$2D1F ld ($8333),hl ld hl,HiScoreText ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZM_STR) call LD_HL_MHL ld de,string+5 ld b,5 CALL_(UnpDigits2) ex de,hl ROM_CALL(D_ZM_STR) WK: call GET_KEY ld hl,difLevel cp K_ENTER ret z cp K_SECOND ret z cp $37 ret z dec a jr z,LevD dec a jr z,CaveD dec a jr z,CaveI dec a jr nz,WK ld a,(hl) cp $04 UpdInfo1: jr z,WK inc (hl) jr C_Wait LevD: ld a,(hl) or a jr z,WK dec (hl) jr C_Wait CaveI: ld hl,curCave ld a,(hl) cp NrLevels-4 jr z,WK add a,4 ld (hl),a JUMP_(C_Wait) CaveD: ld hl,curCave ld a,(hl) or a jr z,WK sub 4 ld (hl),a JUMP_(C_Wait) NewHiscore: ld (hl),e inc hl ld (hl),d ROM_CALL(CLEARLCD) ld hl,$0401 ld ($800C),hl ld hl,NewHiText ld de,(PROGRAM_ADDR) add hl,de ROM_CALL(D_ZT_STR) ld de,$0303 ld ($800C),de ROM_CALL(D_ZT_STR) ld ix,HiScoreName ld de,(PROGRAM_ADDR) add ix,de ld (ix),65 ld (ix+1),65 ld (ix+2),65 push ix pop de ld c,1 ld hl,$8C40 set 0,(hl) EnterName: CALL_(ShowName) WaitKey4: call GET_KEY or a jr z,WaitKey4 cp K_SECOND ret z cp K_EXIT ret z cp K_ENTER jr z,NextLet dec a jr z,LetBelow dec a jr z,PrevLet dec a jr z,NextLet dec a jr z,LetAbove jr WaitKey4 PrevLet: ld a,c dec a jr z,WaitKey4 dec c dec de jr EnterName NextLet: ld a,c cp 3 jr z,WaitKey4 inc c inc de jr EnterName LetBelow: ld a,(de) cp 65 jr z,WaitKey4 dec a ld (de),a jr EnterName LetAbove: ld a,(de) cp 90 jr z,WaitKey4 inc a ld (de),a jr EnterName ShowName: push ix ld b,1 ld hl,$0905 ld ($800C),hl RepTypeLet: res 3,(iy+5) ld a,c cp b jr nz,TypeLet set 3,(iy+5) TypeLet: ld a,(ix) ROM_CALL(TX_CHARPUT) inc ix inc b ld a,b cp 4 jr nz,RepTypeLet res 3,(iy+5) pop ix ret InfoText: .db 102,3,"Cave",0 .db 101,14,"Jewels",0 .db 103,32 ScoreText: .db "Score",0 .db 105,50,"Time",0 InfoText2: .db "Cave: ",0 InfoText3: .db "Lives left: ",0 IMText: .db "Intermission ",0 ExtraLifeText: .db "EXTRA",0 .db " LIFE ",0 ELText2: .db "* Extra life! *",0 GameOverText: .db "* GAME OVER *",0 AuthorText: .db "BY JIMMY MARDELL, " .db "mja@algonet.se",0 TimeOutText: .db " Out of time ",0 ldx: .db 0,1,1,1,0,-1,-1,-1 ldy: .db -1,-1,0,1,1,1,0,-1 DirDat1: ; Dat for checking if Rockford is close .db 1,39,2,39 DirDat2: ; First try ofs, second try ofs .db 81,40,1,42,81 HiScoreText: .db "Hiscore: " HiScoreName: .db 45,45,45," ",0 HiScore: .dw 0 NewHiText: .db "A NEW HISCORE",0 EnterNameText: .db "Enter your name",0 PauseText: .db "PAUSE",0 .db "Press any key to continue",0 CaveDesc: .db 5,"Intro" .db 5,"Rooms" .db 4,"Maze" .db 11,"Butterflies" .db 6,"Guards" .db 12,"Firefly dens" .db 6,"Amoeba" .db 14,"Enchanted wall" .db 5,"Greed" .db 6,"Tracks" .db 5,"Crowd" .db 5,"Walls" .db 10,"Apocalypse" .db 6,"Zigzag" .db 6,"Tunnel" .db 15,"Enchanted boxes" #INCLUDE graphics.h #INCLUDE caves.h #INCLUDE titlepic.h .end