💾 Archived View for uscoffings.net › retro-computing › software › 6502 › nbcombat.asm captured on 2024-08-18 at 21:36:17.
⬅️ Previous capture (2022-07-16)
-=-=-=-=-=-=-
; Combat for Atari by Larry Wagner ; ; Original disassembly by Harry Dodgson ; Commented further by Nick Bensema. ; Last Update: 8/26/97 ; ; First a bit of history. Combat was included with the ; famous Atari 2600/VCS for many years. As a result, ; if you go to any thrift store, you will find crates ; of Combat cartridges, and some guy from ; rec.games.video.classic swimming through it, refusing ; to admit that Sum Guy just ran off with the mega-rare ; Chase the Chuckwagon cart with the misprinted sideways ; label that he's looking for. ; ; To fully appreciate the trouble people had to go through ; to make an Atari 2600 game, I decided to try my hand at ; picking apart a relatively simple game, Combat. This ; game works in only 2K or ROM and not even the full 128 ; bytes of RAM made available to it. As if that weren't ; enough, the program has to literally draw the screen ; every single frame, and even Combat had to resort ; to changing some graphic or other in the middle of ; a scanline. And the programmer had to walk five miles ; to work, uphill both ways! And he only got a nickel ; a day for writing code! ; ; The Atari 2600, or the VCS, or the 2600VCS, or the ; Atari VCS, or the 2600, or the VCS-2600, or the Sears ; Home Arcade System, or the Intellivision Add-On Thingy ; That Plays Atari 2600, VCS, 2600VCS, Atari VCS, 2600, ; VCS-2600, and Sears games, runs with a 6507 processof. ; This processor is exactly like the 6502 found in Apple, ; Atari, and Commodore home computers except for two ; things: 1) it has a wait state, and 2) it has only ; 13 address lines instead of 16. So, while your Apple ; II can address $0000-$FFFF, the Atari 2600 could ; only address $0000-$1FFF. That's a whopping 8K. ; The cartridge ROM accounted for anything about $1000. ; You're going to love this part. It had 128 bytes of RAM ; at $0080-$00FF, and the TIA, its video chip, which ; doubles as the 2600's entire video memory, at both ; $0000-$007F, and $0100-$017F. The first copy, along ; with the RAM, could be accessed with zero-page addresses, ; saving space on the ROM, which by the way was 2K. ; The second copy infiltrated the last 128 bytes of the ; 6507's built-in stack. In the source code, you'll see ; how this is used to the programmer's advantage. ; ; That's all I'm explaining. If you want to hear more ; on the 2600's specifications, do a web search for ; 2600 programming information, because I've already ; wasted so much of your time. ; ; I did a lot of cutting and pasting and searching ; and replacing. Be sure to check that this compiles ; to exactly 2048 bytes, and that it matches up with ; all of your uncommented source code before trying to ; modify it... if you dare! For some reason the guy ; who disassembled this didn't put $ before all the hex ; numbers... so keep in mind, hex is always implied. ; ; I also suggest you hand this to those who want to pirate ; 2600 cartridges. Not that it'll stop them, but it might ; make them feel guilty enough to seek absolution. ; ; Not having an assembler, and of course not wanting ; to try to use an emulator, I may have screwed up ; big-time on many aspects of this program. ; Forgive me if I did. ; ; Note a few things: ; ; 1. If you don't know what the BIT instruction does, ; I'll just sum up how Kaplan used it here. Kaplan ; used BIT to test bits 7 and 6 of a memory location. ; If bit 7 was set, the negative flag would be set, ; so the following BMI would cause a branch. If bit ; 6 was set, the overflow flag would be set, so the ; following BVS would cause a branch. If I find an ; assembler that does macros, I'll use those to do this. ; ; 2. I might refer to players as tanks even though they ; could just as easily be biplanes or jets. ; processor 6502 include vcs.h GAMVAR = $A3 ;Game Variation BCDvar = $81 ;Game Variation in BCD DIRECTN = $95 ;Players and missiles' current bearing. GAMSHP = $85 ;Shape of player and game type ;0 = Tank ;1 = Biplane ;2 = Jet Fighter SCROFF = $E0 ;Score pattern offsets NUMG0 = $DE ;Storage for current byte NUMG1 = $DF ;of score number graphics. TMPSTK = $D3 ;Temporary storage for stack. GUIDED = $83 ;Whether game is a guided missile game GTIMER = $86 ;Game timer. SHOWSCR = $87 ;Show/hide right player score ScanLine = $B4 ;Current scanline on the playfield. SHAPES = $BB ;Pointer to player sprites SCORE = $A1 ;Player scores in BCD. TankY0 = $A4 ;Tank 0's Y-position TankY1 = $A5 ; MissileY0 = $A6 ;Missile 0's Y-position MissileY1 = $A7 ; TEMP = $D2;"score conversion temporary" XOFFS = $B0 ;X-offset for Hmove. LORES = $B5 ;lo-res indirect addresses. HIRES = $BD ;Hi-res shape data. ;Left player's shape stored in ;all even bytes, right player's ;shape stored in all odd bytes. DIFSWCH = $D5 Color0 = $D6 ;Tank Colors. Color1 = $D7 org $1000 START ; Two bytes of housekeeping that must be done... SEI ; Disable interrupts CLD ; Clear decimal bit LDX #$FF TXS ; Set stack to beginning. ; In all truthfulness, LDX #$5D JSR ClearMem ; zero out $00 thru $A2 LDA #$10 STA SWCHB+1 ;Port B data direction register STA $88 ;and $88... JSR J11A3 MLOOP JSR NWSCR ; $1014 JSR ConSwitch JSR J1572 JSR J12DA JSR J1444 JSR J1214 JSR J12A9 JSR BCD2SCR JSR DRAW JMP MLOOP ; NWSCR INC GTIMER ; initial blanking and retrace start STA HMCLR ;Clear horizontal move registers. LDA #2 STA WSYNC STA VBLANK STA WSYNC STA WSYNC STA WSYNC STA VSYNC STA WSYNC STA WSYNC LDA #0 STA WSYNC STA VSYNC LDA #43 STA TIM64T ;set 64 clock interval. RTS ; ; Drawing the screen in the following routine. ; We start with the score, then we render the ; playfield, tanks, and missiles simultaneously. ; All in all, an average day for a VCS. ; DRAW LDA #$20 STA ScanLine ;We're assuming scanline 20. STA WSYNC STA HMOVE ;Move sprites horizontally. B105C LDA INTIM BNE B105C ;Wait for INTIM to time-out. STA WSYNC STA CXCLR ;Clear collision latches STA VBLANK ;We even have to do our own ;vertical blanking! Oh, the ;humanity! TSX STX TMPSTK ; Save stack pointer LDA #$02 STA CTRLPF ; Double, instead of reflect. LDX $DC B1070 STA WSYNC ; Skip a few scanlines... DEX BNE B1070 LDA $DC CMP #$0E BEQ B10CD ; DC is set as such so that when the score is to ; be displayed, it waits for just the right time ; to start drawing the score, but if the score is ; not to be displayed, as when the score flashes ; signifying "time's almost up", it waits for just ; the right time to start drawing the rest of the ; screen. ; ; Start by drawing the score. ; LDX #$05 ;Score is five bytes high. LDA #$00 ;Clear number graphics. STA NUMG0 ;They won't be calculated yet, STA NUMG1 ;but first time through the loop ;the game will try to draw with ;them anyway. DRWSCR STA WSYNC ;Start with a fresh scanline. LDA NUMG0 ;Take last scanline's left score, STA PF1 ;and recycle it, ;Here, we begin drawing the next scanline's ;left score, as the electron beam moves towards ;the right score's position in this scanline. LDY SCROFF+2 LDA NUMBERS,Y ;Get left digit. AND #$F0 STA NUMG0 LDY SCROFF LDA NUMBERS,Y ;Get right digit. AND #$0F ORA NUMG0 STA NUMG0 ;Left score is ready to ship. LDA NUMG1 ;Take last scanline's right score, STA PF1 ;and recycle it. LDY SCROFF+3 LDA NUMBERS,Y ;Left digit... AND #$F0 STA NUMG1 LDY SCROFF+1 LDA NUMBERS,Y ;right digit... AND SHOWSCR ;Now, we use our fresh, new ;score graphics in ;this next scanline. STA WSYNC ; *COUNT* ORA NUMG1 ;Finish calculating (0) +3 STA NUMG1 ;right score. (3) +3 LDA NUMG0 ; (6) +3 STA PF1 ; *9* +3 ;We use this time to check ;whether we're at ;the end of our loop. DEX ; (12)+2 BMI B10CD ; (14)+2 No Branch ;If so, we're out of here. Don't worry, ;the score will be cleared immediately, so ;nobody will know that we've gone past five ;bytes and are displaying garbage. INC SCROFF ; (16)+5 INC SCROFF+2 ; Get ready to draw the next INC SCROFF+1 ; line of the byte. INC SCROFF+3 LDA NUMG1 STA PF1 ; Right score is in place. JMP DRWSCR ;Go to next scanline, ; and that is how we do that... ; ; See what it takes just to display a pair of two-digit ; scores? If you think that's rough, figure out how ; they displayed those six-digit scores in the early ; 1980's. Also consider Stellar Track.... well, if ; you've seen Stellar Track, you know exactly what I'm ; talking about. Full-fledged twelve-column text. ; ; Display loop for playfield. ; B10CD LDA #$00 ; Inner Display Loop STA PF1 ; Clear the score. STA WSYNC LDA #$05 STA CTRLPF ;Reflecting playfield. LDA Color0 STA COLUP0 ;How often must THIS be done? LDA Color1 STA COLUP1 DRWFLD LDX #$1E TXS ;Very Sneaky - set stack to missle registers SEC ; This yields which line of player 0 to draw. LDA TankY0 SBC ScanLine ; A=TankY0-ScanLine AND #$FE ;Force an even number TAX ; Only sixteen bytes of sprite memory, so... AND #$F0 BEQ B10F2 ; If not valid, ; If it's not valid, blank the tank. LDA #$00 BEQ B10F4 ; Else, load the appropriate byte. B10F2 LDA HIRES,X B10F4 STA WSYNC ;---------------END OF ONE LINE------ STA GRP0 ; Just for player 0. ; Keep in mind that at this point, the stack pointer ; is set to the missile registers, and the "zero-result" ; bit of the P register is the same at the bit ENAM0/1 ; looks at. LDA MissileY1 EOR ScanLine AND #$FE PHP ; This turns the missle 1 on/off LDA MissileY0 EOR ScanLine AND #$FE PHP ; This turns the missle 0 on/off ;We've got the missile taken care of. ;Now let's see which line of the playfield to draw. LDA ScanLine ; BPL B110C ;If on the bottom half of the screen, EOR #$F8 ;reverse direction so we can mirror. B110C CMP #$20 ; BCC B1114 ;Branch if at bottom. LSR LSR LSR ;Divide by eight, TAY ;and stow it in the Y-register. ;By now, the electron beam is already at the next ;scanline, so we don't have to do a STA WSYNC. ; This yields which line of Tank 1 to draw. B1114 LDA TankY1 ;TankY1 is other player's position. SEC SBC ScanLine ;A=TankY1 - ScanLine INC ScanLine ;Increment the loop. NOP ORA #$01 ;Add bit 0, force odd number. TAX ; There are only sixteen bytes of sprite memory, so... AND #$F0 BEQ B1127 ; If tank is not ready, blank it. LDA #$00 BEQ B1129 ; Else, draw tank. B1127 LDA HIRES,X ;draw the tank B1129 BIT $82 STA GRP1 BMI B113B ;If 82 bit set to 1, skip draw. (?) LDA (LORES),Y STA PF0 LDA (LORES+2),Y STA PF1 LDA (LORES+4),Y STA PF2 B113B INC ScanLine ;One more up in the loop. LDA ScanLine EOR #$EC ;When we've reached the $ECth line, BNE DRWFLD ;we've had enough. LDX TMPSTK ; Restore stack pointer TXS ; which is NEVER USED ANYWHERE ELSE... STA ENAM0 ; Clear a bunch of registers. STA ENAM1 STA GRP0 STA GRP1 STA GRP0 ;In case GRP0 isn't COMPLETELY zeroed. STA PF0 STA PF1 STA PF2 RTS ; ; Executed immediately after NWSCR. ; ; This subroutine parses all the console switches. ; ConSwitch LDA SWCHB ;Start/Reset button.... LSR ;Shove bit 0 into carry flag, BCS B1170 ;and if it's pushed... ; Start a new game. LDA #$0F STA SHOWSCR ;Show right score. LDA #$FF ;Set all bits STA $88 ;in $88. LDA #$80 STA $DD LDX #$E6 JSR ClearMem ; zero out $89 thru $A2 BEQ ResetField ;Unconditional branch B1170 LDY #$02 LDA $DD AND $88 CMP #$F0 BCC B1182 LDA GTIMER ;GTIMER is the timer. AND #$30 BNE B1182 LDY #$0E B1182 STY $DC LDA GTIMER AND #$3F BNE B1192 STA $89 INC $DD BNE B1192 STA $88 B1192 LDA SWCHB ; Select button. ??? AND #$02 BEQ B119D STA $89 BNE CS_RTS B119D BIT $89 BMI CS_RTS INC $80 ;Go to next game. J11A3 LDX #$DF ;Clear data from current game B11A5 JSR ClearMem ; LDA #$FF STA $89 LDY $80 LDA VARDATA,Y ;Get data bits for this variation. STA GAMVAR EOR #$FF ;#$FF signifies end of variations BNE B11BB LDX #$DD BNE B11A5 ; Clear all gamewise memory and start over. B11BB LDA BCDvar ;Remember we have to increment with BCD... SED CLC ADC #1 STA BCDvar STA SCORE CLD BIT GAMVAR BPL ResetField ;if this is a plane game, INC GAMSHP ;increase GAMSHP. BVC ResetField ;if this is a jet game, INC GAMSHP ;increase GAMSHP further still. ; Branch here when game is started, too. ResetField JSR InitField ; Assuming plane game for now, we set the right player ; at a slightly higher position than the left player, ; and the position of the right player is irrelevant. LDA #50 STA TankY1 LDA #134 STA TankY0 BIT GAMVAR ;Check to see if it is a tank game. BMI CS_RTS ; If it really is a tank game.. STA TankY1 ; Right tank has same Y value, STA RESP1 ;and tank is at opposite side. LDA #$08 STA DIRECTN+1 ;and right player faces left. LDA #$20 STA HMP0 STA HMP1 STA WSYNC STA HMOVE CS_RTS RTS ; ; convert BCD scores to score pattern offset. ; This involves the horrible, horrible implications ; involved in multiplying by five. ; ; If it weren't for the geniuses at NMOS using BCD, ; this routine would be a nightmare. ; BCD2SCR LDX #$01 B11F4 LDA SCORE,X AND #$0F STA TEMP ASL ASL CLC ADC TEMP STA SCROFF,X LDA SCORE,X AND #$F0 LSR LSR STA TEMP LSR LSR CLC ADC TEMP STA SCROFF+2,X DEX BPL B11F4 RTS ; ; ; J1214 BIT GUIDED BVC B121C ;Branch if bit 6 of 83 is clear. LDA #$30 BPL B121E ;JMP. B121C LDA #$20 B121E STA $B1 ;Either $30 or $20 goes here... LDX #$03 JSR J1254 DEX ;X, I _think_, is now 2. JSR J1254 DEX ;And I _think_ it's now 1. B122A LDA $8D,X ;Velocity register AND #$08 LSR LSR STX $D1 CLC ADC $D1 TAY ; Y=($8D,X)&8 / 4 + X ; $00A8,Y is either $00A8,X or $00AA,X. LDA $00A8,Y ;We can't use zero-page? Waaah! SEC BMI B123D CLC ;^^ That's just a fancy way to ; transfer bit 7 to Carry Bit. B123D ROL ;ROL, the wave of the future. STA $00A8,Y BCC B1250 LDA $AC,X AND #$01 ASL ASL ASL ASL STA $B1 ; B1 = (AC & 1) << 4 JSR J1254 B1250 DEX ;Move to _previous_ player. BEQ B122A ;Stop if about to do player -1. :) RTS ; ; This routine will move both tanks and missiles. ; Special cases are made for missiles, which are ; otherwise treated as players 2 and 3. ; ; It doesn't change the X register, but it does ; utilize it. ; J1254 INC $AC,X LDA DIRECTN,X AND #$0F CLC ADC $B1 TAY LDA L15F7,Y ;This has offset information. STA XOFFS ;Store the X-offset. BIT $82 BVS B127A ;Branch if bit 6 of 82 is set. LDA DIRECTN,X SEC SBC #$02 AND #$03 BNE B127A LDA $AC,X AND #$03 BNE B127A ;if AC isn't set, we're go for move. LDA #$08 STA XOFFS B127A LDA XOFFS J127C STA HMP0,X ;Use this to move the tank. AND #$0F SEC SBC #$08 STA $D4 CLC ADC TankY0,X BIT GAMVAR BMI B1290 ;Branch if a plane game. ;What follows is probably a bounds check. CPX #$02 BCS B12A0 ;Branch if moving a player B1290 CMP #$DB BCS B1298 CMP #$25 BCS B12A0 B1298 LDA #$D9 BIT $D4 BMI B12A0 LDA #$28 ;#$28 if D4 is positive, #$D9 if not B12A0 STA TankY0,X ;The tank/missile is moved here. CPX #$02 BCS B12A8 ;Skip if moving a missile. STA VDELP0,X ;Vertical Delay Player X... B12A8 RTS ; ; This subroutine sets up the sprite data for each player by copying ; them into sixteen bytes of RAM. ; ; The X-register starts at 0x0E plus player number and goes down by two ; each time through the loop, until it hits zero. This way, after calling ; this subroutine twice, every even-numbered byte contains the left player ; shape, and every odd-numbered byte contains the right player shape. Since ; each player is updated every two scanlines, this saves us some math. ; ; Only the first 180 degrees of rotation has been drawn into ROM. In the ; case of the other 180 degrees, this subroutine renders a flipped version ; by doing the following: ; ; 1. It sets the TIA's reflection flag for that player, taking care of ; the horizontal aspect rather easily. ; ; 2. It copies the bytes into memory last-to-first instead of first-to- ; last, using the carry bit as a flag for which to do. ; J12A9 LDA #$01 AND GTIMER TAX LDA DIRECTN,X STA REFP0,X ;Step 1 taken care of. AND #$0F TAY ;Y = DIRECTN[X] & 0x0F. BIT GUIDED BPL B12BB ;If bit 7 is set, STY DIRECTN+2,X ;then set missile bearings(?) B12BB TXA ; X ^= 0x0E, EOR #$0E ; TAX ; TYA ASL ASL ASL CMP #$3F ;And so step 2 begins... CLC BMI B12CB ;Branch if <180 deg. SEC EOR #$47 ;and it doesn't end here. ;The EOR sets bits 0-2, and clears bit 4 ;to subtract 180 degrees from the memory ;pointer, too. B12CB TAY ;Put all the shapes where they ought to be. B12CC LDA (SHAPES),Y STA HIRES,X BCC B12D4 DEY ; Decrement instead of increment DEY ; plus cancel the upcoming INY. B12D4 INY ;More of step 2. DEX DEX ;X-=2. BPL B12CC ;Keep going until X runs out. RTS ; ; Stir the tanks. :-) ; J12DA LDA $8A SEC SBC #$02 BCC B130C ;If tank is not exploding, ;parse joystick instead. STA $8A CMP #$02 BCC B130B ;RTS if tank has ;just finished exploding. AND #$01 ;Stir the LOSER's tank. TAX ;One of these is the tank's bearings. INC DIRECTN,X LDA $D8,X STA Color0,X LDA $8A CMP #$F7 BCC B12F9 JSR J1508 B12F9 LDA $8A BPL B130B ;Don't start decrementing ;volume until halfway through. LSR LSR LSR J1300 STA AUDV0,X ;Sound effects. BOOOM! LDA #$08 STA AUDC0,X LDA L17FE,X STA AUDF0,X B130B RTS ; ; Process joysticks. ; B130C LDX #$01 LDA SWCHB ;Console switches. STA DIFSWCH ;Store switches in D5. LDA SWCHA ;Joysticks. B1316 BIT $88 BMI B131C ;Branch if bit 7 is set. LDA #$FF ;Freeze all joystick movement. B131C EOR #$FF ;Reverse all bits AND #$0F ;Keep high four bits (Right Player) ;At this point, the joystick's switches are in ;the A-register, with a bit set wherever the ;joystick is pointed. ; Bit 0 = up Bit 1 = down ; Bit 2 = left Bit 3 = right STA TEMP LDY GAMSHP LDA L170F,Y ;Account for two-dimensional array CLC ADC TEMP TAY LDA CTRLTBL,Y AND #$0F ;Get rotation from table. STA $D1 BEQ B1338 ;Branch if no turn. CMP $91,X BNE B133C ;Some speed control I'm guessing. B1338 DEC $93,X BNE B1349 B133C STA $91,X LDA #$0F STA $93,X ; Turn the tank here. LDA $D1 CLC ADC DIRECTN,X STA DIRECTN,X B1349 INC $8D,X BMI B136B LDA CTRLTBL,Y LSR LSR LSR LSR ;Get velocity from table. BIT DIFSWCH BMI B137B B1358 STA $8B,X ; Stash velocity in $8B ASL ;Multiply by two TAY ;Stash in Y. LDA L1637,Y STA $A8,X ;This is the player's ? INY LDA L1637,Y STA $AA,X LDA #$F0 STA $8D,X B136B JSR J1380 LDA SWCHA ;Joysticks.. LSR LSR LSR LSR ;Keep bottom four bits (Left Player) ASL DIFSWCH ;Use other difficulty switch. DEX BEQ B1316 ; RTS ; B137B SEC SBC GAMSHP BPL B1358 ;If GAMSHP<A, then pass A-GAMSHP here. J1380 LDA GAMVAR BMI B138C ;If this is a tank game, AND #$01 ;check also for bit 0. BEQ B138C LDA $DB STA Color0,X ;Only then may it be Colored such. B138C LDA $99,X BEQ B13B7 LDA $D8,X STA Color0,X LDA $99,X CMP #$07 BCC J13AE BIT DIFSWCH BPL B13A2 CMP #$1C BCC J13AE B13A2 CMP #$30 BCC B13C5 CMP #$37 BCS J13CB BIT GUIDED BVC J13CB ;Branch if machine gun. J13AE LDA #$00 STA $99,X LDA #$FF B13B4 STA RESMP0,X ;Reset missile to player. RTS ; I assume we get the trigger from here. B13B7 BIT $88 BPL B13BF ;if it's negative, go ahead. LDA INPT4,X ;Read Input (Trigger) X. BPL B13F6 ;^^ Since the specs say there is no bit 7, ; I guess that means "JMP B13F6. B13BF JSR J1410 JMP J13AE B13C5 JSR J1410 JMP J13DE J13CB LDA $9F,X BEQ B13D9 JSR J1410 LDA #$30 STA $99,X JMP J13DE ; B13D9 LDA $99,X JSR J1300 J13DE LDA GTIMER AND #$03 BEQ B13F0 BIT $84 BVS B13F2 BIT $82 BVC B13F0 AND #$01 BNE B13F2 B13F0 DEC $99,X B13F2 LDA #$00 BEQ B13B4 ;Reset missiles to tanks and RTS. ;Launch a tank. B13F6 LDA #$3F STA $99,X SEC LDA TankY0,X ;Copy Y-position... SBC #$06 ;The barrel is 6 scanlines down. STA MissileY0,X LDA DIRECTN,X ;Copy player bearing to missile. STA DIRECTN+2,X LDA #$1F STA $9B,X ;9B has to do with missiles & sound. LDA #$00 STA $9D,X ;9D also has to do with missiles. JMP J13CB ; ; This routine parses the sound effects. ; J1410 LDA $9F,X BEQ B1421 ;Gunshot sound. LDA #$04 STA AUDC0,X LDA #$07 STA AUDV0,X LDA $9B,X STA AUDF0,X RTS ;Ambient sound. B1421 LDY GAMSHP LDA SNDV,Y AND $88 ;$88 affects sound too? wow. ;Perhaps speed too STA AUDV0,X ;see how it affects volume? LDA SNDC,Y STA AUDC0,X CLC LDA #$00 B1432 DEY BMI B1439 ADC #$0C BPL B1432 B1439 ADC $8B,X TAY TXA ASL ADC SNDP,Y STA AUDF0,X RTS ; ; Check to see whether, during all that drawing, ; a missile hit one of the tanks. ; J1444 LDX #$01 J1446 LDA CXM0P,X BPL B1476 BIT $84 BVC B1454 LDA $9B,X CMP #$1F BEQ B1476 ;A touch, a touch! I do confess. B1454 INC DIRECTN,X ; Turn the tanks 22.5 degrees. INC DIRECTN+2,X ;Increase player's score. ;A simple INC SCORE,X won't do because ;we're doing it in BCD. SED LDA SCORE,X CLC ADC #$01 STA SCORE,X CLD TXA CLC ADC #$FD STA $8A ;Now 8a contains loser's ID in bit 0, ;victor's ID in bit 1, and set bits ;2-7: the clock is ticking. LDA #$FF STA RESMP0 ;Reset both missiles. STA RESMP1 LDA #$00 STA AUDV0,X ;Turn off the victor's engine. STA $99 ;clear 99 STA $9A ;and 9A. RTS ; B1476 BIT GAMVAR BPL B147D ;Branch if a tank game. JMP J1501 B147D LDA $9F,X BEQ B148B CMP #$04 INC $9F,X BCC B148B LDA #$00 STA $9F,X B148B LDA CXM0FB,X ;Tank collision with ball? BMI B1496 ;If true(?), go below... LDA #$00 STA $9D,X ;clear. JMP J14D6 ; B1496 BIT $82 BVC B14D0 ;Branch if bit 6 is clear. LDA $9D,X BNE B14B7 INC $9F,X DEC $9B,X LDA DIRECTN+2,X STA $B2,X EOR #$FF STA DIRECTN+2,X INC DIRECTN+2,X LDA DIRECTN+2,X AND #$03 BNE B14B4 INC DIRECTN+2,X B14B4 JMP J14D4 ; B14B7 CMP #$01 BEQ B14C6 CMP #$03 BCC J14D4 BNE J14D4 LDA $B2,X JMP J14C8 ; ; Bounce for Tank Pong... maybe. ; If I'm reading this right, it calls for a ; complete 180-degree turn. I guess whatever ; happens after jumping to J14D4 helps a lot. ; B14C6 LDA DIRECTN+2,X J14C8 CLC ADC #$08 STA DIRECTN+2,X JMP J14D4 ; B14D0 LDA #$01 STA $99,X J14D4 INC $9D,X J14D6 LDA CXP0FB,X BMI B14DE ;check if tank collided ;with a wall. LDA CXPPMM ;check for a tank collision. BPL B14E7 B14DE LDA $8A ;See if timer has run out. CMP #$02 BCC B14ED JSR J1508 B14E7 LDA #$03 STA $E4,X BNE B1501 B14ED DEC $E4,X BMI B14F7 LDA $8B,X BEQ B1501 BNE B14F9 B14F7 INC DIRECTN,X B14F9 LDA DIRECTN,X CLC ADC #$08 ;Add 180 degrees to direction. JSR J150F J1501 B1501 DEX BMI B1507 ;Return if X<0. JMP J1446 B1507 RTS ; ; I bet this moves the missiles. ; J1508 TXA EOR #$01 TAY ; Y = NOT X LDA DIRECTN+2,Y ;Missile's Direction J150F AND #$0F TAY LDA HDGTBL,Y ;Nove JSR J127C ;Move object in that direction. LDA #$00 STA $A8,X STA $AA,X STA $8D,X ;Stop it dead in its tracks.... LDA $D8,X STA Color0,X RTS ; ; Set everything up to draw the playfield. ; ; When we find out what BB and BC are for, ; we'll keep in mind ; InitField LDX GAMSHP LDA SPRLO,X ;Appropriate something for velocity. STA SHAPES ;Velocity could double as sprite LDA SPRHI,X ;shape. STA SHAPES+1 LDA GAMVAR LSR LSR AND #$03 ;Determine maze type. TAX ;send it to X. LDA GAMVAR ;Determine game type. BPL B1546 ;If a plane game, AND #$08 ;test for clouds BEQ B1544 ;If there are any, LDX #$03 ;replace X with 3. ;That, I don't get. They wanted 3, ;that fits into two bits, so why not just ;put a 3 in there instead of going through ;all of this? BPL B1548 ;skip to next test. B1544 LDA #$80 ;Otherwise, B1546 STA $82 ;store $80 in 82. B1548 LDA GAMVAR ;Next test.. ASL ASL ;Do this again.... BIT GAMVAR BMI B1556 ;Branch if a plane game. STA WSYNC STA $84 ;Store GAMVAR*4 in 84. AND #$80 ;IF it's a tank game. B1556 STA GUIDED ;store in 83. ;GUIDED is ZERO if a tank game ;it is negative if a guided missile game, ;it is overflowed if a machine gun game. ;(Inapplicable in tank games, hence the ;previous branch trick) LDA #$F7 ;Store page F7 STA LORES+1 ;as high order byte STA LORES+3 ;for all of these pointers, STA LORES+5 ;'cause that's where it is. ;Store the proper offsets for each column of ;playfield from the vectors given LDA PLFPNT,X STA RESP0 ;Reset player 0 while we're at it. STA LORES LDA PLFPNT+4,X STA LORES+2 LDA PLFPNT+8,X STA LORES+4 RTS ; ; I think this one determines sprite shape. ; J1572 LDA GAMVAR AND #$87 BMI B157A ;If bit 7 is set, we are playing with one or more ;planes. If not, well, we can only have one tank, ;so... LDA #$00 B157A ASL TAX LDA WIDTHS,X ;The TIA's NUSIZ registers make STA NUSIZ0 ;it as easy to play with two or LDA WIDTHS+1,X ;three planes as it is for one STA NUSIZ1 ;freakin' huge bomber. LDA GAMVAR AND #$C0 LSR LSR LSR LSR ;Our hardware is now in bits 3 and 2. TAY ;Of the Y-register. ; Render joysticks immobile if game not in play. LDA $88 ;1 = Game in play STA SWCHB ;1 = Joysticks enabled. EOR #$FF AND $DD STA $D1 LDX #$FF LDA SWCHB AND #$08 BNE B15A7 LDY #$10 LDX #$0F B15A7 STX TEMP LDX #$03 B15AB LDA L1765,Y EOR $D1 AND TEMP STA COLUP0,X ;Color the real tank. STA Color0,X ;Color the virtual tank. STA $D8,X INY DEX BPL B15AB RTS ; ; Zero all memory up to $A2. Returns with zero bit set. ; ClearMem LDA #$00 B15BF INX STA $A2,X BNE B15BF ;Continue until X rolls over. RTS ; *= $15C5 ; ; Patterns for numbers ; NUMBERS .byte $0E ;| XXX | $F5C5 Leading zero is not drawn .byte $0A ; | X X | $F5C6 because it's never used. .byte $0A ; | X X | $F5C7 .byte $0A ; | X X | $F5C8 .byte $0E ; | XXX | $F5C9 .byte $22 ; | X X | $F5CA .byte $22 ; | X X | $F5CB .byte $22 ; | X X | $F5CC .byte $22 ; | X X | $F5CD .byte $22 ; | X X | $F5CE .byte $EE ; |XXX XXX | $F5CF .byte $22 ; | X X | $F5D0 .byte $EE ; |XXX XXX | $F5D1 .byte $88 ; |X X | $F5D2 .byte $EE ; |XXX XXX | $F5D3 .byte $EE ; |XXX XXX | $F5D4 .byte $22 ; | X X | $F5D5 .byte $66 ; | XX XX | $F5D6 .byte $22 ; | X X | $F5D7 .byte $EE ; |XXX XXX | $F5D8 .byte $AA ; |X X X X | $F5D9 .byte $AA ; |X X X X | $F5DA .byte $EE ; |XXX XXX | $F5DB .byte $22 ; | X X | $F5DC .byte $22 ; | X X | $F5DD .byte $EE ; |XXX XXX | $F5DE .byte $88 ; |X X | $F5DF .byte $EE ; |XXX XXX | $F5E0 .byte $22 ; | X X | $F5E1 .byte $EE ; |XXX XXX | $F5E2 .byte $EE ; |XXX XXX | $F5E3 .byte $88 ; |X X | $F5E4 .byte $EE ; |XXX XXX | $F5E5 .byte $AA ; |X X X X | $F5E6 .byte $EE ; |XXX XXX | $F5E7 .byte $EE ; |XXX XXX | $F5E8 .byte $22 ; | X X | $F5E9 .byte $22 ; | X X | $F5EA .byte $22 ; | X X | $F5EB .byte $22 ; | X X | $F5EC .byte $EE ; |XXX XXX | $F5ED .byte $AA ; |X X X X | $F5EE .byte $EE ; |XXX XXX | $F5EF .byte $AA ; |X X X X | $F5F0 .byte $EE ; |XXX XXX | $F5F1 .byte $EE ; |XXX XXX | $F5F2 .byte $AA ; |X X X X | $F5F3 .byte $EE ; |XXX XXX | $F5F4 .byte $22 ; | X X | $F5F5 .byte $EE ; |XXX XXX | $F5F6 ; ; A bunch of data read with the Y-register. ; I still don't know. ; L15F7 .BYTE $F8 ,$F7 ,$F6 ,$06 ,$06 .BYTE $06 ,$16 ,$17 ,$18 ; $15FC .BYTE $19 ,$1A ,$0A ,$0A ; $1600 .BYTE $0A ,$FA ,$F9 ,$F8 ; $1604 .BYTE $F7 ,$F6 ,$F6 ,$06 ; $1608 .BYTE $16 ,$16 ,$17 ,$18 ; $160C .BYTE $19 ,$1A ,$1A ,$0A ; $1610 .BYTE $FA ,$FA ,$F9 ,$E8 ; $1614 .BYTE $E6 ,$E4 ,$F4 ,$04 ; $1618 .BYTE $14 ,$24 ,$26 ,$28 ; $161C .BYTE $2A ,$2C ,$1C ,$0C ; $1620 .BYTE $FC ,$EC ,$EA ; $1624 ; ; Vectors for all sixteen possible headings, in 22.5 ; degree increments. This uses some sort of binary ; notation, or it might just go by nybble. I just ; haven't figured it out yet. ; HDGTBL .BYTE $C8 ,$C4 ,$C0 ,$E0 .BYTE $00 ,$20 ,$40 ,$44 .BYTE $48 ,$4C ,$4F ,$2F .BYTE $0F ,$EF ,$CF ,$CC ; ; Has to do with player velocity. Every ; even location goes to $A8,X and every ; odd location goes to $AA,X. Bit 7 is ; significant. I can't help but think ; this is a multiplication table of some ; kind. ; L1637 .BYTE $00 ,$00 ,$80 ,$80 .BYTE $84 ,$20 ,$88 ,$88 .BYTE $92 ,$48 ,$A4 ,$A4 .BYTE $A9 ,$52 ,$AA ,$AA .BYTE $D5 ,$AA ,$DA ,$DA .BYTE $DB ,$6D ,$EE ,$EE ; ; These are all the sprite shapes. ; The most I suspect any of you will do is ; modify these. And/or the number shapes. ; TankShape .byte $00 ; | | $F64F .byte $FC ; |XXXXXX | $F650 .byte $FC ; |XXXXXX | $F651 .byte $38 ; | XXX | $F652 .byte $3F ; | XXXXXX| $F653 .byte $38 ; | XXX | $F654 .byte $FC ; |XXXXXX | $F655 .byte $FC ; |XXXXXX | $F656 .byte $1C ; | XXX | $F657 .byte $78 ; | XXXX | $F658 .byte $FB ; |XXXXX XX| $F659 .byte $7C ; | XXXXX | $F65A .byte $1C ; | XXX | $F65B .byte $1F ; | XXXXX| $F65C .byte $3E ; | XXXXX | $F65D .byte $18 ; | XX | $F65E .byte $19 ; | XX X| $F65F .byte $3A ; | XXX X | $F660 .byte $7C ; | XXXXX | $F661 .byte $FF ; |XXXXXXXX| $F662 .byte $DF ; |XX XXXXX| $F663 .byte $0E ; | XXX | $F664 .byte $1C ; | XXX | $F665 .byte $18 ; | XX | $F666 .byte $24 ; | X X | $F667 .byte $64 ; | XX X | $F668 .byte $79 ; | XXXX X| $F669 .byte $FF ; |XXXXXXXX| $F66A .byte $FF ; |XXXXXXXX| $F66B .byte $4E ; | X XXX | $F66C .byte $0E ; | XXX | $F66D .byte $04 ; | X | $F66E .byte $08 ; | X | $F66F .byte $08 ; | X | $F670 .byte $6B ; | XX X XX| $F671 .byte $7F ; | XXXXXXX| $F672 .byte $7F ; | XXXXXXX| $F673 .byte $7F ; | XXXXXXX| $F674 .byte $63 ; | XX XX| $F675 .byte $63 ; | XX XX| $F676 .byte $24 ; | X X | $F677 .byte $26 ; | X XX | $F678 .byte $9E ; |X XXXX | $F679 .byte $FF ; |XXXXXXXX| $F67A .byte $FF ; |XXXXXXXX| $F67B .byte $72 ; | XXX X | $F67C .byte $70 ; | XXX | $F67D .byte $20 ; | X | $F67E .byte $98 ; |X XX | $F67F .byte $5C ; | X XXX | $F680 .byte $3E ; | XXXXX | $F681 .byte $FF ; |XXXXXXXX| $F682 .byte $FB ; |XXXXX XX| $F683 .byte $70 ; | XXX | $F684 .byte $38 ; | XXX | $F685 .byte $18 ; | XX | $F686 .byte $38 ; | XXX | $F687 .byte $1E ; | XXXX | $F688 .byte $DF ; |XX XXXXX| $F689 .byte $3E ; | XXXXX | $F68A .byte $38 ; | XXX | $F68B .byte $F8 ; |XXXXX | $F68C .byte $7C ; | XXXXX | $F68D .byte $18 ; | XX | $F68E JetShape .byte $60 ; | XX | $F68F .byte $70 ; | XXX | $F690 .byte $78 ; | XXXX | $F691 .byte $FF ; |XXXXXXXX| $F692 .byte $78 ; | XXXX | $F693 .byte $70 ; | XXX | $F694 .byte $60 ; | XX | $F695 .byte $00 ; | | $F696 .byte $00 ; | | $F697 .byte $C1 ; |XX X| $F698 .byte $FE ; |XXXXXXX | $F699 .byte $7C ; | XXXXX | $F69A .byte $78 ; | XXXX | $F69B .byte $30 ; | XX | $F69C .byte $30 ; | XX | $F69D .byte $30 ; | XX | $F69E .byte $00 ; | | $F69F .byte $03 ; | XX| $F6A0 .byte $06 ; | XX | $F6A1 .byte $FC ; |XXXXXX | $F6A2 .byte $FC ; |XXXXXX | $F6A3 .byte $3C ; | XXXX | $F6A4 .byte $0C ; | XX | $F6A5 .byte $0C ; | XX | $F6A6 .byte $02 ; | X | $F6A7 .byte $04 ; | X | $F6A8 .byte $0C ; | XX | $F6A9 .byte $1C ; | XXX | $F6AA .byte $FC ; |XXXXXX | $F6AB .byte $FC ; |XXXXXX | $F6AC .byte $1E ; | XXXX | $F6AD .byte $06 ; | XX | $F6AE .byte $10 ; | X | $F6AF .byte $10 ; | X | $F6B0 .byte $10 ; | X | $F6B1 .byte $38 ; | XXX | $F6B2 .byte $7C ; | XXXXX | $F6B3 .byte $FE ; |XXXXXXX | $F6B4 .byte $FE ; |XXXXXXX | $F6B5 .byte $10 ; | X | $F6B6 .byte $40 ; | X | $F6B7 .byte $20 ; | X | $F6B8 .byte $30 ; | XX | $F6B9 .byte $38 ; | XXX | $F6BA .byte $3F ; | XXXXXX| $F6BB .byte $3F ; | XXXXXX| $F6BC .byte $78 ; | XXXX | $F6BD .byte $60 ; | XX | $F6BE .byte $40 ; | X | $F6BF .byte $60 ; | XX | $F6C0 .byte $3F ; | XXXXXX| $F6C1 .byte $1F ; | XXXXX| $F6C2 .byte $1E ; | XXXX | $F6C3 .byte $1E ; | XXXX | $F6C4 .byte $18 ; | XX | $F6C5 .byte $18 ; | XX | $F6C6 .byte $00 ; | | $F6C7 .byte $83 ; |X XX| $F6C8 .byte $7F ; | XXXXXXX| $F6C9 .byte $3E ; | XXXXX | $F6CA .byte $1E ; | XXXX | $F6CB .byte $0C ; | XX | $F6CC .byte $0C ; | XX | $F6CD .byte $0C ; | XX | $F6CE PlaneShape .byte $00 ; | | $F6CF .byte $8E ; |X XXX | $F6D0 .byte $84 ; |X X | $F6D1 .byte $FF ; |XXXXXXXX| $F6D2 .byte $FF ; |XXXXXXXX| $F6D3 .byte $04 ; | X | $F6D4 .byte $0E ; | XXX | $F6D5 .byte $00 ; | | $F6D6 .byte $00 ; | | $F6D7 .byte $0E ; | XXX | $F6D8 .byte $04 ; | X | $F6D9 .byte $8F ; |X XXXX| $F6DA .byte $7F ; | XXXXXXX| $F6DB .byte $72 ; | XXX X | $F6DC .byte $07 ; | XXX| $F6DD .byte $00 ; | | $F6DE .byte $10 ; | X | $F6DF .byte $36 ; | XX XX | $F6E0 .byte $2E ; | X XXX | $F6E1 .byte $0C ; | XX | $F6E2 .byte $1F ; | XXXXX| $F6E3 .byte $B2 ; |X XX X | $F6E4 .byte $E0 ; |XXX | $F6E5 .byte $40 ; | X | $F6E6 .byte $24 ; | X X | $F6E7 .byte $2C ; | X XX | $F6E8 .byte $5D ; | X XXX X| $F6E9 .byte $1A ; | XX X | $F6EA .byte $1A ; | XX X | $F6EB .byte $30 ; | XX | $F6EC .byte $F0 ; |XXXX | $F6ED .byte $60 ; | XX | $F6EE .byte $18 ; | XX | $F6EF .byte $5A ; | X XX X | $F6F0 .byte $7E ; | XXXXXX | $F6F1 .byte $5A ; | X XX X | $F6F2 .byte $18 ; | XX | $F6F3 .byte $18 ; | XX | $F6F4 .byte $18 ; | XX | $F6F5 .byte $78 ; | XXXX | $F6F6 .byte $34 ; | XX X | $F6F7 .byte $36 ; | XX XX | $F6F8 .byte $5A ; | X XX X | $F6F9 .byte $78 ; | XXXX | $F6FA .byte $2C ; | X XX | $F6FB .byte $0C ; | XX | $F6FC .byte $06 ; | XX | $F6FD .byte $0C ; | XX | $F6FE .byte $08 ; | X | $F6FF .byte $6C ; | XX XX | $F700 .byte $70 ; | XXX | $F701 .byte $B8 ; |X XXX | $F702 .byte $DC ; |XX XXX | $F703 .byte $4E ; | X XXX | $F704 .byte $07 ; | XXX| $F705 .byte $06 ; | XX | $F706 .byte $38 ; | XXX | $F707 .byte $10 ; | X | $F708 .byte $F0 ; |XXXX | $F709 .byte $7C ; | XXXXX | $F70A .byte $4F ; | X XXXX| $F70B .byte $E3 ; |XXX XX| $F70C .byte $02 ; | X | $F70D .byte $00 ; | | $F70E ; ; These are sub-pointers, used to set up the ; two-dimensional array at CTRLTBL. ; L170F .BYTE $00 ,$0B ,$16 ; ; Two-dimensional array, 12x3. ; ; This array specifies what the joystick does ; in each game. Looking at it now the format looks ; like this: ; ; Low nybble = Amount to rotate object (signed) ; $00 = Not at all ; $01 = Clockwise (+1) ; $0F = Counter-clockwise (-1) ; High nybble = Speed to move object (unsigned) ; $00 = Not moving ; $F0 = Warp speed ; ; Observe the $FF's. Notice how indexing out of bounds with impossible ; joystick movements will cause strange behavior. ; ; Tank movement ; UP DOWN (No reverse) CTRLTBL .BYTE $00 ,$10 ,$00 ,$FF .BYTE $01 ,$11 ,$01 ,$FF ;LEFT .BYTE $0F ,$1F ,$0F ;RIGHT ; ; Biplane movement (This is why controls are sideways) ; UP DOWN .BYTE $50 ,$5F ,$51 ,$FF ; .BYTE $30 ,$3F ,$31 ,$FF ;LEFT .BYTE $70 ,$7F ,$71 ;RIGHT ; ; Jet fighter movement ; UP DOWN .BYTE $90 ,$B0 ,$70 ,$FF ; .BYTE $91 ,$B1 ,$71 ,$FF ;LEFT .BYTE $9F ,$BF ,$7F ;RIGHT ; ORG $1733 ; Sound information for different game types. ; Different tools of destruction make different ; sound. ; ; There is some more data below which looks to ; be other information; different machines at ; different speeds. However this is reached, ; this could be called a three-dimensional array. ; ; Tanks Biplane, Jet Fighter SNDV .BYTE $08 ,$02 ,$02 ; sound volumes SNDC .BYTE $02 ,$03 ,$08 ; sound types SNDP .BYTE $1D ,$05 ,$00 ; sound pitches .BYTE $00 ,$00 ,$00 ,$00 ; $173C .BYTE $00 ,$00 ,$00 ,$00 ; $1740 .BYTE $00 ,$00 ,$00 ,$1D ; $1747 .BYTE $1D ,$16 ,$16 ; $174A .BYTE $0F ,$0F ,$00 .BYTE $00 ,$00 ,$00 ; $174E .BYTE $00 ,$00 ,$00 ; $1751 .BYTE $00 ,$00 ,$12 ; $1754 .BYTE $10 ,$10 ,$0C ; $1757 .BYTE $0C ,$07 ,$07 ; $175A ORG $175D ; ; Player widths for various plane games. ; Through the miracle of the Atari 2600's NUSIZ ; register, the difference between a 1 vs. 1 game ; and a Bomber vs. 3 game is contained in just ; two bytes. ; WIDTHS .BYTE $00 ,$00 ;1 vs. 1 .BYTE $01 ,$01 ;2 vs. 2 .BYTE $00 ,$03 ;1 vs. 3 .BYTE $27 ,$03 ;Bomber vs. 3 ORG $1765 L1765: .byte $EA ; |XXX X X | $F765 .byte $3C ; | XXXX | $F766 .byte $82 ; |X X | $F767 .byte $44 ; | X X | $F768 .byte $32 ; | XX X | $F769 .byte $2C ; | X XX | $F76A .byte $8A ; |X X X | $F76B .byte $DA ; |XX XX X | $F76C .byte $80 ; |X | $F76D .byte $9C ; |X XXX | $F76E .byte $DA ; |XX XX X | $F76F .byte $3A ; | XXX X | $F770 .byte $64 ; | XX X | $F771 .byte $A8 ; |X X X | $F772 .byte $DA ; |XX XX X | $F773 .byte $4A ; | X X X | $F774 PFWall1 .byte $08 ; | X | $F775 .byte $04 ; | X | $F776 .byte $00 ; | | $F777 .byte $0E ; | XXX | $F778 .byte $F0 ; |XXXX | $F779 .byte $10 ; | X | $F77A .byte $10 ; | X | $F77B .byte $10 ; | X | $F77C .byte $10 ; | X | $F77D .byte $10 ; | X | $F77E .byte $10 ; | X | $F77F .byte $10 ; | X | $F780 .byte $10 ; | X | $F781 .byte $10 ; | X | $F782 .byte $10 ; | X | $F783 .byte $10 ; | X | $F784 .byte $FF ; |XXXXXXXX| $F785 .byte $00 ; | | $F786 .byte $00 ; | | $F787 .byte $00 ; | | $F788 .byte $38 ; | XXX | $F789 .byte $00 ; | | $F78A .byte $00 ; | | $F78B .byte $00 ; | | $F78C .byte $60 ; | XX | $F78D .byte $20 ; | X | $F78E .byte $20 ; | X | $F78F .byte $23 ; | X XX| $F790 .byte $FF ; |XXXXXXXX| $F791 .byte $80 ; |X | $F792 .byte $80 ; |X | $F793 .byte $00 ; | | $F794 .byte $00 ; | | $F795 .byte $00 ; | | $F796 .byte $1C ; | XXX | $F797 .byte $04 ; | X | $F798 PFWall2 .byte $00 ; | | $F799 .byte $00 ; | | $F79A .byte $00 ; | | $F79B .byte $00 ; | | $F79C .byte $FF ; |XXXXXXXX| $F79D .byte $00 ; | | $F79E .byte $00 ; | | $F79F .byte $00 ; | | $F7A0 .byte $00 ; | | $F7A1 .byte $00 ; | | $F7A2 .byte $00 ; | | $F7A3 .byte $00 ; | | $F7A4 .byte $00 ; | | $F7A5 .byte $00 ; | | $F7A6 .byte $00 ; | | $F7A7 .byte $00 ; | | $F7A8 .byte $00 ; | | $F7A9 .byte $07 ; | XXX| $F7AA .byte $1F ; | XXXXX| $F7AB .byte $3F ; | XXXXXX| $F7AC .byte $7F ; | XXXXXXX| $F7AD .byte $FF ; |XXXXXXXX| $F7AE .byte $00 ; | | $F7AF .byte $00 ; | | $F7B0 .byte $00 ; | | $F7B1 .byte $00 ; | | $F7B2 .byte $00 ; | | $F7B3 .byte $00 ; | | $F7B4 .byte $00 ; | | $F7B5 .byte $00 ; | | $F7B6 .byte $60 ; | XX | $F7B7 .byte $20 ; | X | $F7B8 .byte $21 ; | X X| $F7B9 .byte $FF ; |XXXXXXXX| $F7BA .byte $00 ; | | $F7BB .byte $00 ; | | $F7BC .byte $00 ; | | $F7BD .byte $80 ; |X | $F7BE .byte $80 ; |X | $F7BF .byte $80 ; |X | $F7C0 .byte $80 ; |X | $F7C1 .byte $00 ; | | $F7C2 .byte $00 ; | | $F7C3 .byte $00 ; | | $F7C4 .byte $07 ; | XXX| $F7C5 ; Addresses for Sprite Graphics SPRLO .BYTE #<TankShape, #<PlaneShape, #<JetShape SPRHI .BYTE #>TankShape, #>PlaneShape, #>JetShape ; Playfield address data ; ; Complex, None, Simple, Clouds PLFPNT .BYTE $75 ,$75 ,$75 ,$9A .BYTE $81 ,$99 ,$AA ,$9D .BYTE $8D ,$99 ,$B6 ,$9D ; Format of game, best guess I have so far... ; ; bits ; 1,0: TANKS PLANES ; 00 = Normal 1 vs. 1 ; 01 = Invisible 2 vs. 2 ; 10 = 3 vs. 1 ; 11 = 3 vs. Giant ; 3,2: 01 = No maze ; 10 = Simple maze or clouds ; 00 = Complex maze or no clouds ; 4: Tanks, 1 = Must bounce to score hit ; Planes, 1 = Machine Gun ; 5: 1 = Guided Missiles ; 7,6: 00 = Tanks ; 01 = Tank Pong ; 10 = Biplanes ; 11 = Jet Fighter ; (Bit 7 controls whether this is a tank or plane game) ; VARDATA .BYTE $24 ;Game 1: 0010 0100 TANK .BYTE $28 ;Game 2: 0010 1000 .BYTE $08 ;Game 3: 0000 1000 .BYTE $20 ;Game 4: 0010 0000 .BYTE $00 ;Game 5: 0000 0000 .BYTE $48 ;Game 6: 0100 1000 TANK PONG .BYTE $40 ;Game 7: 0100 0000 .BYTE $54 ;Game 8: 0101 0100 .BYTE $58 ;Game 9: 0101 1000 .BYTE $25 ;Game 10: 0010 0101 INVISIBLE TANK .BYTE $29 ;Game 11: 0010 1001 .BYTE $49 ;Game 12: 0100 1001 .BYTE $55 ;Game 13: 0101 0101 .BYTE $59 ;Game 14: 0101 1001 .BYTE $A8 ;Game 15: 1010 1000 BIPLANE .BYTE $88 ;Game 16: 1000 1000 .BYTE $98 ;Game 17: 1001 1000 .BYTE $90 ;Game 18: 1001 0000 .BYTE $A1 ;Game 19: 1010 0001 .BYTE $83 ;Game 20: 1000 0011 .BYTE $E8 ;Game 21: 1110 1000 JET FIGHTER .BYTE $C8 ;Game 22: 1100 1000 .BYTE $E0 ;Game 23: 1110 0000 .BYTE $C0 ;Game 24: 1100 0000 .BYTE $E9 ;Game 25: 1110 1001 .BYTE $E2 ;Game 26: 1110 0010 .BYTE $C1 ;Game 27: 1100 0001 ; $FF to signify end of game variations. ; Theoretically one could add up to six ; additional variations. .BYTE $FF ORG $17FC .word $f000 ; Reset L17FE .BYTE $0F, $11 ; IRQ - (used as pitch for sound generator) ; ; Recent changes: ; ; 08/05/96: Added dollar-signs to signify hex numbers. ; The original, strangely, omitted them. ; Started update list at end of document. ; Still have no clue where the joystick code ; is.... ; ; 08/12/96: Figured out some joystick code, now that ; I understand how they work. Renamed GAMSHP ; because it wasn't really "velocity", but ; really the tank type. Velocity is now ; what it should be. ; ; 10/19/96: Cracked the mystery of the joystick-port ; write. No, Tim, it's not an LED, it's for ; disabling the joystick when in game select ; mode. Thanks to AlanD for this theory. ; ; 2/21/97: Added cycle counting to score drawing section. ; I'm sure Kaplan wasn't this precise, but it ; is a bit helpful. ; ; 2/26/97: Changed year of above update to 1997. :-) ; Changed a few variable names and made some of ; my notes a bit clearer. I'm also naming some ; of those mysterious JSR's. Plus, it actually ; COMPILES with DASM. Whee! ; ; 8/26/97: Oops. Turns out Larry Wagner made Combat. Sorry.