processor 6502 ;Default 2600 Constants set up by dissasembler.. VSYNC = $00 VBLANK = $01 WSYNC = $02 RSYNC = $03 NUSIZ0 = $04 NUSIZ1 = $05 COLUP0 = $06 COLUP1 = $07 COLUPF = $08 COLUBK = $09 CTRLPF = $0A PF0 = $0D PF1 = $0E PF2 = $0F RESP0 = $10 AUDC0 = $15 AUDF0 = $17 AUDV0 = $19 AUDV1 = $1A GRP0 = $1B GRP1 = $1C ENAM0 = $1D ENAM1 = $1E ENABL = $1F HMP0 = $20 VDEL01 = $26 HMOVE = $2A HMCLR = $2B CXCLR = $2C CXP0FB = $32 CXP1FB = $33 CXM0FB = $34 CXM1FB = $35 CXBLPF = $36 CXPPMM = $37 INPT4 = $3C SWCHA = $0280 SWCHB = $0282 INTIM = $0284 TIM64T = $0296 ORG $F000 START: JMP StartGame ;Jump To Start Game ;3 ;Alternate Start .byte $78,$D8,$4C,$06,$F3 ;Setup for 6507, Start with no Variable Initialisation. ;Print Display PrintDisplay: STA HMCLR ;Clear horzontal motion. ;3 LDA $86 ;Position Player00 Sprite To ;3 LDX #$00 ; the X Coordinate of Object1. ;2 JSR PosSpriteX ;6 LDA $88 ;Position Player01 Sprite to ;3 LDX #$01 ; the X Coordinate of Object2. ;2 JSR PosSpriteX ;6 LDA $8B ;Position Ball Strite to ;3 LDX #$04 ; the X Coordinate of the Man. ;2 JSR PosSpriteX ;6 STA WSYNC ;Wait for horizontal Blank. ;3 STA HMOVE ;Apply Horizontal Motion. ;3 STA CXCLR ;Clear Collision Latches. ;3 LDA $8C ;Get the Y Coordinate of the Man. ;3 SEC ;2 SBC #$04 ;And Adjust it (By Four Scan Lines) ;2 STA $8D ; for printing (so Y Coordinate Specifies Middle) ;3 PrintDisplay_1: LDA INTIM ;Wait for end of the ;4 BNE PrintDisplay_1 ; current fame. ;2 LDA #$00 ;2 STA $90 ;Set Player00 definition index. ;3 STA $91 ;Set Player01 definition index. ;3 STA $8F ;Set room definition index. ;3 STA GRP1 ;Clear any graphics for Player01. ;3 LDA #$01 ;2 STA VDEL01 ;vertically delay Player 01 ;3 LDA #$68 ;2 STA $8E ;Set Scan Lind Count. ;3 ;Print top line of Room. LDY $8F ;Get room definition index. ;3 LDA ($80),Y ;Get first room definition byte. ;5 STA PF0 ; and display. ;3 INY ;2 LDA ($80),Y ;Get Next room definition byte. ;5 STA PF1 ; and display. ;3 INY ;2 LDA ($80),Y ;Get Last room defintion byte. ;5 STA PF2 ; and display. ;3 INY ;2 STY $8F ;Save for Next Time. ;3 STA WSYNC ;Wait for Horizontal Blank. ;3 LDA #$00 ;2 STA VBLANK ;Clear any Vertical Blank. ;3 JMP PrintPlayer00 ;3 ;Print Player01 (Object 02) PrintPlayer01: LDA $8E ;Get Current Scan Line. ;3 SEC ;Have we reached Object2's ;2 SBC $89 ; Y Coordinate? ;3 STA WSYNC ; Wait for Horzonal Blank. ;3 BPL PrintPlayer00 ;If Not, Branch. ;2 LDY $91 ;Get the Player01 definition index. ;3 LDA ($84),Y ;Get the Next Player01 Definition byte ;5 STA GRP1 ; and display. ;3 BEQ PrintPlayer00 ;If Zero then Definition finished. ;2 INC $91 ;Goto next Player01 definition byte. ;5 ;Print Player00 (Object01), Ball (Man) and Room. PrintPlayer00: LDX #$00 ;2 LDA $8E ;Get the Current Scan Line. ;3 SEC ;Have we reached the Object1's ;2 SBC $87 ; Y coordinate? ;3 BPL PrintPlayer00_1 ;If not then Branch. ;2 LDY $90 ;Get Player00 definition index. ;3 LDA ($82),Y ;Get the Next Player00 definition byte. ;5 TAX ;2 BEQ PrintPlayer00_1 ;If Zero then Definition finished. ;2 INC $90 ;Go to Next Player00 definition byte. ;5 PrintPlayer00_1: LDY #$00 ;Disable Ball Graphic. ;2 LDA $8E ;Get Scan line count. ;3 SEC ;Have we reached the Man's ;2 SBC $8D ; Y Coordinate? ;3 AND #$FC ;Mask value to four either side (getting depth of 8) ;2 BNE PrintPlayer00_2 ;If Not, Branch. ;2 LDY #$02 ;Enable Ball Graphic. ;2 PrintPlayer00_2: LDA $8E ;Get Scan Line Count. ;3 AND #$0F ;Have we reached a sixteenth scan line. ;2 BNE PrintPlayer00_4 ;If not, Branch. ;2 STA WSYNC ;Wait for Horzontal Blank. ;3 STY ENABL ;Enable Ball (If Wanted) ;3 STX GRP0 ;Display Player 00 definition byte (if wanted) ;3 LDY $8F ;Get room definition index. ;3 LDA ($80),Y ;Get first room definition byte, ;5 STA PF0 ; and display. ;3 INY ;2 LDA ($80),Y ;Get next room definition byte, ;5 STA PF1 ; and display. ;3 INY ;2 LDA ($80),Y ;Get next room definition byte, ;5 STA PF2 ; and display. ;3 INY ;2 STY $8F ;Save for Next Time. ;3 PrintPlayer00_3: DEC $8E ;Goto next scan line. ;5 LDA $8E ;Get the scan line. ;3 CMP #$08 ;Have we reached to within 8 scanlines of the bottom? ;2 BPL PrintPlayer01 ;If not, Branch. ;2 STA VBLANK ;Turn on VBLANK ;3 JMP TidyUp ;3 ;Print Player00 (Object 01) and Ball (Man) PrintPlayer00_4: STA WSYNC ;Wait for Horzontal blank. ;3 STY ENABL ;Enable Ball (If Wanted.) ;3 STX GRP0 ;Display Player00 definition byte (if Wanted). ;3 JMP PrintPlayer00_3 ;3 ;Tidy Up TidyUp: LDA #$00 ;2 STA GRP1 ;Clear any graphics for Player01 ;3 STA GRP0 ;Clear any graphics for Player00 ;3 LDA #$20 ;2 STA TIM64T ;Stat Timing this frame using ;4 RTS ; the 64 bit counter. ;6 ;Position Sprite X horizontally. PosSpriteX: LDY #$02 ;Start with 10 clock cycles (to avoid HBLANK) ;2 SEC ;Divide the Coordinate. ;2 PosSpriteX_1: INY ; Wanted by Fifteen I.E. ;2 SBC #$0F ; Get Course Horizontal ;2 BCS PosSpriteX_1 ; Value (In Multiples of 5 Clock Cycles ;2 ; (Therefore giving 15 Color Cycles) EOR #$FF ;Flip remanter to positive value (inverted). ;2 SBC #$06 ;Convert to left or right of current position. ;2 ASL ;2 ASL ;Move to high nybble for TIA ;2 ASL ; horizontal motion. ;2 ASL ;2 STY WSYNC ;Wait for horozontal blank. ;3 PosSpriteX_2: DEY ;Count down the color ;2 BPL PosSpriteX_2 ; cycles (these are 5 machine/15 color cycles). ;2 STA RESP0,X ;Reset the sprite, thus positioning it coursely. ;4 STA HMP0,X ;Set horizontal (fine) motion of sprite. ;4 RTS ;6 ;Preform VSYNC DoVSYNC: LDA INTIM ;Get Timer Output ;4 BNE DoVSYNC ;Wait for Time-Out ;2 LDA #$02 ;2 STA WSYNC ;Wait for horizonal blank. ;3 STA VBLANK ;Start Vertical Blanking. ;3 STA WSYNC ;Wait for horizonal blank. ;3 STA WSYNC ;Wait for horizonal blank. ;3 STA WSYNC ;Wait for horizonal blank. ;3 STA VSYNC ;Start verticle sync. ;3 STA WSYNC ;Wait for horizonal blank. ;3 STA WSYNC ;Wait for horizonal blank. ;3 LDA #$00 ;2 STA WSYNC ;Wait for horizonal blank. ;3 STA VSYNC ;End Vertical sync. ;3 LDA #$2A ;Set clock interval to ;2 STA TIM64T ;Countdown next frame. ;4 RTS ;6 ;Setup a room for print. SetupRoomPrint: LDA $8A ;Get current room number. ;3 JSR RoomNumToAddress ;Convert it to an address. ;6 LDY #$00 ;2 LDA ($93),Y ;Get low pointer to room ;5 STA $80 ; Graphics ;3 LDY #$01 ;2 LDA ($93),Y ;Get high pointer to room ;5 STA $81 ; Graphics ;3 ;Check B&W Switch for foom graphics. LDA SWCHB ;Get console switches. ;4 AND #$08 ;Check black and white switch ;2 BEQ UseBW ;Branch if B&W. ;2 ;Use Color LDY #$02 ;2 LDA ($93),Y ;Get room color ;5 JSR ChangeColor ;Change if necessary ;6 STA COLUPF ;Put in Playfiled color register. ;3 JMP UseColor ;3 ;Use B&W UseBW: LDY #$03 ;2 LDA ($93),Y ;Get B&W Color ;5 JSR ChangeColor ;Change if necessary ;6 STA COLUPF ;Put in the Playfield color register. ;3 ;Color Background. UseColor: LDA #$08 ;Get light grey background ;2 JSR ChangeColor ;Change if necessary ;6 STA COLUBK ;Put it in the Background color register. ;3 ;Playfield Control. LDY #$04 ;2 LDA ($93),Y ;Get the playfield control value. ;5 STA CTRLPF ;And put in the playfield control register. ;3 AND #$C0 ;Get the "this wall" flag. ;2 LSR ;2 LSR ;2 LSR ;Get the first bit into position. ;2 LSR ;2 LSR ;2 STA ENAM1 ;Enable right hand thin wall. (if wanted - missile01) ;3 LSR ;2 STA ENAM0 ;Enable left hand thin wall (if wanted - missle00) ;3 ;Get objects to display. JSR CacheObjects ;Get next two objects to display. ;6 ;Sort out their order. LDA $95 ;If the object1 is the ;3 CMP #$00 ;Invisible surround ;2 BEQ SwapPrintObjects ;Then branch to swap (we want it as player01) ;2 CMP #$5A ;If the first object is the bridge then ;2 BNE SetupObjectPrint ;Swap the objects (we want it as player01) ;2 LDA $96 ;If the object2 is the ;3 CMP #$00 ;Invisble surround then branch to leave ;2 BEQ SetupObjectPrint ;it (we want it as player01) ;2 SwapPrintObjects: LDA $95 ;3 STA $D8 ;3 LDA $96 ;3 STA $95 ;Swap the objects to print. ;3 LDA $D8 ;3 STA $96 ;3 ;Setup Object1 to print. SetupObjectPrint: LDX $95 ;Get Object1 ;3 LDA Store1,X ;Get low pointer to it's dynamic information. ;4 STA $93 ;3 LDA Store2,X ;Get high pointer to it's dynamic informtion. ;4 STA $94 ;3 LDY #$01 ;2 LDA ($93),Y ;Get Object1's X coordinate ;5 STA $86 ;and Store for print. ;3 LDY #$02 ;2 LDA ($93),Y ;Get Object1's Y coordinate ;5 STA $87 ;and Store for print. ;3 LDA Store3,X ;Get low pointer to state value. ;4 STA $93 ;3 LDA Store4,X ;Get high pointer to state value. ;4 STA $94 ;3 LDY #$00 ;2 LDA ($93),Y ;Retrieve Object1's current state. ;5 STA $DC ;3 LDA Store5,X ;Get low pointer to state information. ;4 STA $93 ;3 LDA Store6,X ;Get high pointer to state information. ;4 STA $94 ;3 JSR GetObjectState ;Find current state in the state information. ;6 INY ;Index to the state's corresponding graphic pointer. ;2 LDA ($93),Y ;Get Object1's low graphic address ;5 STA $82 ;and store for print. ;3 INY ;2 LDA ($93),Y ;Get Object1's high graphic address ;5 STA $83 ;and store for print. ;3 ;Check B&W for object01 LDA SWCHB ;Get console switches ;4 AND #$08 ;Check B&W switches. ;2 BEQ MakeObjectBW ;Branch if B&W. ;2 ;Colour LDA Store7,X ;Get Object1's Color. ;4 JSR ChangeColor ;Change if necessary. ;6 STA COLUP0 ;And set color luminance00. ;3 JMP ResizeObject ;3 ;B&W MakeObjectBW: LDA Store8,X ;Get Object's B&W Color. ;4 JSR ChangeColor ;Change if necessary. ;6 STA COLUP0 ;Set color luminance00. ;3 ;Object1 Size ResizeObject: LDA Store9,X ;Get Object1's Size ;4 ORA #$10 ;And set to larger size if necessary. ;2 STA NUSIZ0 ;(Used by bridge and invisible surround) ;3 ;Setup Object 2 to Print. LDX $96 ;Get Object 2 ;3 LDA Store1,X ;4 STA $93 ;Get low pointer to it's dynamic information. ;3 LDA Store2,X ;4 STA $94 ;Get high pointer to it's dynamic information. ;3 LDY #$01 ;2 LDA ($93),Y ;Get Object2's X coordinate ;5 STA $88 ;and store for print. ;3 LDY #$02 ;2 LDA ($93),Y ;Get Object2's Y coordinate ;5 STA $89 ;and store for print. ;3 LDA Store3,X ;Get low pointer to state value. ;4 STA $93 ;3 LDA Store4,X ;Get high pointer to state value. ;4 STA $94 ;3 LDY #$00 ;2 LDA ($93),Y ;Retrieve Object2's current state. ;5 STA $DC ;3 LDA Store5,X ;Get low pointer to state information. ;4 STA $93 ;3 LDA Store6,X ;Get high pointer to state information. ;4 STA $94 ;3 JSR GetObjectState ;Find the current state in the state information. ;6 INY ;Index to the state's corresponding graphic pointer. ;2 LDA ($93),Y ;5 STA $84 ;Get Object2's low graphic address. ;3 INY ;2 LDA ($93),Y ;Get Object2's high graphic address. ;5 STA $85 ;3 ;Check B&W for Object2 LDA SWCHB ;Get Console Switches ;4 AND #$08 ;Check B&W Switch. ;2 BEQ MakeObject2BW ;If B&W then Branch. ;2 ;Color LDA Store7,X ;Get Object2;s Color ;4 JSR ChangeColor ;Change if Necessary. ;6 STA COLUP1 ;and set color luminance01. ;3 JMP ResizeObject2 ;3 ;B&W MakeObject2BW: LDA Store8,X ;Get Object's B&W Color. ;4 JSR ChangeColor ;Change if Necessary. ;6 STA COLUP1 ;and set color luminance01. ;3 ;Object2 Size ResizeObject2: LDA Store9,X ;Get Object2's Size ;4 ORA #$10 ;And set to larger size if necessary. ;2 STA NUSIZ1 ;(Used by bridge and invisible surround) ;3 RTS ;6 ;Fill cache with two objects in this room. CacheObjects: LDY $9C ;Get Last Object ;3 LDA #$A2 ;Set cache to ;2 STA $95 ; no-ojects. ;3 STA $96 ;3 MoveNextObject: TYA ;2 CLC ;Goto the next object to ;2 ADC #$09 ;check (add nine). ;2 CMP #$A2 ;Check if over maximum. ;2 BCC GetObjectsInfo ;2 LDA #$00 ;If so, wrap to zero. ;2 GetObjectsInfo: TAY ;2 LDA Store1,Y ;Get low byte of object info. ;4 STA $93 ;3 LDA Store2,Y ;Get high byte of object info. ;4 STA $94 ;3 LDX #$00 ;2 LDA ($93,X) ;Get objects current room. ;6 CMP $8A ;Is it in this room? ;3 BNE CheckForMoreObjects ;If not lets try next object (branch) ;2 LDA $95 ;Check first slot. ;3 CMP #$A2 ;If not default (no-object) ;2 BNE StoreObjectToPrint ;then branch. ;2 STY $95 ;Store this object's number to print ;3 JMP CheckForMoreObjects ; and try for more. ;3 StoreObjectToPrint: STY $96 ;Store this object's number to print. ;3 JMP StoreCount ; and then give up - no slots free. ;3 CheckForMoreObjects: CPY $9C ;Have we done all the objets? ;3 BNE MoveNextObject ;If not, continue. ;2 StoreCount: STY $9C ;If so, store current count ;3 RTS ; for next time. ;6 ;Convert room number to address. RoomNumToAddress: STA $D8 ;Strore room number wanted. ;3 STA $93 ;3 LDA #$00 ;Zero the high byte of the ;2 STA $94 ; offset. ;3 CLC ;2 ROL $93 ;5 ROL $94 ;Multiply room number by eight. ;5 ROL $93 ;5 ROL $94 ;5 ROL $93 ;5 ROL $94 ;5 LDA $D8 ;Get the original room number. ;3 CLC ;2 ADC $93 ;3 STA $93 ;And add it to the offset. ;3 LDA #$00 ;2 ADC $94 ;In effect the room number is ;3 STA $94 ; multiplied by nine. ;3 LDA #RoomDataTable ; the final room data address. ;2 ADC $94 ;3 STA $94 ;3 RTS ;6 ;Get pointer to current state. GetObjectState: LDY #$00 ;2 LDA $DC ;Get the current object state. ;3 GetObjectState_1: CMP ($93),Y ;Have we found it in the list of states. ;5 BCC GetObjectState_2 ;If nearing it then found it and return ;2 BEQ GetObjectState_2 ;If found it then return. ;2 INY ;2 INY ;Goto next state in list of states. ;2 INY ;2 JMP GetObjectState_1 ;3 GetObjectState_2: RTS ;6 ;Check for input. CheckInput: INC $E5 ;Increment low count. ;5 BNE GetJoystick ;2 INC $E6 ;Increment hight count if ;5 BNE GetJoystick ; needed. ;2 LDA #$80 ;Wrap the high count (indicating ;2 STA $E6 ; timeout) if needed. ;3 GetJoystick: LDA SWCHA ;Get joystick values. ;4 CMP #$FF ;If any movement then branch. ;2 BNE GetJoystick_2 ;2 LDA SWCHB ;Get the consol switches ;4 AND #$03 ;Mast for the reset/select switchs. ;2 CMP #$03 ;Have either of them been used? ;2 BEQ GetJoystick_3 ;If not branch. ;2 GetJoystick_2: LDA #$00 ;Zero the high count of the ;2 STA $E6 ; switches or joystick have been used. ;3 GetJoystick_3: RTS ;6 ;Change color if necessary. ChangeColor: LSR ;If bit 0 of the color is set ;2 BCC ChangeColor_2 ; then the room is to flash. ;2 TAY ;Use color as an index (usually E5- the low counter). ;2 LDA.wy $0080,Y ;Get flash color (usually the low counter.) ;4 ChangeColor_2: LDY $E6 ;Get the input counter. ;3 BPL ChangeColor_3 ;If console/joystick moved reciently then branch. ;2 EOR $E6 ;Merge the high counter with the color wanted. ;3 AND #$FB ;Keep this color bug merge down the luminance. ;2 ChangeColor_3: ASL ;And restore original color if necessary. ;2 RTS ;6 ;Get the address of the dynamic information for an object. GetObjectAddress: LDA Store1,X ;4 STA $93 ;Get and store the low address. ;3 LDA Store2,X ;4 STA $94 ;Get and store the high address. ;3 RTS ;6 ;Game Start StartGame: SEI ;Set Interupts Off ;2 CLD ;2 LDX #$28 ;Clear TIA Registers ;2 LDA #$00 ;&04-&2C i.e. blank ;2 ResetAll: STA NUSIZ0,X ;Everything And Turn. ;4 DEX ;Everything Off. ;2 BPL ResetAll ;2 TXS ;Reset Stack ;2 SetupVars: STA VSYNC,X ;Clear &80 to &FF User Vars. ;4 DEX ;2 BMI SetupVars ;2 JSR ThinWalls ;Position the thin walls (missiles) ;6 JSR SetupRoomObjects ;Setup objects rooms and positions. ;6 MainGameLoop: JSR CheckGameStart ;Check for Game Start ;6 JSR MakeSound ;Make noise if necessary ;6 JSR CheckInput ;Check for input. ;6 LDA $DE ;Is The Game Active? ;3 BNE NonActiveLoop ;If Not Branch.. ;2 LDA $B9 ;Get the room the Chalise is in. ;3 CMP #$12 ;Is it in the yellow castle? ;2 BNE MainGameLoop_2 ;If Not Branch.. ;2 LDA #$FF ;2 STA $DF ;Set the note count to maximum. ;3 STA $DE ;Set the game to inactive. ;3 LDA #$00 ;Set the noise type to end-noise. ;2 STA $E0 ;3 MainGameLoop_2: LDY #$00 ;Allow joystick read - all movement. ;2 JSR BallMovement ;Check ball collisions and move ball. ;6 JSR MoveCarriedObject ;Move the Carried Object ;6 JSR DoVSYNC ;Wait for VSYNC ;6 JSR SetupRoomPrint ;Setup the room and objects for display. ;6 JSR PrintDisplay ;Display the room and objects. ;6 JSR PickupPutdown ;Deal with object pickup and putdown. ;6 LDY #$01 ;Dissalow joystick read - move vertically only. ;2 JSR BallMovement ;Check ball collisions and move ball. ;6 JSR Surround ;Deal With Invisible Surround Moving. ;6 JSR DoVSYNC ;Wait for VSYNC ;6 JSR MoveBat ;Move and deal with bat. ;6 JSR Portals ;Move and deal with portcullises. ;6 JSR PrintDisplay ;Display the room and objects. ;6 JSR MoveGreenDragon ;Move and deal with the green dragon. ;6 JSR MoveYellowDragon ;Move and deal with the yellow dragon. ;6 JSR DoVSYNC ;Wait for VSYNC. ;6 LDY #$02 ;Dissalow joystic read/bridge check - move horrizonally only. ;2 JSR BallMovement ;Check ball collisions and move ball. ;6 JSR MoveRedDragon ;Move and deal with red dragon. ;6 JSR Mag_1 ;Deal with the magnet. ;6 JSR PrintDisplay ;Display the room and objects. ;6 JMP MainGameLoop ;3 ;Non Active Game Loop. NonActiveLoop: JSR DoVSYNC ;Wait for VSYNC ;6 JSR PrintDisplay ;Display the room and objects. ;6 JSR SetupRoomPrint ;Set up room and objects for display. ;6 JMP MainGameLoop ;3 ;Position missiles to "thin wall" areas. ThinWalls: LDA #$0D ;Position missile 00 to ;2 LDX #$02 ;(0D,00) - left thin wall. ;2 JSR PosSpriteX ;6 LDA #$96 ;Position missile 01 to ;2 LDX #$03 ;(96,00) - right thin wall. ;2 JSR PosSpriteX ;6 STA WSYNC ;Wait for horizonal blank. ;3 STA HMOVE ;Apply the horizonal move. ;3 RTS ;6 CheckGameStart: LDA SWCHB ;Get the console switches. ;4 EOR #$FF ;Flip (as reset active low). ;2 AND $92 ;Compare with what was before ;3 AND #$01 ;And check only the reset switch ;2 BEQ CheckReset ;If no reset then branch. ;2 LDA $DE ;Has the Game Started? ;3 CMP #$FF ;If not then branch. ;2 BEQ SetupRoomObjects ;2 LDA #$11 ;Get the yellow castle room. ;2 STA $8A ;Make it the current room. ;3 STA $E2 ;Make it the previous room. ;3 LDA #$50 ;Get the X coordinate. ;2 STA $8B ;Make it the current ball X coordinate. ;3 STA $E3 ;Make it the previous ball X coordinate. ;3 LDA #$20 ;Get the Y coordinate. ;2 STA $8C ;Make it the current ball Y coordinate. ;3 STA $E4 ;Make it the previous ball Y coordinate. ;3 LDA #$00 ;2 STA $A8 ;Set the red dragon's state to OK. ;3 STA $AD ;Set the yellow dragon's state to OK. ;3 STA $B2 ;Set the green dragon's state to OK. ;3 STA $DF ;Set the note count to zero.. (ops!??) ;3 LDA #$A2 ;2 STA $9D ;Set no object being carried. ;3 CheckReset: LDA SWCHB ;Get the console switches. ;4 EOR #$FF ;Flip (as select active low) ;2 AND $92 ;Compare with what was before. ;3 AND #$02 ;And check only the select switch. ;2 BEQ StoreSwitches ;Branch if select not being used. ;2 LDA $8A ;Get the Current Room. ;3 CMP #$00 ;Is it the "Number" room? ;2 BNE SetupRoomObjects ;Branch if not. ;2 LDA $DD ;Increment the level. ;3 CLC ;Number (by two). ;2 ADC #$02 ;2 CMP #$06 ;Have we reached the maximum? ;2 BCC ResetSetup ;2 LDA #$00 ;If yep then set back to zero. ;2 ResetSetup: STA $DD ;Store the new level number. ;3 SetupRoomObjects: LDA #$00 ;Set the current room to the ;2 STA $8A ;"Number" room. ;3 STA $E2 ;And the previous room. ;3 LDA #$00 ;Set the ball's Y coordinate to zero. ;2 STA $8C ;And the previous Y coordinate. ;3 STA $E4 ;(So can't be seen.) ;3 LDY $DD ;Get the level number. ;3 LDA Loc_4,Y ;Get the low pointer to object locations. ;4 STA $93 ;3 LDA Loc_5,Y ;Get the high pointer to object locations. ;4 STA $94 ;3 LDY #$30 ;Copy all the objects dynamic information. ;2 SetupRoomObjects_2: LDA ($93),Y ;(the rooms and positions) into ;5 STA.wy $00A1,Y ;the working area. ;5 DEY ;2 BPL SetupRoomObjects_2 ;2 LDA $DD ;Get the level number. ;3 CMP #$04 ;Branch if level one. ;2 BCC SignalGameStart ;Or two (Where all objects are in defined areas.) ;2 JSR RandomizeLevel3 ;Put some objects in random rooms. ;6 JSR DoVSYNC ;Wait for VSYNC ;6 JSR PrintDisplay ;Display rooms and objects. ;6 SignalGameStart: LDA #$00 ;Signal that the game has started. ;2 STA $DE ;3 LDA #$A2 ;Set no object being carried. ;2 STA $9D ;3 StoreSwitches: LDA SWCHB ;Store the current console switches ;4 STA $92 ;3 RTS ;6 ;Put objects in random rooms for level 3. RandomizeLevel3: LDY #$1E ;For each of the eleven objects.. ;2 RandomizeLevel3_2: LDA $E5 ;Get the low input counter as seed. ;3 LSR ;2 LSR ;2 LSR ;Generate a psudo-random ;2 LSR ;room number. ;2 LSR ;2 SEC ;2 ADC $E5 ;Store the low input counter. ;3 STA $E5 ;3 AND #$1F ;Trim so represents a room value. ;2 CMP Loc_2,Y ;If it is less than the ;4 BCC RandomizeLevel3_2 ;lower bound for object then get another. ;2 CMP Loc_3,Y ;If it equals or is ;4 BEQ RandomizeLevel3_3 ;Less than the higher bound for object ;2 BCS RandomizeLevel3_2 ;Then continue (branch if higher) ;2 RandomizeLevel3_3: LDX Loc_1,Y ;Get the dynamic data index for this object ;4 STA VSYNC,X ;Store the new room value. ;4 DEY ;2 DEY ;Goto the next object. ;2 DEY ;2 BPL RandomizeLevel3_2 ;Untill all done ;2 RTS ;6 ;Room Bounds Data. ;Ex. the chalise at location &B9 can only exist in rooms 13-1A for ; level 3. Loc_1: .byte $B9 ; Loc_2: .byte $13 ;Chalise Loc_3: .byte $1A ; .byte $A4,$01,$1D ;Red Dragon .byte $A9,$01,$1D ;Yellow Dragon .byte $AE,$01,$1D ;Green Dragon .byte $B6,$01,$1D ;Sword .byte $BC,$01,$1D ;Bridge .byte $BF,$01,$1D ;Yellow Key .byte $C2,$01,$16 ;White Key .byte $C5,$01,$12 ;Black Key .byte $CB,$01,$1D ;Bat .byte $B3,$01,$1D ;Magnet Loc_4: .byte Game1Objects ; --continued. .byte Game2Objects ;Pointer to object locations for game 02. .byte Game2Objects ;Pointer to object locations for game 03. ;Object locations (room and coordinate) for game 01. Game1Objects: .byte $15,$51,$12 ;Black dot (Room, X, Y) .byte $0E,$50,$20,$00,$00 ;Red Dragon (Room, X, Y, Movement, State) .byte $01,$50,$20,$00,$00 ;Yellow Dragon (Room, X, Y, Movement, State) .byte $1D,$50,$20,$00,$00 ;Green Dragon (Room, X, Y, Movement, State) .byte $1B,$80,$20 ;Magnet (Room,X,Y) .byte $12,$20,$20 ;Sword (Room,X,Y) .byte $1C,$30,$20 ;Challise (Room,X,Y) .byte $04,$29,$37 ;Bridge (Room,X,Y) .byte $11,$20,$40 ;Yellow Key (Room,X,Y) .byte $0E,$20,$40 ;White Key (Room,X,Y) .byte $1D,$20,$40 ;Black Key (Room,X,Y) .byte $1C ;Portcullis State .byte $1C ;Portcullis State .byte $1C ;Portcullis State .byte $1A,$20,$20,$00,$00 ;Bat (Room, X, Y, Movement, State) .byte $78,$00 ;Bat (Carrying, Fed-Up) ;Object locations (room and coordinate) for Games 02 and 03. Game2Objects: .byte $15,$51,$12 ;Black Dot (Room,X,Y) .byte $14,$50,$20,$A0,$00 ;Red Dragon (Room,X,Y,Movement,State) .byte $19,$50,$20,$A0,$00 ;Yellow Dragon (Room,X,Y,Movement,State) .byte $04,$50,$20,$A0,$00 ;Green Dragon (Room,X,Y,Movement,State) .byte $0E,$80,$20 ;Magnet (Room,X,Y) .byte $11,$20,$20 ;Sword (Room,X,Y) .byte $14,$30,$20 ;Chalise (Room,X,Y) .byte $0B,$40,$40 ;Bridge (Room,X,Y) .byte $09,$20,$40 ;Yellow Key (Room,X,Y) .byte $06,$20,$40 ;White Key (Room,X,Y) .byte $19,$20,$40 ;Black Key (Room,X,Y) .byte $1C ;Portcullis State .byte $1C ;Portcullis State .byte $1C ;Portcullis State .byte $02,$20,$20,$90,$00 ;Bat (Room,X,Y,Movement,State) .byte $78,$00 ;Bat (Carrying, Fed-Up) ;Check ball collisions and move ball. BallMovement: LDA CXBLPF ;3 AND #$80 ;Get ball-playfield collision ;2 BNE PlayerCollision ;Branch if collision (Player-Wall) ;2 LDA CXM0FB ;3 AND #$40 ;Get ball-missile00 collision. ;2 BNE PlayerCollision ;Branch if collision. (Player-Left Thin) ;2 LDA CXM1FB ;3 AND #$40 ;Get ball-missile01 collision. ;2 BEQ BallMovement_2 ;Branch if no collision. ;2 LDA $96 ;If object2 (to print) is ;3 CMP #$87 ; not the black dot then collide. ;2 BNE PlayerCollision ;2 BallMovement_2: LDA CXP0FB ;3 AND #$40 ;Get ball-player00 collision. ;2 BEQ BallMovement_3 ;If no collision then branch. ;2 LDA $95 ;If object1 (to print) is ;3 CMP #$00 ; not the invisible surround then ;2 BNE PlayerCollision ; branch (collision) ;2 BallMovement_3: LDA CXP1FB ;3 AND #$40 ;Get ball-player01 collision. ;2 BEQ NoCollision ;If no collision then branch. ;2 LDA $96 ;If player01 to print is ;3 CMP #$00 ; not the invisible surround then ;2 BNE PlayerCollision ; branch (collision) ;2 JMP NoCollision ;No collision - branch. ;3 ;Player collided (with something) PlayerCollision: CPY #$02 ;Are we checking for the bridge? ;2 BNE ReadStick ;If not, branch. ;2 LDA $9D ;Get the object being carried. ;3 CMP #$5A ; Branch if it is the bridge. ;2 BEQ ReadStick ;2 LDA $8A ;Get the current room. ;3 CMP $BC ;Is the bridge in this room. ;3 BNE ReadStick ;If not branch. ;2 ;Check going through the bridge. LDA $8B ;Get the ball's X coordinate. ;3 SEC ;2 SBC $BD ;Subtract the bridge's X coordinate. ;3 CMP #$0A ;If less than &0A then forget it. ;2 BCC ReadStick ;2 CMP #$17 ;If more than &17 then forget it. ;2 BCS ReadStick ;2 LDA $BE ;Get the bridge's Y coordinate. ;3 SEC ;2 SBC $8C ;Subtrac the ball's Y coordinate. ;3 CMP #$FC ;2 BCS NoCollision ;If more than &FC then going through bridge. ;2 CMP #$19 ;If more than &19 then forget it. ;2 BCS ReadStick ;2 ;No collision (and going through bridge) NoCollision: LDA #$FF ;Reset the joystick input. ;2 STA $99 ;3 LDA $8A ;Get the current room. ;3 STA $E2 ; and store temporarily. ;3 LDA $8B ;Get the ball's X coordinate. ;3 STA $E3 ; and store temporarily. ;3 LDA $8C ;Get the ball's Y coordinate. ;3 STA $E4 ;And Store Temporarily. ;3 ;Read Sticks ReadStick: CPY #$00 ;???Is game in first phase? ;2 BNE ReadStick_2 ;If not, don't bother with joystick read. ;2 LDA SWCHA ;Read joysticks. ;4 STA $99 ; and store value. ;3 ReadStick_2: LDA $E2 ;Get Temporary room. ;3 STA $8A ; and make it the current room. ;3 LDA $E3 ;Get temporary X coordinate ;3 STA $8B ; and make it the man's X coordinate. ;3 LDA $E4 ;Get temporary Y coordinate ;3 STA $8C ; and make it the man's Y coordinate. ;3 LDA $99 ;Get the Joystick position. ;3 ORA ReadStick_3,Y ;Merge out movement not allowed in this phase. ;4 STA $9B ;And store cooked movement. ;3 LDY #$03 ;Set the delta for the ball. ;2 LDX #$8A ;Point to ball's coordiates. ;2 JSR MoveGroundObject ;Move the ball ;6 RTS ;6 ;Joystick Merge Values ReadStick_3: .byte $00,$C0,$30 ;No change, No horizontal, No vertical. ;Deal with object pickup and putdown. PickupPutdown: ROL INPT4 ;Get joystick trigger. ;5 ROR $D7 ;Merget into joystick record. ;5 LDA $D7 ;Get joystick record. ;3 AND #$C0 ;Merget out previous presses. ;2 CMP #$40 ;Was it previously pressed? ;2 BNE PickupPutdown_2 ;If not branch. ;2 LDA #$A2 ;2 CMP $9D ;If nothing is being carried ;3 BEQ PickupPutdown_2 ; then branch. ;2 STA $9D ;Drop object. ;3 LDA #$04 ;Set noise type to four. ;2 STA $E0 ;3 LDA #$04 ;Set noise count to four. ;2 STA $DF ;3 PickupPutdown_2: LDA #$FF ;???? ;2 STA $98 ;3 ;Check for collision. LDA CXP0FB ;3 AND #$40 ;Get Ball-Player00 collision. ;2 BEQ PickupPutdown_3 ;If nothing occured then branch. ;2 ;With Player00 LDA $95 ;Get type of Player00 ;3 STA $97 ;And Store. ;3 JMP CollisionDetected ;Deal with collision. ;3 PickupPutdown_3: LDA CXP1FB ;3 AND #$40 ;Get Ball-Player01 collision. ;2 BEQ PickupPutdown_4 ;If nothing has happened, branch. ;2 LDA $96 ;Get type of Player01 ;3 STA $97 ; and store. ;3 JMP CollisionDetected ;Deal with collision. ;3 PickupPutdown_4: JMP NoObject ;Deal with no collision (return). ;3 ;Collision occured. CollisionDetected: LDX $97 ;Get the object collided with. ;3 JSR GetObjectAddress ;Get it's dynamic information. ;6 LDA $97 ;Get the object collided with. ;3 CMP #$51 ;Is it carriable? ;2 BCC NoObject ;If not, branch. ;2 LDY #$00 ;2 LDA ($93),Y ;Get the object's room. ;5 CMP $8A ;Is it in the current room? ;3 BNE NoObject ;If not, branch. ;2 LDA $97 ;Get the object collided with. ;3 CMP $9D ;Is it the object being carried? ;3 BEQ PickupObject ;If so, branch (and actually pick it up.) ;2 LDA #$05 ;Set noise type to five. ;2 STA $E0 ;3 LDA #$04 ;Set noise type to four. ;2 STA $DF ;3 PickupObject: LDA $97 ;Set the object as being ;3 STA $9D ; carried. ;3 LDX $93 ;Get the dynamice address low byte. ;3 LDY #$06 ;2 LDA $99 ;???? ;3 JSR MoveObjectDelta ;???? ;6 LDY #$01 ;2 LDA ($93),Y ;Get the object's X coordinate. ;5 SEC ;2 SBC $8B ;Subtract the ball's X coordinate. ;3 STA $9E ; and store the difference. ;3 LDY #$02 ;2 LDA ($93),Y ;Get the object's Y coordinate. ;5 SEC ;2 SBC $8C ;Subtract the Ball's Y coordinate. ;3 STA $9F ; and store the difference. ;3 ;No collision NoObject: RTS ;6 ;Move the carried object MoveCarriedObject: LDX $9D ;Get the object being carried. ;3 CPX #$A2 ;If nothing then branch (return) ;2 BEQ MoveCarriedObject_2 ;2 JSR GetObjectAddress ;Get it's dynamic information. ;6 LDY #$00 ;2 LDA $8A ;Get the current room. ;3 STA ($93),Y ; and stroe the object's current room. ;6 LDY #$01 ;2 LDA $8B ;Get the ball's X coordinate. ;3 CLC ;2 ADC $9E ;Add the X difference. ;3 STA ($93),Y ; and store as the object's X coordinate. ;6 LDY #$02 ;2 LDA $8C ;Get the ball's Y coordinate. ;3 CLC ;2 ADC $9F ;Add the Y difference. ;3 STA ($93),Y ; and store as the object's Y coordinate. ;6 LDY #$00 ;Set no delta. ;2 LDA #$FF ;Set no movement. ;2 LDX $93 ;Get the object's dynamic address. ;3 JSR MoveGroundObject ;Move the object. ;6 MoveCarriedObject_2: RTS ;6 ;Move the object. MoveGroundObject: JSR MoveObjectDelta ;Move the object by delta. ;6 LDY #$02 ;Set to do the three ;2 MoveGroundObject_2: STY $9A ; portcullises. ;3 LDA.wy $00C8,Y ;Get the portal state. ;4 CMP #$1C ;Is it in a closed state? ;2 BEQ GetPortal ;If not, next portal. ;2 ;Deal with object moving out of a castle. LDY $9A ;Get port number. ;3 LDA VSYNC,X ;Get object's room number. ;4 CMP EntryRoomOffsets,Y ;Is it in a castle entry room. ;4 BNE GetPortal ;If not, next portal. ;2 LDA WSYNC,X ;Get the object's Y coordinate. ;4 CMP #$0D ;Is it above &OD i.e at the bottom. ;2 BPL GetPortal ;If so then branch. ;2 LDA CastleRoomOffsets,Y ;Get the castle room. ;4 STA VSYNC,X ;And put the object in the castle room. ;4 LDA #$50 ;2 STA VBLANK,X ;Set the object's new X coordinate. ;4 LDA #$2C ;2 STA WSYNC,X ;Set the new object's Y coordinate. ;4 LDA #$01 ;2 STA.wy $00C8,Y ;Set the portcullis state to 01. ;5 RTS ;6 GetPortal: LDY $9A ;Get the portcullis number. ;3 DEY ; goto next, ;2 BPL MoveGroundObject_2 ; and continue. ;2 ;Check and Deal with Up. LDA WSYNC,X ;Get the object's Y coordinate. ;4 CMP #$6A ;Has it reched above the top. ;2 BMI DealWithLeft ;If not, branch. ;2 LDA #$0D ;Set new Y coordinate to bottom. ;2 STA WSYNC,X ;4 LDY #$05 ;Get the direction wanted. ;2 JMP GetNewRoom ;Go and get new room. ;3 ;Check and Deal with Left. DealWithLeft: LDA VBLANK,X ;Get the object's X coordinate. ;4 CMP #$03 ;Is it Three or less? ;2 BCC DealWithLeft_2 ;IF so, branch. (off to left) ;2 CMP #$F0 ;Is it's &F0 or more. ;2 BCS DealWithLeft_2 ;If so, branch. (off to right) ;2 JMP DealWithDown ;3 DealWithLeft_2: CPX #$8A ;Are we dealling with the ball? ;2 BEQ DealWithLeft_3 ;If so Branch. ;2 LDA #$9A ;Set new X coordinate for the others. ;2 JMP DealWithLeft_4 ;3 DealWithLeft_3: LDA #$9E ;Set new X coordinate for the ball. ;2 DealWithLeft_4: STA VBLANK,X ;Store the next X coordinate. ;4 LDY #$08 ;And get the direction wanted. ;2 JMP GetNewRoom ;Go and get new room. ;3 ;Check and Deal with Down. DealWithDown: LDA WSYNC,X ;Get object's Y coordinate. ;4 CMP #$0D ;If it's greater than &0D then ;2 BCS DealWithRight ;Branch. ;2 LDA #$69 ;Set new Y coordinate. ;2 STA WSYNC,X ;4 LDY #$07 ;Get the direction wanted. ;2 JMP GetNewRoom ;Go and get new room. ;3 ;Check and Deal with Right. DealWithRight: LDA VBLANK,X ;Get the object's X coordinate. ;4 CPX #$8A ;Are we dealing with the ball. ;2 BNE DealWithRight_2 ;Branch if not. ;2 CMP #$9F ;Has the object reached the right? ;2 BCC MovementReturn ;Branch if not. ;2 LDA VSYNC,X ;Get the Ball's Room. ;4 CMP #$03 ;Is it room #3 (Right to secret room) ;2 BNE DealWithRight_3 ;Branch if not. ;2 LDA $A1 ;Check the room of the black dot. ;3 CMP #$15 ;Is it in the hidden room area? ;2 BEQ DealWithRight_3 ;If so, Branch. ;2 ;Manually change to secret room. LDA #$1E ;Set room to secret room. ;2 STA VSYNC,X ;And make it current. ;4 LDA #$03 ;Set the X coordinate. ;2 STA VBLANK,X ;4 JMP MovementReturn ;And Exit. ;3 DealWithRight_2: CMP #$9B ;Has the object reached the right of the screen? ;2 BCC MovementReturn ;Branch if not (no room change) ;2 DealWithRight_3: LDA #$03 ;Set the next X coordinate. ;2 STA VBLANK,X ;4 LDY #$06 ;And get the direction wanted. ;2 JMP GetNewRoom ;Get the new room. ;3 ;Get new room GetNewRoom: LDA VSYNC,X ;Get the object's room. ;4 JSR RoomNumToAddress ;Convert it to an address. ;6 LDA ($93),Y ;Get the adjacent room. ;5 JSR AdjustRoomLevel ;Deal with the level differences. ;6 STA VSYNC,X ; and store as new object's room. ;4 MovementReturn: RTS ;6 ;Move the object in direction by delta. MoveObjectDelta: STA $9B ;Stored direction wanted. ;3 MoveObjectDelta_2: DEY ;Count down the delta. ;2 BMI MoveObjectDelta_7 ;2 LDA $9B ;Get direction wanted. ;3 AND #$80 ;Check for right move. ;2 BNE MoveObjectDelta_3 ;If no move right then branch. ;2 INC VBLANK,X ;Increment the X coordinate. ;6 MoveObjectDelta_3: LDA $9B ;Get the direction wanted. ;3 AND #$40 ;Check for left move. ;2 BNE MoveObjectDelta_4 ;If no move left then branch. ;2 DEC VBLANK,X ;Decrement the X coordinate. ;6 MoveObjectDelta_4: LDA $9B ;Get the direction wanted. ;3 AND #$10 ;Check for move up.