mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-09-28 15:54:40 +00:00
4215 lines
73 KiB
Plaintext
4215 lines
73 KiB
Plaintext
ifconst bankswitch
|
|
if bankswitch == 8
|
|
ORG $2FFC
|
|
RORG $FFFC
|
|
endif
|
|
if bankswitch == 16
|
|
ORG $4FFC
|
|
RORG $FFFC
|
|
endif
|
|
if bankswitch == 32
|
|
ORG $8FFC
|
|
RORG $FFFC
|
|
endif
|
|
else
|
|
ifconst ROM2k
|
|
ORG $F7FC
|
|
else
|
|
ORG $FFFC
|
|
endif
|
|
endif
|
|
.word start
|
|
.word start
|
|
; MACRO.H
|
|
; Version 1.05, 13/NOVEMBER/2003
|
|
|
|
VERSION_MACRO = 105
|
|
|
|
;
|
|
; THIS FILE IS EXPLICITLY SUPPORTED AS A DASM-PREFERRED COMPANION FILE
|
|
; PLEASE DO *NOT* REDISTRIBUTE MODIFIED VERSIONS OF THIS FILE!
|
|
;
|
|
; This file defines DASM macros useful for development for the Atari 2600.
|
|
; It is distributed as a companion machine-specific support package
|
|
; for the DASM compiler. Updates to this file, DASM, and associated tools are
|
|
; available at at http://www.atari2600.org/dasm
|
|
;
|
|
; Many thanks to the people who have contributed. If you take issue with the
|
|
; contents, or would like to add something, please write to me
|
|
; (atari2600@taswegian.com) with your contribution.
|
|
;
|
|
; Latest Revisions...
|
|
;
|
|
; 1.05 14/NOV/2003 - Added VERSION_MACRO equate (which will reflect 100x version #)
|
|
; This will allow conditional code to verify MACRO.H being
|
|
; used for code assembly.
|
|
; 1.04 13/NOV/2003 - SET_POINTER macro added (16-bit address load)
|
|
;
|
|
; 1.03 23/JUN/2003 - CLEAN_START macro added - clears TIA, RAM, registers
|
|
;
|
|
; 1.02 14/JUN/2003 - VERTICAL_SYNC macro added
|
|
; (standardised macro for vertical synch code)
|
|
; 1.01 22/MAR/2003 - SLEEP macro added.
|
|
; - NO_ILLEGAL_OPCODES switch implemented
|
|
; 1.0 22/MAR/2003 Initial release
|
|
|
|
; Note: These macros use illegal opcodes. To disable illegal opcode usage,
|
|
; define the symbol NO_ILLEGAL_OPCODES (-DNO_ILLEGAL_OPCODES=1 on command-line).
|
|
; If you do not allow illegal opcode usage, you must include this file
|
|
; *after* including VCS.H (as the non-illegal opcodes access hardware
|
|
; registers and require them to be defined first).
|
|
|
|
; Available macros...
|
|
; SLEEP n - sleep for n cycles
|
|
; VERTICAL_SYNC - correct 3 scanline vertical synch code
|
|
; CLEAN_START - set machine to known state on startup
|
|
; SET_POINTER - load a 16-bit absolute to a 16-bit variable
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; SLEEP duration
|
|
; Original author: Thomas Jentzsch
|
|
; Inserts code which takes the specified number of cycles to execute. This is
|
|
; useful for code where precise timing is required.
|
|
; ILLEGAL-OPCODE VERSION DOES NOT AFFECT FLAGS OR REGISTERS.
|
|
; LEGAL OPCODE VERSION MAY AFFECT FLAGS
|
|
; Uses illegal opcode (DASM 2.20.01 onwards).
|
|
|
|
MAC SLEEP ;usage: SLEEP n (n>1)
|
|
.CYCLES SET {1}
|
|
|
|
IF .CYCLES < 2
|
|
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 1"
|
|
ERR
|
|
ENDIF
|
|
|
|
IF .CYCLES & 1
|
|
IFNCONST NO_ILLEGAL_OPCODES
|
|
nop 0
|
|
ELSE
|
|
bit VSYNC
|
|
ENDIF
|
|
.CYCLES SET .CYCLES - 3
|
|
ENDIF
|
|
|
|
REPEAT .CYCLES / 2
|
|
nop
|
|
REPEND
|
|
ENDM
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; VERTICAL_SYNC
|
|
; Original author: Manuel Polik
|
|
; Inserts the code required for a proper 3 scannline
|
|
; vertical sync sequence
|
|
;
|
|
; Note: Alters the accumulator
|
|
;
|
|
; IN:
|
|
; OUT: A = 1
|
|
|
|
MAC VERTICAL_SYNC
|
|
LDA #$02 ; A = VSYNC enable
|
|
STA WSYNC ; Finish current line
|
|
STA VSYNC ; Start vertical sync
|
|
STA WSYNC ; 1st line vertical sync
|
|
STA WSYNC ; 2nd line vertical sync
|
|
LSR ; A = VSYNC disable
|
|
STA WSYNC ; 3rd line vertical sync
|
|
STA VSYNC ; Stop vertical sync
|
|
ENDM
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; CLEAN_START
|
|
; Original author: Andrew Davie
|
|
; Standardised start-up code, clears stack, all TIA registers and RAM to 0
|
|
; Sets stack pointer to $FF, and all registers to 0
|
|
; Sets decimal mode off, sets interrupt flag (kind of un-necessary)
|
|
; Use as very first section of code on boot (ie: at reset)
|
|
; Code written to minimise total ROM usage - uses weird 6502 knowledge :)
|
|
|
|
MAC CLEAN_START
|
|
sei
|
|
cld
|
|
|
|
ldx #0
|
|
txa
|
|
tay
|
|
.CLEAR_STACK dex
|
|
txs
|
|
pha
|
|
bne .CLEAR_STACK ; SP=$FF, X = A = Y = 0
|
|
|
|
ENDM
|
|
|
|
;-------------------------------------------------------
|
|
; SET_POINTER
|
|
; Original author: Manuel Rotschkar
|
|
;
|
|
; Sets a 2 byte RAM pointer to an absolute address.
|
|
;
|
|
; Usage: SET_POINTER pointer, address
|
|
; Example: SET_POINTER SpritePTR, SpriteData
|
|
;
|
|
; Note: Alters the accumulator, NZ flags
|
|
; IN 1: 2 byte RAM location reserved for pointer
|
|
; IN 2: absolute address
|
|
|
|
MAC SET_POINTER
|
|
.POINTER SET {1}
|
|
.ADDRESS SET {2}
|
|
|
|
LDA #<.ADDRESS ; Get Lowbyte of Address
|
|
STA .POINTER ; Store in pointer
|
|
LDA #>.ADDRESS ; Get Hibyte of Address
|
|
STA .POINTER+1 ; Store in pointer+1
|
|
|
|
ENDM
|
|
|
|
; EOF
|
|
; this file is screwed, I accidentally deleted the comments. Restore with version in .99b zip file.
|
|
2600basicheader.asm
|
|
bB.asm
|
|
std_kernel.asm
|
|
startup.asm
|
|
pf_drawing.asm
|
|
pf_scrolling.asm
|
|
std_routines.asm
|
|
std_overscan.asm
|
|
bB2.asm
|
|
score_graphics.asm
|
|
banksw.asm
|
|
2600basicfooter.asm
|
|
minikernel ; display up to 6 lives on screen
|
|
sta WSYNC
|
|
sleep 10 ; can we optimize this?
|
|
lda #0
|
|
ldy #7
|
|
sta VDELP0
|
|
sta VDELP1
|
|
ifnconst lives_compact
|
|
ifnconst lives_centered
|
|
sta RESP0
|
|
endif
|
|
lda.w lives
|
|
ifnconst lives_centered
|
|
sta RESP1
|
|
endif
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
ifconst lives_centered
|
|
sta RESP0
|
|
endif
|
|
lsr
|
|
tax
|
|
ifconst lives_centered
|
|
sta RESP1
|
|
endif
|
|
lda lifenusiz0table,x
|
|
sta NUSIZ0
|
|
lda lifenusiz1table,x
|
|
sta NUSIZ1
|
|
lda lifecolor
|
|
sta COLUP0
|
|
sta COLUP1
|
|
lda #$b0
|
|
sta HMP0
|
|
|
|
else
|
|
|
|
ifnconst lives_centered
|
|
sta.w RESP0
|
|
sta RESP1
|
|
endif
|
|
lda lives
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
tax
|
|
lda lifenusiz0table,x
|
|
ifconst lives_centered
|
|
sta RESP0
|
|
sta RESP1
|
|
sta.w NUSIZ0
|
|
else
|
|
sta NUSIZ0
|
|
endif
|
|
lda lifenusiz1table,x
|
|
sta NUSIZ1
|
|
lda lifecolor
|
|
sta COLUP0
|
|
sta COLUP1
|
|
lda #$10
|
|
sta HMP1
|
|
|
|
endif
|
|
|
|
sta HMOVE ; cycle 73
|
|
|
|
lifeloop
|
|
cpx #0
|
|
beq skipall
|
|
lda (lifepointer),y
|
|
sta GRP0
|
|
cpx #1
|
|
beq skipall
|
|
sta GRP1
|
|
skipall
|
|
dey
|
|
sta WSYNC
|
|
bpl lifeloop
|
|
iny
|
|
sty GRP0
|
|
sty GRP1
|
|
rts
|
|
|
|
if (<*) > $F5
|
|
align 256
|
|
endif
|
|
ifconst lives_compact
|
|
lifenusiz1table
|
|
.byte 0
|
|
lifenusiz0table
|
|
.byte 0,0,0,1,1,3,3,3
|
|
else
|
|
lifenusiz1table
|
|
.byte 0
|
|
lifenusiz0table
|
|
.byte 0,0,0,2,2,6,6,6
|
|
endif
|
|
; VCS.H
|
|
; Version 1.05, 13/November/2003
|
|
|
|
VERSION_VCS = 105
|
|
|
|
; THIS IS A PRELIMINARY RELEASE OF *THE* "STANDARD" VCS.H
|
|
; THIS FILE IS EXPLICITLY SUPPORTED AS A DASM-PREFERRED COMPANION FILE
|
|
; PLEASE DO *NOT* REDISTRIBUTE THIS FILE!
|
|
;
|
|
; This file defines hardware registers and memory mapping for the
|
|
; Atari 2600. It is distributed as a companion machine-specific support package
|
|
; for the DASM compiler. Updates to this file, DASM, and associated tools are
|
|
; available at at http://www.atari2600.org/dasm
|
|
;
|
|
; Many thanks to the original author(s) of this file, and to everyone who has
|
|
; contributed to understanding the Atari 2600. If you take issue with the
|
|
; contents, or naming of registers, please write to me (atari2600@taswegian.com)
|
|
; with your views. Please contribute, if you think you can improve this
|
|
; file!
|
|
;
|
|
; Latest Revisions...
|
|
; 1.05 13/NOV/2003 - Correction to 1.04 - now functions as requested by MR.
|
|
; - Added VERSION_VCS equate (which will reflect 100x version #)
|
|
; This will allow conditional code to verify VCS.H being
|
|
; used for code assembly.
|
|
; 1.04 12/NOV/2003 Added TIA_BASE_WRITE_ADDRESS and TIA_BASE_READ_ADDRESS for
|
|
; convenient disassembly/reassembly compatibility for hardware
|
|
; mirrored reading/writing differences. This is more a
|
|
; readability issue, and binary compatibility with disassembled
|
|
; and reassembled sources. Per Manuel Rotschkar's suggestion.
|
|
; 1.03 12/MAY/2003 Added SEG segment at end of file to fix old-code compatibility
|
|
; which was broken by the use of segments in this file, as
|
|
; reported by Manuel Polik on [stella] 11/MAY/2003
|
|
; 1.02 22/MAR/2003 Added TIMINT($285)
|
|
; 1.01 Constant offset added to allow use for 3F-style bankswitching
|
|
; - define TIA_BASE_ADDRESS as $40 for Tigervision carts, otherwise
|
|
; it is safe to leave it undefined, and the base address will
|
|
; be set to 0. Thanks to Eckhard Stolberg for the suggestion.
|
|
; Note, may use -DLABEL=EXPRESSION to define TIA_BASE_ADDRESS
|
|
; - register definitions are now generated through assignment
|
|
; in uninitialised segments. This allows a changeable base
|
|
; address architecture.
|
|
; 1.0 22/MAR/2003 Initial release
|
|
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
; TIA_BASE_ADDRESS
|
|
; The TIA_BASE_ADDRESS defines the base address of access to TIA registers.
|
|
; Normally 0, the base address should (externally, before including this file)
|
|
; be set to $40 when creating 3F-bankswitched (and other?) cartridges.
|
|
; The reason is that this bankswitching scheme treats any access to locations
|
|
; < $40 as a bankswitch.
|
|
|
|
IFNCONST TIA_BASE_ADDRESS
|
|
TIA_BASE_ADDRESS = 0
|
|
ENDIF
|
|
|
|
; Note: The address may be defined on the command-line using the -D switch, eg:
|
|
; dasm.exe code.asm -DTIA_BASE_ADDRESS=$40 -f3 -v5 -ocode.bin
|
|
; *OR* by declaring the label before including this file, eg:
|
|
; TIA_BASE_ADDRESS = $40
|
|
; include "vcs.h"
|
|
|
|
; Alternate read/write address capability - allows for some disassembly compatibility
|
|
; usage ; to allow reassembly to binary perfect copies). This is essentially catering
|
|
; for the mirrored ROM hardware registers.
|
|
|
|
; Usage: As per above, define the TIA_BASE_READ_ADDRESS and/or TIA_BASE_WRITE_ADDRESS
|
|
; using the -D command-line switch, as required. If the addresses are not defined,
|
|
; they defaut to the TIA_BASE_ADDRESS.
|
|
|
|
IFNCONST TIA_BASE_READ_ADDRESS
|
|
TIA_BASE_READ_ADDRESS = TIA_BASE_ADDRESS
|
|
ENDIF
|
|
|
|
IFNCONST TIA_BASE_WRITE_ADDRESS
|
|
TIA_BASE_WRITE_ADDRESS = TIA_BASE_ADDRESS
|
|
ENDIF
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
SEG.U TIA_REGISTERS_WRITE
|
|
ORG TIA_BASE_WRITE_ADDRESS
|
|
|
|
; DO NOT CHANGE THE RELATIVE ORDERING OF REGISTERS!
|
|
|
|
VSYNC ds 1 ; $00 0000 00x0 Vertical Sync Set-Clear
|
|
VBLANK ds 1 ; $01 xx00 00x0 Vertical Blank Set-Clear
|
|
WSYNC ds 1 ; $02 ---- ---- Wait for Horizontal Blank
|
|
RSYNC ds 1 ; $03 ---- ---- Reset Horizontal Sync Counter
|
|
NUSIZ0 ds 1 ; $04 00xx 0xxx Number-Size player/missle 0
|
|
NUSIZ1 ds 1 ; $05 00xx 0xxx Number-Size player/missle 1
|
|
COLUP0 ds 1 ; $06 xxxx xxx0 Color-Luminance Player 0
|
|
COLUP1 ds 1 ; $07 xxxx xxx0 Color-Luminance Player 1
|
|
COLUPF ds 1 ; $08 xxxx xxx0 Color-Luminance Playfield
|
|
COLUBK ds 1 ; $09 xxxx xxx0 Color-Luminance Background
|
|
CTRLPF ds 1 ; $0A 00xx 0xxx Control Playfield, Ball, Collisions
|
|
REFP0 ds 1 ; $0B 0000 x000 Reflection Player 0
|
|
REFP1 ds 1 ; $0C 0000 x000 Reflection Player 1
|
|
PF0 ds 1 ; $0D xxxx 0000 Playfield Register Byte 0
|
|
PF1 ds 1 ; $0E xxxx xxxx Playfield Register Byte 1
|
|
PF2 ds 1 ; $0F xxxx xxxx Playfield Register Byte 2
|
|
RESP0 ds 1 ; $10 ---- ---- Reset Player 0
|
|
RESP1 ds 1 ; $11 ---- ---- Reset Player 1
|
|
RESM0 ds 1 ; $12 ---- ---- Reset Missle 0
|
|
RESM1 ds 1 ; $13 ---- ---- Reset Missle 1
|
|
RESBL ds 1 ; $14 ---- ---- Reset Ball
|
|
AUDC0 ds 1 ; $15 0000 xxxx Audio Control 0
|
|
AUDC1 ds 1 ; $16 0000 xxxx Audio Control 1
|
|
AUDF0 ds 1 ; $17 000x xxxx Audio Frequency 0
|
|
AUDF1 ds 1 ; $18 000x xxxx Audio Frequency 1
|
|
AUDV0 ds 1 ; $19 0000 xxxx Audio Volume 0
|
|
AUDV1 ds 1 ; $1A 0000 xxxx Audio Volume 1
|
|
GRP0 ds 1 ; $1B xxxx xxxx Graphics Register Player 0
|
|
GRP1 ds 1 ; $1C xxxx xxxx Graphics Register Player 1
|
|
ENAM0 ds 1 ; $1D 0000 00x0 Graphics Enable Missle 0
|
|
ENAM1 ds 1 ; $1E 0000 00x0 Graphics Enable Missle 1
|
|
ENABL ds 1 ; $1F 0000 00x0 Graphics Enable Ball
|
|
HMP0 ds 1 ; $20 xxxx 0000 Horizontal Motion Player 0
|
|
HMP1 ds 1 ; $21 xxxx 0000 Horizontal Motion Player 1
|
|
HMM0 ds 1 ; $22 xxxx 0000 Horizontal Motion Missle 0
|
|
HMM1 ds 1 ; $23 xxxx 0000 Horizontal Motion Missle 1
|
|
HMBL ds 1 ; $24 xxxx 0000 Horizontal Motion Ball
|
|
VDELP0 ds 1 ; $25 0000 000x Vertical Delay Player 0
|
|
VDELP1 ds 1 ; $26 0000 000x Vertical Delay Player 1
|
|
VDELBL ds 1 ; $27 0000 000x Vertical Delay Ball
|
|
RESMP0 ds 1 ; $28 0000 00x0 Reset Missle 0 to Player 0
|
|
RESMP1 ds 1 ; $29 0000 00x0 Reset Missle 1 to Player 1
|
|
HMOVE ds 1 ; $2A ---- ---- Apply Horizontal Motion
|
|
HMCLR ds 1 ; $2B ---- ---- Clear Horizontal Move Registers
|
|
CXCLR ds 1 ; $2C ---- ---- Clear Collision Latches
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
SEG.U TIA_REGISTERS_READ
|
|
ORG TIA_BASE_READ_ADDRESS
|
|
|
|
; bit 7 bit 6
|
|
CXM0P ds 1 ; $00 xx00 0000 Read Collision M0-P1 M0-P0
|
|
CXM1P ds 1 ; $01 xx00 0000 M1-P0 M1-P1
|
|
CXP0FB ds 1 ; $02 xx00 0000 P0-PF P0-BL
|
|
CXP1FB ds 1 ; $03 xx00 0000 P1-PF P1-BL
|
|
CXM0FB ds 1 ; $04 xx00 0000 M0-PF M0-BL
|
|
CXM1FB ds 1 ; $05 xx00 0000 M1-PF M1-BL
|
|
CXBLPF ds 1 ; $06 x000 0000 BL-PF -----
|
|
CXPPMM ds 1 ; $07 xx00 0000 P0-P1 M0-M1
|
|
INPT0 ds 1 ; $08 x000 0000 Read Pot Port 0
|
|
INPT1 ds 1 ; $09 x000 0000 Read Pot Port 1
|
|
INPT2 ds 1 ; $0A x000 0000 Read Pot Port 2
|
|
INPT3 ds 1 ; $0B x000 0000 Read Pot Port 3
|
|
INPT4 ds 1 ; $0C x000 0000 Read Input (Trigger) 0
|
|
INPT5 ds 1 ; $0D x000 0000 Read Input (Trigger) 1
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
SEG.U RIOT
|
|
ORG $280
|
|
|
|
; RIOT MEMORY MAP
|
|
|
|
SWCHA ds 1 ; $280 Port A data register for joysticks:
|
|
; Bits 4-7 for player 1. Bits 0-3 for player 2.
|
|
|
|
SWACNT ds 1 ; $281 Port A data direction register (DDR)
|
|
SWCHB ds 1 ; $282 Port B data (console switches)
|
|
SWBCNT ds 1 ; $283 Port B DDR
|
|
INTIM ds 1 ; $284 Timer output
|
|
|
|
TIMINT ds 1 ; $285
|
|
|
|
; Unused/undefined registers ($285-$294)
|
|
|
|
ds 1 ; $286
|
|
ds 1 ; $287
|
|
ds 1 ; $288
|
|
ds 1 ; $289
|
|
ds 1 ; $28A
|
|
ds 1 ; $28B
|
|
ds 1 ; $28C
|
|
ds 1 ; $28D
|
|
ds 1 ; $28E
|
|
ds 1 ; $28F
|
|
ds 1 ; $290
|
|
ds 1 ; $291
|
|
ds 1 ; $292
|
|
ds 1 ; $293
|
|
|
|
TIM1T ds 1 ; $294 set 1 clock interval
|
|
TIM8T ds 1 ; $295 set 8 clock interval
|
|
TIM64T ds 1 ; $296 set 64 clock interval
|
|
T1024T ds 1 ; $297 set 1024 clock interval
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; The following required for back-compatibility with code which does not use
|
|
; segments.
|
|
|
|
SEG
|
|
|
|
; EOF
|
|
; this file is screwed, I accidentally deleted the comments. Restore with version in .99b zip file.
|
|
superchipheader.asm
|
|
bB.asm
|
|
std_kernel.asm
|
|
startup.asm
|
|
pf_drawing.asm
|
|
pf_scrolling.asm
|
|
std_routines.asm
|
|
std_overscan.asm
|
|
bB2.asm
|
|
score_graphics.asm
|
|
banksw.asm
|
|
2600basicfooter.asm
|
|
; Compute mul1*mul2+acc -> acc:mul1 [mul2 is unchanged]
|
|
; Routine courtesy of John Payson (AtariAge member supercat)
|
|
|
|
; x and a contain multiplicands, result in a, temp1 contains any overflow
|
|
|
|
mul16
|
|
sty temp1
|
|
sta temp2
|
|
ldx #8
|
|
dec temp2
|
|
loopmul
|
|
lsr
|
|
ror temp1
|
|
bcc noaddmul
|
|
adc temp2
|
|
noaddmul
|
|
dex
|
|
bne loopmul
|
|
RETURN
|
|
|
|
; div int/int
|
|
; numerator in A, denom in temp1
|
|
; returns with quotient in A, remainder in temp1
|
|
|
|
div16
|
|
sty temp1
|
|
ldx #8
|
|
loopdiv
|
|
cmp temp1
|
|
bcc toosmalldiv
|
|
sbc temp1 ; Note: Carry is, and will remain, set.
|
|
rol temp2
|
|
rol
|
|
dex
|
|
bne loopdiv
|
|
beq donediv
|
|
toosmalldiv
|
|
rol temp2
|
|
rol
|
|
dex
|
|
bne loopdiv
|
|
donediv
|
|
sta temp1
|
|
lda temp2
|
|
RETURN
|
|
drawscreen
|
|
ifconst debugscore
|
|
ldx #14
|
|
lda INTIM ; display # cycles left in the score
|
|
|
|
ifconst mincycles
|
|
lda mincycles
|
|
cmp INTIM
|
|
lda mincycles
|
|
bcc nochange
|
|
lda INTIM
|
|
sta mincycles
|
|
nochange
|
|
endif
|
|
|
|
; cmp #$2B
|
|
; bcs no_cycles_left
|
|
bmi cycles_left
|
|
ldx #64
|
|
eor #$ff ;make negative
|
|
cycles_left
|
|
stx scorecolor
|
|
and #$7f ; clear sign bit
|
|
tax
|
|
lda scorebcd,x
|
|
sta score+2
|
|
lda scorebcd1,x
|
|
sta score+1
|
|
jmp done_debugscore
|
|
scorebcd
|
|
.byte $00, $64, $28, $92, $56, $20, $84, $48, $12, $76, $40
|
|
.byte $04, $68, $32, $96, $60, $24, $88, $52, $16, $80, $44
|
|
.byte $08, $72, $36, $00, $64, $28, $92, $56, $20, $84, $48
|
|
.byte $12, $76, $40, $04, $68, $32, $96, $60, $24, $88
|
|
scorebcd1
|
|
.byte 0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6
|
|
.byte 7, 7, 8, 8, 9, $10, $10, $11, $12, $12, $13
|
|
.byte $14, $14, $15, $16, $16, $17, $17, $18, $19, $19, $20
|
|
.byte $21, $21, $22, $23, $23, $24, $24, $25, $26, $26
|
|
done_debugscore
|
|
endif
|
|
|
|
ifconst debugcycles
|
|
lda INTIM ; if we go over, it mucks up the background color
|
|
; cmp #$2B
|
|
; BCC overscan
|
|
bmi overscan
|
|
sta COLUBK
|
|
bcs doneoverscan
|
|
endif
|
|
|
|
|
|
overscan
|
|
lda INTIM ;wait for sync
|
|
bmi overscan
|
|
doneoverscan
|
|
;do VSYNC
|
|
lda #2
|
|
sta WSYNC
|
|
sta VSYNC
|
|
STA WSYNC
|
|
STA WSYNC
|
|
LDA #0
|
|
STA WSYNC
|
|
STA VSYNC
|
|
sta VBLANK
|
|
ifnconst overscan_time
|
|
lda #37+128
|
|
else
|
|
lda #overscan_time+128
|
|
endif
|
|
sta TIM64T
|
|
|
|
ifconst legacy
|
|
if legacy < 100
|
|
ldx #4
|
|
adjustloop
|
|
lda player0x,x
|
|
sec
|
|
sbc #14 ;?
|
|
sta player0x,x
|
|
dex
|
|
bpl adjustloop
|
|
endif
|
|
endif
|
|
if (<*)>$F0
|
|
align 256, $EA
|
|
endif
|
|
sta WSYNC
|
|
ldx #4
|
|
SLEEP 3
|
|
HorPosLoop ; 5
|
|
lda player0x,X ;+4 9
|
|
sec ;+2 11
|
|
DivideLoop
|
|
sbc #15
|
|
bcs DivideLoop;+4 15
|
|
sta temp1,X ;+4 19
|
|
sta RESP0,X ;+4 23
|
|
sta WSYNC
|
|
dex
|
|
bpl HorPosLoop;+5 5
|
|
; 4
|
|
|
|
ldx #4
|
|
ldy temp1,X
|
|
lda repostable-256,Y
|
|
sta HMP0,X ;+14 18
|
|
|
|
dex
|
|
ldy temp1,X
|
|
lda repostable-256,Y
|
|
sta HMP0,X ;+14 32
|
|
|
|
dex
|
|
ldy temp1,X
|
|
lda repostable-256,Y
|
|
sta HMP0,X ;+14 46
|
|
|
|
dex
|
|
ldy temp1,X
|
|
lda repostable-256,Y
|
|
sta HMP0,X ;+14 60
|
|
|
|
dex
|
|
ldy temp1,X
|
|
lda repostable-256,Y
|
|
sta HMP0,X ;+14 74
|
|
|
|
sta WSYNC
|
|
|
|
sta HMOVE ;+3 3
|
|
|
|
|
|
ifconst legacy
|
|
if legacy < 100
|
|
ldx #4
|
|
adjustloop2
|
|
lda player0x,x
|
|
clc
|
|
adc #14 ;?
|
|
sta player0x,x
|
|
dex
|
|
bpl adjustloop2
|
|
endif
|
|
endif
|
|
|
|
|
|
|
|
|
|
;set score pointers
|
|
lax score+2
|
|
jsr scorepointerset
|
|
sty scorepointers+5
|
|
stx scorepointers+2
|
|
lax score+1
|
|
jsr scorepointerset
|
|
sty scorepointers+4
|
|
stx scorepointers+1
|
|
lax score
|
|
jsr scorepointerset
|
|
sty scorepointers+3
|
|
stx scorepointers
|
|
|
|
vblk
|
|
; run possible vblank bB code
|
|
ifconst vblank_bB_code
|
|
jsr vblank_bB_code
|
|
endif
|
|
vblk2
|
|
LDA INTIM
|
|
bmi vblk2
|
|
jmp kernel
|
|
|
|
|
|
.byte $80,$70,$60,$50,$40,$30,$20,$10,$00
|
|
.byte $F0,$E0,$D0,$C0,$B0,$A0,$90
|
|
repostable
|
|
|
|
scorepointerset
|
|
and #$0F
|
|
asl
|
|
asl
|
|
asl
|
|
adc #<scoretable
|
|
tay
|
|
txa
|
|
; and #$F0
|
|
; lsr
|
|
asr #$F0
|
|
adc #<scoretable
|
|
tax
|
|
rts
|
|
; This is a 2-line kernel!
|
|
kernel
|
|
sta WSYNC
|
|
lda #255
|
|
sta TIM64T
|
|
|
|
lda #1
|
|
sta VDELBL
|
|
sta VDELP0
|
|
ldx ballheight
|
|
inx
|
|
inx
|
|
stx temp4
|
|
lda player1y
|
|
sta temp3
|
|
|
|
ifconst shakescreen
|
|
jsr doshakescreen
|
|
else
|
|
ldx missile0height
|
|
inx
|
|
endif
|
|
|
|
inx
|
|
stx stack1
|
|
|
|
lda bally
|
|
sta stack2
|
|
|
|
lda player0y
|
|
ldx #0
|
|
sta WSYNC
|
|
stx GRP0
|
|
stx GRP1
|
|
stx PF1
|
|
stx PF2
|
|
stx CXCLR
|
|
ifconst readpaddle
|
|
stx paddle
|
|
else
|
|
sleep 3
|
|
endif
|
|
|
|
sta temp2,x
|
|
|
|
;store these so they can be retrieved later
|
|
ifnconst pfres
|
|
ldx #128-44
|
|
else
|
|
ldx #132-pfres*4
|
|
endif
|
|
|
|
inc player1y
|
|
|
|
lda missile0y
|
|
sta temp5
|
|
lda missile1y
|
|
sta temp6
|
|
|
|
lda playfieldpos
|
|
sta temp1
|
|
|
|
ifconst pfrowheight
|
|
lda #pfrowheight+2
|
|
else
|
|
ifnconst pfres
|
|
lda #10
|
|
else
|
|
lda #(96/pfres)+2 ; try to come close to the real size
|
|
endif
|
|
endif
|
|
|
|
clc
|
|
sbc playfieldpos
|
|
sta playfieldpos
|
|
jmp .startkernel
|
|
|
|
.skipDrawP0
|
|
lda #0
|
|
tay
|
|
jmp .continueP0
|
|
|
|
.skipDrawP1
|
|
lda #0
|
|
tay
|
|
jmp .continueP1
|
|
|
|
.kerloop ; enter at cycle 59??
|
|
|
|
continuekernel
|
|
sleep 2
|
|
continuekernel2
|
|
lda ballheight
|
|
|
|
ifconst pfres
|
|
ldy playfield+pfres*4-132,x
|
|
sty PF1 ;3
|
|
ldy playfield+pfres*4-131,x
|
|
sty PF2 ;3
|
|
ldy playfield+pfres*4-129,x
|
|
sty PF1 ; 3 too early?
|
|
ldy playfield+pfres*4-130,x
|
|
sty PF2 ;3
|
|
else
|
|
ldy playfield+44-128,x ;4
|
|
sty PF1 ;3
|
|
ldy playfield+45-128,x ;4
|
|
sty PF2 ;3
|
|
ldy playfield+47-128,x ;4
|
|
sty PF1 ; 3 too early?
|
|
ldy playfield+46-128,x;4
|
|
sty PF2 ;3
|
|
endif
|
|
|
|
dcp bally
|
|
rol
|
|
rol
|
|
; rol
|
|
; rol
|
|
goback
|
|
sta ENABL
|
|
.startkernel
|
|
lda player1height ;3
|
|
dcp player1y ;5
|
|
bcc .skipDrawP1 ;2
|
|
ldy player1y ;3
|
|
lda (player1pointer),y ;5; player0pointer must be selected carefully by the compiler
|
|
; so it doesn't cross a page boundary!
|
|
|
|
.continueP1
|
|
sta GRP1 ;3
|
|
|
|
ifnconst player1colors
|
|
lda missile1height ;3
|
|
dcp missile1y ;5
|
|
rol;2
|
|
rol;2
|
|
sta ENAM1 ;3
|
|
else
|
|
lda (player1color),y
|
|
sta COLUP1
|
|
ifnconst playercolors
|
|
sleep 7
|
|
else
|
|
lda.w player0colorstore
|
|
sta COLUP0
|
|
endif
|
|
endif
|
|
|
|
ifconst pfres
|
|
lda playfield+pfres*4-132,x
|
|
sta PF1 ;3
|
|
lda playfield+pfres*4-131,x
|
|
sta PF2 ;3
|
|
lda playfield+pfres*4-129,x
|
|
sta PF1 ; 3 too early?
|
|
lda playfield+pfres*4-130,x
|
|
sta PF2 ;3
|
|
else
|
|
lda playfield+44-128,x ;4
|
|
sta PF1 ;3
|
|
lda playfield+45-128,x ;4
|
|
sta PF2 ;3
|
|
lda playfield+47-128,x ;4
|
|
sta PF1 ; 3 too early?
|
|
lda playfield+46-128,x;4
|
|
sta PF2 ;3
|
|
endif
|
|
; sleep 3
|
|
|
|
lda player0height
|
|
dcp player0y
|
|
bcc .skipDrawP0
|
|
ldy player0y
|
|
lda (player0pointer),y
|
|
.continueP0
|
|
sta GRP0
|
|
|
|
ifnconst no_blank_lines
|
|
ifnconst playercolors
|
|
lda missile0height ;3
|
|
dcp missile0y ;5
|
|
sbc stack1
|
|
sta ENAM0 ;3
|
|
else
|
|
lda (player0color),y
|
|
sta player0colorstore
|
|
sleep 6
|
|
endif
|
|
dec temp1
|
|
bne continuekernel
|
|
else
|
|
dec temp1
|
|
beq altkernel2
|
|
ifconst readpaddle
|
|
ldy currentpaddle
|
|
lda INPT0,y
|
|
bpl noreadpaddle
|
|
inc paddle
|
|
jmp continuekernel2
|
|
noreadpaddle
|
|
sleep 2
|
|
jmp continuekernel
|
|
else
|
|
ifnconst playercolors
|
|
ifconst PFcolors
|
|
txa
|
|
tay
|
|
lda (pfcolortable),y
|
|
ifnconst backgroundchange
|
|
sta COLUPF
|
|
else
|
|
sta COLUBK
|
|
endif
|
|
jmp continuekernel
|
|
else
|
|
sleep 12
|
|
endif
|
|
else
|
|
lda (player0color),y
|
|
sta player0colorstore
|
|
sleep 4
|
|
endif
|
|
jmp continuekernel
|
|
endif
|
|
altkernel2
|
|
txa
|
|
sbx #252
|
|
bmi lastkernelline
|
|
ifconst pfrowheight
|
|
lda #pfrowheight
|
|
else
|
|
ifnconst pfres
|
|
lda #8
|
|
else
|
|
lda #(96/pfres) ; try to come close to the real size
|
|
endif
|
|
endif
|
|
sta temp1
|
|
jmp continuekernel
|
|
endif
|
|
|
|
altkernel
|
|
|
|
ifconst PFmaskvalue
|
|
lda #PFmaskvalue
|
|
else
|
|
lda #0
|
|
endif
|
|
sta PF1
|
|
sta PF2
|
|
|
|
|
|
;sleep 3
|
|
|
|
;28 cycles to fix things
|
|
;minus 11=17
|
|
|
|
; lax temp4
|
|
; clc
|
|
txa
|
|
sbx #252
|
|
|
|
bmi lastkernelline
|
|
|
|
ifconst PFcolorandheight
|
|
ldy playfieldcolorandheight-87,x
|
|
ifnconst backgroundchange
|
|
sty COLUPF
|
|
else
|
|
sty COLUBK
|
|
endif
|
|
lda playfieldcolorandheight-88,x
|
|
sta.w temp1
|
|
endif
|
|
ifconst PFheights
|
|
lsr
|
|
lsr
|
|
tay
|
|
lda (pfheighttable),y
|
|
sta.w temp1
|
|
endif
|
|
ifconst PFcolors
|
|
tay
|
|
lda (pfcolortable),y
|
|
ifnconst backgroundchange
|
|
sta COLUPF
|
|
else
|
|
sta COLUBK
|
|
endif
|
|
ifconst pfrowheight
|
|
lda #pfrowheight
|
|
else
|
|
ifnconst pfres
|
|
lda #8
|
|
else
|
|
lda #(96/pfres) ; try to come close to the real size
|
|
endif
|
|
endif
|
|
sta temp1
|
|
endif
|
|
ifnconst PFcolorandheight
|
|
ifnconst PFcolors
|
|
ifnconst PFheights
|
|
ifnconst no_blank_lines
|
|
; read paddle 0
|
|
; lo-res paddle read
|
|
; bit INPT0
|
|
; bmi paddleskipread
|
|
; inc paddle0
|
|
;donepaddleskip
|
|
sleep 10
|
|
ifconst pfrowheight
|
|
lda #pfrowheight
|
|
else
|
|
ifnconst pfres
|
|
lda #8
|
|
else
|
|
lda #(96/pfres) ; try to come close to the real size
|
|
endif
|
|
endif
|
|
sta temp1
|
|
endif
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
|
|
lda ballheight
|
|
dcp bally
|
|
sbc temp4
|
|
|
|
|
|
jmp goback
|
|
|
|
|
|
ifnconst no_blank_lines
|
|
lastkernelline
|
|
ifnconst PFcolors
|
|
sleep 10
|
|
else
|
|
ldy #124
|
|
lda (pfcolortable),y
|
|
sta COLUPF
|
|
endif
|
|
|
|
ifconst PFheights
|
|
ldx #1
|
|
sleep 4
|
|
else
|
|
ldx playfieldpos
|
|
sleep 3
|
|
endif
|
|
|
|
jmp enterlastkernel
|
|
|
|
else
|
|
lastkernelline
|
|
|
|
ifconst PFheights
|
|
ldx #1
|
|
sleep 5
|
|
else
|
|
ldx playfieldpos
|
|
sleep 4
|
|
endif
|
|
|
|
cpx #1
|
|
bne .enterfromNBL
|
|
jmp no_blank_lines_bailout
|
|
endif
|
|
|
|
if ((<*)>$d5)
|
|
align 256
|
|
endif
|
|
; this is a kludge to prevent page wrapping - fix!!!
|
|
|
|
.skipDrawlastP1
|
|
sleep 2
|
|
lda #0
|
|
jmp .continuelastP1
|
|
|
|
.endkerloop ; enter at cycle 59??
|
|
|
|
nop
|
|
|
|
.enterfromNBL
|
|
ifconst pfres
|
|
ldy.w playfield+pfres*4-4
|
|
sty PF1 ;3
|
|
ldy.w playfield+pfres*4-3
|
|
sty PF2 ;3
|
|
ldy.w playfield+pfres*4-1
|
|
sty PF1 ; possibly too early?
|
|
ldy.w playfield+pfres*4-2
|
|
sty PF2 ;3
|
|
else
|
|
ldy.w playfield+44
|
|
sty PF1 ;3
|
|
ldy.w playfield+45
|
|
sty PF2 ;3
|
|
ldy.w playfield+47
|
|
sty PF1 ; possibly too early?
|
|
ldy.w playfield+46
|
|
sty PF2 ;3
|
|
endif
|
|
|
|
enterlastkernel
|
|
lda ballheight
|
|
|
|
; tya
|
|
dcp bally
|
|
; sleep 4
|
|
|
|
; sbc stack3
|
|
rol
|
|
rol
|
|
sta ENABL
|
|
|
|
lda player1height ;3
|
|
dcp player1y ;5
|
|
bcc .skipDrawlastP1
|
|
ldy player1y ;3
|
|
lda (player1pointer),y ;5; player0pointer must be selected carefully by the compiler
|
|
; so it doesn't cross a page boundary!
|
|
|
|
.continuelastP1
|
|
sta GRP1 ;3
|
|
|
|
ifnconst player1colors
|
|
lda missile1height ;3
|
|
dcp missile1y ;5
|
|
else
|
|
lda (player1color),y
|
|
sta COLUP1
|
|
endif
|
|
|
|
dex
|
|
;dec temp4 ; might try putting this above PF writes
|
|
beq endkernel
|
|
|
|
|
|
ifconst pfres
|
|
ldy.w playfield+pfres*4-4
|
|
sty PF1 ;3
|
|
ldy.w playfield+pfres*4-3
|
|
sty PF2 ;3
|
|
ldy.w playfield+pfres*4-1
|
|
sty PF1 ; possibly too early?
|
|
ldy.w playfield+pfres*4-2
|
|
sty PF2 ;3
|
|
else
|
|
ldy.w playfield+44
|
|
sty PF1 ;3
|
|
ldy.w playfield+45
|
|
sty PF2 ;3
|
|
ldy.w playfield+47
|
|
sty PF1 ; possibly too early?
|
|
ldy.w playfield+46
|
|
sty PF2 ;3
|
|
endif
|
|
|
|
ifnconst player1colors
|
|
rol;2
|
|
rol;2
|
|
sta ENAM1 ;3
|
|
else
|
|
ifnconst playercolors
|
|
sleep 7
|
|
else
|
|
lda.w player0colorstore
|
|
sta COLUP0
|
|
endif
|
|
endif
|
|
|
|
lda.w player0height
|
|
dcp player0y
|
|
bcc .skipDrawlastP0
|
|
ldy player0y
|
|
lda (player0pointer),y
|
|
.continuelastP0
|
|
sta GRP0
|
|
|
|
|
|
|
|
ifnconst no_blank_lines
|
|
lda missile0height ;3
|
|
dcp missile0y ;5
|
|
sbc stack1
|
|
sta ENAM0 ;3
|
|
jmp .endkerloop
|
|
else
|
|
ifconst readpaddle
|
|
ldy currentpaddle
|
|
lda INPT0,y
|
|
bpl noreadpaddle2
|
|
inc paddle
|
|
jmp .endkerloop
|
|
noreadpaddle2
|
|
sleep 4
|
|
jmp .endkerloop
|
|
else ; no_blank_lines and no paddle reading
|
|
sleep 14
|
|
jmp .endkerloop
|
|
endif
|
|
endif
|
|
|
|
|
|
; ifconst donepaddleskip
|
|
;paddleskipread
|
|
; this is kind of lame, since it requires 4 cycles from a page boundary crossing
|
|
; plus we get a lo-res paddle read
|
|
; bmi donepaddleskip
|
|
; endif
|
|
|
|
.skipDrawlastP0
|
|
sleep 2
|
|
lda #0
|
|
jmp .continuelastP0
|
|
|
|
ifconst no_blank_lines
|
|
no_blank_lines_bailout
|
|
ldx #0
|
|
endif
|
|
|
|
endkernel
|
|
; 6 digit score routine
|
|
stx PF1
|
|
stx PF2
|
|
stx PF0
|
|
clc
|
|
|
|
ifconst pfrowheight
|
|
lda #pfrowheight+2
|
|
else
|
|
ifnconst pfres
|
|
lda #10
|
|
else
|
|
lda #(96/pfres)+2 ; try to come close to the real size
|
|
endif
|
|
endif
|
|
|
|
sbc playfieldpos
|
|
sta playfieldpos
|
|
txa
|
|
|
|
ifconst shakescreen
|
|
bit shakescreen
|
|
bmi noshakescreen2
|
|
ldx #$3D
|
|
noshakescreen2
|
|
endif
|
|
|
|
sta WSYNC,x
|
|
|
|
; STA WSYNC ;first one, need one more
|
|
sta REFP0
|
|
sta REFP1
|
|
STA GRP0
|
|
STA GRP1
|
|
; STA PF1
|
|
; STA PF2
|
|
sta HMCLR
|
|
sta ENAM0
|
|
sta ENAM1
|
|
sta ENABL
|
|
|
|
lda temp2 ;restore variables that were obliterated by kernel
|
|
sta player0y
|
|
lda temp3
|
|
sta player1y
|
|
ifnconst player1colors
|
|
lda temp6
|
|
sta missile1y
|
|
endif
|
|
ifnconst playercolors
|
|
ifnconst readpaddle
|
|
lda temp5
|
|
sta missile0y
|
|
endif
|
|
endif
|
|
lda stack2
|
|
sta bally
|
|
|
|
ifconst no_blank_lines
|
|
sta WSYNC
|
|
endif
|
|
|
|
lda INTIM
|
|
clc
|
|
ifnconst vblank_time
|
|
adc #43+12+87
|
|
else
|
|
adc #vblank_time+12+87
|
|
endif
|
|
; sta WSYNC
|
|
sta TIM64T
|
|
|
|
ifconst minikernel
|
|
jsr minikernel
|
|
endif
|
|
|
|
; now reassign temp vars for score pointers
|
|
|
|
; score pointers contain:
|
|
; score1-5: lo1,lo2,lo3,lo4,lo5,lo6
|
|
; swap lo2->temp1
|
|
; swap lo4->temp3
|
|
; swap lo6->temp5
|
|
ifnconst noscore
|
|
lda scorepointers+1
|
|
; ldy temp1
|
|
sta temp1
|
|
; sty scorepointers+1
|
|
|
|
lda scorepointers+3
|
|
; ldy temp3
|
|
sta temp3
|
|
; sty scorepointers+3
|
|
|
|
|
|
sta HMCLR
|
|
tsx
|
|
stx stack1
|
|
ldx #$10
|
|
stx HMP0
|
|
|
|
sta WSYNC
|
|
ldx #0
|
|
STx GRP0
|
|
STx GRP1 ; seems to be needed because of vdel
|
|
|
|
lda scorepointers+5
|
|
; ldy temp5
|
|
sta temp5,x
|
|
; sty scorepointers+5
|
|
lda #>scoretable
|
|
sta scorepointers+1
|
|
sta scorepointers+3
|
|
sta scorepointers+5,x
|
|
sta temp2,x
|
|
sta temp4,x
|
|
sta temp6,x
|
|
LDY #7
|
|
STA RESP0
|
|
STA RESP1
|
|
|
|
|
|
LDA #$03
|
|
STA NUSIZ0
|
|
STA NUSIZ1,x
|
|
STA VDELP0
|
|
STA VDELP1
|
|
LDA #$20
|
|
STA HMP1
|
|
LDA scorecolor
|
|
; STA HMCLR
|
|
; STA WSYNC; second one
|
|
STA HMOVE ; cycle 73 ?
|
|
|
|
STA COLUP0
|
|
STA COLUP1
|
|
lda (scorepointers),y
|
|
sta GRP0
|
|
ifconst pfscore
|
|
lda pfscorecolor
|
|
sta COLUPF
|
|
endif
|
|
lda (scorepointers+8),y
|
|
sta WSYNC
|
|
sleep 2
|
|
jmp beginscore
|
|
|
|
if ((<*)>$d4)
|
|
align 256 ; kludge that potentially wastes space! should be fixed!
|
|
endif
|
|
|
|
loop2
|
|
lda (scorepointers),y ;+5 68 204
|
|
sta GRP0 ;+3 71 213 D1 -- -- --
|
|
ifconst pfscore
|
|
lda.w pfscore1
|
|
sta PF1
|
|
else
|
|
sleep 7
|
|
endif
|
|
; cycle 0
|
|
lda (scorepointers+$8),y ;+5 5 15
|
|
beginscore
|
|
sta GRP1 ;+3 8 24 D1 D1 D2 --
|
|
lda (scorepointers+$6),y ;+5 13 39
|
|
sta GRP0 ;+3 16 48 D3 D1 D2 D2
|
|
lax (scorepointers+$2),y ;+5 29 87
|
|
txs
|
|
lax (scorepointers+$4),y ;+5 36 108
|
|
sleep 3
|
|
|
|
ifconst pfscore
|
|
lda pfscore2
|
|
sta PF1
|
|
else
|
|
sleep 6
|
|
endif
|
|
|
|
lda (scorepointers+$A),y ;+5 21 63
|
|
stx GRP1 ;+3 44 132 D3 D3 D4 D2!
|
|
tsx
|
|
stx GRP0 ;+3 47 141 D5 D3! D4 D4
|
|
sta GRP1 ;+3 50 150 D5 D5 D6 D4!
|
|
sty GRP0 ;+3 53 159 D4* D5! D6 D6
|
|
dey
|
|
bpl loop2 ;+2 60 180
|
|
|
|
ldx stack1
|
|
txs
|
|
; lda scorepointers+1
|
|
ldy temp1
|
|
; sta temp1
|
|
sty scorepointers+1
|
|
|
|
LDA #0
|
|
sta PF1
|
|
STA GRP0
|
|
STA GRP1
|
|
STA VDELP0
|
|
STA VDELP1;do we need these
|
|
STA NUSIZ0
|
|
STA NUSIZ1
|
|
|
|
; lda scorepointers+3
|
|
ldy temp3
|
|
; sta temp3
|
|
sty scorepointers+3
|
|
|
|
; lda scorepointers+5
|
|
ldy temp5
|
|
; sta temp5
|
|
sty scorepointers+5
|
|
endif ;noscore
|
|
LDA #%11000010
|
|
sta WSYNC
|
|
STA VBLANK
|
|
RETURN
|
|
|
|
ifconst shakescreen
|
|
doshakescreen
|
|
bit shakescreen
|
|
bmi noshakescreen
|
|
sta WSYNC
|
|
noshakescreen
|
|
ldx missile0height
|
|
inx
|
|
rts
|
|
endif
|
|
|
|
processor 6502
|
|
include "vcs.h"
|
|
include "macro.h"
|
|
include "2600basic_variable_redefs.h"
|
|
|
|
player0x = $80
|
|
player1x = $81
|
|
missile0x = $82
|
|
missile1x = $83
|
|
ballx = $84
|
|
|
|
objecty = $85
|
|
player0y = $85
|
|
player1y = $86
|
|
missile1height = $87
|
|
missile1y = $88
|
|
bally = $89
|
|
|
|
player1color = $87 ; replaces missile 1
|
|
|
|
player0pointer = $8A ;uses $8A-$8B
|
|
player0pointerlo = $8A
|
|
player0pointerhi = $8B
|
|
player1pointer = $8C ; $8C-$8D
|
|
player1pointerlo = $8C
|
|
player1pointerhi = $8D
|
|
|
|
player0height = $8E
|
|
player1height = $8F
|
|
missile0height = $90
|
|
missile0y = $91
|
|
ballheight = $92
|
|
|
|
currentpaddle = $90 ; replaces missile 0 (and can't be used with playercolor)
|
|
paddle = $91 ; replaces missile 0
|
|
player0colorstore = $82 ; replaces missile 0
|
|
player0color = $90 ; replaces missile 0
|
|
|
|
score = $93 ; $93-$95
|
|
scorepointers = $96 ; $96-$9B = 6 bytes
|
|
temp1 = $9C ;used by kernel. can be used in program too, but
|
|
temp2 = $9D ;are obliterated when drawscreen is called.
|
|
temp3 = $9E
|
|
temp4 = $9F
|
|
temp5 = $A0
|
|
temp6 = $A1
|
|
|
|
rand = $A2
|
|
scorecolor = $A3
|
|
|
|
var0 = $A4
|
|
var1 = $A5
|
|
var2 = $A6
|
|
var3 = $A7
|
|
var4 = $A8
|
|
var5 = $A9
|
|
var6 = $AA
|
|
var7 = $AB
|
|
var8 = $AC
|
|
var9 = $AD
|
|
var10 = $AE
|
|
var11 = $AF
|
|
var12 = $B0
|
|
var13 = $B1
|
|
var14 = $B2
|
|
var15 = $B3
|
|
var16 = $B4
|
|
var17 = $B5
|
|
var18 = $B6
|
|
var19 = $B7
|
|
var20 = $B8
|
|
var21 = $B9
|
|
var22 = $BA
|
|
var23 = $BB
|
|
var24 = $BC
|
|
var25 = $BD
|
|
var26 = $BE
|
|
var27 = $BF
|
|
var28 = $C0
|
|
var29 = $C1
|
|
var30 = $C2
|
|
var31 = $C3
|
|
var32 = $C4
|
|
var33 = $C5
|
|
var34 = $C6
|
|
var35 = $C7
|
|
var36 = $C8
|
|
var37 = $C9
|
|
var38 = $CA
|
|
var39 = $CB
|
|
var40 = $CC
|
|
var41 = $CD
|
|
var42 = $CE
|
|
var43 = $CF
|
|
var44 = $D0
|
|
var45 = $D1
|
|
var46 = $D2
|
|
var47 = $D3
|
|
|
|
temp7 = $D4 ; This is used to aid in bankswitching
|
|
|
|
playfieldpos = $D5
|
|
|
|
A = $d6
|
|
a = $d6
|
|
B = $d7
|
|
b = $d7
|
|
C = $d8
|
|
c = $d8
|
|
D = $d9
|
|
d = $d9
|
|
E = $da
|
|
e = $da
|
|
F = $db
|
|
f = $db
|
|
G = $dc
|
|
g = $dc
|
|
H = $dd
|
|
h = $dd
|
|
I = $de
|
|
i = $de
|
|
J = $df
|
|
j = $df
|
|
K = $e0
|
|
k = $e0
|
|
L = $e1
|
|
l = $e1
|
|
M = $e2
|
|
m = $e2
|
|
N = $e3
|
|
n = $e3
|
|
O = $e4
|
|
o = $e4
|
|
P = $e5
|
|
p = $e5
|
|
Q = $e6
|
|
q = $e6
|
|
R = $e7
|
|
r = $e7
|
|
S = $e8
|
|
s = $e8
|
|
T = $e9
|
|
t = $e9
|
|
U = $ea
|
|
u = $ea
|
|
V = $eb
|
|
v = $eb
|
|
W = $ec
|
|
w = $ec
|
|
X = $ed
|
|
x = $ed
|
|
Y = $ee
|
|
y = $ee
|
|
Z = $ef
|
|
z = $ef
|
|
|
|
; available for other uses, or if unused, provide more stack space
|
|
|
|
aux1 = $f0
|
|
aux2 = $f1
|
|
aux3 = $f2
|
|
aux4 = $f3
|
|
aux5 = $f4
|
|
aux6 = $f5
|
|
|
|
; playfield color/height pointers
|
|
pfcolortable = $f0 ; and $d5
|
|
pfheighttable = $f0 ; and $d5
|
|
; the above pointers are the same because if color and height are both used together,
|
|
; they must used absolute indexed and cannot use pointers
|
|
|
|
lifepointer = $f2 ; pointer to "lives" shape
|
|
; upper 3 bits of $f2 contain the number of lives
|
|
lifecolor = $f4
|
|
lives = $f3 ; # lives >> 5
|
|
statusbarlength = $f5 ; only uses upper 5 bits; other bits free
|
|
|
|
pfscore1 = $f2 ; optional playfield bytes in score
|
|
pfscore2 = $f3
|
|
pfscorecolor = $f4
|
|
|
|
stack1 = $f6
|
|
stack2 = $f7
|
|
stack3 = $f8
|
|
stack4 = $f9
|
|
; the stack bytes above may be used in the kernel
|
|
; stack = F6-F7, F8-F9, FA-FB, FC-FD, FE-FF
|
|
|
|
MAC RETURN ; auto-return from either a regular or bankswitched module
|
|
ifnconst bankswitch
|
|
rts
|
|
else
|
|
jmp BS_return
|
|
endif
|
|
ENDM
|
|
|
|
ifconst superchip
|
|
playfieldbase = $10D0
|
|
else
|
|
playfieldbase = $A4
|
|
endif
|
|
|
|
; define playfield start based on height
|
|
ifnconst pfres
|
|
playfield = playfieldbase
|
|
else
|
|
playfield = playfieldbase-(pfres-12)*4
|
|
endif
|
|
|
|
; every bank has this stuff at the same place
|
|
; this code can switch to/from any bank at any entry point
|
|
; and can preserve register values
|
|
; note: lines not starting with a space are not placed in all banks
|
|
;
|
|
; line below tells the compiler how long this is - do not remove
|
|
;size=32
|
|
begin_bscode
|
|
ldx #$ff
|
|
txs
|
|
lda #>(start-1)
|
|
pha
|
|
lda #<(start-1)
|
|
pha
|
|
BS_return
|
|
pha
|
|
txa
|
|
pha
|
|
tsx
|
|
lda 4,x ; get high byte of return address
|
|
rol
|
|
rol
|
|
rol
|
|
rol
|
|
and #bs_mask ;1 3 or 7 for F8/F6/F4
|
|
tax
|
|
inx
|
|
BS_jsr
|
|
lda bankswitch_hotspot-1,x
|
|
pla
|
|
tax
|
|
pla
|
|
rts
|
|
if ((* & $1FFF) > ((bankswitch_hotspot & $1FFF) - 1))
|
|
echo "WARNING: size parameter in banksw.asm too small - the program probably will not work."
|
|
echo "Change to",[(*-begin_bscode+1)&$FF]d,"and try again."
|
|
endif
|
|
processor 6502
|
|
include "vcs.h"
|
|
include "macro.h"
|
|
include "multisprite.h"
|
|
include "2600basic_variable_redefs.h"
|
|
ifconst bankswitch
|
|
if bankswitch == 8
|
|
ORG $1000
|
|
RORG $D000
|
|
endif
|
|
if bankswitch == 16
|
|
ORG $1000
|
|
RORG $9000
|
|
endif
|
|
if bankswitch == 32
|
|
ORG $1000
|
|
RORG $1000
|
|
endif
|
|
else
|
|
ORG $F000
|
|
endif
|
|
; y and a contain multiplicands, result in a
|
|
|
|
mul8
|
|
sty temp1
|
|
sta temp2
|
|
lda #0
|
|
reptmul8
|
|
lsr temp2
|
|
bcc skipmul8
|
|
clc
|
|
adc temp1
|
|
;bcs donemul8 might save cycles?
|
|
skipmul8
|
|
;beq donemul8 might save cycles?
|
|
asl temp1
|
|
bne reptmul8
|
|
donemul8
|
|
RETURN
|
|
|
|
div8
|
|
; a=numerator y=denominator, result in a
|
|
cpy #2
|
|
bcc div8end+1;div by 0 = bad, div by 1=no calc needed, so bail out
|
|
sty temp1
|
|
ldy #$ff
|
|
div8loop
|
|
sbc temp1
|
|
iny
|
|
bcs div8loop
|
|
div8end
|
|
tya
|
|
; result in a
|
|
RETURN
|
|
minikernel ; display up to 6 lives on screen
|
|
sta WSYNC
|
|
ldx #$20
|
|
stx HMP1
|
|
stx VDELP0
|
|
lda lives
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta RESP0
|
|
sta RESP1
|
|
stx VDELP1
|
|
tax
|
|
lda lifenusiz0table,x
|
|
sta NUSIZ0
|
|
lda lifenusiz1table,x
|
|
sta NUSIZ1
|
|
lda lifecolor
|
|
sta COLUP0
|
|
sta COLUP1
|
|
lda #$10
|
|
sta HMP0
|
|
|
|
lda statusbarlength
|
|
lsr
|
|
lsr
|
|
lsr ; 0-31
|
|
; 3 cases: 0-7, 8-15, 16-24
|
|
; if 0-7, temp1=val, temp2=0, temp3=0
|
|
; if 8-15, temp1=255, temp2=val (rev), temp3=0
|
|
; if 16-23, temp1=255, temp2=255, temp3=val
|
|
tay
|
|
|
|
sta HMOVE ;cycle 74?
|
|
|
|
ifconst statusbarcolor
|
|
; only write COLUPF if color variable exists, otherwise use existing PF color
|
|
lda statusbarcolor
|
|
sta COLUPF
|
|
endif
|
|
|
|
cmp #8
|
|
bcc zero_7
|
|
cmp #16
|
|
bcc eight_15
|
|
lda #255
|
|
sta temp1
|
|
sta temp2
|
|
lda statustable-16,y
|
|
sta temp3
|
|
lda statustable,y
|
|
sta temp4
|
|
jmp startlifedisplay
|
|
|
|
zero_7
|
|
lda #0
|
|
sta temp4
|
|
sta temp3
|
|
sta temp2
|
|
lda statustable,y
|
|
sta temp1
|
|
jmp startlifedisplay
|
|
eight_15
|
|
lda #255
|
|
sta temp1
|
|
lda #0
|
|
sta temp4
|
|
sta temp3
|
|
lda statustable+16,y
|
|
sta temp2
|
|
startlifedisplay
|
|
ldy #7
|
|
lifeloop
|
|
sta WSYNC
|
|
stx PF0
|
|
lda (lifepointer),y
|
|
cpx #0
|
|
bne onelife
|
|
.byte $0C
|
|
onelife
|
|
sta GRP0
|
|
|
|
cpx #2
|
|
bcs nolives
|
|
.byte $0C
|
|
nolives
|
|
sta GRP1
|
|
lda temp4
|
|
sta PF0
|
|
lda temp1
|
|
sta PF2
|
|
lda temp3
|
|
sta PF1
|
|
lda temp2
|
|
sta PF2 ;cycle 48!
|
|
sleep 14
|
|
lda #0
|
|
dey
|
|
sta PF1
|
|
bpl lifeloop
|
|
sta WSYNC
|
|
iny
|
|
sty PF0
|
|
sty PF2
|
|
sty PF1
|
|
sty GRP0
|
|
sty GRP1
|
|
rts
|
|
|
|
if (<*) > $F5
|
|
align 256
|
|
endif
|
|
lifenusiz1table
|
|
.byte 0
|
|
lifenusiz0table
|
|
.byte 0,0,0,1,1,3,3,3
|
|
|
|
statustable
|
|
;0-7 and 16+
|
|
.byte %00000000
|
|
.byte %00000001
|
|
.byte %00000011
|
|
.byte %00000111
|
|
.byte %00001111
|
|
.byte %00011111
|
|
.byte %00111111
|
|
.byte %01111111
|
|
.byte 255
|
|
.byte 255
|
|
.byte 255
|
|
.byte 255
|
|
.byte 255
|
|
.byte 255
|
|
.byte 255
|
|
.byte 255
|
|
; 8-15
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte 0
|
|
.byte %00000000
|
|
.byte %10000000
|
|
.byte %11000000
|
|
.byte %11100000
|
|
.byte %11110000
|
|
.byte %11111000
|
|
.byte %11111100
|
|
.byte %11111110
|
|
|
|
FineAdjustTableBegin
|
|
.byte %01100000 ;left 6
|
|
.byte %01010000
|
|
.byte %01000000
|
|
.byte %00110000
|
|
.byte %00100000
|
|
.byte %00010000
|
|
.byte %00000000 ;left 0
|
|
.byte %11110000
|
|
.byte %11100000
|
|
.byte %11010000
|
|
.byte %11000000
|
|
.byte %10110000
|
|
.byte %10100000
|
|
.byte %10010000
|
|
.byte %10000000 ;right 8
|
|
FineAdjustTableEnd = FineAdjustTableBegin - 241
|
|
|
|
PFStart
|
|
.byte 87,43,0,21,0,0,0,10
|
|
blank_pf
|
|
.byte 0,0,0,0,0,0,0,5
|
|
; .byte 43,21,0,10,0,0,0,5
|
|
ifconst screenheight
|
|
pfsub
|
|
.byte 8,4,2,2,1,0,0,1,0
|
|
endif
|
|
;--set initial P1 positions
|
|
multisprite_setup
|
|
lda #15
|
|
sta pfheight
|
|
|
|
ldx #4
|
|
; stx temp3
|
|
SetCopyHeight
|
|
; lda #76
|
|
; sta NewSpriteX,X
|
|
; lda CopyColorData,X
|
|
; sta NewCOLUP1,X
|
|
;lda SpriteHeightTable,X
|
|
; sta spriteheight,x
|
|
txa
|
|
sta SpriteGfxIndex,X
|
|
sta spritesort,X
|
|
dex
|
|
bpl SetCopyHeight
|
|
|
|
|
|
|
|
; since we can't turn off pf, point PF to zeros here
|
|
lda #>blank_pf
|
|
sta PF2pointer+1
|
|
sta PF1pointer+1
|
|
lda #<blank_pf
|
|
sta PF2pointer
|
|
sta PF1pointer
|
|
rts
|
|
|
|
drawscreen
|
|
ifconst debugscore
|
|
jsr debugcycles
|
|
endif
|
|
|
|
WaitForOverscanEnd
|
|
lda INTIM
|
|
bmi WaitForOverscanEnd
|
|
|
|
lda #2
|
|
sta WSYNC
|
|
sta VSYNC
|
|
sta WSYNC
|
|
sta WSYNC
|
|
lsr
|
|
sta VDELBL
|
|
sta VDELP0
|
|
sta WSYNC
|
|
sta VSYNC ;turn off VSYNC
|
|
ifconst overscan_time
|
|
lda #overscan_time+5+128
|
|
else
|
|
lda #42+128
|
|
endif
|
|
sta TIM64T
|
|
|
|
jsr setscorepointers
|
|
jsr SetupP1Subroutine
|
|
|
|
;-------------
|
|
|
|
|
|
|
|
|
|
|
|
;--position P0, M0, M1, BL
|
|
|
|
jsr PrePositionAllObjects
|
|
|
|
;--set up player 0 pointer
|
|
|
|
lda player0pointer ; player0: must be run every frame!
|
|
sec
|
|
sbc player0y
|
|
clc
|
|
adc player0height
|
|
sta player0pointer
|
|
|
|
lda player0y
|
|
sta P0Top
|
|
sec
|
|
sbc player0height
|
|
clc
|
|
adc #$80
|
|
sta P0Bottom
|
|
|
|
|
|
;--some final setup
|
|
|
|
ldx #4
|
|
lda #$80
|
|
cycle74_HMCLR
|
|
sta HMP0,X
|
|
dex
|
|
bpl cycle74_HMCLR
|
|
; sta HMCLR
|
|
|
|
|
|
lda #0
|
|
sta PF1
|
|
sta PF2
|
|
sta GRP0
|
|
sta GRP1
|
|
|
|
|
|
jsr KernelSetupSubroutine
|
|
|
|
; run possible vblank bB code
|
|
ifconst vblank_bB_code
|
|
jsr vblank_bB_code
|
|
endif
|
|
|
|
WaitForVblankEnd
|
|
lda INTIM
|
|
bmi WaitForVblankEnd
|
|
lda #0
|
|
sta WSYNC
|
|
sta VBLANK ;turn off VBLANK - it was turned on by overscan
|
|
sta CXCLR
|
|
|
|
|
|
jmp KernelRoutine
|
|
|
|
|
|
PositionASpriteSubroutine ;call this function with A == horizontal position (0-159)
|
|
;and X == the object to be positioned (0=P0, 1=P1, 2=M0, etc.)
|
|
;if you do not wish to write to P1 during this function, make
|
|
;sure Y==0 before you call it. This function will change Y, and A
|
|
;will be the value put into HMxx when returned.
|
|
;Call this function with at least 11 cycles left in the scanline
|
|
;(jsr + sec + sta WSYNC = 11); it will return 9 cycles
|
|
;into the second scanline
|
|
sec
|
|
sta WSYNC ;begin line 1
|
|
sta.w HMCLR ;+4 4
|
|
DivideBy15Loop
|
|
sbc #15
|
|
bcs DivideBy15Loop ;+4/5 8/13.../58
|
|
|
|
tay ;+2 10/15/...60
|
|
lda FineAdjustTableEnd,Y ;+5 15/20/...65
|
|
|
|
; 15
|
|
sta HMP0,X ;+4 19/24/...69
|
|
sta RESP0,X ;+4 23/28/33/38/43/48/53/58/63/68/73
|
|
sta WSYNC ;+3 0 begin line 2
|
|
sta HMOVE ;+3
|
|
rts ;+6 9
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
PrePositionAllObjects
|
|
|
|
ldx #4
|
|
lda ballx
|
|
jsr PositionASpriteSubroutine
|
|
|
|
dex
|
|
lda missile1x
|
|
jsr PositionASpriteSubroutine
|
|
|
|
dex
|
|
lda missile0x
|
|
jsr PositionASpriteSubroutine
|
|
|
|
dex
|
|
dex
|
|
lda player0x
|
|
jsr PositionASpriteSubroutine
|
|
|
|
rts
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
KernelSetupSubroutine
|
|
|
|
ldx #4
|
|
AdjustYValuesUpLoop
|
|
lda NewSpriteY,X
|
|
clc
|
|
adc #2
|
|
sta NewSpriteY,X
|
|
dex
|
|
bpl AdjustYValuesUpLoop
|
|
|
|
|
|
ldx temp3 ; first sprite displayed
|
|
|
|
lda SpriteGfxIndex,x
|
|
tay
|
|
lda NewSpriteY,y
|
|
sta RepoLine
|
|
|
|
lda SpriteGfxIndex-1,x
|
|
tay
|
|
lda NewSpriteY,y
|
|
sta temp6
|
|
|
|
stx SpriteIndex
|
|
|
|
|
|
|
|
lda #255
|
|
sta P1Bottom
|
|
|
|
lda player0y
|
|
ifconst screenheight
|
|
cmp #screenheight+1
|
|
else
|
|
cmp #$59
|
|
endif
|
|
bcc nottoohigh
|
|
lda P0Bottom
|
|
sta P0Top
|
|
|
|
|
|
|
|
nottoohigh
|
|
rts
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
;*************************************************************************
|
|
|
|
;-------------------------------------------------------------------------
|
|
;-------------------------Data Below--------------------------------------
|
|
;-------------------------------------------------------------------------
|
|
|
|
MaskTable
|
|
.byte 1,3,7,15,31
|
|
|
|
; shove 6-digit score routine here
|
|
|
|
sixdigscore
|
|
lda #0
|
|
; sta COLUBK
|
|
sta PF0
|
|
sta PF1
|
|
sta PF2
|
|
sta ENABL
|
|
sta ENAM0
|
|
sta ENAM1
|
|
;end of kernel here
|
|
|
|
|
|
; 6 digit score routine
|
|
; lda #0
|
|
; sta PF1
|
|
; sta PF2
|
|
; tax
|
|
|
|
sta WSYNC;,x
|
|
|
|
; STA WSYNC ;first one, need one more
|
|
sta REFP0
|
|
sta REFP1
|
|
STA GRP0
|
|
STA GRP1
|
|
sta HMCLR
|
|
|
|
; restore P0pointer
|
|
|
|
lda player0pointer
|
|
clc
|
|
adc player0y
|
|
sec
|
|
sbc player0height
|
|
sta player0pointer
|
|
|
|
ifconst vblank_time
|
|
ifconst screenheight
|
|
if screenheight == 84
|
|
lda #vblank_time+9+128+10
|
|
else
|
|
lda #vblank_time+9+128+19
|
|
endif
|
|
else
|
|
lda #vblank_time+9+128
|
|
endif
|
|
else
|
|
ifconst screenheight
|
|
if screenheight == 84
|
|
lda #52+128+10
|
|
else
|
|
lda #52+128+19
|
|
endif
|
|
else
|
|
lda #52+128
|
|
endif
|
|
endif
|
|
|
|
sta TIM64T
|
|
ifconst minikernel
|
|
jsr minikernel
|
|
endif
|
|
ifconst noscore
|
|
jmp skipscore
|
|
endif
|
|
|
|
; score pointers contain:
|
|
; score1-5: lo1,lo2,lo3,lo4,lo5,lo6
|
|
; swap lo2->temp1
|
|
; swap lo4->temp3
|
|
; swap lo6->temp5
|
|
|
|
lda scorepointers+5
|
|
sta temp5
|
|
lda scorepointers+1
|
|
sta temp1
|
|
lda scorepointers+3
|
|
sta temp3
|
|
|
|
lda #>scoretable
|
|
sta scorepointers+1
|
|
sta scorepointers+3
|
|
sta scorepointers+5
|
|
sta temp2
|
|
sta temp4
|
|
sta temp6
|
|
|
|
rts
|
|
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;----------------------Kernel Routine-------------------------------------
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
; echo *
|
|
; repeat $f147-*
|
|
; brk
|
|
; repend
|
|
; org $F240
|
|
|
|
SwitchDrawP0K1 ; 72
|
|
lda P0Bottom
|
|
sta P0Top ;+6 2
|
|
jmp BackFromSwitchDrawP0K1 ;+3 5
|
|
|
|
WaitDrawP0K1 ; 74
|
|
SLEEP 4 ;+4 2
|
|
jmp BackFromSwitchDrawP0K1 ;+3 5
|
|
|
|
SkipDrawP1K1 ; 11
|
|
lda #0
|
|
sta GRP1 ;+5 16 so Ball gets drawn
|
|
jmp BackFromSkipDrawP1 ;+3 19
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
KernelRoutine
|
|
ifnconst screenheight
|
|
jsr wastetime ; waste 12 cycles
|
|
else
|
|
sleep 6
|
|
endif
|
|
tsx
|
|
stx stack1
|
|
ldx #ENABL
|
|
txs ;+9 9
|
|
|
|
ldx #0
|
|
lda pfheight
|
|
bpl asdhj
|
|
.byte $24
|
|
asdhj
|
|
tax
|
|
|
|
; ldx pfheight
|
|
lda PFStart,x ; get pf pixel resolution for heights 15,7,3,1,0
|
|
|
|
ifconst screenheight
|
|
sec
|
|
if screenheight == 84
|
|
sbc pfsub+1,x
|
|
else
|
|
sbc pfsub,x
|
|
endif
|
|
endif
|
|
|
|
sta pfpixelheight
|
|
|
|
ifconst screenheight
|
|
ldy #screenheight
|
|
else
|
|
ldy #88
|
|
endif
|
|
|
|
; lda #$02
|
|
; sta COLUBK ;+5 18
|
|
|
|
; sleep 25
|
|
sleep 2
|
|
KernelLoopa ; 50
|
|
SLEEP 7 ;+4 54
|
|
KernelLoopb ; 54
|
|
SLEEP 2 ;+12 66
|
|
cpy P0Top ;+3 69
|
|
beq SwitchDrawP0K1 ;+2 71
|
|
bpl WaitDrawP0K1 ;+2 73
|
|
lda (player0pointer),Y ;+5 2
|
|
sta GRP0 ;+3 5 VDEL because of repokernel
|
|
BackFromSwitchDrawP0K1
|
|
|
|
cpy P1Bottom ;+3 8 unless we mean to draw immediately, this should be set
|
|
; to a value greater than maximum Y value initially
|
|
bcc SkipDrawP1K1 ;+2 10
|
|
lda (P1display),Y ;+5 15
|
|
sta.w GRP1 ;+4 19
|
|
BackFromSkipDrawP1
|
|
|
|
;fuck
|
|
sty temp1
|
|
ldy pfpixelheight
|
|
lax (PF1pointer),y
|
|
stx PF1 ;+7 26
|
|
lda (PF2pointer),y
|
|
sta PF2 ;+7 33
|
|
;sleep 6
|
|
stx PF1temp2
|
|
sta PF2temp2
|
|
dey
|
|
lda (PF1pointer),y
|
|
sta PF1temp1
|
|
lda (PF2pointer),y
|
|
sta PF2temp1
|
|
ldy temp1
|
|
|
|
ldx #ENABL
|
|
txs
|
|
cpy bally
|
|
php ;+6 39 VDEL ball
|
|
|
|
|
|
cpy missile1y
|
|
php ;+6 71
|
|
|
|
cpy missile0y
|
|
php ;+6 1
|
|
ldx #1
|
|
|
|
|
|
dey ;+2 15
|
|
|
|
cpy RepoLine ;+3 18
|
|
beq RepoKernel ;+2 20
|
|
; SLEEP 20 ;+23 43
|
|
sleep 6
|
|
|
|
newrepo ; since we have time here, store next repoline
|
|
ldx SpriteIndex
|
|
lda SpriteGfxIndex-1,x
|
|
tax
|
|
lda NewSpriteY,x
|
|
sta temp6
|
|
sleep 4
|
|
|
|
BackFromRepoKernel
|
|
tya ;+2 45
|
|
and pfheight ;+2 47
|
|
bne KernelLoopa ;+2 49
|
|
dec pfpixelheight
|
|
bpl KernelLoopb ;+3 54
|
|
; bmi donewkernel ;+3 54
|
|
; bne KernelLoopb+1 ;+3 54
|
|
|
|
donewkernel
|
|
jmp DoneWithKernel ;+3 56
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
; room here for score?
|
|
|
|
setscorepointers
|
|
lax score+2
|
|
jsr scorepointerset
|
|
sty scorepointers+5
|
|
stx scorepointers+2
|
|
lax score+1
|
|
jsr scorepointerset
|
|
sty scorepointers+4
|
|
stx scorepointers+1
|
|
lax score
|
|
jsr scorepointerset
|
|
sty scorepointers+3
|
|
stx scorepointers
|
|
wastetime
|
|
rts
|
|
|
|
scorepointerset
|
|
and #$0F
|
|
asl
|
|
asl
|
|
asl
|
|
adc #<scoretable
|
|
tay
|
|
txa
|
|
and #$F0
|
|
lsr
|
|
adc #<scoretable
|
|
tax
|
|
rts
|
|
; align 256
|
|
|
|
SwitchDrawP0KR ; 45
|
|
lda P0Bottom
|
|
sta P0Top ;+6 51
|
|
jmp BackFromSwitchDrawP0KR ;+3 54
|
|
|
|
WaitDrawP0KR ; 47
|
|
SLEEP 4 ;+4 51
|
|
jmp BackFromSwitchDrawP0KR ;+3 54
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
noUpdateXKR
|
|
sleep 3
|
|
JMP retXKR
|
|
|
|
skipthis
|
|
ldx #1
|
|
; sleep 2
|
|
jmp goback
|
|
|
|
RepoKernel ; 22 crosses page boundary
|
|
tya
|
|
and pfheight ;+2 26
|
|
bne noUpdateXKR ;+2 28
|
|
dex ;+2 30
|
|
dec pfpixelheight
|
|
; stx Temp ;+3 35
|
|
; SLEEP 3
|
|
retXKR
|
|
|
|
cpy P0Top ;+3 42
|
|
beq SwitchDrawP0KR ;+2 44
|
|
bpl WaitDrawP0KR ;+2 46
|
|
lda (player0pointer),Y ;+5 51
|
|
sta GRP0 ;+3 54 VDEL
|
|
BackFromSwitchDrawP0KR
|
|
sec ;+2 56
|
|
|
|
|
|
|
|
lda PF2temp1,X
|
|
ldy PF1temp1,X
|
|
|
|
ldx SpriteIndex ;+3 2
|
|
|
|
sta PF2 ;+7 63
|
|
|
|
lda SpriteGfxIndex,x
|
|
sty PF1 ;+7 70 too early?
|
|
tax
|
|
lda #0
|
|
sta GRP1 ;+5 75 to display player 0
|
|
lda NewSpriteX,X ;+4 6
|
|
|
|
DivideBy15LoopK ; 6 (carry set above)
|
|
sbc #15
|
|
bcs DivideBy15LoopK ;+4/5 10/15.../60
|
|
|
|
tax ;+2 12/17/...62
|
|
lda FineAdjustTableEnd,X ;+5 17/22/...67
|
|
|
|
sta HMP1 ;+3 20/25/...70
|
|
sta RESP1 ;+3 23/28/33/38/43/48/53/58/63/68/73
|
|
sta WSYNC ;+3 0 begin line 2
|
|
;sta HMOVE ;+3 3
|
|
|
|
ldx #ENABL
|
|
txs ;+4 25
|
|
ldy RepoLine ; restore y
|
|
cpy bally
|
|
php ;+6 9 VDEL ball
|
|
|
|
cpy missile1y
|
|
php ;+6 15
|
|
|
|
cpy missile0y
|
|
php ;+6 21
|
|
|
|
|
|
|
|
|
|
|
|
;15 cycles
|
|
tya
|
|
and pfheight
|
|
;eor #1
|
|
and #$FE
|
|
bne skipthis
|
|
tax
|
|
sleep 4
|
|
; sleep 2
|
|
goback
|
|
|
|
dey
|
|
cpy P0Top ;+3 52
|
|
beq SwitchDrawP0KV ;+2 54
|
|
bpl WaitDrawP0KV ;+2 56
|
|
lda (player0pointer),Y ;+5 61
|
|
sta GRP0 ;+3 64 VDEL
|
|
BackFromSwitchDrawP0KV
|
|
|
|
; sleep 3
|
|
|
|
lda PF2temp1,X
|
|
sta PF2 ;+7 5
|
|
lda PF1temp1,X
|
|
sta PF1 ;+7 74
|
|
sta HMOVE
|
|
|
|
lda #0
|
|
sta GRP1 ;+5 10 to display GRP0
|
|
|
|
ldx #ENABL
|
|
txs ;+4 8
|
|
|
|
ldx SpriteIndex ;+3 13 restore index into new sprite vars
|
|
;--now, set all new variables and return to main kernel loop
|
|
|
|
|
|
;
|
|
lda SpriteGfxIndex,X ;+4 31
|
|
tax ;+2 33
|
|
;
|
|
lda NewSpriteY,X ;+4 46
|
|
sta P1Bottom ;+3 49 adjust for height below
|
|
|
|
|
|
|
|
lda NewNUSIZ,X
|
|
sta NUSIZ1 ;+7 20
|
|
sta REFP1
|
|
lda NewCOLUP1,X
|
|
sta COLUP1 ;+7 27
|
|
|
|
; lda SpriteGfxIndex,X ;+4 31
|
|
; tax ;+2 33
|
|
;fuck2
|
|
lda P1Bottom ;+3 36
|
|
sec ;+2 38
|
|
sbc spriteheight,X ;+4 42
|
|
sta P1Bottom ;+3 45
|
|
|
|
|
|
lda player1pointerlo,X ;+4 49
|
|
sbc P1Bottom ;+3 52 carry should still be set
|
|
sta P1display ;+3 55
|
|
lda player1pointerhi,X
|
|
sta P1display+1 ;+7 62
|
|
|
|
|
|
cpy bally
|
|
php ;+6 68 VDELed
|
|
|
|
cpy missile1y
|
|
php ;+6 74
|
|
|
|
cpy missile0y
|
|
php ;+6 4
|
|
|
|
|
|
|
|
; lda SpriteGfxIndex-1,x
|
|
; sleep 3
|
|
dec SpriteIndex ;+5 13
|
|
; tax
|
|
; lda NewSpriteY,x
|
|
; sta RepoLine
|
|
|
|
; 10 cycles below...
|
|
bpl SetNextLine
|
|
lda #255
|
|
jmp SetLastLine
|
|
SetNextLine
|
|
; lda NewSpriteY-1,x
|
|
lda.w temp6
|
|
SetLastLine
|
|
sta RepoLine
|
|
|
|
tya
|
|
and pfheight
|
|
bne nodec
|
|
dec pfpixelheight
|
|
dey ;+2 30
|
|
|
|
; 10 cycles
|
|
|
|
|
|
jmp BackFromRepoKernel ;+3 43
|
|
|
|
nodec
|
|
sleep 4
|
|
dey
|
|
jmp BackFromRepoKernel
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
SwitchDrawP0KV ; 69
|
|
lda P0Bottom
|
|
sta P0Top ;+6 75
|
|
jmp BackFromSwitchDrawP0KV ;+3 2
|
|
|
|
WaitDrawP0KV ; 71
|
|
SLEEP 4 ;+4 75
|
|
jmp BackFromSwitchDrawP0KV ;+3 2
|
|
|
|
;-------------------------------------------------------------------------
|
|
|
|
DoneWithKernel
|
|
|
|
BottomOfKernelLoop
|
|
|
|
sta WSYNC
|
|
ldx stack1
|
|
txs
|
|
jsr sixdigscore ; set up score
|
|
|
|
|
|
sta WSYNC
|
|
ldx #0
|
|
sta HMCLR
|
|
STx GRP0
|
|
STx GRP1 ; seems to be needed because of vdel
|
|
|
|
LDY #7
|
|
STy VDELP0
|
|
STy VDELP1
|
|
LDA #$10
|
|
STA HMP1
|
|
LDA scorecolor
|
|
STA COLUP0
|
|
STA COLUP1
|
|
|
|
LDA #$03
|
|
STA NUSIZ0
|
|
STA NUSIZ1
|
|
|
|
STA RESP0
|
|
STA RESP1
|
|
|
|
sleep 9
|
|
lda (scorepointers),y
|
|
sta GRP0
|
|
ifconst pfscore
|
|
lda pfscorecolor
|
|
sta COLUPF
|
|
else
|
|
sleep 6
|
|
endif
|
|
|
|
STA HMOVE
|
|
lda (scorepointers+8),y
|
|
; sta WSYNC
|
|
;sleep 2
|
|
jmp beginscore
|
|
|
|
|
|
loop2
|
|
lda (scorepointers),y ;+5 68 204
|
|
sta GRP0 ;+3 71 213 D1 -- -- --
|
|
ifconst pfscore
|
|
lda.w pfscore1
|
|
sta PF1
|
|
else
|
|
sleep 7
|
|
endif
|
|
; cycle 0
|
|
lda (scorepointers+$8),y ;+5 5 15
|
|
beginscore
|
|
sta GRP1 ;+3 8 24 D1 D1 D2 --
|
|
lda (scorepointers+$6),y ;+5 13 39
|
|
sta GRP0 ;+3 16 48 D3 D1 D2 D2
|
|
lax (scorepointers+$2),y ;+5 29 87
|
|
txs
|
|
lax (scorepointers+$4),y ;+5 36 108
|
|
sleep 3
|
|
ifconst pfscore
|
|
lda pfscore2
|
|
sta PF1
|
|
else
|
|
sleep 6
|
|
endif
|
|
lda (scorepointers+$A),y ;+5 21 63
|
|
stx GRP1 ;+3 44 132 D3 D3 D4 D2!
|
|
tsx
|
|
stx GRP0 ;+3 47 141 D5 D3! D4 D4
|
|
sta GRP1 ;+3 50 150 D5 D5 D6 D4!
|
|
sty GRP0 ;+3 53 159 D4* D5! D6 D6
|
|
dey
|
|
bpl loop2 ;+2 60 180
|
|
ldx stack1
|
|
txs
|
|
|
|
|
|
; lda scorepointers+1
|
|
ldy temp1
|
|
; sta temp1
|
|
sty scorepointers+1
|
|
|
|
LDA #0
|
|
STA GRP0
|
|
STA GRP1
|
|
sta PF1
|
|
STA VDELP0
|
|
STA VDELP1;do we need these
|
|
STA NUSIZ0
|
|
STA NUSIZ1
|
|
|
|
; lda scorepointers+3
|
|
ldy temp3
|
|
; sta temp3
|
|
sty scorepointers+3
|
|
|
|
; lda scorepointers+5
|
|
ldy temp5
|
|
; sta temp5
|
|
sty scorepointers+5
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;------------------------Overscan Routine---------------------------------
|
|
;-------------------------------------------------------------------------
|
|
|
|
OverscanRoutine
|
|
|
|
|
|
|
|
skipscore
|
|
lda #2
|
|
sta WSYNC
|
|
sta VBLANK ;turn on VBLANK
|
|
|
|
|
|
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;----------------------------End Main Routines----------------------------
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
;*************************************************************************
|
|
|
|
;-------------------------------------------------------------------------
|
|
;----------------------Begin Subroutines----------------------------------
|
|
;-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
KernelCleanupSubroutine
|
|
|
|
ldx #4
|
|
AdjustYValuesDownLoop
|
|
lda NewSpriteY,X
|
|
sec
|
|
sbc #2
|
|
sta NewSpriteY,X
|
|
dex
|
|
bpl AdjustYValuesDownLoop
|
|
|
|
|
|
RETURN
|
|
;rts
|
|
|
|
SetupP1Subroutine
|
|
; flickersort algorithm
|
|
; count 4-0
|
|
; table2=table1 (?)
|
|
; detect overlap of sprites in table 2
|
|
; if overlap, do regular sort in table2, then place one sprite at top of table 1, decrement # displayed
|
|
; if no overlap, do regular sort in table 2 and table 1
|
|
ldx #255
|
|
copytable
|
|
inx
|
|
lda spritesort,x
|
|
sta SpriteGfxIndex,x
|
|
cpx #4
|
|
bne copytable
|
|
|
|
stx temp3 ; highest displayed sprite
|
|
dex
|
|
stx temp2
|
|
sortloop
|
|
ldx temp2
|
|
lda spritesort,x
|
|
tax
|
|
lda NewSpriteY,x
|
|
sta temp1
|
|
|
|
ldx temp2
|
|
lda spritesort+1,x
|
|
tax
|
|
lda NewSpriteY,x
|
|
sec
|
|
sbc temp1
|
|
bcc largerXislower
|
|
|
|
; larger x is higher (A>=temp1)
|
|
cmp spriteheight,x
|
|
bcs countdown
|
|
; overlap with x+1>x
|
|
;
|
|
; stick x at end of gfxtable, dec counter
|
|
overlapping
|
|
dec temp3
|
|
ldx temp2
|
|
inx
|
|
jsr shiftnumbers
|
|
jmp skipswapGfxtable
|
|
|
|
largerXislower ; (temp1>A)
|
|
tay
|
|
ldx temp2
|
|
lda spritesort,x
|
|
tax
|
|
tya
|
|
eor #$FF
|
|
cmp spriteheight,x
|
|
bcs notoverlapping
|
|
|
|
dec temp3
|
|
ldx temp2
|
|
inx
|
|
jsr shiftnumbers
|
|
jmp skipswapGfxtable
|
|
notoverlapping
|
|
ldx temp2 ; swap display table
|
|
ldy SpriteGfxIndex+1,x
|
|
lda SpriteGfxIndex,x
|
|
sty SpriteGfxIndex,x
|
|
sta SpriteGfxIndex+1,x
|
|
|
|
skipswapGfxtable
|
|
ldx temp2 ; swap sort table
|
|
ldy spritesort+1,x
|
|
lda spritesort,x
|
|
sty spritesort,x
|
|
sta spritesort+1,x
|
|
|
|
countdown
|
|
dec temp2
|
|
bpl sortloop
|
|
|
|
checktoohigh
|
|
ldx temp3
|
|
lda SpriteGfxIndex,x
|
|
tax
|
|
lda NewSpriteY,x
|
|
ifconst screenheight
|
|
cmp #screenheight-2
|
|
else
|
|
cmp #$56
|
|
endif
|
|
bcc nonetoohigh
|
|
dec temp3
|
|
bne checktoohigh
|
|
|
|
nonetoohigh
|
|
rts
|
|
|
|
|
|
shiftnumbers
|
|
; stick current x at end, shift others down
|
|
; if x=4: don't do anything
|
|
; if x=3: swap 3 and 4
|
|
; if x=2: 2=3, 3=4, 4=2
|
|
; if x=1: 1=2, 2=3, 3=4, 4=1
|
|
; if x=0: 0=1, 1=2, 2=3, 3=4, 4=0
|
|
ldy SpriteGfxIndex,x
|
|
swaploop
|
|
cpx #4
|
|
beq shiftdone
|
|
lda SpriteGfxIndex+1,x
|
|
sta SpriteGfxIndex,x
|
|
inx
|
|
jmp swaploop
|
|
shiftdone
|
|
sty SpriteGfxIndex,x
|
|
rts
|
|
|
|
ifconst debugscore
|
|
debugcycles
|
|
ldx #14
|
|
lda INTIM ; display # cycles left in the score
|
|
|
|
ifconst mincycles
|
|
lda mincycles
|
|
cmp INTIM
|
|
lda mincycles
|
|
bcc nochange
|
|
lda INTIM
|
|
sta mincycles
|
|
nochange
|
|
endif
|
|
|
|
; cmp #$2B
|
|
; bcs no_cycles_left
|
|
bmi cycles_left
|
|
ldx #64
|
|
eor #$ff ;make negative
|
|
cycles_left
|
|
stx scorecolor
|
|
and #$7f ; clear sign bit
|
|
tax
|
|
lda scorebcd,x
|
|
sta score+2
|
|
lda scorebcd1,x
|
|
sta score+1
|
|
rts
|
|
scorebcd
|
|
.byte $00, $64, $28, $92, $56, $20, $84, $48, $12, $76, $40
|
|
.byte $04, $68, $32, $96, $60, $24, $88, $52, $16, $80, $44
|
|
.byte $08, $72, $36, $00, $64, $28, $92, $56, $20, $84, $48
|
|
.byte $12, $76, $40, $04, $68, $32, $96, $60, $24, $88
|
|
scorebcd1
|
|
.byte 0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6
|
|
.byte 7, 7, 8, 8, 9, $10, $10, $11, $12, $12, $13
|
|
.byte $14, $14, $15, $16, $16, $17, $17, $18, $19, $19, $20
|
|
.byte $21, $21, $22, $23, $23, $24, $24, $25, $26, $26
|
|
endif
|
|
;
|
|
; Inclues go below - order is crucial, since this is also the order in which
|
|
; they will appear in the generated assembly file
|
|
;
|
|
|
|
|
|
; header file
|
|
2600basicheader.asm
|
|
|
|
|
|
; standard kernel: two players, two missiles, a ball and an asymmetric playfield.
|
|
std_kernel.asm
|
|
|
|
; standard startup routine.
|
|
startup.asm
|
|
|
|
|
|
; below are collections of subroutines and functions
|
|
; if you have any more to add, put them immediately below this line.
|
|
|
|
pf_drawing.asm
|
|
pf_scrolling.asm
|
|
std_routines.asm
|
|
|
|
; The overscan routine goes below. it sets up sprites for the std_kernel.
|
|
; if you have any routines that will not run until the overscan period,
|
|
; put them immediately below this line.
|
|
std_overscan.asm
|
|
|
|
|
|
; below is the generated batari Basic file
|
|
|
|
bB.asm
|
|
|
|
|
|
; score graphics.
|
|
score_graphics.asm
|
|
|
|
; below is the footer, which contains the score digits and startup vectors.
|
|
; If you want to create your own custom score digits, you may hack the file below,
|
|
; but first you should rename it to something else.
|
|
|
|
2600basicfooter.asm
|
|
processor 6502
|
|
include "vcs.h"
|
|
include "macro.h"
|
|
include "2600basic.h"
|
|
include "2600basic_variable_redefs.h"
|
|
ifconst bankswitch
|
|
if bankswitch == 8
|
|
ORG $1000
|
|
RORG $D000
|
|
endif
|
|
if bankswitch == 16
|
|
ORG $1000
|
|
RORG $9000
|
|
endif
|
|
if bankswitch == 32
|
|
ORG $1000
|
|
RORG $1000
|
|
endif
|
|
else
|
|
ORG $F000
|
|
endif
|
|
repeat 256
|
|
.byte $ff
|
|
repend
|
|
pfscroll ;(a=0 left, 1 right, 2 up, 4 down, 6=upup, 12=downdown)
|
|
bne notleft
|
|
;left
|
|
ifconst pfres
|
|
ldx #pfres*4
|
|
else
|
|
ldx #48
|
|
endif
|
|
leftloop
|
|
lda playfield-1,x
|
|
lsr
|
|
|
|
ifconst superchip
|
|
lda playfield-2,x
|
|
rol
|
|
sta playfield-130,x
|
|
lda playfield-3,x
|
|
ror
|
|
sta playfield-131,x
|
|
lda playfield-4,x
|
|
rol
|
|
sta playfield-132,x
|
|
lda playfield-1,x
|
|
ror
|
|
sta playfield-129,x
|
|
else
|
|
rol playfield-2,x
|
|
ror playfield-3,x
|
|
rol playfield-4,x
|
|
ror playfield-1,x
|
|
endif
|
|
|
|
txa
|
|
sbx #4
|
|
bne leftloop
|
|
RETURN
|
|
|
|
notleft
|
|
lsr
|
|
bcc notright
|
|
;right
|
|
|
|
ifconst pfres
|
|
ldx #pfres*4
|
|
else
|
|
ldx #48
|
|
endif
|
|
rightloop
|
|
lda playfield-4,x
|
|
lsr
|
|
ifconst superchip
|
|
lda playfield-3,x
|
|
rol
|
|
sta playfield-131,x
|
|
lda playfield-2,x
|
|
ror
|
|
sta playfield-130,x
|
|
lda playfield-1,x
|
|
rol
|
|
sta playfield-129,x
|
|
lda playfield-4,x
|
|
ror
|
|
sta playfield-132,x
|
|
else
|
|
rol playfield-3,x
|
|
ror playfield-2,x
|
|
rol playfield-1,x
|
|
ror playfield-4,x
|
|
endif
|
|
txa
|
|
sbx #4
|
|
bne rightloop
|
|
RETURN
|
|
|
|
notright
|
|
lsr
|
|
bcc notup
|
|
;up
|
|
lsr
|
|
bcc onedecup
|
|
dec playfieldpos
|
|
onedecup
|
|
dec playfieldpos
|
|
beq shiftdown
|
|
bpl noshiftdown2
|
|
shiftdown
|
|
ifconst pfrowheight
|
|
lda #pfrowheight
|
|
else
|
|
ifnconst pfres
|
|
lda #8
|
|
else
|
|
lda #(96/pfres) ; try to come close to the real size
|
|
endif
|
|
endif
|
|
|
|
sta playfieldpos
|
|
lda playfield+3
|
|
sta temp4
|
|
lda playfield+2
|
|
sta temp3
|
|
lda playfield+1
|
|
sta temp2
|
|
lda playfield
|
|
sta temp1
|
|
ldx #0
|
|
up2
|
|
lda playfield+4,x
|
|
ifconst superchip
|
|
sta playfield-128,x
|
|
lda playfield+5,x
|
|
sta playfield-127,x
|
|
lda playfield+6,x
|
|
sta playfield-126,x
|
|
lda playfield+7,x
|
|
sta playfield-125,x
|
|
else
|
|
sta playfield,x
|
|
lda playfield+5,x
|
|
sta playfield+1,x
|
|
lda playfield+6,x
|
|
sta playfield+2,x
|
|
lda playfield+7,x
|
|
sta playfield+3,x
|
|
endif
|
|
txa
|
|
sbx #252
|
|
ifconst pfres
|
|
cpx #(pfres-1)*4
|
|
else
|
|
cpx #44
|
|
endif
|
|
bne up2
|
|
|
|
lda temp4
|
|
|
|
ifconst superchip
|
|
ifconst pfres
|
|
sta playfield+pfres*4-129
|
|
lda temp3
|
|
sta playfield+pfres*4-130
|
|
lda temp2
|
|
sta playfield+pfres*4-131
|
|
lda temp1
|
|
sta playfield+pfres*4-132
|
|
else
|
|
sta playfield+47-128
|
|
lda temp3
|
|
sta playfield+46-128
|
|
lda temp2
|
|
sta playfield+45-128
|
|
lda temp1
|
|
sta playfield+44-128
|
|
endif
|
|
else
|
|
ifconst pfres
|
|
sta playfield+pfres*4-1
|
|
lda temp3
|
|
sta playfield+pfres*4-2
|
|
lda temp2
|
|
sta playfield+pfres*4-3
|
|
lda temp1
|
|
sta playfield+pfres*4-4
|
|
else
|
|
sta playfield+47
|
|
lda temp3
|
|
sta playfield+46
|
|
lda temp2
|
|
sta playfield+45
|
|
lda temp1
|
|
sta playfield+44
|
|
endif
|
|
endif
|
|
noshiftdown2
|
|
RETURN
|
|
|
|
|
|
notup
|
|
;down
|
|
lsr
|
|
bcs oneincup
|
|
inc playfieldpos
|
|
oneincup
|
|
inc playfieldpos
|
|
lda playfieldpos
|
|
|
|
ifconst pfrowheight
|
|
cmp #pfrowheight+1
|
|
else
|
|
ifnconst pfres
|
|
cmp #9
|
|
else
|
|
cmp #(96/pfres)+1 ; try to come close to the real size
|
|
endif
|
|
endif
|
|
|
|
bcc noshiftdown
|
|
lda #1
|
|
sta playfieldpos
|
|
|
|
ifconst pfres
|
|
lda playfield+pfres*4-1
|
|
sta temp4
|
|
lda playfield+pfres*4-2
|
|
sta temp3
|
|
lda playfield+pfres*4-3
|
|
sta temp2
|
|
lda playfield+pfres*4-4
|
|
else
|
|
lda playfield+47
|
|
sta temp4
|
|
lda playfield+46
|
|
sta temp3
|
|
lda playfield+45
|
|
sta temp2
|
|
lda playfield+44
|
|
endif
|
|
|
|
sta temp1
|
|
|
|
ifconst pfres
|
|
ldx #(pfres-1)*4
|
|
else
|
|
ldx #44
|
|
endif
|
|
down2
|
|
lda playfield-1,x
|
|
ifconst superchip
|
|
sta playfield-125,x
|
|
lda playfield-2,x
|
|
sta playfield-126,x
|
|
lda playfield-3,x
|
|
sta playfield-127,x
|
|
lda playfield-4,x
|
|
sta playfield-128,x
|
|
else
|
|
sta playfield+3,x
|
|
lda playfield-2,x
|
|
sta playfield+2,x
|
|
lda playfield-3,x
|
|
sta playfield+1,x
|
|
lda playfield-4,x
|
|
sta playfield,x
|
|
endif
|
|
txa
|
|
sbx #4
|
|
bne down2
|
|
|
|
lda temp4
|
|
ifconst superchip
|
|
sta playfield-125
|
|
lda temp3
|
|
sta playfield-126
|
|
lda temp2
|
|
sta playfield-127
|
|
lda temp1
|
|
sta playfield-128
|
|
else
|
|
sta playfield+3
|
|
lda temp3
|
|
sta playfield+2
|
|
lda temp2
|
|
sta playfield+1
|
|
lda temp1
|
|
sta playfield
|
|
endif
|
|
noshiftdown
|
|
RETURN
|
|
;standard routines needed for pretty much all games
|
|
; just the random number generator is left - maybe we should remove this asm file altogether?
|
|
; repositioning code and score pointer setup moved to overscan
|
|
; read switches, joysticks now compiler generated (more efficient)
|
|
|
|
randomize
|
|
lda rand
|
|
lsr
|
|
ifconst rand16
|
|
rol rand16
|
|
endif
|
|
bcc noeor
|
|
eor #$B4
|
|
noeor
|
|
sta rand
|
|
ifconst rand16
|
|
eor rand16
|
|
endif
|
|
RETURN
|
|
processor 6502
|
|
include "vcs.h"
|
|
include "macro.h"
|
|
include "2600basic.h"
|
|
include "2600basic_variable_redefs.h"
|
|
ifconst bankswitch
|
|
if bankswitch == 8
|
|
ORG $1000
|
|
RORG $D000
|
|
endif
|
|
if bankswitch == 16
|
|
ORG $1000
|
|
RORG $9000
|
|
endif
|
|
if bankswitch == 32
|
|
ORG $1000
|
|
RORG $1000
|
|
endif
|
|
else
|
|
ORG $F000
|
|
endif
|
|
;
|
|
; Inclues go below - order is crucial, since this is also the order in which
|
|
; they will appear in the generated assembly file
|
|
;
|
|
; header file
|
|
multispriteheader.asm
|
|
|
|
; this is the batari Basic file
|
|
; for bankswitching, the concatenator will only parse until the end of
|
|
; bank 1
|
|
bB.asm
|
|
|
|
; standard kernel: two players, two missiles, a ball and an asymmetric playfield.
|
|
multisprite_kernel.asm
|
|
|
|
; standard startup routine.
|
|
startup.asm
|
|
|
|
|
|
; below are collections of subroutines and functions
|
|
; if you have any more to add, put them immediately below this line.
|
|
|
|
std_routines.asm
|
|
|
|
; below is the generated batari Basic file
|
|
; note: this file is generated by the concatenation program.
|
|
; automatically split off from the bB.asm file where the new bank occurs
|
|
|
|
bB2.asm
|
|
|
|
|
|
; score gfx
|
|
score_graphics.asm
|
|
|
|
;bankswitch support
|
|
banksw.asm
|
|
|
|
|
|
; below is the footer, which contains the score digits and startup vectors.
|
|
; If you want to create your own custom score digits, you may hack the file below,
|
|
; but first you should rename it to something else.
|
|
; also includes bankswitching support (if applicable)
|
|
|
|
2600basicfooter.asm
|
|
start
|
|
sei
|
|
cld
|
|
ldy #0
|
|
lda $D0
|
|
cmp #$2C ;check RAM location #1
|
|
bne MachineIs2600
|
|
lda $D1
|
|
cmp #$A9 ;check RAM location #2
|
|
bne MachineIs2600
|
|
dey
|
|
MachineIs2600
|
|
ldx #0
|
|
txa
|
|
clearmem
|
|
inx
|
|
txs
|
|
pha
|
|
bne clearmem
|
|
sty temp1
|
|
ifconst pfrowheight
|
|
lda pfrowheight
|
|
else
|
|
ifconst pfres
|
|
lda #(96/pfres)
|
|
else
|
|
lda #8
|
|
endif
|
|
endif
|
|
sta playfieldpos
|
|
ldx #5
|
|
initscore
|
|
lda #<scoretable
|
|
sta scorepointers,x
|
|
dex
|
|
bpl initscore
|
|
lda #1
|
|
sta CTRLPF
|
|
ora INTIM
|
|
sta rand
|
|
|
|
ifconst multisprite
|
|
jsr multisprite_setup
|
|
endif
|
|
|
|
ifnconst bankswitch
|
|
jmp game
|
|
else
|
|
lda #>(game-1)
|
|
pha
|
|
lda #<(game-1)
|
|
pha
|
|
pha
|
|
pha
|
|
ldx #1
|
|
jmp BS_jsr
|
|
endif
|
|
; playfield drawing routines
|
|
; you get a 32x12 bitmapped display in a single color :)
|
|
; 0-31 and 0-11
|
|
|
|
pfclear ; clears playfield - or fill with pattern
|
|
ifconst pfres
|
|
ldx #pfres*4-1
|
|
else
|
|
ldx #47
|
|
endif
|
|
pfclear_loop
|
|
ifnconst superchip
|
|
sta playfield,x
|
|
else
|
|
sta playfield-128,x
|
|
endif
|
|
dex
|
|
bpl pfclear_loop
|
|
RETURN
|
|
|
|
setuppointers
|
|
stx temp2 ; store on.off.flip value
|
|
tax ; put x-value in x
|
|
lsr
|
|
lsr
|
|
lsr ; divide x pos by 8
|
|
sta temp1
|
|
tya
|
|
asl
|
|
asl ; multiply y pos by 4
|
|
clc
|
|
adc temp1 ; add them together to get actual memory location offset
|
|
tay ; put the value in y
|
|
lda temp2 ; restore on.off.flip value
|
|
rts
|
|
|
|
pfread
|
|
;x=xvalue, y=yvalue
|
|
jsr setuppointers
|
|
lda setbyte,x
|
|
and playfield,y
|
|
eor setbyte,x
|
|
; beq readzero
|
|
; lda #1
|
|
; readzero
|
|
RETURN
|
|
|
|
pfpixel
|
|
;x=xvalue, y=yvalue, a=0,1,2
|
|
jsr setuppointers
|
|
|
|
ifconst bankswitch
|
|
lda temp2 ; load on.off.flip value (0,1, or 2)
|
|
beq pixelon_r ; if "on" go to on
|
|
lsr
|
|
bcs pixeloff_r ; value is 1 if true
|
|
lda playfield,y ; if here, it's "flip"
|
|
eor setbyte,x
|
|
ifconst superchip
|
|
sta playfield-128,y
|
|
else
|
|
sta playfield,y
|
|
endif
|
|
RETURN
|
|
pixelon_r
|
|
lda playfield,y
|
|
ora setbyte,x
|
|
ifconst superchip
|
|
sta playfield-128,y
|
|
else
|
|
sta playfield,y
|
|
endif
|
|
RETURN
|
|
pixeloff_r
|
|
lda setbyte,x
|
|
eor #$ff
|
|
and playfield,y
|
|
ifconst superchip
|
|
sta playfield-128,y
|
|
else
|
|
sta playfield,y
|
|
endif
|
|
RETURN
|
|
|
|
else
|
|
jmp plotpoint
|
|
endif
|
|
|
|
pfhline
|
|
;x=xvalue, y=yvalue, a=0,1,2, temp3=endx
|
|
jsr setuppointers
|
|
jmp noinc
|
|
keepgoing
|
|
inx
|
|
txa
|
|
and #7
|
|
bne noinc
|
|
iny
|
|
noinc
|
|
jsr plotpoint
|
|
cpx temp3
|
|
bmi keepgoing
|
|
RETURN
|
|
|
|
pfvline
|
|
;x=xvalue, y=yvalue, a=0,1,2, temp3=endx
|
|
jsr setuppointers
|
|
sty temp1 ; store memory location offset
|
|
inc temp3 ; increase final x by 1
|
|
lda temp3
|
|
asl
|
|
asl ; multiply by 4
|
|
sta temp3 ; store it
|
|
; Thanks to Michael Rideout for fixing a bug in this code
|
|
; right now, temp1=y=starting memory location, temp3=final
|
|
; x should equal original x value
|
|
keepgoingy
|
|
jsr plotpoint
|
|
iny
|
|
iny
|
|
iny
|
|
iny
|
|
cpy temp3
|
|
bmi keepgoingy
|
|
RETURN
|
|
|
|
plotpoint
|
|
lda temp2 ; load on.off.flip value (0,1, or 2)
|
|
beq pixelon ; if "on" go to on
|
|
lsr
|
|
bcs pixeloff ; value is 1 if true
|
|
lda playfield,y ; if here, it's "flip"
|
|
eor setbyte,x
|
|
ifconst superchip
|
|
sta playfield-128,y
|
|
else
|
|
sta playfield,y
|
|
endif
|
|
rts
|
|
pixelon
|
|
lda playfield,y
|
|
ora setbyte,x
|
|
ifconst superchip
|
|
sta playfield-128,y
|
|
else
|
|
sta playfield,y
|
|
endif
|
|
rts
|
|
pixeloff
|
|
lda setbyte,x
|
|
eor #$ff
|
|
and playfield,y
|
|
ifconst superchip
|
|
sta playfield-128,y
|
|
else
|
|
sta playfield,y
|
|
endif
|
|
rts
|
|
|
|
setbyte
|
|
.byte $80
|
|
.byte $40
|
|
.byte $20
|
|
.byte $10
|
|
.byte $08
|
|
.byte $04
|
|
.byte $02
|
|
.byte $01
|
|
.byte $01
|
|
.byte $02
|
|
.byte $04
|
|
.byte $08
|
|
.byte $10
|
|
.byte $20
|
|
.byte $40
|
|
.byte $80
|
|
.byte $80
|
|
.byte $40
|
|
.byte $20
|
|
.byte $10
|
|
.byte $08
|
|
.byte $04
|
|
.byte $02
|
|
.byte $01
|
|
.byte $01
|
|
.byte $02
|
|
.byte $04
|
|
.byte $08
|
|
.byte $10
|
|
.byte $20
|
|
.byte $40
|
|
.byte $80
|
|
; feel free to modify the score graphics - just keep each digit 8 high
|
|
; and keep the conditional compilation stuff intact
|
|
ifconst ROM2k
|
|
ORG $F7AC
|
|
else
|
|
ifconst bankswitch
|
|
if bankswitch == 8
|
|
ORG $2F94-bscode_length
|
|
RORG $FF94-bscode_length
|
|
endif
|
|
if bankswitch == 16
|
|
ORG $4F94-bscode_length
|
|
RORG $FF94-bscode_length
|
|
endif
|
|
if bankswitch == 32
|
|
ORG $8F94-bscode_length
|
|
RORG $FF94-bscode_length
|
|
endif
|
|
else
|
|
ORG $FF9C
|
|
endif
|
|
endif
|
|
|
|
|
|
scoretable
|
|
.byte %00111100
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %00111100
|
|
|
|
.byte %01111110
|
|
.byte %00011000
|
|
.byte %00011000
|
|
.byte %00011000
|
|
.byte %00011000
|
|
.byte %00111000
|
|
.byte %00011000
|
|
.byte %00001000
|
|
|
|
.byte %01111110
|
|
.byte %01100000
|
|
.byte %01100000
|
|
.byte %00111100
|
|
.byte %00000110
|
|
.byte %00000110
|
|
.byte %01000110
|
|
.byte %00111100
|
|
|
|
.byte %00111100
|
|
.byte %01000110
|
|
.byte %00000110
|
|
.byte %00000110
|
|
.byte %00011100
|
|
.byte %00000110
|
|
.byte %01000110
|
|
.byte %00111100
|
|
|
|
.byte %00001100
|
|
.byte %00001100
|
|
.byte %01111110
|
|
.byte %01001100
|
|
.byte %01001100
|
|
.byte %00101100
|
|
.byte %00011100
|
|
.byte %00001100
|
|
|
|
.byte %00111100
|
|
.byte %01000110
|
|
.byte %00000110
|
|
.byte %00000110
|
|
.byte %00111100
|
|
.byte %01100000
|
|
.byte %01100000
|
|
.byte %01111110
|
|
|
|
.byte %00111100
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01111100
|
|
.byte %01100000
|
|
.byte %01100010
|
|
.byte %00111100
|
|
|
|
.byte %00110000
|
|
.byte %00110000
|
|
.byte %00110000
|
|
.byte %00011000
|
|
.byte %00001100
|
|
.byte %00000110
|
|
.byte %01000010
|
|
.byte %00111110
|
|
|
|
.byte %00111100
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %00111100
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %00111100
|
|
|
|
.byte %00111100
|
|
.byte %01000110
|
|
.byte %00000110
|
|
.byte %00111110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %01100110
|
|
.byte %00111100
|
|
|
|
|
|
ifconst ROM2k
|
|
ORG $F7FC
|
|
else
|
|
ifconst bankswitch
|
|
if bankswitch == 8
|
|
ORG $2FF4-bscode_length
|
|
RORG $FFF4-bscode_length
|
|
endif
|
|
if bankswitch == 16
|
|
ORG $4FF4-bscode_length
|
|
RORG $FFF4-bscode_length
|
|
endif
|
|
if bankswitch == 32
|
|
ORG $8FF4-bscode_length
|
|
RORG $FFF4-bscode_length
|
|
endif
|
|
else
|
|
ORG $FFFC
|
|
endif
|
|
endif
|
|
pfread
|
|
cmp #16
|
|
bcc lefthalf
|
|
eor #31 ; 16-31 converted to 15-0
|
|
lefthalf
|
|
tax
|
|
lda bytemask,x
|
|
cpx #8
|
|
bcc bytedone
|
|
and (PF2pointer),y
|
|
.byte $0C
|
|
bytedone
|
|
and (PF1pointer),y
|
|
RETURN
|
|
bytemask
|
|
.byte $80,$40,$20,$10,8,4,2,1
|
|
.byte 1,2,4,8,$10,$20,$40,$80
|
|
; Fixed point math routines - created by AtariAge member djmips
|
|
; some changes by Fred Quimby
|
|
|
|
;assignment from 8.8 to 4.4
|
|
|
|
Assign88to44:
|
|
|
|
; A(4.4) = A,X(8.8)
|
|
|
|
stx temp1
|
|
rol temp1
|
|
asl
|
|
rol temp1
|
|
asl
|
|
rol temp1
|
|
asl
|
|
rol temp1
|
|
asl
|
|
rts
|
|
|
|
;assignment from 4.4 to 8.8
|
|
;
|
|
|
|
Assign44to88:
|
|
|
|
; A,X(8.8) = A(4.4)
|
|
|
|
sta temp1
|
|
lda #0
|
|
asl temp1
|
|
sbc #0 ;
|
|
eor #$ff ; do sign extend
|
|
rol
|
|
asl temp1
|
|
rol
|
|
asl temp1
|
|
rol
|
|
asl temp1
|
|
rol
|
|
ldx temp1
|
|
rts
|
|
|
|
ifconst bankswitch
|
|
Assign88to44bs:
|
|
|
|
; A(4.4) = A,X(8.8)
|
|
|
|
stx temp1
|
|
rol temp1
|
|
asl
|
|
rol temp1
|
|
asl
|
|
rol temp1
|
|
asl
|
|
rol temp1
|
|
asl
|
|
RETURN
|
|
|
|
;assignment from 4.4 to 8.8
|
|
;
|
|
|
|
Assign44to88bs:
|
|
|
|
; A,X(8.8) = A(4.4)
|
|
|
|
sta temp1
|
|
lda #0
|
|
asl temp1
|
|
sbc #0 ;
|
|
eor #$ff ; do sign extend
|
|
rol
|
|
asl temp1
|
|
rol
|
|
asl temp1
|
|
rol
|
|
asl temp1
|
|
rol
|
|
ldx temp1
|
|
RETURN
|
|
endif
|
|
|
|
;
|
|
;Addition/subtraction asm procedures:
|
|
|
|
;add/sub 8.8 to/from 4.4
|
|
|
|
Add88to44:
|
|
|
|
; A(4.4) = A,X(8.8) + Y(4.4)
|
|
|
|
jsr Assign88to44
|
|
sty temp1
|
|
clc
|
|
adc temp1
|
|
rts
|
|
|
|
Sub88from44:
|
|
|
|
; A(4.4) = A,X(8.8) - Y(4.4)
|
|
|
|
jsr Assign88to44
|
|
sty temp1
|
|
sec
|
|
sbc temp1
|
|
rts
|
|
|
|
|
|
Add44to88:
|
|
|
|
; A,X(8.8) = A,X(8.8) + Y(4.4)
|
|
|
|
sta temp2
|
|
stx temp3
|
|
tya
|
|
jsr Assign44to88
|
|
clc
|
|
sta temp1
|
|
txa
|
|
adc temp3
|
|
tax
|
|
lda temp1
|
|
adc temp2
|
|
rts
|
|
|
|
|
|
Sub44from88:
|
|
|
|
; A,X(8.8) = A,X(8.8) - Y(4.4)
|
|
|
|
sta temp2
|
|
stx temp3
|
|
tya
|
|
jsr Assign44to88
|
|
sec
|
|
sta temp1
|
|
lda temp3
|
|
stx temp3
|
|
sbc temp3
|
|
tax
|
|
lda temp2
|
|
sbc temp1
|
|
rts
|
|
|
|
missile0x = $80
|
|
missile1x = $81
|
|
ballx = $82
|
|
|
|
objecty = $83
|
|
missile0y = $83
|
|
missile1y = $84
|
|
bally = $85
|
|
|
|
; multisprite stuff below - 5 bytes each starting with spritex
|
|
|
|
SpriteIndex = $86
|
|
|
|
player0x = $87
|
|
NewSpriteX = $88 ; X position
|
|
player1x = $88
|
|
player2x = $89
|
|
player3x = $8A
|
|
player4x = $8B
|
|
player5x = $8C
|
|
|
|
player0y = $8D
|
|
NewSpriteY = $8E ; Y position
|
|
player1y = $8E
|
|
player2y = $8F
|
|
player3y = $90
|
|
player4y = $91
|
|
player5y = $92
|
|
|
|
NewNUSIZ = $93
|
|
_NUSIZ1 = $93
|
|
NUSIZ2 = $94
|
|
NUSIZ3 = $95
|
|
NUSIZ4 = $96
|
|
NUSIZ5 = $97
|
|
|
|
NewCOLUP1 = $98
|
|
_COLUP1 = $98
|
|
COLUP2 = $99
|
|
COLUP3 = $9A
|
|
COLUP4 = $9B
|
|
COLUP5 = $9C
|
|
|
|
SpriteGfxIndex = $9D
|
|
|
|
player0pointer = $A2
|
|
player0pointerlo = $A2
|
|
player0pointerhi = $A3
|
|
|
|
;P0Top = $A4
|
|
P0Top = temp5
|
|
P0Bottom = $A4
|
|
P1Bottom = $A5
|
|
|
|
player1pointerlo = $A6
|
|
player2pointerlo = $A7
|
|
player3pointerlo = $A8
|
|
player4pointerlo = $A9
|
|
player5pointerlo = $AA
|
|
|
|
player1pointerhi = $AB
|
|
player2pointerhi = $AC
|
|
player3pointerhi = $AD
|
|
player4pointerhi = $AE
|
|
player5pointerhi = $AF
|
|
|
|
player0height = $B0
|
|
spriteheight = $B1 ; heights of multiplexed player sprite
|
|
player1height = $B1
|
|
player2height = $B2
|
|
player3height = $B3
|
|
player4height = $B4
|
|
player5height = $B5
|
|
|
|
PF1temp1 = $B6
|
|
PF1temp2 = $B7
|
|
PF2temp1 = $B8
|
|
PF2temp2 = $B9
|
|
|
|
pfpixelheight = $BA
|
|
|
|
; playfield is now a pointer to graphics
|
|
playfield = $BB
|
|
PF1pointer = $BB
|
|
|
|
PF2pointer = $BD
|
|
|
|
statusbarlength = $BF
|
|
aux3 = $BF
|
|
|
|
lifecolor = $C0
|
|
pfscorecolor = $C0
|
|
aux4 = $C0
|
|
|
|
P1display = temp2 ; temp2 and temp3
|
|
lifepointer = $c1
|
|
lives = $c2
|
|
pfscore1 = $c1
|
|
pfscore2 = $c2
|
|
aux5 = $c1
|
|
aux6 = $c2
|
|
|
|
playfieldpos = $C3
|
|
|
|
RepoLine = temp4
|
|
|
|
scorepointers = $C4
|
|
|
|
temp1 = $CA ;used by kernel. can be used in program too, but
|
|
temp2 = $CB ;are obliterated when drawscreen is called.
|
|
temp3 = $CC
|
|
temp4 = $CD
|
|
temp5 = $CE
|
|
temp6 = $CF
|
|
temp7 = $D0 ; This is used to aid in bankswitching
|
|
|
|
score = $D1
|
|
pfheight = $D4
|
|
scorecolor = $D5 ;need to find other places for these, possibly...
|
|
rand = $D6
|
|
|
|
|
|
|
|
A = $d7
|
|
a = $d7
|
|
B = $d8
|
|
b = $d8
|
|
C = $d9
|
|
c = $d9
|
|
D = $da
|
|
d = $da
|
|
E = $db
|
|
e = $db
|
|
F = $dc
|
|
f = $dc
|
|
G = $dd
|
|
g = $dd
|
|
H = $de
|
|
h = $de
|
|
I = $df
|
|
i = $df
|
|
J = $e0
|
|
j = $e0
|
|
K = $e1
|
|
k = $e1
|
|
L = $e2
|
|
l = $e2
|
|
M = $e3
|
|
m = $e3
|
|
N = $e4
|
|
n = $e4
|
|
O = $e5
|
|
o = $e5
|
|
P = $e6
|
|
p = $e6
|
|
Q = $e7
|
|
q = $e7
|
|
R = $e8
|
|
r = $e8
|
|
S = $e9
|
|
s = $e9
|
|
T = $ea
|
|
t = $ea
|
|
U = $eb
|
|
u = $eb
|
|
V = $ec
|
|
v = $ec
|
|
W = $ed
|
|
w = $ed
|
|
X = $ee
|
|
x = $ee
|
|
Y = $ef
|
|
y = $ef
|
|
Z = $f0
|
|
z = $f0
|
|
|
|
spritesort = $f1 ; helps with flickersort
|
|
spritesort2 = $f2 ; helps with flickersort
|
|
spritesort3 = $f3
|
|
spritesort4 = $f4
|
|
spritesort5 = $f5
|
|
|
|
stack1 = $f6
|
|
stack2 = $f7
|
|
stack3 = $f8
|
|
stack4 = $f9
|
|
; the stack bytes above may be used in the kernel
|
|
; stack = F6-F7, F8-F9, FA-FB, FC-FD, FE-FF
|
|
|
|
MAC RETURN ; auto-return from either a regular or bankswitched module
|
|
ifnconst bankswitch
|
|
rts
|
|
else
|
|
jmp BS_return
|
|
endif
|
|
ENDM
|
|
|
|
|
|
;
|
|
; Inclues go below - order is crucial, since this is also the order in which
|
|
; they will appear in the generated assembly file
|
|
;
|
|
|
|
|
|
; header file
|
|
multispriteheader.asm
|
|
|
|
|
|
multisprite_kernel.asm
|
|
|
|
; standard startup routine.
|
|
startup.asm
|
|
|
|
|
|
; below are collections of subroutines and functions
|
|
; if you have any more to add, put them immediately below this line.
|
|
|
|
std_routines.asm
|
|
|
|
; The overscan routine goes below. it sets up sprites for the std_kernel.
|
|
; if you have any routines that will not run until the overscan period,
|
|
; put them immediately below this line.
|
|
|
|
|
|
; below is the generated batari Basic file
|
|
|
|
bB.asm
|
|
|
|
|
|
; score graphics.
|
|
score_graphics.asm
|
|
|
|
; below is the footer, which contains the score digits and startup vectors.
|
|
; If you want to create your own custom score digits, you may hack the file below,
|
|
; but first you should rename it to something else.
|
|
|
|
2600basicfooter.asm
|