Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;===============================================================================
- ; Program Information
- ;===============================================================================
- ; Program: Collect2
- ; Program by: Darrell Spice, Jr
- ; Last Update: May 2, 2015
- ;
- ; Super simple game of "collect the boxes" used to show how to develop
- ; a DPC+ with ARM Atari 2600 homebrew game.
- ;
- ; See readme.txt for build instructions
- ;===============================================================================
- ; Change Log
- ;===============================================================================
- ; 2015.03.29 - initial version.
- ; 2015.04.04 - "menu" and "game" screens.
- ; new ECHO statements, copy/paste output to custom/define_dasm.h
- ; to keep 6507 and ARM code in sync with memory usage
- ; 2015.04.16 - functional main menu
- ; 2015.04.25 - score/timer display, ARM run time diagnostic info
- ; 2015.05.02 - beginnings of Arena Kernel
- ;===============================================================================
- ; Initialize dasm
- ;===============================================================================
- PROCESSOR 6502
- include vcs.h
- include macro.h
- include DPCplus.h
- ;===============================================================================
- ; Define constants
- ;===============================================================================
- ; which ARM function to run
- ARM_INIT = 0
- ARM_OS = 1
- ARM_VB = 2
- ARM_MENU_OS = 3
- ARM_MENU_VB = 4
- ; NTSC color values. ARM code will do on-the-fly conversion for PAL and SECAM
- GREY = $00
- YELLOW = $10
- ORANGE = $20
- RED_ORANGE = $30
- RED = $40
- PURPLE = $50
- VIOLET = $60
- BLUE = $80
- CYAN = $B0
- GREEN = $C0
- WHITE = $0E
- HAIR = $F4
- FACE = $4C
- ; controls spacing in main menu
- MM_TITLE_GAP = 25
- MM_OPTION_GAP = 20
- MM_START_GAP = 20
- MM_LOGO_GAP = 25
- ; aliases for menu kernel
- DS_MENU_CONTROL = DF0DATA
- DS_TWO_COLORS = DF1DATA
- DS_GRP0A = DF2DATA
- DS_GRP1A = DF3DATA
- DS_GRP0B = DF4DATA
- DS_GRP1B = DF5DATA
- DS_GRP0C = DF6DATA
- DS_GRP1C = DF7DATA
- ; aliases for score kernel
- DS_LEFTSCOREA = DF0DATA
- DS_LEFTSCOREB = DF1DATA
- DS_TIMERA = DF2DATA
- DS_TIMERB = DF3DATA
- DS_RIGHTSCOREA = DF4DATA
- DS_RIGHTSCOREB = DF5DATA
- DS_ST_COLORS = DF6DATA
- ; aliases for arena kernel
- DS_GRP0 = DF0DATA
- DS_GRP1 = DF1DATA
- DS_COLUP0 = DF2DATA
- DS_COLUP1 = DF3DATA
- DS_PF0 = DF0FRACDATA
- DS_PF1 = DF1FRACDATA
- DS_PF2 = DF2FRACDATA
- ;===============================================================================
- ; Define custom Macros
- ;===============================================================================
- MAC BANKS_AND_VECTORS
- ; allocate space for the bankswitch hotspots and set the 6502 vectors
- RORG $FFF6
- SelectBank0 .byte $00
- SelectBank1 .byte $00
- SelectBank2 .byte $00
- SelectBank3 .byte $00
- SelectBank4 .byte $00
- SelectBank5 .byte $00
- ; .word InitSystem ; NMI - overlaps with SelectBank4 and 5
- .word InitSystem ; RESET
- .word InitSystem ; IRQ
- ENDM
- MAC CALL_ARM_CODE
- ; saves function to call (passed in Y), controller info, switches, etc.
- ; for the ARM code, the runs the specified ARM code
- CallArmCode:
- ldx #<DS_ToARM
- stx DF0LOW
- ldx #>DS_ToARM
- stx DF0HI
- sty DF0WRITE ; Y holds which function to call
- ldx SWCHA ; read state of both joysticks
- stx DF0WRITE ; save in ARMswcha
- ldx SWCHB ; read state of console switches
- stx DF0WRITE ; save in ARMswchb
- ldx INPT4 ; read state of left joystick firebutton
- stx DF0WRITE ; save in ARMinpt4
- ldx INPT5 ; read state of right joystick firebutton
- stx DF0WRITE ; save in ARMinpt5
- ldx TimeLeftVB ; Time remaining in VB (only tracked for game screen)
- stx DF0WRITE ; save in ARMvbtime
- ldx TimeLeftOS ; Time remaining in OS (only tracked for game screen)
- stx DF0WRITE ; save in ARMostime
- ldx #$FF
- stx CALLFUNCTION ; runs main() in the C code
- rts
- ENDM
- MAC POSITION_OBJECT
- ; sets X position of any object. X holds which object, A holds position
- PosObject: ; A holds X value
- sec ; 2
- sta WSYNC ; X holds object, 0=P0, 1=P1, 2=M0, 3=M1, 4=Ball
- DivideLoop
- sbc #15 ; 2
- bcs DivideLoop ; 2 4
- eor #7 ; 2 6
- asl ; 2 8
- asl ; 2 10
- asl ; 2 12
- asl ; 2 14
- sta.wx HMP0,X ; 5 19
- sta RESP0,X ; 4 23 <- set object position
- SLEEP12: rts ; 6 29
- ENDM
- ;===============================================================================
- ; Define Zero Page RAM Usage
- ;----------------------------------------
- ; ZP RAM variables can only be seen by the 6507 CPU.
- ; C variables can only be seen by the ARM CPU.
- ; The 4K Display Data bank is used for any variables both CPUs need access to.
- ;===============================================================================
- SEG.U VARS
- ORG $80
- LoopCounter: ds 1
- Sleep5: ds 1
- TimeLeftOS: ds 1
- TimeLeftVB: ds 1
- LeftScoreColor: ds 1
- echo "----",($00FE - *) , "bytes of RAM left (space reserved for 2 byte stack)"
- ;===============================================================================
- ; Define Start of Cartridge
- ;----------------------------------------
- ; DPC+ cartridges must start with the Harmony/Melody driver. The driver is the
- ; ARM code that emulates the DPC+ coprocessor.
- ;===============================================================================
- SEG CODE
- ORG $0000
- HM_DRIVER:
- INCBIN DPCplus20121020.arm
- ; calculate size as all following ORGs must compensate for the driver size
- HM_DRIVER_SIZE = * - HM_DRIVER
- ;===============================================================================
- ; Bank 0 to 3 - ARM user code
- ;----------------------------------------
- ; The ARM code must start in bank 0 and will grow upward from there.
- ; Banks 0 thru 4 may be used for ARM code.
- ; DO NOT make space for DPC+ registers as is done in banks for 6507 code.
- ;===============================================================================
- ; the Atari banks of ROM begin *after* the Harmony/Melody driver, so we
- ; need to adjust ORG to compensate for the size of the DPC+ driver.
- ORG $0000 + HM_DRIVER_SIZE
- RORG $0000
- ; include the custom ARM code. This must be compiled before compiling
- ; the 6507 code by executing the MAKE command in the custom directory.
- INCBIN custom/bin/custom2.bin
- ; value used in this echo depends upon how many banks are allocated
- ; for the ARM code - $1000 per bank, so $4000 for banks 0-3
- echo "------",($4000 - *) , "bytes of ARM stationary data space left"
- ;===============================================================================
- ; Bank 4 - 6507 code
- ;----------------------------------------
- ; I normally allocate banks 0-4 for ARM code, and just use bank 5 for all the
- ; 6507 code, but for this example I'll use bank 4 for the menu routines in order
- ; to include an example of DPC+'s bankswitching.
- ;===============================================================================
- ORG $4000 + HM_DRIVER_SIZE
- RORG $F000
- ; you can store 128 bytes of data here that's accessible to the ARM
- ; chip, but not the 6507.
- echo "------",($F080 - *), " bytes free for BANK 4 'DPC+ overlap' ARM data storage"
- ;allocate the first $80 bytes of each 6507 bank for the DPC+ registers
- ORG $4080 + HM_DRIVER_SIZE
- RORG $F080
- ;----------------------------------------
- ; Routines that are the same in both banks
- ;----------------------------------------
- CALL_ARM_CODE
- POSITION_OBJECT
- SwitchBanks:
- cmp SelectBank5 ; after switching to bank 5 the JMP will be OSwaitGame
- jmp OSwaitMenu
- ;----------------------------------------
- ; Two Color Graphic routine
- ;----------------------------------------
- ; This works by using a "negative" image when drawing the players, just like a
- ; stencil. The players are colored black while the background is the color that
- ; creates the image. The second color is achieved by using the playfield and/or
- ; ball.
- ;
- ; The missiles (also black) and setting the screen & playfield to black is
- ; used to hide the screen and playfield on either side of the 48 pixel image.
- ShowTwoColorGraphic:
- sty LoopCounter
- S2CGloop:
- ;---------------------------------------
- sta WSYNC
- dec Sleep5 ; 5 5 ; time for DPC+ 3 voice music update
- Lda #<DS_GRP0A ; 2 7
- sta GRP0 ; 3 10
- lda #<DS_GRP1A ; 2 12
- sta GRP1 ; 3 15
- lda #<DS_GRP0B ; 2 17
- sta GRP0 ; 3 20
- ldx DS_GRP0C ; 4 24
- ldy DS_GRP1C ; 4 28
- lda #<DS_TWO_COLORS ; 2 30
- sta.w COLUPF ; 4 34
- lda #<DS_TWO_COLORS ; 2 36
- sta COLUBK ; 3 39
- lda #<DS_GRP1B ; 2 41
- sta GRP1 ; 3 44
- stx GRP0 ; 3 47
- sty GRP1 ; 3 50
- sty GRP0 ; 3 53
- ldx #0 ; 2 55
- stx COLUBK ; 3 58
- stx COLUPF ; 3 61
- dec LoopCounter ; 5 66
- bne S2CGloop ; 3 69 <- OK if page crossed
- stx PF0 ; 3 72
- stx PF1 ; 3 75
- ;---------------------------------------
- stx GRP0 ; 3 78/2
- stx GRP1 ; 3 5
- stx GRP0 ; 3 8
- rts ; 6 14
- ;----------------------------------------
- ; menu loop
- ;----------------------------------------
- ;Loop:
- ; OverScan - process joysticks, console switches, etc.
- ; VerticalSync - trigger vertical sync
- ; VerticalBlank - update menu datastream
- ; Kernel - draw menu using datastream
- ; goto Loop
- ;----------------------------------------
- OverScanMenu:
- sta WSYNC ; Wait for SYNC (halts CPU until end of scanline)
- ldx #2 ; LoaD Accumulator with 2 so D1=1
- stx VBLANK ; STore Accumulator to VBLANK, D1=1 turns image output off
- ; set the timer so the total number of scanlines ends up being 262
- ldx #35
- stx TIM64T
- ldy #ARM_MENU_OS
- jsr CallArmCode ; run MenuOverscan() in the ARM code
- ; after CallArmCode, Data Fetcher 0 is pointing at ARMmode, so we don't need
- ; to set DF0LOW and DF0HI in order to retrieve the value
- lda #<DF0DATA
- bne OSwaitMenu ; 0 = game active, 1 = menu active
- jmp SwitchBanks ; show the game
- OSwaitMenu:
- sta WSYNC ; Wait for SYNC (halts CPU until end of scanline)
- lda INTIM ; Check the Timer
- bne OSwaitMenu ; Branch if its Not Equal to 0
- VerticalSyncMenu:
- ldy #2 ; LoaD Accumulator with 2 so D1=1
- ldx #47 ; (47 * 64) / 76 = 40, used to set timer
- sta WSYNC ; Wait for SYNC (halts CPU until end of scanline)
- sty VSYNC ; Y D1=1, turns on Vertical Sync signal
- stx TIM64T ; set timer to go off in 40 scanlines
- sta WSYNC ; Wait for Sync - halts CPU until end of 1st scanline of VSYNC
- sta WSYNC ; wait until end of 2nd scanline of VSYNC
- ldy #0 ; LoaD Y with 0 so D1=0
- sta WSYNC ; wait until end of 3rd scanline of VSYNC
- sty VSYNC ; Y D1=0, turns off Vertical Sync signal
- VerticalBlankMenu:
- ldy #ARM_MENU_VB
- jsr CallArmCode ; run MenuVerticalBlank() in the ARM code
- ldy #%00110011
- sty ENAM0 ; turns on missile0
- sty ENAM1 ; turns on missile1
- sty ENABL ; turns on ball
- sty NUSIZ0 ; set player0 to triplicate, missile0 to 8x
- sty NUSIZ1 ; set player1 to triplicate, missile1 to 8x
- ldy #%00100000 ; set ball size to 4x
- sty CTRLPF
- ldx #1
- stx VDELP0 ; turn on vertical delay for 48 pixel routine
- stx VDELP1 ; turn on vertical delay for 48 pixel routine
- ; position players and missiles for two color 48 pixel routine
- ; the Kernel will reposition the ball for each menu entry
- PositionMMobjects:
- ldx #3
- pmmoLoop:
- lda MMobjectPosition,x
- jsr PosObject
- dex
- bpl pmmoLoop
- sta WSYNC
- sta HMOVE
- ldx #<MenuOptionsDatastream
- stx DF0LOW
- ldx #>MenuOptionsDatastream
- stx DF0HI
- ldx #0
- stx COLUP0
- stx COLUP1
- stx COLUPF
- KernelMenu:
- sta WSYNC
- lda INTIM
- bne KernelMenu
- stx VBLANK
- MMloop:
- ; set position of datastreams 1-7 for current menu entry
- ldx #6
- MMloop2:
- lda #<DS_MENU_CONTROL
- sta DF1LOW,x
- lda #<DS_MENU_CONTROL
- sta DF1HI,x
- dex
- bpl MMloop2
- ; playfield is used for the second color
- lda #<DS_MENU_CONTROL
- sta PF0
- lda #<DS_MENU_CONTROL
- sta PF1
- lda #<DS_MENU_CONTROL
- sta PF2
- ; position the ball, also used for the second color
- sta HMCLR
- ldx #4
- lda #<DS_MENU_CONTROL
- jsr PosObject
- sta WSYNC
- sta HMOVE
- ; get number of rows for menu entry, then show it
- ldy DS_MENU_CONTROL
- jsr ShowTwoColorGraphic
- ; get the vertical spacing after current menu entry
- lda #<DS_MENU_CONTROL
- bmi MMdone ; negative value means we're done drawing the menu
- beq MMloop ; no delay, start loop right now
- tay
- MMloop3:
- sta WSYNC
- dey
- bne MMloop3
- beq MMloop
- MMdone:
- sta WSYNC
- ldx #0
- stx ENAM0
- stx ENAM1
- stx ENABL
- stx PF0
- stx PF1
- stx PF2
- ldx #MM_LOGO_GAP
- SLgap:
- sta WSYNC
- dex
- bpl SLgap
- ;----------------------------------------
- ; SpiceWare logo
- ;----------------------------------------
- ; Drawn with a normal 48 pixel routine, but the first and last scanlines have
- ; extra code to draw the extended lines. The top line is extended to the right
- ; using just the playfield. The bottom line is extended to the left using the
- ; playfield and missile0.
- ;----------------------------------------
- ShowSpiceWareLogo:
- ldx #5
- SSWL0:
- lda SWLlo,x
- sta DF2LOW,x
- lda SWLhi,x
- sta DF2HI,x
- dex
- bpl SSWL0
- ldx #WHITE
- stx COLUP0
- stx COLUP1
- stx COLUPF
- ldy #7
- sty LoopCounter
- ; draw 1st line of logo with line extended to right
- sta WSYNC
- lda #<DS_GRP0A ; 2 2
- sta GRP0 ; 3 5
- lda #<DS_GRP1A ; 2 7
- sta GRP1 ; 3 10
- lda #<DS_GRP0B ; 2 12
- sta GRP0 ; 3 15
- lda #<DS_GRP1B ; 2 17
- ldx DS_GRP0C ; 4 21
- ldy DS_GRP1C ; 4 25
- jsr SLEEP12 ;12 37
- SLEEP 4 ; 4 41
- sta GRP1 ; 3 44 <- time critical
- stx GRP0 ; 3 47
- sty GRP1 ; 3 50
- sty GRP0 ; 3 53
- sty PF1 ; 3 56 ; Y = $FF, extends line on right
- sty PF2 ; 3 59 ; Y = $FF, extends line on right
- SSWL1:
- sta WSYNC
- ldy #0 ; 2 2
- sty PF1 ; 3 5 ; make sure extended line is off
- sty PF2 ; 3 8
- lda #<DS_GRP0A ; 2 10
- sta GRP0 ; 3 13
- lda #<DS_GRP1A ; 2 15
- sta GRP1 ; 3 18
- lda #<DS_GRP0B ; 2 20
- sta GRP0 ; 3 23
- lda #<DS_GRP1B ; 2 25
- ldx DS_GRP0C ; 4 29
- ldy DS_GRP1C ; 4 33
- SLEEP 3 ; 3 36
- dec LoopCounter ; 5 41
- sta GRP1 ; 3 44 <- time critical
- stx GRP0 ; 3 47
- sty GRP1 ; 3 50
- sty GRP0 ; 3 53
- bne SSWL1 ; 3 56
- ; 2 55 if not taken
- ; draw last line of logo with line extended to the left
- lda #<DS_GRP0A ; 2 57
- sta GRP0 ; 3 60 ; for next line
- ldx DS_GRP1A ; 4 64
- stx GRP1 ; 3 67 ; for next line
- sta PF0 ; 3 70 ; A = $FF, extends line on left
- sta PF1 ; 3 73 ; A = $FF, extends line on left
- sta ENAM0 ; 3 76/0; A = $FF, extends line on left
- ldx #1 ; 2 2
- stx CTRLPF ; 3 5 ; reflect playfield, gives extra time to clear PF0 and PF1
- lda #<DS_GRP0B ; 2 7
- sta GRP0 ; 3 10
- lda #<DS_GRP1B ; 2 12
- ldx DS_GRP0C ; 4 16
- jsr SLEEP12 ;12 28
- SLEEP 9 ; 9 37
- ldy DS_GRP1C ; 4 40
- sta GRP1 ; 3 44 <- time critical
- stx GRP0 ; 3 47
- sty GRP1 ; 3 50
- sty GRP0 ; 3 53
- ldy #0 ; 2 55
- sty PF1 ; 3 58
- sty PF0 ; 3 61
- stx GRP1 ; 3 67
- stx GRP0 ; 3 70
- EndShowSpiceWareLogo:
- jmp OverScanMenu
- MMobjectPosition: ; These are the player and missile X positions required by
- ; the Two Color Kernel.
- ; The Ball object is repositioned for each menu entry
- .byte $38 ; Player 0
- .byte $40 ; Player 1
- .byte 17 ; Missile 0 - to hide color run-over on the left
- .byte 105 ; Missile 1 - to hide color run-over on the right
- SWLlo: .byte <SpiceWareLogoA
- .byte <SpiceWareLogoB
- .byte <SpiceWareLogoC
- .byte <SpiceWareLogoD
- .byte <SpiceWareLogoE
- .byte <SpiceWareLogoF
- SWLhi: .byte >SpiceWareLogoA
- .byte >SpiceWareLogoB
- .byte >SpiceWareLogoC
- .byte >SpiceWareLogoD
- .byte >SpiceWareLogoE
- .byte >SpiceWareLogoF
- Font:
- .byte %11011101 ; bit 7 of TimerB bleeds into bit 7 of RightScoreB
- .byte %10101010 ; so font is design to not use bit 7
- .byte %10101010
- .byte %10101010
- .byte %10101010
- .byte %10101010
- .byte %11011101
- .byte %11011101
- .byte %10011001
- .byte %11011101
- .byte %11011101
- .byte %11011101
- .byte %11011101
- .byte %10001000
- .byte %10011001
- .byte %11101110
- .byte %11101110
- .byte %11011101
- .byte %10111011
- .byte %10111011
- .byte %10001000
- .byte %10011001
- .byte %11101110
- .byte %11101110
- .byte %11011101
- .byte %11101110
- .byte %11101110
- .byte %10011001
- .byte %11101110
- .byte %10101010
- .byte %10101010
- .byte %10001000
- .byte %11101110
- .byte %11101110
- .byte %11101110
- .byte %10001000
- .byte %10111011
- .byte %10111011
- .byte %10011001
- .byte %11101110
- .byte %11101110
- .byte %10011001
- .byte %11001100
- .byte %10111011
- .byte %10111011
- .byte %10011001
- .byte %10101010
- .byte %10101010
- .byte %11011101
- .byte %10001000
- .byte %11101110
- .byte %11101110
- .byte %11011101
- .byte %11011101
- .byte %10111011
- .byte %10111011
- .byte %11011101
- .byte %10101010
- .byte %10101010
- .byte %11011101
- .byte %10101010
- .byte %10101010
- .byte %11011101
- .byte %11011101
- .byte %10101010
- .byte %10101010
- .byte %11001100
- .byte %11101110
- .byte %11101110
- .byte %10011001
- .byte %11011101
- .byte %10101010
- .byte %10101010
- .byte %10001000
- .byte %10101010
- .byte %10101010
- .byte %10101010
- .byte %10111011 ; in a 3 pixel font B is difficult to discern from 8,
- .byte %10111011 ; so use lowercase for better visibility
- .byte %10111011
- .byte %10011001
- .byte %10101010
- .byte %10101010
- .byte %10011001
- .byte %11011101
- .byte %10101010
- .byte %10111011
- .byte %10111011
- .byte %10111011
- .byte %10101010
- .byte %11011101
- .byte %11101110 ; in a 3 pixel font D is difficult to discern from 8,
- .byte %11101110 ; so use lowercase for better visibility
- .byte %11101110
- .byte %11001100
- .byte %10101010
- .byte %10101010
- .byte %11001100
- .byte %10001000
- .byte %10111011
- .byte %10111011
- .byte %10011001
- .byte %10111011
- .byte %10111011
- .byte %10001000
- .byte %10001000
- .byte %10111011
- .byte %10111011
- .byte %10011001
- .byte %10111011
- .byte %10111011
- .byte %10111011
- Space = (*-Font)/7
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- Colon = (*-Font)/7
- .byte %11111111
- .byte %11111111
- .byte %11011101
- .byte %11111111
- .byte %11011101
- .byte %11111111
- .byte %11111111
- VB = (*-Font)/7
- .byte %11111111
- .byte %11111111
- .byte %10101001
- .byte %10101010
- .byte %10101001
- .byte %10101010
- .byte %11011001
- OS = (*-Font)/7
- .byte %11111111
- .byte %11111111
- .byte %11011100
- .byte %10101011
- .byte %10101101
- .byte %10101110
- .byte %11011001
- echo "------",($FFF6 - *) , "bytes of BANK 4 ROM left"
- ORG $4FF6 + HM_DRIVER_SIZE
- BANKS_AND_VECTORS
- ;===============================================================================
- ; Bank 5 - 6507 code
- ;----------------------------------------
- ; Game screen routines are in this bank.
- ;===============================================================================
- ORG $5000 + HM_DRIVER_SIZE
- RORG $F000
- ; you can store 128 bytes of data here that's accessible to the ARM
- ; chip, but not the 6507.
- echo "------",($F080 - *), " bytes free for BANK 4 'DPC+ overlap' ARM data storage"
- ;allocate the first $80 bytes of each 6507 bank for the DPC+ registers
- ORG $5080 + HM_DRIVER_SIZE
- RORG $F080
- ;----------------------------------------
- ; Routines that are the same in both banks
- ;----------------------------------------
- CALL_ARM_CODE
- POSITION_OBJECT
- SwitchBanks:
- cmp SelectBank4 ; after switching to bank 4 the JMP will be OSwaitMenu
- jmp OSwaitGame
- ;----------------------------------------
- ; Initialize System
- ;----------------------------------------
- InitSystem:
- CLEAN_START
- ;----------------------------------------
- ; FASTFETCH mode
- ;----------------------------------------
- ; Here we turn on FASTFETCH mode, which lets us access DPC+ registers using:
- ; lda #<DF0DATA ; 2 cycle instruction
- ;
- ; instead of:
- ; lda DF0DATA ; 4 cycle instruction
- ;
- ; NOTE: This program never turns off FASTFETCH mode, so don't use LDA # for
- ; anything except accessing DPC+ registers.
- ;----------------------------------------
- ldx #0
- stx FASTFETCH
- ldy #ARM_INIT
- jsr CallArmCode ; run Initialize() in the ARM code
- ;----------------------------------------
- ; main program loop
- ;----------------------------------------
- ;Loop:
- ; OverScan - process joysticks, console switches, etc
- ; VerticalSync - trigger vertical sync
- ; VerticalBlank - run sprite multiplexer and populate the datastreams
- ; Kernel - draw screen using datastreams
- ; goto Loop
- ;----------------------------------------
- OverScan:
- sta WSYNC ; Wait for SYNC (halts CPU until end of scanline)
- ldy #2 ; LoaD Y with 2 so D1=1
- sty VBLANK ; STore Y to VBLANK, D1=1 turns image output off
- ; set the timer so the total number of scanlines ends up being 262
- ldy #35
- sty TIM64T
- ldy #ARM_OS
- jsr CallArmCode ; run OverScan() in the ARM code
- ; after CallArmCode Data Fetcher 0 is pointing at ARMmode, so we don't need
- ; to set DF0LOW and DF0HI in order to retrieve the value
- lda #<DF0DATA ; retreives ARMmode
- beq OSwaitGame ; 0 = game active, 1 = menu active
- jmp SwitchBanks ; show the menu
- OSwaitGame:
- lda INTIM
- sta TimeLeftOS
- OSwaitLoop:
- sta WSYNC ; Wait for SYNC (halts CPU until end of scanline)
- lda INTIM ; Check the Timer
- bne OSwaitLoop ; Branch if its Not Equal to 0
- VerticalSync:
- ldy #2 ; LoaD Y with 2 so D1=1
- ldx #47 ; (47 * 64) / 76 = 40, used to set timer
- sta WSYNC ; Wait for SYNC (halts CPU until end of scanline)
- sty VSYNC ; Y D1=1, turns on Vertical Sync signal
- stx TIM64T ; set timer to go off in 40 scanlines
- sta WSYNC ; Wait for Sync - halts CPU until end of 1st scanline of VSYNC
- sta WSYNC ; wait until end of 2nd scanline of VSYNC
- ldy #0 ; 2 2 LoaD Y with 0 so D1=0
- sty GRP0 ; 3 5 clear all objects
- sty GRP1 ; 3 8
- sty GRP0 ; 3 11
- sty ENABL ; 3 14
- sty ENAM0 ; 3 17
- sty ENAM1 ; 3 20
- sty PF1 ; 3 23
- sty PF2 ; 3 26
- sty NUSIZ0 ; 3 29 - set players to just 1 copy at 1x size
- sty NUSIZ1 ; 3 32
- sty VDELP1 ; 3 35 - player1 doesn't use VDEL in the Arena kernel
- iny ; 2 37
- sty VDELP0 ; 3 40 - player0 uses Vertical Delay in the Arena Kernel
- sta WSYNC ; wait until end of 3rd scanline of VSYNC
- sty VSYNC ; Y D1=0, turns off Vertical Sync signal
- VerticalBlank:
- ldy #ARM_VB
- jsr CallArmCode ; run VerticalBlank() in the ARM code
- ; set datafetcher 0 so we can retreive variables updated by the ARM code
- ldx #<DS_FromARM
- stx DF0LOW
- ldx #>DS_FromARM
- stx DF0HI
- PrepPlayfield:
- lda #<DF0DATA ; read value in ARMcolupf
- sta COLUPF ; set playfield color
- ldx #2
- ldy #256/8
- PPFloop:
- lda PFDSlow,x
- sta DF0FRACLOW,x
- lda PFDShi,x
- sta DF0FRACHI,x
- tya
- sta DF0FRACINC,x
- dex
- bpl PPFloop
- PrepDataStreams:
- ldx #3
- PDSloop:
- lda DSlow,x
- sta DF0LOW,x
- lda DShi,x
- sta DF0HI,x
- dex
- bpl PDSloop
- PositionPlayers:
- ldx #1
- PPloop:
- lda PlayerPos,x
- jsr PosObject
- dex
- bpl PPloop
- sta WSYNC
- sta HMOVE
- ldx #8*22 ; use X for KernelLoop counter
- lda INTIM
- sta TimeLeftVB
- ArenaKernel:
- sta WSYNC
- lda INTIM ; 4 4
- bne ArenaKernel ; 2 6 - 3 7 if taken
- sta VBLANK ; 3 9 - Accumulator D1=0, turns off Vertical Blank signal (image output on)
- lda #<DS_GRP0 ; 2 11
- sta GRP0 ; 3 14 - @any, for next scanline as VDELP0 is on
- ArenaLoop:
- sta WSYNC
- lda #<DS_GRP1 ; 2 2
- sta GRP1 ; 3 5 - @0-22, also triggers update of GRP0
- lda #<DS_COLUP0 ; 2 7
- sta COLUP0 ; 3 10 - @0-22
- lda #<DS_COLUP1 ; 2 12
- sta COLUP1 ; 3 15 - @0-22
- lda #<DS_PF0 ; 2 17
- sta PF0 ; 3 20 - @0-22
- lda #<DS_PF1 ; 2 22
- sta PF1 ; 3 25 - @71-28
- lda #<DS_PF2 ; 2 27
- sta PF2 ; 3 30 - @0-39
- lda #<DS_GRP0 ; 2 32
- sta GRP0 ; 3 35 - @any, for next scanline as VDELP0 is on
- dex ; 2 37
- bne ArenaLoop ; 2 39 - 3 40 if taken
- ScoreKernel:
- sta WSYNC
- ldx #0
- stx PF0
- stx PF1
- stx PF2
- stx GRP0
- stx GRP1
- stx GRP0
- sta WSYNC
- sta WSYNC
- sta WSYNC
- sta WSYNC
- sta WSYNC
- sta WSYNC
- ldx #0 ; 2 2
- stx GRP0 ; 3 5 turn off display
- stx GRP1 ; 3 8
- stx PF0 ; 3 11
- stx COLUBK ; 3 14
- stx COLUPF ; 3 17
- stx COLUP0 ; 3 20
- stx COLUP1 ; 3 23
- inx ; 2 25
- stx VDELP0 ; 3 28 turn on vertical delay for player 0
- stx VDELP1 ; 3 31 turn on vertical delay for player 1
- stx RESP0 ; 3 34 roughly position player0
- stx RESP1 ; 3 37 roughly position player1
- ldx #<LeftScoreA ; 2 39 prep datastreams for score and timer
- stx DF0LOW ; 4 43
- ldx #<LeftScoreB ; 2 45
- stx DF1LOW ; 4 49
- ldx #<TimerA ; 2 51
- stx DF2LOW ; 4 55
- ldx #<TimerB ; 2 57
- stx DF3LOW ; 4 61
- ldx #$FF ; 2 63 $fx = shift right 1
- stx HMP0 ; 3 67 fine tune player0 postion
- inx ; 2 69 $0x = no shift
- stx HMP1 ; 3 72 fine tune player1 postion
- ldx #<RightScoreA ; 2 74
- SLEEP 2 ; 2 76
- stx HMOVE ; 3 3 reposition players
- stx DF4LOW ; 4 7
- ldx #<RightScoreB ; 2 9
- stx DF5LOW ; 4 13
- ldx #%00000110 ; 2 15 set for 3 copies medium spacing
- stx NUSIZ0 ; 4 19
- stx NUSIZ1 ; 3 22
- ldx #<ScoreTimerColors ; 2 24
- stx DF6LOW ; 3 27
- ldx #>LeftScoreA ; 2 29
- stx DF0HI ; 4 33
- stx DF1HI ; 4 37 space savings trick - all these
- stx DF2HI ; 4 41 datastreams were purposely located on
- stx DF3HI ; 4 45 the same page as LeftScoreA
- stx DF4HI ; 4 49
- stx DF5HI ; 4 53
- stx DF6HI ; 4 57
- ldx #7 ; 2 59
- stx LoopCounter ; 3 62
- lda #<DS_ST_COLORS ; 2 64
- sta LeftScoreColor ; 3 67
- ldx #%00000011 ; 2 69
- stx PF1 ; 3 72
- ldx #%11000011 ; 2 74
- stx PF2 ; 3 77/1
- ldx DS_ST_COLORS ; 4 5 X holds Timer Color during ScoreLoop
- ldy DS_ST_COLORS ; 4 9 Y holds Right Score Color
- bne SL_Start ; 3 12 always branchs as Y is not 0
- ScoreLoop:
- sta WSYNC
- lda LeftScoreColor ; 3 3
- sta COLUPF ; 3 6
- lda #<DS_LEFTSCOREB ; 2 8
- sta GRP1 ; 3 11 LeftScoreA now visible in GRP0
- lda #<DS_TIMERA ; 2 13
- sta GRP0 ; 3 16 LeftScoreB now visible in GRP1
- lda #<DS_TIMERB ; 2 18
- SLEEP 18 ;18 36
- sta GRP1 ; 3 39 TimerA now visible in GRP0
- stx COLUPF ; 3 42 set timer color
- lda #<DS_RIGHTSCOREA ; 2 44
- sta GRP0 ; 3 47 TimerB now visible in GRP1
- lda #<DS_RIGHTSCOREB ; 2 49
- sty COLUPF ; 3 52
- sta GRP1 ; 3 55 RightScoreA now visible in GRP0
- SL_Start:
- ; NOTE: the following update of GRP0 is 1 pixel late so the contents of
- ; bit 7 of TimerB are displayed instead of the contents of
- ; bit 7 of RightScoreB. We'll work around this late update
- ; by not using bit 7 in the font.
- lda #<DS_LEFTSCOREA ; 2 57
- sta GRP0 ; 3 60 RightScoreB now visible in GRP1
- dec LoopCounter ; 5 65
- bpl ScoreLoop ; 2 67 3 68 if taken
- jmp OverScan ; 3 70
- PFDSlow:
- .byte <ArenaPF0
- .byte <ArenaPF1
- .byte <ArenaPF2
- PFDShi:
- .byte >ArenaPF0
- .byte >ArenaPF1
- .byte >ArenaPF2
- DSlow:
- .byte <Player0DataStream
- .byte <Player1DataStream
- .byte <Color0DataStream
- .byte <Color1DataStream
- DShi:
- .byte >Player0DataStream
- .byte >Player1DataStream
- .byte >Color0DataStream
- .byte >Color1DataStream
- PlayerPos:
- .byte 6
- .byte 146
- echo "------",($FFF6 - *) , "bytes of BANK 5 ROM left"
- ORG $5FF6 + HM_DRIVER_SIZE
- BANKS_AND_VECTORS
- ;===============================================================================
- ; Display Data
- ;----------------------------------------
- ; The Display Data bank is copied into RAM when DPC+ initializes the cartridge.
- ; This allows us to manipulate the data during run-time, but have a known
- ; starting state when the Atari is first turned on.
- ;
- ; Unlike normal Atari VCS/2600 sprite definitions, the sprite data in the
- ; Display Data bank is stored right-side-up.
- ;
- ; NOTE: The initial contents of Display Data is stored in ROM and can be
- ; accessed by ARM routines. This can prove handy for saving ROM
- ;===============================================================================
- ORG $6000 + HM_DRIVER_SIZE
- RORG $0000
- LeftScoreA:
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- LeftScoreB:
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- TimerA:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- TimerB:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- RightScoreA:
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- RightScoreB:
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- ScoreTimerColors
- .byte BLUE + 4
- .byte WHITE
- .byte GREEN + 4
- ArenaPF0: ; PF0 is drawn in reverse order, and only the upper nybble
- .byte %11110000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %11110000
- ArenaPF1: ; PF1 is drawn in expected order
- .byte %11111111 ; Arena 1
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00011100
- .byte %00000000
- .byte %00000000
- .byte %11000000
- .byte %01000000
- .byte %01000000
- .byte %01000001
- .byte %01000001
- .byte %01000000
- .byte %01000000
- .byte %11000000
- .byte %00000000
- .byte %00000000
- .byte %00011100
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %11111111
- ArenaPF2: ; PF2 is drawn in reverse order
- .byte %11111111 ; Arena 1
- .byte %10000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00011100
- .byte %00000100
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000100
- .byte %00011100
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %10000000
- .byte %11111111
- Player0DataStream:
- ds 8, 0 ; top Arena border
- .byte %11111111 ; alignment test
- ;ds 71, 0
- ds 30, 0
- .byte %00000001 ; 1 invader
- .byte %01000010 ; 2
- .byte %10100100 ; 3
- .byte %10011000 ; 4
- .byte %01111110 ; 5
- .byte %01101011 ; 6
- .byte %01111110 ; 7
- .byte %01111110 ; 8
- .byte %01000010 ; 9
- .byte %11100111 ; 10
- ds 31,0
- .byte %00010000 ; 1 left player
- .byte %00010000 ; 2
- .byte %00010000 ; 3
- .byte %00111000 ; 4
- .byte %00111000 ; 5
- .byte %01011000 ; 6
- .byte %01010100 ; 7
- .byte %01010000 ; 8
- .byte %00010000 ; 9
- .byte %00010000 ; 10
- .byte %00010000 ; 11
- .byte %00010000 ; 12
- .byte %00010000 ; 13
- .byte %00010000 ; 14
- .byte %00010000 ; 15
- .byte %00011000 ; 16
- ds 29, 0
- .byte %11111100 ; 1 tank
- .byte %11111100 ; 2
- .byte %11111100 ; 3
- .byte %11111100 ; 4
- .byte %00111000 ; 5
- .byte %00111000 ; 6
- .byte %00111111 ; 7
- .byte %00111111 ; 8
- .byte %00111000 ; 9
- .byte %00111000 ; 10
- .byte %11111100 ; 11
- .byte %11111100 ; 12
- .byte %11111100 ; 13
- .byte %11111100 ; 14
- ds 28,0
- .byte %11111111 ; alignment test
- ds 8,0 ; bottom Arena border
- echo "Player0DataStream Size = ", [* - Player0DataStream]d
- Player1DataStream:
- ds 8, 0 ; top Arena border
- .byte %11111111 ; alignment test
- ds 30, 0
- .byte %00111100 ; 1 invader
- .byte %01111110 ; 2
- .byte %01011010 ; 3
- .byte %11111111 ; 4
- .byte %10100101 ; 5
- .byte %10011001 ; 6
- .byte %10011001 ; 7
- .byte %10100101 ; 8
- .byte %10100101 ; 9
- .byte %10100101 ; 10
- ds 31,0
- .byte %00001000 ; 1 right player
- .byte %00001000 ; 2
- .byte %00001000 ; 3
- .byte %00011100 ; 4
- .byte %00011100 ; 5
- .byte %00011010 ; 6
- .byte %00101010 ; 7
- .byte %00001010 ; 8
- .byte %00001000 ; 9
- .byte %00001000 ; 10
- .byte %00001000 ; 11
- .byte %00001000 ; 12
- .byte %00001000 ; 13
- .byte %00001000 ; 14
- .byte %00001000 ; 15
- .byte %00011000 ; 16
- ds 29, 0
- .byte %00111111 ; 1 tank
- .byte %00111111 ; 2
- .byte %00111111 ; 3
- .byte %00111111 ; 4
- .byte %00011100 ; 5
- .byte %00011100 ; 6
- .byte %11111100 ; 7
- .byte %11111100 ; 8
- .byte %00011100 ; 9
- .byte %00011100 ; 10
- .byte %00111111 ; 11
- .byte %00111111 ; 12
- .byte %00111111 ; 13
- .byte %00111111 ; 14
- ds 28,0
- .byte %11111111 ; alignment test
- ds 8,0 ; bottom Arena border
- echo "Player1DataStream Size = ", [* - Player1DataStream]d
- Color0DataStream:
- ds 8, WHITE ; top Arena border
- .byte WHITE ; alignment test
- ds 30, WHITE
- ds 10, YELLOW+4 ; invader
- ds 31, WHITE
- .byte HAIR ; 1 left player
- .byte FACE ; 2
- .byte FACE ; 3
- .byte BLUE+2 ; 4
- .byte WHITE -2 ; 5
- .byte WHITE -2 ; 6
- .byte GREY+8 ; 7
- .byte GREY+4 ; 8
- .byte BLUE+4 ; 9
- .byte WHITE-2-2 ; 10
- .byte WHITE-2-2 ; 11
- .byte WHITE-2-2 ; 12
- .byte BLUE ; 13
- .byte BLUE+2 ; 14
- .byte BLUE+4 ; 15
- .byte BLUE+6 ; 16
- ds 29, WHITE
- ds 14, RED+4 ; tank
- ds 28, WHITE
- .byte WHITE ; alignment test
- ds 8, WHITE ; bottom Arena border
- echo "Color0DataStream Size = ", [* - Color0DataStream]d
- Color1DataStream:
- ds 8, WHITE ; top Arena border
- .byte WHITE ; alignment test
- ds 30, WHITE
- ds 10, YELLOW+4 ; invader
- ds 31, WHITE
- .byte HAIR ; 1 right player
- .byte FACE ; 2
- .byte FACE ; 3
- .byte GREEN+2 ; 4
- .byte WHITE -2 ; 5
- .byte WHITE -2 ; 6
- .byte GREY+8 ; 7
- .byte GREY+4 ; 8
- .byte GREEN+4 ; 9
- .byte WHITE-2-2 ; 10
- .byte WHITE-2-2 ; 11
- .byte WHITE-2-2 ; 12
- .byte GREEN ; 13
- .byte GREEN+2 ; 14
- .byte GREEN+4 ; 15
- .byte GREEN+6 ; 16
- ds 29, WHITE
- ds 14, BLUE+2 ; tank
- ds 28, WHITE
- .byte WHITE ; alignment test
- ds 8, WHITE ; bottom Arena border
- echo "Color1DataStream Size = ", [* - Color1DataStream]d
- ColorDataStreamSize = * - Color0DataStream
- DS_ToARM:
- ARMfunction: ds 1 ; which function to run
- ARMswcha: ds 1 ; controller state
- ARMswchb: ds 1 ; state of console switches
- ARMinpt4: ds 1 ; state of left joystick's fire button
- ARMinpt5: ds 1 ; state of right joystick's fire button
- ARMvbtime: ds 1 ; vertical blank time remaining
- ARMostime: ds 1 ; over scan time remaining
- ; this is part of DS_ToARM, but is actually used as "from the ARM to the 6507"
- ARMmode: ds 1 ; tells 6507 to show menu or game screen
- DS_FromARM:
- ARMcolupf: ds 1 ; playfield color from ARM code
- ;----------------------------------------
- ; menu variables
- ;----------------------------------------
- ; Instead of using global C variables, we'll allocate space in Display Data
- ; to hold the state of the main menu.
- ;----------------------------------------
- MM_JoystickTimer: .byte 0
- MM_FireDown: .byte 0
- MM_SelectedOption: .byte MENU_START_ID
- MM_Players: .byte 0 ; 0=1 player, 1=2 players
- MM_TVtype: .byte 0 ; 0=NTSC, 1=PAL, 2=SECAM
- ;----------------------------------------
- ; menu datastream
- ;----------------------------------------
- ; For the menu datastream, the .word values will be accessed by the ARM code as
- ; unsigned short int values. The ARM requires short int (signed and unsigned)
- ; to be aligned in memory on a 2 byte boundary. The align 2 instruction does
- ; this for us.
- ;
- ; Each menu entry is 20 bytes, so align is only needed for the first one.
- ;
- ; The _ID values for each menu entry will be used in the ARM code.
- ;
- ; To create the 2-color 48 pixel image, the players are drawn in black and act
- ; like a stencil - any pixel turned on is black, any pixel turned off will show
- ; either the background or playfield/ball color.
- ;----------------------------------------
- align 2
- MenuData:
- MenuOptionsDatastream:
- .word Collect2LogoF ; 0 0 first value is unsigned char[] index
- .word Collect2LogoE ; 2 1 not actually used in the ARM code, but
- .word Collect2LogoD ; 4 2 keeping track of it helps us to make
- .word Collect2LogoC ; 6 3 sure each menu entry is exactly 20 bytes
- .word Collect2LogoB ; 8 4 second value is unsigned short int[] index
- .word Collect2LogoA ; 10 5 this is used in the ARM code to update
- .word Collect2LogoColor ; 12 6 the datastream to show selected values
- .byte %00000000 ; 14 PF0 - reversed
- .byte %01000000 ; 15 PF1
- .byte %00000000 ; 16 PF2 - reversed
- .byte 100 ; 17 ball x location
- .byte 25 ; 18 rows to show
- .byte MM_TITLE_GAP ; 19 scanline padding before next entry
- MENU_FIRST_OPTION_ID = (* - MenuOptionsDatastream) / 20
- MENU_PLAYERS_ID = (* - MenuOptionsDatastream) / 20
- .word OptionDigit1 ; 0 0 first value is unsigned char[] index
- .word OptionSpace ; 2 1 not actually used in the ARM code, but
- .word PlayersD ; 4 2 keeping track of it helps us to make
- .word PlayersC ; 6 3 sure each menu entry is exactly 20 bytes
- .word PlayersB ; 8 4 second value is unsigned short int[] index
- .word PlayersA ; 10 5 this is used in the ARM code to update
- .word MenuOptionGreen ; 12 6 the datastream to show selected values
- .byte %11100000 ; 14 PF0 - reversed
- .byte %11000000 ; 15 PF1
- .byte %00000000 ; 16 PF2 - reversed
- .byte 0 ; 17 ball x location
- .byte 7 ; 18 rows to show
- .byte MM_OPTION_GAP ; 19 scanline padding before next entry
- MENU_TV_TYPE_ID = (* - MenuOptionsDatastream) / 20
- .word OptionNTSCB ; 0 0 first value is unsigned char[] index
- .word OptionNTSCA ; 2 1 not actually used in the ARM code, but
- .word TVtypeD ; 4 2 keeping track of it helps us to make
- .word TVtypeC ; 6 3 sure each menu entry is exactly 20 bytes
- .word TVtypeB ; 8 4 second value is unsigned short int[] index
- .word TVtypeA ; 10 5 this is used in the ARM code to update
- .word MenuOptionGreen ; 12 6 the datastream to show selected values
- .byte %11100000 ; 14 PF0 - reversed
- .byte %11000000 ; 15 PF1
- .byte %00000000 ; 16 PF2 - reversed
- .byte 0 ; 17 ball x location
- .byte 7 ; 18 rows to show
- .byte 0 ; 19 scanline padding before next entry
- MENU_RGB_ID = (* - MenuOptionsDatastream) / 20
- .word RGBC ; 0 0 first value is unsigned char[] index
- .word RGBB ; 2 1 not actually used in the ARM code, but
- .word RGBA ; 4 2 keeping track of it helps us to make
- .word RGBspace ; 6 3 sure each menu entry is exactly 20 bytes
- .word RGBspace ; 8 4 second value is unsigned short int[] index
- .word RGBspace ; 10 5 this is used in the ARM code to update
- .word MenuOptionRGB ; 12 6 the datastream to show selected values
- .byte %00000000 ; 14 PF0 - reversed
- .byte %00000000 ; 15 PF1
- .byte %00000000 ; 16 PF2 - reversed
- .byte 0 ; 17 ball x location
- .byte 17 ; 18 rows to show
- .byte MM_START_GAP ; 19 scanline padding before next entry
- MENU_START_ID = (* - MenuOptionsDatastream) / 20
- .word StartA ; 0 0 first value is unsigned char[] index
- .word StartE ; 2 1 not actually used in the ARM code, but
- .word StartD ; 4 2 keeping track of it helps us to make
- .word StartC ; 6 3 sure each menu entry is exactly 20 bytes
- .word StartB ; 8 4 second value is unsigned short int[] index
- .word StartA ; 10 5 this is used in the ARM code to update
- .word StartColor ; 12 6 the datastream to show selected values
- .byte %00000000 ; 14 PF0 - reversed
- .byte %11000000 ; 15 PF1
- .byte %00001100 ; 16 PF2 - reversed
- .byte 0 ; 17 ball x location
- .byte 8 ; 18 rows to show
- .byte $80 ; 19 flags end of menu
- Collect2LogoA:
- .byte %00000000 ; 0
- .byte %11111111 ; 1
- .byte %00000000 ; 2
- .byte %11111111 ; 3
- .byte %00000000 ; 4
- .byte %11111111 ; 5
- .byte %00000000 ; 6
- .byte %11111111 ; 7
- .byte %10000110 ; 8
- .byte %01111101 ; 9
- .byte %01111101 ; 10
- .byte %01111101 ; 11
- .byte %01111101 ; 12
- .byte %01111101 ; 13
- .byte %01111101 ; 14
- .byte %01111101 ; 15
- .byte %10000110 ; 16
- .byte %11111111 ; 17
- .byte %00000000 ; 18
- .byte %11111111 ; 19
- .byte %00000000 ; 20
- .byte %11111111 ; 21
- .byte %00000000 ; 22
- .byte %11111111 ; 23
- .byte %00000000 ; 24
- Collect2LogoB:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00011011
- .byte %11101011
- .byte %11101011
- .byte %11101011
- .byte %11101011
- .byte %11101011
- .byte %11101011
- .byte %11101011
- .byte %00011000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- Collect2LogoC:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %11101111
- .byte %11101111
- .byte %11101111
- .byte %11101111
- .byte %11101111
- .byte %11101111
- .byte %11101111
- .byte %11101111
- .byte %00100000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- Collect2LogoD:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %10000011
- .byte %10111110
- .byte %10111110
- .byte %10111110
- .byte %10001110
- .byte %10111110
- .byte %10111110
- .byte %10111110
- .byte %10000011
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- Collect2LogoE:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00001000
- .byte %11111110
- .byte %11111110
- .byte %11111110
- .byte %11111110
- .byte %11111110
- .byte %11111110
- .byte %11111110
- .byte %00001110
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- Collect2LogoF:
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00110001
- .byte %11101110
- .byte %11111110
- .byte %11111110
- .byte %11111101
- .byte %11111011
- .byte %11110111
- .byte %11101111
- .byte %11100000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- .byte %11111111
- .byte %00000000
- PlayersA:
- .byte %00110111
- .byte %01010111
- .byte %01010111
- .byte %00110111
- .byte %01110111
- .byte %01110111
- .byte %01110001
- PlayersB:
- .byte %10110101
- .byte %01010101
- .byte %01010101
- .byte %00011011
- .byte %01011011
- .byte %01011011
- .byte %01011011
- PlayersC:
- .byte %00010011
- .byte %01110101
- .byte %01110101
- .byte %00110011
- .byte %01110101
- .byte %01110101
- .byte %00010101
- PlayersD:
- .byte %10011111
- .byte %01111111
- .byte %01111111
- .byte %10111111
- .byte %11011111
- .byte %11011111
- .byte %00111111
- OptionDigit1:
- .byte %11111101
- .byte %11111001
- .byte %11111101
- .byte %11111101
- .byte %11111101
- .byte %11111101
- .byte %11111000
- OptionDigit2:
- .byte %11111001
- .byte %11111110
- .byte %11111110
- .byte %11111101
- .byte %11111011
- .byte %11111011
- .byte %11111000
- TVtypeA:
- .byte %00010101
- .byte %10110101
- .byte %10110101
- .byte %10110101
- .byte %10110101
- .byte %10110101
- .byte %10111011
- TVtypeB:
- .byte %11000101
- .byte %11101101
- .byte %11101101
- .byte %01101110
- .byte %11101110
- .byte %11101110
- .byte %11101110
- TVtypeC:
- .byte %01001100
- .byte %01010101
- .byte %01010101
- .byte %11001100
- .byte %11011101
- .byte %11011101
- .byte %11011100
- TVtypeD:
- .byte %01111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %01111111
- OptionNTSCA:
- .byte %10011000
- .byte %10101101
- .byte %10101101
- .byte %10101101
- .byte %10101101
- .byte %10101101
- .byte %10101101
- OptionNTSCB:
- .byte %11001101
- .byte %10111010
- .byte %10111011
- .byte %11011011
- .byte %11101011
- .byte %11101010
- .byte %10011101
- OptionPALA:
- .byte %11111001
- .byte %11111010
- .byte %11111010
- .byte %11111001
- .byte %11111011
- .byte %11111011
- .byte %11111011
- OptionPALB:
- .byte %11011011
- .byte %10101011
- .byte %10101011
- .byte %10001011
- .byte %10101011
- .byte %10101011
- .byte %10101000
- OptionSECAMA:
- .byte %01111100
- .byte %11111011
- .byte %11111011
- .byte %11111101
- .byte %11111110
- .byte %11111110
- .byte %01111001
- OptionSECAMB:
- .byte %10001101
- .byte %10111010
- .byte %10111011
- .byte %10011011
- .byte %10111011
- .byte %10111010
- .byte %10001101
- OptionSECAMC:
- .byte %11011010
- .byte %10101000
- .byte %10101010
- .byte %10001010
- .byte %10101010
- .byte %10101010
- .byte %10101010
- RGBspace:
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- RGBA:
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111100
- .byte %11111011
- .byte %11111010
- .byte %11111010
- .byte %11111101
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- RGBB:
- .byte %11111001
- .byte %11111010
- .byte %11111001
- .byte %11111010
- .byte %11111010
- .byte %11111111
- .byte %10011000
- .byte %10101011
- .byte %10011001
- .byte %10101011
- .byte %10101000
- .byte %11111111
- .byte %10011011
- .byte %10101011
- .byte %10011011
- .byte %10101011
- .byte %10011000
- RGBC:
- .byte %10001001
- .byte %10111010
- .byte %10011010
- .byte %10111010
- .byte %10001001
- .byte %11111111
- .byte %10001001
- .byte %10111010
- .byte %10011010
- .byte %10111010
- .byte %10001010
- .byte %11111111
- .byte %10101000
- .byte %10101011
- .byte %10101001
- .byte %10101011
- .byte %10001000
- OptionSpace:
- StartA:
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- .byte %11111111
- StartB:
- .byte %11100001
- .byte %11011111
- .byte %11011111
- .byte %11100011
- .byte %11111101
- .byte %11111101
- .byte %11111101
- .byte %11000011
- StartC:
- .byte %00000110
- .byte %11011101
- .byte %11011101
- .byte %11011100
- .byte %11011101
- .byte %11011101
- .byte %11011101
- .byte %11011101
- StartD:
- .byte %00110000
- .byte %11010111
- .byte %11010111
- .byte %00010000
- .byte %11010111
- .byte %11010111
- .byte %11010111
- .byte %11010111
- StartE:
- .byte %11000001
- .byte %01110111
- .byte %01110111
- .byte %11110111
- .byte %01110111
- .byte %01110111
- .byte %01110111
- .byte %01110111
- SpiceWareLogoA:
- .byte %00001111
- .byte %00010000
- .byte %00010000
- .byte %00010000
- .byte %00001111
- .byte %00000000
- .byte %00000000
- .byte %00000000
- .byte %11111111
- SpiceWareLogoB:
- .byte %11111111
- .byte %00000000
- .byte %00011001
- .byte %00010101
- .byte %10010101
- .byte %01011001
- .byte %01010001
- .byte %01010001
- .byte %10010001
- SpiceWareLogoC:
- .byte %11111111
- .byte %00000000
- .byte %00100111
- .byte %01010100
- .byte %01000100
- .byte %01000110
- .byte %01000100
- .byte %01010100
- .byte %00100111
- SpiceWareLogoD:
- .byte %11000001
- .byte %01000001
- .byte %01100011
- .byte %00101010
- .byte %00101010
- .byte %00111110
- .byte %00010100
- .byte %00010100
- .byte %00010100
- SpiceWareLogoE:
- .byte %11111111
- .byte %00000000
- .byte %00100110
- .byte %01010101
- .byte %01010101
- .byte %01110110
- .byte %01010101
- .byte %01010101
- .byte %01010101
- SpiceWareLogoF:
- .byte %11111111
- .byte %00000000
- .byte %01110000
- .byte %01000000
- .byte %01000000
- .byte %01100000
- .byte %01000000
- .byte %01000000
- .byte %01110000
- MenuColors:
- Collect2LogoColor:
- .byte BLUE + 2, BLUE + 2 ; 0
- .byte 0, 0 ; 1
- .byte BLUE + 4, BLUE + 4 ; 2
- .byte 0, 0 ; 3
- .byte BLUE + 8, BLUE + 8 ; 4
- .byte 0, 0 ; 5
- .byte BLUE + 10, BLUE + 10 ; 6
- .byte 0, 0 ; 7
- .byte RED + 12, GREEN + 12 ; 8
- .byte RED + 12, GREEN + 12 ; 9
- .byte RED + 12, GREEN + 12 ; 10
- .byte RED + 12, GREEN + 12 ; 11
- .byte RED + 12, GREEN + 12 ; 12
- .byte RED + 12, GREEN + 12 ; 13
- .byte RED + 12, GREEN + 12 ; 14
- .byte RED + 12, GREEN + 12 ; 15
- .byte RED + 12, GREEN + 12 ; 16
- .byte 0, 0 ; 17
- .byte BLUE + 10, BLUE + 10 ; 18
- .byte 0, 0 ; 19
- .byte BLUE + 8, BLUE + 8 ; 20
- .byte 0, 0 ; 21
- .byte BLUE + 4, BLUE + 4 ; 22
- .byte 0, 0 ; 23
- .byte BLUE + 2, BLUE + 2 ; 24
- MenuOptionGreen:
- .byte GREEN + 8, BLUE + 8
- .byte GREEN +10, BLUE +10
- .byte GREEN +12, BLUE +12
- .byte GREEN +14, BLUE +14
- .byte GREEN +12, BLUE +12
- .byte GREEN +10, BLUE +10
- .byte GREEN + 8, BLUE + 8
- MenuOptionRGB:
- .byte RED+10, RED+10
- .byte RED+12, RED+12
- .byte RED+14, RED+14
- .byte RED+12, RED+12
- .byte RED+10, RED+10
- .byte WHITE, WHITE
- .byte GREEN+10, GREEN+10
- .byte GREEN+12, GREEN+12
- .byte GREEN+14, GREEN+14
- .byte GREEN+12, GREEN+12
- .byte GREEN+10, GREEN+10
- .byte WHITE, WHITE
- .byte BLUE+10, BLUE+10
- .byte BLUE+12, BLUE+12
- .byte BLUE+14, BLUE+14
- .byte BLUE+12, BLUE+12
- .byte BLUE+10, BLUE+10
- MenuSelectedColor:
- .byte GREY+6, GREY+ 8; 0
- .byte GREY+6, GREY+10; 1
- .byte GREY+6, GREY+12; 2
- .byte GREY+6, GREY+14; 3
- .byte GREY+6, GREY+14; 4
- .byte GREY+6, GREY+12; 5
- .byte GREY+6, GREY+10; 6
- .byte GREY+6, GREY+ 8; 7
- StartColor:
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- .byte WHITE, WHITE
- MenuColorsSize = * - MenuColors
- MenuDataSize = * - MenuData
- Delay:
- .byte 0
- if (* <= $1000)
- echo "------",($1000 - *) , "bytes of Display Data ROM left"
- ds ($1000 - *) ; pad out remaining space in Display Data ROM
- else
- echo "FATAL ERROR - Display Data exceeds 4K", *
- err
- endif
- include DPC_frequencies.h
- ;===============================================================================
- ; custom/defines.h
- ;----------------------------------------
- ; Instead of manually keeping custom/defines_dasm.h in sync with what's in the
- ; 6507 code, we'll have DASM echo out defines that can be copied/pasted into
- ; the defines.h file.
- ;
- ; Wrapping the 6507 variables in []d will cause their values to be output in
- ; decimal instead of hexadecimal. This is required because C requires a prefix
- ; of 0x for hex values, but echo outputs them using $ for the prefix.
- ;===============================================================================
- echo ""
- echo ""
- echo ""
- echo ""
- echo ""
- echo ""
- echo "// Copy/paste the following to custom/defines_dasm.h"
- echo ""
- echo "// functions to run"
- echo "#define ARM_INIT ", [ARM_INIT]d
- echo "#define ARM_OS ", [ARM_OS]d
- echo "#define ARM_VB ", [ARM_VB]d
- echo "#define ARM_MENU_OS ", [ARM_MENU_OS]d
- echo "#define ARM_MENU_VB ", [ARM_MENU_VB]d
- echo ""
- echo "// datastream DS_ToARM"
- echo "#define FUNCTION queue[", [ARMfunction]d, "]"
- echo "#define SWCHA queue[", [ARMswcha]d, "]"
- echo "#define SWCHB queue[", [ARMswchb]d, "]"
- echo "#define INPT4 queue[", [ARMinpt4]d, "]"
- echo "#define INPT5 queue[", [ARMinpt5]d, "]"
- echo "#define VB_TIME queue[", [ARMvbtime]d, "]"
- echo "#define OS_TIME queue[", [ARMostime]d, "]"
- echo "#define MODE queue[", [ARMmode]d, "]"
- echo ""
- echo "// datastream DS_FromARM"
- echo "#define COLUPF queue[", [ARMcolupf]d, "]"
- echo ""
- echo "// Main Menu"
- echo "#define MENU_FIRST_OPTION_ID ", [MENU_FIRST_OPTION_ID]d
- echo "#define MENU_PLAYERS_ID ", [MENU_PLAYERS_ID]d
- echo "#define MENU_TV_TYPE_ID ", [MENU_TV_TYPE_ID]d
- echo "#define MENU_RGB_ID ", [MENU_RGB_ID]d
- echo "#define MENU_START_ID ", [MENU_START_ID]d
- echo "#define MENU_DATA ", [MenuData]d
- echo "#define MENU_DATA_SIZE ", [MenuDataSize]d
- echo "#define MENU_COLORS ", [MenuColors]d
- echo "#define MENU_COLORS_SIZE ", [MenuColorsSize]d
- echo "#define MENU_SELECTED_COLOR ", [MenuSelectedColor]d
- echo "#define OPTION_DIGIT_1 ", [OptionDigit1]d
- echo "#define OPTION_DIGIT_2 ", [OptionDigit2]d
- echo "#define OPTION_PAL_A ", [OptionPALA]d
- echo "#define OPTION_PAL_B ", [OptionPALB]d
- echo "#define OPTION_SECAM_A ", [OptionSECAMA]d
- echo "#define OPTION_SECAM_B ", [OptionSECAMB]d
- echo "#define OPTION_SECAM_C ", [OptionSECAMC]d
- echo "#define MM_JOYSTICK_TIMER queue[", [MM_JoystickTimer]d, "]"
- echo "#define MM_FIRE_DOWN queue[", [MM_FireDown]d, "]"
- echo "#define MM_SELECTED_OPTION queue[", [MM_SelectedOption]d, "]"
- echo "#define MM_PLAYERS queue[", [MM_Players]d, "]"
- echo "#define MM_TV_TYPE queue[", [MM_TVtype]d, "]"
- echo ""
- echo "// score and timer"
- echo "#define FONT ", [[Font & $fff] + $4000]d
- echo "#define LEFT_SCORE_A ", [LeftScoreA]d
- echo "#define LEFT_SCORE_B ", [LeftScoreB]d
- echo "#define TIMER_A ", [TimerA]d
- echo "#define TIMER_B ", [TimerB]d
- echo "#define RIGHT_SCORE_A ", [RightScoreA]d
- echo "#define RIGHT_SCORE_B ", [RightScoreB]d
- echo "#define SCORE_TIMER_COLORS ", [ScoreTimerColors]d
- echo "#define CHARACTER_SPACE ", [Space]d
- echo "#define CHARACTER_COLON ", [Colon]d
- echo "#define CHARACTER_VB ", [VB]d
- echo "#define CHARACTER_OS ", [OS]d
- echo "#define DELAY ", [Delay]d
- echo ""
- echo "// Arena Kernel"
- echo "#define ARENA_PF0 ", [ArenaPF0]d
- echo "#define ARENA_PF1 ", [ArenaPF1]d
- echo "#define ARENA_PF2 ", [ArenaPF2]d
- echo "#define PLAYER0_DS ", [Player0DataStream]d
- echo "#define PLAYER1_DS ", [Player1DataStream]d
- echo "#define COLOR0_DS ", [Color0DataStream]d
- echo "#define COLOR1_DS ", [Color1DataStream]d
- echo "#define COLOR_DS_SIZE ", [ColorDataStreamSize]d
- echo ""
- echo "// colors"
- echo "#define GREY ", [GREY]d
- echo "#define YELLOW ", [YELLOW]d
- echo "#define ORANGE ", [ORANGE]d
- echo "#define RED_ORANGE ", [RED_ORANGE]d
- echo "#define RED ", [RED]d
- echo "#define PURPLE ", [PURPLE]d
- echo "#define VIOLET ", [VIOLET]d
- echo "#define BLUE ", [BLUE]d
- echo "#define CYAN ", [CYAN]d
- echo "#define GREEN ", [GREEN]d
- echo "#define WHITE ", [WHITE]d
- echo ""
- echo ""
- echo ""
- echo ""
- echo ""
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement