Subject: [stella] Better Music Driver Demo From: Paul Slocum <paul-stella@xxxxxxxxxxxxxx> Date: Sun, 03 Feb 2002 02:54:17 -0600 |
SAUDC0 = $15 SAUDF0 = $17 SAUDV0 = $19 ; Song Data ; ---------------------------------------------------------- ; song1 and song2 are lists of patterns to be played ; out of the patternArray. ; They are played simlutaneously using the two oscillators song1 byte 2, 4, 6, 6 byte 2, 4, 6, 6 byte 20,22,20,24 byte 20,22,20,42 byte 2, 4,6,44 byte 2, 4,6,6 byte 20,22,20,24 byte 20,22,20,42 byte 2, 4,6,44 byte 2, 4,6,6 byte 12, 40, 12,36 byte 34, 34, 34,38 byte 12, 40, 12,36 byte 34, 34, 34,38 byte 12, 40, 12,36 byte 48, 48, 34,38 byte 52, 52, 12,36 byte 52, 52, 12,36 byte 50, 50, 34,38 byte 48, 48, 34,38 byte 52, 52, 12,36 byte 52, 52, 12,0 byte 12, 40, 12,36 byte 34, 34, 34,38 byte 12, 40, 12,36 byte 34, 34, 34,38 byte 255 ; intro byte 16 byte 255 song2 byte 8,10,12,12 byte 8,10,12,12 byte 26,12,28,12 byte 26,12,28,12 byte 30,12,32,32 byte 30,12,32,32 byte 26,12,28,12 byte 26,12,28,12 byte 30,12,32,32 byte 30,12,32,32 byte 14,14,14,14 byte 14,14,14,14 byte 14,14,14,14 byte 14,14,14,14 byte 46,46,46,46 byte 46,46,46,46 byte 46,46,46,46 byte 46,46,46,46 byte 46,46,46,46 byte 46,46,46,46 byte 46,46,46,46 byte 46,46,46,46 byte 14,14,14,14 byte 14,14,14,14 byte 14,14,14,14 byte 14,14,14,14 byte 255 ;intro byte 18 byte 255 patternArray word patternMute, bass1 ;0 2 word bass2, bass3 ;4 6 word piano1, piano2 ;8 10 word beat1, hat ;12 14 word introbeat, intropiano ;16 18 word bass4, bass5 ;20 22 word bass6, verse1 ;24 26 word verse2, chorus1 ;28 30 word chorus2, beat2 ;32 34 word beat1fill, beat2fill;36 38 word beat1fill2, bass6leadin;40 42 word bass3leadin, chorusAlt ;44 46 word chorusAlt2, chorusAlt3 ;48 50 word chorusAlt4 ;52 ; Pattern Data ; ---------------------------------------------------------- ; ; The patterns are made up of 32 numbers (bytes) of note data followed ; by 4 numbers (bytes) of accent data. ; ; Note Encoding ; ---------------------------------------------------------- ; ; The 32 note numbers are encoded with sound type and pitch. ; ; The first three bits (1's and 0's) determine the ; sound type according to the following table: ; ; 000 Square ; 001 Bass ; 010 Pitfall ; 011 Noise ; 100 Buzz ; 101 Lead ; 110 Saw ; 111 Engine ; ; The remaining 5 bits determine the pitch. ; ; 11111 is a very low pitch ; 00001 us a very high pitch ; 00100 is somewhere in between ; ; Synthcart major scale: ; ; 29=11101 26=11010 23=10111 ; 19=10011 17=10001 15=01111 ; 14=01110 11=01011 9=01001 ; 4=00100 2=00010 1=00001 ; ; (!) Note that 255 or %11111111 means no sound (a rest) ; ; Accent Encoding ; ---------------------------------------------------------- ; ; The four numbers at the end of the pattern data ; that look like this: ; ; byte #%10001000, #%10001000, #%10001000, #%10001000 ; ; determine which notes are accented. The 32 bits ; from left to right correspond to the 32 notes in ; the pattern. 0=no accent, 1=accent chorus1 byte %10101110, %10101110 byte %10101110, %10101110 byte %10101111, %10101111 byte %10101111, %10101111 byte %10110001, %10110001 byte %10110001, %10110001 byte %10110011, %10110011 byte %10110011, %10110011 byte %10101111, %10101111 byte %10101111, %10101111 byte %10101111, %10101111 byte 255, 255 byte %10110001, %10110001 byte %10110001, %10110001 byte %10110011, %10110011 byte %10110011, %10110011 byte #%11001100, #%11001100, #%11000000, #%11001100 chorusAlt byte %10110111, 255 byte %10110111, 255 byte %10110111, 255 byte %10110111, 255 byte %10110011, 255 byte %10110011, 255 byte %10110011, 255 byte %10110011, 255 byte %10101111, 255 byte %10101111, 255 byte %10101111, 255 byte %10101111, 255 byte %10110011, 255 byte %10110011, 255 byte %10110011, 255 byte %10110011, 255 byte #%00000000, #%00000000, #%00000000, #%00000000 chorusAlt2 byte %10101110, 255 byte %10101110, 255 byte %10101111, 255 byte %10101111, 255 byte %01100101, 255 byte %10110001, 255 byte %10110011, 255 byte %10110011, 255 byte %10101111, 255 byte %10101111, 255 byte %10101111, 255 byte 255, 255 byte %01100101, 255 byte %10110001, 255 byte %10110011, 255 byte %10110011, 255 byte #%11001100, #%11001100, #%11000000, #%11001100 chorusAlt3 byte %10110111, %10101001 byte %10110111, %10101001 byte %10110111, %10101001 byte %10110111, %10101001 byte %01100101, %10101001 byte %10110011, %10101001 byte %10110011, %10101011 byte %10110011, %10101011 byte %10101111, %10110111 byte %10101111, %10110111 byte %10101111, %10110111 byte %10101111, %10110111 byte %01100101, %10110111 byte %10110011, %10110111 byte %10110011, %10110111 byte %10110011, %10110111 byte #%00000000, #%00000000, #%00000000, #%00000000 chorusAlt4 byte %11111110, %11111010 byte %10110001, 255 byte %10101111, 255 byte %10110001, 255 byte %01100101, 255 byte %10110001, 255 byte %10101111, 255 byte %10110001, 255 byte %11111110, %11111010 byte %10110001, 255 byte %10101111, 255 byte %10110001, 255 byte %01100101, 255 byte %10110001, 255 byte %10101111, 255 byte %10110001, 255 byte #%11001100, #%11001100, #%11000000, #%11001100 chorus2 byte %10101111, %10101111 byte %10101111,255 byte %01100001, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110111,255 byte 255,255 byte %11111110, %11111010 byte 255, 255 byte %10110111, 255 byte 255, 255 byte %01000101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%11000000, #%11101000, #%10001000, #%00000000 verse1 byte %10110111, %10110111 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110011, %10110011 byte 255, 255 byte %10110111, %11111010 byte 255, 255 byte %01000101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%11001000, #%10001000, #%11001000, #%00001000 verse2 byte %10110111, %10110111 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110001, %10110001 byte %10110001, %10110001 byte %10110011, %11110011 byte %10110111, %11111010 byte %01000101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%10001000, #%10001000, #%11001000, #%00001000 bass4 byte %10110111, %10110111 byte %01100000, 255 byte %10110111, 255 byte %01100000, 255 byte %01100101, 255 byte %01100000, 255 byte %01100000, 255 byte %01100000, 255 byte %10110111, %10110111 byte %10110111,255 byte %01100101, 255 byte 255,255 byte %01100101, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %11001000, %10000000, %11001100, %10000000 bass5 byte %10101111, %10101111 byte %10101111,255 byte %10101111, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %01100000, 255 byte 255,255 byte %10101111, %10101111 byte %10101111,255 byte %10101111, 255 byte 255,255 byte %01100101, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %00000000, %10000000, %00000000, %10000000 bass6 byte %10110001, %10110001 byte %10110001,255 byte %10110001, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %01100000, 255 byte 255,255 byte %10110001, %10110001 byte %10110001,255 byte %10110001, 255 byte 255,255 byte %01100101, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %00000000, %10000000, %00000000, %10000000 bass6leadin byte %10110001, %10110001 byte %10110001,255 byte %10110001, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte 255, 255 byte 255,255 byte %10110001, %10110001 byte %10110001,255 byte %10110001, 255 byte 255,255 byte 255, 255 byte 255, 255 byte %10101111, %10101111 byte %10101111, %10101111 byte %00000000, %10000000, %00000000, %10000000 introbeat byte 255,255 byte 255,255 byte 255,255 byte 255,255 byte 255,255 byte 255,255 byte 255,255 byte 255,255 byte 255,255 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100101, 255 byte 255, 255 byte #%10001000, #%00001000, #%10000000, #%10001000 intropiano byte 255, 255 byte 255, 255 byte 255, 255 byte 255,255 byte 255, 255 byte 255, 255 byte 255, 255 byte 255,255 byte 255, 255 byte 255, 255 byte %10110001, %10110001 byte %10110001, %10110001 byte %10101110, %10101110 byte 255, 255 byte 255, 255 byte 255, 255 byte %11001000, %10001000, %11001100, %10001000 beat1 byte %11111110, %11111010 byte 255,255 byte %01100001, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %01100001, 255 byte 255,255 byte %11111110, %11111010 byte 255, 255 byte %11111110, %11111010 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%10000000, #%10000000, #%10000000, #%10000000 beat1fill byte %11111110, %11111010 byte 255,255 byte %01100001, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %01100001, 255 byte 255,255 byte %11111110, %11111010 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%10000000, #%10000000, #%10001000, #%10000000 beat1fill2 byte %11111110, %11111010 byte 255,255 byte %01100001, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %01100001, 255 byte 255,255 byte %11111110, %11111010 byte %01100101, 255 byte %01100001, 255 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%10000000, #%10000000, #%11100000, #%10000000 piano2 byte 255,255 byte 255,255 byte %10101110, %10101110 byte %10101110, 255 byte %10101011, %10101011 byte 255, 255 byte %10101001, 255 byte 255, 255 byte %10101011, %10101011 byte 255, 255 byte %10101110, 255 byte 255, 255 byte %10101111, %10101110 byte 255, 255 byte %10110001, %10110001 byte %10110001, 255 byte %11001000, %10001000, %11001100, %10001000 piano1 byte %10101110, %10101110 byte %10101011, %10101011 byte %01100000, 255 byte 255,255 byte %10101110, %10101011 byte %10101011, %10101011 byte %01100000, 255 byte 255,255 byte %10101110, %10101110 byte %10101110, 255 byte %10110001, %10110001 byte 255, 255 byte %10110011, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %11001000, %10001000, %11001100, %10001000 bass1 byte %10110111, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %01100000, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %10110111, 255 byte 255,255 byte %01100101, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %10001000, %10000000, %10001000, %10000000 bass2 byte %10101111, %10101111 byte %10101111, %10101111 byte %10101111, 255 byte 255,255 byte %01100101, 255 byte 255,255 byte %10110001, %10110001 byte %10110001, %10110001 byte %10110001, %10110001 byte %10110001, 255 byte %01100000, 255 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %00000000, %10000000, %00000000, %10000000 bass3 byte %10101111, %10101111 byte %10101111, %10101111 byte 255,255 byte 255,255 byte %01100101, 255 byte 255,255 byte %10110111, %10110111 byte 255,255 byte 255, 255 byte 255, 255 byte %10110111, %10110111 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %11001000, %10000000, %11001100, %10000000 bass3leadin byte %10101111, %10101111 byte %10101111, %10101111 byte 255,255 byte 255,255 byte %01100101, 255 byte 255,255 byte %10110111, %10110111 byte 255,255 byte 255, 255 byte 255, 255 byte %10110111, %10110111 byte 255, 255 byte %01100101, 255 byte 255, 255 byte %10101111, %10101111 byte %10101111, %10101111 byte %11001000, %10000000, %11001100, %10000000 hat byte %01100000, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte 255, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte 255, 255 byte 255, 255 byte %01100000, 255 byte 255, 255 byte #%00000000, #%00000000, #%00000000, #%00000000 beat2 byte %11111110, %11111010 byte 255,255 byte %01100001, 255 byte 255,%11100101 byte %01100101, 255 byte 255,255 byte %01100001, 255 byte 255,255 byte %11111110, %11111010 byte 255, 255 byte %11111110, %11111010 byte 255,%11100101 byte %01100101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%10000000, #%10000000, #%10000000, #%10000000 beat2fill byte %11111110, %11111010 byte 255,255 byte %01100001, 255 byte 255,%11100101 byte %01100101, 255 byte 255,255 byte %01100001, 255 byte 255,255 byte %11111110, %11111010 byte 255, 255 byte %01100101, 255 byte 255,%11100101 byte %01100101, 255 byte 255, 255 byte %01100001, 255 byte 255, 255 byte #%10000000, #%10000000, #%10001000, #%10000000 patternMute byte 255,255,255,255 byte 255,255,255,255 byte 255,255,255,255 byte 255,255,255,255 byte 255,255,255,255 byte 255,255,255,255 byte 255,255,255,255 byte 255,255,255,255 soundTypeArray byte 4,6,7,8 byte 15,12,1,3 ;-------------------------------------------------------------------------- ; Accent Reader ;-------------------------------------------------------------------------- ; Each set of pattern data is followed by 4 accept bytes. ; Each bit in order represents the accent (on or off) ; of its corresponding 32nd note. This function ; returns the attenuation of a note in a pattern. ; ; - temp16 must contain an indirect pointer to the pattern data ; - Y must contain the current 32nd note (beat) ; ; = will return the volume in ACC ; ; changes X,Y,ACC ;-------------------------------------------------------------------------- bitMaskArray byte #%10000000 byte #%01000000 byte #%00100000 byte #%00010000 byte #%00001000 byte #%00000100 byte #%00000010 byte #%00000001 accentReader ; There are 4 accent bytes. Get the ; correct one. tya pha and #%00011000 lsr lsr lsr ; The 4 accent bytes are after the 32 bytes ; that make up the pattern. clc adc #32 tay ; Now set up a mask for the bit pla and #%00000111 tax lda (temp16L),y and bitMaskArray,x beq noAccent ; It's an Accent, so don't attenuate lda #15 rts noAccent ; No accent, so use a lower volume lda #5 rts ; accentReader ;-------------------------------------------------------------------------- ; Extract Pattern Data ;-------------------------------------------------------------------------- ; Each byte of pattern data contains the frequency and ; sound type data. This function separates and decodes them. ; ; The encoding is: the 3 high bits contain the encoded sound ; type and the lower 5 bits contain the freq data. ; ; - ACC must contain pattern byte ; ; = ACC will return the freq ; = X will return the sound type ; ; changes ACC,X ;-------------------------------------------------------------------------- extractPatternData cmp #255 beq noNote tax ; Extract freq data and push it and #%00011111 pha txa lsr lsr lsr lsr lsr tax lda soundTypeArray,x tax pla rts noNote lda #255 rts ; extractPatternData : other rts ;-------------------------------------------------------------------------- ; playPattern ;-------------------------------------------------------------------------- ; Plays a pattern ; ; - X should contain the offset in the patternArray of the pattern to play ; - ACC should contain the oscillator to be used (0 or 1) ; ;-------------------------------------------------------------------------- playPattern ; save osc number sta temp ; Get address of selected pattern lda patternArray,x sta temp16L inx lda patternArray,x sta temp16H ; The variable, beat, contains the 32nd note ; that the beat is currently on. lda beat and #%00011111 tay lda (temp16L),y jsr extractPatternData ; Get the osc number again ldy temp sta SAUDF0,y stx SAUDC0,y cmp #255 beq noteOff1 tax lda beat and #%00011111 tay txa jsr accentReader ; Get the osc number again ldy temp sta SAUDV0,y rts noteOff1 lda #0 ldy temp sta SAUDV0,y rts ; playPattern ;-------------------------------------------------------------------------- ; songPlayer ;-------------------------------------------------------------------------- ; Plays up to two pre-programmed patterns simlutaneously. ; ; Call this once per screen-draw. ;-------------------------------------------------------------------------- songPlayer ; Tempo ;-------------------------------------------------------------------------- ; I'm using the top 3 bits of the beat as a tempo counter. ; I increase the beat number every 3 screen draws. lda beat and #%11100000 beq tempoStep1 cmp #%00100000 beq tempoStep2 ;reset tempo count lda beat and #%00011111 sta beat tax inx stx beat cpx #32 bne quitTempo inc measure lda #0 sta beat jmp quitTempo tempoStep1 lda beat ora #%00100000 sta beat jmp quitTempo tempoStep2 lda beat ora #%01100000 sta beat quitTempo ; Now the actual player ;-------------------------------------------------------------------------- ldy measure ldx song1,y ; Check to see if the end of the song was reached cpx #255 bne notEndOfSong ; Go back to the first measure ldy #0 sty measure ldx song1,y notEndOfSong lda #0 ; oscillator zero jsr playPattern ldy measure ldx song2,y lda #1 ; oscillator one jsr playPattern rts ; songPlayer
; 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 ;--------------------------------------------------------------------------- ; Song player variables temp = TEMP ; 16 bit temp temp16L = NUMG0 temp16H = NUMG1 ; Metrenome stuff beat = $F4 measure = $F5 ;selectSwitch = $DB ;tempoCount = $D9 audioDefer = temp DAUDC0 = audioDefer DAUDV0 = audioDefer DAUDF0 = audioDefer 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 songSetup ; JSR J11A3 MLOOP JSR NWSCR ; $1014 ; JSR ConSwitch JSR excuseMe 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 DAUDV0,X ;Sound effects. BOOOM! LDA #$08 STA DAUDC0,X LDA L17FE,X STA DAUDF0,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 DAUDC0,X LDA #$07 STA DAUDV0,X LDA $9B,X STA DAUDF0,X RTS ;Ambient sound. B1421 LDY GAMSHP LDA SNDV,Y AND $88 ;$88 affects sound too? wow. ;Perhaps speed too STA DAUDV0,X ;see how it affects volume? LDA SNDC,Y STA DAUDC0,X CLC LDA #$00 B1432 DEY BMI B1439 ADC #$0C BPL B1432 B1439 ADC $8B,X TAY TXA ASL ADC SNDP,Y STA DAUDF0,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 DAUDV0,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) ;------------------------------------------------------------------------- ; Song player stuff excuseMe ;DEBUG ; JMP ConSwitch ; When the select button is pressed ; the memory is cleared which takes ; a bunch of extra cycles, so skip ; the song player. LDA SWCHB ; Select button. ??? AND #$02 BEQ noPlayer jsr songPlayer noPlayer JMP ConSwitch ;------------------------------------------------------------------------- ; This is called at program startup. ; Init song variables here songSetup lda #105 sta measure JMP J11A3 include songplay.h ORG $1FFC .word $f000 ; Reset L1FFE .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.
Attachment:
combrock.bin
Description: Binary data
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[stella] Song Player, Paul Slocum | Thread | Re: [stella] Better Music Driver De, Thomas Jentzsch |
Re: [stella] Perfect BIN copy prote, Roger Williams | Date | Re: [stella] Perfect BIN copy prote, Thomas Jentzsch |
Month |