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 $80
BDF_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) ; - = unused
ObjDelay 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 CHECKED
Overlay 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 Overlay
TS_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 Overlay
DNC_CharCount ds 1 ; character draw counter ECHO "FREE BYTES IN IN OVERLAY_DrawNewCharacters = ", OVERLAY_SIZE - ( * - Overlay ) VALIDATE_OVERLAY
SEG.U OVERLAY_ClearScreen org Overlay
CS_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+1
PFrame .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+2
SetupLinePtr 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 #88
Overscan2 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} ENDM
MAC DONE .byte TOKEN_DONE ENDM
MAC MOVE .byte TOKEN_MOVE .word {1} .byte {2} ENDM
MAC 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 change
ReAnimate lda ObjAnimHI,x sta Anim+1 lda ObjAnimLO,x sta Anim ; (Anim) points to frame sequence
ReReAnim 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} ENDM
AnimVec TOKEN JUMP TOKEN LOCK TOKEN MOVE TOKEN UNLOCK TOKEN DONE TOKEN FLIP TOKEN COLOUR TOKEN SYNCH
AnimateDONE lda ObjFlag,x and #(~OBJFLAG_WAIT)&$FF sta ObjFlag,x lda #1 jmp AnimUp
lda ObjFacing,x eor #D7 sta ObjFacing,x
lda #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 tax
AnimUp 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} ENDM
StateTables 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 REPEND
ORIGIN SET FIXED_BANK NEWBANK THE_FIXED_BANK RORG $f800
lda rnd eor timer lsr lsr sbc rnd lsr ror rnd+1 ror rnd ror rnd
lda 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+1
jmp 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 TIM64T
OverscanBD 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 bank
sta 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) --> 9
ScanRedStart ; @3
; now 9 cycles after WSYNC jsr sleep61
ScanRed CHRONOLINE 0 dey beq ScanEnd jmp ScanGreen
ScanGreenStart ; @7 SLEEP 2 jsr sleep61
ScanGreen CHRONOLINE 1 dey beq ScanEnd jmp ScanBlue
ScanBlueStart ; @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 |