|
Subject: notBD 0.12 - some extra graphics From: "Andrew Davie" <atari2600@xxxxxxxxxxxxx> Date: Wed, 12 Jan 2005 00:20:26 +1100 |
Attachment:
notBD12JAN2005b.zip
Description: Zip compressed data
Attachment:
01911734.jpg
Description: JPEG image
;------------------------------------------------------------------------------ ; not-Boulderdash! Copyright (C)2003-2005 Andrew Davie ; This is a testbed for background animation games. ; Display technology developed late 2004 by Andrew Davie
; The genesis of the large-sprite system contained herein comes from Eckhard Stohlberg's ; fine work on the 'BIGTWO' sprite system (see the [stella] list archives at ; http://www.biglist.com/lists/stella/archives/ ) and in his preliminary fighter code ; kindly loaned to assist in creating this program.
; The sprite system this program uses is somewhat different to Eckhard's - being more ; efficient and capable (in terms of sprite display) but does essentially retain the ; positioning and movement system of the initial system. Many thanks ES!
; This code is for a 512KB cartridge using the $3F bank-switching scheme. If running ; with Z26 emulator (v1.57+) use -g11 switch on command-line.
;------------------------------------------------------------------------------ ; COLOUR BITMAP COLOUR CYCLING TESTBED ; Code Copyright (C)2003 Andrew Davie -- atari2600@xxxxxxxxxxxxx ; May be freely used for private, educational and research purposes. ; If you wish to profit from it, please ask me for permission first. ; Distributed to the [stella] list 30/March/2003
FIXED_BANK = 63 * 2048 ;--> 128K ROM for KK/CC2 compatibility ;FIXED_BANK = 239 * 2048 ;--> 480K ROM for KK/CC2 compatibility ;FIXED_BANK = 255 * 2048 ;--> 512K ROM tested OK ;FIXED_BANK = 127 * 2048 ;--> 256K ROM tested OK
NTSC = 0 PAL = 1 SECAM = 2
#ifconst COLOUR #else
COLOUR = PAL ; <-- change THIS to NTSC, PAL, or SECAM #endif
; THE SCREEN BUFFERS... ; We have a double-buffered bitmap screen system. Each of the screens itself ; is composed of two 'frames' -- as we're displaying using an interlaced display ; system. Each screen/frame buffer is in its own RAM bank, as it is close to ; 1K in size. In theory, we fill the non-visible pair of frame buffers (eg: ; Screen0A *and* Screen0B), and then switch the display system to use these ; now-completed buffers -- freeing Screen1A and Screen1B for the next draw.
BYTES_PER_LINE = 5 ; PF0 is double-packed! SCREEN_WIDTH = 10 ; board characters per line (DIFFICULT TO CHANGE)
LINES_PER_CHAR = 18 ; MULTIPLE OF 3 SO RGB INTERFACES CHARS OK SCREEN_LINES = 10 ; number of scanlines in screen buffer
SCREEN_DEPTH = SCREEN_LINES * LINES_PER_CHAR SCREEN_ARRAY_SIZE = SCREEN_WIDTH * SCREEN_LINES
; Note: we're balancing lines per screen (LINES_PER_CHAR * SCREEN_LINES) against scanlines ; which should be 192 or preferably less so we can display status line data ; against 1K (BYTES_PER_LINE * SCREEN_LINES * LINES_PER_CHAR ) RAM limit for buffer ; against aspect ratio of characters (square is about 24 lines per char). ; against the cost per character for drawing and ROM (the less lines the better). ; The best balance seems to be 18 lines/char @ 9 lines/screen. Also Try 18/10
processor 6502
include "vcs.h"
include "macro.h"BGCHRONO = 0 SPRITES = 0 DEBUG = 0 ; non-zero for debug stuff
D0 = 1 D1 = 2 D2 = 4 D3 = 8 D4 = 16 D5 = 32 D6 = 64 D7 = 128
SET_BANK_RAM = $3E ; write address to switch RAM banks
; these live at $1000-$13FF (READ) and +$400 (WRITE)BLACK = 0 NTSC_RED = %00110110 ; NTSC colours NTSC_GREEN = %11001000 NTSC_BLUE = %01110110
PAL_RED = $66 ;64 ; PAL colours $C8? PAL_GREEN = $56 ;54 PAL_BLUE = $D6 ;D4
#if COLOUR = NTSC RED = NTSC_RED GREEN = NTSC_GREEN BLUE = NTSC_BLUE #endif
#if COLOUR = PAL RED = PAL_RED GREEN = PAL_GREEN BLUE = PAL_BLUE #endif
INTERLACED = 1 ; zero for standard Interleaved ChronoColour(TM) ; non-0 generates interlaced image
BIG_ROWS = 1 BIG_COLS = 6 ; DO NOT CHANGE
MAC NEWBANK ; bank name
SEG {1}
ORG ORIGIN
RORG $F000
{1} SET ORIGIN / 2048
ORIGIN SET ORIGIN + 2048
_CURRENT_BANK SET {1}
ENDM
MAC VECTOR ; just a word pointer to code .word {1} ENDM
MAC SETBANK lda #{1} sta ROM_Bank ; store as last-switched bank variable sta SET_BANK ; actually switch ROM bank ENDM
MAC ANIMATION lda #<{1} sta ObjAnimLO,x lda #>{1} sta ObjAnimHI,x lda #1 sta ObjDelay,x
lda ObjFlag,x ora #OBJFLAG_WAIT ; animation in progress sta ObjFlag,x
MAC HANDLER
ldy #{1}*2
jsr SetHandler
ENDM ldy #STATE_{1}*2
jmp SetState MAC CALL ;label
lda #{1}_BANK
sta SET_BANK
sta ROM_Bank
jsr {1}
ENDM MAC DEFINE_SUBROUTINE ; name of subroutine
BANK_{1} = _CURRENT_BANK ; bank in which this subroutine resides
SUBROUTINE ; keep everything local
{1} ; entry point
ENDM SEG.U variables
ORG $80BDF_Line ds 1 ; line counter BDF_LastLine ds 1
BDS_LastChar ds 1 BDS_CharPointer ds 1 BufferedJoystick ds 1
BoardScrollY ds 1 ; scroll position in board (Y) BoardScrollX ds 1 ; scroll position in board (X) ManY ds 1 ManX ds 1 OldX ds 1 OldY ds 1
rnd ds 2 timer ds 1 retry ds 1 BASE_Bank ds 1 BASE_Flag_Bank ds 1
ScreenMask ds 1 NegMask ds 2 ScreenAddress ds 2 ScreenAddressWRITE ds 2
field ds 1 ; for interlace toggle BuildMode ds 1 ; steps through the game/screen build process clearer ds 1 tscol ds 2 tsRow ds 1 Character ds 2 Character2 ds 2
;DrawX ds 2 ;DrawY ds 1 ;CenterX ds 2 ;CenterY ds 1 ;FrameBank ds 1
VisualX ds 2 VisualY ds 1
LoopCount ds 1 SPBASE ds BIG_ROWS * BIG_COLS * 2
BGColour ds 1 BGPlayer ds 1
Temp ds 2 Anim ds 2 RGBVec ds 2 FrameCount ds 1
Player ds 1 FrameAddress ds 2 Phase ds 1 Phase2 ds 1 switch ds 1
RAM_Bank ds 1 ; last switched RAM bank (not accessible if ROM subsequently switched) ROM_Bank ds 1 ; last switched ROM bank (not accessible if RAM subsequently switched)
PCount ds 1 Audio ds 2
;---- Flags ds 1 DrawStackPointer ds 1 ; points to start entry of drawing stack (-1 = nothing to draw)
; -------L
; L = locked to opponent#if 0 LineR0X ; 6 columns of each of RED, GREEN, BLUE LineR0 ds 2 ; 6 columns of RED sub-image LineR1 ds 2 LineR2 ds 2 LineR3 ds 2 LineR4 ds 2 LineR5 ds 2
LineG0 ds 2 ; 6 columns of GREEN sub-image LineG1 ds 2 LineG2 ds 2 LineG3 ds 2 LineG4 ds 2 LineG5 ds 2
LineB0 ds 2 ; 6 columns of BLUE sub-image LineB1 ds 2 LineB2 ds 2 LineB3 ds 2 LineB4 ds 2 LineB5 ds 2 #endif
;---- ; Object variables
ObjXPosition ds BIG_SPRITES ObjYPosition ds BIG_SPRITES
; F-------
; F = facing direction (0 = right, 1 = left)
; - = unusedObjDelay ds BIG_SPRITES ; delay count for frame animation ObjAnimLO ds BIG_SPRITES ; animation pointer lo byte ObjAnimHI ds BIG_SPRITES ; animation pointer hi byte objAnimBank ds BIG_SPRITES ; bank containing animation
ObjStateLO ds BIG_SPRITES ; state table lo byte ObjStateHI ds BIG_SPRITES ; state table hi byte
ObjFSMLO ds BIG_SPRITES ; FSM system lo byte ObjFSMHI ds BIG_SPRITES ; FSM system hi byte
ObjFlag ds BIG_SPRITES ObjFrame ds BIG_SPRITES ObjFrameBank ds BIG_SPRITES ObjPhase ds BIG_SPRITES
Colour ds 3 Count ds 1
STACK_SPACE SET 6 ; bytes for generic use (including jsr) OVERLAY_SIZE SET SCREEN_WIDTH + 10
#if * > $FF - STACK_SPACE
ERR
#endif #if * - Overlay > OVERLAY_SIZE
ERR
#endif
ENDM ; This overlay variable is used for the overlay variables. That's OK.
; However, it is positioned at the END of the variables so, if on the off chance we're overlapping
; stack space and variable, it is LIKELY that that won't be a problem, as the temp variables
; (especially the latter ones) are only used in rare occasions. ; FOR SAFETY, DO NOT USE THIS AREA DIRECTLY (ie: NEVER reference 'Overlay' in the code)
; ADD AN OVERLAY FOR EACH ROUTINE'S USE, SO CLASHES CAN BE EASILY CHECKEDOverlay ds OVERLAY_SIZE ;--> overlay (share) variables
VALIDATE_OVERLAY; EACH OF THESE ARE VARIABLES (TEMPORARY) USED BY ONE ROUTINE (AND IT'S SUBROUTINES) ; THAT IS, LOCAL VARIABLES. USE 'EM FREELY, THEY COST NOTHING
SEG.U OVERLAY_BuildDrawFlags
org Overlay SEG.U OVERLAY_TimeSlice
org OverlayTS_Vector ds 2 ; vector to correct processing code
ECHO "FREE BYTES IN IN OVERLAY_TimeSlice = ", OVERLAY_SIZE - ( * - Overlay )
VALIDATE_OVERLAY SEG.U OVERLAY_DrawNewCharacters
org OverlayDNC_CharCount ds 1 ; character draw counter
ECHO "FREE BYTES IN IN OVERLAY_DrawNewCharacters = ", OVERLAY_SIZE - ( * - Overlay )
VALIDATE_OVERLAY SEG.U OVERLAY_ClearScreen
org OverlayCS_Line ds 1
CS_BoardAddress ds 2
ECHO "FREE BYTES IN IN OVERLAY_ClearScreen = ", OVERLAY_SIZE - ( * - Overlay )
VALIDATE_OVERLAY SEG.U OVERLAY_BuildDrawStack
org Overlay
BDS_DrawFlag ds 2
BDS_ScreenBuffer ds 2
ECHO "FREE BYTES IN IN OVERLAY_BuildDrawStack = ", OVERLAY_SIZE - ( * - Overlay )
VALIDATE_OVERLAY SEG.U OVERLAY_SwapDrawBuffer
org Overlay
SDB_Address ds 2
ECHO "FREE BYTES IN IN OVERLAY_SwapDrawBuffer = ", OVERLAY_SIZE - ( * - Overlay )
VALIDATE_OVERLAY SEG.U OVERLAY_ChronoOverlay
org Overlay
ChronoBank ds 3
ChronoColour ds 3
ScreenPtr ds 2
ECHO "FREE BYTES IN IN ChronoOverlay = ", OVERLAY_SIZE - ( * - Overlay )
VALIDATE_OVERLAY
;============================================================================== ; NOW THE VERY INTERESTING '3E' RAM BANKS ; EACH BANK HAS A READ-ADDRESS AND A WRITE-ADDRESS, WITH 2k TOTAL
RAM_3E = $1000 RAM_SIZE = $400 RAM_WRITE = $400 ; add this to RAM address when doing writes
MAC NEWRAMBANK ; bank name
SEG.U {1}
ORG ORIGIN
RORG RAM_3E
{1} SET ORIGIN / RAM_SIZE
ORIGIN SET ORIGIN + RAM_SIZE
ENDM MAC VALIDATE_RAM_SIZE
#if * - RAM_3E > RAM_SIZE
ERR
#endif
ENDM NEWRAMBANK BANK_SCREEN_0B ; MIRROR of BANK_SCREEN_0A
ds BYTES_PER_LINE * SCREEN_DEPTH ; the actual bitmap buffer
NEWRAMBANK BANK_SCREEN_1A ; MIRROR of BANK_SCREEN_0A
ds BYTES_PER_LINE * SCREEN_DEPTH ; the actual bitmap buffer
NEWRAMBANK BANK_SCREEN_1B ; MIRROR of BANK_SCREEN_0A
ds BYTES_PER_LINE * SCREEN_DEPTH ; the actual bitmap buffer; Note that when we are drawing, we *ONLY* have to draw the characters that are ; different between our ScreenXXBuffer[][] and the Board[][]. Those which are ; the same (which will be MOST of the screen MOST of the time) will already have ; their correct shape in the ScreenXX[][] bitmap.
; Now the interesting 'BOARD' -- which in reality is a free-form system of M*N ; rows and columns. We need to reserve enough RAM for the board's entirety, but ; don't really care much how it overlaps the 1K bank limit. The code accessing ; the board *MUST* calculate and take account of the correct RAM bank to switch ; when accessing. Ouch!
SIZE_BOARD_X = 64 SIZE_BOARD_Y = 32 SIZE_BOARD = SIZE_BOARD_X * SIZE_BOARD_Y
ORIGIN SET ( * + RAM_SIZE - 1 ) / RAM_SIZE ORIGIN SET ORIGIN * RAM_SIZE
; The objects are a list of X,Y positions into the BOARD. Each of these is a board ; position of something that needs to be processed. These things include anything ; that animates. Objects which no longer need processing do not re-add themselves ; to the object stack. There are two stacks -- the one being processed, and the ; one for the next processing iteration.
ObjStackX ds 256 ; X coord of object to process ObjStackY ds 256 ; Y coord of object to process
NEWRAMBANK BANK_RAM_X ; free space here VALIDATE_RAM_SIZE
#if ORIGIN > 32*1024 ERR "RAM overflow" #endif
;============================================================================== ; Include all the graphics into separate 2K segments
NEWBANK FRAMEBANK09
include "Graphics\bank09.asm" NEWBANK FRAMEBANK02
include "Graphics\bank02.asm" NEWBANK FRAMEBANK06
include "Graphics\bank06.asm" NEWBANK FRAMEBANK07
include "Graphics\bank07.asm" NEWBANK FRAMEBANK08
include "Graphics\bank08.asm" NEWBANK FRAMEBANK13
include "Graphics\bank13.asm" NEWBANK FRAMEBANK00
include "Graphics\bank00.asm" NEWBANK FRAMEBANK01
include "Graphics\bank01.asm" NEWBANK FRAMEBANK04
include "Graphics\bank04.asm" NEWBANK FRAMEBANK05
include "Graphics\bank05.asm" NEWBANK FRAMEBANK14
include "Graphics\bank14.asm" NEWBANK FRAMEBANK15
include "Graphics\bank15.asm" NEWBANK FRAMEBANK16
include "Graphics\bank16.asm" NEWBANK FRAMEBANK17
include "Graphics\bank17.asm" NEWBANK FRAMEBANK18
include "Graphics\bank18.asm" NEWBANK FRAMEBANK19
include "Graphics\bank19.asm"
;==============================================================================; NEWBANK BLUEBANK ; include "testblue.asm"
;------------------------------------------------------------------------------ ; NEWBANK REDBANK ; include "testred.asm"
;------------------------------------------------------------------------------ ; NEWBANK GREENBANK ; include "testgreen.asm"
NEWBANK MOVIE0 include "Movie\0red.asm"
NEWBANK MOVIE1
include "Movie\0blue.asm" NEWBANK MOVIE2
include "Movie\1green.asm" NEWBANK MOVIE3
include "Movie\2red.asm"
include "Movie\2green.asm" NEWBANK MOVIE4
include "Movie\2blue.asm"
include "Movie\3red.asm" NEWBANK MOVIE5
include "Movie\3green.asm"
include "Movie\3blue.asm" NEWBANK MOVIE6
include "Movie\4red.asm"
include "Movie\4green.asm" NEWBANK MOVIE7
include "Movie\4blue.asm"
include "Movie\5red.asm" NEWBANK MOVIE8
include "Movie\5green.asm"
include "Movie\5blue.asm" NEWBANK MOVIE0B
include "Movie\0green.asm" NEWBANK MOVIE1B
include "Movie\1red.asm" NEWBANK MOVIE1BLUE
include "Movie\1blue.asm"
;------------------------------------------------------------------------------ NEWBANK TITLESCREEN
DoMovie rts
lda #0
sta PCount ldy PCount
lda PFrame,y
bpl PCOKC
lda #0
sta PCount
beq rr
PCOKC
ldy #3
jsr TitleScreen clc
lda Audio
adc #0
sta Audio
lda Audio+1
adc #1
sta Audio+1PFrame .byte 0,1,0,1,0,1,0,1,0,1,0,1,0,1,4,5,4,5,4,5,4,5,4,5,-1 #endif
; The image file is composed of strips (corresponding to PF0-PF2, repeated) ; which are decomposed by a utility from colour-separated RGB components of ; an original image. The displayed image is 40 pixels x 192 pixels.
; For access to the conversion/decomposition tool which generated these data ; please contact me privately.
asl
tay ; word index
lda ChronoScreen,y
sta ScreenPtr
lda ChronoScreen+1,y
sta ScreenPtr+1 iny
lda (ScreenPtr),y
sta ChronoBank+2SetupLinePtr
iny
lda (ScreenPtr),y
sta LineR0,x
inx
cpx #42
bne SetupLinePtr lda #RED
sta Colour
lda #GREEN
sta Colour+1
lda #BLUE
sta Colour+2 lda #2
sta Phase jsr TitleFrame
jsr TitleFrame dec FrameCount
bne AnotherFrame;------------------------------------------------------------------------------ ; START OF DISPLAY
#if COLOUR = NTSC lda #238 ; NTSC #else lda #238 #endif sta TIM64T
;-------------------------------------------------------------------------- ; START OF COLOUR BITMAP DISPLAY KERNEL
ldx Phase
lda NextPhase,x
sta Phase lda #0
sta Count
Nzap lda #RED
sta ChronoColour
lda #GREEN
sta ChronoColour+1
lda #BLUE
sta ChronoColour+2 sty WSYNC
sty PF0
sty PF1
sty PF2 lda #%01000010
sta VBLANK ; end of screen - enter blanking#else
lda #88Overscan2 lda INTIM
bne Overscan2
.word BeachFrame0 .word BeachFrame1 .word BeachFrame2 .word BeachFrame3 .word BeachFrame4 .word BeachFrame5
BeachFrame0 .byte MOVIE0, MOVIE0B, MOVIE1 .word testred0_STRIP_0, testred0_STRIP_1, testred0_STRIP_2, testred0_STRIP_3, testred0_STRIP_4, testred0_STRIP_5, AUDIO0RED .word testgreen0_STRIP_0, testgreen0_STRIP_1, testgreen0_STRIP_2, testgreen0_STRIP_3, testgreen0_STRIP_4, testgreen0_STRIP_5, $8000 .word testblue0_STRIP_0, testblue0_STRIP_1, testblue0_STRIP_2, testblue0_STRIP_3, testblue0_STRIP_4, testblue0_STRIP_5, $8000
BeachFrame1 .byte MOVIE1B, MOVIE2, MOVIE1BLUE .word testred1_STRIP_0, testred1_STRIP_1, testred1_STRIP_2, testred1_STRIP_3, testred1_STRIP_4, testred1_STRIP_5, $8000 .word testgreen1_STRIP_0, testgreen1_STRIP_1, testgreen1_STRIP_2, testgreen1_STRIP_3, testgreen1_STRIP_4, testgreen1_STRIP_5, $8000 .word testblue1_STRIP_0, testblue1_STRIP_1, testblue1_STRIP_2, testblue1_STRIP_3, testblue1_STRIP_4, testblue1_STRIP_5, $8000
BeachFrame2 .byte MOVIE3, MOVIE3, MOVIE4 .word testred2_STRIP_0, testred2_STRIP_1, testred2_STRIP_2, testred2_STRIP_3, testred2_STRIP_4, testred2_STRIP_5, $8000 .word testgreen2_STRIP_0, testgreen2_STRIP_1, testgreen2_STRIP_2, testgreen2_STRIP_3, testgreen2_STRIP_4, testgreen2_STRIP_5, $8000 .word testblue2_STRIP_0, testblue2_STRIP_1, testblue2_STRIP_2, testblue2_STRIP_3, testblue2_STRIP_4, testblue2_STRIP_5, $8000
BeachFrame3 .byte MOVIE4, MOVIE5, MOVIE5 .word testred3_STRIP_0, testred3_STRIP_1, testred3_STRIP_2, testred3_STRIP_3, testred3_STRIP_4, testred3_STRIP_5, $8000 .word testgreen3_STRIP_0, testgreen3_STRIP_1, testgreen3_STRIP_2, testgreen3_STRIP_3, testgreen3_STRIP_4, testgreen3_STRIP_5, $8000 .word testblue3_STRIP_0, testblue3_STRIP_1, testblue3_STRIP_2, testblue3_STRIP_3, testblue3_STRIP_4, testblue3_STRIP_5, $8000
BeachFrame4 .byte MOVIE6, MOVIE6, MOVIE7 .word testred4_STRIP_0, testred4_STRIP_1, testred4_STRIP_2, testred4_STRIP_3, testred4_STRIP_4, testred4_STRIP_5, $8000 .word testgreen4_STRIP_0, testgreen4_STRIP_1, testgreen4_STRIP_2, testgreen4_STRIP_3, testgreen4_STRIP_4, testgreen4_STRIP_5, $8000 .word testblue4_STRIP_0, testblue4_STRIP_1, testblue4_STRIP_2, testblue4_STRIP_3, testblue4_STRIP_4, testblue4_STRIP_5, $8000
BeachFrame5 .byte MOVIE7, MOVIE7, MOVIE8 .word testred5_STRIP_0, testred5_STRIP_1, testred5_STRIP_2, testred5_STRIP_3, testred5_STRIP_4, testred5_STRIP_5, $8000 .word testgreen5_STRIP_0, testgreen5_STRIP_1, testgreen5_STRIP_2, testgreen5_STRIP_3, testgreen5_STRIP_4, testgreen5_STRIP_5, $8000 .word testblue5_STRIP_0, testblue5_STRIP_1, testblue5_STRIP_2, testblue5_STRIP_3, testblue5_STRIP_4, testblue5_STRIP_5, $8000
;=============================================================================== #endif
InitX .XP SET 80-48
REPEAT BIG_SPRITES .byte .XP .XP SET .XP + 48 REPEND
; There's no particular reason why this code lives in a separate bank ; but it's as good-a-test as any for checking the bankswitching is working
sta field
sta BuildMode ; start at the beginning of the build lda #0
sta Flags
sta Player lda InitX,x
sta ObjXPosition,x dex
bpl PreClear;loopx inx ; stx COLUBK ; jmp loopx
;---------------------------------- ; Hardwire init a single creature...
; lda #D7 ; sta ObjFacing ;todo currently fucked
ldx #1
HANDLER EVENT_INIT2; ldx #0 ; HANDLER 0
lda #BGCOL sta BGColour jmp NewFrame
#if 0 include "Graphics\bank_FRAMETABLE.asm" ;------------------------------------------------------------------------------ ; OBJECT Animation ; *MUST* BE IN ONE BANK
MAC SHOW .byte {1},{2} ENDM
MAC SHOWRGB
REPEAT {2}
SHOW FRAME_{1}RED,1
;SHOW FRAME_{1}GREEN,1
SHOW FRAME_{1}BLUE,1
REPEND
ENDM .byte TOKEN_LOCK
.byte {1}*2
MAC UNLOCK .byte TOKEN_UNLOCK ENDM
MAC GOTO
.byte TOKEN_JUMP
.word {1}
ENDMMAC DONE .byte TOKEN_DONE ENDM
MAC MOVE
.byte TOKEN_MOVE
.word {1}
.byte {2}
ENDMMAC FLIP .byte TOKEN_FLIP ENDM
noAnim lda #NOFRAME sta ObjFrame,x rts
lda ObjAnimHI,x
beq noAnim ; animation switched off - use a null frame
lda ObjAnimHI,x lda ObjDelay,x
beq exitAnim ; static frame - no animation
dec ObjDelay,x
bne exitAnim ; not ready to changeReAnimate lda ObjAnimHI,x
sta Anim+1
lda ObjAnimLO,x
sta Anim ; (Anim) points to frame sequenceReReAnim ldy #0
lda (Anim),y
bpl NormalFrame asl
tay lda AnimVec,y
sta Temp
lda AnimVec+1,y
sta Temp+1
jmp (Temp);------------------------------------------------------------------------------ ; Automatically define tokens and a vector table to token-processing code ; This is fairly neat, as the ordering of the entries in the table auto-generates ; the appropriate equates to access the table correctly!
TOK SET 128
MAC TOKEN
TOKEN_{1} equ TOK
TOK SET TOK + 1
VECTOR Animate{1}
ENDMAnimVec TOKEN JUMP
TOKEN LOCK
TOKEN MOVE
TOKEN UNLOCK
TOKEN DONE
TOKEN FLIP
TOKEN COLOUR
TOKEN SYNCHAnimateDONE lda ObjFlag,x and #(~OBJFLAG_WAIT)&$FF sta ObjFlag,x lda #1 jmp AnimUp
lda ObjFacing,x
eor #D7
sta ObjFacing,xlda #1 jmp AnimUp
iny
lda (Anim),y
sta ObjDelay,x ; should be < 128 clc
lda Anim
adc #2
sta ObjAnimLO,x
lda Anim+1
adc #0
sta ObjAnimHI,x
rts lda ObjXPosition,x
pha
lda ObjYPosition,x
pha lda Flags
ora #FLAG_LOCK
sta Flags txa
eor #1
tax ; other player ldy #1
lda (Anim),y
tay
jsr SetHandler ; cause other player to react pla
sta ObjYPosition,x
pla
sta ObjXPosition,x txa
eor #1
taxAnimUp clc
adc Anim
sta Anim
lda Anim+1
adc #0
sta Anim+1 lda Flags
and #(~FLAG_LOCK)&$FF
sta Flags lda #1
jmp AnimUp ldy #1
lda (Anim),y
sta ObjAnimLO,x
iny
lda (Anim),y
sta ObjAnimHI,x
jmp ReAnimate
AnimateCOLOUR ldy #1 lda (Anim),y sta BGPlayer lda #2 jmp AnimUp
lda (Anim),y
sta Temp
iny
lda (Anim),y
sta Temp+1 lda ObjFacing,x
bpl MoveRight sec
lda #0
sbc Temp
sta Temp
lda #0
sbc Temp+1
sta Temp+1 clc
lda DrawX
adc Temp
sta DrawX
lda DrawX+1
adc Temp+1
sta DrawX+1 iny
lda (Anim),y
clc
adc DrawY
sta DrawY clc
lda Anim
adc #4
sta Anim
lda Anim+1
adc #0
sta Anim+1#if BIG_SPRITES = 1
;lda #0
#else
;lda #2
#endif ;sta Phase
lda #1
jmp AnimUp
; Animations processing code proceeds until it has a frame and duration ; The duration is in TV-frames, and counts down. When 0, the next 'command' in the ; animation sequence is processed. Animations must use the GOTO to halt or repeat ; Animations are tokenised interpreted little programs.
; Commands/Macros ; GOTO label Vector to the label ; LOCK event Lock opponents together, sending the opponent the event ; MOVE x,y Adjust position by x,y pixels ; UNLOCK Unlock opponents ; DONE Indicate animation finished (clears OBJFLAG_WAIT for creature) ; FLIP Mirror creature ; SHOW frame,delay Set th creature rame and delay (also halts animation till delay counts to 0)
SHOWRGB 1,4
SHOWRGB 2,4
SHOWRGB 3,4
SHOWRGB 4,4
SHOWRGB 5,4
SHOWRGB 6,4
SHOWRGB 7,4
SHOWRGB 8,4
SHOWRGB 9,4
SHOWRGB 10,4
SHOWRGB 11,4
SHOWRGB 12,4; SHOWRGB CROC,4
GOTO ANIMATION_STAND2 ;SHOWRGB 11,10
GOTO ANIMATION_STAND2
; OBJECT Animation END ;------------------------------------------------------------------------------
;------------------------------------------------------------------------------ ; STATE Processing ; *MUST* BE IN ONE BANK
MAC WAIT SUBROUTINE .HERE lda #<.HERE sta ObjFSMLO,x lda #>.HERE sta ObjFSMHI,x
lda ObjFlag,x
and #OBJFLAG_WAIT
bne .CONT
lda #<{1}
sta Temp
lda #>{1}
sta Temp+1
jmp (Temp) ; vector to the handler now the wait has completed
.CONT
; Or, wait is incomplete, so fall through; Set object's state base ; x = obj ; y = state table (*2)
lda StateTables,y
sta ObjStateLO,x
lda StateTables+1,y
sta ObjStateHI,x; Change object's processing code ; x = obj ; y = new handler entry (word access)
lda ObjStateHI,x
beq NullHandler ; don't handle anything with no entry sta Temp+1
lda ObjStateLO,x
sta Temp iny
lda (Temp),y
beq NullHandler ; no handler present for given event
sta ObjFSMHI,x
dey
lda (Temp),y
sta ObjFSMLO,x; Vector to the creature's processing code ; x = creature
lda ObjFSMLO,x
sta Temp
lda ObjFSMHI,x
sta Temp+1
jmp (Temp)
;------------------------------------------------------------------------------ ; List of events
EVENT_DEFAULT = 0 ; default entry when switching states EVENT_JOY_NULL = 1 EVENT_JOY_UP = 2 EVENT_JOY_DOWN = 3 EVENT_JOY_LEFT = 4 EVENT_JOY_RIGHT = 5 EVENT_ATTACK_THROW = 6
;------------------------------------------------------------------------------ ; Automatically define states and a vector table to state-processing code ; This is fairly neat, as the ordering of the entries in the table auto-generates ; the appropriate equates to access the table correctly!
STATEQ SET 0
MAC STATENTRY
STATE_{1} equ STATEQ
STATEQ SET STATEQ + 1
VECTOR State{1}
ENDMStateTables STATENTRY NORMAL
STATENTRY WAIT;------------------------------------------------------------------------------ ; NORMAL state table ; Each State table is a table of pointers to code processing 'EVENTS'
StateNORMAL
VECTOR NormalInit ; 0 EVENT_DEFAULT
VECTOR NormalWait ; 1 EVENT_JOY_NULL
VECTOR NormalInitRight ;0 ;GetUp ; 4 EVENT_JOY_UP
VECTOR 0 ;NormalInit;AttackThrow1 ; 5 EVENT_JOY_DOWN
VECTOR 0;WalkTurnAround ; 6 EVENT_JOY_LEFT
VECTOR 0;WalkStart ; 7 EVEMT_JOY_RIGHT
VECTOR 0;React_AttackThrow ; 8 EVENT_ATTACK_THROW VECTOR BusyInit ; 0 EVENT_DEFAULT
VECTOR 0 ; 1 EVENT_JOY_NULL
VECTOR 0 ; 4 EVENT_JOY_UP
VECTOR 0 ; 5 EVENT_JOY_DOWN
VECTOR 0 ; 6 EVENT_JOY_LEFT
VECTOR 0 ; 7 EVEMT_JOY_RIGHT
VECTOR 0 ; 8 EVENT_ATTACK_THROW;------------------------------------------------------------------------------ ; BUSY ; Waits until the animation clears the wait flag ; Then reverts to STATE_NORMAL
BusyInit WAIT BusyDone rts
;------------------------------------------------------------------------------ ; NORMAL ; The basic default standing, doing nothing.
NormalInit ANIMATION ANIMATION_STAND HANDLER EVENT_JOY_NULL rts
NormalWait
;WAIT NormalInit
rts ANIMATION ANIMATION_STAND ;RIGHT
HANDLER EVENT_JOY_NULL
rts; STATE Processing END ;------------------------------------------------------------------------------
#endif
NEWBANK BANK_TABLESX; Gives the absolute screen buffer address of the first line of the given character ; Where character number is 0-99 (in, for example, a 10x10 grid) ; Currently hardwired to 10x10 format. ACROSS first then DOWN
; Gives the absolute screen buffer address of the first line of the given character ; Where character number is 0-99 (in, for example, a 10x10 grid) ; Currently hardwired to 10x10 format. ACROSS first then DOWN
.BOARD_LOCATION SET Board
REPEAT SIZE_BOARD_Y
.byte .BOARD_LOCATION / 1024 ; actual bank #
.BOARD_LOCATION SET .BOARD_LOCATION + SIZE_BOARD_X ; note, we CANNOT cross a page boundary within a row
REPENDORIGIN SET FIXED_BANK
NEWBANK THE_FIXED_BANK
RORG $f800 lda rnd
eor timer
lsr
lsr
sbc rnd
lsr
ror rnd+1
ror rnd
ror rndlda rnd nogo rts ;------------------------------------------------------------------------------
down lda ManY cmp #SIZE_BOARD_Y-1 bcs phase0 inc ManY jmp phase0
left lda ManX
beq phase0
dec ManX
jmp phase0#ifconst DOUBLE_BUFFERED
lda BASE_Bank
eor #SWAP_SCREEN
sta BASE_Bank
lda BASE_Flag_Bank
eor #SWAP_FLAG
sta BASE_Flag_Bank
#endif; lda #RED ; sta COLUBK
lda #BANK_TABLESX
sta SET_BANK inx
stx SET_BANK_RAM
#if 0 clc lda ScreenAddress adc #LINES_PER_CHAR - 1 bcc complete
tay
iny lda #0
sta ScreenAddress
sta ScreenAddressWRITE
inc ScreenAddress+1
inc ScreenAddressWRITE+1jmp normal #endif
cvec .word CharacterBlank, CharacterSoil, CharacterRock, CharacterB
.word CharacterDiamond, CharacterDiamond, CharacterWater, CharacterB.byte 0 .byte 0 .byte 240
.byte 0 .byte 0 .byte 240
.byte 0 .byte 0 .byte 240
.byte 0 .byte 128 .byte 176
.byte 0 .byte 0 .byte 224
.byte 0 .byte 0 .byte 240
.byte 240 .byte 0 .byte 0
.byte 240 .byte 0 .byte 64
.byte 240 .byte 0 .byte 32
.byte 240 .byte 0 .byte 64
.byte 240 .byte 0 .byte 0
.byte 0 .byte 0 .byte 96
.byte 0 .byte 96 .byte 224
.byte 0 .byte 224 .byte 240
.byte 00 .byte 224 .byte 224
.byte 0 .byte 96 .byte 96
.byte 0 .byte 32 .byte 32
.byte 64 .byte 0 .byte 96
.byte 96 .byte 96 .byte 96 .byte 224 .byte 0 .byte 240
.byte 240 .byte 224 .byte 224
.byte 96 .byte 0 .byte 96
.byte 96 .byte 32 .byte 32
.byte 0 .byte 0 .byte 0 .byte 102 .byte 102 .byte 0 .byte 0 .byte 0 .byte 51 .byte 255 .byte 238 .byte 0 .byte 0 .byte 0 .byte 34 .byte 102 .byte 34 .byte 0
.byte 68 ;b .byte 68 .byte 102 .byte 102 .byte 102 .byte 238 .byte 238 .byte 238 .byte 255 .byte 255 .byte 238 .byte 238 .byte 102 .byte 102 .byte 102 .byte 102 .byte 34 .byte 34
.byte %01000100 .byte %00000000 .byte %00000000
.byte %10101010 .byte %00000000 .byte %00000000
.byte %00110010 .byte %00000000 .byte %00000000
.byte %10111011 .byte %00000000 .byte %00000000
.byte %00100010 .byte %00000000 .byte %00000000
.byte %01000101 .byte %00000000 .byte %00000000
.byte %00000000 .byte %00010001 .byte %00000000
.byte %00000000 .byte %01000100 .byte %00000000
.byte %00000000 .byte %01000100 .byte %00000000
.byte %00000000 .byte %01010101 .byte %00000000
.byte %00000000 .byte %00011001 .byte %00000000
.byte %00000000 .byte %00100010 .byte %00000000
.byte %01100110 .byte %01100110 .byte %00000000 .byte %11111111 .byte %00010001 .byte %00000000 .byte %11111111 .byte %00110011 .byte %00000000 .byte %11111111 .byte %10011001 .byte %00000000 .byte %11111111 .byte %00100010 .byte %00000000 .byte %01100110 .byte %00000000 .byte %00000000
; The image file is composed of strips (corresponding to PF0-PF2, repeated) ; which are decomposed by a utility from colour-separated RGB components of ; an original image. The displayed image is 40 pixels x 192 pixels.
lda #RED
sta Colour
lda #GREEN
sta Colour+1
lda #BLUE
sta Colour+2 lda BGColour
sta COLUBK clc
lda BASE_Bank
#ifconst DOUBLE_BUFFERED
eor #SWAP_SCREEN
#endif
adc field
sta SET_BANK_RAM ; we DISPLAY the one we're NOT drawing to
sta RAM_Bank
lda INTIM bne VblankLoopBD inc BGColour
VblankLoopBD lda INTIM
bne VblankLoopBD lda SWCHA
;and BufferedJoystick
sta BufferedJoystick;------------------------------------------------------------------------------ ; START OF DISPLAY
#if COLOUR = PAL lda #238 ; NTSC #else lda #236 #endif sta TIM64T
;-------------------------------------------------------------------------- ; START OF COLOUR BITMAP DISPLAY KERNEL
lda #%00100101 sta NUSIZ0
ldx Phase
lda aPhase2,x
sta Phase lda #0
sta Count lda Colour+1 ; 3
sta COLUPF ; 3
ldx ScreenBitmap,y ; 4 stx PF0 ; 3 ldx ScreenBitmap+1*SCREEN_DEPTH,y ; 4 stx PF1 ; 3 ldx ScreenBitmap+2*SCREEN_DEPTH,y ; 4 stx PF2 ; 3
lda ScreenBitmap,y ; 4
asl
asl
asl
asl
sta PF0 ; 3
lda ScreenBitmap+3*SCREEN_DEPTH,y ; 4
sta PF1 ; 3
lda ScreenBitmap+4*SCREEN_DEPTH,y ; 4
sta PF2 ; 3 lda Colour ; 3
sta COLUPF ; 3 lda ScreenBitmap,y ; 4
asl
asl
asl
asl
sta PF0 ; 3
lda ScreenBitmap+3*SCREEN_DEPTH,y ; 4
sta PF1 ; 3
lda ScreenBitmap+4*SCREEN_DEPTH,y ; 4
sta PF2 ; 3 iny ; 2
cpy #SCREEN_DEPTH
bne ScanGreenBD ; 2(3)
beq ScanEndBD ; 2(3) --> <76 lda Colour+2 ; 3
sta COLUPF ; 3
ldx ScreenBitmap,y ; 4 stx PF0 ; 3 ldx ScreenBitmap+1*SCREEN_DEPTH,y ; 4 stx PF1 ; 3 ldx ScreenBitmap+2*SCREEN_DEPTH,y ; 4 stx PF2 ; 3
lda ScreenBitmap,y ; 4 asl asl asl asl
sta PF0 ; 3
lda ScreenBitmap+3*SCREEN_DEPTH,y ; 4
sta PF1 ; 3
lda ScreenBitmap+4*SCREEN_DEPTH,y ; 4
sta PF2 ; 3 iny ; 2
cpy #SCREEN_DEPTH
bne ScanRedBD ; 2(3) ; Screen has been drawn - now just tidy up
lda #0
sta PF0
sta PF1
sta PF2 lda #%01000010
sta VBLANK ; end of screen - enter blanking lda #60
sta TIM64T
PALTiming lda INTIM
bne PALTiming lda #30
sta TIM64TOverscanBD lda INTIM
bne OverscanBD; Clears the entire screen bank area (1K x 4) ; Must reside in fixed bank ; 30 bytes
ldy #BANK_SCREEN_0A lda #0 ldx #0 ClearBank sty SET_BANK_RAM ClearBlock sta ScreenBitmap + RAM_WRITE,x sta ScreenBitmap + RAM_WRITE + $100,x sta ScreenBitmap + RAM_WRITE + $200,x sta ScreenBitmap + RAM_WRITE + $300,x dex bne ClearBlock iny cpy #BANK_SCREEN_1B + 1 bne ClearBank
BuildStart inc BuildMode ; --> BuildBoardStart rts
lda #0
sta BoardY
sta BoardX ; start at top left of board inc BuildMode ; --> BuildBoard
rts; Where we animate the board itself. Each object in the board has its own behaviour and ; this may affect other objects. We scan through the entire board incrementally until ; we reach the end. Note that this process happens over several (many!) frames.
; We update whatever needs to happen at Board[BoardY][BoardX] ; Should also manage budget
ldx BoardY
ldy BoardX
jsr GetBoardChar;Common subroutines ;------------------------------------------------------ ;$Id: common.s,v 1.2.4.2 2002/08/16 04:14:11 Billy Exp $ ;------------------------------------------------------ ;start the vertical sync and set the timer for 37 lines of blank ;the status registers need to be set to alternate between frames, zero and non-zero ;something like lda with the framenum vertical_sync_interlaced subroutine beq even_sync
;this is the vertical sync for the first field of an interlaced frame ;or just a normal non-interlaced vertical sync lda #2 sta WSYNC sta VSYNC ; Begin vertical sync.
sta WSYNC ; First line of VSYNC sta WSYNC ; Second line of VSYNC. lda #0 sta WSYNC ; Third line of VSYNC. sta VSYNC ; (0)
lda #2 ;40 sta VSYNC ; Begin vertical sync. sta WSYNC ; First line of VSYNC sta WSYNC ; Second line of VSYNC.
sta WSYNC ; Third line of VSYNC. ;need 33 cycles until the end of VSYNC
lda #BLACK sta COLUBK ;; but not duplicated below?!!
lda ObjXPosition,x
sta DrawX
lda #1
sta DrawX+1
lda ObjYPosition,x
sta DrawY; jsr AnimateObject ; process object animation sequence
jsr CalculateDrawPosition ; setup position(s) for next VB draw lda ObjFacing,y
and #D7
lsr
lsr
lsr
lsr
sta REFP0
sta REFP1 ;@17 lda BGColour
sta COLUBK_RTS14 nop
rts ; 14-cycle waste lda #$00
sta HMCLR lda SWCHB
lda #D7
sta switch#if DEBUG
lda INTIM
bne Whoops
inc BGColour ; Overflow
Whoops
#endif;------------------------------------------------------------------------------ ; START OF DISPLAY
#if COLOUR = NTSC
lda #221 ; NTSC
#else
lda #238
#endif
sta TIM64T
;? lda #%00010100 ; reflect, priority, 2 pixel wide ball sta CTRLPF ;^?
sta GRP0 sta GRP1
lda BGPlayer
sta COLUP0
sta COLUP1 ; tentative colour
;-------------------------------------------------------------------------- ; Init the loop counters (16 rows each) for each of the rows
lda #127
sta LoopCount lda ObjFrameBank,y
sta SET_BANK sta VDELP0
sta VDELP1 sta REFP0
sta REFP1
#if COLOUR = PAL sta WSYNC lda #42 sta TIM64T PALx lda INTIM bne PALx #endif
;******************************************************************************* ;****************** START OF OVERSCAN PROCESSING TIME ************************** ;*******************************************************************************
lda field #if INTERLACED eor #1 sta field #endif jsr Interlace
;-------------------------------------------------------------------------- ; PLAYER INTERACTION
; lda #0 ; sta SWACNT ; all input bits (IMPLICITLY SET @ STARTUP)
; ldx Player ; bne P1shift
; lsr ; lsr ; lsr ; lsr
; ldy ObjFacing,x ; bpl FacOK
; tay ; and #D3+D2 ; cmp #D3+D2 ; beq FacOK2
; tya ; eor #D3+D2 ; swap left/right if mirrored ;FacOK tay ;FacOK2
; lda JoystickEvent,y ; bmi NullJoy ; an unhandled joystick direction
; asl ; tay
; ldy #EVENT_JOY_NULL*2 ; jsr SetHandler ; handle joystick event
;NullJoy ; lda SWCHB ; and #$01 ; bne NoResetSwitch
;******************************************************************************* ;****************** END OF VERTICAL BLANK PROCESSING TIME ********************** ;*******************************************************************************
Overscan lda INTIM bne Overscan
; Given the current frame of the player, calculate a draw position such that ; the centerpoint is at the creature's (ObjXPosition,ObjYPosition) and that the ; left and right edges are then forced to be onscreen.
; Calculate the frame definition start address. Each frame is a 32-byte ; definition block giving the bank containing the frame and a matrix of ; 16-sprite numbers making up the nx6 grid.
; FORMAT: ; BYTE centerpointx, centerpointy ; BYTES... 0, 1, 2, 3, 4, 5 \ ; 6, 7, 8, 9,10,11 | n x 6 matrix of 16-sprite #s ; .... | ; 24,25,26,27,28,29 /
lda ObjFrame,y ; animation frame (absolute)
asl
adc ObjFrame,y ; Frametable is bank, AddressLO, AddressHI
tax lda FrameTable+1,x
sta FrameAddress
lda FrameTable+2,x
sta FrameAddress+1 lda FrameTable,x
;sta FrameBank
sta ObjFrameBank,y
sta SET_BANK ldx #0
lda ObjFacing,y
bpl nMirror
ldx #BIG_ROWS*BIG_COLS
nMirror
; Now we have a pointer to the frame definition block (FrameAddress) ; Go through the entire BIG_ROWS*BIG_COLS entries and convert the matrix 16-sprite ; number into an absolute address pointing to the sprite data. This will correspond ; nicely to the vars used for the actual draw.
ldy #0
sty CenterX+1
lda (FrameAddress),y
lda #17 ;0 ;tmp
sta CenterX
iny
lda (FrameAddress),y
lda #0 ;tmp
sta CenterY inc Temp+1
ldx Temp+1
lda BaseMirror-1,x
tax
tya pha
lda (FrameAddress),y
asl
tay
lda T128,y
sta SPBASE,x
lda T128+1,y
sta SPBASE+1,x pla
tay
cpy #BIG_ROWS*BIG_COLS+1 bcc Mirrorable
;-------------------------------------------------------------------------- ; Centerpoint Adjustment based on frame
lda ObjFrame,y
bmi SkipRepos lda ObjFacing,y
bpl nM clc
lda #0
sbc CenterX
sta CenterX
lda #0
sbc CenterX+1
sta CenterX+1 clc
lda CenterX
adc #48
sta CenterX
lda CenterX+1
adc #0
sta CenterX+1 sec
lda DrawX
sbc CenterX
sta VisualX
lda DrawX+1
sbc CenterX+1
sta VisualX+1
; OK, so the object is offscreen (to the left) ; This means that, with the centerpoint adjustment, the left edge of the sprite is offscreen ; So we need to adjust the object position (DrawX,DrawY) such that the sprite will be onscreen ; As a minimum, we know we want the sprite to be at (0,DrawY). So we just adjust the ; object position by the negative of the offsreen offset
sec
lda #0
sbc VisualX ; all we really care about - the offset
sta Temp
adc DrawX ; adjust (what will be) the actual coordinate
sta DrawX; lda #1
; sta VisualX+1
lda #0
sta VisualX
beq Onscreen
sec lda VisualX sbc #160-48 sta Temp lda VisualX+1 sbc #1 bcc Onscreen
lda Temp
eor #$FF
adc #0
sta Temp adc DrawX
sta DrawX
lda #160-48 sta VisualX ; lda #1 ; sta VisualX+1
sec
lda DrawY
sbc CenterY
sta VisualY
SkipRepos ldx Player
lda DrawX
sta ObjXPosition,x
lda DrawY
sta ObjYPosition,x
T128 .T128 SET $F000
REPEAT 22
.word .T128
.T128 SET .T128 + 128
REPEND;-------------------------------------------------------------------------- #endif
SETBANK INITBANK
jmp Cart_Init ; init code is in bank 1!#if 0 VectorToBankedSubroutine
lda ROM_Bank
pha lda SubroutineBank,y
sta ROM_Bank
sta SET_BANK lda SubroutineAddrLO,y
sta temp
lda SubroutineAddrHI,y
sta temp+1 pla
sta ROM_Bank
sta SET_BANK
SubroutineBANK #endif
;-------------------------------------------------------------------------- ; Object X,Y positioning ; Timing is absolutely critical here!
ldx VisualY
inx
DelayVert sta WSYNC
dex
bne DelayVert ldx VisualX
clc
lda MoveTable,x
sta HMP0
adc #$10
sta HMP1 lda #1
sta VDELP0
sta VDELP1 lda #3
sta NUSIZ0
sta NUSIZ1 lda #>JNDelayPos
sta Temp+1
lda DelayTable,x
sta Temp
jmp (Temp) sta RESP0
sta RESP1
sta WSYNC
sta HMOVE lda #>JNDelayDraw
sta Temp+1
lda #<JNDelayDraw
clc
adc DelayTable,x
sta Temp ;lda #0
;sta PF2 .byte $c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9
.byte $c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9
.byte $c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9
.byte $c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9,$c9,$c5
ALIGN 256 DelayTable .byte 37, 37 Q SET 36 REPEAT 37 .byte Q, Q, Q Q SET Q-1 REPEND
MoveTable
.byte $30, $20
REPEAT 37
.byte $40, $30, $20
REPEND
;-------------------------------------------------------------------------- ; The beautiful, beautiful, draw loop which draws the entire matrix onscreen ; This caters for an adjustable (at compile-time) number of rows and also ; facilitates double-size pixels.
.S1 SET SPBASE .S2 SET SPBASE + 2 .S3 SET SPBASE + 4 .S4 SET SPBASE + 6 .S5 SET SPBASE + 8 .S6 SET SPBASE + 10
NextPhase .byte 2,0,0 ;1,2,0 ;1,2,0 ; FIXED BANK ALWAYS
PhasePtr .word .LABR,.LABG,.LABB
.word .LABPALR,.LABPALG,.LABPALB.LABG lda #GREEN ; 2
sta COLUP0 ; 3
sta COLUP1 ; 3 lda (.S1),y ; 5
sta GRP0 ; 3
lda (.S2),y ; 5
sta GRP1 ; 3
lda (.S3),y ; 5
sta GRP0 ; 3.LABR lda #RED ; 2
sta COLUP0 ; 3
sta COLUP1 ; 3 lda (.S1),y ; 5
sta GRP0 ; 3
lda (.S2),y ; 5
sta GRP1 ; 3
lda (.S3),y ; 5
sta GRP0 ; 3.LABB lda #BLUE ; 2
sta COLUP0 ; 3
sta COLUP1 ; 3 lda (.S1),y ; 5
sta GRP0 ; 3
lda (.S2),y ; 5
sta GRP1 ; 3
lda (.S3),y ; 5
sta GRP0 ; 3;PALRED = $64 ;PALGREEN = $54 ;PALBLUE = $D4
PALRED = PAL_RED ;$C8 ;$D6 ; secam 8 PALGREEN = PAL_GREEN ;%00110100 ;$42 ; secam 4 PALBLUE = PAL_BLUE ;%01110100 ; secam 2
.LABPALG lda #PALGREEN ; 2
sta COLUP0 ; 3
sta COLUP1 ; 3 lda (.S1),y ; 5
sta GRP0 ; 3
lda (.S2),y ; 5
sta GRP1 ; 3
lda (.S3),y ; 5
sta GRP0 ; 3.LABPALR lda #PALRED ; 2
sta COLUP0 ; 3
sta COLUP1 ; 3 lda (.S1),y ; 5
sta GRP0 ; 3
lda (.S2),y ; 5
sta GRP1 ; 3
lda (.S3),y ; 5
sta GRP0 ; 3.LABPALB lda #PALBLUE ; 2
sta COLUP0 ; 3
sta COLUP1 ; 3 lda (.S1),y ; 5
sta GRP0 ; 3
lda (.S2),y ; 5
sta GRP1 ; 3
lda (.S3),y ; 5
sta GRP0 ; 3.SP SET 0
REPEAT BIG_ROWS*BIG_COLS
.byte .SP
.SP SET .SP + 2
REPEND
.SPBASE SET 0
REPEAT BIG_ROWS
.SPOFF SET 10
REPEAT BIG_COLS
.byte .SPBASE + .SPOFF
.SPOFF SET .SPOFF-2
REPEND
.SPBASE SET .SPBASE + 12
REPEND;=============================================================================== ; Fixed bank portion of Interleaved ChronoColour Draw System
lda ChronoBank + {1} ; 3
sta SET_BANK ; 3 = 6 lda ChronoColour + {1} ; 3
sta COLUPF ; 3 = 6 lda ( LineR0 + 0 + {1} * 14 ),y ; 5
sta PF0 ; 3
lda ( LineR0 + 2 + {1} * 14 ),y ; 5
sta PF1 ; 3
lda ( LineR0 + 4 + {1} * 14 ),y ; 5
sta PF2 ; 3 = 24 lda ( LineR0 + 6 + {1} * 14 ),y ; 5
sta PF0 ; 3
lda ( LineR0 + 8 + {1} * 14 ),y ; 5
sta PF1 ; 3
lda ( LineR0 + 10 + {1} * 14 ),y ; 5
sta PF2 ; 3 = 24; lda (LineR0 + 12 + {1} * 14 ),y ; 5
; sta.w AUDV0 ; 3 = 8_rts rts
sleep61 SLEEP (61-12)
rts lda ROM_Bank
pha ; save callee's banksta WSYNC ; jsr _rts ; jsr _rts ; jsr _rts ; jsr _rts
ldx Phase
beq ScanRedStart ; 2(3) --> 3 if taken
dex ; 2
beq ScanGreenStart ; 2(3) --> 7 if taken
bne ScanBlueStart ; (3) --> 9ScanRedStart
; @3 ; now 9 cycles after WSYNC
jsr sleep61ScanRed CHRONOLINE 0
dey
beq ScanEnd
jmp ScanGreenScanGreenStart
; @7
SLEEP 2
jsr sleep61ScanGreen CHRONOLINE 1
dey
beq ScanEnd
jmp ScanBlueScanBlueStart
; @9
jsr sleep61
ScanBlue CHRONOLINE 2 dey beq ScanEnd jmp ScanRed
ScanEnd pla sta ROM_Bank sta SET_BANK ; restore previous bank for callee
rts #endif
;========================================================================== ; The reset vectors ; these must live in the fixed bank (last 2K of any ROM image in TigerVision)
SEG InterruptVectors
ORG FIXED_BANK + $7FA
RORG $7ffa VECTOR Reset ; NMI (not used)
VECTOR Reset ; RESET
VECTOR Reset ; IRQ (not used)
; JUNK... ;------------------------------------------------------------------------------
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [stella] notBD 0.11 - scrolling, Andrew Davie | Thread | pitfall batman hack, Adam Wozniak |
| Re: [stella] notBD 0.11 - scrolling, Andrew Davie | Date | pitfall batman hack, Adam Wozniak |
| Month |