PAGE &0E -------- 00:BRK \player x coordinate 01:BRK \player y coordinate 02:BRK \number of lives 04:EQUW &1707 \player sprite data 10:BRK \player bullet x coordinate 11:BRK \player bullet y coordinate 14:EQUW 0 \player bullet sprite addr 19:EQUW 0 \player bullet old scr addr &E20 - &FFF ----------- 30 16-byte blocks of bird data. Attributes at beginning of game are as follows: Offset 00:EQUB 16 \x coordinate (16 for 1st bird) 01:EQUB 16 \y coordinate (16 for 1st bird) 02:EQUB 1 \presence flag, 1=present, 0=absent 03: 04:EQUW &1526 \sprite addr 06:EQUW &80xx \old scr addr 08:EQUW &3540 \new scr addr (&3540 for 1st bird) 0A 0B 0C:BRK \homing byte &1000-&107F ----------- 8 16-byte bird bullet blocks &1080-&11EF ----------- 16 16-byte egg/explosion blocks PAGE &11 (Continued) -------------------- E0:EQUB -98 \INKEY code for left key E1:EQUB -67 \INKEY code for right key E2:EQUB 47 \ASCII code for fire key E3: E4:BRK \silence flag, sound on=0, sound off=1 E5:EQUW 0 \copy of score at end of game PAGE &15 -------- \Each sprite comprises [columns,rows] in decimal \then (column x rows) of data in hex \bird up sprite data 26:EQUB 6,8 28:EQUB 04,00,00,00,00,08 \020000000020 EQUB 04,08,05,0A,04,08 \022003300220 EQUB 00,0C,0D,0E,0C,00 \002223322200 EQUB 00,04,0C,0C,08,00 \000222222000 EQUB 00,00,0C,0C,00,00 \000022220000 EQUB 00,00,26,19,00,00 \000052250000 EQUB 00,00,22,11,00,00 \000050050000 EQUB 00,00,22,11,00,00 \000050050000 \bird down sprite data 88:EQUB 6,8 8A:EQUB 00,00,00,00,00,00 \000000000000 EQUB 00,00,05,0A,00,00 \000003300000 EQUB 00,04,0D,0E,08,00 \000223322000 EQUB 00,0C,0C,0C,0C,00 \002222222200 EQUB 04,08,0C,0C,04,08 \022022220220 EQUB 04,00,0C,19,00,08 \020022250020 EQUB 00,00,22,11,00,00 \000050050000 EQUB 00,00,22,11,00,00 \000050050000 PAGE &16 -------- \egg sprite data 4C:EQUB 3,8 4E:EQUB 00,2A,00 \007000 EQUB 15,3F,00 \077700 EQUB 15,3F,00 \077700 EQUB 3F,3F,2A \777770 EQUB 3F,3F,2A \777770 EQUB 3F,3F,2A \777770 EQUB 3F,3F,2A \777770 EQUB 15,3F,00 \077700 \'20' bonus sprite data 8A:EQUB 3,5 8C:EQUB F0,50,F0 \CC0CCC EQUB 50,50,50 \0C0C0C EQUB F0,50,50 \CC0C0C EQUB A0,50,50 \C00C0C EQUB F0,50,F0 \CC0CCC \player bullet sprite data F3:EQUB 1,8 F5:EQUB 2A \70 EQUB 2A \70 EQUB 2A \70 EQUB 2A \70 EQUB 2A \70 EQUB 2A \70 EQUB 2A \70 EQUB 2A \70 FD:EQUB 1,8 FE:EQUB 28 \60 EQUB 28 \60 EQUB 28 \60 EQUB 28 \60 EQUB 28 \60 EQUB 28 \60 EQUB 28 \60 EQUB 28 \60 PAGE &17 -------- \player ship sprite data 07:EQUB 4,12 09:EQUB 00,05,00,00 \00030000 EQUB 00,05,00,00 \00030000 EQUB 00,05,00,00 \00030000 EQUB 00,0F,0A,00 \00333000 EQUB 00,0F,0A,00 \00333000 EQUB 40,0F,4A,00 \08333800 EQUB 01,85,81,00 \01838100 EQUB 03,85,81,02 \11838110 EQUB 03,07,03,02 \11131110 EQUB 03,07,03,02 \11131110 EQUB 03,02,03,02 \11101110 EQUB 03,02,03,02 \11101110 \bird/egg explosion sprite data 39:EQUB 4,12 3B:EQUB 00,CD,45,00 \00AB0B00 EQUB 45,40,88,00 \0B08A000 EQUB CE,41,41,88 \BA0909A0 EQUB 40,82,00,00 \08900000 EQUB 00,88,C2,88 \00A098A0 EQUB CE,C2,41,45 \BA98090B EQUB 00,00,80,88 \000080A0 EQUB 44,41,40,45 \0A09080B EQUB 00,8A,82,8A \00B090B0 EQUB 45,44,44,88 \0B0A0AA0 EQUB 00,45,C4,00 \000B8A00 EQUB 00,00,00,00 \00000000 \player ship explosion sprite data 6B:EQUB 9,16 6D:EQUB 00,00,00,00,00,00,00,00,00 \000000000000000000 EQUB 00,00,00,00,00,00,00,00,00 \000000000000000000 EQUB 00,00,00,8A,8A,8A,8A,00,00 \000000B0B0B0B00000 EQUB 00,00,8A,00,00,00,00,00,00 \0000B0000000000000 EQUB 00,00,45,00,8A,45,00,8A,00 \00000B00B00B00B000 EQUB 00,45,00,00,88,88,00,00,00 \000B0000A0A0000000 EQUB 00,00,00,8A,00,00,45,00,00 \000000B000000B0000 EQUB 45,00,8A,00,8A,8A,88,00,8A \0B00B000B0B0A000B0 EQUB 00,45,00,8A,CD,88,00,45,00 \000B00B0ABA0000B00 EQUB 00,00,45,88,82,00,8A,88,45 \00000BA09000B0A00B EQUB 45,00,00,41,41,C2,CD,00,8A \0B0000090998AB00B0 EQUB 00,8A,8A,C2,00,41,00,00,00 \00B0B0980009000000 EQUB 00,44,41,00,82,00,C6,CE,00 \000A090090009ABA00 EQUB 00,00,44,C1,C1,40,00,00,8A \00000A8989080000B0 EQUB 00,00,CE,00,C2,82,C2,45,00 \0000BA009890980B00 EQUB 45,CE,41,C1,C1,C2,00,8A,45 \0BBA0989899800B00B PAGE &18 -------- 00:JMP &1806 \EXECUTE 03:JMP &24C9 \zeroise score, define envelopes etc 06:LDA &2800:CMP #33:BNE &1810 \?&2800 is always 33 JMP &2801 \so we always go to &2801 \ the top level layout of the game is this: \ &1800:JMP &1806 \ &1806:JMP &2801 \ &2801:JMP &280C \ &280C:REPEAT set up keys, draw mode 7 screen, play game until all lives \ lost, check score against hi scores, enter name if required UNTIL FALSE \ if you change ?&2800 to any number <> 33 the following will happen: 10:LDA #0:STA &2490:STA &2491 \zeroise hi score JMP &2492 \and jump to alternate title page \ *** sprite routine *** \ entry: &82/3 points to parameter block: \ 0 x coordinate of sprite \ 1 y coordinate of sprite \ 4-5 new sprite data addr \ 6-7 old sprite data addr \ 9-10 old screen addr. \ Offset 9 usually set to &80 by routines to give &80xx, an address in ROM, \ when plotting sprite on scr for 1st time. \exit: &82/3 points to updated parameter block, extra details as thus: \ 8 y coordinate AND 7 \ 11 x coordinate AND 1 \calculate screen address \in Basic this would be &3000 + (x AND &FE)*8 + (x AND 7) + \ (y AND &F8)*80 + (y AND 7) 1B:LDY #0:LDA (&82),Y \get x coordinate AND #1:STA &70 \odd or even coordinate LDA (&82),Y:AND #&FE:STA &72 \remainder STY &73:STY &75 \zeroise &73/75 ASLA:ROL &73:ASLA:ROL &73:STA &72 \now &72/3 = (x AND &FE)*8 INY:LDA (&82),Y \get y coordinate AND #7:STA &71 \&71 = row within char row LDA (&82),Y:AND #&F8 \remainder ASLA:ROL &75:ASLA:ROL &75 ASLA:ROL &75:ASLA:ROL &75:STA &74 \&74/5 = (y AND &F8)*16 LDA &75:STA &77 LDA &74:ASLA:ROL &77 ASLA:ROL &77:STA &76 \&76/7 = (y AND &F8)*64 LDA &72:CLC:ADC &71:STA &72 LDA &73:ADC #0:STA &73 \(x AND &FE)*8 + (x AND 7) LDA &72:CLC:ADC &74:STA &72 LDA &73:ADC &75:STA &73 \ + (y AND &F8)*16 LDA &72:CLC:ADC &76:STA &72 LDA &73:ADC &77:STA &73 \ + (y AND &F8)*64 NOP:CLC:ADC &72:STA &72 LDA #&30:NOP:CLC:ADC &73:STA &73 \ + &3000 93:LDY #4:LDA (&82),Y:STA &74 \ INY:LDA (&82),Y:STA &75 \Y=5, &74/5 = new sprite data address INY:LDA (&82),Y:STA &76 \Y=6 INY:LDA (&82),Y:STA &77 \Y=7, &76/7 = old sprite address INY:LDA (&82),Y:STA &7C \Y=8, &7C = (old y AND 7) INY:LDA (&82),Y:STA &7A \Y=9 INY:LDA (&82),Y:STA &7B \Y=10 ,&7A/B old screen address INY:LDA (&82),Y:STA &7D \Y=11. &7D = (oldx AND 1) LDY #0:LDA (&74),Y:STA &78 \&78 = rows INY:LDA (&74),Y:STA &79 \Y=1, &79 = columns LDY #6:LDA &74:STA (&82),Y \ INY:LDA &75:STA (&82),Y \Y=7, sprite data address INY:LDA &71:STA (&82),Y \Y=8 (new y AND 7) INY:LDA &72:STA (&82),Y \Y=9 INY:LDA &73:STA (&82),Y \Y=10 new screen address INY:LDA &70:STA (&82),Y \Y=11 (new x AND 1) DEC &79 LDA &74:CLC:ADC #2:STA &74 \was pointing to rows+columns data LDA &75:ADC #0:STA &75 \now point to sprite data itself LDA &76:CLC:ADC #2:STA &76 \ LDA &77:ADC #0:STA &77 \ PAGE &19 -------- \ remember \ &71 = y AND 7, counter indicating position in char row \ &72/3 = new scr addr \ &74/5 = new sprite addr \ &76/7 = old sprite addr \ &78 = rows \ &79 = columns \ &7A/B = old scr addr 02:LDY #0:JSR &190B DEC &79:BNE &1902 \dec columns until all done 0B:LDX &78 \load rows count LDA &72:PHA:LDA &73:PHA \preserve new scr LDA &7A:PHA:LDA &7B:PHA \preserve old scr \plot byte at new scr addr 19:LDA &70:BEQ &1938 \even newx so don't split byte LDA (&74),Y:BEQ &1940 \zero byte (you don't really need to do this) LSRA:AND #85 \mask right pixel EOR (&72),Y:STA (&72),Y \store right pixel in this column LDA (&74),Y:ASLA:AND #170 \mask left pixel LDY #8 \point to next column EOR (&72),Y:STA (&72),Y LDY #0:JMP &1940 \point to last column and jump back \store pixels straight in memory without splitting 38:LDA (&74),Y:BEQ &1940 EOR (&72),Y:STA (&72),Y \plot byte at old scr addr 40:LDA &7D:BEQ &195F \even oldx so don't split pixels LDA (&76),Y:BEQ &1967 LSRA:AND #85 \mask right pixel EOR (&7A),Y:STA (&7A),Y \store right pixel in this column LDA (&76),Y:ASLA:AND #170 \mask left pixel LDY #8 \point to next column EOR (&7A),Y:STA (&7A),Y LDY #0:JMP &1967 \point to last column and jump \store pixels in memory without splitting 5F:LDA (&76),Y:BEQ &1967 EOR (&7A),Y:STA (&7A),Y 67:LDA &72:CLC:ADC #8:STA &72 \point to next column BCC &1972:INC &73 \new scr=new scr + 8 72:LDA &7A:CLC:ADC #8:STA &7A \point to next column BCC &197D:INC &7B \old scr=old scr + 8 7D:INC &74:BNE &1983:INC &75 \new data=new data + 1, next byte of new sprite 83:INC &76:BNE &1989:INC &77 \old data=old data + 1, next byte of old sprite 89:DEX:BEQ &198F:JMP &1919 \loop till all rows done 8F:PLA:STA &7B:PLA:STA &7A \restore original old scr PLA:STA &73:PLA:STA &72 \restore original new scr INC &71:LDA &71:AND #7:BEQ &19AC \bottom of char row INC &72:BNE &19B9:INC &73 \new scr=new scr+1 B9:JMP &19B9 AC:LDA &72:CLC:ADC #&79:STA &72 LDA &73:ADC #2:STA &73 \new scr = new scr + &279 B9:INC &7C:LDA &7C:AND #7:BEQ &19C8 \bottom of char row INC &79:BNE &19D5:INC &7B RTS C8:LDA &7A:CLC:ADC #&79:STA &7A LDA &7B:ADC #2:STA &7B \old scr = old scr + &279 D8:RTS \ *** move player ship *** D6:BRK \copy of shipx LDA &E00:STA &19D6 LDX &11E1 \get INKEY code for right JSR &1A2A:CPY #&FF:BNE &19F4 \not pressed INC &E00:LDA &E00:CMP #140:BNE &19F4 \not at maximum right DEC &E00 \put back to left F4:LDX &11E0 \get INKEY code for left JSR &1A2A:CPY #&FF:BNE &1A0B \not pressed DEC &E00 PAGE &1A -------- 01:LDA &E00:CMP #10:BNE &1A0B \ship not at maximum left INC &E00 \put back to right 0B:LDA &E00:CMP &19D6:BEQ &1A22 \ship hasn't moved so don't print LDA #&00:STA &82:LDA #&0E:STA &83:JSR &181B \print ship JSR &1F58 \check for collision RTS 22:JSR &1F58 \check if collided with egg LDX #6:JMP &22CE \delay \ *** check for keypress *** \ entry: X=INKEY number \ exit: A and X preserved 2A:PHA:TXA:PHA LDA #&81:LDY #&FF:JSR osbyte PLA:TAX:PLA RTS \ *** move bird *** \ entry: &8E/8F points to data block of bird to be moved 38:LDY #1:LDA (&8E),Y \birdy = TAX:INX:TXA:STA (&8E),Y \birdy + 1 AND #15:BNE &1A48 \wings change position every 16th line JSR &1ACA \swap bird sprite 48:LDY #1:LDA (&8E),Y:CMP #236:BNE &1A5F \birdy <> 236 JSR &1EAE \put egg LDY #1:LDA #8:STA (&8E),Y \set birdy=8 JSR &1FDE \swoop sound 5F:LDY #14:LDA (&8E),Y CLC:ADC #32:AND #&F0 CMP #32:BEQ &1A95:BMI &1A83 LDY #0:LDA (&8E),Y:SEC:SBC #1:STA (&8E),Y \birdx = birdx - 1 CMP #2:BCS &1A95 \ birdx >= 2 CLC:ADC #1:STA (&8E),Y:JMP &1A95 83:LDY #0:LDA (&8E),Y:SEC:ADC #0:STA (&8E),Y \birdx = birdx + 1 CMP #147:BCC &1A95 \ birdx <= 147 SEC:SBC #1:STA (&8E),Y 95:JSR &1EA3 \print egg JSR &2464 \check collision LDY #0:LDA (&8E),Y:CMP &E00:BEQ &1AB7 \birdx = shipx BCC &1AB8 \birdx < shipx LDY #14:LDA (&8E),Y:CLC:ADC #1:STA (&8E),Y CMP #32:BNE &1AB7 LDA #31:STA (&8E),Y B7:RTS B8:LDY #14:LDA (&8E),Y CLC:SBC #0:STA (&8E),Y CMP #224:BNE &1AB7 LDA #225:STA (&8E),Y:RTS \ *** change bird wing position *** \ if bird sprite addr is &1526 change to &1588 and vice versa CA:LDY #4:LDA (&8E),Y \get sprite data hi CMP #&26:BNE &1AD7 LDA #&88:STA (&8E),Y:RTS D7:LDA #&26:STA (&8E),Y:RTS DC:LDA &E10:BNE &1B29 \player bullet x is active LDA #129:LDX #0:LDY #0:JSR osbyte CPY #0:BNE &1AFB \key not pressed CPX &11E2:BEQ &1B0B \fire key pressed CPX #ASC"P":BEQ &1B00:CPX #ASC"p":BEQ &1B00 \pause pressed LDX #1:JMP &22CE \delay to slow down game PAGE &1B -------- 00:JSR &2000 \clear kbd LDA #7:JSR oswrch:JMP &2405 \beep and wait for key press \ *** init player bullet *** 0B:LDA &E00:CLC:ADC #3:STA &E10 \bulletx at shipx+3 LDA #230:STA &E11 \bullety at 230 LDA #&80:STA &E1A \old screen &80xx LDA #&10:STA &82:LDA #&0E:STA &83 \point to &E10 JMP &181B \and call sprite routine to print bullet \ *** move player bullet up screen *** 29:DEC &E11 \bullety = bullety -1 LDA &E11:CMP #11:BCS &1B4E \bullety >= 11 so at top of scr yet LDA #&10:STA &82:LDA #&0E:STA &83 \point to &E10 JSR &181B \erase bullet LDA #0:STA &E10 \signal bullet now inactive JMP &2000 \clear keybd 4E:LDA &E19:STA &70:LDA &E1A:STA &71 \old screen JSR &1B69 \move bullet up LDA &70:STA &E19 LDA &71:STA &E1A:JSR &231E RTS \ *** print bullet at addr in &70/1 *** \ uses &70/1 = addr of top of bullet \ &72 = pixel code to be written \ &73/4 = &70/1 + &280, addr of bottom of bullet 69:LDA &70:AND #7:BNE &1B7F \in row LDA &70:SEC:SBC #&79:STA &70 LDA &71:SBC #2:STA &71 \screen=screen + &279 JMP &1B8C 7F:LDA &70:SEC:SBC #1:STA &70 LDA &71:SBC #0:STA &71 \screen=screen - 1 LDA &E1B:CMP #1:BNE &1B9A LDA #21:STA &72 \code for black-white JMP &1B9E 9A:LDA #42:STA &72 \code for white-black DEC &E18:LDA &E18:AND #7:STA &E18 \old row no LDY #0:LDA &72:EOR (&70),Y:STA (&70),Y \print top pixel of bullet LDA &70:CLC:ADC #&80:STA &73 LDA &71:ADC #2:STA &74 \add &280 to get bottom of bullet EOR (&73),Y:STA (&73),Y \erase bottom pixel of bullet RTS \ *** init bird bullet *** \ entry; &8E/F point to bird block C5:LDY #2:LDA (&8E),Y:BNE &1BCC \bird active RTS CC:LDY #0:LDA (&8E),Y \bird bulletx will be CLC:ADC #6:STA &74 \at birdx + 6 LDA #&00:STA &70:STA &73 LDA #&10:STA &71 \&70/71 points to 1st bullet block LDA &248F:AND #6:CLC:ADC #2:STA &72 \(level AND 6) + 2 E9:LDY #2:LDA (&70),Y \get bullet state BNE &1BFE \bullet block in use LDA &70:STA &75:LDA &71:STA &76 LDA #1:STA &73 \signify free block found FE:LDY #0 PAGE &1C -------- 00:LDA (&70),Y:CMP &74:BEQ &1C1B \get LDA &70:CLC:ADC #16:STA &70 \point to LDA &71:ADC #0:STA &71 \next bullet block DEC &72:BNE &1BE9 \loop until block found LDA &73:BNE &1C1C \and coords aren't same as another bullet 1B:RTS LDA #1:LDY #2:STA (&72),Y \singal bullet active LDY #0:LDA &74:STA (&75),Y LDY #1:LDA (&8E),Y:CLC:ADC #6:STA (&75),Y \store birdy+6 LDY #4:LDA #&FD:STA (&75),Y INY:LDA #&16:STA (&75),Y \bird bullet data @&16FD LDY #10:LDA #&80:STA (&75),Y \old scr &80xx LDA &75:STA &82:LDA &76:STA &83 JMP &181B \ *** check bird bullets *** 4D:LDA #&00:STA &8B:LDA #&10:STA &8C \&8B/8C point to 1st bullet block LDA #8:STA &8D \count 8 blocks 59:LDY #2:LDA (&8B),Y:CMP #1:BEQ &1C91 \bullet active LDA &8B:CLC:ADC #16:STA &8B LDA &8C:ADC #0:STA &8C \point to next block DEC &8D:BNE &1C59 \loop till all bullets checked RTS 73:LDY #1:LDA (&8B),Y:CMP #232:BCC &1C90 \bullety <= 232 DEY:LDA (&8B),Y:CMP &E00:BCC &1C90 \bulletx < shipx CLC:SBC #6:CMP &E00:BCS &1C90 \bulletx + 5 > shipx PLA:PLA:PLA:PLA \ship hit 90:RTS \ move bird bullet, block addr in &8B/C 91:LDY #1:LDA (&8B),Y:CLC:ADC #1:STA (&8B),Y \bullety=bullety + 1 CMP #246:BCS &1D05 \bullety > 246 LDY #9:LDA (&8B),Y:STA &70 INY:LDA (&8B),Y:STA &71 LDA &70:CLC:ADC #&80:STA &73 \bottom of bullet &280 bytes LDA &71:ADC #2:STA &74 \or 1 char row away from top of bullet INY:LDA (&8B),Y \get old (x AND 1) CMP #1:BNE &1CC4 \=0 so even coord LDA #20:STA &72 \code for black-cyan JMP &1CC8 C4:LDA #40:STA &72 \code for cyan-black C8:LDA &72:LDY #0:EOR (&70),Y:STA (&70),Y \erase top of bullet LDA &72:EOR (&73),Y:STA (&73),Y \add to bottom of bullet LDA &70:AND #7:CMP #7:BNE &1CEE \not at bottom of row LDA &70:CLC:ADC #&79:STA &70 LDA &71:ADC #2:STA &71 \scr = scr + &279 JMP &1CF4 EE:INC &70:BNE &1CF4:INC &71 \scr = scr + 1 F4:LDY #9:LDA &70:STA (&8B),Y \put new addr of bullet INY:LDA &71:STA (&8B),Y \back in bird block JSR &1C73 \check if ship hit PAGE &1D -------- 02:JMP &1C61 \loop to check next bullet \ bullet has reached bottom of scr 05:LDY #1:SEC:SBC #1:STA (&8B),Y \y=y-1 LDA #&80:LDY #10:STA (&8B),Y \old scr &80xx LDA &8B:STA &82:LDA &8C:STA &83 JSR &181B \print bullet LDY #2:LDA #0:STA (&8B),Y \signal bullet inactive JMP &1C61 \loop to check next bullet \*** init egg block *** \entry: &70/1 = sprite addr \ &74 = timer countdown value before change of state (e.g. egg -> explosion) \ &78 = state: 1 for explosion or 2 for an egg 26:LDA #&80:STA &75:LDA #&10:STA &76 \first egg block @&1080 LDA #16:STA &77 \count 16 blocks 32:LDY #2:LDA (&75),Y:CMP #0:BNE &1D69 \block occupied LDA &78:STA (&75),Y \store timer LDA &74:INY:STA (&75),Y \store state INY:LDA &70:STA (&75),Y \store new INY:LDA &71:STA (&75),Y \scr addr LDY #0:LDA &72:STA (&75),Y \store eggx INY:LDA &73:STA (&75),Y LDY #10:LDA #&80:STA (&75),Y \old screen &80xx LDA &75:STA &82:LDA &76:STA &83 \transfer egg block to sprite ptr JMP &181B \print egg 69:LDA &75:CLC:ADC #16:STA &75 LDA &76:ADC #0:STA &76 \point to next block DEC &77:BNE &1D32 \loop till all blocks checked RTS \ *** countdown timer for egg or explosion *** 7B:LDA #&80:STA &75:LDA #&10:STA &76 \1st egg block &1080 LDA #16:STA &77 \count 16 blocks LDY #2:LDA (&75),Y:BEQ &1DEE \not active INY:LDA (&75),Y:SEC:SBC #1:STA (&75),Y \timer = timer -1 BNE &1DEE \not 0 yet DEY:LDA (&75),Y:CMP #1:BEQ &1DAA \status=1 CMP #2:BEQ &1DAA \status=2 SEC:SBC #1:STA (&75),Y:JMP &1DEE AA:LDY #10:LDA #&80:STA (&75),Y \old screen &80xx LDA &75:STA &82:LDA &76:STA &83 \egg block addr to &82/83 LDA &75:PHA:LDA &&76:PHA \preserve current block addr LDA &77:PHA \and timer JSR &181B \erase egg PLA:STA &77 \restore timer PLA:STA &66:PLA:STA &75 \and addr LDY #2:LDA (&75),Y:CMP #2:BEQ &1DDC \status=2 so do explosion LDA #0:STA (&75),Y \status=1 JMP &1DEE DC:LDA #0:STA (&75),Y LDY #0:LDA (&75),Y:STA &72 INY:LDA (&75),Y:STA &73:JSR &1EE6 \print explosion EE:LDA &75:CLC:ADC #16:STA &75 \point to next LDA &76:ADC #0:STA &76 \egg block DEC &77:BNE &1D87 \loop till egg blocks checked RTS PAGE &1E -------- \ *** fancy colours *** 00:LDA &200F:AND #15:BEQ &1E08 \change colour every 16th count RTS 08:LDA #0:STA &70 0C:LDA &200F:AND #&F0:LSRA:LSRA:LSRA:LSRA CLC:ADC &70:AND #3:PHA LDA #19:JSR oswrch \VDU 19, LDA &70:CLC:ADC #8:JSR oswrch \ ?&70+8, PLA:JSRoswrch \((count DIV 16)+?&70) AND 3 LDA #0:JSR oswrch:JSR oswrch:JSR oswrch INC &70:LDA &70:CMP #4:BNE &1E0C \loop till colours 8,9,10,11 are done LDA #19:JSR oswrch \VDU19, LDA &200F:LSRA:LSRA:LSRA:LSRA:AND #3 \ CLC:ADC #1:JSR oswrch \(?&200F DIV 16) AND 3 + 1 LDA #0:JSR oswrch:JSR oswrch:JSR oswrch RTS \ *** print hi score *** 64:LDA #31:JSR oswrch:LDA #14:JSR oswrch:LDA #0:JSR oswrch \VDU31,14,0 LDA &2490:STA &70:LDA &2491:STA &71 \hi score -> &70/71 JSR &21FC \print number LDA #17:JSR oswrch:LDA #7:JMP oswrch \COLOUR 7 \ *** VDU 19,2,X;0; *** 8A:LDA #19:JSR oswrch:LDA #2:JSR oswrch \VDU 19,2, TXA:JSR oswrch:LDA #0:JSR oswrch:JSR oswrch:JMP oswrch \X,0,0,0 A3:LDA &11E3:BEQ &1EB4 RTS B4:JSR &1FA7 \egg sound LDY #0:LDA (&8E),Y:CLC:ADC #4:STA &72 \birdx + 2 INY:LDA (&8E),Y:STA &73 \birdy LDA #3:STA &78 LDA #&4C:STA &70:LDA #&16:STA &71 \egg sprite @&164C JMP &1D26 \insert into egg block \ *** exploding egg/bird *** D8:LDY #0:LDA (&8E),Y:CLC:ADC #2:STA &72 \birdx + 2 INY:LDA (&8E),Y:STA &73 \birdy E6:LDA #50:STA &74 \timer LDA #1:STA &78 \egg status=1 LDA #&39:STA &70:LDA #&17:STA &71 \explosion sprite @&1739 JMP &1D26 \insert into block \ *** ship explosion *** F9:LDA #&00:STA &82:LDA #&0E:STA &83 \point to ship block PAGE &1F -------- 01:LDA #&80:STA &E0A \old addr =&80xx JSR &181B \erase ship LDA &E00:SBC #4:STA &73 \shipx-4 LDA #90:STA &74 \timer LDA #1:STA &78 \status LDA #&6B:STA &70:LDA #&17:STA &71 \explosion sprite @&176B JSR &1D26 LDA #7:JSR &1FC3 \do VDU19,0,7;0; LDX #20:JSR &22CE \delay JSR &2451 \explosion sound LDA #2:STA &200F LDA #90 45:LDX #13:JSR &22CE \delay INC &200F:PHA:JSR &1E00 \fancy colours PLA:SEC:SBC #1:BNE &1F45 RTS \ *** check if ship has collided with egg *** 58:LDA #&80:STA &70:LDA #&10:STA &71 \first egg block @&1080 STA &72 \count 16 eggs 62:LDY #2:LDA (&70),Y:CMP #2:BEQ &1F71 \get status CMP #3:BEQ &1F71 \1 if exploding JMP &1F8C \so loop to next block 71:LDA &E00:CLC:ADC #5 \shipx + 5 DEY:DEY:CMP (&70),Y:BCC &1F8C \without 5 pixels LDA (&70),Y:CLC:ADC #4 \get eggx + 4 CMP &E00:BEQ &1F8C \ PLA:PLA:PLA:PLA:RTS \collision 8C:LDA &70:CLC:ADC #16:STA &70 \point to next block LDA &71:ADC #0:STA &71 DEC &72:BNE &1F62 \loop till all eggs examined against ship RTS \ *** make level complete sound, data @&26F7 *** 9E:LDX #&F7:LDY #&26:LDA #7:JMP &1FB0 \ *** make egg sound, data @&270D *** A7:LDX #&0D:LDY #&27:LDA #7:JMP &1FB0 \ *** sound routine *** B0:CMP #7:BEQ &1FB7:JMP osword \A<>7 for e.g. defining envelope B7:PHA:LDA &11E4:BEQ &1FBF \if silence flag =0 make sound PLA:RTS \else just return BF:PLA:JMP osword \ *** VDU19,0,A;0; *** C3:PHA:LDA #19:JSR oswrch:LDA #0:JSR oswrch \VDU19,0, PLA:JSR oswrch \A, LDA #0:JSR oswrch:JSR oswrch:JSR oswrch:RTS \0,0,0 \ *** make bird swoop sound on channel A *** DE:CLC:ADC #&10:STA &2716 \add &10 to force sound LDX #&16:LDY #&27:LDA #7:JMP &1FB0 \ *** choose if bird will drop bullet *** ED:LDY #7:LDA (&8E),Y \get birdy AND #7:BNE &1FFF \not multiple of 8 LDA &FE44 \get a 'changing number' CMP #63:BCC &1FFF \exit if <=63 JSR &1BC5 \else init bird bullet FF:RTS PAGE &20 -------- 00:LDA #15:LDX #0:LDY #0:JMP osbyte \clear kbd 09:BRK \1st bird no in flight 0A:BRK \bird x dir +/-2 0B 0C 0D:BRK \no birds killed 0E:BRK \2nd bird no in flight 0F:BRK \delay for star backdrop 10:BRK \ level AND 1 11: 12: 13:JSR &2000 \clear kbd LDA #2:STA &200A \set bird dx = 0 STA &200D \no birds killed = 0 STA &2011 STA &200C LDA #31:STA &200E \bird count =31 LDA &248F:AND #1:STA &2010 \get (level AND 1) LDA #2:JSR &1FDE \bird swoop sound on ch2 LDA &2010:BEQ &2045 \even level so don't LDA #3:JSR &1FDE \do bird swoop sound on ch3 45:LDA #0:STA &2009 \bird to fly = 0 INC &2011 4D:INC &200F \inc star delay JSR &1E00 \change colours JSR &1ADC \check fire and pause JSR &1D7B \egg timer JSR &241F \check escape JSR &19D7 \move ship JSR &1ADC \check fire and pause again LDA #2:STA &2012 LDA &200F:AND #1:BEQ &2071:JMP &2807 \move stars every 2nd count 71:LDA &200D:JSR &22E3 \calc bird block address LDY #2:LDA (&8E),Y:BNE &208F \extant INC &200D \increase 1st bird no in flight LDA #2:JSR &1FDE \swoop next bird on ch2 LDA &200D:CMP #30:BNE &2071 \30 birds not killed yet JMP &216D \next level 8F:JSR &1A38 \bird flies down LDA &2463:BEQ &2098 \loop till dead flag is TRUE RTS \dead so return 98:JSR &1FED \choose rnd to see if bird will fire LDA #3:STA &2012 JSR &1C4D \check bullets JSR &1ADC \check fire and pause A6:LDA &2010:BEQ &20DB \even level LDA &200E:JSR &22E3 \calc bird block address LDY #2:LDA (&8E),Y:BNE &20C9 \extant DEC &200E \decrease 2nd bird no in flight LDA #3:JSR &1FDE \swoop next bird on ch3 LDA &200E:CMP #&FF:BNE &20A6 JMP &216D \next level C9:JSR &1A38 \bird flies down LDA &2463:BEQ &20D2 \dead = FALSE RTS \player killed D2:JSR &1FED \choose rnd to see if bird will fire JSR &1C4D \check bullets JSR &1ADC \check fire and pause DB:LDA &248F:CMP #6:BCC &20E5 \level <= 6 JSR &1C4D \check bullets E5:LDA &200F:AND #3:BEQ &20EF JMP &204D EF:LDA &2009:CMP &200D:BEQ &213D LDA &2010:BEQ &2104 \even level (easy) LDA &2009:CMP &200E:BEQ &213D PAGE &21 -------- 04:LDA &200A:JSR &22E3 \calc bird block address JSR &1ACA \change wing position LDY #2:LDA (&8E),Y:BEQ &213A \bird not present 13:LDY #0:LDA (&8E),Y:CLC:ADC &200A \birdx = birdx + dx CMP #6:BCC &2156 \birdx <= 6 so change dx CMP #144:BCS &2167 \birdx >= 144 so change dx LDA &8E:STA &82:LDA &8F:STA &83 \point to current bird block JSR &181B \print bird LDA &FE44:CMP #150:BCC &213A \rnd <= 150 JSR &1BC5 \init bullet 3A:JSR &1C4D \check bullets 3D:INC &2009:CMP #30:BEQ &2153 JSR &22E3 \calc bird block address LDY #2:LDA (&8E),Y:BEQ &213D \not present JMP &204D 53:JMP &2045 56:LDA &200A:CMP #2:BNE &2165 \dx=-2 LDA #-2:STA &200A \set dx=-2 JMP &2113 65:LDA #2:STA &200A \set dx=2 JMP &2113 \ *** next level! *** 6D:INC &248F \level = level + 1 LDA &248F:AND #1:BNE &217D \(level AND 1) <> 0 INC &E02 \award extra life after even level JSR &1F9E \make whacky sound 7D:LDA &248F:CMP #8:BNE &2189 \level <> 8 LDA #6:STA &248F \reset level to 6 89:JSR &2520 \set screen for next lot JMP &2013 \back to main loop \*** add A to score *** 8F:CLC:ADC &248B:STA &248B LDA &248C:CMP &2491:BCC &21CC BNE &21B3 LDA &2490:CMP &248B:BCC &21B3 JMP &21CC B3:LDA &248B:STA &2490 LDA &248C:STA &2491 \hiscore = score LDA #17:JSR oswrch:LDA #12:JSR oswrch \COLOUR 12 JSR &1E64 \print hi score CC:LDA #31:JSR oswrch:LDA #2:JSR oswrch:LDA #0:JSR oswrch \VDU31,2,0 LDA #17:JSR oswrch \COLOUR LDA #7:SEC:SBC &248F \7 - (score AND &FF) CLC:ADC #1:CMP #8:BNE &21EF \if colour=8 LDA #3 \then colour=3 EF:JSR oswrch LDA &248B:STA &70:LDA &248C:STA &71 FC:LDY #0 FE:LDX #0 PAGE &22 -------- 00:SEC:SBC &26DF,Y:STA &70 \subtract power of 10 LDA &71:INY:SBC &26DF,Y:STA &71 BCC &2217 \number's gone < 0 STA &71:INX:DEY:JMP &2200 17:DEY:LDA &70:ADC &26DF,Y:STA &70 \make no +ve again TXA:ORA #ASC"0":JSR &2237 \print digit INY:INY:CPY #8:BCC &21FE \loop till digits checked LDA &70:ORA #ASC"0":JSR &2237 LDA #ASC"0":JMP &2237 \add extra 0 on end of score 37:CMP #ASC"0":BNE &2240 \check if 0 LDA #ASC"O":JMP oswrch \if so substitute for O and print 40:JMP oswrch \ *** init player ship *** 43:LDA #0:STA &E10 \player bullet x =0 LDA #&80:STA &E1A \old screen addr =&80xx LDA #76:STA &E00 \player x =76 LDA #235:STA &E01 \player y =235 LDA #&07:STA &E04:LDA #&17:STA &E05 \player ship data @&1707 LDA #&00:STA &82 \point to player ship block LDA #&0E:STA &83 \in &82/83 JMP &181B \and print ship 7A:LDA #0:STA &E10 \set player bullet x =0 (not present) LDA #&80:STA &E1A \bullet address &80xx LDA #&F3:STA &E14:LDA #&16:STA &E15 \bullet sprite @&16F3 RTS \ *** set up mode 2 screen *** 8F:LDA #&21:STA &80:LDA #&26:STA &81 JSR &2307 \Mode 2 + off cursor data @&2621 JSR &2804 \print starry backdrop LDA #17:JSR oswrch \COLOUR LDA &E02:AND #7:JSR oswrch \ (lives AND 7) LDA &E02:CLC:ADC #ASC"0":JSR oswrch \print lives LDA #0:JSR &218F JSR &1E64 \print hi score LDA &248F:BEQ &22C9 AND #3:CLC:ADC #3:TAX:JMP &1E8A \change colour 2 C9:LDX #2:JMP &1E8A \colour 2 = black \ *** delay routine *** \ entry: X=arbitrary counter \ exit: AXY intact CE:PHA:TXA:PHA:TYA:PHA D3:LDA #0 D5:SEC:SBC #1:BNE &22D5:DEX:BNE &22D3 PLA:TAY:PLA:TAX:PLA:RTS \ *** calculate bird block *** \ entry: A=bird no \ exit: &8E/F= &E20 + A*16 E3:STA &8E:LDA #0:STA &8F LDA &8E ASLA:ROL &8F:ASLA:ROL &8F ASLA:ROL &8F:ASLA:ROL &8F STA &8E \*16 LDA #&20:CLC:ADC &8E:STA &8E LDA &8F:ADC #&0E:STA &8F \ + &E20 RTS PAGE &23 -------- \*** print text *** \entry: &80/81 point to text terminated by &FF \exit A and Y intact 07:PHA:TYA:PHA:LDY #0 0C:LDA (&80),Y:CMP #&FF:BNE &2316 \not &FF yet PLA:TAY:PLA:RTS 16:JSR oswrch:INY:JMP &230C \print and jump back into loop \ *** check if player bullet has hit bird *** 1D:BRK 1E:LDA #0:STA &231D LDA &E11:STA &70 \get bullet y in &70 CLC:ADC #8:STA &71 \bulletx+8 LDA #&20:STA &8E:LDA #&0E:STA &8F \first bird block @&E20 LDY #2:LDA (&8E),Y \get bird status BEQ &2347 \not present LDY #0:LDA (&8E),Y:CMP &E10 \get bird x and cf player bullet x BCS &2347 \its > than JMP &234A 47:JMP &23EA \next bird 4A:LDA #10:CLC:ADC (&8E),Y \add 10 to bird x CMP &E10:BCS &2357 \its > JMP &23EA \next bird 57:LDY #1:LDA (&8E),Y:CLC:ADC #6 \get bird y + 6 CMP &E11:BCS &2366 \it's > JMP &23EA \next bird 66:LDA (&8E),Y:CMP &71:BCS &2363 \bird y > bullet y + 6 LDA &8E:STA &82:LDA &83:STA &83 \bird block -> &82/83 LDY #0:STA (&8E),Y \signal bird now inactive LDY #10:LDA #&80:STA (&8E),Y \new bird address =&80xx JSR &181B \erase bird JSR &2000 \clear kbd LDA #&10:STA &82:LDA #&0E:STA &83 \set ptr to player bullet block LDA #&80:STA &E1A \new address =&80xx JSR &181B \erase bullet LDA &231D:CMP &200D:BEQ &23B6 LDA &2010:BEQ &23AB LDA &200E:CMP &231D:BEQ &23B6 AB:JSR &1ED8 \eggsplosion LDA #1:JSR &281F:JMP &23E2 \add 10 to score B6:LDA #&8A:STA &70:LDA #&16:STA &71 \'20' sprite @&168A LDY #0:LDA (&8E),Y:CLC:ADC #3:STA &72 \birdx + 20 INY:LDA (&8E),Y:SEC:SBC #6:STA &73 \birdy - 6 LDA #1:STA &78 \status=1=exploding JSR &1D26 \find free space in egg blocks LDA #2:JSR &218F \add 20 to score JSR &1ED8 \print E2:LDA #0:STA &E10 \signal player bullet inactive JMP &2424 EA:LDA &8E:CLC:ADC #16:STA &8E \ LDA &8F:ADC #0:STA &8F \point to next bird block INC &213D \increment count LDA &231D:CMP #30:BNE &2402 \loop till all birds checked RTS 02:JMP &2335 PAGE &24 -------- 02:JMP &2335 05:JSR osrdch \GET CMP #27:BEQ &240D \escape pressed RTS 0D:LDA #126:JSR osbyte \clear escape JMP &1800 \and start over 24:LDX #&A6:LDY #&26:LDA #7:JMP &1FB0 \killed bird sound @&26A6 \ *** define envelopes *** \ (could have been done with less hassle in a Basic loader) 2D:LDX #&AF:LDY #&26:LDA #8:JSR &1FB0 \env 1 LDX #&BE:LDY #&26:LDA #8:JSR &1FB0 \env 2 LDX #&E8:LDY #&26:LDA #8:JSR &1FB0 \env 3 LDX #&F1:LDY #&27:LDA #8:JMP &1FB0 \env 4 51:LDX #&0D:LDY #&26:LDA #7:JSR &1FB0 \player explodes sound @&260D LDX #&D6:LDY #&26:LDA #7:JMP &1FB0 \and &26D6 \ *** check to see if bird has hit player *** 63:BRK \dead flag 64:LDY #0:STY &2463 INY:LDA (&8E),Y \get bird y coord BPL &2489 \<128 so is nowhere near player CMP #232:BMI &2489 \above player and out of harm's way CMP #243:BPL &2489 \below player on screen DEY:LDA (&8E),Y \get x coord SEC:SBC &E00 \subtract player x coord CLC:ADC #10:CMP #17:BCS &2489 \not within 17 pixels of player x LDA #1:STA &2463 \within 17 pixels, set dead flag = 1 89:RTS 8A:EQUW 0 \current score 8F:BRK \colour cycle 90:EQUW 0 \hi score \ *** set keys and draw alternate title screen *** \ note this is never used! 92:LDA #12:LDX #0:LDY #0:JSR osbyte \autorepeat off LDA #0:STA &11E3:STA &11E4:STA &11E5 LDA #&9E:STA &11E0 \INKEY code for Z (-98) LDA #&BD:STA &11E1 \INKEY code for X (-67) LDA #ASC"?":STA &11E2 \fire key ASCII code LDA #&37:STA &80:LDA #&26:STA &81:JSR &2307 \text at &2637 JSR &2405 \check if escape pressed JSR &1803:JMP &24C0 \ *** zeroise score, define envelopes, init birds *** C9:LDY #0 LDA #&8A:STA &70:LDA #&24:STA &71 \&70/71=&248A LDX #6 D5:LDA #0:STA (&70),Y:INY:DEX:BNE &24D5 \zeroise score + level no JSR &242D \define envelopes LDA #3:STA &E02 \number of lives=3 JSR &2520 \initialise birds JMP &24FA EB:JSR &228F \set up mode 2 screen JSR &2589 \init egg data blocks JSR &2243 \init and print ship JSR &25B3 \init bird positions JSR &25F9 \print birds FA:JSR &2013 \main game routine \ routines that pull 2 addrs of stack (see &1C4D and &1F58) \ will return here where... PAGE &25 -------- 00:DEC &E02 \decrement lives BNE &24EB \until all lives lost JSR &2000 \clear kbd LDA #&2E:STA &80:LDA #&27:STA &81:JSR &2307 \game over message @&272E LDA &248B:STA &11E5:LDA &248C:STA &11E6 \copy score RTS 20:JSR &228F \set up mode 2 JSR &25D2 \set all birds present JSR &227A \init player bullet data block JSR &2589 \init egg data blocks JSR &25F9 \print birds LDA &248F:BEQ &2546 \don't pause on first level AND #1:BNE &2546 \don't pause on odd levels LDX #0:JSR &22CE:JSR &22CE:JSR &22CE:JSR &22CE \long pause 46:JMP &2243 \init player ship \ *** init a line of birds *** \ Entry: &70/71 contains address of bird block, &73=y coord of birds 49:LDX #6 \set up for 6 birds LDA #16:STA &74 \first bird on line at x=16 4F:LDY #0:LDA &74:STA (&70),Y \store x coord INY:LDA &73:STA (&70),Y \store y from &73 LDY #10:LDA #&80:STA (&70),Y \set old addr to &80xx LDA #1:LDY #14:STA (&70),Y \signal bird present LDY #4:LDA #&26:STA (&70),Y \set sprite INY:LDA #&15:STA (&70),Y \address to &1526 (bird data) LDA &70:CLC:ADC #16:STA &70 \point to next LDA &71:ADC #0:STA &71 \bird data block LDA &74:CLC:ADC #16:STA &74 \next bird 16 pixels to the right DEX:BNE &254F \loop until all bird attributes set RTS \ *** reset attributes in egg/explosion block *** 49:LDA #&00:STA &70:LDA #&10:STA &71 \first egg block @&1000 LDA #24:STA &72 \there can be up to 24 eggs on screen 95:LDY #2:LDA #0:STA (&70),Y \signal egg not present LDY #10:LDA #&80:STA (&70),Y \set old addr to &80xx LDA &70:CLC:ADC #16:STA &70 \point to next LDA &71:ADC #0:STA &71 \egg data block DEC &72:BNE &2595 \loop until all egg attributes set RTS \ *** init all lines of birds *** B3:LDA #&20:STA &70:LDA #&0E:STA &71 \first bird block @&0E20 LDA #5:STA &72 \5 lines of birds LDA #16:STA &73 \y coord of first line is 16 C3:JSR &2549 \print a line of birds LDA &73:CLC:ADC #12:STA &73 \next birds are 12 pixels down DEC &72:BNE &25C3 \loop till all lines printed RTS \ *** print birds and signify all present *** D2:JSR &25B3 \init birds LDA #&20:STA &70:LDA #&0E:STA &71 \first bird block @&0E20 LDA #30:STA &72 E1:LDY #2:LDA #1:STA (&70),Y \signal bird present LDA &70:CLC:ADC #16:STA &70 \point to next LDA &71:ADC #0:STA &71 \bird block DEC &72:BNE &25E1 \loop till all birds done RTS F9:LDA #&20:STA &82:LDA #&0E:STA &83 \first bird block @&E20 PAGE &26 -------- 01:LDA #30:STA &84 \count 30 birds 05:LDY #2:LDA (&82),Y:BEQ &260E \bird not present JSR &181B \print bird 0E:LDA &82:CLC:ADC #&10:STA &82 LDA &83:ADC #0:STA &83 \update pointer to next bird block DEC &84:BNE &2605 \loop till all birds printed RTS:RTS \ data for MODE 2 play screen and titles 21:EQUB 22,2, 31,10,0 \MODE 2:VDU 31,10,0 EQUS "HI:" EQUB 30, 23,0,10,32,0,0,0,0,0,0 \home cursor, cursor off EQUB 0,&FF \ data for alternative title screen, never actually seen! 37:EQUB 22,7, 10,10,10,130,141 EQUS STRING$(9," ")+"** SWOOP **"+STRING$(9," ") EQUB 10,13,130,141 EQUS STRING$(9," ")+"** SWOOP **"+STRING$(9," ") EQUB 10,10,10,10,13, 134 EQUS " Z left X right ? fire" EQUB 10,10,10,13 EQUS " Press SPACE to play." EQUB &FF \ sounds data A6:EQUW &10,1,6,16 \bird dead AF:EQUB 1,1,0,0,0,0,0,0,126,-1,-1,-1,126,100 \ENVELOPE 1 BE:EQUB 2,1,-1,-1,-1,65,65,70,1,0,0,0,1,1 \ENVELOPE 2 CD:EQUW &110,-15,7,30 \ D6:EQUW &111,2,200,30 \player dead DF:EQUW 10000,1000,100,10 \another tens table used at &218F E8:EQUB 3,1,-15,-15,-15,255,255,255,126,0,0,-126,126,100 \ENV.3 F7:EQUW &12,3,128,50 \level complete PAGE &27 -------- 0D:EQUW 1,3,140,2 \egg 16:EQUW &12,4,175,65 \bird swooping 1F:EQUB 4,6,-1,-1,-1,80,80,96,126,-2,0,-1,90,40 \ENVELOPE 4 \ GAME OVER message 2E:EQUB 31,5,14 EQUS "Game Over" EQUB &FF \hi score names and scores \1st 14 bytes is name + CR, last 2 bytes is score \(divided by 10 since extra 0 always printed) 80:EQUS "David Elliot ":EQUB 13:EQUW 578 \hi score of 5780 90:EQUS STRING$(16,CHR$0) A0:EQUS STRING$(16,CHR$0) B0:EQUS STRING$(16,CHR$0) C0:EQUS STRING$(16,CHR$0) D0:EQUS STRING$(16,CHR$0) PAGE &28 -------- 00:EQUB 33 \change this to any number <>33 for the alternate title scr 01:JMP &280C 04:JMP &299A \not used (move backdrop) 07:JMP &29CA \not used (move stars) 0A:EQUB 31 \number of stars in backdrop 0C:LDA #0:STA &11E3:STA &11E4 \set silence flag = FALSE LDA #&96:STA &11E0 \INKEY code for Z LDA #&BD:STA &11E1 \INKEY code for X LDA #&2F:STA &11E2 \ASCII code for ? 23:JSR &2A73 \go into mode 7 JSR &2853 \draw mode 7 scr 29:JSR &1803 \ -> &24C9 -> main game JSR &28F1:CMP #5:BEQ &284A \check hi score for place in table 33:JSR &2B41 \clear kbd LDA #&66:STA &80:LDA #&2B:STA &81 JSR &2A35 \print 'You are in the top 5' JSR &2977 \input player name JSR &2A59 \check loc &FF for Escape JMP &2823 \until the cows come home \not in the top 5 4A:JSR &2B41 \clear kbd JSR &2A49 \get a key JMP &2829 \until the cows come home \ *** draw mode 7 scr *** 53:LDA #0:STA &70:STA &72 \&70/71=&7C00 and &72/73=&2C00 LDA #&7C:STA &71:LDA #&2C:STA &73 LDA #&FF:STA &74:LDA #4:STA &75:LDY #0 6B:LDA (&72),Y:STA (&70),Y INC &70:BNE &2875:INC &71 \scr=scr+1 75:INC &72:BNE &287B:INC &73 \dat=dat+1 7B:DEC &74:BNE &286B:DEC &75:BNE &286B \loop till 4 pages done \ print hi score table 83:LDA #0 85:PHA:JSR &2A9A \print a hi score PLA:CLC:ADC #1:CMP #5:BNE &2885 \until all 5 done \ check Y/N keypress for sound options LDA &11E4:BEQ &28B1:JMP &28C4 \check sound flag 99:JSR &2A49 \get keypress CMP #ASC"Y":BEQ &28B1:CMP #ASC"y":BEQ &28B1 \Y or y? CMP #ASC"N":BEQ &28C4:CMP #ASC"n":BEQ &28C4 \N or n? CMP #32:BNE &2899 \spacebar not pressed so loop back to &2899 B1:LDA #&4A:STA &80:LDA #&2B:STA &81 \YES message at &284A JSR &2A33 \print that message LDA #0:STA &11E4:JMP &2899 \set sound flag FALSE and jump back C4:LDA #&52:STA &80:LDA #&2B:STA &81:JSR &2A33 \NO message at &2852 LDA #1:STA &11E4:JMP &2899 \set sound flag TRUE and jump back \ *** clear name in hi score table *** \ &8E/F point to data of position in table D7:LDA #0:PHA:JSR &2A7E LDA #0:LDY #0 E1:STA (&8E),Y:INY:CPY #16:BNE &28E1 PLA:CLC:ADC #1:CMP #5:BNE &28D9:RTS \ *** check score against those in table *** F1:LDA #&80:STA &70:LDA #&27:STA &71 \&70/71=&2780 LDA #0:STA &72:LDY #15:LDA &11E6 PAGE &29 -------- 02:CMP (&70),Y:BEQ &2918:BCS &2922 08:LDA &70:CLC:ADC #16:STA &70 \next position INC &72:LDA &72:CMP #5:BNE &28FD \loop till score >= hi byte in table RTS \or 5th place reached 18:DEY:LDA &11E5 CMP (&70),Y:BEQ &2908:BCC &2908 \low byte of score <= lo in table 22:JSR &2935 \ LDY #15:LDA &11E6:STA (&70),Y \store hi byte of score DEY:LDA &11E5:STA (&70),Y \store lo byte LDA #0:RTS 35:LDA &72:CMP #4:BEQ &2966:STA &73:LDA #4 3F:PHA:JSR &2A7E LDA &8E:STA &8C:LDA &8F:STA &8D \copy from position in &8D/E PLA:PHA:SEC:SBC #1:JSR &2A7E \to pos in &8E/F LDY #0 55:LDA (&8E),Y:STA (&8C),Y \move scores down 1 position INY:CPY #16:BNE &2955 PLA:SEC:SBC #1:CMP &72:BNE &293F 66:LDA &72:JSR &2A7E LDY #0:LDA #20 6F:STA (&8E),Y INY:CPY #14:BNE &296F:RTS \ *** set up buffer for typing name *** 77:LDA &72:JSR &2A7E LDA &8E:STA &78:LDA &8F:STA &79 \buffer pointed to by &78/79 LDA #13:STA &7A \max chars allowed is 13 LDA #32:STA &7B \min ascii char allowed is 32 LDA #127:STA &7C \max ascii char is 127 LDA #0:LDX #&78:LDY #0 \set up registers JSR osword:RTS \call OSWORD 0 to input chars \ *** print starry backdrop *** 9A:LDA #&A0:STA &70:LDA #&2B:STA &71 \&70/71=&2BA0 LDA &280A:STA &72 \number of stars LDY #0:LDA (&70),Y:STA &73 \star's address on mode 2 INY:LDA (&70),Y:STA &74 \screen in &73/74 INY:LDA (&70),Y:STA &75 \pixel value A7:LDY #0:LDA (&73),Y:EOR &75:STA (&73),Y \put star on screen INC &70:INC &70:INC &70 \point to next address and value DEC &72:BNE &29A7:RTS \loop until all stars done then return \ *** move starry backdrop *** CA:LDA #&A0:STA &70:LDA #&2B:STA &71 \&70/71=&28A0 LDA &280A:STA &72 \number of stars D7:LDY #0:LDA (&70),Y:STA &73: \get INY:LDA (&70),Y:STA &74 \star's address INY:LDA (&70),Y:STA &75 \pixel value LDY #0:LDA (&73),Y:EOR &75:STA (&73),Y \EOR it to screen LDA &73:AND #7:CMP #7 \bottom of char row? BEQ &2A00 \yes INC &73:BCC &2A0D:INC &74 \no, just add 1 to scr addr JMP &2A0D \and continue PAGE &2A -------- \ *** scroll starry backdrop cont'd *** 00:LDA &73:CLC:ADC #&79:STA &73 LDA &74:ADC #2:STA &74 \scr=scr+&279 0D:LDA &74:CMP #&80 \check hi byte of screen BCC &2A17 \less than &8000 so still on screen SBC #&4E:STA &74 \wrap round to top of screen 17:LDY #0:LDA (&73),Y:EOR &75:STA (&73),Y LDA &73:STA (&70),Y \put pixel value back in table INC &70:INC &70:INC &70 \point to next addr and value DEC &72:BNE &29D7:RTS \loop till all stars done and return \ *** message print *** \ Entry: &80/81 point to text terminated by &FF. \ Exit: A and Y preserved 33:PHA:TYA:PHA:LDY #0 38:LDA (&80),Y:CMP #&FF:BNE &2A42 \not yet &FF PLA:TAY:PLA:RTS \restore and return 42:JSR oswrch:INY:JMP &2A38 \print it and jump back into loop \ *** get a key, eq of GET in Basic *** 49:JSR osrdch:CMP #27 \escape? BEQ &2A51 \yes, deal with it RTS \no, return with value in A 51:LDA #126:JSR osbyte:JMP &1800 \clear escape and start over \ *** check location &FF *** \ will be -ve if Escape pressed 59:LDA &FF:BMI &2A51:RTS \branch to routine which clears escape \ *** delay routine *** \ Entry: X=arbitrary counter \ Exit: A X and Y preserved 5E:PHA:TXA:PHA:TYA:PHA \preserve AXY 63:LDA #0 65:SEC:SBC #1:BNE &2A65 DEX:BNE &2A63 PLA:TAY:PLA:TAX:PLA:RTS \restore and return \ *** do MODE 7 *** 73:LDA #&5A:STA &80:LDA #&2B:STA &81 \&2B5A contains 22,7, JMP &2A33 \do MODE 7 via message routine \ check position in hi score table 7E:CMP #5:BCC &2A8B \A<5 \ set pointer to '6th' position LDA #&D0:STA &8E:LDA #&27:STA &8F \&27D0 addr of 6th hi name RTS \ *** calculate address of hiscore name *** \ Entry: A=rank of hi name required 8B:ASLA:ASLA:ASLA:ASLA ADC #&80:STA &8E:LDA #&27:STA &8F \&2780 + A*16 RTS \ *** print a high score *** 99:BRK \workspace 9A:STA &2A99 \store rank temporarily JSR &2A7E \is it in '6th' place? A0:LDA #31:JSR oswrch:LDA #3:JSR oswrch \ LDA #15:CLC:ADC &2A99:JSR oswrch \VDU 31,3,15+rank LDY #0 B5:LDA (&8E),Y:JSR oswrch \get char from hi name CMP #13:BEQ &2AC3 \CR is end of hi name INY:CPY #14:BNE &2AB5 \loop till 14 chars of name printed C3:LDA #31:JSR oswrch:LDA #18:JSR oswrch \ LDA &2A99:CLC:ADC #15:JSR oswrch \VDU 31,18,15+rank LDY #14:LDA (&8E),Y:STA &70 \put score in &70/71 INY:LDA (&8E),Y:STA &71 LDA &70:ORA &71:BEQ &2AEA JSR &2AEE EA:LDA &2A99 RTS \ *** print 16bit number with leading spaces *** \ Entry: &70/71 contain number EE:LDY #0 LDA #1:STA &72 \set leading zero as true initially F4:LDA #0 F6:LDA &70:SEC:SBC &2B5D,Y:STA &70 \subtract power of ten from table LDA &71 PAGE &2B -------- 00:INY:SBC &2B5D,Y:BCC &2B0D STA &71:INX:DEY:JMP &2AF6 0D:DEY:LDA &70:ADC &2B5D,Y:STA &70 \restore to +ve JSR &2B28 \print digit INY:INY:CPY #8:BCC &2AF4 LDX &70:JSR &2B28 LDA #&30:JMP oswrch \add extra 0 after number 28:TXA:CMP #0:BNE &2B36 \is digit 0? LDA &72:BEQ &2B3C \leading space flag=0 if first non0 printed LDA #32:JMP oswrch \print leading space 36:PHA: LDA #0:STA &72 \leading space = FALSE now non0 number has been printed PLA:ORA #&30:JMP oswrch \ *** clear keyboard buffer *** 41:LDA #15:LDX #0:LDY #0:JMP osbyte \ YES message (see &28B1) 4A:EQUB 31,32,22 EQUS "YES" EQUB 30,&FF \ NO message (see &28C4) 52:EQUB 31,32,22 EQUS "NO " EQUB &30,&FF \ VDU 22,7 data (see &2B73) EQUB 22,7,&FF \ powers of tens table 5D:EQUW 10000,1000,100,10 \ message inviting player to enter name 66:EQUB 31,0,16 EQUS "You are in the TOP" EQUB 10,10,13 EQUS "FIVE" EQUB 10,10,13 EQUS "Name?" EQUB 8, 23,0,10,103,0,0,0,0,0,0 \backspace + cursor on EQUB 0,&FF \ data for starry backdrop \ there are 31 stars, the number held at &280A \ each item of data comprises a mode 2 address and a pixel value \ see &299A (set up stars) and &29CA (move stars) A0:EQUW &42A8:EQUB 21 EQUW &4E53:EQUB 21 EQUW &3F60:EQUB 21 EQUW &5712:EQUB 21 EQUW &4DBC:EQUB 21 EQUW &4B91:EQUB 21 EQUW &49C4:EQUB 21 EQUW &6417:EQUB 21 EQUW &5A41:EQUB 21 EQUW &68BC:EQUB 21 EQUW &52C5:EQUB 21 EQUW &6FA3:EQUB 21 EQUW &4D30:EQUB 21 EQUW &69EC:EQUB 21 EQUW &7491:EQUB 21 EQUW &59B6:EQUB 21 EQUW &6320:EQUB 21 EQUW &7137:EQUB 21 EQUW &3A86:EQUB 21 EQUW &775E:EQUB 21 EQUW &4D69:EQUB 21 EQUW &3A2A:EQUB 21 EQUW &3E34:EQUB 21 EQUW &6D62:EQUB 21 EQUW &4F05:EQUB 21 EQUW &6734:EQUB 21 EQUW &7345:EQUB 21 EQUW &6D65:EQUB 21 EQUW &4098:EQUB 21 EQUW &3E25:EQUB 21 EQUW &6693:EQUB 21 PAGE &28 -------- 00:150,154, 02:EQUS " " 28:EQUB 150,154,160,240,240,160,146,224,240,160, 32:EQUS " " 34:EQUB 224,240,145, 37:EQUS " " 39:EQUB 224,240,176, 3C:EQUS " " 3E:EQUB 148, 3F:EQUS " " 41:EQUB 240,240, 43:EQUS " " 45:EQUB 147,240,240,240,176, 4A:EQUS " " 50:EQUB 154,150,254,191,175,253,146,234,255,160, 5A:EQUS " " 5C:EQUB 234,255,145, 5F:EQUS " " 60:EQUB 248,255,175,255,244,148, 66:EQUS " " 67:EQUB 224,254,191,239,253,176,147,255,191,175,239,253,176, 74:EQUS " " 78:EQUB 150,154,255,181, 7C:EQUS " " 7D:EQUB 162,146,234,255, 81:EQUS " " 82:EQUB 224, 83:EQUS " " 84:EQUB 234,255,145,232,255, 89:EQUS " " 8B:EQUB 162,255,180,148,254,183, 91:EQUS " " 92:EQUB 160,235,253,147,255,181,160, 99:EQUS " " 9A:EQUB 255,181, 9C:EQUS " " A0:EQUB 150,154,171,255,244,160,146,234,255,232,255,253,234,255,145,234,255, B1:EQUS " " B4:EQUB 255,181,148,255,181, B9:EQUS " " BB:EQUB 234,255,147,255,253,252,254,191,161, C4:EQUS " " C8:EQUB 150,154, CA:EQUS " " CB:EQUB 162,239,253,146,234,255,255,183,255,255,255,145,234,255, D9:EQUS " " DC:EQUB 255,181,148,255,181, E1:EQUS " " E3:EQUB 234,255,147,255,183,163,161, EA:EQUS " " F0:EQUB 154,150,244, F3:EQUS " " F4:EQUB 234,255,146,234,255,191,160,170,255,255,145,162,255,244, 02:EQUS " " 03:EQUB 248,255,161,148,235,253,176,224,254,183,147,255,181, 10:EQUS " " 18:EQUB 150,154,171,255,255,167,146,234,255,161,160, 23:EQUS " " 24:EQUB 235,255,145, 27:EQUS " " 28:EQUB 162,239,255,191,161, 2D:EQUS " " 2E:EQUB 148,160,171,255,255,167, 34:EQUS " " 35:EQUB 147,255,181, 38:EQUS " " 43:EQUB 160, 44:EQUS " " 4D:EQUB 160, 4E:EQUS " " 5D:EQUB 160, 5E:EQUS " " 68:EQUB 131, 69:EQUS " Z=left X=right ?=fire P=pause. " B8:EQUB 134, B9:EQUS " Watch out for the exploding eggs. " 08:EQUB 132,157, 0A:EQUS " " 0B:EQUB 130,135, 0D:EQUS " ** Top Five ** " 21:EQUB 131, 22:EQUS "Written by " 2D:EQUB 156, 2E:EQUS " " 30:EQUB 148,255,130, 33:EQUS " Name: Score:" 48:EQUB 132,157,132,157, 4C:EQUS " " 55:EQUB 156, 56:EQUS " " 58:EQUB 148,255,131, 5B:EQUS " " 70:EQUB 132,157,134, 73:EQUS " David " 7D:EQUB 156, 7E:EQUS " " 80:EQUB 148,255,130, 83:EQUS " " 98:EQUB 132,157,134, 9B:EQUS " Elliot " A5:EQUB 156, A6:EQUS " " A8:EQUB 148,255,130, AB:EQUS " " C0:EQUB 132,157,131, C3:EQUS " " CD:EQUB 156, CE:EQUS " " D0:EQUB 148,255,130, D3:EQUS " " E8:EQUB 132,157,131, EB:EQUS " Elliot " F5:EQUB 156, F6:EQUS " " F8:EQUB 148,255,130, FB:EQUS " " 10:EQUB 132,157,131, 13:EQUS "Software " 1D:EQUB 156, 1E:EQUS " " 20:EQUB 132,157,130, 23:EQUS " " 45:EQUB 156, 46:EQUS " " 48:EQUB 131,157,129, 4B:EQUS " Copyright 1982 Program Power " 6D:EQUB 156, 6E:EQUS " " 70:EQUB 129,157,131, 73:EQUS "Do you want sound (Y/N)? = " 95:EQUB 156, 96:EQUS " " 98:EQUB 130,157,136,132, 9C:EQUS " Press SPACE to play. " BD:EQUB 156, BE:EQUS " " D3:EQUB 160, D4:EQUS " "