Skip to content

Instantly share code, notes, and snippets.

@sehugg
Created December 9, 2018 14:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sehugg/bdd58f3c6f7964f9022b9e273d8c7394 to your computer and use it in GitHub Desktop.
Save sehugg/bdd58f3c6f7964f9022b9e273d8c7394 to your computer and use it in GitHub Desktop.
Star Castle 2600 by Scott Williamson (from http://starcastle2600.blogspot.com/p/star-castle-2600-story.html)
;----------------------
; Star Castle
; By Scott Williamson
; Started 2/6/2008
; CX2655
;----------------------
;
; TODO
;
;----------------------
;
; SCORING
; OUTER RING SEGMENT 10
; MIDDLE RING SEGMENT 20
; INNER RING SEGMENT 30
; CANNON 1440 + 1 SHIP
;
;----------------------
;
; For the purposes of Stella programming, a single television "frame" consists of 262 horizontal lines,
; and each line is divided by 228 clock counts (3.58MHz). The actual TV picture is drawn line by line
; from the top down 60 times a second, and actaully consists of only a portion of the entire "frame"
; (see diag. #1). A typical frame will consists of 3 vertical sync (VSYNC) lines*, 37 vertical blank
; (VBLANK) lines, 192 NTSC, 242 PAL TV picture lines, and 30 overscan lines. Atari's research has shown that this
; pattern will work on all types of TV sets. Each scan lines starts with 68 clock counts of horizontal
; blank (not seen on the TV screen) followed by 160 clock counts to fully scan one line of TV picture.
; When the electron beam reaches the end of a scan line, it returns to the left side of the screen, waits
; for the 68 horizontal blank clock counts, and proceeds to draw the next line below.
; Since one microprocessor machine cycle occurs every 3 clock counts, the programmer has only 76 machine
; cycles per line (228/3 = 76) to construct the actual picture
; In general, the remaining 70 scan lines (3 for VSYNC, 37 for VBLANK, and 30 for overscan) will provides
; 5,320 machine cycles (70 lines x 76 machine cycles) for housekeeping and game logic.
; 228 COLOR CLOCKS PER LINE
; 68 COLOR CLOCKS OF HBLANK
; 160 COLOR CLOCKS OF SCREEN PIXELS
; 3 COLOR CLOCKS PER CPU CLOCK
; 76 CPU CYCLES PER LINE
; 3 PIXELS PER CPU CLOCK
; 22.6 CPU CYCLES OF BLANK
; Vertical timing in lines
; 0
; 37 37
; 192 229
; 30 259
; 3 262
; 90 dd ------ 2** BCC/BLT/JNC/JB disp ;C=0 (less/below/no carry)
; B0 dd ------ 2** BCS/BGE/JC/JAE disp ;C=1 (above/greater/equal/carry)
PAL EQU 0
PALCOLORS EQU PAL ; SET TO 1 TO BUILD PAL CONFIGURATION
PALTIMING EQU PAL
#IF PAL != 0
DISPLAYSCANLINES EQU 242
#ELSE
DISPLAYSCANLINES EQU 192
#ENDIF
CUSTOM_TITLESCREEN EQU 0
CUSTOM_TITLECOLOR EQU $62
; ROM CONTROL ADDRESSES
ROM_END EQU $FFEC
ROM_END12 EQU ROM_END & $0FFF
LED_LATCH_BASE EQU $FFFC
LED_LATCH_11 EQU $FFFC ; LATCH LEDS
LED_LATCH_10 EQU $FFFD ; LATCH LEDS
LED_LATCH_01 EQU $FFFE ; LATCH LEDS
LED_LATCH_00 EQU $FFFF ; LATCH LEDS
DISTELLA EQU 0
DEBUG_CHEAT_INVINCIBLE EQU 0 ; THIS IS A CHEAT+
DEBUGTEXTENABLE EQU 0
DEBUGSYNCENABLE EQU 0
DEBUGWORSTCASEHPOS EQU 0
; ENABLE THESE THREE TOGETHER TO DEBUG SHIELDS COLLISSIONS
DEBUG_DISABLE_SPARKS EQU 0
DEBUG_DISABLE_FUZZBALL EQU 0
DEBUG_BULLET_SHIELD_COL EQU 0
DEBUG_DISABLE_SPARK_COL EQU 0
DEBUG_DISABLE_FUZZBALL_COL EQU 0
DEBUG_DONT_ROT_SHIELDS EQU 0
SHOT_OUTER_SHIELD_RADIUS EQU 25
SHOT_MIDDLE_SHIELD_RADIUS EQU 15
SHOT_INNER_SHIELD_RADIUS EQU 6
SPARKSHOTRADIUS EQU 4
SHIPSPARKRADIUS EQU 4
SHIPFUZZBALLRADIUS EQU 7 ; RADIUS OF BOX COLLISION BETWEEN SHIP AND FUZZBALL
SHOTTIME EQU 33 ; SHOT TIME TO LIVE
OUTERSHIELDDIAMETER EQU $19+4 ; OUTER SHIELD DIAMETER FOR SHIP/SHIELD COLISIONS
SCREEN_CENTER_X EQU 160/2
SCREEN_CENTER_Y EQU DISPLAYSCANLINES/4
; MACRO TO LOAD X AND USE DEBUGWORSTCASEX
MAC LOADX
#IF DEBUGWORSTCASEHPOS==0
LDA {1}
#ELSE
LDA #159
#ENDIF
ENDM
processor 6502
include vcs.h
include macro.h
MAC GETDIGITLINE
; BCD NUMBER IN X
; LINE OFFSET IN Y
; MULTIPLY LINES BY 10 FOR TABLE LOOKUP
LDA TIMES16,Y
STA TEMP0
; GET LOW DIGIT LINE IN TEMP0
TXA
AND #$0F
CLC
ADC TEMP0
TAY
LDA DIGITS,Y
AND #$0F
STA TEMP1
; GET HIGH DIGIT LINE OR-ED INTO TEMP1
TXA
LSR
LSR
LSR
LSR
CLC
ADC TEMP0
TAY
LDA DIGITS,Y
AND #$F0
ORA TEMP1
ENDM
NO_ILLEGAL_OPCODES = 0 ; FOR DELAY MACRO
;--------------------------------------
;CONSTANTS
;--------------------------------------
SHIELDVERSION EQU 4 ; SELECT SHIELDS ROUTINE
;--------------------------------------
;SOUND
;--------------------------------------
; SOUNDS WILL ALL BE PROGRAMATIC, AND USE 2 BYTES?
; SOUNDS BY PRIORITY
; SHIP EXPLOSION (1 OR 2 CHANNELS)
; FUZZBALL (CHANNEL 2 OR CHANNEL 2 AND 1)
; SHIELD EXPLOSION (CHANNEL 2)
; SHOTS (CHANNEL 1)
; THRUST (CHANNEL2)
; SPARK IN FLIGHT (1 CHANNEL AMBIENT)
; DRONING BACKGROUND (2 CHANNEL AMBIENT)
;--------------------------------------
;VARIABLES
;--------------------------------------
SEG.U VARS
org $80
; SYSTEM WIDE VARS
VBLS DS 1 ; VBLANK COUNTER
SCORE DS 3 ; BCD MAX SCORE 999990
SHIPS DS 1 ; SHIPS LEFT
DIFFICULTY DS 1 ; $FF IS HARDEST, 0 IS STANDSTILL
SPEEDTIMER DS 2 ; AFFECTS CANNON ROTATION AND SPARK UPDATES
FLAGS0 DS 1
F0_PLAYERCANMOVE EQU %00001000 ;
F0_CANNONDYING EQU %00000111 ;
F0_PLAYERDYING EQU %00010000 ;
F0_FUZZBALLACTIVE EQU %00100000 ; FUZZBALL ACTIVE
F0_SHIELDROTCCW EQU %01000000 ; ROTATION DIRECTION OF SHIELDS - WHEN OUTER SHIELD SHOT, THEY EXPAND AND CHANGE DIRECTIONS
F0_PREVBUTTON EQU %10000000 ; STORE PREVIOUS BUTTON IN HIGH BIT OF LAST BYTE
; ***** SOUND *****
SOUND0 DS 1
SOUND1 DS 1
SHIELDBITSDRONE DS 1 ; NUMBER OF SHIELD BITS ON - SLOW DRIFT FOR DRONE
;**********************************************
;
; EVERYTHING AFTER THIS POINT CAN BE DESTROYED BETWEEN MATCHES
; (TITLE SCREEN/SCORE SCREEN)
;
SOUNDFLAGS DS 1 ; FLAGS INDICATING WHAT SOUNDS ARE ELLIGIBLE TO PLAY
SB_FUZZBALL EQU %10000000
SB_SHOOTING EQU %01000000
SB_SHIP_BOUNCE EQU %00100000
SB_CHANNEL0_FLAGS EQU %11100000
SB_CANNON_EXLOSION EQU %00000001
SB_SHIP_EXLOSION EQU %00000010
SB_SHIELD_SPARK_EXPLOSION EQU %00000100
SB_THRUSTING EQU %00001000
SB_SPARK_ACTIVE EQU %00010000
SB_CHANNEL1_FLAGS EQU %00011111
; PLAYERS SHIP
SHIPX DS 2 ;0 TO 9F
SHIPY DS 2
SHIPVX DS 1
SHIPVY DS 1
SHIPDIR DS 1
; PLAYERS SHOTS
SHOT0
SHOT0X DS 1
SHOT0Y DS 1
SHOT0VX DS 1
SHOT0VY DS 1
SHOT0TIME DS 1
SHOT1
SHOT1X DS 1
SHOT1Y DS 1
SHOT1VX DS 1
SHOT1VY DS 1
SHOT1TIME DS 1
SHOT2
SHOT2X DS 1
SHOT2Y DS 1
SHOT2VX DS 1
SHOT2VY DS 1
SHOT2TIME DS 1
SHOTSIZE EQU SHOT1-SHOT0
; CANNON IS THING IN THE CENTER THAT POINTS AT YOU
CANNONDIR DS 1
; FUZZBALL IS THING THAT CANNON SHOOTS AT YOU WHEN IT CAN SEE THROUGH ALL 3 SHIELDS AND IS LOOKING AT THE SHIP
; CONSTANT VELOCITY, CONSTANT DIRECTION
FUZZBALLX DS 1
FUZZBALLY DS 1
FUZZBALLDIR DS 1
; SHIELDS ROTATE AT DIFFERENT SPEEDS AND DIRECTIONS
; OUTER AND INNER TURN LEFT, MIDDLE TURNS RIGHT
;SHIELDSO DS 16 ; 16*8 = 128 128/12 = 10.666 ; 10,11,11
;SHIELDSM DS 11 ; 11*8 = 88 88/12 = 7.333 ; 7,7,8
;SHIELDSI DS 6 ; 6*8-4 = 44 44/12=3.666 ; 3,4,4 ; 4 UNUSED BITS
OSHIELDBITSL DS 1
OSHIELDBITSH DS 1
OSHIELDANGLE DS 1
MSHIELDBITSL DS 1
MSHIELDBITSH DS 1
MSHIELDANGLE DS 1
ISHIELDBITSL DS 1
ISHIELDBITSH DS 1
ISHIELDANGLE DS 1
OSHIELDBITSIZE EQU 10
OSHIELDBITSIZEFRAC EQU (256*2/3)+1
MSHIELDBITSIZE EQU 7
MSHIELDBITSIZEFRAC EQU (256/3)+1
ISHIELDBITSIZE EQU 3
ISHIELDBITSIZEFRAC EQU (256*2/3)+1
SHIELDBITSON DS 1 ; NUMBER OF SHIELD BITS ON
; SPARKS HAVE POSITION AND DIRECTION
; START IN CENTER AND CAN GET STUCK TO SHIELDS
; CAN ONLY JUMP OFF SHIELDS WHEN DIRECTION IS NORMAL TO SHIELD
; THEN DIR TURNS TOWARDS SHIP AND THEY MOVE AT CONSTANT VELOCITY BASED ON GAME LEVEL
SPARK0
SPARK0X DS 1 ; 1 - A0 1 to 160
SPARK0Y DS 1
SPARK0DIR DS 1
SPARK1
SPARK1X DS 1
SPARK1Y DS 1
SPARK1DIR DS 1
SPARK2
SPARK2X DS 1
SPARK2Y DS 1
SPARK2DIR DS 1
FREERAM
; BASE FOR DRAWSHIELDS
; MACRO TO SET STACK BASED ALLOCATION BASE
MAC SETSTACKBASE
STACKBASE SET {1}
ENDM
; MACRO TO DEFINE A BYTE IN THE STACK FRAME
MAC STACKALLOC
{1} EQU STACKBASE
STACKBASE SET STACKBASE-1
ENDM
MAC STACKALLOCN
{1} EQU STACKBASE+1{2}
STACKBASE SET STACKBASE-{2}
ENDM
; TOP OF STACK
SETSTACKBASE $FF
; ROOM FOR ONE SUBROUTINE CALL
STACKALLOC DS_TEMP2 ; RETURN ADDRESS IF JSR USED
STACKALLOC DS_TEMP3 ; RETURN ADDRESS IF JSR USED
; VARS USED FOR PACKSHIELDS
STACKALLOC DS_TEMP0
STACKALLOC DS_TEMP1
STACKALLOC DS_ENDBITLOW
STACKALLOC DS_ENDBIT
STACKALLOC DS_DELTALOW
STACKALLOC DS_DELTAHIGH
STACKALLOC DS_SHIELDBITSLOW
STACKALLOC DS_SHIELDBITSHIGH
; SHIELD STORAGE
; VARS REFERENCED IN SHIELDPACK1 (THAT MUSSN'T GET CLOBBERED BY THE SHIP SCREEN INIT)
STACKALLOC DS_BASE_00
STACKALLOC DS_BASE_01
STACKALLOC DS_BASE_02
STACKALLOC DS_BASE_05
;IN CANNON STACKALLOC DS_BASE_06
STACKALLOC DS_BASE_07
STACKALLOC DS_BASE_08
;IN CANNON STACKALLOC DS_BASE_09
;IN CANNON STACKALLOC DS_BASE_10
STACKALLOC DS_BASE_11
;IN CANNON STACKALLOC DS_BASE_12
;IN CANNON STACKALLOC DS_BASE_15
;IN CANNON STACKALLOC DS_BASE_16
;IN CANNON STACKALLOC DS_BASE_17
;IN CANNON STACKALLOC DS_BASE_18
;IN CANNON STACKALLOC DS_BASE_19
STACKALLOC DS_BASE_20
;IN CANNON STACKALLOC DS_BASE_21
STACKALLOC DS_BASE_22
STACKALLOC DS_BASE_23
STACKALLOC DS_BASE_26
STACKALLOC DS_BASE_27
STACKALLOC DS_BASE_28
STACKALLOC DS_BASE_29
STACKALLOC DS_BASE_33
;IN CANNON STACKALLOC DS_BASE_34
STACKALLOC DS_BASE_36
STACKALLOC DS_BASE_37
STACKALLOC DS_BASE_39
STACKALLOC DS_BASE_42
STACKALLOC DS_BASE_43
STACKALLOC DS_BASE_44
STACKALLOC DS_BASE_45
STACKALLOC DS_BASE_46
STACKALLOC DS_BASE_48
STACKALLOC DS_BASE_49
STACKALLOC DS_BASE_51
;IN CANNON STACKALLOC DS_BASE_52
STACKALLOC DS_BASE_57
STACKALLOC DS_BASE_58
; PUTTING THESE IN THIS ORDER ALLOWS FASTER CANNONDIR
STACKALLOC DS_BASE_10
STACKALLOC DS_BASE_52
STACKALLOC DS_BASE_14
STACKALLOC DS_BASE_54
STACKALLOC DS_BASE_13
STACKALLOC DS_BASE_55
STACKALLOC DS_BASE_06
STACKALLOC DS_BASE_50
STACKALLOC DS_BASE_09
STACKALLOC DS_BASE_53
STACKALLOC DS_BASE_12
STACKALLOC DS_BASE_56
STACKALLOC DS_BASE_15
STACKALLOC DS_BASE_32
STACKALLOC DS_BASE_18
STACKALLOC DS_BASE_35
STACKALLOC DS_BASE_21
STACKALLOC DS_BASE_38
STACKALLOC DS_BASE_16
STACKALLOC DS_BASE_31
STACKALLOC DS_BASE_17
STACKALLOC DS_BASE_30
STACKALLOC DS_BASE_19
STACKALLOC DS_BASE_34
; UNCOMMENTED ALLOCATIONS BELOW HERE CAN GET CLOBBERED BY SHIP DRAW SCREEN
; STACKALLOC DS_BASE_00
; STACKALLOC DS_BASE_01
; STACKALLOC DS_BASE_02
; STACKALLOC DS_BASE_05
; STACKALLOC DS_BASE_06
; STACKALLOC DS_BASE_07
; STACKALLOC DS_BASE_08
; STACKALLOC DS_BASE_09
; STACKALLOC DS_BASE_10
; STACKALLOC DS_BASE_11
; STACKALLOC DS_BASE_12
;IN CANNON STACKALLOC DS_BASE_13
;IN CANNON STACKALLOC DS_BASE_14
; STACKALLOC DS_BASE_15
; STACKALLOC DS_BASE_16
; STACKALLOC DS_BASE_17
; STACKALLOC DS_BASE_18
; STACKALLOC DS_BASE_19
; STACKALLOC DS_BASE_20
; STACKALLOC DS_BASE_21
; STACKALLOC DS_BASE_22
; STACKALLOC DS_BASE_23
; STACKALLOC DS_BASE_26
; STACKALLOC DS_BASE_27
; STACKALLOC DS_BASE_28
; STACKALLOC DS_BASE_29
;IN CANNON STACKALLOC DS_BASE_30
;IN CANNON STACKALLOC DS_BASE_31
;IN CANNON STACKALLOC DS_BASE_32
; STACKALLOC DS_BASE_33
; STACKALLOC DS_BASE_34
;IN CANNON STACKALLOC DS_BASE_35
; STACKALLOC DS_BASE_36
; STACKALLOC DS_BASE_37
;IN CANNON STACKALLOC DS_BASE_38
; STACKALLOC DS_BASE_39
; STACKALLOC DS_BASE_42
; STACKALLOC DS_BASE_43
; STACKALLOC DS_BASE_44
; STACKALLOC DS_BASE_49
;IN CANNON STACKALLOC DS_BASE_50
; STACKALLOC DS_BASE_51
; STACKALLOC DS_BASE_52
;IN CANNON STACKALLOC DS_BASE_53
;IN CANNON STACKALLOC DS_BASE_54
;IN CANNON STACKALLOC DS_BASE_55
;IN CANNON STACKALLOC DS_BASE_56
; STACKALLOC DS_BASE_57
; STACKALLOC DS_BASE_58
; NOT USED IN PACKSHIELDS1 AND WILL BE CLOBBERED
STACKALLOC DS_BASE_03
STACKALLOC DS_BASE_04
STACKALLOC DS_BASE_24
STACKALLOC DS_BASE_25
STACKALLOC DS_BASE_40
STACKALLOC DS_BASE_41
STACKALLOC DS_BASE_47
STACKALLOC DS_BASE_59
STACKALLOC DS_BASE ; NOT REALLY AN ALLOCATION, _59DS_BASE EQU $FF-(2+67) ; 2 BYTES FOR SUBROUTINE RETURN ON STACK, AND 62 BYTES USED FOR SHIELDS
echo "----",(*-$80)d,"Bytes of RAM used;", ($100 - *)d , "bytes of RAM left. ", "FREERAM(*) =",(FREERAM)d, "DS_BASE=",(DS_BASE)d, "STACKBASE=",(STACKBASE)d
echo "---- ",((DS_BASE+1) - FREERAM)d, "ROOM BETWEEN DS_BASE AND FREERAM"
echo "---- ",((TEXT_BASE+1) - FREERAM)d, "ROOM BETWEEN TEXT_BASE AND FREERAM"
SND_FREQUENCY_______________________________V EQU 0
SND_FREQUENCY______________________________V_ EQU 1
SND_FREQUENCY_____________________________V__ EQU 2
SND_FREQUENCY____________________________V___ EQU 3
SND_FREQUENCY___________________________V____ EQU 4
SND_FREQUENCY__________________________V_____ EQU 5
SND_FREQUENCY_________________________V______ EQU 6
SND_FREQUENCY________________________V_______ EQU 7
SND_FREQUENCY_______________________V________ EQU 8
SND_FREQUENCY______________________V_________ EQU 9
SND_FREQUENCY_____________________V__________ EQU 10
SND_FREQUENCY____________________V___________ EQU 11
SND_FREQUENCY___________________V____________ EQU 12
SND_FREQUENCY__________________V_____________ EQU 13
SND_FREQUENCY_________________V______________ EQU 14
SND_FREQUENCY________________V_______________ EQU 15
SND_FREQUENCY_______________V________________ EQU 16
SND_FREQUENCY______________V_________________ EQU 17
SND_FREQUENCY_____________V__________________ EQU 18
SND_FREQUENCY____________V___________________ EQU 19
SND_FREQUENCY___________V____________________ EQU 20
SND_FREQUENCY__________V_____________________ EQU 21
SND_FREQUENCY_________V______________________ EQU 22
SND_FREQUENCY________V_______________________ EQU 23
SND_FREQUENCY_______V________________________ EQU 24
SND_FREQUENCY______V_________________________ EQU 25
SND_FREQUENCY_____V__________________________ EQU 26
SND_FREQUENCY____V___________________________ EQU 27
SND_FREQUENCY___V____________________________ EQU 28
SND_FREQUENCY__V_____________________________ EQU 29
SND_FREQUENCY_V______________________________ EQU 30
SND_FREQUENCYV_______________________________ EQU 31
SND_VOLUME_______________V EQU 0
SND_VOLUME______________V_ EQU 1
SND_VOLUME_____________V__ EQU 2
SND_VOLUME____________V___ EQU 3
SND_VOLUME___________V____ EQU 4
SND_VOLUME__________V_____ EQU 5
SND_VOLUME_________V______ EQU 6
SND_VOLUME________V_______ EQU 7
SND_VOLUME_______V________ EQU 8
SND_VOLUME______V_________ EQU 9
SND_VOLUME_____V__________ EQU 10
SND_VOLUME____V___________ EQU 11
SND_VOLUME___V____________ EQU 12
SND_VOLUME__V_____________ EQU 13
SND_VOLUME_V______________ EQU 14
SND_VOLUMEV_______________ EQU 15
SND_CTRL_1 EQU %0000
SND_CTRL_4_BIT_POLY EQU %0001
SND_CTRL_DIV_15_4_BIT_POLY EQU %0010
SND_CTRL_5_BIT_POLY_INTO_4_BIT_POLY EQU %0011
SND_CTRL_DIV_2 EQU %0100
SND_CTRL_DIV_31 EQU %0110
SND_CTRL_5_BIT_POLY_INTO_DIV_2 EQU %0111
SND_CTRL_9_BIT_POLY EQU %1000
SND_CTRL_5_BIT_POLY EQU %1001
SND_CTRL_15 EQU %1011
SND_CTRL_DIV_6 EQU %1100
SND_CTRL_DIV_93 EQU %1110
SND_CTRL_5_BIT_POLY_DIV_6 EQU %1111
SND_CTRL_SAW EQU 1 ; sounds similar to a saw waveform
SND_CTRL_ENGINE EQU 3 ; many 2600 games use this for an engine sound
SND_CTRL_SQUARE EQU 4 ; a high pitched square waveform
SND_CTRL_BASS EQU 6 ; fat bass sound
SND_CTRL_PITFALL EQU 7 ; log sound in pitfall, low and buzzy
SND_CTRL_NOISE EQU 8 ; white noise
SND_CTRL_LEAD EQU 12 ; lower pitch square wave sound
SND_CTRL_BUZZ EQU 15 ; atonal buzz, good for percussion
;******************************************************************************
;
; ROM STARTS HERE
;
;******************************************************************************
SEG CODE
;******************************************************************************
;
; BANK 0
;
;******************************************************************************
ORG $1000
RORG $f000
VECTOR_NMI ; NMI (6507 IN ATARI 2600 HAS NO NMI PIN)
VECTOR_RESET ; RESET
VECTOR_BREAK ; IRQ/BREAK (6507 IN ATARI 2600 HAS NO IRQ PIN)
LDA $1FF8 ; SWITCH TO BANK 1
JMP START2
GFX_CANNON_LEFT
; FRAME0 (LEFT)
dc %00000000
dc %00000111
dc %00000100
dc %00001011
dc %00011100
dc %00000001
dc %00000001
dc %00011100
dc %00001011
dc %00000100
dc %00000111
dc %00000000
; FRAME1
dc %00000000
dc %00000011
dc %00000100
dc %00011111
dc %00000000
dc %00000001
dc %00010001
dc %00001111
dc %00001001
dc %00001100
dc %00000010
dc %00000001
; FRAME2
dc %00000000
dc %00000011
dc %00001100
dc %00000011
dc %00000000
dc %00010001
dc %00001001
dc %00010101
dc %00010011
dc %00001101
dc %00000011
dc %00000001
; FRAME3
dc %00000000
dc %00000100
dc %00000011
dc %00000000
dc %00010000
dc %00001001
dc %00010101
dc %00010011
dc %00001010
dc %00000111
dc %00000110
dc %00000010
; FRAME4
dc %00000000
dc %00000010
dc %00000001
dc %00010000
dc %00001000
dc %00011001
dc %00010101
dc %00010110
dc %00001010
dc %00001011
dc %00000101
dc %00000100
; FRAME5
dc %00000000
dc %00000001
dc %00001000
dc %00001000
dc %00010100
dc %00010101
dc %00010110
dc %00010010
dc %00001110
dc %00001110
dc %00001001
dc %00000001
; FRAME6
dc %00000000
dc %00000100
dc %00000100
dc %00001100
dc %00010100
dc %00010101
dc %00010110
dc %00010100
dc %00011100
dc %00010101
dc %00000110
dc %00000100
; FRAME7 (UP)
dc %00000000
dc %00000010
dc %00000110
dc %00011010
dc %00010100
dc %00010101
dc %00100110
dc %00111100
dc %00101001
dc %00001110
dc %00001000
dc %00000000
; FRAME8
dc %00000000
dc %00000001
dc %00001110
dc %00001010
dc %00010010
dc %00100111
dc %00111000
dc %00001000
dc %00001111
dc %00011000
dc %00000000
dc %00000000
; FRAME9
dc %00000000
dc %00000110
dc %00001001
dc %00001010
dc %00010100
dc %00111111
dc %00001000
dc %00010000
dc %00111110
dc %00000001
dc %00000001
dc %00000000
; FRAME10
dc %00000000
dc %00000011
dc %00000100
dc %00011001
dc %00111110
dc %00001111
dc %00010000
dc %00111000
dc %00000110
dc %00000010
dc %00000001
dc %00000001
; FRAME11
dc %00000000
dc %00000011
dc %00001100
dc %00110011
dc %00001110
dc %00011001
dc %00110000
dc %00001100
dc %00000100
dc %00000010
dc %00000011
dc %00000010
; FRAME12
dc %00000000
dc %00000011
dc %00011100
dc %00001101
dc %00001111
dc %00110000
dc %00011000
dc %00000100
dc %00000100
dc %00000101
dc %00000110
dc %00000100
; FRAME13
dc %00000000
dc %00001111
dc %00000100
dc %00111111
dc %00010001
dc %00001000
dc %00000100
dc %00000100
dc %00000101
dc %00001111
dc %00001001
dc %00000001
; FRAME14
dc %00000111
dc %00000010
dc %00011110
dc %00001011
dc %00001001
dc %00000100
dc %00000100
dc %00001001
dc %00001011
dc %00011110
dc %00000010
dc %00000111
SINTAB
DC 0,12,24,36,48,59,70,80,89,98,105,112,117,121,124,126
COSTAB
DC 127,126,124,121,117,112,105,98,89,80,70,59,48,36,24,12
DC 0,-13,-25,-37,-49,-60,-71,-81,-90,-99,-106,-113,-118,-122,-125,-127
DC -127,-127,-125,-122,-118,-113,-106,-99,-90,-81,-71,-60,-49,-37,-25,-13
DC 0,12,24,36,48,59,70,80,89,98,105,112,117,121,124,126
GFX_CANNON_RIGHT
; FRAME0 (LEFT)
dc %11100000
dc %01000000
dc %01111000
dc %11010000
dc %10010000
dc %00100000
dc %00100000
dc %10010000
dc %11010000
dc %01111000
dc %01000000
dc %11100000
; FRAME1
dc %00000000
dc %11110000
dc %00100000
dc %11111100
dc %10001000
dc %00010000
dc %00100000
dc %00100000
dc %10100000
dc %11110000
dc %10010000
dc %10000000
; FRAME2
dc %00000000
dc %11000000
dc %00111000
dc %10110000
dc %11110000
dc %00001100
dc %00011000
dc %00100000
dc %00100000
dc %10100000
dc %01100000
dc %00100000
; FRAME3
dc %00000000
dc %11000000
dc %00110000
dc %11001100
dc %01110000
dc %10011000
dc %00001100
dc %00110000
dc %00100000
dc %01000000
dc %11000000
dc %01000000
; FRAME4
dc %00000000
dc %11000000
dc %00100000
dc %10011000
dc %01111100
dc %11110000
dc %00001000
dc %00011100
dc %01100000
dc %01000000
dc %10000000
dc %10000000
; FRAME5
dc %00000000
dc %01100000
dc %10010000
dc %01010000
dc %00101000
dc %11111100
dc %00010000
dc %00001000
dc %01111100
dc %10000000
dc %10000000
dc %00000000
; FRAME6
dc %00000000
dc %10000000
dc %01110000
dc %01010000
dc %01001000
dc %11100100
dc %00011100
dc %00010000
dc %11110000
dc %00011000
dc %00000000
dc %00000000
; FRAME7 (UP)
dc %00000000
dc %01000000
dc %01100000
dc %01011000
dc %00101000
dc %10101000
dc %01100100
dc %00111100
dc %10010100
dc %01110000
dc %00010000
dc %00000000
; FRAME8
dc %00000000
dc %00100000
dc %00100000
dc %00110000
dc %00101000
dc %10101000
dc %01101000
dc %00101000
dc %00111000
dc %10101000
dc %01100000
dc %00100000
; FRAME9
dc %00000000
dc %10000000
dc %00010000
dc %00010000
dc %00101000
dc %10101000
dc %01101000
dc %01001000
dc %01110000
dc %01110000
dc %10010000
dc %10000000
; FRAME10
dc %00000000
dc %01000000
dc %10000000
dc %00001000
dc %00010000
dc %10011000
dc %10101000
dc %01101000
dc %01010000
dc %11010000
dc %10100000
dc %00100000
; FRAME11
dc %00000000
dc %00100000
dc %11000000
dc %00000000
dc %00001000
dc %10010000
dc %10101000
dc %11001000
dc %01010000
dc %11100000
dc %01100000
dc %01000000
; FRAME12
dc %00000000
dc %11000000
dc %00110000
dc %11000000
dc %00000000
dc %10001000
dc %10010000
dc %10101000
dc %11001000
dc %10110000
dc %11000000
dc %10000000
; FRAME13
dc %00000000
dc %11000000
dc %00100000
dc %11111000
dc %00000000
dc %10000000
dc %10001000
dc %11110000
dc %10010000
dc %00110000
dc %01000000
dc %10000000
; FRAME14
dc %00000000
dc %11100000
dc %00100000
dc %11010000
dc %00111000
dc %10000000
dc %10000000
dc %00111000
dc %11010000
dc %00100000
dc %11100000
dc %00000000
; 64 BIT 6,5,5 PATTERN
; 32 BIT 3,3,2 PATTERN
SHOTSHIELDTAB32
DC 0,0,0,11,11,10,10,10,9,9,9
DC 8,8,7,7,7,6,6,6
DC 5,5,4,4,4,3,3,3
DC 2,2,1,1,1
SHOTSHIELDMASKL
DC %00000001
DC %00000010
DC %00000100
DC %00001000
DC %00010000
DC %00100000
DC %01000000
DC %10000000
DC %00000000
DC %00000000
DC %00000000
DC %00000000
SHOTSHIELDMASKH
DC %00010000
DC %00000000
DC %00000000
DC %00000000
DC %00000000
DC %00000000
DC %00000000
DC %00000000
DC %00000001
DC %00000010
DC %00000100
DC %00001000
DC %00010000
;----------------------
; LDA P0_XPOS;REPOSITIONING P0
; JSR SETXPOS
; STA RESP0
; STA HMP0
;----------------------
; LDA P1_XPOS;REPOSITIONING P1
; JSR SETXPOS
; STA RESP1
; STA HMP1
;-----------------------
; LDA M0_XPOS;REPOSITIONING MISSILE0
; JSR SETXPOS
; STA RESM0
; STA HMM0
;------------------------
; LDA M1_XPOS;REPOSITIONING MISSILE1
; JSR SETXPOS
; STA RESM1
; STA HMM1
;------------------------
; LDA BL_XPOS;REPOSITIONING BALL
; JSR SETXPOS
; STA RESBL
; STA HMBL
;-------------------------
; STA WSYNC
; STA HMOVE
SETXPOS ;SUBROUTINE
SEC
STA WSYNC
.WAITOBJECT:
SBC #$0F
BCS .WAITOBJECT
EOR #$07
ASL
ASL
ASL
ASL
RTS;RETURN
; PLACED HERE TO MINIMIZE BANK CROSSING, AS IT IS, ONLY THE LAST 6 BYTES CAUSE EXTRA CYCLES
ATAN256TAB
;=INT(MOD(ATAN2($B3,C$2)/(2*PI())+1.25,1)*$B$2)
; x down, y across in order 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1
; +x to right, +y down, zero angle up, positive cw
dc 96,128,128,128,128,128,128,128,0,0,0,0,0,0,0,0
dc 64,96,109,114,118,119,121,122,5,5,6,8,9,13,18,32
dc 64,82,96,104,109,112,114,116,9,11,13,15,18,23,32,45
dc 64,77,87,96,101,105,109,111,14,16,18,22,26,32,40,50
dc 64,73,82,90,96,100,104,106,18,21,23,27,32,37,45,54
dc 64,72,79,86,91,96,99,102,22,25,28,32,36,41,48,55
dc 64,70,77,82,87,92,96,99,26,28,32,35,40,45,50,57
dc 64,69,75,80,85,89,92,96,29,32,35,38,42,47,52,58
dc 192,186,182,177,173,169,165,162,224,221,218,214,210,206,201,197
dc 192,186,180,175,170,166,163,160,226,224,220,217,213,208,203,197
dc 192,185,178,173,168,163,160,156,229,227,224,220,215,210,205,198
dc 192,183,176,169,164,160,156,153,233,230,227,224,219,214,207,200
dc 192,182,173,165,160,155,151,149,237,234,232,228,224,218,210,201
dc 192,178,168,160,154,150,146,144,241,239,237,233,229,224,215,205
dc 192,173,160,151,146,143,141,139,246,244,242,240,237,232,224,210
dc 192,160,146,141,137,136,134,133,250,250,249,247,246,242,237,224
SINTAB16
DC 0/16,12/16,24/16,36/16,48/16,59/16,70/16,80/16,89/16,98/16,105/16,112/16,117/16,121/16,124/16,126/16
COSTAB16
DC 127/16,126/16,124/16,121/16,117/16,112/16,105/16,98/16,89/16,80/16,70/16,59/16,48/16,36/16,24/16,12/16
DC 0/16,-13/16,-25/16,-37/16,-49/16,-60/16,-71/16,-81/16,-90/16,-99/16,-106/16,-113/16,-118/16,-122/16,-125/16,-127/16
DC -127/16,-127/16,-125/16,-122/16,-118/16,-113/16,-106/16,-99/16,-90/16,-81/16,-71/16,-60/16,-49/16,-37/16,-25/16,-13/16
DC 0/16,12/16,24/16,36/16,48/16,59/16,70/16,80/16,89/16,98/16,105/16,112/16,117/16,121/16,124/16,126/16
; OTHER TABLES SHOULD FOLLOW HERE TO CAREFULLY MINIMIZE BANK CROSSING
;******************************************************************************
;
; PROGRAM ENTRY (BOOT VECTOR)
;
;******************************************************************************
START2
; CLEAN_START
SEI
CLD
LDX #0
TXA
TAY
.CLEAR_STACK
DEX
TXS
PHA
BNE .CLEAR_STACK ; SP=$FF, X = A = Y = 0
LDA LED_LATCH_00 ; TURN OFF LEDS
JMP TITLESCREEN_ENTRY
TITLESCREEN_DONE
; INCLUDE AND FALL INTO FILES
;;; INCLUDE GAME.ASM
;******************************************************************************
STARTGAME
; PROBLEM IS THAT WE FALL INTO HERE AT SCAN LINE 40
LDX #INITGAMEDATA-INITTAB
JSR INITMEM
; SHOW THE SCORE AND SHIP COUNT AND GET INTO THE GAME
JMP SCORE_SHIPS_SCREEN_ENTRY
SCORE_SHIPS_SCREEN_DONE
CONTINUEGAME
LDX #CONTINUEGAMEDATA-INITTAB
JSR INITMEM
LDA LED_LATCH_00 ; TURN OFF LEDS
; WE SHOULD JUST SET UP THE SHIP SCREEN
JMP PREPFORSHIPSCREEN
; INITMEM WILL LOAD RAM WITH PREDEFINED VALUES FROM
INITMEM
.INITLOOP
LDY INITTAB,X
BEQ .DONE
LDA INITTAB+1,X
STA 0,Y
INX
INX
BNE .INITLOOP
.DONE
RTS
FLASHLEDS
; MASK IN A, USES X AND A
; AND VBLS
; TAX
LDX VBLS
LDA RANDOM1,X
EOR RANDOM2,X
AND #%00000011
TAX
LDA LED_LATCH_BASE,X
RTS
INITTAB
INITGAMEDATA
; DC GRP0,0
; DC GRP1,0
; DC GRP0,0
DC SHIPS,3
; CLEAR VBLS, SCORE, AND DIFFICULTY
DC SCORE,0
DC SCORE+1,0
DC SCORE+2,0
DC DIFFICULTY,0
DC SHIELDBITSDRONE,14
INITREFILSHIELDSDATA
; REFIL SHIELD BITS
DC SHIELDBITSON,3*12
DC OSHIELDBITSL,$FF
DC MSHIELDBITSL,$FF
DC ISHIELDBITSL,$FF
DC OSHIELDBITSH,$FF
DC MSHIELDBITSH,$FF
DC ISHIELDBITSH,$FF
DC 0
CONTINUEGAMEDATA
DC VBLS,0
DC SOUNDFLAGS,0
DC FLAGS0,0
; INIT PLAYER SHIP
; DC SHIPX,0
DC SHIPX+1,140
; DC SHIPY,0
DC SHIPY+1,DISPLAYSCANLINES/3
DC SHIPVX,0
DC SHIPVY,0
DC SHIPDIR,$A0
DC FUZZBALLY,200
DC SHOT0TIME,0
DC SHOT1TIME,0
DC SHOT2TIME,0
; DC SHOT0X,0
; DC SHOT1X,0
; DC SHOT2X,0
DC SHOT0Y,200
DC SHOT1Y,200
DC SHOT2Y,200
; CONFIGURE JOY PORTS AS INPUTS
; DC SWACNT,0
DC OSHIELDANGLE,0
DC MSHIELDANGLE,0
DC ISHIELDANGLE,0
; SET SPARK LOCATIONS
DC SPARK0X,160/2+4
DC SPARK1X,160/2-4
DC SPARK2X,160/2
DC SPARK0Y,DISPLAYSCANLINES/4+4
DC SPARK1Y,DISPLAYSCANLINES/4+4
DC SPARK2Y,DISPLAYSCANLINES/4-4
DC 0
CANNONDIE
DC FLAGS0,F0_CANNONDYING
DC SOUNDFLAGS,SB_CANNON_EXLOSION
DC SOUND1,SOUND1_SHIELD_SPARK_EXPLOSION_SIZE-1
DC FUZZBALLX,160/2-4
DC FUZZBALLY,DISPLAYSCANLINES/4-4
DC SPARK0X,160/2-7
DC SPARK0Y,DISPLAYSCANLINES/4-8
DC SPARK1X,160/2+8
DC SPARK1Y,160/4-6
DC SPARK2X,DISPLAYSCANLINES/2-4
DC SPARK2Y,DISPLAYSCANLINES/4+9
DC SHOT0Y,200
DC SHOT0Y,200
DC SHOT0Y,200
; DC VBLS,0 ; VBLS USED IN SOUND TIMER CALCULATION
DC 0
PLAYERDIE
; VBLS USED AS ANIMATION FRAME AND SOUND TIMER
DC VBLS,0
; TURN OFF SPARKS AND SHOTS
DC SHOT0TIME,0
DC SHOT1TIME,0
DC SHOT2TIME,0
; MOVE SPARKS AND SHOTS OFF SCREEN
DC SHOT0Y,200
DC SHOT1Y,200
DC SHOT2Y,200
DC SPARK0Y,200
DC SPARK1Y,200
DC SPARK2Y,200
DC 0
#IF 0 ; COULD BE USED TO SAVE 2 BYTES
SETUPSHIPSCREENGRAPHICS
DC PF0,0
DC PF1,0
DC PF2,0
; DC GRP0,0
; DC GRP1,0
; DC GRP0,0
; DC GRP1,0
DC ENAM0,0
DC ENAM1,0
DC ENABL,0
; SET COLORS FOR SHIP SCREEN
#IF PALCOLORS != 0
DC COLUP0,$BC
DC COLUP1,$0F
DC COLUPF,$9E
#ELSE
DC COLUP0,$9C
DC COLUP1,$0F
DC COLUPF,$AE
#ENDIF
DC 0
#ENDIF
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
DRAWSHIELDSDONE
MAINLOOP SUBROUTINE
; DEFINE LOCAL VARS
.TEMP0 EQU FREERAM
.TEMP1 EQU FREERAM+1
.TEMP2 EQU FREERAM+2
.TEMP3 EQU FREERAM+3
.TEMP4 EQU FREERAM+4
.TEMP5 EQU FREERAM+5
.TEMP6 EQU FREERAM+6
.TEMP7 EQU FREERAM+7
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
; SHIELDS BOTTOM OVERSCAN - UPDATE GAME
#IF 0
; THIS COSTS A LOT OF CYCLES BUT SAVES 2 BYTES
LDX #SETUPSHIPSCREENGRAPHICS-INITTAB
JSR INITMEM
#ELSE
; CLEAR GRAPHICS REGISTERS (DSW NOT ALL NEEDED, COULD BE DONE IN VSYNC)
LDA #0
STA PF0
STA PF1
STA PF2
; STA GRP0
; STA GRP1
; STA GRP0
; STA GRP1
STA ENAM0
STA ENAM1
STA ENABL
; SET COLORS FOR SHIP SCREEN
#IF PALCOLORS != 0
LDA #$BC
STA COLUP0
LDA #$0F
STA COLUP1
LDA #$9E
STA COLUPF
#ELSE
LDA #$9C
STA COLUP0
LDA #$0F
STA COLUP1
LDA #$AE
STA COLUPF
#ENDIF
#IF DEBUG_BULLET_SHIELD_COL!=0
LDA #$7F
STA SHOT0TIME
LDA #0
STA SHOT0VX
STA SHOT0VY
LDA SWCHA
ASL
BCS .NOROTRIGHT1
INC SHOT0X
.NOROTRIGHT1
ASL
BCS .NOROTLEFT1
DEC SHOT0X
.NOROTLEFT1
ASL
BCS .NOROTDOWN1
INC SHOT0Y
.NOROTDOWN1
ASL
BCS .NOUP
DEC SHOT0Y
.NOUP1
#ENDIF
; RESET BUTTON RETURNS TO TITLE SCREEN
LSR SWCHB
BCS .NORESET
.RESETTING
LDA #0
STA AUDV0
STA AUDV1
LSR SWCHB
BCC .RESETTING
JMP TITLESCREEN_ENTRY
.NORESET
; SEE IF PLAYER IS DYING AND IF SO, SKIP A BUNCH OF STUFF
LDA FLAGS0
AND #F0_PLAYERDYING
BEQ .PLAYERNOTDYING
JMP .SKIP_STUFF_WHEN_PLAYER_DYING
.PLAYERNOTDYING
; JOYSTICK CONTROLS SHIP ROTATION, IN THE VSYNC
LDA SWCHA
LDX SHIPDIR
ASL
BCS .NOROTRIGHT
DEX
DEX
DEX
DEX
.NOROTRIGHT
ASL
BCS .NOROTLEFT
INX
INX
INX
INX
.NOROTLEFT
STX SHIPDIR
ASL
; BCS .NOROTDOWN
;.NOROTDOWN
ASL
BCS .NOUP
LDA #SB_THRUSTING
ORA SOUNDFLAGS
STA SOUNDFLAGS
; THRUST!
TXA ; LDA SHIPDIR ; SHIPDIR IS CONVENIENTLY IN X
LSR
LSR
TAY
LDA SINTAB16,Y
CLC
ADC SHIPVX
BVS .THRUSTOVERFLOWX
; NO OVERFLOW, STORE NEW Vx
STA SHIPVX
.THRUSTOVERFLOWX
LDA COSTAB16,Y
CLC
ADC SHIPVY
BVS .THRUSTOVERFLOWY
; NO OVERFLOW, STORE NEW VY
STA SHIPVY
.THRUSTOVERFLOWY
.NOUP
LDA LED_LATCH_00 ; TURN OFF LEDS ONCE A FRAME
;***** THRUST DONE
; SEE IF CANNON IS DYING AND IF SO SKIP A BUNCH OF STUFF BUT STILL FLY AROUND
LDA #F0_CANNONDYING
AND FLAGS0
BEQ .CANNONNOTDYING
; DO EXTRA CANNON DYING STUFF HERE!
; FLASH LEDS
; LDA #$FF
JSR FLASHLEDS
JMP .SKIP_STUFF_WHEN_CANNON_DYING
#IF DISTELLA!=0
dc %00010000
dc %00111000
dc %01101100
dc %11000110
dc %01101100
#ENDIF
.CANNONNOTDYING
;***** START FIRE SHOT
; CHECK FOR LEADING EDGE ON FIRE BUTTON
ASL FLAGS0 ; F0_PREVBUTTONS IS HIGH BIT
BCC .NOFIRE ; WAS PRESSED - NO FIRE
ASL INPT4
BCS .NOFIRE
; FIRE!!!
; MAKE SOUND
LDA #9
STA SOUND0
LDA #SB_SHOOTING
ORA SOUNDFLAGS
STA SOUNDFLAGS
; REPLACE OLDEST SHOT (LOWEST NUMBER)
LDX #SHOT0-SHOT0
LDA SHOT0TIME
CMP SHOT1TIME
BCC .SHOT0LT1
.SHOT0GE1
LDX #SHOT1-SHOT0
LDA SHOT1TIME
.SHOT0LT1
CMP SHOT2TIME
BCC .NOTSHOT2
LDX #SHOT2-SHOT0
.NOTSHOT2
.SHOT0
; LOAD UP WITH INFO FROM SHIP
; COPY SHIP POSITION
CLC
LDA SHIPX+1
ADC #4
STA SHOT0X,X
;CLC ; CARRY IS CLEAR
LDA SHIPY+1
ADC #4
STA SHOT0Y,X
; SHOT VELOCITY
; COPY SHIP VELOCITY INTO SHOT VELOCITY ACCOUNTING FOR SCALE DIFFERENCE
LDA SHIPVX
BPL .SHIFTSHOTVXPOS
LSR
LSR
LSR
; LSR
ORA #%11100000
BMI .SHIFTSHOTVXDONE
.SHIFTSHOTVXPOS
LSR
LSR
LSR
; LSR
AND #%00011111
.SHIFTSHOTVXDONE
STA .TEMP0
LDA SHIPVY
BPL .SHIFTSHOTVYPOS
LSR
LSR
LSR
; LSR
ORA #%11100000
BMI .SHIFTSHOTVYDONE
.SHIFTSHOTVYPOS
LSR
LSR
LSR
; LSR
AND #%00011111
.SHIFTSHOTVYDONE
STA .TEMP1
; ADD SHIP DIRECTION COMPONENT
LDA SHIPDIR
LSR
LSR
TAY
LDA SINTAB16,Y
; TAY
; ASL
; TYA
; ROR
CLC
ADC .TEMP0
STA SHOT0VX,X
LDA SHIPDIR
LSR
LSR
TAY
LDA COSTAB16,Y
; TAY
; ASL
; TYA
; ROR
CLC
ADC .TEMP1
STA SHOT0VY,X
; SET SHOT TIME
LDA #SHOTTIME
STA SHOT0TIME,X
.NOFIRE
ASL INPT4
ROR FLAGS0 ; F0_PREVBUTTONS IS HIGH BIT
; ***** SHOTS DONE
; ***** FUZZBALL
#IF DEBUG_DISABLE_FUZZBALL == 0
; FUZZBALL
LDA #F0_FUZZBALLACTIVE
BIT FLAGS0
BEQ .FUZZBALLNOTACTIVE
JMP .FUZZBALLACTIVE
.FUZZBALLNOTACTIVE
; NOT ACTIVE, PUT IN THE CENTER
; CHECK TO SEE IF CANNON CAN SHOOT
; LDA VBLS
; AND #$0F
; BNE .CANNON_CANT_SHOOT
LDA CANNONDIR
CLC
ADC ISHIELDANGLE
EOR #$FF
LSR
LSR
LSR
TAY
LDX SHOTSHIELDTAB32,Y
LDA SHOTSHIELDMASKL,X
AND ISHIELDBITSL
STA .TEMP0
LDA SHOTSHIELDMASKH,X
AND ISHIELDBITSH
ORA .TEMP0
BNE .CANNON_CANT_SHOOT
LDA CANNONDIR
CLC
ADC MSHIELDANGLE
EOR #$FF
LSR
LSR
LSR
TAY
LDX SHOTSHIELDTAB32,Y
LDA SHOTSHIELDMASKL,X
AND MSHIELDBITSL
STA .TEMP0
LDA SHOTSHIELDMASKH,X
AND MSHIELDBITSH
ORA .TEMP0
BNE .CANNON_CANT_SHOOT
LDA CANNONDIR
CLC
ADC OSHIELDANGLE
EOR #$FF
LSR
LSR
LSR
TAY
LDX SHOTSHIELDTAB32,Y
LDA SHOTSHIELDMASKL,X
AND OSHIELDBITSL
STA .TEMP0
LDA SHOTSHIELDMASKH,X
AND OSHIELDBITSH
ORA .TEMP0
BNE .CANNON_CANT_SHOOT
; SCALE CANNON DIRECTION TO FUZZBALL DIRECTION
LDA CANNONDIR
LSR
LSR
STA FUZZBALLDIR
; ACTIVATE
LDA #F0_FUZZBALLACTIVE
ORA FLAGS0
STA FLAGS0
LDA #SB_FUZZBALL
ORA SOUNDFLAGS
STA SOUNDFLAGS
BNE .FUZZBALLTOCENTER ; CHEAP JUMP
.FUZZBALLOFFSCREEN
.FUZZBALLDEACTIVATE
; LDA LED_LATCH_00 ; TURN OFF LEDS
LDA #$FF-F0_FUZZBALLACTIVE
AND FLAGS0
STA FLAGS0
LDA #$FF-SB_CHANNEL0_FLAGS
AND SOUNDFLAGS
STA SOUNDFLAGS
.CANNON_CANT_SHOOT
.FUZZBALLTOCENTER
LDA #160/2-4
STA FUZZBALLX
LDA #DISPLAYSCANLINES/4-4
STA FUZZBALLY
BNE .FUZZBALLDONE ; CHEAP JUMP
.FUZZBALLACTIVE
; LDA #$FF
JSR FLASHLEDS
; DX SIN
LDY FUZZBALLDIR
LDA SINTAB16,Y
TAX
ASL
TXA
ROR
ADC FUZZBALLX
CMP #160
BCS .FUZZBALLOFFSCREEN
STA FUZZBALLX
; DY -COS
SEC
LDA #0
SBC COSTAB16,Y
TAX
ASL
TXA
ROR
ADC FUZZBALLY
CMP #DISPLAYSCANLINES/2
BCS .FUZZBALLOFFSCREEN
STA FUZZBALLY
.FUZZBALL_MISS_SHIP
.FUZZBALLDONE
#ENDIF
; ***** FUZZBALLDONE
; ***** UPDATE SPARKS
#IF DEBUG_DISABLE_SPARKS==0
; UPDATE ALL 3
; CALCULATE TURNSPEED AND VELOCITY SCALING FROM DIFFICULTY
LDA #16
SEC
SBC DIFFICULTY ; NOW SPEED TIMER CAN BE 16 LEVELS BEFORE PEAK BIG!
LSR
LSR
STA .TEMP3 ; 0-3 DIFFICULTY SAVE
LDA DIFFICULTY
CLC
ADC #6
STA .TEMP4 ; TURNSPEED
LDX #SPARK2-SPARK0
.SPARK_UPDATE_LOOP
; BOX COLLISION
; TEST Y FIRST BECAUSE X NEDS TO BE RECALCULATED FOR DIRECTION ANYWAY
; CALCULATE ARCTANGENT BETWEEN SHIP AND SPARK
LDA SHIPX+1
SEC
SBC SPARK0X,X
AND #$F0
STA .TEMP0
LDA SPARK0Y,X
SEC
SBC SHIPY+1
LSR
LSR
LSR
LSR
ORA .TEMP0
TAY
; CALCULATE IN WHAT DIRECTION TO ROTATE SPARK
LDA SPARK0DIR,X
CMP ATAN256TAB,Y
BEQ .SPARK_ROT_DONE
BMI .SPARK_CLOCKWISE
.SPARK_COUNTERCLOCKWISE
SEC
SBC .TEMP4
BNE .SPARK_ROT ; CHEAP JUMP
BEQ .SPARK_ROT ; RARE BACKUP
; HIDE SPARK_RESET AFTER JMP
.SPARK_RESET
LDA #160/2
STA SPARK0X,X
LDA #DISPLAYSCANLINES/4
STA SPARK0Y,X
BNE .NEXT_SPARK ; CHEAP JUMP
.SPARK_CLOCKWISE
CLC
ADC .TEMP4
.SPARK_ROT
STA SPARK0DIR,X
.SPARK_ROT_DONE
; MOVE SPARK BY SIN,COS
LSR
LSR
TAY
STY .TEMP2
LDA SINTAB16,Y
JSR .SPARKDELTADIFFICULTY ; SCALES DELTA BASED ON DIFFICULTY, RETURNS WITH DELTA IN A AND CARRY, DESTROYS Y
ADC SPARK0X,X
CMP #160
BCS .SPARK_RESET
STA SPARK0X,X
LDY .TEMP2
LDA COSTAB16,Y
JSR .SPARKDELTADIFFICULTY ; SCALES DELTA BASED ON DIFFICULTY, RETURNS WITH DELTA IN A AND CARRY
ADC SPARK0Y,X
CMP #DISPLAYSCANLINES/2
BCS .SPARK_RESET
STA SPARK0Y,X
; NEXT SPARK
.NEXT_SPARK
DEX
DEX
DEX
BMI .SPARK_UPDATE_DONE
JMP .SPARK_UPDATE_LOOP
; SUBROUTINE TO MOVE SPARK SPEED BASED ON DIFFICULTY
.SPARKDELTADIFFICULTY
BMI .SDDNEG
.SDDPOS
; LSR
LDY .TEMP3 ; REDUCED 0-3 DIFFICULTY COUNTER
BEQ .SDDPOSDONE
LSR
DEY
BEQ .SDDPOSDONE
LSR
DEY
BEQ .SDDPOSDONE
LSR
.SDDPOSDONE
;AND #%00001111
RTS
.SDDNEG
; LSR
LDY .TEMP3 ; REDUCED 0-3 DIFFICULTY COUNTER
BEQ .SDDNEGDONE
LSR
DEY
BEQ .SDDNEGDONE
LSR
DEY
BEQ .SDDNEGDONE
LSR
.SDDNEGDONE
ORA #%11110000
RTS
.SPARK_UPDATE_DONE
; TRIGGER SPARK SOUND IF ANY ARE ALIVE
LDA #SB_SPARK_ACTIVE
ORA SOUNDFLAGS
STA SOUNDFLAGS
;.NOACTIVESPARKS
#ENDIF
; ***** UPDATE SPARKS DONE
; ***** UPDATE SHOTS
; LOOP BACKWARDS THROUGH THE THREE SHOTS
LDX #SHOT2-SHOT0
.SHOTLOOP
; CHECK TIMER
LDY SHOT0TIME,X
BEQ .SHOTDONEVECTOR
; DECREMENT TIMER
DEY
STY SHOT0TIME,X
BNE .SHOTNOTDONE
.KILLSHOT
; JUST WENT TO ZERO, MOVE OFF SCREEN
LDY #0
STY SHOT0X,X
STY SHOT0TIME,X
LDY #200
STY SHOT0Y,X
.SHOTDONEVECTOR
JMP .SHOTDONE
.SHOTNOTDONE
; MOVE SHOT WITH SCREEN WRAPPING
LDA SHOT0VY,X
BPL .SHOTVYPOS
.SHOTVYNEG
LSR
LSR
ORA #%11000000
ADC SHOT0Y,X
BPL .SHOTVYNOWRAP
CLC
ADC #DISPLAYSCANLINES/2
BCS .SAVESHOTY ; QUICK JMP, CARRY ALWAYS SET
.SHOTVYPOS
LSR
LSR
AND #%00111111
ADC SHOT0Y,X
CMP #DISPLAYSCANLINES/2
BCC .SHOTVYNOWRAP
SEC
SBC #DISPLAYSCANLINES/2
.SHOTVYNOWRAP
.SAVESHOTY
STA SHOT0Y,X
; CALC DISTANCE FROM CENTER
SEC
SBC #DISPLAYSCANLINES/4
STA .TEMP1
; STA .TEMP3
; MOVE SHOT WITH SCREEN WRAPPING
LDA SHOT0VX,X
BPL .SHOTVXPOS
.SHOTVXNEG
LSR
LSR
ORA #%11000000
ADC SHOT0X,X
CMP #160
BCC .SHOTVXNOWRAP
CLC
ADC #160
BCS .SAVESHOTX ; QUICK JMP, CARRY ALWAYS SET
.SHOTVXPOS
LSR
LSR
AND #%00111111
ADC SHOT0X,X
CMP #160
BCC .SHOTVXNOWRAP
SEC
SBC #160
.SHOTVXNOWRAP
.SAVESHOTX
STA SHOT0X,X
dswdebug
; CALC DIST FROM CENTER
SEC
SBC #160/2
STA .TEMP2
; AND #$F0
STA .TEMP0
#IF DEBUG_BULLET_SHIELD_COL!=0
LDA #$0
STA COLUBK
#ENDIF
; COLIDE WITH BASE (INLINE TILTED OCTAGON)
; ABS(DX)
LDA .TEMP2
BPL .SHOTXPOS
EOR #$FF
CLC
ADC #1
STA .TEMP2
.SHOTXPOS
; ABS(DY)
LDA .TEMP1
BPL .SHOTYPOS
EOR #$FF
CLC
ADC #1
; STA .TEMP3
.SHOTYPOS
; COMPARE DX TO DY
CMP .TEMP2
BCC .SHOTDXGREATER
.SHOTDYGREATER
; DY IS GREATER: DIST = DY+DX/2
LSR .TEMP2
JMP .SHOTDISTADD
.SHOTDXGREATER
; DX IS GREATER: DIST = DX+DY/2
LSR
.SHOTDISTADD
ADC .TEMP2
.SHOTBASEDIST
STA .TEMP3 ; DISTANCE
CMP #SHOT_OUTER_SHIELD_RADIUS
BCC .SHOT_INSIDE_OUTER_SHIELDS
JMP .SHOT_OUTSIDE_OUTER_SHIELDS
.SHOT_INSIDE_OUTER_SHIELDS
#IF DEBUG_BULLET_SHIELD_COL!=0
LDA #$C0
STA COLUBK
#ENDIF
; INSIDE OUTER SHIELDS
;CALC ANGLE
LDA .TEMP0
ASL
ASL
AND #$F0
STA .TEMP0
LDA .TEMP1
; LSR
; LSR
LSR
LSR
AND #$0F
ORA .TEMP0
TAY
LDA ATAN256TAB,Y
STA .TEMP2 ; ANGLE
#IF DEBUG_BULLET_SHIELD_COL!=0
LSR
LSR
TAY
LDA SINTAB16,Y
CLC
ADC #160/2
STA SPARK0X
LDA .TEMP2
CLC
ADC #$80
LSR
LSR
TAY
LDA COSTAB16,Y
CLC
ADC #DISPLAYSCANLINES/4
STA SPARK0Y
LDA #0
STA OSHIELDBITSL
STA OSHIELDBITSH
STA MSHIELDBITSL
STA MSHIELDBITSH
STA ISHIELDBITSL
STA ISHIELDBITSH
LDA .TEMP2
CLC
ADC OSHIELDANGLE
LSR
LSR
LSR
TAY
LDA SHOTSHIELDTAB32,Y
TAY
LDA SHOTSHIELDMASKL,Y
STA OSHIELDBITSL
LDA SHOTSHIELDMASKH,Y
STA OSHIELDBITSH
LDA .TEMP2
CLC
ADC MSHIELDANGLE
LSR
LSR
LSR
TAY
LDA SHOTSHIELDTAB32,Y
TAY
LDA SHOTSHIELDMASKL,Y
STA MSHIELDBITSL
LDA SHOTSHIELDMASKH,Y
STA MSHIELDBITSH
LDA .TEMP2
CLC
ADC ISHIELDANGLE
LSR
LSR
LSR
TAY
LDA SHOTSHIELDTAB32,Y
TAY
LDA SHOTSHIELDMASKL,Y
STA ISHIELDBITSL
LDA SHOTSHIELDMASKH,Y
STA ISHIELDBITSH
#ENDIF
LDA .TEMP3
CMP #SHOT_MIDDLE_SHIELD_RADIUS
BCC .SHOT_INSIDE_MIDDLE_SHIELDS
; TEST OUTER SHIELDS ONLY
; COLISION DETECT
LDA .TEMP2
CLC
ADC OSHIELDANGLE
LSR
LSR
LSR
TAY
LDA SHOTSHIELDTAB32,Y
TAY
#IF DEBUG_BULLET_SHIELD_COL!=0
; LDA SHOTSHIELDMASKL,Y
; EOR OSHIELDBITSL
; STA OSHIELDBITSL
; LDA SHOTSHIELDMASKH,Y
; EOR OSHIELDBITSH
; STA OSHIELDBITSH
.SHOTSPARK
.SHOTHITSHIELDENDING
JMP .SHOT_SHIELDS_DONE
#ELSE
LDA SHOTSHIELDMASKL,Y
AND OSHIELDBITSL
BNE .SHOTHITOUTERSHIELD
LDA SHOTSHIELDMASKH,Y
AND OSHIELDBITSH
BNE .SHOTTHITOUTERSHIELD
JMP .SHOT_SHIELDS_DONE
.SHOTTHITOUTERSHIELD
; HIT SHIELD
; KNOCK OUT SHIELD
LDA SHOTSHIELDMASKL,Y
.SHOTHITOUTERSHIELD
EOR OSHIELDBITSL
STA OSHIELDBITSL
LDA SHOTSHIELDMASKH,Y
EOR OSHIELDBITSH
STA OSHIELDBITSH
; ADD 1[0] TO SCORE
LDA #1
; FALL INTO SHOT SHIELD ENDING
.SHOTHITSHIELDENDING
; ADD TO SCORE BCD AND BIG ENDIAN - ORDER DIGITS WILL BE DISPLAYED
CLC
SED
ADC SCORE+0
STA SCORE+0
LDA #0
ADC SCORE+1
STA SCORE+1
LDA #0
ADC SCORE+2
STA SCORE+2
CLD
; DECREMENT NUMBER OF SHIELD BITS ON
DEC SHIELDBITSON
.SHOTSPARK
LDA SOUNDFLAGS
AND #SB_FUZZBALL
BNE .FUZZBALLINUSE
; MOVE SPARK TO LOCATION
LDA SHOT0X,X
SEC
SBC #4
STA FUZZBALLX
LDA SHOT0Y,X
SBC #4
STA FUZZBALLY
.FUZZBALLINUSE
; PLAY SFX
LDA #SOUND1_SHIELD_SPARK_EXPLOSION_SIZE-1
STA SOUND1
LDA #SB_SHIELD_SPARK_EXPLOSION
ORA SOUNDFLAGS
STA SOUNDFLAGS
LDA LED_LATCH_11 ; STROBE LEDS
; KILL SHOT
JMP .KILLSHOT
#ENDIF
.SHOT_INSIDE_MIDDLE_SHIELDS
CMP #SHOT_INNER_SHIELD_RADIUS
BCC .SHOT_INSIDE_INNER_SHIELDS
#IF DEBUG_BULLET_SHIELD_COL!=0
LDA #$20
STA COLUBK
#ENDIF
; TEST MIDDLE SHIELDS ONLY
LDA .TEMP2
CLC
ADC MSHIELDANGLE
LSR
LSR
LSR
TAY
#IF DEBUG_BULLET_SHIELD_COL!=0
; LDA SHOTSHIELDMASKL,Y
; EOR MSHIELDBITSL
; STA MSHIELDBITSL
; LDA SHOTSHIELDMASKH,Y
; EOR MSHIELDBITSH
; STA MSHIELDBITSH
JMP .SHOT_SHIELDS_DONE
#ELSE
LDA SHOTSHIELDTAB32,Y
TAY
; COLISION DETECT
LDA SHOTSHIELDMASKL,Y
AND MSHIELDBITSL
BNE .SHOTHITMIDDLESHIELD
LDA SHOTSHIELDMASKH,Y
AND MSHIELDBITSH
BNE .SHOTTHITMIDDLESHIELD
JMP .SHOT_SHIELDS_DONE
.SHOTTHITMIDDLESHIELD
; HIT SHIELD
; KNOCK OUT SHIELD
LDA SHOTSHIELDMASKL,Y
.SHOTHITMIDDLESHIELD
EOR MSHIELDBITSL
STA MSHIELDBITSL
LDA SHOTSHIELDMASKH,Y
EOR MSHIELDBITSH
STA MSHIELDBITSH
; ADD 2[0] TO SCORE
LDA #2
JMP .SHOTHITSHIELDENDING
#ENDIF
.SHOT_INSIDE_INNER_SHIELDS
#IF DEBUG_BULLET_SHIELD_COL!=0
LDA #$40
STA COLUBK
#ENDIF
; TEST INNER SHIELDS ONLY, IF BULLET PASSES THROUGH PLAYER WINS LEVEL
; HIT INNER SHIELD
LDA .TEMP2
CLC
ADC ISHIELDANGLE
LSR
LSR
LSR
TAY
#IF DEBUG_BULLET_SHIELD_COL!=0
; LDA SHOTSHIELDMASKL,Y
; EOR ISHIELDBITSL
; STA ISHIELDBITSL
; LDA SHOTSHIELDMASKH,Y
; EOR ISHIELDBITSH
; STA ISHIELDBITSH
JMP .SHOT_SHIELDS_DONE
#ELSE
LDA SHOTSHIELDTAB32,Y
TAY
; COLISION DETECT
LDA SHOTSHIELDMASKL,Y
AND ISHIELDBITSL
BNE .SHOTHITINNERSHIELD
LDA SHOTSHIELDMASKH,Y
AND ISHIELDBITSH
BEQ .SHOTTHROUGHINNERSHIELD
; HIT SHIELD
; KNOCK OUT SHIELD
LDA SHOTSHIELDMASKL,Y
.SHOTHITINNERSHIELD
EOR ISHIELDBITSL
STA ISHIELDBITSL
LDA SHOTSHIELDMASKH,Y
EOR ISHIELDBITSH
STA ISHIELDBITSH
; ADD 3[0] TO SCORE FOR INNER SHIELD SEGMENT
LDA #3
JMP .SHOTHITSHIELDENDING
#IF DISTELLA != 0
dc %00111100
dc %01111110
dc %11011011
dc %11011011
dc %11111111
dc %11111111
dc %11000011
dc %01111110
dc %00111100
#ENDIF
.SHOTTHROUGHINNERSHIELD
;***** HIT THE CANNON, WON THE LEVEL
; ADD 144[0] SCORE BCD (ALLOW ROLLOVER, WHAT THE HECK)
LDA #$44
CLC
SED
ADC SCORE+0
STA SCORE+0
LDA #$01
ADC SCORE+1
STA SCORE+1
LDA #0
ADC SCORE+2
STA SCORE+2
; ADD A SHIP IF WE ARE NOT MAXED OUT
LDA SHIPS
CMP #99
BEQ .MAXSHIPS
CLC
ADC #1
STA SHIPS
.MAXSHIPS
CLD
; JUMP AND DO CANNON EXPLOSION
; FORCE CANNON TO DIE DEBUG
LDX #CANNONDIE-INITTAB
JSR INITMEM
; REFIL SHIELDS HERE
LDX #INITREFILSHIELDSDATA-INITTAB
JSR INITMEM
JMP .SKIP_STUFF_WHEN_CANNON_DYING
#ENDIF
.SHOT_OUTSIDE_OUTER_SHIELDS
; COLIDE SHOT WITH SPARK0
; COLLIDE X
LDA SHOT0X,X
STA .TEMP0
SEC
SBC SPARK0X
CLC
ADC #SPARKSHOTRADIUS
CMP #SPARKSHOTRADIUS*2
BCS .NOCOLSPARK0
; COLLIDE Y
LDA SHOT0Y,X
TAY
SEC
SBC SPARK0Y
CLC
ADC #SPARKSHOTRADIUS
CMP #SPARKSHOTRADIUS*2
BCS .NOCOLSPARK0
; SHOT SPARK0
LDA #160/2
STA SPARK0X
LDA #DISPLAYSCANLINES/4
STA SPARK0Y
JMP .SHOTSPARK
.NOCOLSPARK0
.SPARK0NOTACTIVE
; COLIDE SHOT WITH SPARK1
; COLLIDE X
LDA SHOT0X,X
STA .TEMP0
SEC
SBC SPARK1X
CLC
ADC #SPARKSHOTRADIUS
CMP #SPARKSHOTRADIUS*2
BCS .NOCOLSPARK1
; COLLIDE Y
LDA SHOT0Y,X
TAY
SEC
SBC SPARK1Y
CLC
ADC #SPARKSHOTRADIUS
CMP #SPARKSHOTRADIUS*2
BCS .NOCOLSPARK1
; SHOT SPARK1
LDA #160/2
STA SPARK1X
LDA #DISPLAYSCANLINES/4
STA SPARK1Y
JMP .SHOTSPARK
.NOCOLSPARK1
.SPARK1NOTACTIVE
; COLIDE SHOT WITH SPARK2
; COLLIDE X
LDA SHOT0X,X
STA .TEMP0
SEC
SBC SPARK2X
CLC
ADC #SPARKSHOTRADIUS
CMP #SPARKSHOTRADIUS*2
BCS .NOCOLSPARK2
; COLLIDE Y
LDA SHOT0Y,X
TAY
SEC
SBC SPARK2Y
CLC
ADC #SPARKSHOTRADIUS
CMP #SPARKSHOTRADIUS*2
BCS .NOCOLSPARK2
; SHOT SPARK2
LDA #160/2
STA SPARK2X
LDA #DISPLAYSCANLINES/4
STA SPARK2Y
JMP .SHOTSPARK
.NOCOLSPARK2
.SPARK2NOTACTIVE
.SHOT_SHIELDS_DONE
.SHOTDONE
TXA ;2
SEC ;2
SBC #SHOT1-SHOT0 ;2
TAX ;2
BMI .SHOTSDONE
JMP .SHOTLOOP
.SHOTSDONE
;***** UPDATE SHOTS DONE
.SKIP_STUFF_WHEN_CANNON_DYING
;***** MOVE SHIP BY VELOCITY WITH DECELERATION
LDA SHIPVX
BPL .VXPOS
.VXNEG
LDX #$FF
CLC
ADC #2
BCS .NOXVEL ; ZERO OR POSITIVE
BCC .VXDONE
.VXPOS
LDX #0
SEC
SBC #2
BCC .NOXVEL ; NEGATIVE
BEQ .NOXVEL ; ZERO
.VXDONE
STA SHIPVX
STX .TEMP0
ASL
ROL .TEMP0
ASL
ROL .TEMP0
ASL
ROL .TEMP0
CLC
ADC SHIPX
STA SHIPX
LDA .TEMP0
ADC SHIPX+1
; BOUND X TO 0 TO 159
CMP #160
BCC .NOWRAPX
CMP #200
BCS .XOFFRIGHT ; BLT
.XOFFLEFT
; SEC
SBC #160-1 ; ACCOUNT FOR WRONG CARRY BIT
JMP .NOWRAPX
.XOFFRIGHT
; CLC
ADC #160-1 ; ACCOUNT FOR WRONG CARRY BIT
BCC .NOWRAPX
.NOWRAPX
STA SHIPX+1
.NOXVEL
LDA SHIPVY
BPL .VYPOS
.VYNEG
LDY #$FF
CLC
ADC #2
BCS .NOYVEL ; ZERO OR POSITIVE
BCC .VYDONE
.VYPOS
LDY #0
SEC
SBC #2
BCC .NOYVEL ; NEGATIVE
BEQ .NOYVEL ; ZERO
.VYDONE
STA SHIPVY
STY .TEMP0
ASL
ROL .TEMP0
ASL
ROL .TEMP0
ASL
ROL .TEMP0
CLC
ADC SHIPY
STA SHIPY
LDA .TEMP0
ADC SHIPY+1
; BOUND Y TO 0 TO DISPLAYSCANLINES/2
CMP #DISPLAYSCANLINES/2
BCC .NOWRAPY
CMP #200
BCS .YOFFBOTTOM ; BLT
.YOFFTOP
; SEC
SBC #(DISPLAYSCANLINES/2)-1 ; ACCOUNT FOR WRONG CARRY BIT
JMP .NOWRAPY
.YOFFBOTTOM
; CLC
ADC #(DISPLAYSCANLINES/2)-1 ; ACCOUNT FOR WRONG CARRY BIT
BCC .NOWRAPY
.NOWRAPY
STA SHIPY+1
.NOYVEL
;***** MOVE SHIP BY VELOCITY WITH DECELERATION DONE
;***** CANNON SHIP COLLISION
.DISTANCETOSHIP EQU .TEMP3
.ANGLETOSHIP EQU .TEMP4
; CALCULATE X DISTANCE FROM CENTER
LDA SHIPX+1
SEC
SBC #(SCREEN_CENTER_X)-4
TAY ; SAVE DX IN Y FOR DISTANCE, NOT FOR ATAN
AND #$F0
STA .TEMP0
; CALCULATE Y DISTANCE FROM CENTER
LDA SHIPY+1
SEC
SBC #(SCREEN_CENTER_Y)-4
STA .TEMP1
LSR
LSR
LSR
LSR
ORA .TEMP0
TAX
LDA ATAN256TAB,X
STA .ANGLETOSHIP
; ABS(DY)
LDA .TEMP1
BPL .DYPOS
EOR #$FF
CLC
ADC #1
STA .TEMP1
.DYPOS
; ABS(DX)
TYA
BPL .DXPOS
EOR #$FF
CLC
ADC #1
.DXPOS
; COMPARE DX TO DY
CMP .TEMP1
BCC .DYGREATER
.DXGREATER
; DX IS GREATER: DIST = DX+DY/2
LSR .TEMP1
BNE .CALCDIST
BEQ .CALCDIST
.DYGREATER
; DY IS GREATER: DIST = DY+DX/2
LSR
.CALCDIST
ADC .TEMP1
STA .DISTANCETOSHIP
; SEE IF THE SHIP BUMPED THE SHIELDS
CMP #OUTERSHIELDDIAMETER
BCS .SHIPNOHITSHIELDS
; SHIP HIT SHILEDS
; PLAY SOUND
LDA #15
STA SOUND0
LDA #SB_SHIP_BOUNCE
ORA SOUNDFLAGS
STA SOUNDFLAGS
; SET BEARING
LDA #20+$80
SEC
SBC .ANGLETOSHIP
STA SHIPDIR
; SET VELOCITY SIN(A), -COS(A)
; -COS(A) = SIN(A+3PI/2) ELIMINATES A NEGATE AND AN ADD IN COS FOR TABLE LOOKUP
LDA .ANGLETOSHIP
SEC
SBC #20
LSR
LSR
TAX
EOR #%00100000
TAY
LDA SINTAB,X
BPL .VXPOSITIVE
SEC
; ROR
; SEC
BCS .VXBOUNCEFINISH
.VXPOSITIVE
; LSR
CLC
.VXBOUNCEFINISH
ROR
STA SHIPVX
LDA COSTAB,Y
BPL .VYPOSITIVE
SEC
; ROR
; SEC
BCS .VYBOUNCEFINISH
.VYPOSITIVE
; LSR
CLC
.VYBOUNCEFINISH
ROR
STA SHIPVY
.SHIPNOHITSHIELDS
.SKIP_STUFF_WHEN_PLAYER_DYING ; STUFF BELOW THIS GETS EXECUTED WHILE PAYER IS DYING
RANDOM1 ; RANDOM SAMPLE SEED
;***** CANNON SHIP COLLISION DONE
; ***** ROTATESHIELDS
; ; FUZZ TEST SHIELD SEGMENTS
; LDA VBLS
; STA OSHIELDBITSL
; STA OSHIELDBITSH
; STA MSHIELDBITSL
; STA MSHIELDBITSH
; STA ISHIELDBITSL
; STA ISHIELDBITSH
; FILL SHIELD BITS IF NEEDED
; DON'T FILL SHIELDS EVERY FRAME SO PLAYER CAN GET CLUE THAT THEY ARE EXPANDING
; FILL FROM OUTSIDE IN ONCE PER FRAME TO ENHANCE EFFECT
LDA VBLS
AND #%00000111
BNE .NOUPDATEDRONEBITS
; DO ONE OF THESE EACH IN ROUND ROBIN
; HANDLE TIMER TO DRONE THE SHIELDS
LDA SHIELDBITSON
CMP SHIELDBITSDRONE
BEQ .FILLSHIELDSDONE
BMI .SOUND0_DRONE_DEC
INC SHIELDBITSDRONE
INC SHIELDBITSDRONE
BNE .SHILDBITSDRONEFINE ; CHEAP JUMP
.SOUND0_DRONE_DEC
STA SHIELDBITSDRONE
; DEC SHIELDBITSDRONE
.SHILDBITSDRONEFINE
JMP .FILLSHIELDSDONE
.NOUPDATEDRONEBITS
TAX
DEX
BNE .NOFLOODOUTER
; IF THE OUTER SHIELDS ARE EMPTY,
; MOVE THE BITS FROM THE MIDDLE ONES OUT AND CLEAR MIDDLE
LDA OSHIELDBITSH
ORA OSHIELDBITSL
BNE .NOFLOODOUTER
LDA MSHIELDBITSL
STA OSHIELDBITSL
LDA MSHIELDBITSH
STA OSHIELDBITSH
; WHEN MOVING MIDDLE BITS OUT, CLEAR MIDDLE
LDA #0
STA MSHIELDBITSL
STA MSHIELDBITSH
; SWITCH SHIELDS ROTATION DIRECTION
LDA FLAGS0
EOR #F0_SHIELDROTCCW
STA FLAGS0
.NOFLOODOUTER
DEX
BNE .NOFLOODMIDDLE
; IF THE MIDDLE SHIELDS ARE EMPTY,
; MOVE THE BITS FROM THE INNER ONES OUT AND CLEAR INNER
LDA MSHIELDBITSH
ORA MSHIELDBITSL
BNE .NOFLOODMIDDLE
LDA ISHIELDBITSL
STA MSHIELDBITSL
LDA ISHIELDBITSH
STA MSHIELDBITSH
; WHEN MOVING INNER BITS OUT, CLEAR INNER
LDA #0
STA ISHIELDBITSL
STA ISHIELDBITSH
BEQ .FILLSHIELDSDONE
.NOFLOODMIDDLE
DEX
BNE .NOFLOODINNER
; IF THE INNER SHIELDS ARE EMPTY, REFILL THEM
LDA ISHIELDBITSH
ORA ISHIELDBITSL
BNE .NOFLOODINNER
LDA #$FF
STA ISHIELDBITSL
STA ISHIELDBITSH
; REPLENISH SHIELDBITS
LDA #12
CLC
ADC SHIELDBITSON
STA SHIELDBITSON
BNE .FILLSHIELDSDONE ; CHEAP JUMP
.NOFLOODINNER
.NOFILLSHIELDS
.FILLSHIELDSDONE
; ROTATE SHIELDS
; SEE IF SHIELDS ARE ROTATING CLOCKWISE OR COUNTERCLOCKWISE (RELATIVE TO OUTER SHIELD)
LDA #F0_SHIELDROTCCW
BIT FLAGS0
BEQ .CW
; "CCW" REFERRING TO THE OUTER SHIELD
; CCW
#IF DEBUG_DONT_ROT_SHIELDS==0
INC OSHIELDANGLE
#ENDIF
LDA OSHIELDANGLE
CMP #OSHIELDBITSIZE+1
BNE .NO_O_WRAPCCW
; RESET SHIELD ANGLE
LDA #0
STA OSHIELDANGLE
; ROTATE SHIELD BITS LEFT
LDA OSHIELDBITSH
LSR
LSR
LSR
LSR
ROL OSHIELDBITSL
LDA OSHIELDBITSH
ROL
AND #%00011111
STA OSHIELDBITSH
.NO_O_WRAPCCW
; CW
#IF DEBUG_DONT_ROT_SHIELDS==0
DEC MSHIELDANGLE
#ELSE
LDA MSHIELDANGLE
#ENDIF
BPL .NO_M_WRAP
; RESET SHIELD ANGLE
LDA #MSHIELDBITSIZE
STA MSHIELDANGLE
; ROTATE BITS RIGHT
LDA MSHIELDBITSH
LSR
AND #%00000111
STA MSHIELDBITSH
LDA MSHIELDBITSL
ROR MSHIELDBITSL
ROL
ROL
ROL
AND #%00011000
ORA MSHIELDBITSH
STA MSHIELDBITSH
.NO_M_WRAP
; CCW
#IF DEBUG_DONT_ROT_SHIELDS==0
INC ISHIELDANGLE
#ENDIF
LDA ISHIELDANGLE
CMP #ISHIELDBITSIZE+1
BNE .NO_I_WRAPCCW
; RESET SHIELD ANGLE
LDA #0
STA ISHIELDANGLE
; ROTATE SHIELD BITS LEFT
LDA ISHIELDBITSH
LSR
LSR
LSR
LSR
ROL ISHIELDBITSL ; 5
LDA ISHIELDBITSH
ROL
AND #%00011111
STA ISHIELDBITSH
.NO_I_WRAPCCW
JMP .ROTDONE
;*****
.CW
; CW
#IF DEBUG_DONT_ROT_SHIELDS==0
DEC OSHIELDANGLE
#ELSE
LDA OSHIELDANGLE
#ENDIF
BPL .NO_O_WRAP
; RESET SHIELD ANGLE
LDA #OSHIELDBITSIZE
STA OSHIELDANGLE
; ROTATE BITS RIGHT
LDA OSHIELDBITSH
LSR
AND #%00000111
STA OSHIELDBITSH
LDA OSHIELDBITSL
ROR OSHIELDBITSL
ROL
ROL
ROL
AND #%00011000
ORA OSHIELDBITSH
STA OSHIELDBITSH
.NO_O_WRAP
; CCW
#IF DEBUG_DONT_ROT_SHIELDS==0
INC MSHIELDANGLE
#ENDIF
LDA MSHIELDANGLE
CMP #MSHIELDBITSIZE+1
BNE .NO_M_WRAPCCW
; RESET SHIELD ANGLE
LDA #0
STA MSHIELDANGLE
; ROTATE SHIELD BITS LEFT
LDA MSHIELDBITSH
LSR
LSR
LSR
LSR
ROL MSHIELDBITSL ; 5
LDA MSHIELDBITSH
ROL
AND #%00011111
STA MSHIELDBITSH
.NO_M_WRAPCCW
; CW
#IF DEBUG_DONT_ROT_SHIELDS==0
DEC ISHIELDANGLE
#ELSE
LDA ISHIELDANGLE
#ENDIF
BPL .NO_I_WRAP
; RESET SHIELD ANGLE
LDA #ISHIELDBITSIZE
STA ISHIELDANGLE
; ROTATE BITS RIGHT
LDA ISHIELDBITSH
LSR
AND #%00000111
STA ISHIELDBITSH
LDA ISHIELDBITSL
ROR ISHIELDBITSL
ROL
ROL
ROL
AND #%00011000
ORA ISHIELDBITSH
STA ISHIELDBITSH
.NO_I_WRAP
.ROTDONE
; ***** ROATATESHIELDS DONE
;***** CANNON DIR
; TURN CANNON TOWARDS SHIP
; ACCOUNT FOR DEAD ZONE
LDX DIFFICULTY
INX
TXA
STA .TEMP0 ; CANNON ROTATE RATE
ASL
STA .TEMP1 ; CANNON ROTATE RATE X 2
LDA CANNONDIR
SEC
SBC .ANGLETOSHIP
CLC
ADC .TEMP0
CMP .TEMP1
BCC .NOCANNONROT
; ROTATE CANNON
LDA CANNONDIR
CMP .ANGLETOSHIP
BPL .CANNONROTCCW
.CANNONROTCW
ADC .TEMP0
STA CANNONDIR
BCC .NOCANNONROT
.CANNONROTCCW
SBC .TEMP0
STA CANNONDIR
.NOCANNONROT
;***** CANNON COLISION AND DIR DONE
; GAME UPDATE COMPLETE
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
; PREPARE TO DRAW SHIP AND FUZZBALL
PREPFORSHIPSCREEN
; POSITION A COUPLE OF SPRITES (1 is first column, and 8 is first column after hpos)
LOADX SHIPX+1
JSR SETXPOS
STA RESP0
STA HMP0
LOADX FUZZBALLX
JSR SETXPOS
STA RESP1
STA HMP1
; GET SHIP FRAME AND FLIP FLAG
; LOAD .TEMP1 WITH OFFSET TO THRUSTING FRAMES IF NEEDED
; LDA SWCHA
; LSR
; LSR
; LSR
; LSR
; EOR #1
; AND VBLS
; AND #1
; EOR #1
; SEC
; SBC #1
; AND #GFX_THRUST-GFX_SHIP
; STA .TEMP1
LDA FLAGS0
AND #F0_PLAYERDYING
BEQ .SHIPNOTEXPLODING
.SHIPEXPLODING
; HANDLE SHIP EXPLODING STATE HERE
; LDA #%000011110
JSR FLASHLEDS
; FLIP P1 ONE AND NOT THE OTHER
LDX #0
STX REFP0
DEX
STX REFP1
LDA VBLS
AND #%00001100
STA .TEMP0
ASL
ADC .TEMP0
AND #%000111000
ADC #GFX_SHIP_EXPLOSION-GFX_SHIP
STA .TEMP6
LDA VBLS
AND #%000111000
STA .TEMP7
LDA #$FF
SEC
SBC VBLS
LSR
LSR
AND #$0F
BNE .SHIPDEADNOTDONE
; THIS WILL SHOW THE SCORE SCREEN OR THE GAME OVER SCREEN
LDA SHIPS
JMP SCORE_SHIPS_SCREEN_ENTRY
.SHIPDEADNOTDONE
#IF PALCOLORS != 0
ORA #$B0
#ELSE
ORA #$90
#ENDIF
STA COLUP0
TXA
; LSR
AND #$0F
; ORA #$80
STA COLUP1
; BNE .ANIMATIONNOTOVER
; LDA #170
; STA SHIPY+1
.ANIMATIONNOTOVER
JMP .SHIPFRAMEDONE ; JEAP JUMP, NEVER ZERO
.SHIPNOTEXPLODING
LDX #0
LDA SWCHA
AND #%00010000
BNE .NOTHRUSTGFX
LDA VBLS
AND #1
BNE .NOTHRUSTGFX
LDX #GFX_THRUST-GFX_SHIP
.NOTHRUSTGFX
STX .TEMP1
LDX #0
LDA SHIPDIR
BPL .NOFLIP
DEX ; SET FLIP BIT (WELL, ALL BITS ACTUALLY)
EOR #$FF ; NEGATE A FOR FRAME CALCULATION
CLC
ADC #1
.NOFLIP
; A IS 0 TO 127 NOW
; (A/2+A/4)/8 IS 0 TO 12, AS IN FRAMES, ADD HALF(6)
CLC
ADC #6
STX REFP0
LSR ; /2
STA .TEMP0
LSR ; /4
CLC
ADC .TEMP0 ; (d/4+d/2)
AND #%11111000
ADC .TEMP1
STA .TEMP6
; LOAD FUZZBALL GRAPHICS
LDA VBLS
STA REFP1
AND #7
ASL
ASL
ASL
ADC #GFX_FUZZBALL-GFX_SHIP_EXPLOSION
STA .TEMP7
.SHIPFRAMEDONE
; CLEAR COLLISION REGISTER
STA CXCLR
PREPFORSHIPSCREENDONE
; PREPARE TO DRAW SHIP AND FUZZBALL COMPLETE
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
; VBLANK
SHIELDS_OVERSCANEND
#IF DEBUGSYNCENABLE!=0
LDY INTIM
BPL .NOTFAIL1
FAIL1 NOP
.NOTFAIL1
#ENDIF
SHIELDS_OVERSCANLOOP
LDA INTIM
BMI SHIELDS_POSTOVERSCAN
BNE SHIELDS_OVERSCANLOOP
STA WSYNC
SHIELDS_POSTOVERSCAN
VBLANK1
LDA #2
DSWVSYNCON1
STA VSYNC ; ENTER VSYNC
; WAIT 3 LINES
; DO NOT SETXPOS HERE BECAUSE THOSE ON THE RIGHT MAY TAKE 2 LINES
; INC VBLS
STA WSYNC
; STA HMOVE ; 2 CYCLES HMOVE
; 52 CYCLES OF PREP
LDX #DISPLAYSCANLINES/2 ; NUMBER OF DOUBLE LINES TO DRAW
TXA
SEC
SBC SPARK0Y
STA .TEMP3
TXA
SEC
SBC SPARK1Y
STA .TEMP4
TXA
SEC
SBC SPARK2Y
STA .TEMP5
LDA SHIPY+1
CLC
ADC #8
STA .TEMP0
LDA FUZZBALLY
CLC
ADC #8
STA .TEMP1
STA WSYNC
; SINGLE WIDE SPRITES
LDA #%00000000
STA NUSIZ0
STA NUSIZ1
STA VDELP0
STA VDELP1
STA VDELBL
; LINE 3
LDA #0
LDx #43+1 ; WAIT 43*64 CYCLES FOR VBLANK
STA WSYNC
DSWVSYNCOFF1
STA VSYNC ; ELECRTON BEAM OFF ; START VBLANK PROCESSING
STx TIM64T ; 43*64 INTVLS = 2752 = 8256 COLCLKS = 36.2LINES
; VBLANK COMPLETE
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
; PREPARE TO DRAW SHIP AND FUZZBALL
; CALL ROUTINE TO PACK SHIELD BITS INTO RAM FOR SHIELD RENDER
JMP PACKSHIELDS1_ENTRY
PACKSHIELDS1DONE
RANDOM2 ; RANDOM 2 SAMPLE POINT
LOADX SPARK2X
CLC
ADC #1
JSR SETXPOS
STA RESM0
STA HMM0
LOADX SPARK1X
CLC
ADC #1
JSR SETXPOS
STA RESM1
STA HMM1
LOADX SPARK0X
CLC
ADC #1
JSR SETXPOS
STA RESBL
STA HMBL
LDX #DISPLAYSCANLINES/2 ; NUMBER OF DOUBLE LINES TO DRAW
SHIP_WAITFORVBLANKEND ; PUT LABEL HERE TO PREVENT BEING HIT EVERY LOOP
#IF DEBUGSYNCENABLE!=0
LDY INTIM
BPL .NOTFAIL2
FAIL2 NOP
.NOTFAIL2
#ENDIF
; WAIT FOR VBLANK TO END AND START LINE LOOP
SHIP_WAITFORVBLANKENDLOOP
LDA INTIM
BMI SHIP_TOPOFFRAME
BNE SHIP_WAITFORVBLANKENDLOOP
SHIP_TOPOFFRAME
STA WSYNC
STA HMOVE
; UNBLANK THE BEAM
LDA #0
DSWVBLANKOFF1
STA VBLANK
; TOP OF IMAGE DISPLAYSCANLINES LINES
; ----------------------------------------------
; SHIP DISPLAY KERNEL
.LINELOOP
; SEE IF IT IS TIME TO DRAW THE SHIP
LDA #7 ; 2
DCP .TEMP0 ; 5 INITIAL VALUE HAS TO BE ADJUSTED
BCC .SKIPDRAW0 ; 2 = 9
LDA .TEMP0 ;3
ORA .TEMP6 ;3
TAY ;2
LDA GFX_SHIP,Y ;4
.CONTINUESHIP0
STA .TEMP2
; SEE IF IT IS TIME TO DRAW THE FUZZBALLP
LDA #7 ; 2
DCP .TEMP1 ; 5 INITIAL VALUE HAS TO BE ADJUSTED
BCC .SKIPDRAW1 ; 2 = 9
LDA .TEMP1 ;3
ORA .TEMP7 ;3
TAY ;2
LDA GFX_SHIP_EXPLOSION,Y ;4
.CONTINUESHIP1
TAY ; 2 SAVE P1 GFX
LDA .TEMP2 ; 3 GET P0 GFX
STX .TEMP2 ; 3 SAVEX
LDX #ENAM1+1 ; 3
TXS ; 2
LDX .TEMP2 ; 3 RECOVER X LINE COUNTER
STA WSYNC
STA GRP0 ; 3
STY GRP1 ; 3
CPX .TEMP3 ; 3
PHP ; 3
CPX .TEMP4 ; 3
PHP ; 3
CPX .TEMP5 ; 3
PHP ; 3
DEX ; 2 NEXT LINE
BNE .LINELOOP ; 3 IF BRANCH TAKEN, 2 IF NOT
; SHIP DISPLAY KERNEL
; ----------------------------------------------
; 30 LINES OF OVERSCAN
LDA #35+1 ; WAIT 35*64 CYCLES FOR OVERSCAN
STA WSYNC
STA TIM64T ; 35*64 INTVLS = 2240 CPU CLOCKS *3 = 6720 COLCLKS / 228 = 29.47 LINES
LDA #2
DSWVBLANKON2
STA VBLANK
JMP .SKIPSKIP
.SKIPDRAW0
LDA #0
BCC .CONTINUESHIP0
.SKIPDRAW1
LDA #0
BCC .CONTINUESHIP1
.SKIPSKIP
; RESET STACK POINTER
LDX #$FF
TXS
; CLEAR GRAPHICS REGISTERS
LDA #0
STA GRP0
STA GRP1
STA GRP0
STA GRP1
STA ENAM0
STA ENAM1
STA ENABL
SHIP_ENDOFFRAME
; DON'T DO COLLISION IF PLAYER OR CANNON IS DYING
LDA FLAGS0
AND #F0_PLAYERDYING|F0_CANNONDYING
BNE .DONTKILLPLAYER
#IF DEBUG_CHEAT_INVINCIBLE==1
BIT SWCHB
BPL .DONTKILLPLAYER
#ENDIF
; CHECK FOR COLISOIN BETWEEN SHIP AND SPARKS
LDA CXM1P ; M1 P0 IN D7
LSR ; PUT BIT INTO D6
ORA CXM0P ; M0 PO IN D6
ORA CXP0FB ; P0 BL IN D6
AND #%01000000 ; MASK OFF BIT NEEDED
#IF DEBUG_DISABLE_SPARK_COL==0
BNE .SPARK_HIT_SHIP
#ENDIF
; FUZZBALL COLLISION
; DON'T KILL PLAYER IF HE TOUCHES FUZZBALL WITHOUT IT BEING ACTIVE
LDA FLAGS0
AND #F0_FUZZBALLACTIVE
BEQ .DONTKILLPLAYER
LDA CXPPMM
AND #%10000000
#IF DEBUG_DISABLE_FUZZBALL_COL==0
BEQ .DONTKILLPLAYER
#ELSE
JMP .DONTKILLPLAYER
#ENDIF
; DEACTIVATE FUZZBALL AND SOUND
.FUZZBALL_HIT_SHIP
.SPARK_HIT_SHIP
.KILLPLAYER
; KILL PLAYER
LDX #PLAYERDIE-INITTAB
JSR INITMEM
; PLACE FUZZBALL ON SHIP
LDA SHIPX+1
STA FUZZBALLX
LDA SHIPY+1
STA FUZZBALLY
; BCD DECREMENT SHIPS
SED
SEC
LDA SHIPS
SBC #1
STA SHIPS
CLD
; PLAY SOUND EFFECT
LDA #SOUND1_SHIP_EXPLOSION_SIZE-1
STA SOUND1
LDA #SB_SHIP_EXLOSION
STA SOUNDFLAGS
; FLAG PLAYER AS DYING
LDA FLAGS0
AND #$FF-F0_FUZZBALLACTIVE
ORA #F0_PLAYERDYING
STA FLAGS0
.DONTKILLPLAYER
#IF 1
; PROCESS SOUND CHANNEL 1 FLAGS IN ORDER OF IMPORTANCE
LDA SOUNDFLAGS
LSR
BCS SOUND1_CANNON_EXPLOSION
LSR
BCS SOUND1_SHIP_EXPLOSION
LSR
BCS SOUND1_SHIELD_SPARK_EXPLOSION
LSR
BCS SOUND1_THRUST
LSR
BCS SOUND1_SPARK_ACTIVE
JSR SOUND1_DRONE
.TOSOUND1DONE
JMP .SOUND1DONE
SOUND1_SHIELD_SPARK_EXPLOSION
SOUND1_CANNON_EXPLOSION
LDX SOUND1
LDA SOUND1_SHIELD_SPARK_EXPLOSION_VOLTAB,X
STA AUDV1
LDA #SND_CTRL_NOISE
STA AUDC1
; LDA #$F
; ROL
LDA #$1E
STA AUDF1
LDA VBLS
AND FLAGS0
AND #F0_CANNONDYING
BNE .CANTDEC
DEX
.CANTDEC
STX SOUND1
BPL .TOSOUND1DONE
LDA FLAGS0
AND #F0_CANNONDYING
BEQ .CLEARSOUND1
; WHEN THE SOUND IS OVER, QUIET IT, MAKE THE BACKGROUND BLACK AND RESTART A LEVEL
LDA #0
; STA AUDV0
; STA AUDV1
STA COLUBK
; INCREMENT DIFFICULTY
LDA DIFFICULTY
CLC
ADC #1
AND #%00001111
BEQ .MAXDIFFICULTY
STA DIFFICULTY
.MAXDIFFICULTY
JMP SCORE_SHIPS_SCREEN_ENTRY
SOUND1_SHIP_EXPLOSION
LDX SOUND1
LDA SOUND1_SHIP_EXPLOSION_VOLTAB,X
STA AUDV1
LDA #SND_CTRL_NOISE
STA AUDC1
LDA SOUND1_SHIP_EXPLOSION_FRQTAB,X
STA AUDF1
DEX
STX SOUND1
BPL .TOSOUND1DONE
.CLEARSOUND1
LDA #SB_CHANNEL0_FLAGS
AND SOUNDFLAGS
STA SOUNDFLAGS
JMP .SOUND1DONE
SOUND1_THRUST
LDA VBLS
CLC
AND #1
ADC #30
STA AUDF1
LDA #SND_CTRL_NOISE
STA AUDC1
LDA #3
STA AUDV1
LDA #$FF-SB_CHANNEL1_FLAGS
AND SOUNDFLAGS
STA SOUNDFLAGS
JMP .SOUND1DONE
SOUND1_SPARK_ACTIVE
LDA #SND_CTRL_SAW ;SND_CTRL_DIV_6
STA AUDC1
LDA #1
STA AUDV1
LDA VBLS
AND #%00000001
ASL
CLC
ADC #5
STA AUDF1
JMP .SOUND1DONE
SOUND1_DRONE
LDA #SND_CTRL_DIV_6
STA AUDC1
LDA SHIELDBITSDRONE
LSR
ADC #(32-(36/2+1+1))-1
STA AUDF1
LDA VBLS
AND #7
TAY
LDA SOUND1_DRONE_VOLTAB,Y
STA AUDV1
; JMP .SOUND1DONE
; BEQ .SOUND1DONE
RTS
; SOUND1_CANNON_EXPLOSION_FRQTAB
; SOUND1_SHIELD_SPARK_EXPLOSION_FRQTAB
; DC SND_FREQUENCYV_______________________________ ; explosion (shield/spark
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCY_V______________________________
; DC SND_FREQUENCY_V______________________________
; DC SND_FREQUENCYV_______________________________
; DC SND_FREQUENCY_V______________________________
; DC SND_FREQUENCY_V______________________________
; SOUND1_CANNON_EXPLOSION_SIZE EQU *-SOUND1_CANNON_EXPLOSION_FRQTAB
; SOUND1_SHIELD_SPARK_EXPLOSION_SIZE EQU *-SOUND1_SHIELD_SPARK_EXPLOSION_FRQTAB
;SOUND1_CANNON_EXPLOSION_SIZE EQU *-SOUND1_CANNON_EXPLOSION_VOLTAB
;SOUND1_CANNON_EXPLOSION_VOLTAB
; DC SND_VOLUME_____________V__
; DC SND_VOLUME_____________V__
; DC SND_VOLUME____________V___
; DC SND_VOLUME___________V____
; DC SND_VOLUME____________V___
; DC SND_VOLUME___________V____
; DC SND_VOLUME__________V_____
; DC SND_VOLUME___________V____
; DC SND_VOLUME__________V_____
; DC SND_VOLUME__________V_____
; DC SND_VOLUME__________V_____
; DC SND_VOLUME__________V_____
; DC SND_VOLUME_________V______
; DC SND_VOLUME________V_______
; DC SND_VOLUME_______V________
; DC SND_VOLUME_________V______
;SOUND1_CANNON_EXPLOSION_SIZE EQU *-SOUND1_CANNON_EXPLOSION_VOLTAB
SOUND1_SHIELD_SPARK_EXPLOSION_VOLTAB
SOUND1_SHIP_EXPLOSION_VOLTAB
DC SND_VOLUME______________V_
DC SND_VOLUME______________V_
DC SND_VOLUME_____________V__
DC SND_VOLUME____________V___
DC SND_VOLUME___________V____
DC SND_VOLUME__________V_____
DC SND_VOLUME_________V______
DC SND_VOLUME________V_______
DC SND_VOLUME_______V________
DC SND_VOLUME______V_________
DC SND_VOLUME_____V__________
DC SND_VOLUME____V___________
DC SND_VOLUME___V____________
DC SND_VOLUME__V_____________
DC SND_VOLUMEV_______________
DC SND_VOLUME___V____________
SOUND1_SHIELD_SPARK_EXPLOSION_SIZE EQU *-SOUND1_SHIELD_SPARK_EXPLOSION_VOLTAB
SOUND1_SHIP_EXPLOSION_FRQTAB
DC SND_FREQUENCY_____V__________________________ ; explosion ship
DC SND_FREQUENCY_____V__________________________
DC SND_FREQUENCY_____V__________________________
DC SND_FREQUENCY____V___________________________
DC SND_FREQUENCY_____V__________________________
DC SND_FREQUENCY_____V__________________________
DC SND_FREQUENCY____V___________________________
DC SND_FREQUENCY____V___________________________
DC SND_FREQUENCY_____V__________________________
DC SND_FREQUENCY_____V__________________________
DC SND_FREQUENCY_______V________________________
DC SND_FREQUENCY_________V______________________
DC SND_FREQUENCY___________V____________________
DC SND_FREQUENCY_____________V__________________
DC SND_FREQUENCY_______________V________________
DC SND_FREQUENCY________________V_______________
SOUND1_SHIP_EXPLOSION_SIZE EQU *-SOUND1_SHIP_EXPLOSION_FRQTAB
#ELSE
SOUND1_SHIELD_SPARK_EXPLOSION_SIZE EQU 1
SOUND1_SHIP_EXPLOSION_SIZE EQU 1
#ENDIF
.SOUND1DONE
;***** SOUND
; POSITION SHOTS HERE SO INSEAD OF ONE BIG LUMP
LOADX SHOT2X
JSR SETXPOS
STA RESM0
STA HMM0
LOADX SHOT1X
JSR SETXPOS
STA RESM1
STA HMM1
LOADX SHOT0X
JSR SETXPOS
STA RESBL
STA HMBL
; CALL ROUTINE TO PACK SHIELD BITS INTO RAM FOR SHIELD RENDER
JMP PACKSHIELDS2_ENTRY
PACKSHIELDS2DONE
; WE OCCASIONALLY GO NEGATIVE HERE
SHIP_BOTTOM_OVERSCANEND
#IF DEBUGSYNCENABLE!=0
LDY INTIM
BPL .NOTFAIL3
FAIL3 NOP
.NOTFAIL3
#ENDIF
; WAIT FOR OVERSCAN TO FINISH
SHIP_BOTTOM_OVERSCANLOOP
LDA INTIM
BMI SHIP_POSTOVERSCAN
BNE SHIP_BOTTOM_OVERSCANLOOP
STA WSYNC
SHIP_POSTOVERSCAN
; BACK TO TOP OF FRAME (VSYNC)
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
; VSYNC
VBLANK2
LDA #2
DSWVSYNCON2
STA VSYNC ; ENTER VSYNC
INC VBLS
; WAIT 3 LINES
; STA WSYNC
; NO HFLIP, CLEAR GRAPHICS, CLEAR VDELP1
LDA #0
STA REFP0
STA REFP1
STA GRP0
STA GRP1
STA VDELP1
; SET SHIELDS P0 POSITION IN FIRST LINE (CONSTANT GUARANTEED NOT TO GO 2 LINES)
LDA #56 ;#$38 56 IS CENTERED ON WIDE SCREEN
JSR SETXPOS ; CALLS STA WSYNC ALMOST IMMEDIATELY
STA RESP0
STA HMP0
; STA WSYNC
; SET SHIELDS P1 POSITION IN SECOND LINE (CONSTANT GUARANTEED NOT TO GO 2 LINES)
LDA #56+8 ;#$38+8
JSR SETXPOS ; CALLS STA WSYNC ALMOST IMMEDIATELY
STA RESP1
STA HMP1
LDA #0
LDX #43+1 ; WAIT 43*64 CYCLES FOR VBLANK
STA WSYNC
DSWVSYNCOFF2
STA VSYNC ; ELECRTON BEAM OFF ; START VBLANK PROCESSING
STX TIM64T ; 43*64 INTVLS = 2752 = 8256 COLCLKS = 36.2LINES
; CALL ROUTINE TO PACK SHIELD BITS INTO RAM FOR SHIELD RENDER
JMP PACKSHIELDS3_ENTRY
PACKSHIELDS3DONE
;***** LOAD CANNON GRAPHICS
; CANNON MUST USE DS_TEMPX RAM FOR SHIELDS,
; AT THIS POINT MAIN LOOP .TEMP_ LOCATIONS ARE ON TOP OF THE SHIELD DATA
LDA #0
STA DS_TEMP1
LDA CANNONDIR
CLC
ADC #$40 ; ACCOUNT FOR FRAME0 POINTING LEFT
; 128*30/256 = 15
; 30 = %00011110
; 30 = 32-2
ASL ;*2
ROL DS_TEMP1 ; SAVE *2
LDX DS_TEMP1
STX DS_TEMP2
STA DS_TEMP0 ; SAVE *2
ASL ; *4
ROL DS_TEMP2
ASL ; *8
ROL DS_TEMP2
ASL ; *16
ROL DS_TEMP2
ASL ; *32
ROL DS_TEMP2
; SUBTRACT *2 AND DIVIDE BY 256 BY DISCARDING LOW BYTE
SEC
SBC DS_TEMP0
LDA DS_TEMP2
SBC DS_TEMP1
LDX #24-2 ; NUMBER OF LINES TO DRAW
CMP #15
BCC .NOVFLIP
EOR #$FF
CLC
ADC #1+(15*2-1)
; MULTIPLY BY 12 (%1100) TO INDEX FRAME
ASL
ASL
STA DS_TEMP0
ASL
ADC DS_TEMP0 ; CARRY ALREADY CLEAR
ADC #12-1 ; START AT BOTTOM
TAY
.COPYBASEUD ;DRAWCANNON_UPSIDEDOWN
LDA GFX_CANNON_LEFT,Y ; 4
ORA DS_BASE_19,X ; 4
STA DS_BASE_19,X ; 4
LDA GFX_CANNON_RIGHT,Y ; 4
ORA DS_BASE_34,X ; 4
STA DS_BASE_34,X ; 4
DEY ; 2
DEX ; 2
DEX ; 2
BPL .COPYBASEUD ; 3 (2)
BMI .CANNONLOADED
.NOVFLIP
ASL
ASL
STA DS_TEMP0
ASL
ADC DS_TEMP0 ; CARRY ALREADY CLEAR
TAY
.COPYBASE ;DRAWCANNON_RIGHTSIDEUP
LDA GFX_CANNON_LEFT,Y ; 4
ORA DS_BASE_19,X ; 4
STA DS_BASE_19,X ; 4
LDA GFX_CANNON_RIGHT,Y ; 4
ORA DS_BASE_34,X ; 4
STA DS_BASE_34,X ; 4
INY ; 2
DEX ; 2
DEX ; 2
BPL .COPYBASE ; 3 (2)
.CANNONLOADED
;***** CANNON GRAPHICS LOADED
#IF 1
;***** SOUND
; SOUNDS BY PRIORITY
; CHANNEL 0 CHANNEL 1
;==========================
;
; SHIP EXPLOSION[S]
;FUZZBALL[P] FUZZBALL CAN JUST MAKE SOUND AND STOMP
; SHIELD EXPLOSION[S]
;SHOTS[P] SHOTS CAN WORK WHEN THERE IS NO FUZZBALL
;SHIP BOUNCE
; THRUST[P]
; P SPARK IN FLIGHT[P]
;P DRONING[P] P DRONING[P] DRONING JUST WORKS WHEN THERE IS NOTHING ELSE
; PROCESS SOUND CHANNEL 0 FLAGS IN ORDER OF IMPORTANCE
LDA SOUNDFLAGS
ASL
BCS SOUND0_FUZZBALL
ASL
BCS SOUND0_SHOTS
ASL
BCS SOUND0_BOUNCE
JSR SOUND0_DRONE
JMP .SOUND0DONE
SOUND0_DRONE
LDA #SND_CTRL_DIV_6
STA AUDC0
LDA SHIELDBITSDRONE
LSR
ADC #(32-(36/2+1+1))
STA AUDF0
LDA VBLS
AND #7
TAY
LDA SOUND1_DRONE_VOLTAB,Y
STA AUDV0
RTS
SOUND0_FUZZBALL
LDA #SND_CTRL_ENGINE
STA AUDC0
LDA VBLS
AND #1
ASL
ADC #5
STA AUDF0
LDY #15
STY AUDV0
BNE .SOUND0DONE ; CHEAP JUMP
SOUND0_SHOT_FRQTAB
DC SND_FREQUENCY__________________________V_____
DC SND_FREQUENCY____________________________V___
SOUND0_SHOT_VOLTAB
DC SND_VOLUME_____________V__
DC SND_VOLUME___________V____
SOUND0_SHOTS
LDA VBLS
AND #1
TAX
LDA #SND_CTRL_SAW
STA AUDC0
LDA SOUND0_SHOT_FRQTAB,X
STA AUDF0
LDA SOUND0_SHOT_VOLTAB,X
STA AUDV0
DEC SOUND0
BNE .SOUND0DONE
LDA #SB_CHANNEL1_FLAGS
AND SOUNDFLAGS
STA SOUNDFLAGS
JMP .SOUND0DONE
SOUND0_DRONE_VOLTAB
SOUND1_DRONE_VOLTAB
DC SND_VOLUME______________V_
DC SND_VOLUME______________V_
DC SND_VOLUME_____________V__
DC SND_VOLUME____________V___
DC SND_VOLUME____________V___
DC SND_VOLUME_____________V__
DC SND_VOLUME______________V_
DC SND_VOLUME______________V_
SOUND0_BOUNCE
LDA #SND_CTRL_ENGINE
STA AUDC0
LDA VBLS
ASL
AND #3
ADC #7
STA AUDF0
LDA SOUND0
STA AUDV0
SEC
SBC #4
STA SOUND0
BPL .SOUND0DONE
LDA #SB_SHIP_BOUNCE
EOR SOUNDFLAGS
STA SOUNDFLAGS
; JMP .SOUND0DONE
.SOUND0DONE
#ENDIF
; GOT ABOUT $125 - $140 CYCLES LEFT
JMP DRAWSHIELDS_ENTRY
;DRAWSHIELDSDONE MOVED TO MAINLOOP
; JMP MAINLOOP
;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************
; INCLUDE ARTWORK
;;; INCLUDE ..\ART\PLAYERSHIP\GFX_SHIP.ASM
GFX_SHIP
dc %00100100
dc %00100100
dc %00100100
dc %00100100
dc %01111110
dc %01111110
dc %11100111
dc %01000010
dc %00010010
dc %00010010
dc %00100100
dc %01100100
dc %01111100
dc %11111110
dc %01001110
dc %10000101
dc %00001000
dc %00010001
dc %00010010
dc %01110010
dc %11111100
dc %01111100
dc %10011110
dc %00001010
dc %00000100
dc %00001000
dc %11110001
dc %01110010
dc %11111100
dc %00111100
dc %00011100
dc %00010100
dc %00000010
dc %11001100
dc %01110000
dc %11110001
dc %01111110
dc %00111000
dc %00111000
dc %01010000
dc %10000000
dc %01100011
dc %11111100
dc %01110000
dc %00110011
dc %00111100
dc %01111000
dc %10100000
dc %01000000
dc %11110000
dc %01111111
dc %00110000
dc %00110000
dc %01111111
dc %11110000
dc %01000000
dc %10100000
dc %01111000
dc %00111100
dc %00110011
dc %01110000
dc %11111100
dc %01100011
dc %10000000
dc %01010000
dc %00111000
dc %00111000
dc %01111110
dc %11110001
dc %01110000
dc %11001100
dc %00000010
dc %00010100
dc %00011100
dc %00111100
dc %11111100
dc %01110010
dc %11110001
dc %00001000
dc %00000100
dc %00001010
dc %10011110
dc %01111100
dc %11111100
dc %01110010
dc %00010010
dc %00010001
dc %00001000
dc %10000101
dc %01001110
dc %11111110
dc %01111100
dc %01100100
dc %00100100
dc %00010010
dc %00010010
dc %01000010
dc %11100111
dc %01111110
dc %01111110
dc %00100100
dc %00100100
dc %00100100
dc %00100100
;;; INCLUDE ..\ART\PLAYERSHIP\GFX_THRUST.ASM
GFX_THRUST
#IF 0
; FAT THRUST
dc %00100100
dc %00100100
dc %00100100
dc %00100100
dc %01111110
dc %01111110
dc %11111111
dc %01011010
dc %00010010
dc %00010010
dc %00100100
dc %01100100
dc %01111100
dc %11111110
dc %01111110
dc %10110101
dc %00001000
dc %00010001
dc %00010010
dc %01110010
dc %11111100
dc %01111100
dc %11111110
dc %01111010
dc %00000100
dc %00001000
dc %11110001
dc %01110010
dc %11111100
dc %01111100
dc %11111100
dc %11010100
dc %00000010
dc %11001100
dc %01110000
dc %11110001
dc %11111110
dc %11111000
dc %11111000
dc %01010000
dc %10000000
dc %01100011
dc %11111100
dc %01110000
dc %11110011
dc %11111100
dc %01111000
dc %10100000
dc %01000000
dc %11110000
dc %01111111
dc %11110000
dc %11110000
dc %01111111
dc %11110000
dc %01000000
#ELSE
; SKINNY THRUST
dc %00100100
dc %00100100
dc %00100100
dc %00100100
dc %01111110
dc %01111110
dc %11111111
dc %01011010
dc %00010010
dc %00010010
dc %00100100
dc %01100100
dc %01111100
dc %11111110
dc %01111110
dc %10110101
dc %00001000
dc %00010001
dc %00010010
dc %01110010
dc %11111100
dc %01111100
dc %10111110
dc %01101010
dc %00000100
dc %00001000
dc %11110001
dc %01110010
dc %11111100
dc %01111100
dc %01111100
dc %00010100
dc %00000010
dc %11001100
dc %01110000
dc %11110001
dc %01111110
dc %11111000
dc %11111000
dc %01010000
dc %10000000
dc %01100011
dc %11111100
dc %01110000
dc %11110011
dc %11111100
dc %01111000
dc %10100000
dc %01000000
dc %11110000
dc %01111111
dc %11110000
dc %11110000
dc %01111111
dc %11110000
dc %01000000
;
dc %10100000
dc %01111000
dc %11111100
dc %11110011
dc %01110000
dc %11111100
dc %01100011
dc %10000000
dc %01010000
dc %11111000
dc %11111000
dc %01111110
dc %11110001
dc %01110000
dc %11001100
dc %00000010
dc %00010100
dc %01111100
dc %01111100
dc %11111100
dc %01110010
dc %11110001
dc %00001000
dc %00000100
dc %01101010
dc %10111110
dc %01111100
dc %11111100
dc %01110010
dc %00010010
dc %00010001
dc %00001000
dc %10110101
dc %01111110
dc %11111110
dc %01111100
dc %01100100
dc %00100100
dc %00010010
dc %00010010
dc %01011010
dc %11111111
dc %01111110
dc %01111110
dc %00100100
dc %00100100
dc %00100100
dc %00100100
#ENDIF
#if 0
GFX_THRUST_BLANK
dc %00000000
dc %00000000
dc %00000000
dc %00000000
dc %00000000
dc %00000000
dc %00000000
dc %00000000
#endif
;;; INCLUDE ..\ART\PLAYERSHIP\GFX_SHIP_EXPLOSION.ASM
GFX_SHIP_EXPLOSION
dc %00000000
dc %00000000
dc %00000000
dc %00011000
dc %00011000
dc %00000000
dc %00000000
dc %00000000
dc %00000000
dc %00000000
dc %00010100
dc %00010000
dc %00010000
dc %00000100
dc %00000000
dc %00000000
dc %00000000
dc %00010100
dc %00100000
dc %00010000
dc %00001000
dc %00100000
dc %00000000
dc %00000000
dc %00100010
dc %00000000
dc %00100000
dc %00000000
dc %00000000
dc %00001000
dc %01000000
dc %00000000
dc %00000000
dc %01000000
dc %00000100
dc %00001000
dc %00010000
dc %00000000
dc %00000100
dc %10000000
dc %00000000
dc %01000000
dc %00001010
dc %00000000
dc %00100000
dc %00000000
dc %00000000
dc %00000100
dc %10000000
dc %00000101
dc %00000000
dc %00000000
dc %01000000
dc %00000000
dc %00000000
dc %00000000
dc %00000100
dc %00000000
dc %00000000
dc %00000000
dc %10000000
dc %00000000
dc %00000000
dc %00000000
;;; INCLUDE ..\ART\CANNON\GFX_FUZZBALL.ASM
GFX_FUZZBALL
dc %00001000
dc %00001000
dc %01111110
dc %00011100
dc %00011000
dc %00101100
dc %01001010
dc %00000000
dc %00010010
dc %00010100
dc %00110100
dc %00011110
dc %11111111
dc %00011000
dc %00100100
dc %00000010
dc %00010000
dc %00010010
dc %01010100
dc %00101000
dc %00011100
dc %00101100
dc %01000010
dc %00000000
dc %01000010
dc %00101100
dc %00011111
dc %00111100
dc %11011010
dc %00011001
dc %00101000
dc %00000000
dc %00000100
dc %11001000
dc %00111000
dc %00011100
dc %00011011
dc %00101000
dc %00100100
dc %01000100
dc %10010000
dc %01010000
dc %00110000
dc %00011110
dc %00011100
dc %01101010
dc %00001001
dc %00001000
dc %00000100
dc %00101000
dc %11101000
dc %00110000
dc %00011100
dc %00101011
dc %00101000
dc %01000000
dc %00100000
dc %00101010
dc %00011100
dc %01111000
dc %00101110
dc %01001001
dc %00010000
dc %00000000
;;;
echo "---- Unused ROM at end of bank 1:",(($fFF8-(6*6+3))-*)d,"bytes"
; DRAWSHIELDS ROUTINE CALLS INTO BANK2
ORG $1FF8-(6*6+3)
RORG $fFF8-(6*6+3)
SCORE_SHIPS_SCREEN_ENTRY
LDA LED_LATCH_00 ; TURN OFF LEDS
LDA SWITCH_TO_HIGHBANK ; SWITCH TO BANK 2
JMP SCORE_SHIPS_SCREEN_DONE ; JUST SWITCHED FROM BANK2, RETURN TO PROGRAM
TITLESCREEN_ENTRY
LDA SWITCH_TO_HIGHBANK ; SWITCH TO BANK 2
JMP TITLESCREEN_DONE ; JUST SWITCHED FROM BANK2, RETURN TO PROGRAM
PACKSHIELDS1_ENTRY
LDA SWITCH_TO_HIGHBANK ; SWITCH TO BANK 2
JMP PACKSHIELDS1DONE ; JUST SWITCHED FROM BANK2, RETURN TO PROGRAM
PACKSHIELDS2_ENTRY
LDA SWITCH_TO_HIGHBANK ; SWITCH TO BANK 2
JMP PACKSHIELDS2DONE ; JUST SWITCHED FROM BANK2, RETURN TO PROGRAM
PACKSHIELDS3_ENTRY
LDA SWITCH_TO_HIGHBANK ; SWITCH TO BANK 2
JMP PACKSHIELDS3DONE ; JUST SWITCHED FROM BANK2, RETURN TO PROGRAM
DRAWSHIELDS_ENTRY
LDA SWITCH_TO_HIGHBANK ; SWITCH TO BANK 2
JMP DRAWSHIELDSDONE ; JUST SWITCHED FROM BANK2, RETURN TO PROGRAM
; VECTOR TABLE BANK0
ORG $1FF8
RORG $fFF8
SWITCH_TO_LOWBANK .BYTE 0 ; READING THIS BYTE SWITCHES TO LOW BANK
SWITCH_TO_HIGHBANK .BYTE 1 ; READING THIS BYTE SWITCHES TO HIGH BANK
ORG $1FFA
.WORD VECTOR_NMI ; NMI (6507 IN ATARI 2600 HAS NO NMI PIN)
.WORD VECTOR_RESET ; RESET
.WORD VECTOR_BREAK ; IRQ/BREAK (6507 IN ATARI 2600 HAS NO IRQ PIN)
;******************************************************************************
;
; BANK 2
;
;******************************************************************************
ORG $2000
RORG $f000
STARTBANK2
LDA $1FF8 ; SWITCH TO BANK 1
; REST OF CODE
;;; include DRAWSHIELDS4.ASM
;******************************************************************************
;
; DRAWSHIELDS 4
;
; FOURTH PROTOTYPE
; USING 60 BYTE BUFFER TO STORE SHIELD DATA FOR FAST KERNEL
; USING DRAW ROUTINE TO REDUCE CODE SIZE
; USING EVERY OTHER LINE SO SINGLE WIDTH MISSILE 0, 1, BALL CAN BE USED
; ALL SHIELD BITS WILL SHIFT SIMPLY TO ALLOW EASY HIT DETECTION AND KNOCKOUT
; USES WSYNC SO BANK CROSSING IMPACT SHOULD BE MINIMIZED
;
; ALL OF THE 4K BANK 2 IS NOW IN THIS SOURCE FILE
DEBUGNEWSHIELDLOCATIONS EQU 1
; VARS USED FOR DRAWSHIELDS (OVERLOAD PACK SHIELD VARS)
DS_SAVEX EQU DS_TEMP0
DS_LINE EQU DS_TEMP1
SHIELDSCANLINES EQU ((23+23)*2) ; SCAN LINES THE SHIELD TAKES UP
SHIELDSPACELINES EQU (DISPLAYSCANLINES-SHIELDSCANLINES)/2 ; SCAN LINES IN EACH BLANK SPACE ABOVE AND BELOW THE SHIELDS
;******************************************************************************
; GRAPHICS CAREFULLY ORGANIZED TO PREVENT THE CROSSING OF PAGE BOUNDARIES
GFX_48_0
#IF DEBUGSYNCENABLE==0
DC %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%00000000
#ENDIF
DC %00000000,%00000000,%00000000,%00000000,%00000000,%00000111,%00001100,%00011000
DC %00110000,%01110000,%01100000,%11100000,%11100000,%11100000,%01100000,%01100000
DC %00110000,%00011000,%00001100,%00000111,%01110010,%01001010,%01110001,%01001000
DC %01110011,%00000000,%01000101,%01000100,%01010100,%01101100,%01000101
GFX_GAMEOVER0
DC %11111011,%10001010,%11111011,%00001010,%11111010
GFX_48_1
DC %00000000,%00000011,%00000110,%00001100,%00001100,%00001110,%00001111,%00000111
DC %00000011,%00000000,%00000000,%00001000,%00001100,%10100110,%01010111,%00110010
DC %00001000,%00001000,%00000001,%00000000,%00000000,%00000001,%00000001,%00000011
DC %00001010,%00010110,%01101110,%11000000,%01000000,%01000000,%10000000,%10000000
DC %00000000,%00000000,%11010001,%10010001,%10010001,%10010001,%11011101
GFX_GAMEOVER1
DC %11101110,%00101001,%11101001,%00101001,%00101001
GFX_48_2
DC %11100100,%10111100,%00000110,%00000010,%00000001,%00000010,%10000011,%11100110
DC %11111100,%01111100,%00001110,%00000110,%00000110,%00000110,%10001101,%11111000
DC %00000000,%00000000,%10000111,%11001100,%11001100,%01101110,%01100011,%11100000
DC %00101000,%00101100,%11110111,%00000000,%00111000,%00100100,%00100100,%00100100
DC %00111001,%00000000,%00011100,%00001001,%00001001,%00001001,%11011101
GFX_GAMEOVER2
DC %11001111,%00101001,%00101110,%00101000,%00101110
GFX_48_3
DC %00000000,%00000000,%00000000,%00000000,%00000000,%00000100,%11111101,%01100110
DC %01100000,%01100001,%01100001,%01100011,%01100010,%01100110,%11111111,%00000000
DC %00000000,%00100000,%10111111,%11100110,%01000110,%00000110,%11000110,%11100110
DC %01100110,%11100110,%11011111,%00000000,%00001100,%00010001,%00001001,%00000101
DC %00011000,%00000000,%11001000,%00101101,%00101010,%11101000,%00101000
GFX_GAMEOVER3
DC %00011111,%00010001,%00010001,%00010001,%00011111
GFX_48_4
DC %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%10000111,%11000011
DC %11000011,%01100011,%01100011,%11100011,%00110011,%00110011,%01111111,%00000000
DC %00000000,%01000000,%11011100,%01101000,%00011000,%00011000,%00011000,%00011000
DC %00011001,%00011001,%10111111,%00000000,%11001100,%00010010,%00010010,%00010010
DC %11001100,%00000000,%10011001,%10100010,%10010010,%10001010,%10110001
GFX_GAMEOVER4
DC %01000101,%01000101,%00101001,%00101001,%00010001
; 10 COLORS THE SHIELDS WILL USE FROM YELLOW THROUGH ORANGE TO RED AS SHIELDS ARE DESTROYED
SHIELDCOLORS
#IF PAL != 0
DC $68 ; RED
DC $6A
DC $6C
DC $4A
DC $4C
DC $4E
DC $28
DC $2A ; YELLOW
DC $2C ; YELLOW
; THIS COLOR VISIBLE UNTIL 1 SHIELD IS HIT
DC $2E ; YELLOW
#ELSE
DC $48 ; RED
DC $4A
DC $4C
DC $3A
DC $3C
DC $2C ; ORANGE
DC $2E ; ORANGE
DC $FC ; YELLOW
DC $FE ; YELLOW
; THIS COLOR VISIBLE UNTIL 1 SHIELD IS HIT
DC $1E ; YELLOW
#ENDIF
GFX_SHIPS_LEFT0
DC %11101010
DC %10001010
DC %11101110
DC %00101010
DC %11101010
GFX_SHIPS_LEFT1
DC %01001110
DC %01001010
DC %01001110
DC %01001000
DC %01001000
GFX_SHIPS_LEFT2
DC %11100100
DC %10000100
DC %11100100
DC %00100100
DC %11100111
GFX_SHIPS_LEFT3
DC %01110111
DC %01010100
DC %01110110
DC %01000100
DC %01110100
GFX_SHIPS_LEFT4
DC %01110000
DC %00100000
DC %00100000
DC %00100000
DC %00100000
;GFX_SHIPS_LEFT5
; DC %00000000
; DC %00000000
; DC %00000000
; DC %00000000
; DC %00000000
DIGITS0 dc %11101110,%01000100,%11101110,%11101110,%00100010,%11101110,%11101110,%11101110,%11101110,%11101110
DIGITS1 dc %10101010,%01000100,%00100010,%00100010,%01100110,%10001000,%10001000,%00100010,%10101010,%10101010
DIGITS2 dc %10101010,%01000100,%11101110,%01000100,%10101010,%11101110,%11101110,%01000100,%11101110,%11101110
DIGITS3 dc %10101010,%01000100,%10001000,%00100010,%11101110,%00100010,%10101010,%01000100,%10101010,%00100010
DIGITS4 dc %11101110,%01000100,%11101110,%11101110,%00100010,%11101110,%11101110,%10001000,%11101110,%11101110
GFX_48_5
DC %00000000,%00000000,%00000000,%00000000,%00000000,%00000000,%11100000,%00110000
DC %00011000,%00111000,%11110000,%01100000,%00110000,%00011000,%10011100,%00000000
DC %00000000,%00000010,%11111111,%01100001,%01100000,%01100100,%01111100,%01100100
DC %01100000,%01100001,%11111111,%00000010,%11101110,%01000100,%01000100,%01000100
DC %01000100,%00000000,%10010010,%01011010,%01011110,%01010110,%10010010
GFX_GAMEOVER5
DC %11101011,%00101100,%11001000,%00001000,%11001000
;******************************************************************************
; 765432107654321076543210
;00 3210 32*4 = 128 BITS TRY 120 OR 132 10 OR 11
;01 7654
;02 10
;03 32
;04 54
;05 6
;06 7
;07 0 210 22*4 = 88 BITS TRY 84 OR 96 7 OR 8
;08 1 543
;19 2 76
;10 3 10
;11 4 2
;12 5 3
;13 6 4
;14 7 5
;15 7 6 210 11*4 = LSR BITS TRY 36 OR 48 3 OR 4 BITS / SHIELD
;16 6 7 43
;17 5 0 5
;18 4 1 6
;19 3 2 7
;20 2 3 0
;21 1 4 1
;22 0 5 2
; 765432107654321076543210
;******************************************************************************
;
; PACK THE SHIELD DATA FOR RENDERING
;
; 765432107654321076543210 BYTE OFS 765432107654321076543210 BYTE OFFSET
;00 AAaaaaaaaaaaaaaaaaaaaaa 2 x x 00aaaaaaaaaaaaaaaaaaaaaAA X X 45
;00 BBbbb bbbbbbbbbbbbbbbb 5 4 x 00bbbbbbbbbbbbbbbb bbbBB X 47 46
;00 CC cccc 00055555555 8 7 6 0055555555000 cccc CC 50 49 48
;00 DD11111dd22222266666666 11 10 9 0066666666222222dd11111DD 53 52 51
;00 3333333 444444477777777 14 13 12 00777777774444444 3333333 62 55 54
;00 aaaa 00aaaa
;01 aaaa 01 aaaa
;02 aa 02 aa
;03 aa 03 aa
;04 aa 04 aa
;05 a 05 a
;06 a 06 a
;07 a bbb 07bbb a
;08 a bbb 08 bbb a
;19 a bb 19 bb a
;10 b bb 10 bb b
;11 a b 11 b a
;12 b b 12 b b
;13 a b 13 b a
;14 b c 14 c b
;15 A b 000 15000 b A
;16 B c 11111 1611111 c B
;17 C b 222222 17222222 b C
;18 D c 3333333 183333333 c D
;19 A d 4444444 194444444 d A
;20 B b 55555555 2055555555 b B
;21 C c 66666666 2166666666 c C
;22 D d 77777777 2277777777 d D
; 765432107654321076543210 701345670123456701234567
; 765432107654321076543210 BYTE OFS 765432107654321076543210 BYTE OFS
;00 3333333 444444477777777 17 16 15 00777777774444444 3333333 32 31 30
;00 DD11111dd22222266666666 20 19 18 0066666666222222dd11111DD 35 34 33
;00 CC cccc 00055555555 23 22 21 0055555555000 cccc CC 38 37 36
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24 00bbbbbbbbbbbbbbbb bbbBB 41 40 39
;00 AAaaaaaaaaaaaaaaaaaaaaa 29 28 27 00aaaaaaaaaaaaaaaaaaaaaAA 44 43 42
;22 D d 77777777 22 7777777 d D
;21 C c 66666666 21 6666666 c C
;20 B b 55555555 20 5555555 b B
;19 A d 4444444 19 444444 d A
;18 D c 3333333 18 333333 c D
;17 C b 222222 17 22222 b C
;16 B c 11111 16 1111 c B
;15 A b 000 15 00 b A
;14 b c 14 c b
;13 a b 13 b a
;12 b b 12 b b
;11 a b 11 b a
;10 b bb 10 bb b
;19 a bb 19 bb a
;08 a bbb 08 bbb a
;07 a bbb 07 bb a
;06 a 06 a
;05 a 05 a
;04 aa 04 aa
;03 aa 03 aa
;02 aa 02 aa
;01 aaaa 01 aaaa
;00 aaaa 00 aaa
; 765432107654321076543210 70134567012345670123456
;******************************************************************************
; FILLASHIELDBYTE
; FILLS A SHIELD BYTE BASED ON STATE OF SHIELDS
; SHIELD BITS ON OR OFF, ANGLE
#IF 1
FILLASHIELDBYTEOUTER SUBROUTINE
LDX #0 ; X IS THE STARTING BIT POSITION WHICH IS ALWAYS ZERO ON ENTRY TO FILL BYTE
STX DS_TEMP0 ; CLEAR BITS IN DESTINATION BYTE
LDY DS_ENDBIT ; Y IS THE END BIT
.NEXT
; IS THIS SEGMENT ON?
LDA #1
BIT DS_SHIELDBITSLOW
BEQ .SHIELDSEGMENTOFF
.SHIELDSEGMENTON
; SHIELD SEGMENT IS ON
LDA FILLBITS,X
CPY #8
BPL .FILLEDTOEND
; PARTIALLY FILLED, MUST TRIM BITS OFF THE END AND LOOP
EOR FILLBITS,Y
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
; NOT FILLED TO THE END, ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #OSHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
ADC #OSHIELDBITSIZE
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.SHIELDSEGMENTOFF
; SHIELD SEGMENT IS OFF
CPY #8
BPL .EMPTYTOEND
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #OSHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
TAX
ADC #OSHIELDBITSIZE
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.FILLEDTOEND
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
.EMPTYTOEND
; SUBTRACT 8 FROM END CURSOR FOR NEXT SHIELD
TYA
SEC
SBC #8
BNE .NOTEXACTEND
TAY
; BITS FILLED TO EXACT END OF BYTE, CUE UP NEXT BYTE
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #OSHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
TAX
ADC #OSHIELDBITSIZE
.NOTEXACTEND
STA DS_ENDBIT ; SAVE END BIT POSITION FOR NEXT TIME THROUGH
LDA DS_TEMP0
RTS
FILLASHIELDBYTEMIDDLE SUBROUTINE
LDX #0 ; X IS THE STARTING BIT POSITION WHICH IS ALWAYS ZERO ON ENTRY TO FILL BYTE
STX DS_TEMP0 ; CLEAR BITS IN DESTINATION BYTE
LDY DS_ENDBIT ; Y IS THE END BIT
.NEXT
; IS THIS SEGMENT ON?
LDA #1
BIT DS_SHIELDBITSLOW
BEQ .SHIELDSEGMENTOFF
.SHIELDSEGMENTON
; SHIELD SEGMENT IS ON
LDA FILLBITS,X
CPY #8
BPL .FILLEDTOEND
; PARTIALLY FILLED, MUST TRIM BITS OFF THE END AND LOOP
EOR FILLBITS,Y
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
; NOT FILLED TO THE END, ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #MSHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
ADC #MSHIELDBITSIZE
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.SHIELDSEGMENTOFF
; SHIELD SEGMENT IS OFF
CPY #8
BPL .EMPTYTOEND
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #MSHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
TAX
ADC #MSHIELDBITSIZE
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.FILLEDTOEND
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
.EMPTYTOEND
; SUBTRACT 8 FROM END CURSOR FOR NEXT SHIELD
TYA
SEC
SBC #8
BNE .NOTEXACTEND
TAY
; BITS FILLED TO EXACT END OF BYTE, CUE UP NEXT BYTE
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #MSHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
TAX
ADC #MSHIELDBITSIZE
.NOTEXACTEND
STA DS_ENDBIT ; SAVE END BIT POSITION FOR NEXT TIME THROUGH
LDA DS_TEMP0
RTS
FILLASHIELDBYTEINNER SUBROUTINE
LDX #0 ; X IS THE STARTING BIT POSITION WHICH IS ALWAYS ZERO ON ENTRY TO FILL BYTE
STX DS_TEMP0 ; CLEAR BITS IN DESTINATION BYTE
LDY DS_ENDBIT ; Y IS THE END BIT
.NEXT
; IS THIS SEGMENT ON?
LDA #1
BIT DS_SHIELDBITSLOW
BEQ .SHIELDSEGMENTOFF
.SHIELDSEGMENTON
; SHIELD SEGMENT IS ON
LDA FILLBITS,X
CPY #8
BPL .FILLEDTOEND
; PARTIALLY FILLED, MUST TRIM BITS OFF THE END AND LOOP
EOR FILLBITS,Y
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
; NOT FILLED TO THE END, ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #ISHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
ADC #ISHIELDBITSIZE
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.SHIELDSEGMENTOFF
; SHIELD SEGMENT IS OFF
CPY #8
BPL .EMPTYTOEND
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #ISHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
TAX
ADC #ISHIELDBITSIZE
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.FILLEDTOEND
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
.EMPTYTOEND
; SUBTRACT 8 FROM END CURSOR FOR NEXT SHIELD
TYA
SEC
SBC #8
BNE .NOTEXACTEND
TAY
; BITS FILLED TO EXACT END OF BYTE, CUE UP NEXT BYTE
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC #ISHIELDBITSIZEFRAC
STA DS_ENDBITLOW
TYA
TAX
ADC #ISHIELDBITSIZE
.NOTEXACTEND
STA DS_ENDBIT ; SAVE END BIT POSITION FOR NEXT TIME THROUGH
LDA DS_TEMP0
RTS
#ELSE
FILLASHIELDBYTE SUBROUTINE
LDX #0 ; X IS THE STARTING BIT POSITION WHICH IS ALWAYS ZERO ON ENTRY TO FILL BYTE
STX DS_TEMP0 ; CLEAR BITS IN DESTINATION BYTE
LDY DS_ENDBIT ; Y IS THE END BIT
.NEXT
; IS THIS SEGMENT ON?
LDA #1
BIT DS_SHIELDBITSLOW
BEQ .SHIELDSEGMENTOFF
.SHIELDSEGMENTON
; SHIELD SEGMENT IS ON
LDA FILLBITS,X
CPY #8
BPL .FILLEDTOEND
; PARTIALLY FILLED, MUST TRIM BITS OFF THE END AND LOOP
EOR FILLBITS,Y
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
; NOT FILLED TO THE END, ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC DS_DELTALOW
STA DS_ENDBITLOW
TYA
ADC DS_DELTAHIGH
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.SHIELDSEGMENTOFF
; SHIELD SEGMENT IS OFF
CPY #8
BPL .EMPTYTOEND
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC DS_DELTALOW
STA DS_ENDBITLOW
TYA
TAX
ADC DS_DELTAHIGH
TAY
BNE .NEXT ; VERY LIKELY
BEQ .NEXT ; CATCH ALL
.FILLEDTOEND
; MERGE INTO DESTINATION REGISTER
ORA DS_TEMP0
STA DS_TEMP0
.EMPTYTOEND
; SUBTRACT 8 FROM END CURSOR FOR NEXT SHIELD
TYA
SEC
SBC #8
BNE .NOTEXACTEND
TAY
; BITS FILLED TO EXACT END OF BYTE, CUE UP NEXT BYTE
; ROTATE NEXT BIT INTO PLACE
LSR DS_SHIELDBITSHIGH
ROR DS_SHIELDBITSLOW
; ADVANCE END CURSOR TO NEXT SHIELD LOCATION
CLC
LDA DS_ENDBITLOW
ADC DS_DELTALOW
STA DS_ENDBITLOW
TYA
TAX
ADC DS_DELTAHIGH
.NOTEXACTEND
STA DS_ENDBIT ; SAVE END BIT POSITION FOR NEXT TIME THROUGH
LDA DS_TEMP0
RTS
#ENDIF
FILLBITS
DC.B %11111111
DC.B %11111110
DC.B %11111100
DC.B %11111000
DC.B %11110000
DC.B %11100000
DC.B %11000000
DC.B %10000000
DC.B %00000000
;******************************************************************************
;
; PACK BITS INTO RAM FOR RENDERING THE SHIELDS
;
PACKSHIELDS1 SUBROUTINE
LDA FLAGS0
AND #F0_CANNONDYING
BEQ .CANNONNOTDYING
JMP PACKSHIELDS1_RETURN
.CANNONNOTDYING
; JMP SHIELDSLOADED
; DSW NEEDS UBER OPTIMIZATION:
; MULTIPLE WRITES TO SAME LOCATIONS FOR PACKING
; SHIFTING IN AND OUT
;
; PACK THE SHIELD DATA INTO A BUFFER FOR DRAWING
; CAN NOT BE A SUBROUTINE BECAUSE IT NEEDS ALL THE MEMORY
; BESIDES, THE 2600 DOES NOT NEED MORE JSR/RTS'S IN ROM/CYCLES
; CLEAR LOCATIONS THAT WILL HAVE SHIP OR'ED INTO THEM
; 765432107654321076543210 BYTE OFFSET
;00 AAaaaaaaaaaaaaaaaaaaaaa 2 x x
;00 BBbbb bbbbbbbbbbbbbbbb 5 4 x
;00 CC cccc 00055555555 8 7 6
;00 DD11111dd22222266666666 11 10 9
;00 3333333 444444477777777 14 13 12
; LOWER LEFT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15
;00 DD11111dd22222266666666 20 19 18
;00 CC cccc 00055555555 23 22 21
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24
;00 AAaaaaaaaaaaaaaaaaaaaaa 29 28 27
; LOWER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00777777774444444 3333333 32 31 30
;0066666666222222dd11111DD 35 34 33
;0055555555000 cccc CC 38 37 36
;00bbbbbbbbbbbbbbbb bbbBB 41 40 39
;00aaaaaaaaaaaaaaaaaaaaaAA 44 43 42
; UPPER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00aaaaaaaaaaaaaaaaaaaaaAA X X 45
;00bbbbbbbbbbbbbbbb bbbBB X 47 46
;0055555555000 cccc CC 50 49 48
;0066666666222222dd11111DD 53 52 51
;00777777774444444 3333333 62 55 54
LDA #0
; CLEAR ENTIRE BITMAP AREA
STA DS_BASE_07
STA DS_BASE_11
STA DS_BASE_10
; STA DS_BASE_14 ; STORED DIRECTLY BELOW
; STA DS_BASE_13 ; STORED DIRECTLY BELOW
STA DS_BASE_06
STA DS_BASE_09
STA DS_BASE_12
STA DS_BASE_15
STA DS_BASE_18
STA DS_BASE_21
STA DS_BASE_16
STA DS_BASE_17
STA DS_BASE_19
STA DS_BASE_20
STA DS_BASE_22
STA DS_BASE_49
STA DS_BASE_51
STA DS_BASE_52
; STA DS_BASE_54 ; STORED DIRECTLY BELOW
; STA DS_BASE_55 ; STORED DIRECTLY BELOW
; STA DS_BASE_50 ; STORED DIRECTLY BELOW
; STA DS_BASE_53 ; STORED DIRECTLY BELOW
; STA DS_BASE_56 ; STORED DIRECTLY BELOW
; STA DS_BASE_32 ; STORED DIRECTLY BELOW
; STA DS_BASE_35 ; STORED DIRECTLY BELOW
; STA DS_BASE_38 ; STORED DIRECTLY BELOW
; STA DS_BASE_31 ; STORED DIRECTLY BELOW
; STA DS_BASE_30 ; STORED DIRECTLY BELOW
STA DS_BASE_34
STA DS_BASE_33
STA DS_BASE_37
; SETUP OUTER SHIELDS
; LDA #OSHIELDBITSIZEFRAC
; STA DS_DELTALOW
; LDA #OSHIELDBITSIZE
; STA DS_DELTAHIGH
; LDA #0
STA DS_ENDBITLOW
LDA OSHIELDANGLE
STA DS_ENDBIT
LDA OSHIELDBITSH
STA DS_SHIELDBITSHIGH
LDA OSHIELDBITSL
STA DS_SHIELDBITSLOW
; OUTER RING
; UPPER LEFT QUADRANT
JSR FILLASHIELDBYTEOUTER
;FREE LDA SHIELDSO
STA DS_BASE_00
JSR FILLASHIELDBYTEOUTER
;FREE LDA SHIELDSO+1
STA DS_BASE_01
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+2
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_05
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_05
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_05
; 0,1,2, 5 DONE
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+3
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_05
LSR
ROR DS_BASE_08
LSR
ROR DS_BASE_11
LSR
ROR DS_BASE_02
LSR
ROR DS_BASE_05
LSR
ROR DS_BASE_08
LSR
ROR DS_BASE_11
LSR DS_BASE_02
LSR DS_BASE_05
LSR DS_BASE_08
LSR DS_BASE_11
; BOTTOM RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15
;00 DD11111dd22222266666666 20 19 18
;00 CC cccc 00055555555 23 22 21
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24
;00 AAaaaaaAaaaaaaaaaaaaaaa 29 28 27
;22 D04 d 77777777
;21 C1 c 66666666
;20 B2 b 55555555
;19 A3 d 4444444
;18 D4 c 3333333
;17 C5 b 222222
;16 B6 c 11111
;15 A7 b 000
;14 b05 c
;13 a1 b
;12 b2 b
;11 a3 b
;10 b4 bb
;19 a5 bb
;08 a6 bbb
;07 a7 bbb
;06 A06
;05 a
;04 aa
;03 aa
;02 aa07
;01 aaaa
;00 aaaa
; 765432107654321076543210
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+4
LSR
ROL DS_BASE_20
LSR
ROL DS_BASE_23
LSR
ROL DS_BASE_26
LSR
ROL DS_BASE_29
LSR
ROL DS_BASE_20
LSR
ROL DS_BASE_23
LSR
ROL DS_BASE_26
LSR
ROL DS_BASE_29
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+5
ROR
ROL DS_BASE_26
ROR
ROL DS_BASE_29
ROR
ROL DS_BASE_26
ROR
ROL DS_BASE_29
ROR
ROL DS_BASE_26
ROR
ROL DS_BASE_29
ROR
ROL DS_BASE_29
ROR
ROL DS_BASE_29
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+6
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
ROR
ROL DS_BASE_28
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+7
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
ROR
ROL DS_BASE_27
; ASL DS_BASE_20
; ASL DS_BASE_20
; ASL DS_BASE_20
; ASL DS_BASE_20
; ASL DS_BASE_20
LDA DS_BASE_20
CLC
ROR
ROR
ROR
ROR
STA DS_BASE_20
; ASL DS_BASE_23
; ASL DS_BASE_23
; ASL DS_BASE_23
; ASL DS_BASE_23
; ASL DS_BASE_23
LDA DS_BASE_23
ROR
ROR
ROR
ROR
STA DS_BASE_23
ASL DS_BASE_26
ASL DS_BASE_26
; 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15
;00 ..11111dd22222266666666 20 19 18
;00 .. cccc 00055555555 23 22 21
;00 ..... bbbbbbbbbbbbbbbb 26 25 24
;00 ....................... 29 28 27
; LOWER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00 777777774444444 3333333 32 31 30
;00 66666666222222dd11111DD 35 34 33
;00 55555555000 cccc CC 38 37 36
;00 bbbbbbbbbbbbbbbb bbbBB 41 40 39
;00 aaaaaaaaaaaaaaaaaaaaaAA 44 43 42
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+8
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
ASL
ROR DS_BASE_44
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+9
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
ASL
ROR DS_BASE_43
JSR FILLASHIELDBYTEOUTER
STA DS_TEMP1
JSR FILLASHIELDBYTEOUTER
; LDA SHIELDSO+11
ASL
ROR DS_BASE_33
ASL
ROR DS_BASE_36
ASL
ROR DS_BASE_39
ASL
ROR DS_BASE_42
ASL
ROL DS_BASE_33 ;5
ROL DS_BASE_33 ;5
ASL DS_BASE_33 ;5
ASL
ROL DS_BASE_36 ;5
ROL DS_BASE_36 ;5
ASL DS_BASE_36 ;5
ASL
ROR DS_BASE_39
ASL
ROR DS_BASE_42
LDA DS_TEMP1
; LDA SHIELDSO+10
ASL
ROR DS_BASE_39
ASL
ROR DS_BASE_42
ASL
ROR DS_BASE_39
ASL
ROR DS_BASE_42
ASL
ROR DS_BASE_39
ASL
ROR DS_BASE_42
ASL
ROR DS_BASE_42
ASL
ROR DS_BASE_42
LSR DS_BASE_39
LSR DS_BASE_39
; UPPER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00aaaaaaaaaaaaaaaaaaaaaAA 57 58 45
;00bbbbbbbbbbbbbbbb bbbBB 59 47 46
;0055555555000 cccc CC 50 49 48
;0066666666222222dd11111DD 53 52 51
;00777777774444444 3333333 56 55 54
JSR FILLASHIELDBYTEOUTER
STA DS_TEMP1
JSR FILLASHIELDBYTEOUTER
#IF DEBUGNEWSHIELDLOCATIONS!=0
STA DS_TEMP0
JMP PACKSHIELDS1_RETURN ; RETURN WITH BANKSWITCH JUMP
PACKSHIELDS2 SUBROUTINE
LDA FLAGS0
AND #F0_CANNONDYING
BEQ .CANNONNOTDYING
JMP PACKSHIELDS2_RETURN
.CANNONNOTDYING
LDA DS_TEMP0
#ENDIF
; LDA SHIELDSO+13
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_46
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_46
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_46
LDA DS_TEMP1
; LDA SHIELDSO+12
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_46
ASL
ROL DS_BASE_48
ASL
ROL DS_BASE_51
ASL
ROL DS_BASE_45
ASL
ROL DS_BASE_46
ASL
ROL DS_BASE_48
ASL
ROL DS_BASE_51
ASL DS_BASE_45
ASL DS_BASE_46
ASL DS_BASE_48
ASL DS_BASE_51
JSR FILLASHIELDBYTEOUTER
STA DS_BASE_58
JSR FILLASHIELDBYTEOUTER
STA DS_BASE_57
#IF DEBUGNEWSHIELDLOCATIONS==0
JMP PACKSHIELDS1_RETURN ; RETURN WITH BANKSWITCH JUMP
PACKSHIELDS2 SUBROUTINE
#ENDIF
; 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15
;00 DD11111dd22222266666666 20 19 18
;00 CC cccc 00055555555 23 22 21
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24
;00 AAaaaaaAaaaaaaaaaaaaaaa 29 28 27
;00 aaaa
;01 aaaa
;02 aa07
;03 aa
;04 aa
;05 a
;06 A06
;07 a7 bbb
;08 a6 bbb
;19 a5 bb
;10 b4 bb
;11 a3 b
;12 b2 b
;13 a1 b
;14 b05 c
;15 A7 b 000
;16 B6 c 11111
;17 C5 b 222222
;18 D4 c 3333333
;19 A3 d 4444444
;22 D04 d 77777777
;21 C1 c 66666666
;20 B2 b 55555555
; 765432107654321076543210
; MIDDLE RING
; 765432107654321076543210 BYTE OFFSET
;00 ....................... 2 1 0
;00 ..... bbbbbbbbbbbbbbbb 5 4 3
;00 .. cccc 00055555555 8 7 6
;00 ..11111dd22222266666666 11 10 9
;00 3333333 444444477777777 14 13 12
; SETUP MIDDLE SHIELDS
; LDA #MSHIELDBITSIZEFRAC
; STA DS_DELTALOW
; LDA #MSHIELDBITSIZE
; STA DS_DELTAHIGH
LDA #0
STA DS_ENDBITLOW
LDA MSHIELDANGLE
STA DS_ENDBIT
LDA MSHIELDBITSH
STA DS_SHIELDBITSHIGH
LDA MSHIELDBITSL
STA DS_SHIELDBITSLOW
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM
STA DS_BASE_03
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+1
; LSR
; ROR DS_BASE_04
; LSR
; ROR DS_BASE_04
; LSR
; ROR DS_BASE_04
; LSR
; ROR DS_BASE_04
; LSR
; ROR DS_BASE_04
; LSR
ROL
ROL
ROL
TAX
AND #%11111000
STA DS_BASE_04
TXA
ROR DS_BASE_07
LSR
ROR DS_BASE_04
LSR
ROR DS_BASE_07
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+2
LSR
ROR DS_BASE_04
LSR
ROR DS_BASE_07
LSR
ROR DS_BASE_10
LSR
ROR DS_BASE_04
LSR
ROR DS_BASE_07
LSR
ROR DS_BASE_10
; LOWER LEFT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15
;00 DD11111dd22222266666666 20 19 18
;00 CC cccc 00055555555 23 22 21
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24
;00 AAaaaaaaaaaaaaaaaaaaaaa 29 28 27
LSR
ROL DS_BASE_19
LSR
ROL DS_BASE_22
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+3
LSR
ROL DS_BASE_25
LSR
; ROL DS_BASE_19
ROR DS_BASE_19
ROR DS_BASE_19
LSR
ROL DS_BASE_22
LSR
ROL DS_BASE_25
LSR
ROL DS_BASE_22
LSR
ROL DS_BASE_25
LSR
ROL DS_BASE_22
LSR
ROL DS_BASE_25
LDA DS_BASE_22 ; 3
ASL ; 2
ASL ; 2
ASL ; 2
ASL ; 2
STA DS_BASE_22 ; 3
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+4
LSR
ROL DS_BASE_25
LSR
ROL DS_BASE_25
LSR
ROL DS_BASE_25
LSR
ROL DS_BASE_25
LSR
ROL DS_BASE_24
LSR
ROL DS_BASE_24
LSR
ROL DS_BASE_24
LSR
ROL DS_BASE_24
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+5
LSR
ROL DS_BASE_24
LSR
ROL DS_BASE_24
LSR
ROL DS_BASE_24
LSR
ROL DS_BASE_24
; ASL DS_BASE_19
; ASL DS_BASE_19
; ASL DS_BASE_19
; ASL DS_BASE_19
; ASL DS_BASE_19
; ASL DS_BASE_19
; ASL DS_BASE_22
; ASL DS_BASE_22
; ASL DS_BASE_22
; ASL DS_BASE_22
; LOWER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00777777774444444 3333333 32 31 30
;0066666666222222dd11111DD 35 34 33
;0055555555000 cccc CC 38 37 36
;00bbbbbbbbbbbbbbbb bbbBB 41 40 39
;00aaaaaaaaaaaaaaaaaaaaaAA 44 43 42
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_41
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+6
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_41
LSR
ROL DS_BASE_40
LSR
ROL DS_BASE_40
LSR
ROL DS_BASE_40
LSR
ROL DS_BASE_40
JSR FILLASHIELDBYTEMIDDLE
#IF DEBUGNEWSHIELDLOCATIONS!=0
; THIS SEEMS TO BE AS FAR AS WE CAN BACK THIS UP
STA DS_TEMP1
; SET SHIELD COLORS BASED ON NUMBER OF SHIELD BITS ON
LDA SHIELDBITSON
LSR
LSR
TAX
LDA SHIELDCOLORS,X
STA COLUP0
STA COLUP1
STA COLUPF
JMP PACKSHIELDS2_RETURN ; RETURN WITH BANKSWITCH JUMP
CANNONDYING SUBROUTINE
LDA VBLS
AND #$07
STA COLUBK
LDA VBLS
STA COLUP0
EOR #$FF
EOR CANNONDIR
EOR SHIPDIR
EOR SHIPX+1
EOR SHIPY+1
STA COLUP1
TAY
STA SPARK0X ; USE SPARK0X Y AS IND REGISTER FOR EXPLOSION
AND #$70
ADC #$40
STA SPARK0X+1
; TYA
; ASL
; ORA #$08
; STA COLUP0
; EOR #$07
; STA COLUP1
LDX #DS_BASE+1
.KILLBASE
LDA (SPARK0X),Y
STA 0,X
INY
INX
BNE .KILLBASE
JMP PACKSHIELDS3_RETURN
PACKSHIELDS3 SUBROUTINE
LDA FLAGS0
AND #F0_CANNONDYING
BNE CANNONDYING ;EQ .CANNONNOTDYING
; JMP PACKSHIELDS3_RETURN
.CANNONNOTDYING
LDA DS_TEMP1
#ENDIF
; LDA SHIELDSM+7
LSR
ROL DS_BASE_40
LSR
ROL DS_BASE_37
LSR
ROL DS_BASE_40
LSR
ROL DS_BASE_37
LSR
ROL DS_BASE_40
LSR
ROL DS_BASE_37
LSR
ROL DS_BASE_34
LSR
ROL DS_BASE_40
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+8
LSR
ROL DS_BASE_37
LSR
ROL DS_BASE_34
; UPPER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00aaaaaaaaaaaaaaaaaaaaaAA X X 45
;00bbbbbbbbbbbbbbbb bbbBB X 47 46
;0055555555000 cccc CC 50 49 48
;0066666666222222dd11111DD 53 52 51
;00777777774444444 3333333 62 55 54
LSR
ROR DS_BASE_52
LSR
ROR DS_BASE_49
LSR
ROR DS_BASE_47
LSR
; ROR DS_BASE_52
ROL DS_BASE_52
ROL DS_BASE_52
LSR
ROR DS_BASE_49
LSR
ROR DS_BASE_47
JSR FILLASHIELDBYTEMIDDLE
; LDA SHIELDSM+9
LSR
ROR DS_BASE_49
LSR
ROR DS_BASE_47
LSR
ROR DS_BASE_49
LSR
ROR DS_BASE_47
LSR
ROR DS_BASE_47
LSR
ROR DS_BASE_47
LSR
ROR DS_BASE_47
LSR
ROR DS_BASE_47
; LSR DS_BASE_49 ;5
; LSR DS_BASE_49 ;5
; LSR DS_BASE_49 ;5
; LSR DS_BASE_49 ;5
LDA DS_BASE_49 ; 3
LSR ; 2
LSR ; 2
LSR ; 2
LSR ; 2
STA DS_BASE_49 ; 3
; LSR DS_BASE_52
; LSR DS_BASE_52
; LSR DS_BASE_52
; LSR DS_BASE_52
; LSR DS_BASE_52
; LSR DS_BASE_52
#IF DEBUGNEWSHIELDLOCATIONS==0
; STA DS_TEMP1
JMP PACKSHIELDS2_RETURN ; RETURN WITH BANKSWITCH JUMP
PACKSHIELDS3 SUBROUTINE
; LDA DS_TEMP1
#ENDIF
JSR FILLASHIELDBYTEMIDDLE
STA DS_BASE_59
PACK_INNER_SHIELDS
; 765432107654321076543210 BYTE OFFSET
;00 ....................... 2 1 0
;00 ..... ................ 5 4 3
;00 .. .... 00055555555 8 7 6
;00 ..11111..22222266666666 11 10 9
;00 3333333 444444477777777 14 13 12
; LDA #ISHIELDBITSIZEFRAC
; STA DS_DELTALOW
; LDA #ISHIELDBITSIZE
; STA DS_DELTAHIGH
LDA #0
STA DS_ENDBITLOW
LDA ISHIELDANGLE
STA DS_ENDBIT
LDA ISHIELDBITSH
STA DS_SHIELDBITSHIGH
LDA ISHIELDBITSL
STA DS_SHIELDBITSLOW
JSR FILLASHIELDBYTEINNER
; LDA SHIELDSI
TAX
AND #%00000111
ORA DS_BASE_07
STA DS_BASE_07
TXA
AND #%00011000
ORA DS_BASE_11
STA DS_BASE_11
TXA
AND #%00100000
ORA DS_BASE_10
STA DS_BASE_10
TXA
AND #%01000000
STA DS_BASE_14
TXA
LSR
AND #%01000000
STA DS_BASE_13
JSR FILLASHIELDBYTEINNER
; LDA SHIELDSI+1
LSR
ROR DS_BASE_06
LSR
ROR DS_BASE_09
LSR
ROR DS_BASE_12
; LOWER LEFT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15
;00 DD11111dd22222266666666 20 19 18
;00 CC cccc 00055555555 23 22 21
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24
;00 AAaaaaaaaaaaaaaaaaaaaaa 29 28 27
LSR
ROR DS_BASE_15
LSR
ROR DS_BASE_18
LSR
ROR DS_BASE_21
LSR
ROR DS_BASE_16
LSR DS_BASE_16
LSR
ROR DS_BASE_17
LSR DS_BASE_17
; BIT 0 TO BIT 5 76543210 -> ..0.....
JSR FILLASHIELDBYTEINNER
; LDA SHIELDSI+2 ; 76543210 _
ROR ; _7654321 0
TAY ;Y=_7654321
ROR ; 0_765432 1
ROR ; 10_76543 2
ROR ; 210_7654 3
TAX ;X=210_7654
AND #%00100000
ORA DS_BASE_19
STA DS_BASE_19
; TRANSPOSE BITS 1 AND 2 INTO BITS 3 AND 4 76543210 => ...12...
TYA ;A=_7654321 3
ROR ; 3_765432 1
TXA ;A=210_7654
ROR ; 1210_765 4
ROR ; 41210_76 5
ROR ; 541210_7 5
ROR ; 6541210_ 7
AND #%00011000
ORA DS_BASE_20
STA DS_BASE_20
; BIT 0 TO BIT 5 76543210 -> .....345
LDA DS_BASE_22
LSR
LSR
LSR
STA DS_BASE_22
TYA ;A=_7654321
LSR
LSR
LSR
ROL DS_BASE_22
LSR
ROL DS_BASE_22
LSR
ROL DS_BASE_22
; LOWER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00777777774444444 3333333 32 31 30
;0066666666222222dd11111DD 35 34 33
;0055555555000 cccc CC 38 37 36
;00bbbbbbbbbbbbbbbb bbbBB 41 40 39
;00aaaaaaaaaaaaaaaaaaaaaAA 44 43 42
;000 cccc is 670 as in bits 6 and 7 from the previous byte and bit 0 from the current
; ROL DS_BASE_37 ;5 ; PRESHIFT BYTE TO RECEIVE BITS
; ROL DS_BASE_37 ;5
; ROL DS_BASE_37 ;5
LDA DS_BASE_37 ;3
ROL ;2
ROL ;2
ROL ;2
STA DS_BASE_37 ;3
STY DS_TEMP1
JSR FILLASHIELDBYTEINNER
LDY DS_TEMP1
; LDA SHIELDSI+3
LSR
ROR DS_BASE_37 ; SHIFT BITS IN
TAX
TYA
ROL
ROL
ROR DS_BASE_37
ROL
ROR DS_BASE_37
; 11111DD_ IS ___12DD_
TXA ;_7654321
ROR ;__765432 1
ROR ;1__76543 2
TXA ;_7654321 2
ROR ;2_765432 1
ROR ;12_76543 2
TAY ;Y=12_76543 2
LSR ;312_7654 3
LSR ;4312_765 4
LSR ;54312_76 5
AND #%00011000
ORA DS_BASE_33
STA DS_BASE_33
; 222222dd IS ____3dd_
TXA ; _7654321 5
AND #%00000100
ORA DS_BASE_34
STA DS_BASE_34
; 3333333_ IS ______4_
TYA ; 12_76543 5
AND #%00000010
STA DS_BASE_30
; 4444444_ IS ______5_
TYA ; 12_76543 5
LSR ; 512_7654 3
AND #%00000010
STA DS_BASE_31
; 55555555 IS _______6
TXA ; _7654321 3
ROL ; 76543213 _
ROL ; 6543213_ 7
ROL ; 543213_7 6
AND #%00000001
STA DS_BASE_35
; 66666666 IS _______7
ROL ; 43213_76 5
AND #%00000001
STA DS_BASE_38
; 77777777 IS _______0
JSR FILLASHIELDBYTEINNER
; LDA SHIELDSI+4
TAX
STA DS_TEMP1
AND #%00000001
STA DS_BASE_32
; UPPER RIGHT QUADRANT
; 765432107654321076543210 BYTE OFFSET
;00aaaaaaaaaaaaaaaaaaaaaAA X X 45
;00bbbbbbbbbbbbbbbb bbbBB X 47 46
;0055555555000 cccc CC 50 49 48
;0066666666222222dd11111DD 53 52 51
;00777777774444444 3333333 56 55 54
; 77777777
TXA
LSR
TAX
AND #%00000001
STA DS_BASE_56
; 66666666
TXA
LSR
TAX
AND #%00000001
STA DS_BASE_53
; 55555555
TXA
LSR
TAX
AND #%00000001
STA DS_BASE_50
; 4444444_
TXA
AND #%00000010
STA DS_BASE_55
; 3333333_
TXA
LSR
TAX
AND #%00000010
STA DS_BASE_54
TXA
AND #%00000100
ORA DS_BASE_52
STA DS_BASE_52
; LDA SHIELDSI+4
; ASL
; LDA SHIELDSI+5
JSR FILLASHIELDBYTEINNER
ASL DS_TEMP1
ROL
ASL
ASL
ASL
TAX
AND #%00011000
ORA DS_BASE_51
STA DS_BASE_51
TXA
AND #%11100000
ORA DS_BASE_49
STA DS_BASE_49
;******************** SHIELD DATA IS PACKED INTO MEMORY
JMP PACKSHIELDS3_RETURN ; RETURN WITH BANKSWITCH JUMP
#IF DISTELLA != 0
dc %11111111
dc %00001100
dc %00110000
dc %00001100
dc %11111111
dc %00000000
dc %10001110
dc %10010001
dc %01100001
dc %00000000
dc %01111110
dc %10000001
dc %10000001
dc %11111111
#ENDIF
;******************************************************************************
;
; SUBROUTINE TO SHOW ONE LINE OF SHIELDS
;
SHIELDSHOWLINE1
; DISABLE MISSILES BALL
LDX #0 ;2
STX ENAM0 ; 3
STX ENAM1 ; 3
STX ENABL ; 3
; TURN ON TRIPPLE CLOSE P0,P1
LDX #%00000011 ;2
STX NUSIZ0 ; 3
STX NUSIZ1 ; 3
LDX #VDELP0 ;2 SET STACK POINTER TO VDELP0
STX VDELP0 ; 3 RESET VDELP0 TO 1
TXS ;2
LDX DS_SAVEX ; 3
; SHOWING A&B(OLD)
PHP ; 3 SHOW C (CARRY MUST BE CLEAR) Write carry to VDELP0
STX GRP1 ; 3 SHOW D 9 PIXELS LATER
STY GRP0 ; 3 SHOW E 9 PIXELS LATER
STA GRP1 ; 3 SHOW F 9 PIXELS LATER
; CLEAR FOR NEXT LINE
LDA #0 ;2
STA GRP0 ; 3
STA GRP1 ; 3
; TURN OFF TRIPPLE CLOSE
STA NUSIZ0 ; 3
STA NUSIZ1 ; 3
; TURN ON MISSILES/BALL
INC DS_LINE ; 5
LDY DS_LINE ; 3
LDX #ENAM1+1 ; 3
TXS ;2
CPY SHOT0Y ; 3
PHP ; 3
CPY SHOT1Y ; 3
PHP ; 3
CPY SHOT2Y ; 3
PHP ; 3
CLC ;1 2
; RESTORE STACK POINTER FOR RETURN
LDX #$fd ;2
TXS ;2
RETURN
KILLTWELVECYCLES
RTS ; 6
;******************************************************************************
;
; DRAW THE SHIELDS
;
DRAWSHIELDS SUBROUTINE
; PACK SHIELDS 1
; PREP SHIP SCREEN
; WAIT FOR TOP OVERSCAN TO END
; SHIP SCREEN
; PACK SHIELDS 2
; VBL
; PACK SHIELDS 3
; DRAW CANNON
; PREPFORSHIELDS
; WAIT FOR TOP OVERSCAN TO END
; SHIELDS
; GAME LOGIC
; WAIT FOR BOTTOM OVERSCAN TO END
SHIELDS_WAITFORVBLANKEND
#IF DEBUGSYNCENABLE!=0
LDY INTIM
BPL .NOTFAIL4
FAIL4 NOP
.NOTFAIL4
#ENDIF
;SHIELDS_WAITFORVBLANKENDLOOP
; LDA INTIM
; BMI SHIELDS_TOPOFFRAME
; BNE SHIELDS_WAITFORVBLANKENDLOOP
; STA WSYNC
SHIELDS_TOPOFFRAME
; ; UNBLANK THE BEAM
; LDA #0
; STA VBLANK
JSR ENDVBLANK_BANK2 ; RETURNS WITH A=0
STA WSYNC
STA HMOVE
; DRAW THE UPPER SHOTS
;ENDVBLANK_BANK2 ; RETURNS WITH A=0 LDA #0
STA DS_LINE
JSR DRAW_SHIELD_UPPER_AND_LOWER_AREA
CLC ;1 2
MAC DRAWSHIELDLINE
.O0 SET {1}
.O1 SET {2}
.O2 SET {3}
.O3 SET {4}
.O4 SET {5}
.O5 SET {6}
.M0 SET {7}
.M1 SET {8}
.M2 SET {9}
.M3 SET {10}
.M4 SET {11}
.M5 SET {12}
.CURLINE SET 0
ALLOW_SHIELD_OPTIMIZATIONS EQU 1 ; SET TO ZERO TO DISALLOW SHIELD OPTIMIZATIONS
#IF .M0==0 && .M1==0 && .M4==0 && .M5==0 && ALLOW_SHIELD_OPTIMIZATIONS
LDY #0 ; 2 2
LDA .O3 ; 2 3
AND #.M3 ; 2 2
STA DS_SAVEX ; 1 2
STY GRP0 ; 2 3
LDA .O2 ; 2 3
AND #.M2 ; 2 2
STY GRP1 ; 2 3
NOP ;1 2
STA GRP0 ; 2 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
STA WSYNC ; 2 3
DEC $7F ; 2 5 KILL CYCLES
TYA ;1 2
JSR SHIELDSHOWLINE1 ; 3 6
#ELSE
#IF .M0==0 && .M2==0 && .M3==0 && .M5==0 && ALLOW_SHIELD_OPTIMIZATIONS
LDX #$0 ; 2 2
STX DS_SAVEX ; 1 2
LDA .O1 ; 2 3
STX GRP0 ; 2 3 LOAD A
AND #.M1 ; 2 2
STA GRP1 ; 2 3 LOAD B COPYING A TO OLD
LDA .O4 ; 2 3
AND #.M4 ; 2 2
STX GRP0 ; 2 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
STA WSYNC ; 2 3
TAY ; 1 2
TXA ; 1 2
NOP ; 1 2
JSR SHIELDSHOWLINE1 ; 3 6
#ELSE
#IF .M2==0 && .M3==0 && ALLOW_SHIELD_OPTIMIZATIONS
LDY #$0 ; 2 2
LDA .O0 ; 2 3
AND #.M0 ; 2 2
STA GRP0 ; 2 3 LOAD A
LDA .O1 ; 2 3
AND #.M1 ; 2 2
STA GRP1 ; 2 3 LOAD B COPYING A TO OLD
LDA .O2 ; 2 3
STY GRP0 ; 2 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
LDA .O4 ; 2 3
AND #.M4 ; 2 2
STY DS_SAVEX ; 1 2
STA WSYNC ; 2 3
TAY ; 1 2
LDA .O5 ; 2 3
AND #.M5 ; 2 2
JSR SHIELDSHOWLINE1 ; 3 6
#ELSE
#IF .M1==0 && .M4==0 && ALLOW_SHIELD_OPTIMIZATIONS
LDY #$0
LDA .O0 ; 2 3
AND #.M0 ; 2 2
STA GRP0 ; 2 3 LOAD A
STY GRP1 ; 2 3 LOAD B COPYING A TO OLD
LDA .O2 ; 2 3
AND #.M2 ; 2 2
STA GRP0 ; 2 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
LDA .O3 ; 2 3
AND #.M3 ; 2 2
STA DS_SAVEX ; 2 3
STA WSYNC ; 2 3
LDA .O5 ; 2 3
AND #.M5 ; 2 2
NOP
JSR SHIELDSHOWLINE1 ; 3 6
#ELSE
; NORMAL FULL LINE
LDA .O0 ; 2 3
AND #.M0 ; 2 2
STA GRP0 ; 2 3 LOAD A
LDA .O1
AND #.M1 ; 2 2
STA GRP1 ; 2 3 LOAD B COPYING A TO OLD
LDA .O2 ; 2 3
AND #.M2 ; 2 2
STA GRP0 ; 2 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
LDA .O3 ; 2 3
AND #.M3 ; 2 2
STA DS_SAVEX ; 1 2
LDA .O4 ; 2 3
AND #.M4 ; 2 2
STA WSYNC ; 2 3
TAY ; 1 2
LDA .O5 ; 2 3
AND #.M5 ; 2 2
JSR SHIELDSHOWLINE1 ; 3 6
#ENDIF
#ENDIF
#ENDIF
#ENDIF
ENDM
; 0,1,3 NOT BEING USED
; 46 LINES OF SHIELDS
; 765432107654321076543210 BYTE OFFSET ; 765432107654321076543210 BYTE OFFSET
;00 AAaaaaaaaaaaaaaaaaaaaaa 2 1 0 ;00aaaaaaaaaaaaaaaaaaaaaAA 57 58 45
;00 BBbbb bbbbbbbbbbbbbbbb 5 4 3 ;00bbbbbbbbbbbbbbbb bbbBB 59 47 46
;00 CC cccc 00055555555 8 7 6 ;0055555555000 cccc CC 50 49 48
;00 DD11111dd22222266666666 11 10 9 ;0066666666222222dd11111DD 53 52 51
;00 3333333 444444477777777 14 13 12 ;00777777774444444 3333333 56 55 54
DRAWSHIELDLINE DS_BASE_00,DS_BASE_00,DS_BASE_00,DS_BASE_57,DS_BASE_16,DS_BASE_16, %00000000,%00000000,%00001111,%11110000,%00000000,%00000000
DRAWSHIELDLINE DS_BASE_00,DS_BASE_00,DS_BASE_00,DS_BASE_57,DS_BASE_16,DS_BASE_16, %00000000,%00000000,%11110000,%00001111,%00000000,%00000000
DRAWSHIELDLINE DS_BASE_00,DS_BASE_01,DS_BASE_00,DS_BASE_16,DS_BASE_58,DS_BASE_16, %00000000,%00000011,%00000000,%00000000,%11000000,%00000000
DRAWSHIELDLINE DS_BASE_00,DS_BASE_01,DS_BASE_00,DS_BASE_16,DS_BASE_58,DS_BASE_16, %00000000,%00001100,%00000000,%00000000,%00110000,%00000000
DRAWSHIELDLINE DS_BASE_00,DS_BASE_01,DS_BASE_00,DS_BASE_16,DS_BASE_58,DS_BASE_16, %00000000,%00110000,%00000000,%00000000,%00001100,%00000000
DRAWSHIELDLINE DS_BASE_00,DS_BASE_01,DS_BASE_00,DS_BASE_16,DS_BASE_58,DS_BASE_16, %00000000,%01000000,%00000000,%00000000,%00000010,%00000000
DRAWSHIELDLINE DS_BASE_00,DS_BASE_01,DS_BASE_00,DS_BASE_16,DS_BASE_58,DS_BASE_16, %00000000,%10000000,%00000000,%00000000,%00000001,%00000000
DRAWSHIELDLINE DS_BASE_02,DS_BASE_00,DS_BASE_03,DS_BASE_59,DS_BASE_16,DS_BASE_45, %00000001,%00000000,%00000111,%11100000,%00000000,%10000000
DRAWSHIELDLINE DS_BASE_02,DS_BASE_00,DS_BASE_03,DS_BASE_59,DS_BASE_16,DS_BASE_45, %00000010,%00000000,%00111000,%00011100,%00000000,%01000000
DRAWSHIELDLINE DS_BASE_02,DS_BASE_00,DS_BASE_03,DS_BASE_59,DS_BASE_16,DS_BASE_45, %00000100,%00000000,%11000000,%00000011,%00000000,%00100000
DRAWSHIELDLINE DS_BASE_05,DS_BASE_04,DS_BASE_00,DS_BASE_16,DS_BASE_47,DS_BASE_46, %00000100,%00000011,%00000000,%00000000,%11000000,%00100000
DRAWSHIELDLINE DS_BASE_02,DS_BASE_04,DS_BASE_00,DS_BASE_16,DS_BASE_47,DS_BASE_45, %00001000,%00000100,%00000000,%00000000,%00100000,%00010000
DRAWSHIELDLINE DS_BASE_05,DS_BASE_04,DS_BASE_00,DS_BASE_16,DS_BASE_47,DS_BASE_46, %00001000,%00001000,%00000000,%00000000,%00010000,%00010000
DRAWSHIELDLINE DS_BASE_02,DS_BASE_04,DS_BASE_00,DS_BASE_16,DS_BASE_47,DS_BASE_45, %00010000,%00010000,%00000000,%00000000,%00001000,%00001000
DRAWSHIELDLINE DS_BASE_05,DS_BASE_07,DS_BASE_00,DS_BASE_16,DS_BASE_49,DS_BASE_46, %00010000,%00010000,%00000000,%00000000,%00001000,%00001000
DRAWSHIELDLINE DS_BASE_02,DS_BASE_04,DS_BASE_07,DS_BASE_49,DS_BASE_47,DS_BASE_45, %00100000,%00100000,%00000111,%11100000,%00000100,%00000100
DRAWSHIELDLINE DS_BASE_05,DS_BASE_07,DS_BASE_11,DS_BASE_51,DS_BASE_49,DS_BASE_46, %00100000,%00100000,%00011111,%11111000,%00000100,%00000100
DRAWSHIELDLINE DS_BASE_08,DS_BASE_04,DS_BASE_10,DS_BASE_52,DS_BASE_47,DS_BASE_48, %00100000,%01000000,%00111111,%11111100,%00000010,%00000100
DRAWSHIELDLINE DS_BASE_11,DS_BASE_07,DS_BASE_14,DS_BASE_54,DS_BASE_49,DS_BASE_51, %00100000,%01000000,%01111111,%11111110,%00000010,%00000100
DRAWSHIELDLINE DS_BASE_02,DS_BASE_10,DS_BASE_13,DS_BASE_55,DS_BASE_52,DS_BASE_45, %01000000,%01000000,%01111111,%11111110,%00000010,%00000010
DRAWSHIELDLINE DS_BASE_05,DS_BASE_04,DS_BASE_06,DS_BASE_50,DS_BASE_47,DS_BASE_46, %01000000,%10000000,%11111111,%11111111,%00000001,%00000010
DRAWSHIELDLINE DS_BASE_08,DS_BASE_07,DS_BASE_09,DS_BASE_53,DS_BASE_49,DS_BASE_48, %01000000,%10000000,%11111111,%11111111,%00000001,%00000010
DRAWSHIELDLINE DS_BASE_11,DS_BASE_10,DS_BASE_12,DS_BASE_56,DS_BASE_52,DS_BASE_51, %01000000,%10000000,%11111111,%11111111,%00000001,%00000010
; 765432107654321076543210 BYTE OFFSET 765432107654321076543210 BYTE OFFSET
;00 3333333 444444477777777 17 16 15 00 777777774444444 3333333 32 31 30
;00 DD11111dd22222266666666 20 19 18 00 66666666222222dd11111DD 35 34 33
;00 CC cccc 00055555555 23 22 21 00 55555555000 cccc CC 38 37 36
;00 BBbbb bbbbbbbbbbbbbbbb 26 25 24 00 bbbbbbbbbbbbbbbb bbbBB 41 40 39
;00 AAaaaaaaaaaaaaaaaaaaaaa 29 28 27 00 aaaaaaaaaaaaaaaaaaaaaAA 44 43 42
DRAWSHIELDLINE DS_BASE_20,DS_BASE_19,DS_BASE_15,DS_BASE_32,DS_BASE_34,DS_BASE_33, %01000000,%10000000,%11111111,%11111111,%00000001,%00000010
DRAWSHIELDLINE DS_BASE_23,DS_BASE_22,DS_BASE_18,DS_BASE_35,DS_BASE_37,DS_BASE_36, %01000000,%10000000,%11111111,%11111111,%00000001,%00000010
DRAWSHIELDLINE DS_BASE_26,DS_BASE_25,DS_BASE_21,DS_BASE_38,DS_BASE_40,DS_BASE_39, %01000000,%10000000,%11111111,%11111111,%00000001,%00000010
DRAWSHIELDLINE DS_BASE_29,DS_BASE_19,DS_BASE_16,DS_BASE_31,DS_BASE_34,DS_BASE_42, %01000000,%01000000,%01111111,%11111110,%00000010,%00000010
DRAWSHIELDLINE DS_BASE_20,DS_BASE_22,DS_BASE_17,DS_BASE_30,DS_BASE_37,DS_BASE_33, %00100000,%01000000,%01111111,%11111110,%00000010,%00000100
DRAWSHIELDLINE DS_BASE_23,DS_BASE_25,DS_BASE_19,DS_BASE_34,DS_BASE_40,DS_BASE_36, %00100000,%01000000,%00111111,%11111100,%00000010,%00000100
DRAWSHIELDLINE DS_BASE_26,DS_BASE_22,DS_BASE_20,DS_BASE_33,DS_BASE_37,DS_BASE_39, %00100000,%00100000,%00011111,%11111000,%00000100,%00000100
DRAWSHIELDLINE DS_BASE_29,DS_BASE_25,DS_BASE_22,DS_BASE_37,DS_BASE_40,DS_BASE_42, %00100000,%00100000,%00000111,%11100000,%00000100,%00000100
DRAWSHIELDLINE DS_BASE_26,DS_BASE_22,DS_BASE_16,DS_BASE_16,DS_BASE_37,DS_BASE_39, %00010000,%00010000,%00000000,%00000000,%00001000,%00001000
DRAWSHIELDLINE DS_BASE_29,DS_BASE_25,DS_BASE_16,DS_BASE_16,DS_BASE_40,DS_BASE_42, %00010000,%00010000,%00000000,%00000000,%00001000,%00001000
DRAWSHIELDLINE DS_BASE_26,DS_BASE_25,DS_BASE_16,DS_BASE_16,DS_BASE_40,DS_BASE_39, %00001000,%00001000,%00000000,%00000000,%00010000,%00010000
DRAWSHIELDLINE DS_BASE_29,DS_BASE_25,DS_BASE_16,DS_BASE_16,DS_BASE_40,DS_BASE_42, %00001000,%00000100,%00000000,%00000000,%00100000,%00010000
DRAWSHIELDLINE DS_BASE_26,DS_BASE_25,DS_BASE_16,DS_BASE_16,DS_BASE_40,DS_BASE_39, %00000100,%00000011,%00000000,%00000000,%11000000,%00100000
DRAWSHIELDLINE DS_BASE_29,DS_BASE_16,DS_BASE_24,DS_BASE_41,DS_BASE_16,DS_BASE_42, %00000100,%00000000,%11000000,%00000011,%00000000,%00100000
DRAWSHIELDLINE DS_BASE_29,DS_BASE_16,DS_BASE_24,DS_BASE_41,DS_BASE_16,DS_BASE_42, %00000010,%00000000,%00111000,%00011100,%00000000,%01000000
DRAWSHIELDLINE DS_BASE_29,DS_BASE_16,DS_BASE_24,DS_BASE_41,DS_BASE_16,DS_BASE_42, %00000001,%00000000,%00000111,%11100000,%00000000,%10000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_28,DS_BASE_16,DS_BASE_16,DS_BASE_43,DS_BASE_16, %00000000,%10000000,%00000000,%00000000,%00000001,%00000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_28,DS_BASE_16,DS_BASE_16,DS_BASE_43,DS_BASE_16, %00000000,%01000000,%00000000,%00000000,%00000010,%00000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_28,DS_BASE_16,DS_BASE_16,DS_BASE_43,DS_BASE_16, %00000000,%00110000,%00000000,%00000000,%00001100,%00000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_28,DS_BASE_16,DS_BASE_16,DS_BASE_43,DS_BASE_16, %00000000,%00001100,%00000000,%00000000,%00110000,%00000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_28,DS_BASE_16,DS_BASE_16,DS_BASE_43,DS_BASE_16, %00000000,%00000011,%00000000,%00000000,%11000000,%00000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_16,DS_BASE_27,DS_BASE_44,DS_BASE_16,DS_BASE_16, %00000000,%00000000,%11110000,%00001111,%00000000,%00000000
DRAWSHIELDLINE DS_BASE_16,DS_BASE_16,DS_BASE_27,DS_BASE_44,DS_BASE_16,DS_BASE_16, %00000000,%00000000,%00001111,%11110000,%00000000,%00000000
; BOTTOM AREA OF SCREEN (COULD DRAW STARS)
; DRAW THE LOWER SHOTS
JSR DRAW_SHIELD_UPPER_AND_LOWER_AREA
STA WSYNC
STA WSYNC
#if PAL!=0
STA WSYNC
STA WSYNC
#endif
SHIELDS_ENDOFFRAME
JSR STARTOVERSCAN_BANK2
; ; 30 LINES OF OVERSCAN
; LDA #35 ; WAIT 35*64 CYCLES FOR OVERSCAN
; STA TIM64T ; 35*64 INTVLS = 2240 CPU CLOCKS *3 = 6720 COLCLKS / 228 = 29.47 LINES
; LDA #2
; STA VBLANK
JMP DRAWSHIELDS_RETURN ; RETURN WITH BANKSWITCH JUMP
DRAW_SHIELD_UPPER_AND_LOWER_AREA
LDY #SHIELDSPACELINES/2-1
.SHIELD_UPPER_AND_LOWER_AREA_LOOP
INC DS_LINE ; 5
LDA DS_LINE ; 3
LDX #ENAM1+1 ; 3
TXS ;2
STX WSYNC
CMP SHOT0Y ; 3
PHP ; 3
CMP SHOT1Y ; 3
PHP ; 3
CMP SHOT2Y ; 3
PHP ; 3
LDX #$ff-2 ;2
TXS ;2
STA WSYNC
LDA #0 ; 2
STA ENAM0 ; 3
STA ENAM1 ; 3
STA.w ENABL ; 4
DEY
BNE .SHIELD_UPPER_AND_LOWER_AREA_LOOP
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SCREENS SUBROUTINE
.LINES EQU (5*2)
.RAMBUF EQU FREERAM
.RAM0 EQU FREERAM+.LINES*0
.RAM1 EQU FREERAM+.LINES*1
.RAM2 EQU FREERAM+.LINES*2
.RAM3 EQU FREERAM+.LINES*3
.RAM4 EQU FREERAM+.LINES*4
.RAM5 EQU FREERAM+.LINES*5
.TEMP0 EQU FREERAM+.LINES*6
.TEMP1 EQU FREERAM+.LINES*6 + 1
.TEMP2 EQU FREERAM+.LINES*6 + 2
.TEMP3 EQU FREERAM+.LINES*6 + 3
WSYNCVSYNCSTARTVBLANK_BANK2
; WAIT FOR OVERSCAN TO FINISH
LDA INTIM
BNE WSYNCVSYNCSTARTVBLANK_BANK2
LDX #$02
STX WSYNC ; WAIT TILL END OF LINE
DSWSTARTVSYNC
STX VSYNC ; VSYNC
; WAIT 3 LINES
STX WSYNC
STX WSYNC
; STILL ZERO LDA #0
LDX #43+1 ; WAIT FOR VBLANK
STA WSYNC
DSWENDVSYNC
STA VSYNC ; END VSYNC
STX TIM64T ; 43*64 INTVLS = 2752 = 8256 COLCLKS = 36.2LINES
; SILENCE
STA AUDV0
STA AUDV1
; RETURNS WITH A=0, X=44
RTS
ENDVBLANK_BANK2
LDA INTIM
BMI ENDVBLANK_BANK2_SKIPWSYNC
BNE ENDVBLANK_BANK2
STA WSYNC ; WAIT TILL END OF LINE
ENDVBLANK_BANK2_SKIPWSYNC
DSWENDVBLANK
DSWVBLANKOFF2
STA VBLANK ; END VBLANK, START DRAWING DISPLAY
; RETURNS WITH A <= 0
RTS
STARTOVERSCAN_BANK2
LDA #35+1 ; 30 * 76 / 64 = 35.625
STA WSYNC
STA TIM64T
DSWVBLANKON1
LDA #2
DSWSTARTVBLANK
STA VBLANK
; RETURNS WITH A=2
RTS
SETXPOS_BANK2
SEC
STA WSYNC
.WAITOBJECT:
SBC #$0F
BCS .WAITOBJECT
EOR #$07
ASL
ASL
ASL
ASL
RTS
SETUP_48_1
; COLORS FOR SPRITES
; LDA VBLS
; AND #3
; ASL
; ORA #$98
; STA COLUP0
; EOR #$07
; STA COLUP1
LDA #56 ;#$38 56 IS CENTERED ON WIDE SCREEN
JSR SETXPOS_BANK2 ; CALLS STA WSYNC ALMOST IMMEDIATELY
STA RESP0
STA HMP0
; SET SHIELDS P1 POSITION IN SECOND LINE (CONSTANT GUARANTEED NOT TO GO 2 LINES)
LDA #56+8 ;#$38+8
JSR SETXPOS_BANK2 ; CALLS STA WSYNC ALMOST IMMEDIATELY
STA RESP1
STA HMP1
STA WSYNC
STA HMOVE
; LDA #$9A
; STA COLUP0
; STA COLUP1
;
; LDX #0
; STX REFP0
; STX REFP1
; STX GRP1
; STX GRP0
; LDX #%00000011 ;2
; STX NUSIZ0 ; 3
; STX NUSIZ1 ; 3
LDX #SETUP48INIT-INITTAB2DEST
; JMP INITMEM_BANK2
; RTS
INITMEM_BANK2
.INITLOOP
LDY INITTAB2DEST,X
BEQ .DONE
LDA INITTAB2VAL,X
STA 0,Y
INX
BNE .INITLOOP
.DONE
; RETURNS WITH Y=0
RTS
INITTAB2DEST
SETUP48INIT
DC COLUP0,COLUP1, REFP0,REFP1,GRP1,GRP0, NUSIZ0,NUSIZ1,0
INITTAB2VAL
#IF PALCOLORS != 0
DC $BA,$BA, 0,0, 0,0, %00000011,%00000011 ;,0
#ELSE
DC $9A,$9A, 0,0, 0,0, %00000011,%00000011 ;,0
#ENDIF
LOADDIGIT
; A HAS DIGIT IN LOWER 4 BITS
; .TEMP0 HAS LEADING ZERO STATUS WHICH WILL BE UPDATED
; .TEMP1 HAS MASK
; Y HAS DESTINATION OFFSET (0,1,2,3,4)
; X & A ARE USED
AND #$0F
TAX
ORA .TEMP0
STA .TEMP0
BEQ .LZ
LDA DIGITS0,X
AND .TEMP1
ORA 0,Y
STA 0,Y
LDA DIGITS1,X
AND .TEMP1
ORA 1,Y
STA 1,Y
LDA DIGITS2,X
AND .TEMP1
ORA 2,Y
STA 2,Y
LDA DIGITS3,X
AND .TEMP1
ORA 3,Y
STA 3,Y
LDA DIGITS4,X
AND .TEMP1
ORA 4,Y
STA 4,Y
.LZ
RTS
; SKIP X LINES (X=0 ON EXIT)
BLANKLINES
STA WSYNC
DEX
BNE BLANKLINES
; RETURNS WITH X=0
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SCORE_SHIPS_SCREEN
.TOPSPACE EQU 30 ; BLANK LINES AT TOP OF THE SCREEN
.MIDDLESPACE EQU 10 ; BLANK LINES BETWEEN LINES OF TEXT
; RESET VBLANKS SO THIS CAN BE TIMED
LDA #$100 - (60*2)
STA VBLS
.NORESET
LSR SWCHB
BCC .NORESET
.SCORE_SHIPS_SCREEN
.SCORE_SHIPS_SCREEN_LOOP
JSR WSYNCVSYNCSTARTVBLANK_BANK2
SCORE_SHIPS_SCREEN2
JSR SETUP_48_1 ; RETURNS WITH Y=0
; CLEAR .RAM BUFFER
LDX #.LINES*6-1
; STILL ZERO LDY #0
.LOOP
STY .RAMBUF,X
DEX
BPL .LOOP
; BUILD SCORE INTO .RAM
; STILL ZERO LDY #0
STY .TEMP0 ; LEADING ZEROES
LDY #.RAM1
LDA #2
STA .TEMP3
.DIGITLOOP
; HIGH DIGIT
LDA #$F0
STA .TEMP1
LDX .TEMP3
LDA SCORE,X
LSR
LSR
LSR
LSR
JSR LOADDIGIT
; LOW DIGIT
LDA #$0F
STA .TEMP1
LDX .TEMP3
LDA SCORE,X
JSR LOADDIGIT
; NEXT DEST COLUMN
TYA
CLC
ADC #.LINES
TAY
; NEXT SCORE INDEX
DEC .TEMP3
BPL .DIGITLOOP
; LOAD CONSTANT ZERO
INC .TEMP0
LDA #$F0
STA .TEMP1
LDA #0
LDY #.RAM4
JSR LOADDIGIT
; LOAD SHIPS LEFT TEXT
LDX #5
; LDY #5-1
.LOOP1
LDA GFX_SHIPS_LEFT0-1,X
STA .RAM0+5-1,X
LDA GFX_SHIPS_LEFT1-1,X
STA .RAM1+5-1,X
LDA GFX_SHIPS_LEFT2-1,X
STA .RAM2+5-1,X
LDA GFX_SHIPS_LEFT3-1,X
STA .RAM3+5-1,X
LDA GFX_SHIPS_LEFT4-1,X
STA .RAM4+5-1,X
; LDA GFX_SHIPS_LEFT5-1,X
; STA .RAM5+5-5,X
DEX
; DEY
BNE .LOOP1
; LOAD NUMBER OF SHIPS
STx .TEMP0
LDA SHIPS
LSR
LSR
LSR
LSR
LDY #.RAM5+5
JSR LOADDIGIT
INC .TEMP0
LDA #$0F
STA .TEMP1
LDA SHIPS
LDY #.RAM5+5
JSR LOADDIGIT
JSR ENDVBLANK_BANK2
; WAIT BLANK LINES
LDX #.TOPSPACE
JSR BLANKLINES ; EXITS WITH X=0
; 2 TIMES THROUGH THE LOOP (IF THERE ARE SHIPS)
LDA #2
STA .TEMP2
LDA #5
STA .TEMP1 ; ENDING LINE
LDY #0
STY .TEMP0 ; STARTING LINE
.DRAWLOOP
LDX #VDELP0 ;2 SET STACK POINTER TO VDELP0
STX VDELP0 ; 3 RESET VDELP0 TO 1
TXS ;2
STA WSYNC
CLC
.LINELOOP
LDA .RAM0,Y ; 4
STA GRP0 ; 3 LOAD A
LDA .RAM1,Y ; 4
STA GRP1 ; 3 LOAD B (LATCHES A)
LDA .RAM2,Y ; 4
STA GRP0 ; 3 LOAD C (LATCHES B)
LDX .RAM3,Y ; 4
LDA .RAM4,Y ; 4
STA .TEMP3 ; 3
LDA .RAM5,Y ; 4
LDY .TEMP3 ; 3
PHP ; 3 SHOW C (CARRY MUST BE CLEAR) Write carry to VDELP0
STX GRP1 ; 3 SHOW D 9 PIXELS LATER
STY GRP0 ; 3 SHOW E 9 PIXELS LATER
STA GRP1 ; 3 SHOW F 9 PIXELS LATER
LDA $7F,X ; 4 KILL CYCLES
LDY .TEMP0 ; 3
INY ;2
LDX #VDELP0 ;2 SET STACK POINTER TO VDELP0
STX VDELP0 ; 3 RESET VDELP0 TO 1
TXS ;2
CPY .TEMP1 ; 3
STY .TEMP0 ; 3
BCC .LINELOOP ; 3
;===== 76
; TURN OFF THE SPRITES
LDA #0
STA GRP0
STA GRP1
; RESTORE STACK
LDX #$FF
TXS
; SKIP SOME LINES
LDX #.MIDDLESPACE
JSR BLANKLINES
; SEE IF WE SHOULD DRAW SHIPS TEXT OR GAME OVER TEXT
LDX #DISPLAYSCANLINES-(.TOPSPACE+(5+1)+.MIDDLESPACE+(5+1)+.MIDDLESPACE)-1
LDA SHIPS
BNE .NOGAMEOVER
; DRAW GAME OVER TEXT
LDA #(44-5)*2
STA .TEMP0
LDA #44
STA .TEMP1
JSR DRAWROM48
DEC .TEMP2
LDX #DISPLAYSCANLINES-(.TOPSPACE+(5+1)+.MIDDLESPACE+(10+1))-1
.NOGAMEOVER
; START GAME ON RESET SWITCH IF PRESSED BUT NOT JOY BUTTON
; ASL INPT4
; BCC .START
LSR SWCHB
BCC .START
; SET END POINT FOR SECOND BLOCK OF TEXT
LDA #10
STA .TEMP1
; SHOW 2 BLOCKS OF TEXT
DEC .TEMP2
BNE .DRAWLOOP
; x LOADED EARLIER - BURN THE HELL OUT OF SOME SCAN LINES
JSR BLANKLINES
JSR STARTOVERSCAN_BANK2
INC VBLS
BNE .NOTDONE
LDA SHIPS
BEQ TITLESCREEN
; WHEN DONE, THIS WILL VECTOR TO CODE THAT WILL SET UP THE GAME FOR PLAY
; SET UP THE SHIP FUZZBALL SCREEN AND WAIT FOR THE SHIELD SCREEN OVERSCAN
JMP SCORE_SHIPS_SCREEN_RETURN
.NOTDONE
JMP .SCORE_SHIPS_SCREEN_LOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TITLESCREENLOOP
ASL INPT4
BCC .START
LSR SWCHB
BCS .NOSTART
.START
JMP TITLESCREEN_RETURN
.NOSTART
INC VBLS
BNE .NOSCORESCREEN
LDA #$100-(60*3)
STA VBLS
JMP SCORE_SHIPS_SCREEN2
.NOSCORESCREEN
JSR SETUP_48_1
JSR ENDVBLANK_BANK2
LDX #50-1
JSR BLANKLINES ; RETURNS WITH Y=0
#IF PALCOLORS != 0
LDA VBLS
LSR
AND #$0F ; THIS IS NOT EXACTLY THE SAME
CLC
ADC #$20
STA COLUP0
STA COLUP1
#ELSE
LDA VBLS
LSR
AND #$1F
CLC
ADC #$20
STA COLUP0
STA COLUP1
#ENDIF
#IF CUSTOM_TITLESCREEN == 0
; THIS IS THE STOCK TITLE SCREEN
LDA #28
STA .TEMP1
; STILL ZERO LDX #0
STx .TEMP0
JSR DRAWROM48 ; EACH CALL TAKES AN EXTRA LINE TO SYNCHRONIZE THE TOP
LDX #40-1
JSR BLANKLINES
LDA #$0C
STA COLUP0
STA COLUP1
; BY D. SCOTT
; WILLIAMSON
LDA #39
STA .TEMP1
JSR DRAWROM48 ; EACH CALL TAKES AN EXTRA LINE TO SYNCHRONIZE THE TOP
#ELSE
; CUSTOM COLOR
LDA #CUSTOM_TITLECOLOR
STA COLUP0
STA COLUP1
; THIS IS A CUSTOM BITMAP
LDA #39
STA .TEMP1
; STILL ZERO LDX #0
STx .TEMP0
JSR DRAWROM48 ; EACH CALL TAKES AN EXTRA LINE TO SYNCHRONIZE THE TOP
LDX #40
JSR BLANKLINES
#ENDIF
; BURN THE HELL OUT OF SOME SCAN LINES
LDX #(DISPLAYSCANLINES-(50+40+(39*2)))-1
JSR BLANKLINES
JSR STARTOVERSCAN_BANK2
TITLESCREEN ; ENTRY POINT FOR TITLE SCREEN LOOP
JSR WSYNCVSYNCSTARTVBLANK_BANK2
JMP TITLESCREENLOOP ; CHEAP JUMP CARRY IS ALWAYS SET WHEN EXITING DRAWROM48
; .TEMP0 IS INDEX INTO GRAPHICS TABLE
; .TEMP1 IS INDEX THAT TERMINATES THE DRAW
DRAWROM48
LDA .TEMP0
LSR
TAY
LDX #VDELP0 ;2 SET STACK POINTER TO VDELP0
STX VDELP0 ; 3 RESET VDELP0 TO 1
TXS ;2
STA WSYNC
CLC
.LINELOOP48
#IF 1
LDA GFX_48_0,Y ; 4
STA GRP0 ; 3
LDA GFX_48_1,Y ; 4
STA GRP1 ; 3
LDA GFX_48_2,Y ; 4
STA GRP0 ; 3 ; LATCHES GRP1
LDX GFX_48_3,Y ; 4
LDA GFX_48_4,Y ; 4
STA .TEMP3 ; 3
LDA GFX_48_5,Y ; 4
LDY .TEMP3 ; 3
PHP ; 3 SHOW C (CARRY MUST BE CLEAR) Write carry to VDELP0
STX GRP1 ; 3 SHOW D 9 PIXELS LATER
STY GRP0 ; 3 SHOW E 9 PIXELS LATER
STA GRP1 ; 3 SHOW F 9 PIXELS LATER
INC .TEMP0 ; 5
LDA .TEMP0 ; 3
LSR ;2 ; DOUBLE LINES
TAY ;2
LDX #VDELP0 ;2 SET STACK POINTER TO VDELP0
STX VDELP0 ; 3 RESET VDELP0 TO 1
TXS ;2
CPY .TEMP1 ; 3
BCC .LINELOOP48 ; 3
;===== 76
#ELSE
; ===============
LDA GFX_48_0,Y ; 4
LDX GFX_48_1,Y ; 4
STA GRP0 ; 3 LOAD A
STX GRP1 ; 3 LOAD B COPYING A TO OLD
LDX GFX_48_2,Y ; 4
STX GRP0 ; 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
LDX GFX_48_3,Y ; 4 D IN X
LDA GFX_48_4,Y ; 4 GET E
STA .TEMP3 ; 3 PUT E IN TEMP2
LDA GFX_48_5,Y ; 4 F IN A
LDY .TEMP3 ; 3 E IN Y
; SHOWING A&B(OLD)
PHP ; 3 SHOW C (CARRY MUST BE CLEAR)
STX GRP1 ; 3 SHOW D 9 PIXELS LATER
STY GRP0 ; 3 SHOW E 9 PIXELS LATER
STA GRP1 ; 3 SHOW F 9 PIXELS LATER
LDY .TEMP0 ; 3
LDA GFX_48_COLOR,Y ; 4
STA COLUP0 ; 3
STA COLUP1 ; 3
STA VDELP0 ; 3 ; ONLY WORKS IF LOW BIT IS 1
DEC $7F ; INC .TEMP0 ; 5
PLA ; 4
; ===============
LDA GFX_48_0,Y ; 4
LDX GFX_48_1,Y ; 4
STA GRP0 ; 3 LOAD A
STX GRP1 ; 3 LOAD B COPYING A TO OLD
LDX GFX_48_2,Y ; 4
STX GRP0 ; 3 LOAD NEW C INTO 0 (COPYTING B TO OLD - NOT IMPORTANT)
LDX GFX_48_3,Y ; 4 D IN X
LDA GFX_48_4,Y ; 4 GET E
STA .TEMP3 ; 3 PUT E IN TEMP2
LDA GFX_48_5,Y ; 4 F IN A
LDY .TEMP3 ; 3 E IN Y
; SHOWING A&B(OLD)
PHP ; 3 SHOW C (CARRY MUST BE CLEAR)
STX GRP1 ; 3 SHOW D 9 PIXELS LATER
STY GRP0 ; 3 SHOW E 9 PIXELS LATER
STA GRP1 ; 3 SHOW F 9 PIXELS LATER
PLA ; 4
NOP ;2
LDA #1 ;2
STA VDELP0 ; 3
INC .TEMP0 ; 5
LDY .TEMP0 ; 3
CPY .TEMP1 ; 3
BCC .LINELOOP ; 3 WHEN TAKEN
; 5*1 + 4*7+ 3*14 + 2*2 = 79 : LOSE 3 CYCLES!
; ===============
#ENDIF
LDA #0
STA GRP0
STA GRP1
LDX #$FF-2
TXS
RTS
;;;
echo "---- Unused ROM at end of bank 2:",(($fFF8-(6*6))-*)d,"bytes"
; DRAWSHIELDS ROUTINE CALL RETURNS TO BANK0
ORG $2FF8-(6*6)
RORG $fFF8-(6*6)
SCORE_SHIPS_SCREEN_RETURN
LDA SWITCH_TO_LOWBANK ; SWITCH TO BANK 1
JMP SCORE_SHIPS_SCREEN ; JUST SWITCHED FROM BANK 1, GO DO WORK
TITLESCREEN_RETURN
LDA SWITCH_TO_LOWBANK ; SWITCH TO BANK 1
JMP TITLESCREEN ; JUST SWITCHED FROM BANK 1, GO DO WORK
PACKSHIELDS1_RETURN
LDA SWITCH_TO_LOWBANK ; SWITCH TO BANK 1
JMP PACKSHIELDS1 ; JUST SWITCHED FROM BANK 1, GO DO WORK
PACKSHIELDS2_RETURN
LDA SWITCH_TO_LOWBANK ; SWITCH TO BANK 1
JMP PACKSHIELDS2 ; JUST SWITCHED FROM BANK 1, GO DO WORK
PACKSHIELDS3_RETURN
LDA SWITCH_TO_LOWBANK ; SWITCH TO BANK 1
JMP PACKSHIELDS3 ; JUST SWITCHED FROM BANK 1, GO DO WORK
DRAWSHIELDS_RETURN
LDA SWITCH_TO_LOWBANK ; SWITCH TO BANK 1
JMP DRAWSHIELDS ; JUST SWITCHED FROM BANK 1, GO DO WORK
; VECTOR TABLE BANK1
ORG $2FFA
.WORD VECTOR_NMI ; NMI (6507 IN ATARI 2600 HAS NO NMI PIN)
.WORD VECTOR_RESET ; RESET
.WORD VECTOR_BREAK ; IRQ/BREAK (6507 IN ATARI 2600 HAS NO IRQ PIN)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment