Match_Race_2600_baby_step_9.txt - release 20220811.0 Experimental test in preparation for my first homebrew. Copyright (c) 2022 The Brew that is True To produce ROM binary execute: ./hexrom.sh Match_Race_2600_baby_step_9 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~> USER MANUAL DRAFT -- STARTS HERE <~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TODO TODO Couch compliance ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~> USER MANUAL DRAFT -- ENDS HERE <~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~> ENGINEERING NOTEBOOK -- STARTS HERE <~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ My Atari 2600 Engineering Notebook. Notes gleaned from Atari Age Forums and various other sources. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Glossary of Terms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Progressive Scan ---------------- Also known as Noninterlaced Scan. See https://en.wikipedia.org/wiki/Progressive_scan See The CRT Controller Handbook - Gerry Kane (1980) Video Blanking -------------- The blanking signal is the synchronizing signal that tells the TV to suppress the beaming of visible picture content onto the screen. A blanking interval (vertical or horizontal) is a period during which the video signal is blanked in order to give a CRT TV time to reposition its electron beam(s) and/or to reduce the risk of the image being cropped at the TV's edges. Also known as Video Suppression. Vertical Blanking Interval -------------------------- The time between the end of the final visible (active) scanline of a frame and the beginning of the first visible (active) scanline of the next frame (i.e. it comprises everything other than the Display Kernel). See https://en.wikipedia.org/wiki/Vertical_blanking_interval https://en.wikipedia.org/wiki/Raster_scan Most of a game's logic and housekeeping occur during the VBI by consuming otherwise idle CPU cycles while the video signal is blanked. Note that the Stella Programmer's Guide Diagram 1 (Atari TV Frame) somewhat confusingly labels as 'VERTICAL BLANK' only the subset of the Vertical Blanking Interval that is commonly known in Analog TV terms as the Vertical Back Porch. Vertical Sync Interval ---------------------- The duration of the Vertical Sync Pulse that signals the TV to perform a vertical retrace, repositioning its electron beam(s) to the top left of the screen. Also known as the Vertical Sync Width. Also known as the Vertical Flyback. Vertical Back Porch ------------------- The padding delay between the Vertical Sync Interval and the start of active scanlines. Display Kernel -------------- The scanlines that carry actual visible picture information are commonly called "active" scanlines. In this document the Display Kernel is the portion of each frame where our program drives the TV display on a scanline-by-scanline basis (i.e. everything other than the Vertical Blanking Interval). The Display Kernel comprises all the active scanlines of each frame. Also known as the Vertical Display Area. Pixel ----- In this document the 160 Visible Color Clocks of an active scanline are also referred to as pixels, i.e. an active scanline's color clocks 68..227 are also its pixels 0..159. Vertical Front Porch -------------------- The padding delay before the Vertical Sync Interval. Also known as the Vertical Sync Offset. Note that in the Stella Programmer's Guide Diagram 1 (Atari TV Frame) the Vertical Front Porch is called 'OVERSCAN'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Anatomy of the Game's NTSC Frame (Progressive Scan) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ time | : | : | .-------------------------. | | Vertical Synch Interval | | '-------------------------' +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Frame Boundary | .-------------------------. | | Vertical Back Porch | | '-------------------------' |<---------- Previous Vertical Blanking Interval ENDS here | .-------------------------. | | Display Kernel | | '-------------------------' |<---------- New Vertical Blanking Interval STARTS here | .-------------------------. | | Vertical Front Porch | | '-------------------------' | .-------------------------. | | Vertical Synch Interval | | '-------------------------' +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Frame Boundary | .-------------------------. | | Vertical Back Porch | | '-------------------------' | : | : v TIA Clock Speeds in MHz - NTSC 3.579545 - PAL 3.546894 - SECAM 3.562500 - PAL-M 3.575611 Source: https://atariage.com/forums/topic/ 316704-the-exact-speed-of-the-tia/ ?do=findComment&comment=4747044 TIA 6507 Horizontal Color CPU Frame Period Scanlines Clocks Cycles -------------------------- ---------- x228 ------- /3 ------- Vertical Front Porch 30 6,840 2,280 Vertical Sync Interval 3 684 228 Vertical Back Porch 37 8,436 2,812 --- ------ ------ Vertical Blanking Interval 70 15,960 5,320 Display Kernel 192 43,776 14,592 --- ------ ------ 60Hz NTSC Frame 262 59,736 19,912 Color Clock Apportionment -------------------------- Frame Game Frame Period Overhead Logic Total -------------------------- -------- + ------ = ------ Vertical Front Porch 15 6,825 6,840 Vertical Sync Interval 9 675 684 Vertical Back Porch 15 8,421 8,436 -------- ------ ------ Vertical Blanking Interval 39 15,921 15,960 Display Kernel 24 43,752 43,780 -------- ------ ------ 60Hz NTSC Frame 63 59,673 59,736 Each active scanline lasts 228 color clocks and is divided as follows: Color CPU Scanline Segment Clocks Cycles ----------------------------- ------ /3 ------ Horizontal Blanking Interval 68 22 2/3 Visible Color Clocks (pixels) 160 53 1/3 ------ ------ Entire Scanline 228 76 Note: A fully NTSC compliant progressive scan NTSC Frame would be 262.5 instead of the 2600's 262 scanlines. A fully NTSC compliant scanline would be 227.5 color clocks, while the 2600 takes 228 color clocks per scanline. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Aide-Memoire of 2600 Read Addresses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ addr chip register function ---- ---- --------- --------------------------- 0000 TIA CXM0P_c0 Collision: M0-P1, M0-P0 0001 TIA CXM1P_c0 Collision: M1-P0, M1-P1 0002 TIA CXP0FB_c0 Collision: P0-PF, P0-BL 0003 TIA CXP1FB_c0 Collision: P1-PF, P1-BL 0004 TIA CXM0FB_c0 Collision: M0-PF, M0-BL 0005 TIA CXM1FB_c0 Collision: M1-PF, M1-BL 0006 TIA CXBLPF_80 Collision: BL-PF 0007 TIA CXPPMM_c0 Collision: P0-P1, M0-M1 0008 TIA INPT0_80 Input Port 0 (Dumped Pot) 0009 TIA INPT1_80 Input Port 1 (Dumped Pot) 000a TIA INPT2_80 Input Port 2 (Dumped Pot) 000b TIA INPT3_80 Input Port 3 (Dumped Pot) 000c TIA INPT4_80 Input Port 4 (Left Joystick Button) 000d TIA INPT5_80 Input Port 5 (Right Joystick Button) 000e TIA undefined 000f TIA undefined 0080 PIA RAM 00:: : : 00ff PIA RAM 0280 PIA SWCHA_ff Port A (Hand Controller Switches) 0281 PIA SWACNT_ff Port A Data Direction Register 0282 PIA SWCHB_ff Port B (Console Switches) 0283 PIA SWBCNT_ff Port B Data Direction Register 0284 PIA INTIM_ff Interval Timer 0285 PIA unnamed 6532 Interrupt Flag canonical READ addr mirrors chip --------- ------------------- -------------------- 0000-000f xxx0 xx0x 0xxx ???? TIA 0080-00ff xxx0 xx0x 1??? ???? PIA/RIOT (RAM) 0280-0283 xxx0 xx1x 1xxx x0?? PIA/RIOT (Ports) 0284-0285 xxx0 xx1x 1xxx x1x? PIA/RIOT 1000-1fff xxx1 ???? ???? ???? Cartridge ROM (4K) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Aide-Memoire of 2600 Write Addresses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ addr chip register function ---- ---- --------- ------------------------------------ 0000 TIA VSYNC_02 Vertical Sync 0001 TIA VBLANK_c2 Vertical Blank & Ports Configuration 0002 TIA WSYNC_STB Wait for leading edge of HBI Strobe 0003 TIA RSYNC_STB Reset Horizontal Sync Counter Strobe 0004 TIA NUSIZ0_3f Number & Size: P0/M0 0005 TIA NUSIZ1_3f Number & Size: P1/M1 0006 TIA COLUP0_fe Color (Hue) & Luminance: P0/M0 0007 TIA COLUP1_fe Color (Hue) & Luminance: P1/M1 0008 TIA COLUPF_fe Color (Hue) & Luminance: PF/BL 0009 TIA COLUBK_fe Color (Hue) & Luminance: BK 000a TIA CTRLPF_37 PF settings & BL size 000b TIA REFP0_08 Reflection: P0 000c TIA REFP1_08 Reflection: P1 000d TIA PF0_f0 PF0 (quads 3-0) 000e TIA PF1_ff PF1 (quads 4-11) 000f TIA PF2_ff PF2 (quads 19-12) 0010 TIA RESP0_STB Reset Horizontal Position Strobe: P0 0011 TIA RESP1_STB Reset Horizontal Position Strobe: P1 0012 TIA RESM0_STB Reset Horizontal Position Strobe: M0 0013 TIA RESM1_STB Reset Horizontal Position Strobe: M1 0014 TIA RESBL_STB Reset Horizontal Position Strobe: BL 0015 TIA AUDC0_0f Control: Audio Channel 0 (left) 0016 TIA AUDC1_0f Control: Audio Channel 1 (right) 0017 TIA AUDF0_1f Frequency: Audio Channel 0 (left) 0018 TIA AUDF1_1f Frequency: Audio Channel 1 (right) 0019 TIA AUDV0_0f Volume: Audio Channel 0 (left) 001a TIA AUDV1_0f Volume: Audio Channel 1 (right) 001b TIA GRP0_ff Graphics Bitmap: P0 001c TIA GRP1_ff Graphics Bitmap: P1 001d TIA ENAM0_02 Enable Control: M0 001e TIA ENAM1_02 Enable Control: M1 001f TIA ENABL_02 Enable Control: BL 0020 TIA HMP0_f0 Horizontal Motion: P0 0021 TIA HMP1_f0 Horizontal Motion: P1 0022 TIA HMM0_f0 Horizontal Motion: M0 0023 TIA HMM1_f0 Horizontal Motion: M1 0024 TIA HMBL_f0 Horizontal Motion: BL 0025 TIA VDELP0_01 Vertical Delay: P0 0026 TIA VDELP1_01 Vertical Delay: P1 0027 TIA VDELBL_01 Vertical Delay: BL 0028 TIA RESMP0_02 Missile-Player Reset: M0/P0 0029 TIA RESMP1_02 Missile-Player Reset: M1/P1 002a TIA HMOVE_STB Horizontal Motion Strobe: Fine Offsets 002b TIA HMCLR_STB Horizontal Motion Strobe: Clear Registers 002c TIA CXCLR_STB Clear Collision Registers Strobe 002d TIA undefined 00:: : : 003f TIA undefined 0080 PIA RAM 00:: : : 00ff PIA RAM 0280 PIA SWCHA_ff Port A (Hand Controller Switches) 0281 PIA SWACNT_ff Port A Data Direction Register 0282 PIA SWCHB_ff Port B (Console Switches) (*) 0283 PIA SWBCNT_ff Port B Data Direction Register (*) 0284 PIA unnamed Disable 6532 PA7 (Timer) Interrupt, and configure for negative edge detect. 0285 PIA unnamed Disable 6532 PA7 (Timer) Interrupt, and configure for positive edge detect. 0286 PIA unnamed Enable 6532 PA7 (Timer) Interrupt, and configure for negative edge detect. 0287 PIA unnamed Enable 6532 PA7 (Timer) Interrupt, and configure for positive edge detect. 0294 PIA TIM1T_ff Set the Interval Timer with divide by 1 0295 PIA TIM8T_ff Set the Interval Timer with divide by 8 0296 PIA TIM64T_ff Set the Interval Timer with divide by 64 0297 PIA T1024T_ff Set the Interval Timer with divide by 1024 (*) Per http://www.qotile.net/minidig/docs/2600_riot_map.txt "The Stella documentation states that Port B is hardwired for input only. In reality, Port B is fully configurable. Configuring Port B as an output, however, will cause direct hardware conflicts with the console switches. DO NOT ATTEMPT THIS." canonical WRITE addr mirrors chip ---------- ------------------- -------------------- 0000-003f xxx0 xx0x 0x?? ???? TIA 0080-00ff xxx0 xx0x 1??? ???? PIA/RIOT (RAM) 0280-0283 xxx0 xx1x 1xxx x0?? PIA/RIOT (Ports) 0284-0287 xxx0 xx1x 1xx0 x1?? PIA/RIOT 0294-0297 xxx0 xx1x 1xx1 x1?? PIA/RIOT (Timer) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Notes on Horizontal Positioning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Coarse Positioning RES Lags --------------------------- Strobing an object's Reset Horizontal Position (RES) strobe resets that object's horizontal position counter to the color clock at which the strobing instruction completed. However, the actual display of an object by the TIA lags the horizontal position counter by a few color clocks as listed below: Object | Width | Lag (Color Clocks) -------+--------+------------------- Mx | | -------+ Any | 4 BL | | -------+--------+------------------- | Single | 5 +--------+------------------- Px | Double | +--------+ 6 | Quad | -------+--------+------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Notes on 6507 System Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Typically a 6502 has three system vectors at the top of its address space (16-bits each, little endian) wired as follows: vector | addr | contains ---------+------+-------------------------------------------- NMI | fffa | low byte of handler's address (page offset) +------+-------------------------------------------- | fffb | high byte of handler's address (page index) ---------+------+-------------------------------------------- RES | fffc | low byte of handler's address (page offset) +------+-------------------------------------------- | fffd | high byte of handler's address (page index) ---------+------+-------------------------------------------- IRQ/BRK | fffe | low byte of handler's address (page offset) +------+-------------------------------------------- | ffff | high byte of handler's address (page index) ---------+------+-------------------------------------------- In the specific case of the 2600 however H/W interrupts are disabled (the 6507 omits the IRQ and NMI pins, and the corresponding lines are hardwired to logic 1). Therefore we can appropriate the 16 bits of the NMI vector for our own purposes. We can do the same with the IRQ/BRK vector unless we plan to use the BRK instruction in our game. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Notes on Resources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 128 bytes of RAM 4,096 bytes of ROM 59,736 color clocks/frame ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~> ENGINEERING NOTEBOOK -- ENDS HERE <~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =============================================================== ===================> 4k ROM -- STARTS HERE <=================== =============================================================== org $1000 4k ROM occupies addresses $1000-$1fff =============================================================== =================> DELAY LINE -- STARTS HERE <================= =============================================================== | | ROM Bytes: $1000-1046 [71] +-------------------------------------------------------------- --------------------------------------------------------------- Directly Called Delay Line. ROM Bytes: $1000-1043 [68] --------------------------------------------------------------- Resolution: 1mc (3cc) Count: 67 Range: 8-74mc (24-222cc) $42 $41 $40 $3f $03 $02 $01 $00 <- offset 6507 .---.---.---.---.- -.---.---.---.---. Cycles | 8| 9| 10| 11| .. | 71| 72| 73| 74| -------+---+---+---+---+- -+---+---+---+---+ Color | 24| 27| 30| 33| .. |213|216|219|222| Clocks '---'---'---'---'- -'---'---'---'---' "Calling" into one of the bytes below (that precede the RTS instruction) "nops" a number of CPU cycles as indicated in the chart above. The requested delay can range from 8 to 74 CPU cycles (i.e. 24 to 222 color clocks). N.B. This delay is in addition to any cycles expended to reach the this subroutine. The minimum target byte offset is 0, it results in the maximum delay of 74mc (222cc). The maximum target byte offset is $42 (66), it resuls in the minimum delay of 8mc (24cc). Use a JSR to call into the code if the delay (and therefore the destination address) is fixed at compile-time, e.g. jsr DELAY_LINE-n resulting in a total delay of (6+8+n) CPU cycles (x3 for cc), where 6mc are consumed by the JSR instruction, 8mc is the minimum overhead of using the delay line, and n is the number of additional CPU cycles of delay you are requesting. Use an RTS or a JMP (ADDR) to call into the code if the delay (and therefore the jump address) needs to be calculated at runtime (see also jsr INDIRECT_DELAY_LINE). This code can be made modified as dictated by the needs of the specific ROM, either to increase the maximum request-able delay, or to recover some ROM by decreasing the maximum. 6507 color offset cycles clocks ------- ------ x3 -------- 80808080808080808080808080808080 $00..0f 74..59 222..177 80808080808080808080808080808080 $10..1f 58..43 174..129 80808080808080808080808080808080 $20..2f 42..27 126.. 81 80808080808080808080808080808080 $30..3f 26..11 78.. 33 0c04 $40..41 10.. 9 30.. 27 DELAY_LINE: ($1042) ea nop (2)x3 $42 8 24 60 rts (6)x3 --------------------------------------------------------------- Indirectly Called Delay Line. ROM Bytes: $1044-1046 [3] --------------------------------------------------------------- Expects the RAM word at ORAM_DELAY_LINE_NDX:ORAM_DELAY_LINE_OFS to hold the precalculated destination address within the delay line page (i.e. $10:ofs). Resolution: 1mc (3cc) Count: 67 Range: 13-79mc (39-237cc), i.e. fixed overhead: 13mc (39cc) + variable delay: 0-66mc (0-198cc) If we assume we arrived here via "jsr INDIRECT_DELAY_LINE", costing us an additional 6mc, this then becomes: Range: 19-85mc (57-255cc), i.e. fixed overhead: 19mc (57cc) + variable delay: 0-66mc (0-198cc) ofs $42 $41 $40 $3f $03 $02 $01 $00 .---.---.---.---.- -.---.---.---.---. mc | 19| 20| 21| 22| .. | 82| 83| 84| 85| ---+---+---+---+---+- -+---+---+---+---+ cc | 57| 60| 63| 66| .. |246|249|252|255| '---'---'---'---'- -'---'---'---'---' INDIRECT_DELAY_LINE: 6cd000 jmp (ORAM_DELAY_LINE_NDX:ORAM_DELAY_LINE_OFS) (5)x3 =============================================================== ==================> DELAY LINE -- ENDS HERE <================== =============================================================== ========> HORIZONTAL POSITIONING TABLES -- START HERE <======== =============================================================== | | N.B. Don't let tables straddle page boundaries. | | ROM Bytes: $1047-119f [345] +-------------------------------------------------------------- N.B. The following assumptions are baked into these tables: - HMOVE strobe takes effect at 213cc (i.e. 71mc) - Single-Width Px, further implying a 5cc RES lag (cf. "Coarse Positioning RES Lags"). - GRPx bits are flush-right, e.g. if the current sprite width of GRP0 (i.e. CRAM_P0_WIDTH) is 5, only the 5 rightmost (least-significant) bits of GRPx are displayed. Horizontal Positioning Summary ------------------------------ Color clocks of "fine" ndx adjustment (c) ofs +/- ------------------------ px HPC (a) (b) 1 2 3 4 5 6 7 8 <- sprite width --- --- --- --- --- -- -- -- -- -- -- -- 000 003 $42 -1 -10 -9 -8 -7 -6 -5 -4 -3 001 003 $42 0 -9 -8 -7 -6 -5 -4 -3 -2 002 003 $42 +1 -8 -7 -6 -5 -4 -3 -2 -1 003 006 $41 -1 -10 -9 -8 -7 -6 -5 -4 -3 004 006 $41 0 -9 -8 -7 -6 -5 -4 -3 -2 005 006 $41 +1 -8 -7 -6 -5 -4 -3 -2 -1 006 009 $40 -1 -10 -9 -8 -7 -6 -5 -4 -3 007 009 $40 0 -9 -8 -7 -6 -5 -4 -3 -2 008 009 $40 +1 -8 -7 -6 -5 -4 -3 -2 -1 009 012 $3f -1 -10 -9 -8 -7 -6 -5 -4 -3 010 012 $3f 0 -9 -8 -7 -6 -5 -4 -3 -2 011 012 $3f +1 -8 -7 -6 -5 -4 -3 -2 -1 012 015 $3e -1 -10 -9 -8 -7 -6 -5 -4 -3 013 015 $3e 0 -9 -8 -7 -6 -5 -4 -3 -2 014 015 $3e +1 -8 -7 -6 -5 -4 -3 -2 -1 015 018 $3d -1 -10 -9 -8 -7 -6 -5 -4 -3 016 018 $3d 0 -9 -8 -7 -6 -5 -4 -3 -2 017 018 $3d +1 -8 -7 -6 -5 -4 -3 -2 -1 018 021 $3c -1 -10 -9 -8 -7 -6 -5 -4 -3 019 021 $3c 0 -9 -8 -7 -6 -5 -4 -3 -2 020 021 $3c +1 -8 -7 -6 -5 -4 -3 -2 -1 021 024 $3b -1 -10 -9 -8 -7 -6 -5 -4 -3 022 024 $3b 0 -9 -8 -7 -6 -5 -4 -3 -2 023 024 $3b +1 -8 -7 -6 -5 -4 -3 -2 -1 024 027 $3a -1 -10 -9 -8 -7 -6 -5 -4 -3 025 027 $3a 0 -9 -8 -7 -6 -5 -4 -3 -2 026 027 $3a +1 -8 -7 -6 -5 -4 -3 -2 -1 028 030 $39 -1 -10 -9 -8 -7 -6 -5 -4 -3 029 030 $39 0 -9 -8 -7 -6 -5 -4 -3 -2 030 030 $39 +1 -8 -7 -6 -5 -4 -3 -2 -1 031 033 $38 -1 -10 -9 -8 -7 -6 -5 -4 -3 032 033 $38 0 -9 -8 -7 -6 -5 -4 -3 -2 033 033 $38 +1 -8 -7 -6 -5 -4 -3 -2 -1 034 036 $37 -1 -10 -9 -8 -7 -6 -5 -4 -3 035 036 $37 0 -9 -8 -7 -6 -5 -4 -3 -2 036 036 $37 +1 -8 -7 -6 -5 -4 -3 -2 -1 037 039 $36 -1 -10 -9 -8 -7 -6 -5 -4 -3 038 039 $36 0 -9 -8 -7 -6 -5 -4 -3 -2 039 039 $36 +1 -8 -7 -6 -5 -4 -3 -2 -1 040 042 $35 -1 -10 -9 -8 -7 -6 -5 -4 -3 040 042 $35 0 -9 -8 -7 -6 -5 -4 -3 -2 041 042 $35 +1 -8 -7 -6 -5 -4 -3 -2 -1 042 045 $34 -1 -10 -9 -8 -7 -6 -5 -4 -3 043 045 $34 0 -9 -8 -7 -6 -5 -4 -3 -2 044 045 $34 +1 -8 -7 -6 -5 -4 -3 -2 -1 045 048 $33 -1 -10 -9 -8 -7 -6 -5 -4 -3 046 048 $33 0 -9 -8 -7 -6 -5 -4 -3 -2 047 048 $33 +1 -8 -7 -6 -5 -4 -3 -2 -1 048 051 $32 -1 -10 -9 -8 -7 -6 -5 -4 -3 049 051 $32 0 -9 -8 -7 -6 -5 -4 -3 -2 050 051 $32 +1 -8 -7 -6 -5 -4 -3 -2 -1 051 054 $31 -1 -10 -9 -8 -7 -6 -5 -4 -3 052 054 $31 0 -9 -8 -7 -6 -5 -4 -3 -2 053 054 $31 +1 -8 -7 -6 -5 -4 -3 -2 -1 054 057 $30 -1 -10 -9 -8 -7 -6 -5 -4 -3 055 057 $30 0 -9 -8 -7 -6 -5 -4 -3 -2 056 057 $30 +1 -8 -7 -6 -5 -4 -3 -2 -1 057 060 $2f -1 -10 -9 -8 -7 -6 -5 -4 -3 058 060 $2f 0 -9 -8 -7 -6 -5 -4 -3 -2 059 060 $2f +1 -8 -7 -6 -5 -4 -3 -2 -1 060 063 $2e -1 -10 -9 -8 -7 -6 -5 -4 -3 061 063 $2e 0 -9 -8 -7 -6 -5 -4 -3 -2 062 063 $2e +1 -8 -7 -6 -5 -4 -3 -2 -1 063 066 $2d -1 -10 -9 -8 -7 -6 -5 -4 -3 064 066 $2d 0 -9 -8 -7 -6 -5 -4 -3 -2 065 066 $2d +1 -8 -7 -6 -5 -4 -3 -2 -1 066 069 $2c -1 -10 -9 -8 -7 -6 -5 -4 -3 067 069 $2c 0 -9 -8 -7 -6 -5 -4 -3 -2 068 069 $2c +1 -8 -7 -6 -5 -4 -3 -2 -1 069 072 $2b -1 -10 -9 -8 -7 -6 -5 -4 -3 070 072 $2b 0 -9 -8 -7 -6 -5 -4 -3 -2 071 072 $2b +1 -8 -7 -6 -5 -4 -3 -2 -1 072 075 $2a -1 -10 -9 -8 -7 -6 -5 -4 -3 073 075 $2a 0 -9 -8 -7 -6 -5 -4 -3 -2 074 075 $2a +1 -8 -7 -6 -5 -4 -3 -2 -1 075 078 $29 -1 -10 -9 -8 -7 -6 -5 -4 -3 076 078 $29 0 -9 -8 -7 -6 -5 -4 -3 -2 077 078 $29 +1 -8 -7 -6 -5 -4 -3 -2 -1 078 081 $28 -1 -10 -9 -8 -7 -6 -5 -4 -3 079 081 $28 0 -9 -8 -7 -6 -5 -4 -3 -2 080 081 $28 +1 -8 -7 -6 -5 -4 -3 -2 -1 081 084 $27 -1 -10 -9 -8 -7 -6 -5 -4 -3 082 084 $27 0 -9 -8 -7 -6 -5 -4 -3 -2 083 084 $27 +1 -8 -7 -6 -5 -4 -3 -2 -1 084 087 $26 -1 -10 -9 -8 -7 -6 -5 -4 -3 085 087 $26 0 -9 -8 -7 -6 -5 -4 -3 -2 086 087 $26 +1 -8 -7 -6 -5 -4 -3 -2 -1 087 090 $25 -1 -10 -9 -8 -7 -6 -5 -4 -3 088 090 $25 0 -9 -8 -7 -6 -5 -4 -3 -2 089 090 $25 +1 -8 -7 -6 -5 -4 -3 -2 -1 090 093 $24 -1 -10 -9 -8 -7 -6 -5 -4 -3 091 093 $24 0 -9 -8 -7 -6 -5 -4 -3 -2 092 093 $24 +1 -8 -7 -6 -5 -4 -3 -2 -1 093 096 $23 -1 -10 -9 -8 -7 -6 -5 -4 -3 094 096 $23 0 -9 -8 -7 -6 -5 -4 -3 -2 095 096 $23 +1 -8 -7 -6 -5 -4 -3 -2 -1 096 099 $22 -1 -10 -9 -8 -7 -6 -5 -4 -3 097 099 $22 0 -9 -8 -7 -6 -5 -4 -3 -2 098 099 $22 +1 -8 -7 -6 -5 -4 -3 -2 -1 099 102 $21 -1 -10 -9 -8 -7 -6 -5 -4 -3 100 102 $21 0 -9 -8 -7 -6 -5 -4 -3 -2 101 102 $21 +1 -8 -7 -6 -5 -4 -3 -2 -1 102 105 $20 -1 -10 -9 -8 -7 -6 -5 -4 -3 103 105 $20 0 -9 -8 -7 -6 -5 -4 -3 -2 104 108 $20 +1 -8 -7 -6 -5 -4 -3 -2 -1 105 108 $1f -1 -10 -9 -8 -7 -6 -5 -4 -3 106 108 $1f 0 -9 -8 -7 -6 -5 -4 -3 -2 107 108 $1f +1 -8 -7 -6 -5 -4 -3 -2 -1 108 111 $1e -1 -10 -9 -8 -7 -6 -5 -4 -3 109 111 $1e 0 -9 -8 -7 -6 -5 -4 -3 -2 100 111 $1e +1 -8 -7 -6 -5 -4 -3 -2 -1 111 114 $1d -1 -10 -9 -8 -7 -6 -5 -4 -3 112 114 $1d 0 -9 -8 -7 -6 -5 -4 -3 -2 113 114 $1d +1 -8 -7 -6 -5 -4 -3 -2 -1 114 117 $1c -1 -10 -9 -8 -7 -6 -5 -4 -3 115 117 $1c 0 -9 -8 -7 -6 -5 -4 -3 -2 116 117 $1c +1 -8 -7 -6 -5 -4 -3 -2 -1 117 120 $1b -1 -10 -9 -8 -7 -6 -5 -4 -3 118 120 $1b 0 -9 -8 -7 -6 -5 -4 -3 -2 119 120 $1b +1 -8 -7 -6 -5 -4 -3 -2 -1 120 123 $1a -1 -10 -9 -8 -7 -6 -5 -4 -3 121 123 $1a 0 -9 -8 -7 -6 -5 -4 -3 -2 122 123 $1a +1 -8 -7 -6 -5 -4 -3 -2 -1 123 126 $19 -1 -10 -9 -8 -7 -6 -5 -4 -3 124 126 $19 0 -9 -8 -7 -6 -5 -4 -3 -2 125 126 $19 +1 -8 -7 -6 -5 -4 -3 -2 -1 126 129 $18 -1 -10 -9 -8 -7 -6 -5 -4 -3 127 129 $18 0 -9 -8 -7 -6 -5 -4 -3 -2 128 129 $18 +1 -8 -7 -6 -5 -4 -3 -2 -1 129 132 $17 -1 -10 -9 -8 -7 -6 -5 -4 -3 130 132 $17 0 -9 -8 -7 -6 -5 -4 -3 -2 131 132 $17 +1 -8 -7 -6 -5 -4 -3 -2 -1 132 135 $16 -1 -10 -9 -8 -7 -6 -5 -4 -3 133 135 $16 0 -9 -8 -7 -6 -5 -4 -3 -2 134 135 $16 +1 -8 -7 -6 -5 -4 -3 -2 -1 135 138 $15 -1 -10 -9 -8 -7 -6 -5 -4 -3 136 138 $15 0 -9 -8 -7 -6 -5 -4 -3 -2 137 138 $15 +1 -8 -7 -6 -5 -4 -3 -2 -1 138 141 $14 -1 -10 -9 -8 -7 -6 -5 -4 -3 139 141 $14 0 -9 -8 -7 -6 -5 -4 -3 -2 140 141 $14 +1 -8 -7 -6 -5 -4 -3 -2 -1 141 144 $13 -1 -10 -9 -8 -7 -6 -5 -4 -3 142 144 $13 0 -9 -8 -7 -6 -5 -4 -3 -2 143 144 $13 +1 -8 -7 -6 -5 -4 -3 -2 -1 144 147 $12 -1 -10 -9 -8 -7 -6 -5 -4 -3 145 147 $12 0 -9 -8 -7 -6 -5 -4 -3 -2 146 147 $12 +1 -8 -7 -6 -5 -4 -3 -2 -1 147 150 $11 -1 -10 -9 -8 -7 -6 -5 -4 -3 148 150 $11 0 -9 -8 -7 -6 -5 -4 -3 -2 149 150 $11 +1 -8 -7 -6 -5 -4 -3 -2 -1 150 153 $10 -1 -10 -9 -8 -7 -6 -5 -4 -3 151 153 $10 0 -9 -8 -7 -6 -5 -4 -3 -2 152 153 $10 +1 -8 -7 -6 -5 -4 -3 -2 -1 153 156 $0f -1 -10 -9 -8 -7 -6 -5 -4 na 154 156 $0f 0 -9 -8 -7 -6 -5 -4 na na 155 156 $0f +1 -8 -7 -6 -5 -4 na na na 156 156 $0f +2 -7 -6 -5 -4 na na na na 157 156 $0f +3 -6 -5 -4 na na na na na 158 156 $0f +4 -5 -4 na na na na na na 159 156 $0f +5 -4 na na na na na na na Horizontal Positioning Summary Notes: (a) Implemented at TAB_RESPx_DELAY. (b) Implemented at TAB_HMPx_NDX. (c) Implemented at TAB_HMPx_VAL. N.B. These are reductions to the cc value produced by the HPC, i.e. their net effect is to pull the final adjusted cc value earlier (i.e. to the left). --------------------------------------------------------------- Table of RESPx DELAY offsets. Maps an X coordinate to a compatible ***coarse*** positioning DELAY offset. ROM Bytes: $1047-10e6 [160] --------------------------------------------------------------- TAB_RESPx_DELAY: 4242424141414040403f3f3f3e3e3e px000-014 3d3d3d3c3c3c3b3b3b3a3a3a393939 px015-029 383838373737363636353535343434 px030-044 3333333232323131313030302f2f2f px045-059 2e2e2e2d2d2d2c2c2c2b2b2b2a2a2a px060-074 292929282828272727262626252525 px075-089 242424232323222222212121202020 px090-104 1f1f1f1e1e1e1d1d1d1c1c1c1b1b1b px105-119 1a1a1a191919181818171717161616 px120-134 151515141414131313121212111111 px135-149 1010100f0f0f0f0f0f0f px150-159 --------------------------------------------------------------- Table of net "fine" cc adjustment values and corresponding HMPx encodings. ROM Bytes: $10e7-10f0 [10] --------------------------------------------------------------- ndx| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 --+-----+-----+-----+-----+-----+-----+-----+-----+-----+----- cc| -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 --+-----+-----+-----+-----+-----+-----+-----+-----+-----+----- HM| $40 | $30 | $20 | $10 | $00 | $f0 | $e0 | $d0 | $c0 | $b0 --+-----+-----+-----+-----+-----+-----+-----+-----+-----+----- *| 4 | 3 | 2 | 1 | 0 | f | e | d | c | b * High nibble as shown in Stella Emulator TIA tab's HM box. TAB_HMPx_VAL: 4030201000f0e0d0c0b0 --------------------------------------------------------------- UNUSED ROM We can replace unused ROM with useful data or code as needed. ROM Bytes: $10f1-$10ff [15] --------------------------------------------------------------- Padding so that TAB_HMPx_NDX won't straddle a page boundary. 1cedc0ffee4babe51cedc0ffee4bab --------------------------------------------------------------- Table of adjustments to the TAB_HMPx_VAL index. Maps an X coordinate to an adjustment that must be applied to the preliminary TAB_HMPx_VAL index. ROM Bytes: $1100-119f [160] --------------------------------------------------------------- TAB_HMPx_NDX: ff0001ff0001ff0001ff0001ff0001 px000-014 ff0001ff0001ff0001ff0001ff0001 px015-029 ff0001ff0001ff0001ff0001ff0001 px030-044 ff0001ff0001ff0001ff0001ff0001 px045-059 ff0001ff0001ff0001ff0001ff0001 px060-074 ff0001ff0001ff0001ff0001ff0001 px075-089 ff0001ff0001ff0001ff0001ff0001 px090-104 ff0001ff0001ff0001ff0001ff0001 px105-119 ff0001ff0001ff0001ff0001ff0001 px120-134 ff0001ff0001ff0001ff0001ff0001 px135-149 ff0001ff000102030405 px150-159 =============================================================== =========> HORIZONTAL POSITIONING TABLES -- END HERE <========= =============================================================== ================> SPRITE TABLES -- START HERE <================ =============================================================== | | ROM Bytes: $11a0-1205 [102] +-------------------------------------------------------------- N.B. Boat headings are numbered clockwise from West: NW=1 N=2 NE=3 \ | / \ | / W=0 --- * --- E=4 / | \ / | \ SW=7 S=6 SE=5 0 %000 West 1 %001 North West 2 %010 North 3 %011 North East 4 %100 East 5 %101 South East 6 %110 South 7 %111 South West orientation ----------- %x00 horizontal %x10 vertical %xx1 diagonal --------------------------------------------------------------- GRPx Templates. --------------------------------------------------------------- Keep in mind that the NTSC 2600's pixel aspect ratio is x:y ≈ 5:3. Sprite templates are encoded upside-down from their display orientation for countdown convenience, and also flush-right as presumed by our Horizontal Positioning Tables. N.B. The flush-right requirement makes it impractical for us to take advantage of player reflection (REFPx). --------------------------------------------------------------- GRPx Template: Boat heading West. ROM Bytes: $11a0-11a4 [5] --------------------------------------------------------------- row# 01 .......x 0 01 .......x 1 7f .xxxxxxx 2 01 .......x 3 01 .......x 4 --------------------------------------------------------------- GRPx Template: Boat heading North-West. ROM Bytes: $11a5-11ac [8] --------------------------------------------------------------- row# 02 ......x. 0 02 ......x. 1 07 .....xxx 2 0c ....xx.. 3 18 ...xx... 4 30 ..xx.... 5 60 .xx..... 6 40 .x...... 7 --------------------------------------------------------------- GRPx Template: Boat heading North. ROM Bytes: $11ad-11b6 [10] --------------------------------------------------------------- row# 07 .....xxx 0 02 ......x. 1 02 ......x. 2 02 ......x. 3 02 ......x. 4 02 ......x. 5 02 ......x. 6 02 ......x. 7 02 ......x. 8 02 ......x. 9 --------------------------------------------------------------- GRPx Template: Boat heading North-East. ROM Bytes: $11b7-11be [8] --------------------------------------------------------------- row# 20 ..x..... 0 20 ..x..... 1 70 .xxx.... 2 18 ...xx... 3 0c ....xx.. 4 06 .....xx. 5 03 ......xx 6 01 .......x 7 --------------------------------------------------------------- GRPx Template: Boat heading East. ROM Bytes: $11bf-11c3 [5] --------------------------------------------------------------- row# 40 .x...... 0 40 .x...... 1 7f .xxxxxxx 2 40 .x...... 3 40 .x...... 4 --------------------------------------------------------------- GRPx Template: Boat heading South-East. ROM Bytes: $11c4-11cb [8] --------------------------------------------------------------- row# 01 .......x 0 03 ......xx 1 06 .....xx. 2 0c ....xx.. 3 18 ...xx... 4 70 .xxx.... 5 20 ..x..... 6 20 ..x..... 7 --------------------------------------------------------------- GRPx Template: Boat heading South. ROM Bytes: $11cc-11d5 [10] --------------------------------------------------------------- row# 02 ......x. 0 02 ......x. 1 02 ......x. 2 02 ......x. 3 02 ......x. 4 02 ......x. 5 02 ......x. 6 02 ......x. 7 02 ......x. 8 07 .....xxx 9 --------------------------------------------------------------- GRPx Template: Boat heading South-West. ROM Bytes: $11d6-11dd [8] --------------------------------------------------------------- row# 40 .x...... 0 60 .xx..... 1 30 ..xx.... 2 18 ...xx... 3 0c ....xx.. 4 07 .....xxx 5 02 ......x. 6 02 ......x. 7 --------------------------------------------------------------- GRPx Template offset by Boat Heading. ROM Bytes: $11de-11e5 [8] --------------------------------------------------------------- PAGE_TAB_GRPx = $1100 (relocatable) TAB_GRPx_OFS: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <- Heading a0a5adb7bfc4ccd6 (relocatable) --------------------------------------------------------------- GRPx Height by Boat Heading. ROM Bytes: $11e6-11ed [8] --------------------------------------------------------------- TAB_GRPx_HEIGHT: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <- Heading 05080a0805080a08 --------------------------------------------------------------- GRPx Width by Boat Heading. ROM Bytes: $11ee-11f5 [8] --------------------------------------------------------------- TAB_GRPx_WIDTH: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <- Heading 0707030707070307 --------------------------------------------------------------- GRPx Bow Pixel. --------------------------------------------------------------- When a boat sprite turns it pivots about the pixel that represents the bow of the boat. The following tables provide quick lookups of the X and Y offsets of the bow pixel pivot point from the lower left sprite origin for each boat heading. --------------------------------------------------------------- GRPx Pivot Point X offset by Boat Heading. ROM Bytes: $11f6-11fd [8] --------------------------------------------------------------- TAB_GRPx_BOW_X_OFS: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Heading 0000010606060100 --------------------------------------------------------------- GRPx Pivot Point Y offset by Boat Heading. ROM Bytes: $11fe-1205 [8] --------------------------------------------------------------- TAB_GRPx_BOW_Y_OFS: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Heading 0207090702000000 =============================================================== =================> SPRITE TABLES -- END HERE <================= =============================================================== ==========> TRAJECTORY SCALING TABLES -- START HERE <========== =============================================================== | | ROM Bytes: $1206-12cf [192] +-------------------------------------------------------------- The NTSC 2600's pixel aspect ratio is x:y ≈ 5:3, i.e. 1 scanline height ≈ 0.6 color clocks. The following trajectory scaling factors account for the pixel aspect ratio and a given trajectory angle: .--------------------.----------------. | delta y | delta x | | (scanline heights) | (color clocks) | .--------------+--------------------+----------------+ | Vertical | 1 | - | +--------------+--------------------+----------------+ | Horizontal | - | 0.6 | +--------------+--------------------+----------------+ | 45° Diagonal | 1/√2 | 0.6/√2 | '--------------'--------------------'----------------' In order to make use of the collision registers we'd like to cap visible player movement in a single frame to one scanline height vertically and one color clock horizontally. We've chosen to have six evenly spaced sailboats speeds, ranging from 0 to a maximum of 1 unit-distance. The following summaries precalculate the binary scalings of the x and y deltas corresponding to each speed and trajectory angle combination. N.B. Binary scaled $01.00 = 1 unit-distance = 1 scanline height. Vertical Trajectory Summary --------------------------- .---------------------------------------. | delta y (in scanline heights) | .-----------------+-------+-------+-------+-------+-------+ | speed rating | 1 | 2 | 3 | 4 | 5 | +-----------------+-------+-------+-------+-------+-------+ | #unit-distances | 1/5 | 2/5 | 3/5 | 4/5 | 1 | +=================+=======+=======+=======+=======+=======+ | ×1 scaling | 0.20 | 0.40 | 0.60 | 0.80 | 1 | +-----------------+-------+-------+-------+-------+-------+ | binary scaling | 51.2 | 102.4 | 153.6 | 204.8 | 256 | +===========.=====+=======+=======+=======+=======+=======+ | | + | 00.33 | 00.66 | 00.99 | 00.cc | 01.00 | | $px.subpx +-----+-------+-------+-------+-------+-------+ | | - | ff.cd | ff.9a | ff.67 | ff.34 | ff.00 | '-----------'-----'-------'-------'-------'-------'-------' Horizontal Trajectory Summary ----------------------------- .---------------------------------------. | delta x (in color clocks) | .-----------------+-------+-------+-------+-------+-------+ | speed rating | 1 | 2 | 3 | 4 | 5 | +-----------------+-------+-------+-------+-------+-------+ | #unit-distances | 1/5 | 2/5 | 3/5 | 4/5 | 1 | +=================+=======+=======+=======+=======+=======+ | ×0.6 scaling | 0.12 | 0.24 | 0.36 | 0.48 | 0.6 | +-----------------+-------+-------+-------+-------+-------+ | binary scaling | 30.7 | 61.4 | 92.1 | 122.8 | 153.6 | +===========.=====+=======+=======+=======+=======+=======+ | | + | 00.1e | 00.3d | 00.5c | 00.7a | 00.99 | | $px.subpx +-----+-------+-------+-------+-------+-------+ | | - | ff.e2 | ff.c3 | ff.a4 | ff.86 | ff.67 | '-----------'-----'-------'-------'-------'-------'-------' 45° Diagonal Trajectory Summary ------------------------------- .---------------------------------------. | delta y (in scanline heights) | .-----------------+-------+-------+-------+-------+-------+ | speed rating | 1 | 2 | 3 | 4 | 5 | +-----------------+-------+-------+-------+-------+-------+ | #unit-distances | 1/5 | 2/5 | 3/5 | 4/5 | 1 | +=================+=======+=======+=======+=======+=======+ | ×1/√2 scaling | 0.141 | 0.282 | 0.424 | 0.565 | 0.707 | +-----------------+-------+-------+-------+-------+-------+ | binary scaling | 36.20 | 72.40 | 108.6 | 144.8 | 181.0 | +===========.=====+=======+=======+=======+=======+=======+ | | + | 00.24 | 00.48 | 00.6c | 00.90 | 00.b5 | | $px.subpx +-----+-------+-------+-------+-------+-------+ | | - | ff.dc | ff.b8 | ff.94 | ff.70 | ff.4b | '-----------'-----'-------'-------'-------'-------'-------' .---------------------------------------. | delta x (in color clocks) | .-----------------+-------+-------+-------+-------+-------+ | speed rating | 1 | 2 | 3 | 4 | 5 | +-----------------+-------+-------+-------+-------+-------+ | #unit-distances | 1/5 | 2/5 | 3/5 | 4/5 | 1 | +=================+=======+=======+=======+=======+=======+ | ×0.6/√2 scaling | 0.084 | 0.169 | 0.254 | 0.339 | 0.424 | +-----------------+-------+-------+-------+-------+-------+ | binary scaling | 21.72 | 43.44 | 65.16 | 86.88 | 108.6 | +===========.=====+=======+=======+=======+=======+=======+ | | + | 00.15 | 00.2b | 00.41 | 00.56 | 00.6c | | $px.subpx +-----+-------+-------+-------+-------+-------+ | | - | ff.eb | ff.d5 | ff.bf | ff.aa | ff.94 | '-----------'-----'-------'-------'-------'-------'-------' --------------------------------------------------------------- Table of color clock deltas. ROM Bytes: $1206-$1235 [48] --------------------------------------------------------------- TAB_X_DELTA: Speed 0 1 2 3 4 5 Heading 00ffffffffff <-- 0 W 00ffffffffff <-- 1 NW 000000000000 <-- 2 N 000000000000 <-- 3 NE 000000000000 <-- 4 E 000000000000 <-- 5 SE 000000000000 <-- 6 S 00ffffffffff <-- 7 SW --------------------------------------------------------------- Table of sub color clock deltas. ROM Bytes: $1236-$1265 [48] --------------------------------------------------------------- TAB_X_SUBPX_DELTA: Speed 0 1 2 3 4 5 Heading 00e2c3a48667 <-- 0 W 00ebd5bfaa94 <-- 1 NW 000000000000 <-- 2 N 00152b41566c <-- 3 NE 001e3d5c7a99 <-- 4 E 00152b41566c <-- 5 SE 000000000000 <-- 6 S 00ebd5bfaa94 <-- 7 SW --------------------------------------------------------------- Table of scanline height deltas. ROM Bytes: $1266-$1295 [48] --------------------------------------------------------------- TAB_Y_DELTA: Speed 0 1 2 3 4 5 Heading 000000000000 <-- 0 W 000000000000 <-- 1 NW 000000000001 <-- 2 N 000000000000 <-- 3 NE 000000000000 <-- 4 E 00ffffffffff <-- 5 SE 00ffffffffff <-- 6 S 00ffffffffff <-- 7 SW --------------------------------------------------------------- Table of sub scanline height deltas. ROM Bytes: $1296-$12c5 [48] --------------------------------------------------------------- TAB_Y_SUBPX_DELTA: Speed 0 1 2 3 4 5 Heading 000000000000 <-- 0 W 0024486c90b5 <-- 1 NW 00336699cc00 <-- 2 N 0024486c90b5 <-- 3 NE 000000000000 <-- 4 E 00dcb894704b <-- 5 SE 00cd9a673400 <-- 6 S 00dcb894704b <-- 7 SW =============================================================== ===========> TRAJECTORY SCALING TABLES -- END HERE <=========== =============================================================== ==============> WIND VANE TABLES -- START HERE <=============== =============================================================== | | ROM Bytes: $12c6-12d5 [16] +-------------------------------------------------------------- --------------------------------------------------------------- Wind Vane's RESBL DELAY offset per Wind Direction ROM Bytes: $12c6-12cd [8] --------------------------------------------------------------- TAB_VANE_RESBL_DELAY: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Wind Direction 2929262323232629 <-- RESBL DELAY offsets N.B. We're only using coarse positioning for the Wind Indicator, fine positioning seems like it would be overkill. --------------------------------------------------------------- Wind Vane's BL Y Coordinate per Wind Direction ROM Bytes: $12ce-12d5 [8] --------------------------------------------------------------- TAB_VANE_BL_Y: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Wind Direction 606c6c6c60545454 <-- BL Y +1 N.B. - The current 4LK is premised on BL Y +1 values being multiples of 4 between 4..188. - The current Reset, Pre-Kernel, and Kernel code are premised on us never needing BL to be on in the top (Y==191) or bottom (Y==0) active scanlines. =============================================================== ===============> WIND VANE TABLES -- END HERE <================ =============================================================== =============> SPEED CHANGE TABLE -- STARTS HERE <============= =============================================================== | | ROM Bytes: $12d6-12f3 [30] +-------------------------------------------------------------- Note that broad reach (point of sail #3) is generally considered more efficient than running directly downdind (point of sail #4). Point of Sail New Speed This Frame This Frame \ 0 1 2 3 4 \ - - - - - 0| 0 1 1 1 1 |0 1| 0 2 2 2 2 |1 Previous 2| 1 2 2 3 3 |2 Speed 3| 1 2 3 4 4 |3 4| 2 2 3 5 4 |4 5| 2 3 3 5 4 |5 - - - - - 0 1 2 3 4 TAB_SPEED_CHANGE: 0001010101 0002020202 0102020303 0102030404 0202030504 0203030504 =============================================================== ==============> SPEED CHANGE TABLE -- ENDS HERE <============== =============================================================== =================> (PADDING) -- STARTS HERE <================== =============================================================== | | ROM Bytes: $12f4-$12ff [12] +-------------------------------------------------------------- Padding so that Points of Sail table won't straddle a page boundary. We can replace unused ROM with useful data or code as needed. 1cedc0ffee4babe51cedc0ff =============================================================== ==================> (PADDING) -- ENDS HERE <=================== =============================================================== ============> POINTS OF SAIL TABLE -- STARTS HERE <============ =============================================================== | | ROM Bytes: $1300-133f [64] +-------------------------------------------------------------- # Point of Sail - ----------------------------- 0 In Irons (i.e. into the wind) 1 Close Hauled 2 Beam Reach 3 Broad Reach 4 Running Downwind - ----------------------------- \ \ Wind Direction \ ----------------------- \ W NW N NE E SE S SW \ 0 1 2 3 4 5 6 7 \ -- -- -- -- -- -- -- -- | W 0| 0 1 2 3 4 3 2 1 |0 W | NW 1| 1 0 1 2 3 4 3 2 |1 NW | N 2| 2 1 0 1 2 3 4 3 |2 N Boat | NE 3| 3 2 1 0 1 2 3 4 |3 NE Heading | E 4| 4 3 2 1 0 1 2 3 |4 E | SE 5| 3 4 3 2 1 0 1 2 |5 SE | S 6| 2 3 4 3 2 1 0 1 |6 S | SW 7| 1 2 3 4 3 2 1 0 |7 SW -- -- -- -- -- -- -- -- 0 1 2 3 4 5 6 7 W NW N NE E SE S SW TAB_POINT_OF_SAIL: 0001020304030201 0100010203040302 0201000102030403 0302010001020304 0403020100010203 0304030201000102 0203040302010001 0102030403020100 =============================================================== ============> POINTS OF SAIL TABLE -- ENDS HERE <============= =============================================================== ==============> PLAYFIELD TABLES -- START HERE <=============== =============================================================== | | ROM Bytes: $1340-13cf [144] +-------------------------------------------------------------- --------------------------------------------------------------- PF0_f0 Values (i.e. quads 3-0) by Playfield Row. ROM Bytes: $1340-136f [48] --------------------------------------------------------------- TAB_PF0: [N.B. low 4 bits of each byte UNUSED] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 <-- PF Row f0f0f0f000000000000000008080808080808080808080c0 <-- PF0 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 <-- PF Row 808000000010101010303030303030303070f0f0f0f0f0f0 <-- PF0 --------------------------------------------------------------- PF1_ff Values (i.e. quads 4-11) by Playfield Row. ROM Bytes: $1370-139f [48] --------------------------------------------------------------- TAB_PF1: 1 1 1 1 1 1 1 1 1 1 2 2 2 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 <-- PF Row ffffe0e00000000000000800000000008080000080000000 <-- PF1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 <-- PF Row 00000402010000000000000001000000000080c0c0c0e0ff <-- PF1 --------------------------------------------------------------- PF2_ff Values (i.e. quads 19-12) by Playfield Row. ROM Bytes: $13a0-13cf [48] --------------------------------------------------------------- TAB_PF2: 1 1 1 1 1 1 1 1 1 1 2 2 2 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 <-- PF Row c08080000000001800006000000000000060f01010109090 <-- PF2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 <-- PF Row 90101010f060000000000000002018080400000000000080 <-- PF2 =============================================================== ===============> PLAYFIELD TABLES -- END HERE <================ =============================================================== ===========> EDGE REDIRECTION TABLES -- START HERE <=========== =============================================================== | | ROM Bytes: $13d0-13ef [32] +-------------------------------------------------------------- --------------------------------------------------------------- New Heading after attempting to exit via the Western edge. ROM Bytes: $13d0-$13d7 [8] --------------------------------------------------------------- TODO EXPLAIN TAB_REDIRECT_WEST: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Old Heading 0504030304050504 <-- New Heading --------------------------------------------------------------- New Heading after attempting to exit via the Northern edge. ROM Bytes: $13d8-$13df [8] --------------------------------------------------------------- TAB_REDIRECT_NORTH: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Old Heading 0707070605050707 <-- New Heading --------------------------------------------------------------- New Heading after attempting to exit via the Eastern edge. ROM Bytes: $13e0-$13e7 [8] --------------------------------------------------------------- TAB_REDIRECT_EAST: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Old Heading 0001010001000707 <-- New Heading --------------------------------------------------------------- New Heading after attempting to exit via the Southern edge. ROM Bytes: $13e8-$13ef [8] --------------------------------------------------------------- TAB_REDIRECT_SOUTH: NW NE SE SW W | N | E | S | 0 1 2 3 4 5 6 7 <-- Old Heading 0101030303030302 <-- New Heading =============================================================== ============> EDGE REDIRECTION TABLES -- END HERE <============ =============================================================== =================> BUOY TABLES -- START HERE <================= =============================================================== | | ROM Bytes: $13f0-13f7 [8] +-------------------------------------------------------------- TODO Untested and coordinates not finalized N.B. The current code that uses these tables assumes that race mark buoys #0 and #1 are always located in the lower half of the pixel area, and that race mark buoys #2 and #3 are always located in the upper half of the pixel area. Buoy # 0 1 2 3 LR LL UL UR --------------------------------------------------------------- Race Mark Buoy X Coordinates. ROM Bytes: $13f0-$13f3 [4] --------------------------------------------------------------- TAB_BUOY_X: 0 1 2 3 <-- Buoy # 7c203074 <-- X Coordinate --------------------------------------------------------------- Race Mark Buoy Y Coordinates. ROM Bytes: $13f4-$13f7 [4] --------------------------------------------------------------- TAB_BUOY_Y: 0 1 2 3 <-- Buoy # 2020a0a0 <-- Y Coordinate =============================================================== ==================> BUOY TABLES -- END HERE <================== =============================================================== ===================> RESET -- STARTS HERE <==================== =============================================================== | | Color Clocks: (3+)x3, 441 | ROM Bytes: $13f8-1460 [105] +-------------------------------------------------------------- The reset state of the 6507: NV-BDIZC A X Y SP ??1??1?? ?? ?? ?? ?? --------------------------------------------------------------- Synchronize with the TIA Color Clock. Color Clocks: (3+)x3 ROM Bytes: 2 --------------------------------------------------------------- 8502 sta WSYNC_STB (3+)x3 @ reset.-1.???-227 --------------------------------------------------------------- Initialize the MOS 6507 CPU. Color Clocks: 30 ROM Bytes: 7 --------------------------------------------------------------- d8 cld (2)x3 @ reset.0.000-005 18 clc (2)x3 @ reset.0.006-011 We use the CPU's Y register as our Zero register, except within the Display Kernel where it acts as our Active Scanline countdown counter. a000 ldy #0 (2)x3 @ reset.0.012-017 When the stack is empty we use SP as our -1 ($ff) mask register (cf. TSX instruction). a2ff ldx #$ff (2)x3 @ reset.0.018-023 9a txs (2)x3 @ reset.0.024-029 NV-BDIZC A X Y SP 1?1?0100 02 ff 00 ff --------------------------------------------------------------- Initialize Atari TIA Chip. Color Clocks: 168 ROM Bytes: 38 --------------------------------------------------------------- Turn the sound off early to preempt any incidental noises. Audio Channel 0 (left) Volume: sound off Audio Channel 1 (right) Volume: sound off 8419 sty AUDV0_0f (3)x3 @ reset.0.030-038 841a sty AUDV1_0f (3)x3 @ reset.0.039-047 Skipping. ---------------- $0000 VSYNC_02 $0001 VBLANK_c2 $0002 WSYNC_STB $0003 RSYNC_STB P0 count: 1, scale: 1, spacing: n/a; M0 width: 1cc P1 count: 1, scale: 1, spacing: n/a; M1 width: 1cc 8404 sty NUSIZ0_3f (3)x3 @ reset.0.048-056 8405 sty NUSIZ1_3f (3)x3 @ reset.0.057-065 Skipping. ---------------- $0006 COLUP0_fe $0007 COLUP1_fe $0008 COLUPF_fe $0009 COLUBK_fe BL width: 1cc; Priorities: normal; Score mode: off; PF reflection: on a901 lda #$01 (2)x3 @ reset.0.066-071 850a sta CTRLPF_37 (3)x3 @ reset.0.072-080 P0 reflection: off P1 reflection: off 840b sty REFP0_08 (3)x3 @ reset.0.081-089 840c sty REFP1_08 (3)x3 @ reset.0.090-098 Skipping. ---------------- $000d PF0_f0 $000e PF1_ff $000f PF2_ff $0010 RESP0_STB $0011 RESP1_STB $0012 RESM0_STB $0013 RESM1_STB $0014 RESBL_STB Audio Channel 0 (left) Noise-Tone: none, Division: 1 Audio Channel 1 (right) Noise-Tone: none, Division: 1 8415 sty AUDC0_0f (3)x3 @ reset.0.099-107 8416 sty AUDC1_0f (3)x3 @ reset.0.108-116 Audio Channel 0 (left) Frequency: 0 <=> divide by 1 <=> 30KHz Audio Channel 1 (right) Frequency: 0 <=> divide by 1 <=> 30KHz 8417 sty AUDF0_1f (3)x3 @ reset.0.117-125 8418 sty AUDF1_1f (3)x3 @ reset.0.126-134 Skipping. --------------- $0019 AUDV0_0f (already done at start of this section) $001a AUDV0_1f (already done at start of this section) $001b GRP0_ff $001c GRP1_ff $001d ENAM0_02 $001e ENAM1_02 $001f ENABL_02 $0020 HMP0_f0 $0021 HMP1_f0 $0022 HMM0_f0 $0023 HMM1_f0 Horizontal Motion BL: 0 8424 sty HMBL_f0 (3)x3 @ reset.0.135-143 P0 vertical delay: none P1 vertical delay: none BL vertical delay: none 8425 sty VDELP0_01 (3)x3 @ reset.0.144-152 8426 sty VDELP1_01 (3)x3 @ reset.0.153-161 8427 sty VDELBL_01 (3)x3 @ reset.0.162-170 M0 moves: independently from P0 M1 moves: independently from P1 8428 sty RESMP0_02 (3)x3 @ reset.0.171-179 8429 sty RESMP1_02 (3)x3 @ reset.0.180-188 Skipping. ---------------- $002a HMOVE_STB $002b HMCLR_STB 852c sta CXCLR_STB (3)x3 @ reset.0.189-197 TIA undefined. -------------- $002d .. 003f --------------------------------------------------------------- Initialize PIA (MOS 6532 RIOT) Chip. Color Clocks: 243 ROM Bytes: 58 --------------------------------------------------------------- Game State RAM -------------- Headings range 0-7, Clockwise West to South-West. Boats start out heading West. 8480 sty SRAM_P0_HEADING (3)x3 @ reset.0.198-206 8481 sty SRAM_P1_HEADING (3)x3 @ reset.0.207-215 X coordinate of Px sprite. Px_X ranges from 0 to 159. Subpixel holds binary scaling of leftover fractional X value. TODO These initial values are for testing purposes, and will be revised for the actual game. 8482 sty SRAM_P0_X_SUBPX (3)x3 @ reset.0.216-224 a996 lda #$96 (2)x3 @ reset.0.225-1.002 8583 sta SRAM_P0_X (3)x3 @ reset.1.003-011 8484 sty SRAM_P1_X_SUBPX (3)x3 @ reset.1.012-020 a996 lda #$96 (2)x3 @ reset.1.021-026 8585 sta SRAM_P1_X (3)x3 @ reset.1.027-035 Y coordinate of Px sprite. Px_Y ranges from 0 to 191. Subpixel holds binary scaling of leftover fractional Y value. TODO These initial values are for testing purposes, and will be revised for the actual game. 8486 sty SRAM_P0_Y_SUBPX (3)x3 @ reset.1.036-044 a922 lda #$22 (2)x3 @ reset.1.045-050 8587 sta SRAM_P0_Y (3)x3 @ reset.1.051-059 8488 sty SRAM_P1_Y_SUBPX (3)x3 @ reset.1.060-068 a917 lda #$17 (2)x3 @ reset.1.069-074 8589 sta SRAM_P1_Y (3)x3 @ reset.1.075-083 Clear Switch debounce memories. TODO We aren't yet making use of SRAM_SWCHB_SV. 848a sty SRAM_SWCHA_SV (3)x3 @ reset.1.084-092 848b sty SRAM_SWCHB_SV (3)x3 @ reset.1.093-101 TODO According to Wikipedia: "Wind direction is generally reported by the direction from which it originates. For example, a north or northerly wind blows from the north to the south." The game starts with a Westerly wind, i.e. blowing from the West to the East. TODO This wind direction value is for testing purposes, it may need to change for the actual game. 848c sty SRAM_WIND_DIRECTION (3)x3 @ reset.1.102-110 848d sty SRAM_P0_SPEED (3)x3 @ reset.1.111-119 848e sty SRAM_P1_SPEED (3)x3 @ reset.1.120-128 Seed the PRNG. TODO PRNG is untested code. Whenever we need a random byte ($00..ff), we use SRAM_RND. If we need a 16-BIT ***non-zero*** word (i.e. $0001..ffff), we can use SRAM_RND:SRAM_RND_LO together (SRAM_RND_LO is never 0). Either way we need to crank the PRNG to advance to the next value in the current pseudo-random sequence. In order to inject some additional unpredictability, we'll use the timing of user input to occasionaly reseed the PRNG. Ensure SRAM_RND_LO is not 0 (by setting it to $ff). ba tsx (2)x3 @ reset.1.129-134 868f stx SRAM_RND_LO (3)x3 @ reset.1.135-143 Use whatever garbage happens to be in the interval timer to initialize the high byte of SRAM_RND:SRAM_RND_LO. ad8402 lda INTIM_ff (4)x3 @ reset.1.144-155 8590 sta SRAM_RND (3)x3 @ reset.1.156-164 TODO EXPLAIN 8491 sty SRAM_P0_BUOYS_CNT (3)x3 @ reset.1.165-173 8492 sty SRAM_P1_BUOYS_CNT (3)x3 @ reset.1.174-182 Unused at the moment. $0093-$00a6 Cache RAM --------- These are cached intermediate values mostly for the benefit of the Display Kernel. The P0 Frame Cache. --------------------------------- $00a7 CRAM_P0_HEIGHT $00a8 CRAM_P0_WIDTH $00a9-$00b2 CRAM_GRP0_ROWS (0-9) The P1 Frame Cache. --------------------------------- $00b3 CRAM_P1_HEIGHT $00b4 CRAM_P1_WIDTH $00b5-$00be CRAM_GRP1_ROWS (0-9) TODOEXPLAIN $00bf CRAM_P0_HEADING_DELTA $00c0 CRAM_P1_HEADING_DELTA TODO Do points of sail actually need caching? Perhaps remove these from the actual game. $00c1 CRAM_P0_POINT_OF_SAIL $00c2 CRAM_P1_POINT_OF_SAIL TODOEXPLAIN $00c3 CRAM_VANE_BL_Y Unused at the moment. $00c4-$00cf Overlay RAM ----------- Overlay RAM is RAM that we intend to overwrite and reuse multiple times per frame. Overlay RAM can be volatile in the sense that it can hold temporary data local to the section of the frame currently executing. Skipping. -------------------------- $00d0 ORAM_DELAY_LINE_OFS Indirect Delay Line Page Index (hardcoded to $10, i.e. page index of this page of ROM, that started at address $1000). See DELAY LINE for details. a910 lda #$10 (2)x3 @ reset.1.183-188 Wasting an extra 3mc to reach exactly reset.1.212 at the end of this section. TODO temporary 8dd100 sta.w ORAM_DELAY_LINE_NDX (3)x3 @ reset.1.189-200 STD 85d1 sta ORAM_DELAY_LINE_NDX (3)x3 @ reset.1.189-197 Skipping. ------------------- $00d2 ORAM_GRP0 $00d3 ORAM_PF0 $00d4 ORAM_PF1 $00d5 ORAM_PF2 $00d6 ORAM_PF_ROW $00d7 ORAM_ENABL $00d8 ORAM_Px_X_SV $00d9 ORAM_Px_Y_SV $00da ORAM_ENAMx Unused at the moment. --------------------- $00dc-00f9 Reserving these for the stack. ------------------------------ $00fa-00ff Skipping. --------------- $0280 SWCHA_ff Set all Port A pins to input. 8c8102 sty SWACNT_ff (4)x3 @ reset.1.201-212 Skipping. ---------------- $0282 SWCHB_ff (read only) $0283 SWBCNT_ff (hardwired as input) $0284 unamed $0285 unamed $0286 unamed $0287 unamed $0294 TIM1T_ff $0295 TIM8T_ff $0296 TIM64T_ff $0297 T1024T_ff NV-BDIZC A X Y SP ??1????? ?? ff 00 ff TODO --------------------------------------------------------------- Bridge to Mainline. Initialization merges into mainline processing at the point where each frame's Vertical Blanking Interval is triggered, i.e. at color clock 213. These NOP instructions bridge the gap. Color Clocks: 0 ROM Bytes: 0 --------------------------------------------------------------- TODO not needed at the moment (but see @ reset.1.189-200). =============================================================== ====================> RESET -- ENDS HERE <===================== =============================================================== ============> MAINLINE PROCESSING -- STARTS HERE <============= =============================================================== =============> DISPLAY KERNEL -- CONTINUES HERE <============== =============================================================== --------------------------------------------------------------- FRAME OVERHEAD 1/5 - Trigger the Vertical Blanking Interval. Color Clocks: 15 ROM Bytes: $1461-1464 [4] --------------------------------------------------------------- N.B. The VBLANK TIA register includes the bits for input port configuration. For this game, we've chosen to use the optional latches on the joystick button input ports. TODO VBI_TRIGGER: 76543210 function -------- ----------------------------------------- xx....x. Vertical Blank & Latched Ports. 0....... Remove INPT0,1,2,3 (Paddle Ports) dump path to ground. TODO.0...... Disable latches for Ports INPT4,5 (Joystick Buttons Left,Right) and reset them to logic 1. N.B. A button press is a logic 0. When disabled the 6507 reads the logic level of the ports directly. .1...... Enable latches for Ports INPT4,5 (Joystick Buttons Left,Right). Both latches are set to logic 1, and remain there until the corresponding port goes to logic 0. N.B. A button press is a logic 0. When the corresponsding port goes to logic 0 the latch goes to logic 0 and remains there regardless of what the port does. ......1. Vertical Blank On. |||||||| a942 lda #%01000010 (2)x3 @ dk.191.213-218 8501 sta VBLANK_c2 (3)x3 @ dk.191.219-227 =============================================================== ================> DISPLAY KERNEL -- ENDS HERE <================ =============================================================== =========> VERTICAL BLANKING INTERVAL -- STARTS HERE <========= =============================================================== ============> VERTICAL FRONT PORCH -- STARTS HERE <============ =============================================================== | | Lasts 30 scanlines = 2,280 CPU cycles = 6,840 color clocks | | ROM Bytes: $1465-177c [792] +-------------------------------------------------------------- --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 2,280 ROM Bytes: 20 --------------------------------------------------------------- 8502 sta WSYNC_STB (3+)x3 @ vfp.00.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.01.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.02.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.03.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.04.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.05.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.06.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.07.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.08.000~227 8502 sta WSYNC_STB (3+)x3 @ vfp.09.000~227 --------------------------------------------------------------- GAME LOGIC 1/5 - Process Inputs. --------------------------------------------------------------- --------------------------------------------------------------- GAME LOGIC 1.1 Process Port B Inputs (Console Switches). Color Clocks: 228 ROM Bytes: 52 --------------------------------------------------------------- x....... P1 Difficulty: 0....... amateur (B) 1....... pro (A) .x...... P0 Difficulty: .0...... amateur (B) .1...... pro (A) ..xx.... ***UNUSED*** ....x... Color - B/W: ....0... B/W ....1... color .....x.. ***UNUSED*** ......x. Game Select: ......0. pressed ......1. not pressed .......x Game Reset: .......0 pressed .......1 not pressed ad8202 lda SWCHB_ff (4)x3 @ vfp.10.000-011 Process Game Reset Console Switch. 4a lsr (2)x3 @ vfp.10.012-017 b003 bcs +3 SKIP_RESET (3!)x3 @ vfp.10.018-026 (2)x3 (~023) 6cfc1f jmp (RESET_VECTOR) (5)x3 @ (vfp.10.024~038) SKIP_RESET: Process Game Select Console Switch. 4a lsr (2)x3 @ vfp.10.027-032 b000 bcs +0 SKIP_GAME_SELECT (3!)x3 @ vfp.10.033~041 (2)x3 ~038 TODO game select processing SKIP_GAME_SELECT: Process Color - B/W Console Switch. Color B/W --------- ----------- P0/M0 greenish white P1/M1 reddish dark grey PF/BL yellowish light grey BK blueish darker grey 4a lsr (2)x3 @ vfp.10.039~044 4a lsr (2)x3 @ vfp.10.045~050 b012 bcs +18 SKIP_B/W (3!)x3 @ vfp.10.051~059 (2)x3 ~056 a20e ldx #$0e (2)x3 @ vfp.10.057~062 8606 stx COLUP0_fe (3)x3 @ vfp.10.063~071 a206 ldx #$06 (2)x3 @ vfp.10.072~077 8607 stx COLUP1_fe (3)x3 @ vfp.10.078~086 a20a ldx #$0a (2)x3 @ vfp.10.087~092 8608 stx COLUPF_fe (3)x3 @ vfp.10.093~101 a203 ldx #$03 (2)x3 @ vfp.10.102~107 8609 stx COLUBK_fe (3)x3 @ vfp.10.108~116 Branch always. d010 bne +16 B/W_COLOR_DONE (3!)x3 @ vfp.10.117~125 SKIP_B/W: TODO When you can't avoid it use luminescence that is close for both colors, and it will minimize the flicker. TODO Flickering might be good if done with a softer color, with 0 luminance. a2c6 ldx #$c6 (2)x3 @ vfp.10.060~065 8606 stx COLUP0_fe (3)x3 @ vfp.10.066~074 a230 ldx #$30 (2)x3 @ vfp.10.075~080 8607 stx COLUP1_fe (3)x3 @ vfp.10.081~089 a21a ldx #$1a (2)x3 @ vfp.10.090~095 8608 stx COLUPF_fe (3)x3 @ vfp.10.096~104 a284 ldx #$84 (2)x3 @ vfp.10.105~110 8609 stx COLUBK_fe (3)x3 @ vfp.10.111~119 B/W_COLOR_DONE: TODO Process P1 Difficulty Switch. Process P0 Difficulty Switch. 8502 sta WSYNC_STB (3+)x3 @ vfp.10.126~227 --------------------------------------------------------------- GAME LOGIC 1.2 Process Collisions. Color Clocks: 912 ROM Bytes: 77 --------------------------------------------------------------- TODO TORE OUT THE GUTS, REDO COMPLETELY Generate a random number for use by collision handling code. PRNG macro (master). Cf. "Seed the PRNG" for usage notes. 16-bit '798' xorshift. seed^=seed<<7; seed^=seed>>9; seed^=seed<<8; 19 bytes ROM, 90 cc. a590 lda SRAM_RND (3)x3 @ vfp.11.000-008 4a lsr (2)x3 @ vfp.11.009-014 a58f lda SRAM_RND_LO (3)x3 @ vfp.11.015-023 6a ror (2)x3 @ vfp.11.024-029 4590 eor SRAM_RND (3)x3 @ vfp.11.030-038 8590 sta SRAM_RND (3)x3 @ vfp.11.039-047 6a ror (2)x3 @ vfp.11.048-053 458f eor SRAM_RND_LO (3)x3 @ vfp.11.054-062 858f sta SRAM_RND_LO (3)x3 @ vfp.11.063-071 4590 eor SRAM_RND (3)x3 @ vfp.11.072-080 8590 sta SRAM_RND (3)x3 @ vfp.11.081-089 Check P0 for collisions. a502 lda CXP0FB_c0 (3)x3 @ vfp.11.090-098 0507 ora CXPPMM_c0 (3)x3 @ vfp.11.099-107 8502 sta WSYNC_STB (3+)x3 @ vfp.11.108-227 1012 bpl +18 CHECK_CXP1FB (3!)x3 @ vfp.12.000~008 (2)x3 ~005 P0 has collided with the PF and/or P1. Reset P0. 848d sty SRAM_P0_SPEED (3)x3 @ vfp.12.006~014 8480 sty SRAM_P0_HEADING (3)x3 @ vfp.12.015~023 8482 sty SRAM_P0_X_SUBPX (3)x3 @ vfp.12.024~032 a996 lda #$96 (2)x3 @ vfp.12.033~038 8583 sta SRAM_P0_X (3)x3 @ vfp.12.039~047 8486 sty SRAM_P0_Y_SUBPX (3)x3 @ vfp.12.048~056 a922 lda #$22 (2)x3 @ vfp.12.057~062 8587 sta SRAM_P0_Y (3)x3 @ vfp.12.063~071 8491 sty SRAM_P0_BUOYS_CNT (3)x3 @ vfp.12.072~080 CHECK_CXP1FB: Check P1 for collisions. 8502 sta WSYNC_STB (3+)x3 @ vfp.12.081~227 a503 lda CXP1FB_c0 (3)x3 @ vfp.13.000-008 0507 ora CXPPMM_c0 (3)x3 @ vfp.13.009-017 1012 bpl +18 CX_PREP (3!)x3 @ vfp.13.018~026 (2)x3 ~023 P1 has collided with the PF and/or P0. Reset P1. 848e sty SRAM_P1_SPEED (3)x3 @ vfp.13.024~032 8481 sty SRAM_P1_HEADING (3)x3 @ vfp.13.033~041 8484 sty SRAM_P1_X_SUBPX (3)x3 @ vfp.13.042~050 a996 lda #$96 (2)x3 @ vfp.13.051~056 8585 sta SRAM_P1_X (3)x3 @ vfp.13.057~065 8488 sty SRAM_P1_Y_SUBPX (3)x3 @ vfp.13.066~074 a917 lda #$17 (2)x3 @ vfp.13.075~080 8589 sta SRAM_P1_Y (3)x3 @ vfp.13.081~089 8492 sty SRAM_P1_BUOYS_CNT (3)x3 @ vfp.12.090~098 CX_PREP: 8502 sta WSYNC_STB (3+)x3 @ vfp.13.099~227 Clear TIA Collision Registers. 852c sta CXCLR_STB (3)x3 @ vfp.14.000-008 8502 sta WSYNC_STB (3+)x3 @ vfp.14.116-227 --------------------------------------------------------------- GAME LOGIC 1.3 Process Port A Inputs (Joysticks). Color Clocks: 684 ROM Bytes: 65 --------------------------------------------------------------- TODO refactor this section completely Clear Px heading deltas. TODOEXPLAIN 84bf sty CRAM_P0_HEADING_DELTA (3)x3 @ vfp.15.000-008 84c0 sty CRAM_P1_HEADING_DELTA (3)x3 @ vfp.15.009-017 Check P0 joystick left/right bits for change. af8002 lax SWCHA_ff (4)x3 @ vfp.15.018-029 458a eor SRAM_SWCHA_SV (3)x3 @ vfp.15.030-038 29c0 and #$c0 (2)x3 @ vfp.15.039-044 f017 beq +23 P1_CHECK_STICK (3!)x3 @ vfp.15.045~053 (2)x3 ~050 One or both P0 joystick left/right bits are different from the last time we checked port A. Reseed PRNG. We (arbitrarily) use P0's action as the opportunity to reseed the PRNG (N.B. high byte only) so as to inject some additional unpredictability. N.B. This is just a simple reseeder, not the PRNG itself. SRAM_RND*=5; SRAM_RND+=3 a590 lda SRAM_RND (3)x3 @ vfp.15.051~059 0a asl (2)x3 @ vfp.15.060~065 0a asl (2)x3 @ vfp.15.066~071 18 clc (2)x3 @ vfp.15.072~077 6590 adc SRAM_RND (3)x3 @ vfp.15.078~086 18 clc (2)x3 @ vfp.15.087~092 6903 adc #$03 (2)x3 @ vfp.15.093~098 8590 sta SRAM_RND (3)x3 @ vfp.15.099~107 2c8002 bit SWCHA_ff (4)x3 @ vfp.15.108~119 3002 bmi +2 P0_CHECK_LEFT (3!)x3 @ vfp.15.120~128 (2)x3 ~125 P0 joystick moved right. e6bf inc CRAM_P0_HEADING_DELTA (5)x3 @ vfp.15.126~140 P0_CHECK_LEFT: 7002 bvs +2 P1_CHECK_STICK (3!)x3 @ vfp.15.141~149 (2)x3 ~146 P0 joystick moved left. c6bf dec CRAM_P0_HEADING_DELTA (5)x3 @ vfp.15.147~161 P1_CHECK_STICK: Check P1 joystick left/right bits for change. 8502 sta WSYNC_STB (3+)x3 @ vfp.15.162~227 8a txa (2)x3 @ vfp.16.000-005 458a eor SRAM_SWCHA_SV (3)x3 @ vfp.16.006-014 290c and #$0c (2)x3 @ vfp.16.015-020 f00e beq +14 SWCHA_SAVE (3!)x3 @ vfp.16.021~029 (2)x3 ~026 One or both P1 joystick left/right bits are different from the last time we checked port A. 8a txa (2)x3 @ vfp.16.027~032 2908 and #$08 (2)x3 @ vfp.16.033~038 d002 bne +2 P1_CHECK_LEFT (3!)x3 @ vfp.16.039~047 (2)x3 ~044 P1 joystick moved right. e6c0 inc CRAM_P1_HEADING_DELTA (5)x3 @ vfp.16.045~059 P1_CHECK_LEFT: 8a txa (2)x3 @ vfp.16.060~065 2904 and #$04 (2)x3 @ vfp.16.066~071 d002 bne +2 SWCHA_SAVE (3!)x3 @ vfp.16.072~080 (2)x3 ~077 P1 joystick moved left. c6c0 dec CRAM_P1_HEADING_DELTA (5)x3 @ vfp.16.078~092 SWCHA_SAVE: 8502 sta WSYNC_STB (3+)x3 @ vfp.16.093~227 868a stx SRAM_SWCHA_SV (3)x3 @ vfp.17.000-008 TODO 000c TIA INPT4_80 Input Port 4 (Left Joystick Button) 000d TIA INPT5_80 Input Port 5 (Right Joystick Button) 8502 sta WSYNC_STB (3+)x3 @ vfp.17.009~227 --------------------------------------------------------------- GAME LOGIC 2/5 - Detect and Process Miscellaneous Changes. --------------------------------------------------------------- --------------------------------------------------------------- GAME LOGIC 2.1 Timeout to "Attract" Mode. Color Clocks: TODO ROM Bytes: TODO --------------------------------------------------------------- TODO --------------------------------------------------------------- GAME LOGIC 3/5 - Update Game State. --------------------------------------------------------------- --------------------------------------------------------------- GAME LOGIC 3.1 Update Wind Direction. Color Clocks: 126 ROM Bytes: 29 --------------------------------------------------------------- PRNG macro (expansion). a590 lda SRAM_RND (3)x3 @ vfp.18.000-008 4a lsr (2)x3 @ vfp.18.009-014 a58f lda SRAM_RND_LO (3)x3 @ vfp.18.015-023 6a ror (2)x3 @ vfp.18.024-029 4590 eor SRAM_RND (3)x3 @ vfp.18.030-038 8590 sta SRAM_RND (3)x3 @ vfp.18.039-047 6a ror (2)x3 @ vfp.18.048-053 458f eor SRAM_RND_LO (3)x3 @ vfp.18.054-062 858f sta SRAM_RND_LO (3)x3 @ vfp.18.063-071 4590 eor SRAM_RND (3)x3 @ vfp.18.072-080 8590 sta SRAM_RND (3)x3 @ vfp.18.081-089 1/256 chance of a clockwise wind change per frame. c9ff cmp #$ff (2)x3 @ vfp.18.090-095 a58c lda SRAM_WIND_DIRECTION (3)x3 @ vfp.18.096-104 6900 adc #$00 (2)x3 @ vfp.18.105-110 2907 and #$07 (2)x3 @ vfp.18.111-116 858c sta SRAM_WIND_DIRECTION (3)x3 @ vfp.18.117-125 --------------------------------------------------------------- GAME LOGIC 3.2 Update P0 Heading. Color Clocks: 183 ROM Bytes: 41 --------------------------------------------------------------- Pivot P0 to new heading (using the bow pixel as the pivot point), has no effect if CRAM_P0_HEADING_DELTA is 0. heading' = (heading + heading_delta) & $07 x'= x +bow_x_delta[heading] -bow_x_delta[heading'] y'= y +bow_y_delta[heading] -bow_y_delta[heading'] N.B. After a pivot the sprite might end up slightly overshooting the edges of the playing surface. We must keep this in mind when dealing with its coordinates from this point on, and we must make sure it no longer overshoots the playing surface by the time we reach the display kernel (cf. "P0 Edge Detection and Handling"). a680 ldx SRAM_P0_HEADING (3)x3 @ vfp.18.126-134 bdf611 lda TAB_GRPx_BOW_X_OFS,X (4!)x3 @ vfp.18.135-146 18 clc (2)x3 @ vfp.18.147-152 6583 adc SRAM_P0_X (3)x3 @ vfp.18.153-161 8583 sta SRAM_P0_X (3)x3 @ vfp.18.162-170 bdfe11 lda TAB_GRPx_BOW_Y_OFS,X (4!)x3 @ vfp.18.171-182 6587 adc SRAM_P0_Y (3)x3 @ vfp.18.183-191 8587 sta SRAM_P0_Y (3)x3 @ vfp.18.192-200 8a txa (2)x3 @ vfp.18.201-206 65bf adc CRAM_P0_HEADING_DELTA (3)x3 @ vfp.18.207-215 2907 and #$07 (2)x3 @ vfp.18.216-221 8580 sta SRAM_P0_HEADING (3)x3 @ vfp.18.222-19.002 aa tax (2)x3 @ vfp.19.003-008 a583 lda SRAM_P0_X (3)x3 @ vfp.19.009-017 38 sec (2)x3 @ vfp.19.018-023 fdf611 sbc TAB_GRPx_BOW_X_OFS,X (4!)x3 @ vfp.19.024-035 8583 sta SRAM_P0_X (3)x3 @ vfp.19.036-044 a587 lda SRAM_P0_Y (3)x3 @ vfp.19.045-053 38 sec (2)x3 @ vfp.19.054-059 fdfe11 sbc TAB_GRPx_BOW_Y_OFS,X (4!)x3 @ vfp.19.060-071 8587 sta SRAM_P0_Y (3)x3 @ vfp.19.072-080 --------------------------------------------------------------- GAME LOGIC 3.3 Determine P0 Point of Sail. Color Clocks: 63 ROM Bytes: 13 --------------------------------------------------------------- a580 lda SRAM_P0_HEADING (3)x3 @ vfp.19.081-089 x8 0a asl (2)x3 @ vfp.19.090-095 0a asl (2)x3 @ vfp.19.096-101 0a asl (2)x3 @ vfp.19.102-107 C=0 invariant 658c adc SRAM_WIND_DIRECTION (3)x3 @ vfp.19.108-116 aa tax (2)x3 @ vfp.19.117-122 bd0013 lda TAB_POINT_OF_SAIL,X (4!)x3 @ vfp.19.123-134 85c1 sta CRAM_P0_POINT_OF_SAIL (3)x3 @ vfp.19.135-143 --------------------------------------------------------------- GAME LOGIC 3.4 Update P0 Speed. Color Clocks: 66 ROM Bytes: 14 --------------------------------------------------------------- a58d lda SRAM_P0_SPEED (3)x3 @ vfp.19.144-152 x5 0a asl (2)x3 @ vfp.19.153-158 0a asl (2)x3 @ vfp.19.159-164 C=0 invariant 658d adc SRAM_P0_SPEED (3)x3 @ vfp.19.165-173 C=0 invariant 65c1 adc CRAM_P0_POINT_OF_SAIL (3)x3 @ vfp.19.174-182 aa tax (2)x3 @ vfp.19.183-188 bdd612 lda TAB_SPEED_CHANGE,X (4!)x3 @ vfp.19.189-200 858d sta SRAM_P0_SPEED (3)x3 @ vfp.19.201-209 --------------------------------------------------------------- GAME LOGIC 3.5 Update P0 Location. Color Clocks: 207 ROM Bytes: 46 --------------------------------------------------------------- Save last frame's P0 location. a583 lda SRAM_P0_X (3)x3 @ vfp.19.210-218 85d8 sta ORAM_Px_X_SV (3)x3 @ vfp.19.219-227 a587 lda SRAM_P0_Y (3)x3 @ vfp.20.000-008 85d9 sta ORAM_Px_Y_SV (3)x3 @ vfp.20.009-017 a580 lda SRAM_P0_HEADING (3)x3 @ vfp.20.018-026 x6 0a asl (2)x3 @ vfp.20.027-032 C=0 invariant 6580 adc SRAM_P0_HEADING (3)x3 @ vfp.20.033-041 0a asl (2)x3 @ vfp.20.042-047 C=0 invariant 658d adc SRAM_P0_SPEED (3)x3 @ vfp.20.048-056 aa tax (2)x3 @ vfp.20.057-062 bd3612 lda TAB_X_SUBPX_DELTA,X (4!)x3 @ vfp.20.063-074 C=0 invariant 6582 adc SRAM_P0_X_SUBPX (3)x3 @ vfp.20.075-083 8582 sta SRAM_P0_X_SUBPX (3)x3 @ vfp.20.084-092 bd0612 lda TAB_X_DELTA,X (4!)x3 @ vfp.20.093-104 6583 adc SRAM_P0_X (3)x3 @ vfp.20.105-113 8583 sta SRAM_P0_X (3)x3 @ vfp.20.114-122 bd9612 lda TAB_Y_SUBPX_DELTA,X (4!)x3 @ vfp.20.123-134 18 clc (2)x3 @ vfp.20.135-140 6586 adc SRAM_P0_Y_SUBPX (3)x3 @ vfp.20.141-149 8586 sta SRAM_P0_Y_SUBPX (3)x3 @ vfp.20.150-158 bd6612 lda TAB_Y_DELTA,X (4!)x3 @ vfp.20.159-170 6587 adc SRAM_P0_Y (3)x3 @ vfp.20.171-179 8587 sta SRAM_P0_Y (3)x3 @ vfp.20.180-188 --------------------------------------------------------------- GAME LOGIC 3.6 P0 Race Mark Buoy Rounding. Color Clocks: 148 ROM Bytes: 54 --------------------------------------------------------------- a791 lax SRAM_P0_BUOYS_CNT (3)x3 @ vfp.20.189-197 2902 and #$02 (2)x3 @ vfp.20.198-206 8502 sta WSYNC_STB (3+)x3 @ vfp.20.207~227 d018 bne +24 BUOY_UPPER_HALF (3!)x3 @ vfp.21.000-008 (2)x3 ~005 The race mark buoy P0 needs to "round" next is on the lower half of the pixel area. The race mark buoy's X coordinate needs to be East of P0's upcoming X coordinate, i.e. TAB_BUOY_X,X u> SRAM_P0_X. bdf013 lda TAB_BUOY_X,X (4!)x3 @ vfp.21.006~017 c583 cmp SRAM_P0_X (3)x3 @ vfp.21.018~026 C = (TAB_BUOY_X,X u>= SRAM_P0_X) 9027 bcc +39 DONE_BUOY (3!)x3 @ vfp.21.027~035 (2)x3 ~032 f025 beq +37 DONE_BUOY (3!)x3 @ vfp.21.033~041 (2)x3 ~038 The race mark buoy's X coordinate needs to be either West of or on P0's previous frame X coordinate, i.e. TAB_BUOY_X,X u<= ORAM_Px_X_SV. c5d8 cmp ORAM_Px_X_SV (3)x3 @ vfp.21.039~047 C = (TAB_BUOY_X,X u>= ORAM_Px_X_SV) f021 beq +33 DONE_BUOY (3!)x3 @ vfp.21.048~056 (2)x3 ~053 b01f bcs +31 DONE_BUOY (3!)x3 @ vfp.21.054~062 (2)x3 ~057 The race mark buoy's Y coordinate needs to be either North of or on P0's upcoming Y coordinate, i.e. TAB_BUOY_Y,X u>= SRAM_P0_Y. bdf413 lda TAB_BUOY_Y,X (4!)x3 @ vfp.21.058~069 c587 cmp SRAM_P0_Y (3)x3 @ vfp.21.070~078 C = (TAB_BUOY_Y,X u>= SRAM_P0_Y) 9018 bcc +24 DONE_BUOY (3!)x3 @ vfp.21.079~087 (2)x3 ~084 C=1 invariant b014 bcs +20 NEXT_BUOY (3!)x3 @ vfp.21.085~093 BUOY_UPPER_HALF: The next race mark buoy P0 needs to "round" is on the upper half of the pixel area. The race mark buoy's X coordinate needs to be West of P0's upcoming X coordinate, i.e. TAB_BUOY_X,X u< SRAM_P0_X. bdf013 lda TAB_BUOY_X,X (4!)x3 @ vfp.21.009*~020 c583 cmp SRAM_P0_X (3)x3 @ vfp.21.021~029 C = (TAB_BUOY_X,X u>= SRAM_P0_X) b00f bcs +15 DONE_BUOY (3!)x3 @ vfp.21.030~038 (2)x3 ~035 The race mark buoy's X coordinate needs to be either East of or on P0's previous frame X coordinate, i.e. TAB_BUOY_X,X u>= ORAM_Px_X_SV. c5d8 cmp ORAM_Px_X_SV (3)x3 @ vfp.21.036~044 C = (TAB_BUOY_X,X u>= ORAM_Px_X_SV) 900b bcc +11 DONE_BUOY (3!)x3 @ vfp.21.045~053 (2)x3 ~050 The race mark buoy's Y coordinate needs to be either South of or on P0's upcoming Y coordinate, i.e. TAB_BUOY_Y,X u<= SRAM_P0_Y. bdf413 lda TAB_BUOY_Y,X (4!)x3 @ vfp.21.051~062 c587 cmp SRAM_P0_Y (3)x3 @ vfp.21.063~071 C = (TAB_BUOY_Y,X u>= SRAM_P0_Y) f002 beq +2 NEXT_BUOY (3!)x3 @ vfp.21.072~080 (2)x3 ~077 b002 bcs +2 DONE_BUOY (3!)x3 @ vfp.21.078~086 (2)x3 ~083 NEXT_BUOY: e691 inc SRAM_P0_BUOYS_CNT (5)x3 @ vfp.21.094*~108 DONE_BUOY: --------------------------------------------------------------- GAME LOGIC 3.7 P0 Edge Detection and Handling. Color Clocks: 575 ROM Bytes: 88 --------------------------------------------------------------- Preload Register X. a680 ldx SRAM_P0_HEADING (3)x3 @ vfp.21.109~117 a587 lda SRAM_P0_Y (3)x3 @ vfp.21.118-126 c9f0 cmp #$f0 TODOEXPLAIN (2)x3 @ vfp.21.127~132 C = (A u>= $f0) 8502 sta WSYNC_STB (3+)x3 @ vfp.21.133~227 900d bcc +13 CHECK_P0_NORTH (3!)x3 @ vfp.22.000~008 (2)x3 ~005 P0 is exiting via the Southern edge, let's prevent this. 8487 sty SRAM_P0_Y (3)x3 @ vfp.22.006~014 8486 sty SRAM_P0_Y_SUBPX (3)x3 @ vfp.22.015~023 848d sty SRAM_P0_SPEED (3)x3 @ vfp.22.024~032 bde813 lda TAB_REDIRECT_SOUTH,X (4!)x3 @ vfp.22.033~044 8580 sta SRAM_P0_HEADING (3)x3 @ vfp.22.045~053 Branch always. 1015 bpl +21 CHECK_P0_WEST (3!)x3 @ vfp.22.054~062 CHECK_P0_NORTH: (N.B. Expects SRAM_P0_Y in A) a9c0 lda #192 (2)x3 @ vfp.22.009~014 38 sec (2)x3 @ vfp.22.015~020 fde611 sbc TAB_GRPx_HEIGHT,X (4!)x3 @ vfp.22.021~032 c587 cmp SRAM_P0_Y (3)x3 @ vfp.22.033~041 C = (A u>= SRAM_P0_Y) b00b bcs +11 CHECK_P0_WEST (3!)x3 @ vfp.22.042~050 (2)x3 ~047 P0 is exiting via the Northern edge, let's prevent this. (N.B. Expects NEW SRAM_P0_Y in A) 8587 sta SRAM_P0_Y (3)x3 @ vfp.22.048~056 8486 sty SRAM_P0_Y_SUBPX (3)x3 @ vfp.22.057~065 848d sty SRAM_P0_SPEED (3)x3 @ vfp.22.066~074 bdd813 lda TAB_REDIRECT_NORTH,X (4!)x3 @ vfp.22.075~086 8580 sta SRAM_P0_HEADING (3)x3 @ vfp.22.087~095 CHECK_P0_WEST: N.B. East/West redirection overrides a North/South one. TODO test the four corner pixels a583 lda SRAM_P0_X (3)x3 @ vfp.22.096~104 c9f0 cmp #$f0 TODOEXPLAIN (2)x3 @ vfp.22.105~110 C = (A u>= $f0) 8502 sta WSYNC_STB (3+)x3 @ vfp.22.111~227 900d bcc +13 CHECK_P0_EAST (3!)x3 @ vfp.23.000~008 (2)x3 ~005 P0 is exiting via the Western edge, let's prevent this. 8483 sty SRAM_P0_X (3)x3 @ vfp.23.006~014 8482 sty SRAM_P0_X_SUBPX (3)x3 @ vfp.23.015~023 848d sty SRAM_P0_SPEED (3)x3 @ vfp.23.024~032 bdd013 lda TAB_REDIRECT_WEST,X (4!)x3 @ vfp.23.033~044 8580 sta SRAM_P0_HEADING (3)x3 @ vfp.23.045~053 Branch always. 1015 bpl +21 DONE_P0_EDGES (3!)x3 @ vfp.23.054~062 CHECK_P0_EAST: a9a0 lda #160 (2)x3 @ vfp.23.009~014 38 sec (2)x3 @ vfp.23.015~020 fdee11 sbc TAB_GRPx_WIDTH,X (4!)x3 @ vfp.23.021~032 c583 cmp SRAM_P0_X (3)x3 @ vfp.23.033~041 C = (A u>= SRAM_P0_X) b00b bcs +11 DONE_P0_EDGES (3!)x3 @ vfp.23.042~050 (2)x3 ~047 P0 is exiting via the Eastern edge, let's prevent this. 8583 sta SRAM_P0_X (3)x3 @ vfp.23.048~056 8482 sty SRAM_P0_X_SUBPX (3)x3 @ vfp.23.057~065 848d sty SRAM_P0_SPEED (3)x3 @ vfp.23.066~074 bde013 lda TAB_REDIRECT_EAST,X (4!)x3 @ vfp.23.075~086 8580 sta SRAM_P0_HEADING (3)x3 @ vfp.23.087~095 DONE_P0_EDGES: 8502 sta WSYNC_STB (3+)x3 @ vfp.23.096~227 --------------------------------------------------------------- GAME LOGIC 3.8 Update P1 Heading. Color Clocks: 183 ROM Bytes: 41 --------------------------------------------------------------- N.B. Cf. "Update P0 Heading". a681 ldx SRAM_P1_HEADING (3)x3 @ vfp.24.000-008 bdf611 lda TAB_GRPx_BOW_X_OFS,X (4!)x3 @ vfp.24.009-020 18 clc (2)x3 @ vfp.24.021-026 6585 adc SRAM_P1_X (3)x3 @ vfp.24.027-035 8585 sta SRAM_P1_X (3)x3 @ vfp.24.036-044 bdfe11 lda TAB_GRPx_BOW_Y_OFS,X (4!)x3 @ vfp.24.045-056 6589 adc SRAM_P1_Y (3)x3 @ vfp.24.057-065 8589 sta SRAM_P1_Y (3)x3 @ vfp.24.066-074 8a txa (2)x3 @ vfp.24.075-080 65c0 adc CRAM_P1_HEADING_DELTA (3)x3 @ vfp.24.081-089 2907 and #$07 (2)x3 @ vfp.24.090-095 8581 sta SRAM_P1_HEADING (3)x3 @ vfp.24.096-104 aa tax (2)x3 @ vfp.24.105-110 a585 lda SRAM_P1_X (3)x3 @ vfp.24.111-119 38 sec (2)x3 @ vfp.24.120-125 fdf611 sbc TAB_GRPx_BOW_X_OFS,X (4!)x3 @ vfp.24.126-137 8585 sta SRAM_P1_X (3)x3 @ vfp.24.138-146 a589 lda SRAM_P1_Y (3)x3 @ vfp.24.147-155 38 sec (2)x3 @ vfp.24.156-161 fdfe11 sbc TAB_GRPx_BOW_Y_OFS,X (4!)x3 @ vfp.24.162-173 8589 sta SRAM_P1_Y (3)x3 @ vfp.24.174-182 --------------------------------------------------------------- GAME LOGIC 3.9 Determine P1 Point of Sail. Color Clocks: 63 ROM Bytes: 13 --------------------------------------------------------------- a581 lda SRAM_P1_HEADING (3)x3 @ vfp.24.183-191 x8 0a asl (2)x3 @ vfp.24.192-197 0a asl (2)x3 @ vfp.24.198-203 0a asl (2)x3 @ vfp.24.204-209 C=0 invariant 658c adc SRAM_WIND_DIRECTION (3)x3 @ vfp.24.210-218 aa tax (2)x3 @ vfp.24.219-224 bd0013 lda TAB_POINT_OF_SAIL,X (4!)x3 @ vfp.24.225-25.008 85c2 sta CRAM_P1_POINT_OF_SAIL (3)x3 @ vfp.25.009-017 --------------------------------------------------------------- GAME LOGIC 3.10 Update P1 Speed. Color Clocks: 66 ROM Bytes: 14 --------------------------------------------------------------- a58e lda SRAM_P1_SPEED (3)x3 @ vfp.25.018-026 x5 0a asl (2)x3 @ vfp.25.027-032 0a asl (2)x3 @ vfp.25.033-038 C=0 invariant 658e adc SRAM_P1_SPEED (3)x3 @ vfp.25.039-047 C=0 invariant 65c2 adc CRAM_P1_POINT_OF_SAIL (3)x3 @ vfp.25.048-056 aa tax (2)x3 @ vfp.25.057-062 bdd612 lda TAB_SPEED_CHANGE,X (4!)x3 @ vfp.25.063-074 858e sta SRAM_P1_SPEED (3)x3 @ vfp.25.075-083 --------------------------------------------------------------- GAME LOGIC 3.11 Update P1 Location. Color Clocks: 207 ROM Bytes: 46 --------------------------------------------------------------- Save last frame's P1 location. a585 lda SRAM_P1_X (3)x3 @ vfp.25.084-092 85d8 sta ORAM_Px_X_SV (3)x3 @ vfp.25.093-101 a589 lda SRAM_P1_Y (3)x3 @ vfp.25.102-110 85d9 sta ORAM_Px_Y_SV (3)x3 @ vfp.25.111-119 a581 lda SRAM_P1_HEADING (3)x3 @ vfp.25.120-128 x6 0a asl (2)x3 @ vfp.25.129-134 C=0 invariant 6581 adc SRAM_P1_HEADING (3)x3 @ vfp.25.135-143 0a asl (2)x3 @ vfp.25.144-149 C=0 invariant 658e adc SRAM_P1_SPEED (3)x3 @ vfp.25.150-158 aa tax (2)x3 @ vfp.25.159-164 bd3612 lda TAB_X_SUBPX_DELTA,X (4!)x3 @ vfp.25.165-176 C=0 invariant 6584 adc SRAM_P1_X_SUBPX (3)x3 @ vfp.25.177-185 8584 sta SRAM_P1_X_SUBPX (3)x3 @ vfp.25.186-194 bd0612 lda TAB_X_DELTA,X (4!)x3 @ vfp.25.195-206 6585 adc SRAM_P1_X (3)x3 @ vfp.25.207-215 8585 sta SRAM_P1_X (3)x3 @ vfp.25.216-224 bd9612 lda TAB_Y_SUBPX_DELTA,X (4!)x3 @ vfp.25.225-26.008 18 clc (2)x3 @ vfp.26.009-014 6588 adc SRAM_P1_Y_SUBPX (3)x3 @ vfp.26.015-023 8588 sta SRAM_P1_Y_SUBPX (3)x3 @ vfp.26.024-032 bd6612 lda TAB_Y_DELTA,X (4!)x3 @ vfp.26.033-044 6589 adc SRAM_P1_Y (3)x3 @ vfp.26.045-053 8589 sta SRAM_P1_Y (3)x3 @ vfp.26.054-062 --------------------------------------------------------------- GAME LOGIC 3.12 P1 Race Mark Buoy Rounding. Color Clocks: 126 ROM Bytes: 52 --------------------------------------------------------------- a792 lax SRAM_P1_BUOYS_CNT (3)x3 @ vfp.26.063-071 2902 and #$02 (2)x3 @ vfp.26.072-077 d018 bne +24 BUOY_UPPER_HALF (3!)x3 @ vfp.26.078~086 (2)x3 ~083 The race mark buoy P1 needs to "round" next is on the lower half of the pixel area. The race mark buoy's X coordinate needs to be East of P1's upcoming X coordinate, i.e. TAB_BUOY_X,X u> SRAM_P1_X. bdf013 lda TAB_BUOY_X,X (4!)x3 @ vfp.26.084~095 c585 cmp SRAM_P1_X (3)x3 @ vfp.26.096~104 C = (TAB_BUOY_X,X u>= SRAM_P0_X) 9027 bcc +39 DONE_BUOY (3!)x3 @ vfp.26.105~113 (2)x3 ~110 f025 beq +37 DONE_BUOY (3!)x3 @ vfp.26.111~119 (2)x3 ~116 The race mark buoy's X coordinate needs to be either West of or on P1's previous frame X coordinate, i.e. TAB_BUOY_X,X u<= ORAM_Px_X_SV. c5d8 cmp ORAM_Px_X_SV (3)x3 @ vfp.26.117~125 C = (TAB_BUOY_X,X u>= ORAM_Px_X_SV) f021 beq +33 DONE_BUOY (3!)x3 @ vfp.26.126~134 (2)x3 ~131 b01f bcs +31 DONE_BUOY (3!)x3 @ vfp.26.132~140 (2)x3 ~137 The race mark buoy's Y coordinate needs to be either North of or on P1's upcoming Y coordinate, i.e. TAB_BUOY_Y,X u>= SRAM_P1_Y. bdf413 lda TAB_BUOY_Y,X (4!)x3 @ vfp.26.138~149 c589 cmp SRAM_P1_Y (3)x3 @ vfp.26.150~158 C = (TAB_BUOY_Y,X u>= SRAM_P1_Y) 9018 bcc +24 DONE_BUOY (3!)x3 @ vfp.26.159~167 (2)x3 ~164 C=1 invariant b014 bcs +20 NEXT_BUOY (3!)x3 @ vfp.26.165~173 BUOY_UPPER_HALF: The next race mark buoy P1 needs to "round" is on the upper half of the pixel area. The race mark buoy's X coordinate needs to be West of P1's upcoming X coordinate, i.e. TAB_BUOY_X,X u< SRAM_P1_X. bdf013 lda TAB_BUOY_X,X (4!)x3 @ vfp.26.087*~098 c585 cmp SRAM_P1_X (3)x3 @ vfp.26.099~107 C = (TAB_BUOY_X,X u>= SRAM_P1_X) b00f bcs +15 DONE_BUOY (3!)x3 @ vfp.26.108~116 (2)x3 ~113 The race mark buoy's X coordinate needs to be either East of or on P1's previous frame X coordinate, i.e. TAB_BUOY_X,X u>= ORAM_Px_X_SV. c5d8 cmp ORAM_Px_X_SV (3)x3 @ vfp.26.114~122 C = (TAB_BUOY_X,X u>= ORAM_Px_X_SV) 900b bcc +11 DONE_BUOY (3!)x3 @ vfp.26.123~131 (2)x3 ~128 The race mark buoy's Y coordinate needs to be either South of or on P1's upcoming Y coordinate, i.e. TAB_BUOY_Y,X u<= SRAM_P1_Y. bdf413 lda TAB_BUOY_Y,X (4!)x3 @ vfp.26.129~140 c589 cmp SRAM_P1_Y (3)x3 @ vfp.26.141~149 C = (TAB_BUOY_Y,X u>= SRAM_P1_Y) f002 beq +2 NEXT_BUOY (3!)x3 @ vfp.26.150~158 (2)x3 ~155 b002 bcs +2 DONE_BUOY (3!)x3 @ vfp.26.156~164 (2)x3 ~161 NEXT_BUOY: e692 inc SRAM_P1_BUOYS_CNT (5)x3 @ vfp.26.174*~188 DONE_BUOY: --------------------------------------------------------------- GAME LOGIC 3.13 P1 Edge Detection and Handling. Color Clocks: 495 ROM Bytes: 88 --------------------------------------------------------------- Preload Register X. a681 ldx SRAM_P1_HEADING (3)x3 @ vfp.26.189~197 a589 lda SRAM_P1_Y (3)x3 @ vfp.26.198-206 c9f0 cmp #$f0 TODOEXPLAIN (2)x3 @ vfp.26.207~212 C = (A u>= $f0) 8502 sta WSYNC_STB (3+)x3 @ vfp.26.213~227 900d bcc +13 CHECK_P1_NORTH (3!)x3 @ vfp.27.000~008 (2)x3 ~005 P1 is exiting via the Southern edge, let's prevent this. 8489 sty SRAM_P1_Y (3)x3 @ vfp.27.006~014 8488 sty SRAM_P1_Y_SUBPX (3)x3 @ vfp.27.015~023 848e sty SRAM_P1_SPEED (3)x3 @ vfp.27.024~032 bde813 lda TAB_REDIRECT_SOUTH,X (4!)x3 @ vfp.27.033~044 8581 sta SRAM_P1_HEADING (3)x3 @ vfp.27.045~053 Branch always. 1015 bpl +21 CHECK_P1_WEST (3!)x3 @ vfp.27.054~062 CHECK_P1_NORTH: (N.B. Expects SRAM_P1_Y in A) a9c0 lda #192 (2)x3 @ vfp.27.009~014 38 sec (2)x3 @ vfp.27.015~020 fde611 sbc TAB_GRPx_HEIGHT,X (4!)x3 @ vfp.27.021~032 c589 cmp SRAM_P1_Y (3)x3 @ vfp.27.033~041 C = (A u>= SRAM_P1_Y) b00b bcs +11 CHECK_P1_WEST (3!)x3 @ vfp.27.042~050 (2)x3 ~047 P1 is exiting via the Northern edge, let's prevent this. (N.B. Expects NEW SRAM_P1_Y in A) 8589 sta SRAM_P1_Y (3)x3 @ vfp.27.048~056 8488 sty SRAM_P1_Y_SUBPX (3)x3 @ vfp.27.057~065 848e sty SRAM_P1_SPEED (3)x3 @ vfp.27.066~074 bdd813 lda TAB_REDIRECT_NORTH,X (4!)x3 @ vfp.27.075~086 8581 sta SRAM_P1_HEADING (3)x3 @ vfp.27.087~095 CHECK_P1_WEST: N.B. East/West redirection overrides a North/South one. TODO test the four corner pixels a585 lda SRAM_P1_X (3)x3 @ vfp.27.096~104 c9f0 cmp #$f0 TODOEXPLAIN (2)x3 @ vfp.27.105~110 C = (A u>= $f0) 8502 sta WSYNC_STB (3+)x3 @ vfp.27.111~227 900d bcc +13 CHECK_P1_EAST (3!)x3 @ vfp.28.000~008 (2)x3 ~005 P1 is exiting via the Western edge, let's prevent this. 8485 sty SRAM_P1_X (3)x3 @ vfp.28.006~014 8484 sty SRAM_P1_X_SUBPX (3)x3 @ vfp.28.015~023 848e sty SRAM_P1_SPEED (3)x3 @ vfp.28.024~032 bdd013 lda TAB_REDIRECT_WEST,X (4!)x3 @ vfp.28.033~044 8581 sta SRAM_P1_HEADING (3)x3 @ vfp.28.045~053 Branch always. 1015 bpl +21 DONE_P1_EDGES (3!)x3 @ vfp.28.054~062 CHECK_P1_EAST: a9a0 lda #160 (2)x3 @ vfp.28.009~014 38 sec (2)x3 @ vfp.28.015~020 fdee11 sbc TAB_GRPx_WIDTH,X (4!)x3 @ vfp.28.021~032 c585 cmp SRAM_P1_X (3)x3 @ vfp.28.033~041 C = (A u>= SRAM_P1_X) b00b bcs +11 DONE_P1_EDGES (3!)x3 @ vfp.28.042~050 (2)x3 ~047 P1 is exiting via the Eastern edge, let's prevent this. 8585 sta SRAM_P1_X (3)x3 @ vfp.28.048~056 8484 sty SRAM_P1_X_SUBPX (3)x3 @ vfp.28.057~065 848e sty SRAM_P1_SPEED (3)x3 @ vfp.28.066~074 bde013 lda TAB_REDIRECT_EAST,X (4!)x3 @ vfp.28.075~086 8581 sta SRAM_P1_HEADING (3)x3 @ vfp.28.087~095 DONE_P1_EDGES: 8502 sta WSYNC_STB (3+)x3 @ vfp.28.096~227 --------------------------------------------------------------- GAME LOGIC 3.14 Update Mx State. Color Clocks: TODO ROM Bytes: TODO --------------------------------------------------------------- TODO --------------------------------------------------------------- GAME LOGIC 3.15 Update Audio Channels. Color Clocks: TODO ROM Bytes: TODO --------------------------------------------------------------- TODO --------------------------------------------------------------- GAME LOGIC 3.16 Update Other Displays (e.g. scores). Color Clocks: TODO ROM Bytes: TODO --------------------------------------------------------------- TODO --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 213 ROM Bytes: 36 --------------------------------------------------------------- eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea @ vfp.29.000-113 eaeaeaeaeaeaeaeaeaeaeaeaeaeaea @ vfp.29.114-203 04ea skb (3)x3 @ vfp.29.204-212 --------------------------------------------------------------- FRAME OVERHEAD 2/5 - Trigger the Vertical Sync Interval. Color Clocks: 15 ROM Bytes: 3 --------------------------------------------------------------- ba tsx (2)x3 @ vfp.29.213-218 8600 stx VSYNC_02 (3)x3 @ vfp.29.219-227 =============================================================== =============> VERTICAL FRONT PORCH -- ENDS HERE <============= =============================================================== ===========> VERTICAL SYNC INTERVAL -- STARTS HERE <=========== =============================================================== | | Lasts 3 scanlines = 228 CPU cycles = 684 color clocks | | ROM Bytes: $177d-17a7 [43] +-------------------------------------------------------------- --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 675 ROM Bytes: 41 --------------------------------------------------------------- 8502 sta WSYNC_STB (3+)x3 @ vsi.0.000~227 8502 sta WSYNC_STB (3+)x3 @ vsi.1.000~227 eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea @ vsi.2.000-113 eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea @ vsi.2.114-209 04ea skb (3)x3 @ vsi.2.210-218 --------------------------------------------------------------- FRAME OVERHEAD 3/5 - Stop Vertical Sync. Color Clocks: 9 ROM Bytes: 2 --------------------------------------------------------------- 8400 sty VSYNC_02 (3)x3 @ vsi.2.219-227 =============================================================== ============> VERTICAL SYNC INTERVAL -- ENDS HERE <============ =============================================================== ----------------------< FRAME BOUNDARY >----------------------- =============================================================== ============> VERTICAL BACK PORCH -- STARTS HERE <============= =============================================================== | | Lasts 37 scanlines = 2,812 CPU cycles = 8,436 color clocks | | ROM Bytes: $17a8-191d [374] +-------------------------------------------------------------- --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 5,244 ROM Bytes: 46 --------------------------------------------------------------- 8502 sta WSYNC_STB (3+)x3 @ vbp.00.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.01.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.02.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.03.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.04.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.05.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.06.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.07.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.08.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.09.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.10.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.11.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.12.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.13.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.14.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.15.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.16.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.17.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.18.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.19.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.20.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.21.000~227 8502 sta WSYNC_STB (3+)x3 @ vbp.22.000~227 --------------------------------------------------------------- GAME LOGIC 4/5 - Refresh Frame Caches. --------------------------------------------------------------- --------------------------------------------------------------- GAME LOGIC 4.1 - Refresh P0 Frame Cache. Color Clocks: 333 ROM Bytes: 75 --------------------------------------------------------------- a680 ldx SRAM_P0_HEADING (3)x3 @ vbp.23.000-008 bde611 lda TAB_GRPx_HEIGHT,X (4!)x3 @ vbp.23.009-020 85a7 sta CRAM_P0_HEIGHT (3)x3 @ vbp.23.021-029 bdee11 lda TAB_GRPx_WIDTH,X (4!)x3 @ vbp.23.030-041 85a8 sta CRAM_P0_WIDTH (3)x3 @ vbp.23.042-050 bdde11 lda TAB_GRPx_OFS,X (4!)x3 @ vbp.23.051-062 aa tax (2)x3 @ vbp.23.063-068 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.23.069-080 85a9 sta CRAM_GRP0_ROWS+0 (3)x3 @ vbp.23.081-089 e8 inx (2)x3 @ vbp.23.090-095 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.23.096-107 85aa sta CRAM_GRP0_ROWS+1 (3)x3 @ vbp.23.108-116 e8 inx (2)x3 @ vbp.23.117-122 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.23.123-134 85ab sta CRAM_GRP0_ROWS+2 (3)x3 @ vbp.23.135-143 e8 inx (2)x3 @ vbp.23.144-149 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.23.150-161 85ac sta CRAM_GRP0_ROWS+3 (3)x3 @ vbp.23.162-170 e8 inx (2)x3 @ vbp.23.171-176 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.23.177-188 85ad sta CRAM_GRP0_ROWS+4 (3)x3 @ vbp.23.189-197 e8 inx (2)x3 @ vbp.23.198-203 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.23.204-215 85ae sta CRAM_GRP0_ROWS+5 (3)x3 @ vbp.23.216-224 e8 inx (2)x3 @ vbp.23.225-24.002 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.24.003-014 85af sta CRAM_GRP0_ROWS+6 (3)x3 @ vbp.24.015-023 e8 inx (2)x3 @ vbp.24.024-029 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.24.030-041 85b0 sta CRAM_GRP0_ROWS+7 (3)x3 @ vbp.24.042-050 e8 inx (2)x3 @ vbp.24.051-056 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.24.057-068 85b1 sta CRAM_GRP0_ROWS+8 (3)x3 @ vbp.24.069-077 e8 inx (2)x3 @ vbp.24.078-083 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.24.084-095 85b2 sta CRAM_GRP0_ROWS+9 (3)x3 @ vbp.24.096-104 --------------------------------------------------------------- GAME LOGIC 4.2 - Refresh P1 Frame Cache. Color Clocks: 333 ROM Bytes: 75 --------------------------------------------------------------- a681 ldx SRAM_P1_HEADING (3)x3 @ vbp.24.105-113 bde611 lda TAB_GRPx_HEIGHT,X (4!)x3 @ vbp.24.114-125 85b3 sta CRAM_P1_HEIGHT (3)x3 @ vbp.24.126-134 bdee11 lda TAB_GRPx_WIDTH,X (4!)x3 @ vbp.24.135-146 85b4 sta CRAM_P1_WIDTH (3)x3 @ vbp.24.147-155 bdde11 lda TAB_GRPx_OFS,X (4!)x3 @ vbp.24.156-167 aa tax (2)x3 @ vbp.24.168-173 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.24.174-185 85b5 sta CRAM_GRP1_ROWS+0 (3)x3 @ vbp.24.186-194 e8 inx (2)x3 @ vbp.24.195-200 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.24.201-212 85b6 sta CRAM_GRP1_ROWS+1 (3)x3 @ vbp.24.213-221 e8 inx (2)x3 @ vbp.24.222-227 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.000-011 85b7 sta CRAM_GRP1_ROWS+2 (3)x3 @ vbp.25.012-020 e8 inx (2)x3 @ vbp.25.021-026 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.027-038 85b8 sta CRAM_GRP1_ROWS+3 (3)x3 @ vbp.25.039-047 e8 inx (2)x3 @ vbp.25.048-053 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.054-065 85b9 sta CRAM_GRP1_ROWS+4 (3)x3 @ vbp.25.066-074 e8 inx (2)x3 @ vbp.25.075-080 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.081-092 85ba sta CRAM_GRP1_ROWS+5 (3)x3 @ vbp.25.093-101 e8 inx (2)x3 @ vbp.25.102-107 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.108-119 85bb sta CRAM_GRP1_ROWS+6 (3)x3 @ vbp.25.120-128 e8 inx (2)x3 @ vbp.25.129-134 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.135-146 85bc sta CRAM_GRP1_ROWS+7 (3)x3 @ vbp.25.147-155 e8 inx (2)x3 @ vbp.25.156-161 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.162-173 85bd sta CRAM_GRP1_ROWS+8 (3)x3 @ vbp.25.174-182 e8 inx (2)x3 @ vbp.25.183-188 bd0011 lda PAGE_TAB_GRPx,X (4!)x3 @ vbp.25.189-200 85be sta CRAM_GRP1_ROWS+9 (3)x3 @ vbp.25.201-209 --------------------------------------------------------------- GAME LOGIC 4.3 - Refresh Vane BL Frame Cache. Color Clocks: 30 ROM Bytes: 7 --------------------------------------------------------------- a68c ldx SRAM_WIND_DIRECTION (3)x3 @ vbp.25.210-218 bdce12 lda TAB_VANE_BL_Y,X (4!)x3 @ vbp.25.219-26.002 85c3 sta CRAM_VANE_BL_Y (3)x3 @ vbp.26.003-011 --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 216 ROM Bytes: 2 --------------------------------------------------------------- 8502 sta WSYNC_STB (3+)x3 @ vbp.26.012~227 --------------------------------------------------------------- GAME LOGIC 5/5 - Pre-Kernel. Translate the Game State to the TIA in preparation for the Display Kernel. --------------------------------------------------------------- --------------------------------------------------------------- GAME LOGIC 5.1 - Preload RESP0 delay. Preload delay line offset in preparation for upcoming RESP0 strobe. Color Clocks: 228 ROM Bytes: 9 --------------------------------------------------------------- a683 ldx SRAM_P0_X (3)x3 @ vbp.27.000-008 bd4710 lda TAB_RESPx_DELAY,X (4!)x3 @ vbp.27.009-020 85d0 sta ORAM_DELAY_LINE_OFS (3)x3 @ vbp.27.021-029 8502 sta WSYNC_STB (3+)x3 @ vbp.27.030-227 --------------------------------------------------------------- GAME LOGIC 5.2 - Strobe RESP0. Update P0's Horizontal Position Counter register by strobing RESP0 at just the right time. This gives us coarse horizontal positioning with a resolution of 3cc. Color Clocks: 228 ROM Bytes: 7 --------------------------------------------------------------- 204410 jsr INDIRECT_DELAY_LINE (19+#)x3 min (i.e. #=0): @ vbp.28.000-056 max (i.e. #=51): @ vbp.28.000-209 8510 sta RESP0_STB (3)x3 min (i.e. #=0): @ vbp.28.057-065 max (i.e. #=51): @ vbp.28.210-218 N.B. After a 5cc lag... (cf. "Coarse Positioning RES Lags") min (i.e. #=0): @ vbp.28.066-070 max (i.e. #=51): @ vbp.28.219-223, ... P0's HPC resets to... min (i.e. #=0): 71cc -68cc = 3px max (i.e. #=51): 224cc -68cc = 156px 8502 sta WSYNC_STB (3+)x3 min (i.e. #=0): (172cc) @ vbp.28.066-227 max (i.e. #=51): (9cc) @ vbp.28.219-227 --------------------------------------------------------------- GAME LOGIC 5.3 - Preload RESP1 delay. Color Clocks: 228 ROM Bytes: 9 --------------------------------------------------------------- a685 ldx SRAM_P1_X (3)x3 @ vbp.29.000-008 bd4710 lda TAB_RESPx_DELAY,X (4!)x3 @ vbp.29.009-020 85d0 sta ORAM_DELAY_LINE_OFS (3)x3 @ vbp.29.021-029 8502 sta WSYNC_STB (3+)x3 @ vbp.29.030-227 --------------------------------------------------------------- GAME LOGIC 5.4 - Strobe RESP1. Color Clocks: 228 ROM Bytes: 7 --------------------------------------------------------------- 204410 jsr INDIRECT_DELAY_LINE (19+#)x3 @ vbp.30.000-056(+3#) 8511 sta RESP1_STB (3)x3 @ vbp.30.057(+3#)-065(+3#) 8502 sta WSYNC_STB (3+)x3 @ vbp.30.066(+3#)-227 --------------------------------------------------------------- GAME LOGIC 5.5 - Preload RESBL delay. TODO we should combine all these delay preloads TODO have a different ORAM_DELAY_LINE_OFS for each Color Clocks: 228 ROM Bytes: 9 --------------------------------------------------------------- a68c ldx SRAM_WIND_DIRECTION (3)x3 @ vbp.31.000-008 bdc612 lda TAB_VANE_RESBL_DELAY,X (4!)x3 @ vbp.31.009-020 85d0 sta ORAM_DELAY_LINE_OFS (3)x3 @ vbp.31.021-029 8502 sta WSYNC_STB (3+)x3 @ vbp.31.030-227 --------------------------------------------------------------- GAME LOGIC 5.6 - Strobe RESBL. Color Clocks: 228 ROM Bytes: 7 --------------------------------------------------------------- N.B. If time gets really tight strobing the BL reset could be spliced between strobing the Mx resets in a single scanline, albeit with some rework. 204410 jsr INDIRECT_DELAY_LINE (19+#)x3 @ vbp.32.000-056(+3#) 8514 sta RESBL_STB (3)x3 @ vbp.32.057(+3#)-065(+3#) 8502 sta WSYNC_STB (3+)x3 @ vbp.32.066(+3#)-227 --------------------------------------------------------------- GAME LOGIC STD - Strobe RESMx. Color Clocks: 456 ROM Bytes: 22 --------------------------------------------------------------- STD move to reset? Reset M0's HPC (coarse positioning). 202810 jsr DELAY_LINE-25 (6+8+25)x3 @ vbp.33.000-119 8512 sta RESM0_STB (3)x3 @ vbp.33.120-128 *** After a 4cc lag... (cf. "Coarse Positioning RES Lags") @ vbp.33.129-132 ... M0's HPC resets to 133cc -68cc = 65px When HMOVE is eventually strobed it will "finely adjust" M0's horizontal position. 65px (M0 coarse positioning) -0cc (M0 fine adjustment, i.e. horizontal motion) ---- 65px (M1 net horizontal position). -2 | -1 | 0 <- horizontal motion (cc) -----+-----+----- $c0 | $b0 | $a0 <- HMMx byte value a9a0 lda #$a0 (2)x3 @ vbp.33.129-134 8522 sta HMM0_f0 (3)x3 @ vbp.33.135-143 8502 sta WSYNC_STB (3+)x3 @ vbp.33.144-227 Reset M1's HPC (coarse positioning). 201e10 jsr DELAY_LINE-36 (6+8+36)x3 @ vbp.34.000-149 8513 sta RESM1_STB (3)x3 @ vbp.34.150-158 *** After a 4cc lag... (cf. "Coarse Positioning RES Lags") @ vbp.34.159-162 ... M1's HPC resets to 163cc -68cc = 95px When HMOVE is eventually strobed it will "finely adjust" M1's horizontal position. 95px (M1 coarse positioning) -1cc (M1 fine adjustment, i.e. horizontal motion) ---- 94px (M1 net horizontal position). -2 | -1 | 0 <- horizontal motion (cc) -----+-----+----- $c0 | $b0 | $a0 <- HMMx byte value a9b0 lda #$b0 (2)x3 @ vbp.34.159-164 8523 sta HMM1_f0 (3)x3 @ vbp.34.165-173 8502 sta WSYNC_STB (3+)x3 @ vbp.34.174-227 --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 78 ROM Bytes: 13 --------------------------------------------------------------- STD eaeaeaeaeaeaeaeaeaeaeaeaea (26)x3 @ vbp.35.000-077 STD temporary replacement for testing only 841d sty ENAM0_02 (3)x3 @ STD 8c1e00 sty.w ENAM1_02 (4)x3 @ STD 0828 php/plp (7x3) eaeaeaeaeaea (12)x3 STD temporary for testing only a902 lda #2 (2)x3 @ STD 851d sta ENAM0_02 (3)x3 @ STD 851e sta ENAM1_02 (3)x3 @ STD --------------------------------------------------------------- GAME LOGIC 5.7 - Preload HMPx. Preload Horizontal Motion registers in preparation for upcoming HMOVE strobe. This will allow us to further refine the horizontal positioning of objects to a resolution of 1cc. Color Clocks: 126 ROM Bytes: 28 --------------------------------------------------------------- Preload HMP0. a5a8 lda CRAM_P0_WIDTH (3)x3 @ vbp.35.078-086 a683 ldx SRAM_P0_X (3)x3 @ vbp.35.087-095 18 clc (2)x3 @ vbp.35.096-101 7d0011 adc TAB_HMPx_NDX,X (4!)x3 @ vbp.35.102-113 aa tax (2)x3 @ vbp.35.114-119 bde710 lda TAB_HMPx_VAL,X (4!)x3 @ vbp.35.120-131 8520 sta HMP0_f0 (3)x3 @ vbp.35.132-140 Preload HMP1. a5b4 lda CRAM_P1_WIDTH (3)x3 @ vbp.35.141-149 a685 ldx SRAM_P1_X (3)x3 @ vbp.35.150-158 18 clc (2)x3 @ vbp.35.159-164 7d0011 adc TAB_HMPx_NDX,X (4!)x3 @ vbp.35.165-176 aa tax (2)x3 @ vbp.35.177-182 bde710 lda TAB_HMPx_VAL,X (4!)x3 @ vbp.35.183-194 8521 sta HMP1_f0 (3)x3 @ vbp.35.195-203 --------------------------------------------------------------- GAME LOGIC 5.8 - Restart Active Scanline countdown counter. Color Clocks: 6 ROM Bytes: 2 --------------------------------------------------------------- We're using the lower left of the Display Kernel pixel area as its local coordinate origin. The pixel area is 160 color clocks wide by 192 scanlines tall. Keep in mind that the NTSC 2600's pixel aspect ratio is x:y ≈ 5:3. Using scanline height as our standard unit, this implies an overall pixel area aspect ratio of: X:Y ≈ 160x5:192x3 ≈ 800:576 ≈ 25:18. 0,191 scanlines ^ | | | Pixel | Area | | +------------------> color clocks 0,0 159,0 Within the Display Kernel the CPU Y register acts as our Active Scanline countdown counter. a0bf ldy #191 (2)x3 @ vbp.35.204-209 --------------------------------------------------------------- GAME LOGIC 5.9 - 4LK Preloads for first active scanline of frame. Color Clocks: 84 ROM Bytes: 20 --------------------------------------------------------------- 192/4 -1 = 47 a22f ldx #47 (2)x3 @ vbp.35.210-215 bd4013 lda TAB_PF0,X (4!)x3 @ vbp.35.216-227 85d3 sta ORAM_PF0 (3)x3 @ vbp.36.000-008 bd7013 lda TAB_PF1,X (4!)x3 @ vbp.36.009-020 85d4 sta ORAM_PF1 (3)x3 @ vbp.36.021-029 bda013 lda TAB_PF2,X (4!)x3 @ vbp.36.030-041 85d5 sta ORAM_PF2 (3)x3 @ vbp.36.042-050 ca dex (2)x3 @ vbp.36.051-056 86d6 stx ORAM_PF_ROW (3)x3 @ vbp.36.057-065 --------------------------------------------------------------- GAME LOGIC 5.10 - 1LK Preloads for first active scanline of frame. Color Clocks: 138 ROM Bytes: 30 --------------------------------------------------------------- CPU Y register acts as our Active Scanline countdown counter. row# is the candidate P0 sprite local row number: row# = Y - SRAM_P0_Y. P0 sprite for scanline Y: ORAM_GRP0 <- CRAM_GRP0_ROW{row#} & A 98 tya (2)x3 @ vbp.36.066-071 38 sec (2)x3 @ vbp.36.072-077 e587 sbc SRAM_P0_Y (3)x3 @ vbp.36.078-086 c5a7 cmp CRAM_P0_HEIGHT (3)x3 @ vbp.36.087-095 aa tax (2)x3 @ vbp.36.096-101 a900 lda #$00 (2)x3 @ vbp.36.102-107 e900 sbc #$00 (2)x3 @ vbp.36.108-113 35a9 and CRAM_GRP0_ROWS,X (4)x3 @ vbp.36.114-125 85d2 sta ORAM_GRP0 (3)x3 @ vbp.36.126-134 P1 sprite for scanline Y: A <- CRAM_GRP1_ROW{row#} & A 98 tya (2)x3 @ vbp.36.135-140 38 sec (2)x3 @ vbp.36.141-146 e589 sbc SRAM_P1_Y (3)x3 @ vbp.36.147-155 c5b3 cmp CRAM_P1_HEIGHT (3)x3 @ vbp.36.156-164 aa tax (2)x3 @ vbp.36.165-170 a900 lda #$00 (2)x3 @ vbp.36.171-176 e900 sbc #$00 (2)x3 @ vbp.36.177-182 35b5 and CRAM_GRP1_ROWS,X (4)x3 @ vbp.36.183-194 04ea skb (3)x3 @ vbp.36.195-203 --------------------------------------------------------------- GAME LOGIC 5.11 - Strobe HMOVE. N.B. Takes effect at 213cc (i.e. 71mc). Color Clocks: 9 ROM Bytes: 2 --------------------------------------------------------------- 862a stx HMOVE_STB (3)x3 @ vbp.36.204-212 *** N.B. *** --------------------------------------------------------------- FRAME OVERHEAD 4/5 - Stop Vertical Blanking. Color Clocks: 15 ROM Bytes: 4 --------------------------------------------------------------- 76543210 function -------- --------------------------------- xx....x. Vertical Blank & Latched Ports. 0....... Remove INPT0,1,2,3 (Paddle Ports) dump path to ground. .1...... Enable latches for Ports INPT4,5 (Joystick Buttons Left,Right). Both latches are set to logic 1, and remain there until the corresponding port goes to logic 0. N.B. A button press is a logic 0. When the corresponsding port goes to logic 0 the latch goes to logic 0 and remains there regardless of what the port does. ......0. Vertical Blank Off. |||||||| a240 ldx #%01000000 (2)x3 @ vbp.36.213-218 8601 stx VBLANK_c2 (3)x3 @ vbp.36.219-227 =============================================================== =============> VERTICAL BACK PORCH -- ENDS HERE <============== =============================================================== ==========> VERTICAL BLANKING INTERVAL -- ENDS HERE <========== =============================================================== ===============> DISPLAY KERNEL -- STARTS HERE <=============== =============================================================== | | Lasts 192 scanlines = 14,592 CPU cycles = 43,776 color clocks | | ROM Bytes: $191e-1a04, $1461-1464 [231 + 4 = 235] +-------------------------------------------------------------- TODO - implement the 2LK There 3 sub-kernels: - a single scanline resolution kernel (1LK) for the Px. - a two-scanline resolution kernel (2LK) for the Mx. (TODO) - a four-scanline resolution kernel (4LK) for the BL and PFx. The sub-kernels are interleaved as follows: 111111111111111111111111111111111111111111111111 998888888888777777777766666666665555555555444444 SL 109876543210987654321098765432109876543210987654 ------------------------------------------------ 1LK 123412341234123412341234123412341234123412341234 2LK .1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2 4LK 1...1...1...1...1...1...1...1...1...1...1...1... 111111111111111111111111111111111111111111110000 444433333333332222222222111111111100000000009999 SL 321098765432109876543210987654321098765432109876 ------------------------------------------------ 1LK 123412341234123412341234123412341234123412341234 2LK .1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2 4LK 1...1...1...1...1...1...1...1...1...1...1...1... 000000000000000000000000000000000000000000000000 999999888888888877777777776666666666555555555544 SL 543210987654321098765432109876543210987654321098 ------------------------------------------------ 1LK 123412341234123412341234123412341234123412341234 2LK .1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2 4LK 1...1...1...1...1...1...1...1...1...1...1...1... 000000000000000000000000000000000000000000000000 444444443333333333222222222211111111110000000000 SL 765432109876543210987654321098765432109876543210 ------------------------------------------------ 1LK 123412341234123412341234123412341234123412341234 2LK .1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2 4LK 1...1...1...1...1...1...1...1...1...1...1...1... DK: --------------------------------------------------------------- DK WORK 1/18 - 1LK TIA Updates - 1st of 4. Color Clocks: 27 x192/4 = 27 x48 = 1,296 ROM Bytes: 6 --------------------------------------------------------------- N.B. Assumes preloaded A register. 851c sta GRP1_ff (3)x3 @ dk.000*.000-008 *** a5d2 lda ORAM_GRP0 (3)x3 @ dk.000*.009-017 851b sta GRP0_ff (3)x3 @ dk.000*.018-026 *** --------------------------------------------------------------- DK WORK 2/18 - 4LK TIA Updates. Color Clocks: 72 x192/4 = 72 x48 = 3,456 ROM Bytes: 16 --------------------------------------------------------------- TODO This is temporary test code. TODO splice ORAM_ENABL and ORAM_PF0 together into ORAM_PF0_BL a5d7 lda ORAM_ENABL (3)x3 @ dk.000*.027-035 851f sta ENABL_02 (3)x3 @ dk.000*.036-044 *** a5d3 lda ORAM_PF0 (3)x3 @ dk.000*.045-053 850d sta PF0_f0 (3)x3 @ dk.000*.054-062 *** a5d4 lda ORAM_PF1 (3)x3 @ dk.000*.063-071 850e sta PF1_ff (3)x3 @ dk.000*.072-080 *** a5d5 lda ORAM_PF2 (3)x3 @ dk.000*.081-089 850f sta PF2_ff (3)x3 @ dk.000*.090-098 *** --------------------------------------------------------------- DK WORK 3/18 - Preloads for 2nd of 4 1LK TIA Updates. Color Clocks: 129 x192/4 = 129 x48 = 6,192 ROM Bytes: 28 --------------------------------------------------------------- 98 tya (2)x3 @ dk.000*.099-104 N.B. clc rather than sec. 18 clc (2)x3 @ dk.000*.105-110 e587 sbc SRAM_P0_Y (3)x3 @ dk.000*.111-119 c5a7 cmp CRAM_P0_HEIGHT (3)x3 @ dk.000*.120-128 aa tax (2)x3 @ dk.000*.129-134 a900 lda #$00 (2)x3 @ dk.000*.135-140 e900 sbc #$00 (2)x3 @ dk.000*.141-146 35a9 and CRAM_GRP0_ROWS,X (4)x3 @ dk.000*.147-158 85d2 sta ORAM_GRP0 (3)x3 @ dk.000*.159-167 98 tya (2)x3 @ dk.000*.168-173 N.B. clc rather than sec. 18 clc (2)x3 @ dk.000*.174-179 e589 sbc SRAM_P1_Y (3)x3 @ dk.000*.180-188 c5b3 cmp CRAM_P1_HEIGHT (3)x3 @ dk.000*.189-197 aa tax (2)x3 @ dk.000*.198-203 a900 lda #$00 (2)x3 @ dk.000*.204-209 e900 sbc #$00 (2)x3 @ dk.000*.210-215 35b5 and CRAM_GRP1_ROWS,X (4)x3 @ dk.000*.216-227 --------------------------------------------------------------- DK WORK 4/18 - 1LK TIA Updates - 2nd of 4. Color Clocks: 27 x192/4 = 27 x48 = 1,296 ROM Bytes: 6 --------------------------------------------------------------- N.B. Assumes preloaded A register. 851c sta GRP1_ff (3)x3 @ dk.001*.000-008 *** a5d2 lda ORAM_GRP0 (3)x3 @ dk.001*.009-017 851b sta GRP0_ff (3)x3 @ dk.001*.018-026 *** --------------------------------------------------------------- DK WORK TODO/TODO - 2LK TIA Updates - 1st of 2. TODO Color Clocks: 33 x192/4 = 33 x48 = 1,584 TODO ROM Bytes: 7 --------------------------------------------------------------- TODO a5da lda ORAM_ENAMx (3)x3 @ dk.001*.STD 851d sta ENAM0_02 (3)x3 @ dk.001*.STD *** 4a lsr (2)x3 @ dk.001*.STD 851e sta ENAM1_02 (3)x3 @ dk.001*.STD *** --------------------------------------------------------------- DK WORK 5/18 - 4LK Preloads (part 1 of 3). Color Clocks: 51 x192/4 = 51 x48 = 2,448 ROM Bytes: 12 --------------------------------------------------------------- TODO This is temporary test code. TODO splice ORAM_ENABL and ORAM_PF0 together into ORAM_PF0_BL a6d6 ldx ORAM_PF_ROW (3)x3 @ dk.001*.027-035 bd4013 lda TAB_PF0,X (4!)x3 @ dk.001*.036-047 85d3 sta ORAM_PF0 (3)x3 @ dk.001*.048-056 bd7013 lda TAB_PF1,X (4!)x3 @ dk.001*.057-068 85d4 sta ORAM_PF1 (3)x3 @ dk.001*.069-077 --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 15 x192/4 = 15 x48 = 720 ROM Bytes: 3 --------------------------------------------------------------- 04ea skb (3)x3 @ dk.001*.078-086 ea (2)x3 @ dk.001*.087-092 --------------------------------------------------------------- DK WORK 6/18 - Decrement Active Scanline countdown counter. Color Clocks: 6 x192/4 = 6 x48 = 288 ROM Bytes: 1 --------------------------------------------------------------- 88 dey (2)x3 @ dk.001*.093-098 --------------------------------------------------------------- DK WORK 7/18 - Preloads for 3rd of 4 1LK TIA Updates. Color Clocks: 129 x192/4 = 129 x48 = 6,192 ROM Bytes: 28 --------------------------------------------------------------- 98 tya (2)x3 @ dk.001*.099-104 N.B. clc rather than sec. 18 clc (2)x3 @ dk.001*.105-110 e587 sbc SRAM_P0_Y (3)x3 @ dk.001*.111-119 c5a7 cmp CRAM_P0_HEIGHT (3)x3 @ dk.001*.120-128 aa tax (2)x3 @ dk.001*.129-134 a900 lda #$00 (2)x3 @ dk.001*.135-140 e900 sbc #$00 (2)x3 @ dk.001*.141-146 35a9 and CRAM_GRP0_ROWS,X (4)x3 @ dk.001*.147-158 85d2 sta ORAM_GRP0 (3)x3 @ dk.001*.159-167 98 tya (2)x3 @ dk.001*.168-173 N.B. clc rather than sec. 18 clc (2)x3 @ dk.001*.174-179 e589 sbc SRAM_P1_Y (3)x3 @ dk.001*.180-188 c5b3 cmp CRAM_P1_HEIGHT (3)x3 @ dk.001*.189-197 aa tax (2)x3 @ dk.001*.198-203 a900 lda #$00 (2)x3 @ dk.001*.204-209 e900 sbc #$00 (2)x3 @ dk.001*.210-215 35b5 and CRAM_GRP1_ROWS,X (4)x3 @ dk.001*.216-227 --------------------------------------------------------------- DK WORK 8/18 - 1LK TIA Updates - 3rd of 4. Color Clocks: 27 x192/4 = 27 x48 = 1,296 ROM Bytes: 6 --------------------------------------------------------------- N.B. Assumes preloaded A register. 851c sta GRP1_ff (3)x3 @ dk.002*.000-008 *** a5d2 lda ORAM_GRP0 (3)x3 @ dk.002*.009-017 851b sta GRP0_ff (3)x3 @ dk.002*.018-026 *** --------------------------------------------------------------- DK WORK 9/18 - 4LK Preloads (part 2 of 3). Color Clocks: 45 x192/4 = 45 x48 = 2,160 ROM Bytes: 9 --------------------------------------------------------------- TODO This is temporary test code. a6d6 ldx ORAM_PF_ROW (3)x3 @ dk.002*.027-035 bda013 lda TAB_PF2,X (4!)x3 @ dk.002*.036-047 85d5 sta ORAM_PF2 (3)x3 @ dk.002*.048-056 c6d6 dec ORAM_PF_ROW (5)x3 @ dk.002*.057-071 --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 21 x192/4 = 21 x48 = 1,008 ROM Bytes: 4 --------------------------------------------------------------- eaea (4)x3 @ dk.002*.072-083 04ea skb (3)x3 @ dk.002*.084-092 --------------------------------------------------------------- DK WORK 10/18 - Decrement Active Scanline countdown counter. Color Clocks: 6 x192/4 = 6 x48 = 288 ROM Bytes: 1 --------------------------------------------------------------- 88 dey (2)x3 @ dk.002*.093-098 --------------------------------------------------------------- DK WORK 11/18 - Preloads for 4th of 4 1LK TIA Updates. Color Clocks: 129 x192/4 = 129 x48 = 6,192 ROM Bytes: 28 --------------------------------------------------------------- 98 tya (2)x3 @ dk.002*.099-104 N.B. clc rather than sec. 18 clc (2)x3 @ dk.002*.105-110 e587 sbc SRAM_P0_Y (3)x3 @ dk.002*.111-119 c5a7 cmp CRAM_P0_HEIGHT (3)x3 @ dk.002*.120-128 aa tax (2)x3 @ dk.002*.129-134 a900 lda #$00 (2)x3 @ dk.002*.135-140 e900 sbc #$00 (2)x3 @ dk.002*.141-146 35a9 and CRAM_GRP0_ROWS,X (4)x3 @ dk.002*.147-158 85d2 sta ORAM_GRP0 (3)x3 @ dk.002*.159-167 98 tya (2)x3 @ dk.002*.168-173 N.B. clc rather than sec. 18 clc (2)x3 @ dk.002*.174-179 e589 sbc SRAM_P1_Y (3)x3 @ dk.002*.180-188 c5b3 cmp CRAM_P1_HEIGHT (3)x3 @ dk.002*.189-197 aa tax (2)x3 @ dk.002*.198-203 a900 lda #$00 (2)x3 @ dk.002*.204-209 e900 sbc #$00 (2)x3 @ dk.002*.210-215 35b5 and CRAM_GRP1_ROWS,X (4)x3 @ dk.002*.216-227 --------------------------------------------------------------- DK WORK 12/18 - 1LK TIA Updates - 4th of 4. Color Clocks: 27 x192/4 = 27 x48 = 1,296 ROM Bytes: 6 --------------------------------------------------------------- N.B. Assumes preloaded A register. 851c sta GRP1_ff (3)x3 @ dk.003*.000-008 *** a5d2 lda ORAM_GRP0 (3)x3 @ dk.003*.009-017 851b sta GRP0_ff (3)x3 @ dk.003*.018-026 *** --------------------------------------------------------------- DK WORK TODO/TODO - 2LK TIA Updates - 2nd of 2. TODO Color Clocks: 33 x192/4 = 33 x48 = 1,584 TODO ROM Bytes: 7 --------------------------------------------------------------- TODO a5da lda ORAM_ENAMx (3)x3 @ dk.001*.STD 851d sta ENAM0_02 (3)x3 @ dk.001*.STD *** 4a lsr (2)x3 @ dk.001*.STD 851e sta ENAM1_02 (3)x3 @ dk.001*.STD *** --------------------------------------------------------------- DK WORK 13/18 - Decrement Active Scanline countdown counter. Color Clocks: 6 x192/4 = 6 x48 = 288 ROM Bytes: 1 --------------------------------------------------------------- 88 dey (2)x3 @ dk.003*.027-032 --------------------------------------------------------------- DK WORK 14/18 - Exit DK loop when Active Scanline Countdown counter reaches 0. Color Clocks: 6 x192/4 + 3 = 6 x48 + 3 = 291 ROM Bytes: 2 --------------------------------------------------------------- f02c beq +44 EXIT_DK_LOOP (3!)x3 @ dk.191.033-041 (2)x3 @ dk.003*.033-038 --------------------------------------------------------------- DK WORK 15/18 - 4LK Preloads (part 3 of 3). Color Clocks: 42 x(192/4 -1) = 42 x47 = 1,974 ROM Bytes: 11 --------------------------------------------------------------- TODO This is temporary test code. TODO splice ORAM_ENABL and ORAM_PF0 together into ORAM_PF0_BL ORAM_ENABL = -(Y==CRAM_VANE_BL_Y) 98 tya (2)x3 @ dk.003*.039-044 45c3 eor CRAM_VANE_BL_Y (3)x3 @ dk.003*.045-053 c901 cmp #$01 (2)x3 @ dk.003*.054-059 a900 lda #$00 (2)x3 @ dk.003*.060-065 e900 sbc #$00 (2)x3 @ dk.003*.066-071 85d7 sta ORAM_ENABL (3)x3 @ dk.003*.072-080 --------------------------------------------------------------- DK WORK 16/18 - Preloads for 1st of 4 1LK TIA Updates. (N.B. 1st of the *next* group of 4). Color Clocks: 132 x(192/4 -1) = 132 x47 = 6,204 ROM Bytes: 29 --------------------------------------------------------------- 98 tya (2)x3 @ dk.003*.081-086 N.B. clc rather than sec. 18 clc (2)x3 @ dk.003*.087-092 e587 sbc SRAM_P0_Y (3)x3 @ dk.003*.093-101 c5a7 cmp CRAM_P0_HEIGHT (3)x3 @ dk.003*.102-110 aa tax (2)x3 @ dk.003*.111-116 a900 lda #$00 (2)x3 @ dk.003*.117-122 e900 sbc #$00 (2)x3 @ dk.003*.123-128 35a9 and CRAM_GRP0_ROWS,X (4)x3 @ dk.003*.129-140 N.B. Using sta.w instead of sta because we need to burn an extra 3 cc before we reach jump to DK. (85d2 sta ORAM_GRP0 (3)x3 @ dk.003*.141-149) 8dd200 sta.w ORAM_GRP0 (4)x3 @ dk.003*.141-152 98 tya (2)x3 @ dk.003*.153-158 N.B. clc rather than sec. 18 clc (2)x3 @ dk.003*.159-164 e589 sbc SRAM_P1_Y (3)x3 @ dk.003*.165-173 c5b3 cmp CRAM_P1_HEIGHT (3)x3 @ dk.003*.174-182 aa tax (2)x3 @ dk.003*.183-188 a900 lda #$00 (2)x3 @ dk.003*.189-194 e900 sbc #$00 (2)x3 @ dk.003*.195-200 35b5 and CRAM_GRP1_ROWS,X (4)x3 @ dk.003*.201-212 --------------------------------------------------------------- DK WORK 17/18 - Decrement Active Scanline countdown counter. Color Clocks: 6 x(192/4 -1) = 6 x47 = 282 ROM Bytes: 1 --------------------------------------------------------------- 88 dey (2)x3 @ dk.003*.213-218 --------------------------------------------------------------- DK WORK 18/18 - Loop to process the next scanline group. Color Clocks: 9 x(192/4 -1) = 9 x47 = 423 ROM Bytes: 3 --------------------------------------------------------------- 4c1e19 jmp DK (3)x3 @ dk.003*.219-227 EXIT_DK_LOOP: --------------------------------------------------------------- IDLING We can replace these idle cycles with useful work as needed. Color Clocks: 162 ROM Bytes: 27 --------------------------------------------------------------- eaeaeaeaeaeaeaeaea (18)x3 @ dk.191.042-095 eaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea (36)x3 @ dk.191.096-203 --------------------------------------------------------------- FRAME OVERHEAD 5/5 - Loop back to VBI trigger. Color Clocks: 9 ROM Bytes: 3 --------------------------------------------------------------- 4c6114 jmp VBI_TRIGGER (3)x3 @ dk.191.204-212 =============================================================== =============> MAINLINE PROCESSING -- ENDS HERE <============== =============================================================== ==================> RESOURCES -- START HERE <================== =============================================================== | | ROM Bytes: $1a05-1fff [1,531] +============================================================== --------------------------------------------------------------- UNUSED ROM We can replace unused ROM with useful data or code as needed. ROM Bytes: 1,527 --------------------------------------------------------------- (iced coffee for babes) 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4babe5 1cedc0ffee4babe51cedc0ffee4babe51cedc0ffee4bab --------------------------------------------------------------- The Reset Vector. ROM Bytes: $1ffc-1ffd [2] --------------------------------------------------------------- f813 RES Vector (relocatable) [N.B. top 3 bits IGNORED] --------------------------------------------------------------- The Break Vector (unused at the moment). We can replace unused ROM with useful data or code as needed. ROM Bytes: $1ffe-1fff [2] --------------------------------------------------------------- 1ced BRK Vector (relocatable) [N.B. top 3 bits IGNORED] =============================================================== ===================> RESOURCES -- END HERE <=================== =============================================================== ====================> 4k ROM -- ENDS HERE <==================== =============================================================== EOF