From a292f62843fea72270d239aec00d2d630db1f23d Mon Sep 17 00:00:00 2001 From: Joerg Deckert Date: Sat, 3 May 2014 18:12:00 +0200 Subject: [PATCH] Boulderdash correction (charsets ans line andings), use only one tv driver code --- make.sh | 10 +- .../bellatrix/Boulderdash_Tile_TV.spin | 607 ++- source/boulder/bellatrix/Game_controller.spin | 77 +- source/boulder/bellatrix/Keyboard.spin | 737 +++- source/boulder/bellatrix/RealRandom.spin | 147 +- source/boulder/bellatrix/Scroller.spin | 1333 +++++- source/boulder/bellatrix/Status.spin | 221 +- source/boulder/bellatrix/bd_ntsc.spin | 3812 ----------------- .../bellatrix/{bd_pal.spin => bd_tv.spin} | 8 +- source/shoot/bellatrix/_readme_.txt | 23 - source/stracker/bellatrix/stkeyb.spin | 738 ---- source/stracker/bellatrix/stmouse.spin | 470 -- source/stracker/bellatrix/stvga.spin | 543 --- 13 files changed, 3127 insertions(+), 5599 deletions(-) delete mode 100644 source/boulder/bellatrix/bd_ntsc.spin rename source/boulder/bellatrix/{bd_pal.spin => bd_tv.spin} (99%) delete mode 100644 source/shoot/bellatrix/_readme_.txt delete mode 100644 source/stracker/bellatrix/stkeyb.spin delete mode 100644 source/stracker/bellatrix/stmouse.spin delete mode 100644 source/stracker/bellatrix/stvga.spin diff --git a/make.sh b/make.sh index 6c64350..a24f126 100755 --- a/make.sh +++ b/make.sh @@ -40,10 +40,10 @@ cp -r sounds/* ${sdsnd} ${BSTC} -L ${libpath} ${D} -b -O a source/3dmulti/3dmulti.spin mv 3dmulti.binary "${sdtbox}/demo/3dmulti.bel" -${BSTC} -L ${libpath} ${D} -b -O a source/boulder/bellatrix/bd_pal.spin -${BSTC} -L ${libpath} ${D} -b -O a source/boulder/bellatrix/bd_ntsc.spin -mv bd_pal.binary "${sdtbox}/boulder/bd_pal.bin" -mv bd_ntsc.binary "${sdtbox}/boulder/bd_ntsc.bin" +${BSTC} -L ${libpath} ${D} -D __TV_NTSC -b -O a source/boulder/bellatrix/bd_tv.spin +mv bd_tv.binary "${sdtbox}/boulder/bd_ntsc.bel" +${BSTC} -L ${libpath} ${D} -D __TV_PAL -b -O a source/boulder/bellatrix/bd_tv.spin +mv bd_tv.binary "${sdtbox}/boulder/bd_pal.bel" ${BSTC} -L ${libpath} ${D} -b -O a source/boulder/regnatix/bd.spin mv bd.binary "${sdtbox}/boulder/bd.bin" cp source/boulder/musik/bd.wav "${sdtbox}/boulder/" @@ -58,7 +58,7 @@ ${BSTC} -L ${libpath} ${D} -b -O a source/vecdem/vecdem.spin mv vecdem.binary "${sdtbox}/demo/vecdem.bel" ${BSTC} -L ${libpath} ${D} -b -O a source/stracker/bellatrix/stint.spin -cp stint.binary "${sdsnd}/hss/stint.bin" +cp stint.binary "${sdsnd}/hss/stint.bel" mv stint.binary "${sdtbox}/stracker/stint.bel" ${BSTC} -L ${libpath} ${D} -b -O a source/stracker/regnatix/stplay.spin cp stplay.binary "${sdsnd}/hss/stplay.bin" diff --git a/source/boulder/bellatrix/Boulderdash_Tile_TV.spin b/source/boulder/bellatrix/Boulderdash_Tile_TV.spin index d71bb49..8407a8b 100644 --- a/source/boulder/bellatrix/Boulderdash_Tile_TV.spin +++ b/source/boulder/bellatrix/Boulderdash_Tile_TV.spin @@ -1 +1,606 @@ -'' 2-bit paletted tile-based video driver'' Based on the NTSC Spectrum-like TV Video Driver'' ──────────────────────────────────────────────────────────────────────────────────'' Version story:'''' 2007-11-25 2.0 Tiled Version (Spork Frog)'' 2007-12-05 1.0 First version (José Luis Cebrián)'' 2009-11-12 Halved tile horizontal resolution (Héctor Peraza)'' to eliminate redundant pixel pairs'' (BoulderDash uses 8x16 tiles).'' This also halves tile memory requirements.'' Fixed vertical sync pulse generation.'' 2009-11-13 Changed pixel clock settings (Héctor Peraza)'' in order to display 20 tiles per line,'' as in the classic C64 BoulderDash.'' 2009-11-14 Reverse pixel order before waitvid (Héctor Peraza)'' to avoid having to define mirrored tiles.'' 2009-11-15 Added an optional status line. (Héctor Peraza)'' 2009-11-17 Video config parameters can be passed (Héctor Peraza)'' on driver startup, to allow for different'' configurations and/or platforms.'' 2009-11-18 Implemented PAL mode. Color seems to (Héctor Peraza)'' be a bit off in PAL mode.'' 2009-12-05 Added the possibilty to halve tile (Héctor Peraza)'' height (we need that for the title screen,'' since it has text on the bottom part'' and characters are half-size)'' '' ──────────────────────────────────────────────────────────────────────────────────'' This code is in the public domain. Feel free to use it in any way you like.'''' The screen for this driver is composed of two major parts:'''' 1. Tile map'' Each of these entries is 1 byte long, representing the tile number.'' There are 880 words total for a 40 by 22 tile screen. The displayed'' area is 20 x 12 in NTSC mode, 20 x 14 in PAL mode.'''' 2. Tiles'' Each tile is made up of 16 words with 2 bit color encoding on'' each tile. You can define as few or as many tiles as you want,'' but be sure not to use any tiles that you don't define.'''' There is also an optional status line at the top of the screen that does not'' scroll with the rest. It is also composed of tiles, but these are only 8 pixels'' high. Two empty raster lines separate the status from the main screen. The'' foreground color can be set per character basis. '''' 80Mhz is *required* in order to output pixels fast enough.CON ' Border offset, to center the image HorizBorderOffset = 9 ' positive values move the screen to the right VertBorderOffset = 10 ' positive values move the screen down ' Counter Module Configuration ' • CTRMode - Operating mode (0001 for Video Mode) ' • PLLDiv - Divisor for the VCO frequency (111: use VCO value as-is) '┌─────────── CTRMode '│ ┌───── PLLDiv CTRA_TVGEN = %00001_111 ' NTSC Color frequency in Hz ' ' This is the 'base' clock rate for all our NTSC timings. At start, the ' driver will program the FRQA register to output at this rate. Our base ' clock value is 1/16 of the NTSC clock rate, or approximately 0.01746 µs. NTSC_ClockFreq = 3_579_545 ' NTSC Timings table ' Time Clocks Output ' Total horizontal timing: 63.5 µs 3638 ' Horizontal blanking period: 10.9 µs 624 ' Front porch: 1.5 µs 86 * Black ($02) ' Synchronizing pulse: 4.7 µs 269 * Blank ($00) ' Back porch: 4.7 µs 269 ' Breeze away: 0.6 µs 34 * Black ($02) ' Colour burst: 2.5 µs 144 * Y Hue ($8A) ' Wait to data: 1.6 µs 92 * Black ($02) ' Visible line 52.6 µs 3008 ' Left border 2.5 µs 146 * Black ($00) ' Pixel data 47.5 µs 2720 ' Character (x20) 2.4 µs 136 * Data ' Right border 2.6 µs 146 * Black ($00) ' Half visible line ¹ 20.8 µs 1195 ' ' Lines marked with * are the actual parts of a visible line as sent to the TV. ' ' ¹ The vertical sync pulse is a series of half lines with inverted horizontal sync ' pulses (the so-called equalization pulses). These half lines should have a length ' of 3638/2 = 1819 clocks (that is, a 624-clocks HSync followed by about 1195 clocks ' of visible data). VSCL_NTSC_FrontPorch = 85 VSCL_NTSC_SynchronizingPulse = 270 VSCL_NTSC_BackPorch = 34 + 144 + 92 VSCL_NTSC_BreezeAway = 34 VSCL_NTSC_ColourBurst = 144 VSCL_NTSC_WaitToData = 92 VSCL_NTSC_VisibleLine = 3008 VSCL_NTSC_HalfLine = 1192 ' NTSC Half line VSCL_NTSC_LeftBorder = 146 + HorizBorderOffset VSCL_NTSC_RightBorder = 146 - HorizBorderOffset VSCL_NTSC_Character = (17 << 12) + 136 ' Eight double-width pixels NTSC_VerticalLines = 262 - 9 NTSC_TopLine = (NTSC_VerticalLines + 192) / 2 - VertBorderOffset NTSC_BottomLine = (NTSC_VerticalLines - 192) / 2 - VertBorderOffset ' PAL Color frequency in Hz ' ' This is the 'base' clock rate for all the PAL timings. At start, the ' driver will program the FRQA register to output at this rate. Our base ' clock value is 1/16 of the PAL clock rate, or approximately 0.014097 µs PAL_ClockFreq = 4_433_618 ' PAL Timings table ' Time Clocks Output ' Total horizontal timing: 64.0 µs 4540 ' Horizontal blanking period: 12.0 µs 851 ' Front porch: 1.6 µs 113 * Black ($02) ' Synchronizing pulse: 4.7 µs 333 * Blank ($00) ' Back porch: 5.7 µs 404 ' Breeze away: 0.9 µs 64 * Black ($02) ' Colour burst: 2.3 µs 160 * Y Hue ($8A) ' Wait to data: 2.5 µs 180 * Black ($02) ' Visible line 52.0 µs 3689 ' Left border 3.4 µs 244 * Black ($00) ' Pixel data 45.1 µs 3200 ' Character (x20) 2.3 µs 160 * Data ' Right border 3.4 µs 245 * Black ($00) ' Half visible line ¹ 20.0 µs 1419 ' ' Lines marked with * are the actual parts of a visible line as sent to the TV. ' ' ¹ The vertical sync pulse is a series of half lines with inverted horizontal sync ' pulses (the so-called equalization pulses). These half lines should have a length ' of 4540/2 = 2270 clocks (that is, a 851-clocks HSync followed by about 1419 clocks ' of visible data). VSCL_PAL_FrontPorch = 114 VSCL_PAL_SynchronizingPulse = 332 VSCL_PAL_BackPorch = 64 + 160 + 180 VSCL_PAL_BreezeAway = 64 VSCL_PAL_ColourBurst = 160 VSCL_PAL_WaitToData = 180 VSCL_PAL_VisibleLine = 3689 VSCL_PAL_HalfLine = 1419 ' PAL Half line VSCL_PAL_LeftBorder = 244 + HorizBorderOffset VSCL_PAL_RightBorder = 245 - HorizBorderOffset VSCL_PAL_Character = (20 << 12) + 160 ' Eight double-width pixels PAL_VerticalLines = 312 - 9 PAL_TopLine = (PAL_VerticalLines + 224) / 2 - VertBorderOffset PAL_BottomLine = (PAL_VerticalLines - 224) / 2 - VertBorderOffset PUB Start(vParam)'' Starts the TV driver and begins the output of NTSC video.'' Uses a Cog.'''' Parameters:'' vParam → Array with video parameters:'' [0] → VCFG mode'' [1] → Pingroup for VCFG pins'' [2] → Pinmask for VCFG pins'' [3] → Pinmask for output pins'' [4] → Color standard: 0 = NTSC, 1 = PAL'' [5] → Tile map address'' [6] → Address of a vsync flag byte in HUB memory cognew(@Entry, vParam) DAT org $000 Entry jmp #StartDriver ' ───────────────────────────────────────── ' Data section ' ───────────────────────────────────────── ' Colors used in waitvid COLOR_SYNC long $00 ' Sync level is below black COLOR_BLACK long $02 COLOR_YHUE_NTSC long $8A ' NTSC color burst COLOR_YHUE_PAL_1 long $7A ' PAL swinging color burst COLOR_YHUE_PAL_2 long $AA ' " " " " COLOR_BORDER long $02 ' Black border ' The following constants are too big to use in-place, so we need to ' reserve some registers to put them here _ScreenSize long 40 * 28 ' Tile map size _NTSC_ClockFreq long NTSC_ClockFreq _VSCL_NTSC_Character long VSCL_NTSC_Character _VSCL_NTSC_VisibleLine long VSCL_NTSC_VisibleLine _VSCL_NTSC_HalfLine long VSCL_NTSC_HalfLine _PAL_ClockFreq long PAL_ClockFreq _VSCL_PAL_Character long VSCL_PAL_Character _VSCL_PAL_VisibleLine long VSCL_PAL_VisibleLine _VSCL_PAL_HalfLine long VSCL_PAL_HalfLine ' Other constants TrueWord long $FFFF ' ───────────────────────────────────────── ' Code section ' ─────────────────────────────────────────StartDriver ' Configure the Cog generators mov R0, PAR rdlong _VCFG_Mode, R0 add R0, #4 rdlong _VCFG_PinGroup, R0 add R0, #4 rdlong _VCFG_PinMask, R0 add R0, #4 rdlong _PortMask, R0 add R0, #4 rdlong VideoMode, R0 add R0, #4 rdlong ScreenPtr, R0 add R0, #4 rdlong VSyncPtr, R0 test VideoMode, #1 wz if_z mov _ClockFreq, _NTSC_ClockFreq if_nz mov _ClockFreq, _PAL_ClockFreq if_z mov _VSCL_Character, _VSCL_NTSC_Character if_nz mov _VSCL_Character, _VSCL_PAL_Character if_z mov _VSCL_VisibleLine, _VSCL_NTSC_VisibleLine if_nz mov _VSCL_VisibleLine, _VSCL_PAL_VisibleLine if_z mov _VSCL_HalfLine, _VSCL_NTSC_HalfLine if_nz mov _VSCL_HalfLine, _VSCL_PAL_HalfLine if_z mov _VSCL_LeftBorder, #VSCL_NTSC_LeftBorder if_nz mov _VSCL_LeftBorder, #VSCL_PAL_LeftBorder if_z mov _VSCL_RightBorder, #VSCL_NTSC_RightBorder if_nz mov _VSCL_RightBorder, #VSCL_PAL_RightBorder if_z mov _VSCL_FrontPorch, #VSCL_NTSC_FrontPorch if_nz mov _VSCL_FrontPorch, #VSCL_PAL_FrontPorch if_z mov _VSCL_SynchronizingPulse, #VSCL_NTSC_SynchronizingPulse if_nz mov _VSCL_SynchronizingPulse, #VSCL_PAL_SynchronizingPulse if_z mov _VSCL_BreezeAway, #VSCL_NTSC_BreezeAway if_nz mov _VSCL_BreezeAway, #VSCL_PAL_BreezeAway if_z mov _VSCL_ColourBurst, #VSCL_NTSC_ColourBurst if_nz mov _VSCL_ColourBurst, #VSCL_PAL_ColourBurst if_z mov _VSCL_BackPorch, #VSCL_NTSC_BackPorch if_nz mov _VSCL_BackPorch, #VSCL_PAL_BackPorch if_z mov _VSCL_WaitToData, #VSCL_NTSC_WaitToData if_nz mov _VSCL_WaitToData, #VSCL_PAL_WaitToData if_z mov _VerticalLines, #NTSC_VerticalLines if_nz mov _VerticalLines, #PAL_VerticalLines if_z mov _TopLine, #NTSC_TopLine if_nz mov _TopLine, #PAL_TopLine if_z mov _BottomLine, #NTSC_BottomLine if_nz mov _BottomLine, #PAL_BottomLine if_z mov _Burst1, COLOR_YHUE_NTSC if_nz mov _Burst1, COLOR_YHUE_PAL_1 if_z mov _Burst2, COLOR_YHUE_NTSC if_nz mov _Burst2, COLOR_YHUE_PAL_2 movs VCFG, _VCFG_PinMask ' VCFG'S = pinmask (pin31: 0000_0111 : pin24) movd VCFG, _VCFG_PinGroup ' VCFG'D = pingroup (grp. 3 i.e. pins 24-31) movi VCFG, _VCFG_Mode ' Baseband video on bottom nibble, 2-bit color, enable chroma on baseband or DIRA, _PortMask ' Setup the port mask for DAC access (set DAC pins to output) movi CTRA, #CTRA_TVGEN ' Setup the Counter Module Generator A mov R1, _ClockFreq ' R1 := Video Clock Frequency in Hz rdlong R2, #0 ' R2 := Current CPU Clock Frequency in Hz call #Divide ' R3 := R1÷R2 (fractional part) mov FRQA, R3 ' Setup the Counter Module Generator frequency mov phaseflip, #0 ' Frame loop :Frame mov LineCounter, _VerticalLines ' LineCounter := Number of vertical lines mov CharacterRows, #0 ' Copy the screen parameters to local variables in Cog memory mov AttribPtr, ScreenPtr mov TilePtr, AttribPtr add TilePtr, _ScreenSize rdlong COLORS, TilePtr add TilePtr, #4 rdlong OffsetX, TilePtr mov OffsetY, OffsetX shr OffsetX, #16 and OffsetY, TrueWord add TilePtr, #4 rdlong Status, TilePtr add TilePtr, #4 mov StatusPtr, TilePtr add TilePtr, #20*2 ' Y Offset Calculations mov R0, OffsetY test Status, #2 wz if_z and OffsetY, #%1111 if_nz and OffsetY, #%111 shl OffsetY, #1 mov CharacterRows, OffsetY if_z shr R0, #4 if_nz shr R0, #3 add R0, #1:AddLoop add AttribPtr, #40 djnz R0, #:AddLoop sub AttribPtr, #40 ' X Offset Calculations mov R0, OffsetX and OffsetX, #%111 shl OffsetX, #1 mov R5, #16 sub R5, OffsetX shr R0, #3 add AttribPtr, R0 ' Status Line row count mov R6, #0 ' Visible line loop:ScanLine call #HSync ' Check if the current line is in the top or bottom border cmp LineCounter, _BottomLine wc if_c jmp #:EmptyLine cmp LineCounter, _TopLine wc if_nc jmp #:CheckStat jmp #:DataLine:CheckStat test Status, #1 wz if_z jmp #:EmptyLine mov R0, _TopLine add R0, #10 cmp LineCounter, R0 wc if_nc jmp #:EmptyLine cmp R6, #16 wz if_z jmp #:EmptyLine ' Draw the status line mov VSCL, _VSCL_LeftBorder waitvid COLOR_BORDER, #0 ' Character rendering loop mov VSCL, _VSCL_Character mov R0, #20 ' R0 := Character counter (per line) mov R1, StatusPtr ' R1 := Pointer to status line mov R4, R1 add R4, R0 ' R4 := Pointer to foreground color:StatusChar rdbyte R3, R1 ' R3 := Tile description add R1, #1 ' Advance the attribute pointer for the next character shl R3, #4 ' Multiply by bitmap size to form an address add R3, R6 ' Add the row offset for each tile add R3, TilePtr ' R3 := Address of the bitmap word to read rdword PIXELS, R3 ' Set pixels to the proper data rev PIXELS, #16 ' Reverse bit order to output pixels MSB first rdbyte R3, R4 ' R3 := foreground color add R4, #1 ' Advance the color pointer for the next character mov R2, COLORS shl R2, #8 or R2, R3 ' Only foreground color is set, background remains the same from palette ror R2, #8 test VideoMode, #1 wz if_nz xor R2, phaseflip ' Flip color phase if PAL mode waitvid R2, PIXELS ' Output our video djnz R0, #:StatusChar ' and loop mov VSCL, _VSCL_RightBorder waitvid COLOR_BORDER, #0 ' Output the right border add R6, #2 djnz LineCounter, #:ScanLine ' Next line (note that here LineCounter is always > 0)' jmp #:EmptyLine ' Draw a data line:DataLine mov VSCL, _VSCL_LeftBorder waitvid COLOR_BORDER, #0 ' Output the left border ' Character rendering loop mov VSCL, _VSCL_Character mov R0, #20 ' R0 := Character counter (per line) mov R1, AttribPtr ' R1 := Pointer to attribute (tile) area:Character rdbyte R2, R1 ' R2 := Tile description long add R1, #1 ' Advance the attribute pointer for the next character test Status, #2 wz if_z shl R2, #5 ' Multiply by bitmap size to form an address if_nz shl R2, #4 add R2, CharacterRows ' Add the row offset for each tile add R2, TilePtr ' R2 := Address of the bitmap word to read rdword PIXELS, R2 ' Set pixels to the proper data cmp OffsetX, #0 wz if_z jmp #:Output shl PIXELS, OffsetX rdbyte R2, R1 test Status, #2 wz if_z shl R2, #5 ' Multiply by bitmap size to form an address if_nz shl R2, #4 add R2, CharacterRows ' Add the row offset for each tile add R2, TilePtr ' R2 := Address of the bitmap word to read rdword R3, R2 shr R3, R5 or PIXELS, R3:Output rev PIXELS, #16 ' Reverse bit order to output pixels MSB first mov R2, COLORS test VideoMode, #1 wz if_nz xor R2, phaseflip ' Flip color phase if PAL mode waitvid R2, PIXELS ' Output our video djnz R0, #:Character ' and loop mov VSCL, _VSCL_RightBorder waitvid COLOR_BORDER, #0 ' Output the right border ' Calculate the address of the next attribute line add CharacterRows, #2 test Status, #2 wz if_z mov R2, #32 if_nz mov R2, #16 cmp CharacterRows, R2 wz if_z mov CharacterRows, #0 ' Advance to the next line of attributes if the sub-character counter if_z add AttribPtr, #40 ' reaches the end of character, and reset it to 8 djnz LineCounter, #:ScanLine ' Next line (note that here LineCounter is always > 0) ' Empty (border only) lines :EmptyLine mov VSCL, _VSCL_VisibleLine ' Output an entire visible line of BORDER color waitvid COLOR_BORDER, #0 djnz LineCounter, #:ScanLine ' Next line: note that this may be the last one ' VSync mov R0, #$FF wrbyte R0, VSyncPtr test VideoMode, #1 wz if_nz xor phaseflip, phasemask call #VSyncHigh ' VSync procedure: 6 half-lines of HSync-only values (3 lines) call #VSyncLow ' 6 half-lines inverted from the previous ones (3 lines) call #VSyncHigh ' 6 half-lines more of HSync-only values (3 lines) mov R0, #0 wrbyte R0, VSyncPtr jmp #:Frame ' Next frame ' ───────────────────────────────────────── ' Synchronization subroutines ' ─────────────────────────────────────────HSync mov VSCL, _VSCL_FrontPorch waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_SynchronizingPulse waitvid COLOR_SYNC, #0 mov VSCL, _VSCL_BreezeAway waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_ColourBurst test VideoMode, #1 wz if_nz xor phaseflip, phasemask wz ' Swing color burst if PAL if_z mov R0, _Burst1 if_nz mov R0, _Burst2 waitvid R0, #0 mov VSCL, _VSCL_WaitToData waitvid COLOR_BLACK, #0HSync_Ret retVSyncHigh mov R0, #6:Loop mov VSCL, _VSCL_FrontPorch waitvid COLOR_BLACK, #0 mov R1, _VSCL_SynchronizingPulse shr R1, #1 ' Half-length pulses mov VSCL, R1 waitvid COLOR_SYNC, #0 mov VSCL, R1 waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_BackPorch ' BackPorch = BreezeAway + ColourBurst + WaitToData waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_HalfLine waitvid COLOR_BLACK, #0 djnz R0, #:LoopVSyncHigh_Ret retVSyncLow mov R0, #6:Loop mov VSCL, _VSCL_FrontPorch waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_HalfLine waitvid COLOR_SYNC, #0 mov VSCL, _VSCL_BackPorch ' BackPorch = BreezeAway + ColourBurst + WaitToData waitvid COLOR_SYNC, #0 mov VSCL, _VSCL_FrontPorch waitvid COLOR_SYNC, #0 mov R1, _VSCL_SynchronizingPulse sub R1, _VSCL_FrontPorch mov VSCL, R1' mov VSCL, _VSCL_SynchronizingPulse waitvid COLOR_BLACK, #0 djnz R0, #:Loop VSyncLow_Ret ret ' ───────────────────────────────────────── ' Utility subroutines ' ───────────────────────────────────────── ' Divide R1 by R2 and return the result in R3 with 32 bits of decimal precision ' Input: R1 → Dividend ' R2 → Divisor (it is required that R1 < R2) ' Output: R3 → (R1/R2) << 32 Divide mov R0, #33:Loop cmpsub R1, R2 wc rcl R3, #1 shl R1, #1 djnz R0, #:LoopDivide_Ret retphaseflip long $00000000phasemask long $F0F0F0F0 ' invert hue portion of color ' ───────────────────────────────────────── ' Uninitialized data ' ───────────────────────────────────────── R0 res 1 R1 res 1 R2 res 1 R3 res 1 R4 res 1 R5 res 1 R6 res 1 COLORS res 1 PIXELS res 1 _VCFG_PinMask res 1 _VCFG_PinGroup res 1 _VCFG_Mode res 1 _PortMask res 1 _ClockFreq res 1 _VSCL_Character res 1 _VSCL_VisibleLine res 1 _VSCL_HalfLine res 1 _VSCL_LeftBorder res 1 _VSCL_RightBorder res 1 _VSCL_FrontPorch res 1 _VSCL_SynchronizingPulse res 1 _VSCL_BreezeAway res 1 _VSCL_ColourBurst res 1 _VSCL_BackPorch res 1 _VSCL_WaitToData res 1 _VerticalLines res 1 _TopLine res 1 _BottomLine res 1 _Burst1 res 1 _Burst2 res 1 LineCounter res 1 CharacterRows res 1 TilePtr res 1 AttribPtr res 1 ScreenPtr res 1 StatusPtr res 1 VSyncPtr res 1 PAddr res 1 PCtr res 1 OffsetX res 1 OffsetY res 1 Status res 1 VideoMode res 1 fit \ No newline at end of file +'' 2-bit paletted tile-based video driver +'' Based on the NTSC Spectrum-like TV Video Driver +'' ────────────────────────────────────────────────────────────────────────────────── +'' Version story: +'' +'' 2007-11-25 2.0 Tiled Version (Spork Frog) +'' 2007-12-05 1.0 First version (José Luis Cebrián) +'' 2009-11-12 Halved tile horizontal resolution (Héctor Peraza) +'' to eliminate redundant pixel pairs +'' (BoulderDash uses 8x16 tiles). +'' This also halves tile memory requirements. +'' Fixed vertical sync pulse generation. +'' 2009-11-13 Changed pixel clock settings (Héctor Peraza) +'' in order to display 20 tiles per line, +'' as in the classic C64 BoulderDash. +'' 2009-11-14 Reverse pixel order before waitvid (Héctor Peraza) +'' to avoid having to define mirrored tiles. +'' 2009-11-15 Added an optional status line. (Héctor Peraza) +'' 2009-11-17 Video config parameters can be passed (Héctor Peraza) +'' on driver startup, to allow for different +'' configurations and/or platforms. +'' 2009-11-18 Implemented PAL mode. Color seems to (Héctor Peraza) +'' be a bit off in PAL mode. +'' 2009-12-05 Added the possibilty to halve tile (Héctor Peraza) +'' height (we need that for the title screen, +'' since it has text on the bottom part +'' and characters are half-size) +'' +'' ────────────────────────────────────────────────────────────────────────────────── +'' This code is in the public domain. Feel free to use it in any way you like. +'' +'' The screen for this driver is composed of two major parts: +'' +'' 1. Tile map +'' Each of these entries is 1 byte long, representing the tile number. +'' There are 880 words total for a 40 by 22 tile screen. The displayed +'' area is 20 x 12 in NTSC mode, 20 x 14 in PAL mode. +'' +'' 2. Tiles +'' Each tile is made up of 16 words with 2 bit color encoding on +'' each tile. You can define as few or as many tiles as you want, +'' but be sure not to use any tiles that you don't define. +'' +'' There is also an optional status line at the top of the screen that does not +'' scroll with the rest. It is also composed of tiles, but these are only 8 pixels +'' high. Two empty raster lines separate the status from the main screen. The +'' foreground color can be set per character basis. +'' +'' 80Mhz is *required* in order to output pixels fast enough. + +CON + + ' Border offset, to center the image + + HorizBorderOffset = 9 ' positive values move the screen to the right + VertBorderOffset = 10 ' positive values move the screen down + + ' Counter Module Configuration + + ' • CTRMode - Operating mode (0001 for Video Mode) + ' • PLLDiv - Divisor for the VCO frequency (111: use VCO value as-is) + + '┌─────────── CTRMode + '│ ┌───── PLLDiv + CTRA_TVGEN = %00001_111 + + ' NTSC Color frequency in Hz + ' + ' This is the 'base' clock rate for all our NTSC timings. At start, the + ' driver will program the FRQA register to output at this rate. Our base + ' clock value is 1/16 of the NTSC clock rate, or approximately 0.01746 µs. + + NTSC_ClockFreq = 3_579_545 + + ' NTSC Timings table + ' Time Clocks Output + ' Total horizontal timing: 63.5 µs 3638 + ' Horizontal blanking period: 10.9 µs 624 + ' Front porch: 1.5 µs 86 * Black ($02) + ' Synchronizing pulse: 4.7 µs 269 * Blank ($00) + ' Back porch: 4.7 µs 269 + ' Breeze away: 0.6 µs 34 * Black ($02) + ' Colour burst: 2.5 µs 144 * Y Hue ($8A) + ' Wait to data: 1.6 µs 92 * Black ($02) + ' Visible line 52.6 µs 3008 + ' Left border 2.5 µs 146 * Black ($00) + ' Pixel data 47.5 µs 2720 + ' Character (x20) 2.4 µs 136 * Data + ' Right border 2.6 µs 146 * Black ($00) + ' Half visible line ¹ 20.8 µs 1195 + ' + ' Lines marked with * are the actual parts of a visible line as sent to the TV. + ' + ' ¹ The vertical sync pulse is a series of half lines with inverted horizontal sync + ' pulses (the so-called equalization pulses). These half lines should have a length + ' of 3638/2 = 1819 clocks (that is, a 624-clocks HSync followed by about 1195 clocks + ' of visible data). + + VSCL_NTSC_FrontPorch = 85 + VSCL_NTSC_SynchronizingPulse = 270 + VSCL_NTSC_BackPorch = 34 + 144 + 92 + VSCL_NTSC_BreezeAway = 34 + VSCL_NTSC_ColourBurst = 144 + VSCL_NTSC_WaitToData = 92 + VSCL_NTSC_VisibleLine = 3008 + VSCL_NTSC_HalfLine = 1192 ' NTSC Half line + VSCL_NTSC_LeftBorder = 146 + HorizBorderOffset + VSCL_NTSC_RightBorder = 146 - HorizBorderOffset + VSCL_NTSC_Character = (17 << 12) + 136 ' Eight double-width pixels + + NTSC_VerticalLines = 262 - 9 + NTSC_TopLine = (NTSC_VerticalLines + 192) / 2 - VertBorderOffset + NTSC_BottomLine = (NTSC_VerticalLines - 192) / 2 - VertBorderOffset + + ' PAL Color frequency in Hz + ' + ' This is the 'base' clock rate for all the PAL timings. At start, the + ' driver will program the FRQA register to output at this rate. Our base + ' clock value is 1/16 of the PAL clock rate, or approximately 0.014097 µs + + PAL_ClockFreq = 4_433_618 + + ' PAL Timings table + ' Time Clocks Output + ' Total horizontal timing: 64.0 µs 4540 + ' Horizontal blanking period: 12.0 µs 851 + ' Front porch: 1.6 µs 113 * Black ($02) + ' Synchronizing pulse: 4.7 µs 333 * Blank ($00) + ' Back porch: 5.7 µs 404 + ' Breeze away: 0.9 µs 64 * Black ($02) + ' Colour burst: 2.3 µs 160 * Y Hue ($8A) + ' Wait to data: 2.5 µs 180 * Black ($02) + ' Visible line 52.0 µs 3689 + ' Left border 3.4 µs 244 * Black ($00) + ' Pixel data 45.1 µs 3200 + ' Character (x20) 2.3 µs 160 * Data + ' Right border 3.4 µs 245 * Black ($00) + ' Half visible line ¹ 20.0 µs 1419 + ' + ' Lines marked with * are the actual parts of a visible line as sent to the TV. + ' + ' ¹ The vertical sync pulse is a series of half lines with inverted horizontal sync + ' pulses (the so-called equalization pulses). These half lines should have a length + ' of 4540/2 = 2270 clocks (that is, a 851-clocks HSync followed by about 1419 clocks + ' of visible data). + + VSCL_PAL_FrontPorch = 114 + VSCL_PAL_SynchronizingPulse = 332 + VSCL_PAL_BackPorch = 64 + 160 + 180 + VSCL_PAL_BreezeAway = 64 + VSCL_PAL_ColourBurst = 160 + VSCL_PAL_WaitToData = 180 + VSCL_PAL_VisibleLine = 3689 + VSCL_PAL_HalfLine = 1419 ' PAL Half line + VSCL_PAL_LeftBorder = 244 + HorizBorderOffset + VSCL_PAL_RightBorder = 245 - HorizBorderOffset + VSCL_PAL_Character = (20 << 12) + 160 ' Eight double-width pixels + + PAL_VerticalLines = 312 - 9 + PAL_TopLine = (PAL_VerticalLines + 224) / 2 - VertBorderOffset + PAL_BottomLine = (PAL_VerticalLines - 224) / 2 - VertBorderOffset + +PUB Start(vParam) +'' Starts the TV driver and begins the output of NTSC video. +'' Uses a Cog. +'' +'' Parameters: +'' vParam → Array with video parameters: +'' [0] → VCFG mode +'' [1] → Pingroup for VCFG pins +'' [2] → Pinmask for VCFG pins +'' [3] → Pinmask for output pins +'' [4] → Color standard: 0 = NTSC, 1 = PAL +'' [5] → Tile map address +'' [6] → Address of a vsync flag byte in HUB memory + + cognew(@Entry, vParam) + +DAT + + org $000 + +Entry jmp #StartDriver + + ' ───────────────────────────────────────── + ' Data section + ' ───────────────────────────────────────── + + ' Colors used in waitvid + + COLOR_SYNC long $00 ' Sync level is below black + COLOR_BLACK long $02 + COLOR_YHUE_NTSC long $8A ' NTSC color burst + COLOR_YHUE_PAL_1 long $7A ' PAL swinging color burst + COLOR_YHUE_PAL_2 long $AA ' " " " " + COLOR_BORDER long $02 ' Black border + + ' The following constants are too big to use in-place, so we need to + ' reserve some registers to put them here + + _ScreenSize long 40 * 28 ' Tile map size + + _NTSC_ClockFreq long NTSC_ClockFreq + _VSCL_NTSC_Character long VSCL_NTSC_Character + _VSCL_NTSC_VisibleLine long VSCL_NTSC_VisibleLine + _VSCL_NTSC_HalfLine long VSCL_NTSC_HalfLine + + _PAL_ClockFreq long PAL_ClockFreq + _VSCL_PAL_Character long VSCL_PAL_Character + _VSCL_PAL_VisibleLine long VSCL_PAL_VisibleLine + _VSCL_PAL_HalfLine long VSCL_PAL_HalfLine + + ' Other constants + + TrueWord long $FFFF + + ' ───────────────────────────────────────── + ' Code section + ' ───────────────────────────────────────── + +StartDriver + + ' Configure the Cog generators + + mov R0, PAR + rdlong _VCFG_Mode, R0 + add R0, #4 + rdlong _VCFG_PinGroup, R0 + add R0, #4 + rdlong _VCFG_PinMask, R0 + add R0, #4 + rdlong _PortMask, R0 + add R0, #4 + rdlong VideoMode, R0 + add R0, #4 + rdlong ScreenPtr, R0 + add R0, #4 + rdlong VSyncPtr, R0 + + test VideoMode, #1 wz + if_z mov _ClockFreq, _NTSC_ClockFreq + if_nz mov _ClockFreq, _PAL_ClockFreq + if_z mov _VSCL_Character, _VSCL_NTSC_Character + if_nz mov _VSCL_Character, _VSCL_PAL_Character + if_z mov _VSCL_VisibleLine, _VSCL_NTSC_VisibleLine + if_nz mov _VSCL_VisibleLine, _VSCL_PAL_VisibleLine + if_z mov _VSCL_HalfLine, _VSCL_NTSC_HalfLine + if_nz mov _VSCL_HalfLine, _VSCL_PAL_HalfLine + if_z mov _VSCL_LeftBorder, #VSCL_NTSC_LeftBorder + if_nz mov _VSCL_LeftBorder, #VSCL_PAL_LeftBorder + if_z mov _VSCL_RightBorder, #VSCL_NTSC_RightBorder + if_nz mov _VSCL_RightBorder, #VSCL_PAL_RightBorder + if_z mov _VSCL_FrontPorch, #VSCL_NTSC_FrontPorch + if_nz mov _VSCL_FrontPorch, #VSCL_PAL_FrontPorch + if_z mov _VSCL_SynchronizingPulse, #VSCL_NTSC_SynchronizingPulse + if_nz mov _VSCL_SynchronizingPulse, #VSCL_PAL_SynchronizingPulse + if_z mov _VSCL_BreezeAway, #VSCL_NTSC_BreezeAway + if_nz mov _VSCL_BreezeAway, #VSCL_PAL_BreezeAway + if_z mov _VSCL_ColourBurst, #VSCL_NTSC_ColourBurst + if_nz mov _VSCL_ColourBurst, #VSCL_PAL_ColourBurst + if_z mov _VSCL_BackPorch, #VSCL_NTSC_BackPorch + if_nz mov _VSCL_BackPorch, #VSCL_PAL_BackPorch + if_z mov _VSCL_WaitToData, #VSCL_NTSC_WaitToData + if_nz mov _VSCL_WaitToData, #VSCL_PAL_WaitToData + if_z mov _VerticalLines, #NTSC_VerticalLines + if_nz mov _VerticalLines, #PAL_VerticalLines + if_z mov _TopLine, #NTSC_TopLine + if_nz mov _TopLine, #PAL_TopLine + if_z mov _BottomLine, #NTSC_BottomLine + if_nz mov _BottomLine, #PAL_BottomLine + if_z mov _Burst1, COLOR_YHUE_NTSC + if_nz mov _Burst1, COLOR_YHUE_PAL_1 + if_z mov _Burst2, COLOR_YHUE_NTSC + if_nz mov _Burst2, COLOR_YHUE_PAL_2 + + movs VCFG, _VCFG_PinMask ' VCFG'S = pinmask (pin31: 0000_0111 : pin24) + movd VCFG, _VCFG_PinGroup ' VCFG'D = pingroup (grp. 3 i.e. pins 24-31) + movi VCFG, _VCFG_Mode ' Baseband video on bottom nibble, 2-bit color, enable chroma on baseband + or DIRA, _PortMask ' Setup the port mask for DAC access (set DAC pins to output) + + movi CTRA, #CTRA_TVGEN ' Setup the Counter Module Generator A + mov R1, _ClockFreq ' R1 := Video Clock Frequency in Hz + rdlong R2, #0 ' R2 := Current CPU Clock Frequency in Hz + call #Divide ' R3 := R1÷R2 (fractional part) + mov FRQA, R3 ' Setup the Counter Module Generator frequency + + mov phaseflip, #0 + + ' Frame loop + +:Frame + mov LineCounter, _VerticalLines ' LineCounter := Number of vertical lines + mov CharacterRows, #0 + + ' Copy the screen parameters to local variables in Cog memory + + mov AttribPtr, ScreenPtr + mov TilePtr, AttribPtr + add TilePtr, _ScreenSize + rdlong COLORS, TilePtr + add TilePtr, #4 + rdlong OffsetX, TilePtr + mov OffsetY, OffsetX + shr OffsetX, #16 + and OffsetY, TrueWord + add TilePtr, #4 + rdlong Status, TilePtr + add TilePtr, #4 + mov StatusPtr, TilePtr + add TilePtr, #20*2 + + ' Y Offset Calculations + + mov R0, OffsetY + test Status, #2 wz + if_z and OffsetY, #%1111 + if_nz and OffsetY, #%111 + shl OffsetY, #1 + mov CharacterRows, OffsetY + if_z shr R0, #4 + if_nz shr R0, #3 + add R0, #1 +:AddLoop add AttribPtr, #40 + djnz R0, #:AddLoop + sub AttribPtr, #40 + + ' X Offset Calculations + + mov R0, OffsetX + and OffsetX, #%111 + shl OffsetX, #1 + mov R5, #16 + sub R5, OffsetX + shr R0, #3 + add AttribPtr, R0 + + ' Status Line row count + + mov R6, #0 + + ' Visible line loop + +:ScanLine call #HSync + + ' Check if the current line is in the top or bottom border + + cmp LineCounter, _BottomLine wc + if_c jmp #:EmptyLine + cmp LineCounter, _TopLine wc + if_nc jmp #:CheckStat + jmp #:DataLine + +:CheckStat test Status, #1 wz + if_z jmp #:EmptyLine + mov R0, _TopLine + add R0, #10 + cmp LineCounter, R0 wc + if_nc jmp #:EmptyLine + cmp R6, #16 wz + if_z jmp #:EmptyLine + + ' Draw the status line + + mov VSCL, _VSCL_LeftBorder + waitvid COLOR_BORDER, #0 + + ' Character rendering loop + + mov VSCL, _VSCL_Character + mov R0, #20 ' R0 := Character counter (per line) + mov R1, StatusPtr ' R1 := Pointer to status line + mov R4, R1 + add R4, R0 ' R4 := Pointer to foreground color +:StatusChar rdbyte R3, R1 ' R3 := Tile description + add R1, #1 ' Advance the attribute pointer for the next character + shl R3, #4 ' Multiply by bitmap size to form an address + add R3, R6 ' Add the row offset for each tile + add R3, TilePtr ' R3 := Address of the bitmap word to read + rdword PIXELS, R3 ' Set pixels to the proper data + rev PIXELS, #16 ' Reverse bit order to output pixels MSB first + rdbyte R3, R4 ' R3 := foreground color + add R4, #1 ' Advance the color pointer for the next character + mov R2, COLORS + shl R2, #8 + or R2, R3 ' Only foreground color is set, background remains the same from palette + ror R2, #8 + test VideoMode, #1 wz + if_nz xor R2, phaseflip ' Flip color phase if PAL mode + waitvid R2, PIXELS ' Output our video + djnz R0, #:StatusChar ' and loop + + mov VSCL, _VSCL_RightBorder + waitvid COLOR_BORDER, #0 ' Output the right border + + add R6, #2 + djnz LineCounter, #:ScanLine ' Next line (note that here LineCounter is always > 0) + +' jmp #:EmptyLine + + ' Draw a data line + +:DataLine mov VSCL, _VSCL_LeftBorder + waitvid COLOR_BORDER, #0 ' Output the left border + + ' Character rendering loop + + mov VSCL, _VSCL_Character + mov R0, #20 ' R0 := Character counter (per line) + mov R1, AttribPtr ' R1 := Pointer to attribute (tile) area +:Character rdbyte R2, R1 ' R2 := Tile description long + add R1, #1 ' Advance the attribute pointer for the next character + test Status, #2 wz + if_z shl R2, #5 ' Multiply by bitmap size to form an address + if_nz shl R2, #4 + add R2, CharacterRows ' Add the row offset for each tile + add R2, TilePtr ' R2 := Address of the bitmap word to read + rdword PIXELS, R2 ' Set pixels to the proper data + cmp OffsetX, #0 wz + if_z jmp #:Output + shl PIXELS, OffsetX + rdbyte R2, R1 + test Status, #2 wz + if_z shl R2, #5 ' Multiply by bitmap size to form an address + if_nz shl R2, #4 + add R2, CharacterRows ' Add the row offset for each tile + add R2, TilePtr ' R2 := Address of the bitmap word to read + rdword R3, R2 + shr R3, R5 + or PIXELS, R3 +:Output rev PIXELS, #16 ' Reverse bit order to output pixels MSB first + mov R2, COLORS + test VideoMode, #1 wz + if_nz xor R2, phaseflip ' Flip color phase if PAL mode + waitvid R2, PIXELS ' Output our video + djnz R0, #:Character ' and loop + + mov VSCL, _VSCL_RightBorder + waitvid COLOR_BORDER, #0 ' Output the right border + + ' Calculate the address of the next attribute line + + add CharacterRows, #2 + test Status, #2 wz + if_z mov R2, #32 + if_nz mov R2, #16 + cmp CharacterRows, R2 wz + if_z mov CharacterRows, #0 ' Advance to the next line of attributes if the sub-character counter + if_z add AttribPtr, #40 ' reaches the end of character, and reset it to 8 + djnz LineCounter, #:ScanLine ' Next line (note that here LineCounter is always > 0) + + ' Empty (border only) lines + +:EmptyLine mov VSCL, _VSCL_VisibleLine ' Output an entire visible line of BORDER color + waitvid COLOR_BORDER, #0 + djnz LineCounter, #:ScanLine ' Next line: note that this may be the last one + + ' VSync + + mov R0, #$FF + wrbyte R0, VSyncPtr + + test VideoMode, #1 wz + if_nz xor phaseflip, phasemask + + call #VSyncHigh ' VSync procedure: 6 half-lines of HSync-only values (3 lines) + call #VSyncLow ' 6 half-lines inverted from the previous ones (3 lines) + call #VSyncHigh ' 6 half-lines more of HSync-only values (3 lines) + + mov R0, #0 + wrbyte R0, VSyncPtr + + jmp #:Frame ' Next frame + + ' ───────────────────────────────────────── + ' Synchronization subroutines + ' ───────────────────────────────────────── + +HSync mov VSCL, _VSCL_FrontPorch + waitvid COLOR_BLACK, #0 + mov VSCL, _VSCL_SynchronizingPulse + waitvid COLOR_SYNC, #0 + mov VSCL, _VSCL_BreezeAway + waitvid COLOR_BLACK, #0 + mov VSCL, _VSCL_ColourBurst + + test VideoMode, #1 wz + if_nz xor phaseflip, phasemask wz ' Swing color burst if PAL + if_z mov R0, _Burst1 + if_nz mov R0, _Burst2 + waitvid R0, #0 + + mov VSCL, _VSCL_WaitToData + waitvid COLOR_BLACK, #0 +HSync_Ret ret + +VSyncHigh mov R0, #6 +:Loop mov VSCL, _VSCL_FrontPorch + waitvid COLOR_BLACK, #0 + mov R1, _VSCL_SynchronizingPulse + shr R1, #1 ' Half-length pulses + mov VSCL, R1 + waitvid COLOR_SYNC, #0 + mov VSCL, R1 + waitvid COLOR_BLACK, #0 + mov VSCL, _VSCL_BackPorch ' BackPorch = BreezeAway + ColourBurst + WaitToData + waitvid COLOR_BLACK, #0 + mov VSCL, _VSCL_HalfLine + waitvid COLOR_BLACK, #0 + djnz R0, #:Loop +VSyncHigh_Ret ret + +VSyncLow mov R0, #6 +:Loop mov VSCL, _VSCL_FrontPorch + waitvid COLOR_BLACK, #0 + mov VSCL, _VSCL_HalfLine + waitvid COLOR_SYNC, #0 + mov VSCL, _VSCL_BackPorch ' BackPorch = BreezeAway + ColourBurst + WaitToData + waitvid COLOR_SYNC, #0 + mov VSCL, _VSCL_FrontPorch + waitvid COLOR_SYNC, #0 + mov R1, _VSCL_SynchronizingPulse + sub R1, _VSCL_FrontPorch + mov VSCL, R1 +' mov VSCL, _VSCL_SynchronizingPulse + waitvid COLOR_BLACK, #0 + djnz R0, #:Loop +VSyncLow_Ret ret + + + ' ───────────────────────────────────────── + ' Utility subroutines + ' ───────────────────────────────────────── + + ' Divide R1 by R2 and return the result in R3 with 32 bits of decimal precision + ' Input: R1 → Dividend + ' R2 → Divisor (it is required that R1 < R2) + ' Output: R3 → (R1/R2) << 32 + +Divide mov R0, #33 +:Loop cmpsub R1, R2 wc + rcl R3, #1 + shl R1, #1 + djnz R0, #:Loop +Divide_Ret ret + + +phaseflip long $00000000 +phasemask long $F0F0F0F0 ' invert hue portion of color + + ' ───────────────────────────────────────── + ' Uninitialized data + ' ───────────────────────────────────────── + + R0 res 1 + R1 res 1 + R2 res 1 + R3 res 1 + R4 res 1 + R5 res 1 + R6 res 1 + + COLORS res 1 + PIXELS res 1 + + _VCFG_PinMask res 1 + _VCFG_PinGroup res 1 + _VCFG_Mode res 1 + _PortMask res 1 + + _ClockFreq res 1 + _VSCL_Character res 1 + _VSCL_VisibleLine res 1 + _VSCL_HalfLine res 1 + _VSCL_LeftBorder res 1 + _VSCL_RightBorder res 1 + _VSCL_FrontPorch res 1 + _VSCL_SynchronizingPulse res 1 + _VSCL_BreezeAway res 1 + _VSCL_ColourBurst res 1 + _VSCL_BackPorch res 1 + _VSCL_WaitToData res 1 + _VerticalLines res 1 + _TopLine res 1 + _BottomLine res 1 + _Burst1 res 1 + _Burst2 res 1 + + LineCounter res 1 + CharacterRows res 1 + TilePtr res 1 + AttribPtr res 1 + ScreenPtr res 1 + StatusPtr res 1 + VSyncPtr res 1 + + PAddr res 1 + PCtr res 1 + + OffsetX res 1 + OffsetY res 1 + + Status res 1 + VideoMode res 1 + + fit + \ No newline at end of file diff --git a/source/boulder/bellatrix/Game_controller.spin b/source/boulder/bellatrix/Game_controller.spin index 941a977..247aaef 100644 --- a/source/boulder/bellatrix/Game_controller.spin +++ b/source/boulder/bellatrix/Game_controller.spin @@ -1 +1,76 @@ -con GP_RIGHT = %00000001 GP_LEFT = %00000010 GP_DOWN = %00000100 GP_UP = %00001000 GP_START = %00010000 GP_SELECT = %00100000 GP_B = %01000000 GP_A = %10000000 var long stack[6] long nes_bitspub start nes_bits := 0 'cognew(process, @stack)pub read 'return nes_bits return processpub process | i, bits ' set I/O ports to proper direction ' P3 = JOY_CLK (4) ' P4 = JOY_SH/LDn (5) ' P5 = JOY_DATAOUT0 (6) ' P6 = JOY_DATAOUT1 (7) ' NES Bit Encoding ' step 1: set I/Os DIRA[3] := 1 ' output DIRA[4] := 1 ' output DIRA[5] := 0 ' input DIRA[6] := 0 ' input repeat ' step 2: set clock and latch to 0 OUTA[3] := 0 ' JOY_CLK = 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 'Delay(1) ' step 3: set latch to 1 OUTA[4] := 1 ' JOY_SH/LDn = 1 'Delay(1) ' step 4: set latch to 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 ' step 5: read first bit of each game pad ' data is now ready to shift out ' first bit is ready ' left controller bits := INA[5] | (INA[6] << 8) ' step 7: read next 7 bits repeat i from 0 to 6 OUTA[3] := 1 ' JOY_CLK = 1 'Delay(1) OUTA[3] := 0 ' JOY_CLK = 0 bits := (bits << 1) bits := bits | INA[5] | (INA[6] << 8) 'Delay(1) ' invert bits to make positive logic and store result nes_bits := (!bits & $FFFF) return nes_bits \ No newline at end of file +con + + GP_RIGHT = %00000001 + GP_LEFT = %00000010 + GP_DOWN = %00000100 + GP_UP = %00001000 + GP_START = %00010000 + GP_SELECT = %00100000 + GP_B = %01000000 + GP_A = %10000000 + +var + + long stack[6] + long nes_bits + +pub start + + nes_bits := 0 + + 'cognew(process, @stack) + +pub read + + 'return nes_bits + return process + +pub process | i, bits + + ' set I/O ports to proper direction + ' P3 = JOY_CLK (4) + ' P4 = JOY_SH/LDn (5) + ' P5 = JOY_DATAOUT0 (6) + ' P6 = JOY_DATAOUT1 (7) + ' NES Bit Encoding + + ' step 1: set I/Os + DIRA[3] := 1 ' output + DIRA[4] := 1 ' output + DIRA[5] := 0 ' input + DIRA[6] := 0 ' input + + repeat + ' step 2: set clock and latch to 0 + OUTA[3] := 0 ' JOY_CLK = 0 + OUTA[4] := 0 ' JOY_SH/LDn = 0 + 'Delay(1) + + ' step 3: set latch to 1 + OUTA[4] := 1 ' JOY_SH/LDn = 1 + 'Delay(1) + + ' step 4: set latch to 0 + OUTA[4] := 0 ' JOY_SH/LDn = 0 + + ' step 5: read first bit of each game pad + + ' data is now ready to shift out + ' first bit is ready + + ' left controller + bits := INA[5] | (INA[6] << 8) + + ' step 7: read next 7 bits + repeat i from 0 to 6 + OUTA[3] := 1 ' JOY_CLK = 1 + 'Delay(1) + OUTA[3] := 0 ' JOY_CLK = 0 + bits := (bits << 1) + bits := bits | INA[5] | (INA[6] << 8) + 'Delay(1) + + ' invert bits to make positive logic and store result + nes_bits := (!bits & $FFFF) + return nes_bits + \ No newline at end of file diff --git a/source/boulder/bellatrix/Keyboard.spin b/source/boulder/bellatrix/Keyboard.spin index c9ec831..08c915f 100644 --- a/source/boulder/bellatrix/Keyboard.spin +++ b/source/boulder/bellatrix/Keyboard.spin @@ -1 +1,736 @@ -''***************************************''* PS/2 Keyboard Driver v1.0.1 *''* Author: Chip Gracey *''* Copyright (c) 2004 Parallax, Inc. *''* See end of file for terms of use. *''***************************************{-----------------REVISION HISTORY----------------- v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96} VAR long cog long par_tail 'key buffer tail read/write (19 contiguous longs) long par_head 'key buffer head read-only long par_present 'keyboard present read-only long par_states[8] 'key states (256 bits) read-only long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters)PUB start(dpin, cpin) : okay'' Start keyboard driver - starts a cog'' returns false if no cog available'''' dpin = data signal on PS/2 jack'' cpin = clock signal on PS/2 jack'''' use 100-ohm resistors between pins and jack'' use 10K-ohm resistors to pull jack-side signals to VDD'' connect jack-power to 5V, jack-gnd to VSS'''' all lock-keys will be enabled, NumLock will be initially 'on','' and auto-repeat will be set to 15cps with a delay of .5s okay := startx(dpin, cpin, %0_000_100, %01_01000)PUB startx(dpin, cpin, locks, auto) : okay'' Like start, but allows you to specify lock settings and auto-repeat'''' locks = lock setup'' bit 6 disallows shift-alphas (case set soley by CapsLock)'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on')'''' auto = auto-repeat setup'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s)'' bits 4..0 specify repeat rate (0=30cps..31=2cps)'' (eg %01_00000 = .5s delay, 30cps repeat) stop longmove(@par_keys, @dpin, 4) okay := cog := cognew(@entry, @par_tail) + 1PUB stop'' Stop keyboard driver - frees a cog if cog cogstop(cog~ - 1) longfill(@par_tail, 0, 19)PUB present : truefalse'' Check if keyboard present - valid ~2s after start'' returns t|f truefalse := -par_presentPUB key : keycode'' Get key (never waits)'' returns key (0 if buffer empty) if par_tail <> par_head keycode := par_keys.word[par_tail] par_tail := ++par_tail & $FPUB getkey : keycode'' Get next key (may wait for keypress)'' returns key repeat until (keycode := key)PUB newkey : keycode'' Clear buffer and get new key (always waits for keypress)'' returns key par_tail := par_head keycode := getkeyPUB gotkey : truefalse'' Check if any key in buffer'' returns t|f truefalse := par_tail <> par_headPUB clearkeys'' Clear key buffer par_tail := par_headPUB keystate(k) : state'' Get the state of a particular key'' returns t|f state := -(par_states[k >> 5] >> k & 1)DAT'******************************************'* Assembly language PS/2 keyboard driver *'****************************************** org''' Entry'entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto mov x,par add x,#11*4 mov y,#4:par rdlong 0,x add :par,dlsb add x,#4 djnz y,#:par mov dmask,#1 'set pin masks shl dmask,_dpin mov cmask,#1 shl cmask,_cpin test _dpin,#$20 wc 'modify port registers within code muxc _d1,dlsb muxc _d2,dlsb muxc _d3,#1 muxc _d4,#1 test _cpin,#$20 wc muxc _c1,dlsb muxc _c2,dlsb muxc _c3,#1 mov _head,#0 'reset output parameter _head''' Reset keyboard'reset mov dira,#0 'reset directions mov dirb,#0 movd :par,#_present 'reset output parameters _present/_states[8] mov x,#1+8:par mov 0,#0 add :par,dlsb djnz x,#:par mov stat,#8 'set reset flag''' Update parameters'update movd :par,#_head 'update output parameters _head/_present/_states[8] mov x,par add x,#1*4 mov y,#1+1+8:par wrlong 0,x add :par,dlsb add x,#4 djnz y,#:par test stat,#8 wc 'if reset flag, transmit reset command if_c mov data,#$FF if_c call #transmit''' Get scancode'newcode mov stat,#0 'reset state:same call #receive 'receive byte from keyboard cmp data,#$83+1 wc 'scancode? if_nc cmp data,#$AA wz 'powerup/reset? if_nc_and_z jmp #configure if_nc cmp data,#$E0 wz 'extended? if_nc_and_z or stat,#1 if_nc_and_z jmp #:same if_nc cmp data,#$F0 wz 'released? if_nc_and_z or stat,#2 if_nc_and_z jmp #:same if_nc jmp #newcode 'unknown, ignore''' Translate scancode and enter into buffer' test stat,#1 wc 'lookup code with extended flag rcl data,#1 call #look cmp data,#0 wz 'if unknown, ignore if_z jmp #newcode mov t,_states+6 'remember lock keys in _states mov x,data 'set/clear key bit in _states shr x,#5 add x,#_states movd :reg,x mov y,#1 shl y,data test stat,#2 wc:reg muxnc 0,y if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done if_c jmp #update mov y,_states+7 'get shift/ctrl/alt/win bit pairs shr y,#16 cmpsub data,#$E0 wc 'translate keypad, considering numlock if_c test _locks,#%100 wz if_c_and_z add data,#@keypad1-@table if_c_and_nz add data,#@keypad2-@table if_c call #look if_c jmp #:flags cmpsub data,#$DD wc 'handle scrlock/capslock/numlock if_c mov x,#%001_000 if_c shl x,data if_c andn x,_locks if_c shr x,#3 if_c shr t,#29 'ignore auto-repeat if_c andn x,t wz if_c xor _locks,x if_c add data,#$DD if_c_and_nz or stat,#4 'if change, set configure flag to update leds test y,#%11 wz 'get shift into nz if_nz cmp data,#$60+1 wc 'check shift1 if_nz_and_c cmpsub data,#$5B wc if_nz_and_c add data,#@shift1-@table if_nz_and_c call #look if_nz_and_c andn y,#%11 if_nz cmp data,#$3D+1 wc 'check shift2 if_nz_and_c cmpsub data,#$27 wc if_nz_and_c add data,#@shift2-@table if_nz_and_c call #look if_nz_and_c andn y,#%11 test _locks,#%010 wc 'check shift-alpha, considering capslock muxnc :shift,#$20 test _locks,#$40 wc if_nz_and_nc xor :shift,#$20 cmp data,#"z"+1 wc if_c cmpsub data,#"a" wc:shift if_c add data,#"A" if_c andn y,#%11:flags ror data,#8 'add shift/ctrl/alt/win flags mov x,#4 '+$100 if shift:loop test y,#%11 wz '+$200 if ctrl shr y,#2 '+$400 if alt if_nz or data,#1 '+$800 if win ror data,#1 djnz x,#:loop rol data,#12 rdlong x,par 'if room in buffer and key valid, enter sub x,#1 and x,#$F cmp x,_head wz if_nz test data,#$FF wz if_nz mov x,par if_nz add x,#11*4 if_nz add x,_head if_nz add x,_head if_nz wrword data,x if_nz add _head,#1 if_nz and _head,#$F test stat,#4 wc 'if not configure flag, done if_nc jmp #update 'else configure to update leds''' Configure keyboard'configure mov data,#$F3 'set keyboard auto-repeat call #transmit mov data,_auto and data,#%11_11111 call #transmit mov data,#$ED 'set keyboard lock-leds call #transmit mov data,_locks rev data,#-3 & $1F test data,#%100 wc rcl data,#1 and data,#%111 call #transmit mov x,_locks 'insert locks into _states and x,#%111 shl _states+7,#3 or _states+7,x ror _states+7,#3 mov _present,#1 'set _present jmp #update 'done''' Lookup byte in table'look ror data,#2 'perform lookup movs :reg,data add :reg,#table shr data,#27 mov x,data:reg mov data,0 shr data,x jmp #rand 'isolate byte''' Transmit byte to keyboard'transmit_c1 or dira,cmask 'pull clock low movs napshr,#13 'hold clock for ~128us (must be >100us) call #nap_d1 or dira,dmask 'pull data low movs napshr,#18 'hold data for ~4us call #nap_c2 xor dira,cmask 'release clock test data,#$0FF wc 'append parity and stop bits to byte muxnc data,#$100 or data,dlsb mov x,#10 'ready 10 bitstransmit_bit call #wait_c0 'wait until clock low shr data,#1 wc 'output data bit_d2 muxnc dira,dmask mov wcond,c1 'wait until clock high call #wait djnz x,#transmit_bit 'another bit? mov wcond,c0d0 'wait until clock and data low call #wait mov wcond,c1d1 'wait until clock and data high call #wait call #receive_ack 'receive ack byte with timed wait cmp data,#$FA wz 'if ack error, reset keyboard if_nz jmp #resettransmit_ret ret''' Receive byte from keyboard'receive test _cpin,#$20 wc 'wait indefinitely for initial clock low waitpne cmask,cmaskreceive_ack mov x,#11 'ready 11 bitsreceive_bit call #wait_c0 'wait until clock low movs napshr,#16 'pause ~16us call #nap_d3 test dmask,ina wc 'input data bit rcr data,#1 mov wcond,c1 'wait until clock high call #wait djnz x,#receive_bit 'another bit? shr data,#22 'align byte test data,#$1FF wc 'if parity error, reset keyboard if_nc jmp #resetrand and data,#$FF 'isolate bytelook_retreceive_ack_retreceive_ret ret''' Wait for clock/data to be in required state(s)'wait_c0 mov wcond,c0 '(wait until clock low)wait mov y,tenms 'set timeout to 10mswloop movs napshr,#18 'nap ~4us call #nap_c3 test cmask,ina wc 'check required state(s)_d4 test dmask,ina wz 'loop until got state(s) or timeoutwcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) tjz y,#reset 'if timeout, reset keyboardwait_retwait_c0_ret retc0 if_c djnz y,#wloop '(if_never replacements)c1 if_nc djnz y,#wloopc0d0 if_c_or_nz djnz y,#wloopc1d1 if_nc_or_z djnz y,#wloop''' Nap'nap rdlong t,#0 'get clkfreqnapshr shr t,#18/16/13 'shr scales time min t,#3 'ensure waitcnt won't snag add t,cnt 'add cnt to time waitcnt t,#0 'wait until time elapses (nap)nap_ret ret''' Initialized data''dlsb long 1 << 9tenms long 10_000 / 4''' Lookup table' ascii scan extkey regkey ()=keypad'table word $0000 '00 word $00D8 '01 F9 word $0000 '02 word $00D4 '03 F5 word $00D2 '04 F3 word $00D0 '05 F1 word $00D1 '06 F2 word $00DB '07 F12 word $0000 '08 word $00D9 '09 F10 word $00D7 '0A F8 word $00D5 '0B F6 word $00D3 '0C F4 word $0009 '0D Tab word $0060 '0E ` word $0000 '0F word $0000 '10 word $F5F4 '11 Alt-R Alt-L word $00F0 '12 Shift-L word $0000 '13 word $F3F2 '14 Ctrl-R Ctrl-L word $0071 '15 q word $0031 '16 1 word $0000 '17 word $0000 '18 word $0000 '19 word $007A '1A z word $0073 '1B s word $0061 '1C a word $0077 '1D w word $0032 '1E 2 word $F600 '1F Win-L word $0000 '20 word $0063 '21 c word $0078 '22 x word $0064 '23 d word $0065 '24 e word $0034 '25 4 word $0033 '26 3 word $F700 '27 Win-R word $0000 '28 word $0020 '29 Space word $0076 '2A v word $0066 '2B f word $0074 '2C t word $0072 '2D r word $0035 '2E 5 word $CC00 '2F Apps word $0000 '30 word $006E '31 n word $0062 '32 b word $0068 '33 h word $0067 '34 g word $0079 '35 y word $0036 '36 6 word $CD00 '37 Power word $0000 '38 word $0000 '39 word $006D '3A m word $006A '3B j word $0075 '3C u word $0037 '3D 7 word $0038 '3E 8 word $CE00 '3F Sleep word $0000 '40 word $002C '41 , word $006B '42 k word $0069 '43 i word $006F '44 o word $0030 '45 0 word $0039 '46 9 word $0000 '47 word $0000 '48 word $002E '49 . word $EF2F '4A (/) / word $006C '4B l word $003B '4C ; word $0070 '4D p word $002D '4E - word $0000 '4F word $0000 '50 word $0000 '51 word $0027 '52 ' word $0000 '53 word $005B '54 [ word $003D '55 = word $0000 '56 word $0000 '57 word $00DE '58 CapsLock word $00F1 '59 Shift-R word $EB0D '5A (Enter) Enter word $005D '5B ] word $0000 '5C word $005C '5D \ word $CF00 '5E WakeUp word $0000 '5F word $0000 '60 word $0000 '61 word $0000 '62 word $0000 '63 word $0000 '64 word $0000 '65 word $00C8 '66 BackSpace word $0000 '67 word $0000 '68 word $C5E1 '69 End (1) word $0000 '6A word $C0E4 '6B Left (4) word $C4E7 '6C Home (7) word $0000 '6D word $0000 '6E word $0000 '6F word $CAE0 '70 Insert (0) word $C9EA '71 Delete (.) word $C3E2 '72 Down (2) word $00E5 '73 (5) word $C1E6 '74 Right (6) word $C2E8 '75 Up (8) word $00CB '76 Esc word $00DF '77 NumLock word $00DA '78 F11 word $00EC '79 (+) word $C7E3 '7A PageDn (3) word $00ED '7B (-) word $DCEE '7C PrScr (*) word $C6E9 '7D PageUp (9) word $00DD '7E ScrLock word $0000 '7F word $0000 '80 word $0000 '81 word $0000 '82 word $00D6 '83 F7keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/"keypad2 byte "0123456789.", $0D, "+-*/"shift1 byte "{|}", 0, 0, "~"shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+"''' Uninitialized data'dmask res 1cmask res 1stat res 1data res 1x res 1y res 1t res 1_head res 1 'write-only_present res 1 'write-only_states res 8 'write-only_dpin res 1 'read-only at start_cpin res 1 'read-only at start_locks res 1 'read-only at start_auto res 1 'read-only at start'''''' _________'' Key Codes'''' 00..DF = keypress and keystate'' E0..FF = keystate only'''''' 09 Tab'' 0D Enter'' 20 Space'' 21 !'' 22 "'' 23 #'' 24 $'' 25 %'' 26 &'' 27 ''' 28 ('' 29 )'' 2A *'' 2B +'' 2C ,'' 2D -'' 2E .'' 2F /'' 30 0..9'' 3A :'' 3B ;'' 3C <'' 3D ='' 3E >'' 3F ?'' 40 @ '' 41..5A A..Z'' 5B ['' 5C \'' 5D ]'' 5E ^'' 5F _'' 60 `'' 61..7A a..z'' 7B {'' 7C |'' 7D }'' 7E ~'''' 80-BF (future international character support)'''' C0 Left Arrow'' C1 Right Arrow'' C2 Up Arrow'' C3 Down Arrow'' C4 Home'' C5 End'' C6 Page Up'' C7 Page Down'' C8 Backspace'' C9 Delete'' CA Insert'' CB Esc'' CC Apps'' CD Power'' CE Sleep'' CF Wakeup'''' D0..DB F1..F12'' DC Print Screen'' DD Scroll Lock'' DE Caps Lock'' DF Num Lock'''' E0..E9 Keypad 0..9'' EA Keypad .'' EB Keypad Enter'' EC Keypad +'' ED Keypad -'' EE Keypad *'' EF Keypad /'''' F0 Left Shift'' F1 Right Shift'' F2 Left Ctrl'' F3 Right Ctrl'' F4 Left Alt'' F5 Right Alt'' F6 Left Win'' F7 Right Win'''' FD Scroll Lock State'' FE Caps Lock State'' FF Num Lock State'''' +100 if Shift'' +200 if Ctrl'' +400 if Alt'' +800 if Win'''' eg. Ctrl-Alt-Delete = $6C9'''''' Note: Driver will buffer up to 15 keystrokes, then ignore overflow.{{┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ││modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software││is furnished to do so, subject to the following conditions: ││ ││The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.││ ││THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ││WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ││COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ││ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘}} \ No newline at end of file +''*************************************** +''* PS/2 Keyboard Driver v1.0.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +{-----------------REVISION HISTORY----------------- + v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96} + +VAR + + long cog + + long par_tail 'key buffer tail read/write (19 contiguous longs) + long par_head 'key buffer head read-only + long par_present 'keyboard present read-only + long par_states[8] 'key states (256 bits) read-only + long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters) + + +PUB start(dpin, cpin) : okay + +'' Start keyboard driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS +'' +'' all lock-keys will be enabled, NumLock will be initially 'on', +'' and auto-repeat will be set to 15cps with a delay of .5s + + okay := startx(dpin, cpin, %0_000_100, %01_01000) + + +PUB startx(dpin, cpin, locks, auto) : okay + +'' Like start, but allows you to specify lock settings and auto-repeat +'' +'' locks = lock setup +'' bit 6 disallows shift-alphas (case set soley by CapsLock) +'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state +'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock +'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') +'' +'' auto = auto-repeat setup +'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) +'' bits 4..0 specify repeat rate (0=30cps..31=2cps) +'' (eg %01_00000 = .5s delay, 30cps repeat) + + stop + longmove(@par_keys, @dpin, 4) + okay := cog := cognew(@entry, @par_tail) + 1 + + +PUB stop + +'' Stop keyboard driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@par_tail, 0, 19) + + +PUB present : truefalse + +'' Check if keyboard present - valid ~2s after start +'' returns t|f + + truefalse := -par_present + + +PUB key : keycode + +'' Get key (never waits) +'' returns key (0 if buffer empty) + + if par_tail <> par_head + keycode := par_keys.word[par_tail] + par_tail := ++par_tail & $F + + +PUB getkey : keycode + +'' Get next key (may wait for keypress) +'' returns key + + repeat until (keycode := key) + + +PUB newkey : keycode + +'' Clear buffer and get new key (always waits for keypress) +'' returns key + + par_tail := par_head + keycode := getkey + + +PUB gotkey : truefalse + +'' Check if any key in buffer +'' returns t|f + + truefalse := par_tail <> par_head + + +PUB clearkeys + +'' Clear key buffer + + par_tail := par_head + + +PUB keystate(k) : state + +'' Get the state of a particular key +'' returns t|f + + state := -(par_states[k >> 5] >> k & 1) + + +DAT + +'****************************************** +'* Assembly language PS/2 keyboard driver * +'****************************************** + + org +' +' +' Entry +' +entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto + mov x,par + add x,#11*4 + mov y,#4 +:par rdlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + mov _head,#0 'reset output parameter _head +' +' +' Reset keyboard +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + movd :par,#_present 'reset output parameters _present/_states[8] + mov x,#1+8 +:par mov 0,#0 + add :par,dlsb + djnz x,#:par + + mov stat,#8 'set reset flag +' +' +' Update parameters +' +update movd :par,#_head 'update output parameters _head/_present/_states[8] + mov x,par + add x,#1*4 + mov y,#1+1+8 +:par wrlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + test stat,#8 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get scancode +' +newcode mov stat,#0 'reset state + +:same call #receive 'receive byte from keyboard + + cmp data,#$83+1 wc 'scancode? + + if_nc cmp data,#$AA wz 'powerup/reset? + if_nc_and_z jmp #configure + + if_nc cmp data,#$E0 wz 'extended? + if_nc_and_z or stat,#1 + if_nc_and_z jmp #:same + + if_nc cmp data,#$F0 wz 'released? + if_nc_and_z or stat,#2 + if_nc_and_z jmp #:same + + if_nc jmp #newcode 'unknown, ignore +' +' +' Translate scancode and enter into buffer +' + test stat,#1 wc 'lookup code with extended flag + rcl data,#1 + call #look + + cmp data,#0 wz 'if unknown, ignore + if_z jmp #newcode + + mov t,_states+6 'remember lock keys in _states + + mov x,data 'set/clear key bit in _states + shr x,#5 + add x,#_states + movd :reg,x + mov y,#1 + shl y,data + test stat,#2 wc +:reg muxnc 0,y + + if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done + if_c jmp #update + + mov y,_states+7 'get shift/ctrl/alt/win bit pairs + shr y,#16 + + cmpsub data,#$E0 wc 'translate keypad, considering numlock + if_c test _locks,#%100 wz + if_c_and_z add data,#@keypad1-@table + if_c_and_nz add data,#@keypad2-@table + if_c call #look + if_c jmp #:flags + + cmpsub data,#$DD wc 'handle scrlock/capslock/numlock + if_c mov x,#%001_000 + if_c shl x,data + if_c andn x,_locks + if_c shr x,#3 + if_c shr t,#29 'ignore auto-repeat + if_c andn x,t wz + if_c xor _locks,x + if_c add data,#$DD + if_c_and_nz or stat,#4 'if change, set configure flag to update leds + + test y,#%11 wz 'get shift into nz + + if_nz cmp data,#$60+1 wc 'check shift1 + if_nz_and_c cmpsub data,#$5B wc + if_nz_and_c add data,#@shift1-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + if_nz cmp data,#$3D+1 wc 'check shift2 + if_nz_and_c cmpsub data,#$27 wc + if_nz_and_c add data,#@shift2-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + test _locks,#%010 wc 'check shift-alpha, considering capslock + muxnc :shift,#$20 + test _locks,#$40 wc + if_nz_and_nc xor :shift,#$20 + cmp data,#"z"+1 wc + if_c cmpsub data,#"a" wc +:shift if_c add data,#"A" + if_c andn y,#%11 + +:flags ror data,#8 'add shift/ctrl/alt/win flags + mov x,#4 '+$100 if shift +:loop test y,#%11 wz '+$200 if ctrl + shr y,#2 '+$400 if alt + if_nz or data,#1 '+$800 if win + ror data,#1 + djnz x,#:loop + rol data,#12 + + rdlong x,par 'if room in buffer and key valid, enter + sub x,#1 + and x,#$F + cmp x,_head wz + if_nz test data,#$FF wz + if_nz mov x,par + if_nz add x,#11*4 + if_nz add x,_head + if_nz add x,_head + if_nz wrword data,x + if_nz add _head,#1 + if_nz and _head,#$F + + test stat,#4 wc 'if not configure flag, done + if_nc jmp #update 'else configure to update leds +' +' +' Configure keyboard +' +configure mov data,#$F3 'set keyboard auto-repeat + call #transmit + mov data,_auto + and data,#%11_11111 + call #transmit + + mov data,#$ED 'set keyboard lock-leds + call #transmit + mov data,_locks + rev data,#-3 & $1F + test data,#%100 wc + rcl data,#1 + and data,#%111 + call #transmit + + mov x,_locks 'insert locks into _states + and x,#%111 + shl _states+7,#3 + or _states+7,x + ror _states+7,#3 + + mov _present,#1 'set _present + + jmp #update 'done +' +' +' Lookup byte in table +' +look ror data,#2 'perform lookup + movs :reg,data + add :reg,#table + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + + jmp #rand 'isolate byte +' +' +' Transmit byte to keyboard +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov x,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz x,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset keyboard + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from keyboard +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov x,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz x,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset keyboard + if_nc jmp #reset +rand and data,#$FF 'isolate byte + +look_ret +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov y,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz y,#reset 'if timeout, reset keyboard +wait_ret +wait_c0_ret ret + + +c0 if_c djnz y,#wloop '(if_never replacements) +c1 if_nc djnz y,#wloop +c0d0 if_c_or_nz djnz y,#wloop +c1d1 if_nc_or_z djnz y,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +' +' +' Lookup table +' ascii scan extkey regkey ()=keypad +' +table word $0000 '00 + word $00D8 '01 F9 + word $0000 '02 + word $00D4 '03 F5 + word $00D2 '04 F3 + word $00D0 '05 F1 + word $00D1 '06 F2 + word $00DB '07 F12 + word $0000 '08 + word $00D9 '09 F10 + word $00D7 '0A F8 + word $00D5 '0B F6 + word $00D3 '0C F4 + word $0009 '0D Tab + word $0060 '0E ` + word $0000 '0F + word $0000 '10 + word $F5F4 '11 Alt-R Alt-L + word $00F0 '12 Shift-L + word $0000 '13 + word $F3F2 '14 Ctrl-R Ctrl-L + word $0071 '15 q + word $0031 '16 1 + word $0000 '17 + word $0000 '18 + word $0000 '19 + word $007A '1A z + word $0073 '1B s + word $0061 '1C a + word $0077 '1D w + word $0032 '1E 2 + word $F600 '1F Win-L + word $0000 '20 + word $0063 '21 c + word $0078 '22 x + word $0064 '23 d + word $0065 '24 e + word $0034 '25 4 + word $0033 '26 3 + word $F700 '27 Win-R + word $0000 '28 + word $0020 '29 Space + word $0076 '2A v + word $0066 '2B f + word $0074 '2C t + word $0072 '2D r + word $0035 '2E 5 + word $CC00 '2F Apps + word $0000 '30 + word $006E '31 n + word $0062 '32 b + word $0068 '33 h + word $0067 '34 g + word $0079 '35 y + word $0036 '36 6 + word $CD00 '37 Power + word $0000 '38 + word $0000 '39 + word $006D '3A m + word $006A '3B j + word $0075 '3C u + word $0037 '3D 7 + word $0038 '3E 8 + word $CE00 '3F Sleep + word $0000 '40 + word $002C '41 , + word $006B '42 k + word $0069 '43 i + word $006F '44 o + word $0030 '45 0 + word $0039 '46 9 + word $0000 '47 + word $0000 '48 + word $002E '49 . + word $EF2F '4A (/) / + word $006C '4B l + word $003B '4C ; + word $0070 '4D p + word $002D '4E - + word $0000 '4F + word $0000 '50 + word $0000 '51 + word $0027 '52 ' + word $0000 '53 + word $005B '54 [ + word $003D '55 = + word $0000 '56 + word $0000 '57 + word $00DE '58 CapsLock + word $00F1 '59 Shift-R + word $EB0D '5A (Enter) Enter + word $005D '5B ] + word $0000 '5C + word $005C '5D \ + word $CF00 '5E WakeUp + word $0000 '5F + word $0000 '60 + word $0000 '61 + word $0000 '62 + word $0000 '63 + word $0000 '64 + word $0000 '65 + word $00C8 '66 BackSpace + word $0000 '67 + word $0000 '68 + word $C5E1 '69 End (1) + word $0000 '6A + word $C0E4 '6B Left (4) + word $C4E7 '6C Home (7) + word $0000 '6D + word $0000 '6E + word $0000 '6F + word $CAE0 '70 Insert (0) + word $C9EA '71 Delete (.) + word $C3E2 '72 Down (2) + word $00E5 '73 (5) + word $C1E6 '74 Right (6) + word $C2E8 '75 Up (8) + word $00CB '76 Esc + word $00DF '77 NumLock + word $00DA '78 F11 + word $00EC '79 (+) + word $C7E3 '7A PageDn (3) + word $00ED '7B (-) + word $DCEE '7C PrScr (*) + word $C6E9 '7D PageUp (9) + word $00DD '7E ScrLock + word $0000 '7F + word $0000 '80 + word $0000 '81 + word $0000 '82 + word $00D6 '83 F7 + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + +shift1 byte "{|}", 0, 0, "~" + +shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +x res 1 +y res 1 +t res 1 + +_head res 1 'write-only +_present res 1 'write-only +_states res 8 'write-only +_dpin res 1 'read-only at start +_cpin res 1 'read-only at start +_locks res 1 'read-only at start +_auto res 1 'read-only at start + +'' +'' +'' _________ +'' Key Codes +'' +'' 00..DF = keypress and keystate +'' E0..FF = keystate only +'' +'' +'' 09 Tab +'' 0D Enter +'' 20 Space +'' 21 ! +'' 22 " +'' 23 # +'' 24 $ +'' 25 % +'' 26 & +'' 27 ' +'' 28 ( +'' 29 ) +'' 2A * +'' 2B + +'' 2C , +'' 2D - +'' 2E . +'' 2F / +'' 30 0..9 +'' 3A : +'' 3B ; +'' 3C < +'' 3D = +'' 3E > +'' 3F ? +'' 40 @ +'' 41..5A A..Z +'' 5B [ +'' 5C \ +'' 5D ] +'' 5E ^ +'' 5F _ +'' 60 ` +'' 61..7A a..z +'' 7B { +'' 7C | +'' 7D } +'' 7E ~ +'' +'' 80-BF (future international character support) +'' +'' C0 Left Arrow +'' C1 Right Arrow +'' C2 Up Arrow +'' C3 Down Arrow +'' C4 Home +'' C5 End +'' C6 Page Up +'' C7 Page Down +'' C8 Backspace +'' C9 Delete +'' CA Insert +'' CB Esc +'' CC Apps +'' CD Power +'' CE Sleep +'' CF Wakeup +'' +'' D0..DB F1..F12 +'' DC Print Screen +'' DD Scroll Lock +'' DE Caps Lock +'' DF Num Lock +'' +'' E0..E9 Keypad 0..9 +'' EA Keypad . +'' EB Keypad Enter +'' EC Keypad + +'' ED Keypad - +'' EE Keypad * +'' EF Keypad / +'' +'' F0 Left Shift +'' F1 Right Shift +'' F2 Left Ctrl +'' F3 Right Ctrl +'' F4 Left Alt +'' F5 Right Alt +'' F6 Left Win +'' F7 Right Win +'' +'' FD Scroll Lock State +'' FE Caps Lock State +'' FF Num Lock State +'' +'' +100 if Shift +'' +200 if Ctrl +'' +400 if Alt +'' +800 if Win +'' +'' eg. Ctrl-Alt-Delete = $6C9 +'' +'' +'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/source/boulder/bellatrix/RealRandom.spin b/source/boulder/bellatrix/RealRandom.spin index d9f2724..62c31d8 100644 --- a/source/boulder/bellatrix/RealRandom.spin +++ b/source/boulder/bellatrix/RealRandom.spin @@ -1 +1,146 @@ -{{┌───────────────────────────────────────────┬────────────────┬───────────────────────────────────┬───────────────┐│ Real Random v1.2 │ by Chip Gracey │ Copyright (c) 2007 Parallax, Inc. │ 23 March 2007 │├───────────────────────────────────────────┴────────────────┴───────────────────────────────────┴───────────────┤│ ││ This object generates real random numbers by stimulating and tracking CTR PLL jitter. It requires one cog and ││ at least 20MHz. ││ │├────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│ Background and Detail: ││ ││ A real random number is impossible to generate within a closed digital system. This is because there are no ││ reliably-random states within such a system at power-up, and after power-up, it behaves deterministically. ││ Random values can only be 'earned' by measuring something outside of the digital system. │ │ ││ In your programming, you might have used 'var?' to generate a pseudo-random sequence, but found the same ││ pattern playing every time you ran your program. You might have then used 'cnt' to 'randomly' seed the 'var'. ││ As long as you kept downloading to RAM, you saw consistently 'random' results. At some point, you probably ││ downloaded to EEPROM to set your project free. But what happened nearly every time you powered it up? You were ││ probably dismayed to discover the same sequence playing each time! The problem was that 'cnt' was always ││ powering-up with the same initial value and you were then sampling it at a constant offset. This can make you ││ wonder, "Where's the end to this madness? And will I ever find true randomness?". │ │ ││ In order to have real random numbers, either some external random signal must be input, or some analog system ││ must be used to generate random noise which can be measured. We're in luck here, because it turns out that the ││ Propeller does have sufficiently-analog subsystems which can be exploited for this purpose -- each cog's CTR ││ PLLs. These can be exercised internally to good effect, without any I/O activity. │ │ ││ This object sets up a cog's CTRA PLL to run at the main clock's frequency. It then uses a pseudo-random ││ sequencer to modulate the PLL's target phase. The PLL responds by speeding up and slowing down in a an endless ││ effort to lock. This results in very unpredictable frequency jitter which is fed back into the sequencer to ││ keep the bit salad tossing. The final output is a truly-random 32-bit unbiased value that is fully updated ││ every ~100us, with new bits rotated in every ~3us. This value can be sampled by your application whenever a │ │ random number is needed. ││ │├────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│ Revision History v1.0 released 21 March 2007 ││ │ │ v1.1 Bias removal has been added to ensure true randomness. Released 22 March 2007. ││ v1.2 Assembly code made more efficient. Documentation improved. Released 23 March 2007. ││ │└────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘}}VAR long cog, random_valuePUB start : okay'' Start real random driver - starts a cog'' returns false if no cog available 'Reset driver stop 'Launch real random cog return cog := cognew(@entry, @random_value) + 1 'allow 5ms to launch and randomize waitcnt(clkfreq / 200 + cnt)PUB stop'' Stop real random driver - frees a cog 'If already running, stop real random cog if cog cogstop(cog~ - 1)PUB random : value'' Returns a new long random value 'wait to insure new random (~200us at 80MHz system clock) waitcnt($4000 + cnt) return random_valuePUB random_ptr : ptr'' Returns the address of the long which receives the random value'''' A random bit is rotated into the long every ~3us, resuling in a'' new long every ~100us, on average, at 80MHz. You may want to double'' these times, though, to be sure that you are getting new bits. The'' timing uncertainty comes from the unbiasing algorithm which throws'' away identical bit pairs, and only outputs the different ones. return @random_valueDAT' ┌─────────────────────────┐' │ Real Random Generator │' └─────────────────────────┘ orgentry movi ctra,#%00001_111 'set ctra to internal pll mode, select x16 tap movi frqa,#$020 'set frqa to system clock frequency / 16 movi vcfg,#$040 'set vcfg to discrete output, but without pins mov vscl,#70 'set vscl to 70 pixel clocks per waitvid:twobits waitvid 0,0 'wait for next 70-pixel mark ± jitter time test phsa,#%10111 wc 'pseudo-randomly sequence phase to induce jitter rcr phsa,#1 '(c holds random bit #1) add phsa,cnt 'mix PLL jitter back into phase rcl par,#1 wz, nr 'transfer c into nz (par shadow register = 0) wrlong _random_value,par 'write random value back to spin variable waitvid 0,0 'wait for next 70-pixel mark ± jitter time test phsa,#%10111 wc 'pseudo-randomly sequence phase to induce jitter rcr phsa,#1 '(c holds random bit #2) add phsa,cnt 'mix PLL jitter back into phase if_z_eq_c rcl _random_value,#1 'only allow different bits (removes bias) jmp #:twobits 'get next two bits_random_value res 1{{┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ││modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software││is furnished to do so, subject to the following conditions: ││ ││The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.││ ││THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ││WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ││COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ││ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘}} \ No newline at end of file +{{ +┌───────────────────────────────────────────┬────────────────┬───────────────────────────────────┬───────────────┐ +│ Real Random v1.2 │ by Chip Gracey │ Copyright (c) 2007 Parallax, Inc. │ 23 March 2007 │ +├───────────────────────────────────────────┴────────────────┴───────────────────────────────────┴───────────────┤ +│ │ +│ This object generates real random numbers by stimulating and tracking CTR PLL jitter. It requires one cog and │ +│ at least 20MHz. │ +│ │ +├────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ Background and Detail: │ +│ │ +│ A real random number is impossible to generate within a closed digital system. This is because there are no │ +│ reliably-random states within such a system at power-up, and after power-up, it behaves deterministically. │ +│ Random values can only be 'earned' by measuring something outside of the digital system. │ +│ │ +│ In your programming, you might have used 'var?' to generate a pseudo-random sequence, but found the same │ +│ pattern playing every time you ran your program. You might have then used 'cnt' to 'randomly' seed the 'var'. │ +│ As long as you kept downloading to RAM, you saw consistently 'random' results. At some point, you probably │ +│ downloaded to EEPROM to set your project free. But what happened nearly every time you powered it up? You were │ +│ probably dismayed to discover the same sequence playing each time! The problem was that 'cnt' was always │ +│ powering-up with the same initial value and you were then sampling it at a constant offset. This can make you │ +│ wonder, "Where's the end to this madness? And will I ever find true randomness?". │ +│ │ +│ In order to have real random numbers, either some external random signal must be input, or some analog system │ +│ must be used to generate random noise which can be measured. We're in luck here, because it turns out that the │ +│ Propeller does have sufficiently-analog subsystems which can be exploited for this purpose -- each cog's CTR │ +│ PLLs. These can be exercised internally to good effect, without any I/O activity. │ +│ │ +│ This object sets up a cog's CTRA PLL to run at the main clock's frequency. It then uses a pseudo-random │ +│ sequencer to modulate the PLL's target phase. The PLL responds by speeding up and slowing down in a an endless │ +│ effort to lock. This results in very unpredictable frequency jitter which is fed back into the sequencer to │ +│ keep the bit salad tossing. The final output is a truly-random 32-bit unbiased value that is fully updated │ +│ every ~100us, with new bits rotated in every ~3us. This value can be sampled by your application whenever a │ +│ random number is needed. │ +│ │ +├────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ Revision History v1.0 released 21 March 2007 │ +│ │ +│ v1.1 Bias removal has been added to ensure true randomness. Released 22 March 2007. │ +│ v1.2 Assembly code made more efficient. Documentation improved. Released 23 March 2007. │ +│ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +}} +VAR + + long cog, random_value + + +PUB start : okay + +'' Start real random driver - starts a cog +'' returns false if no cog available + + 'Reset driver + stop + + 'Launch real random cog + return cog := cognew(@entry, @random_value) + 1 + + 'allow 5ms to launch and randomize + waitcnt(clkfreq / 200 + cnt) + + +PUB stop + +'' Stop real random driver - frees a cog + + 'If already running, stop real random cog + if cog + cogstop(cog~ - 1) + + +PUB random : value + +'' Returns a new long random value + + 'wait to insure new random (~200us at 80MHz system clock) + waitcnt($4000 + cnt) + + return random_value + + +PUB random_ptr : ptr + +'' Returns the address of the long which receives the random value +'' +'' A random bit is rotated into the long every ~3us, resuling in a +'' new long every ~100us, on average, at 80MHz. You may want to double +'' these times, though, to be sure that you are getting new bits. The +'' timing uncertainty comes from the unbiasing algorithm which throws +'' away identical bit pairs, and only outputs the different ones. + + return @random_value + + +DAT + +' ┌─────────────────────────┐ +' │ Real Random Generator │ +' └─────────────────────────┘ + + org + +entry movi ctra,#%00001_111 'set ctra to internal pll mode, select x16 tap + movi frqa,#$020 'set frqa to system clock frequency / 16 + movi vcfg,#$040 'set vcfg to discrete output, but without pins + mov vscl,#70 'set vscl to 70 pixel clocks per waitvid + +:twobits waitvid 0,0 'wait for next 70-pixel mark ± jitter time + test phsa,#%10111 wc 'pseudo-randomly sequence phase to induce jitter + rcr phsa,#1 '(c holds random bit #1) + add phsa,cnt 'mix PLL jitter back into phase + + rcl par,#1 wz, nr 'transfer c into nz (par shadow register = 0) + wrlong _random_value,par 'write random value back to spin variable + + waitvid 0,0 'wait for next 70-pixel mark ± jitter time + test phsa,#%10111 wc 'pseudo-randomly sequence phase to induce jitter + rcr phsa,#1 '(c holds random bit #2) + add phsa,cnt 'mix PLL jitter back into phase + + if_z_eq_c rcl _random_value,#1 'only allow different bits (removes bias) + jmp #:twobits 'get next two bits + + +_random_value res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/source/boulder/bellatrix/Scroller.spin b/source/boulder/bellatrix/Scroller.spin index 1b4471a..75ed27a 100644 --- a/source/boulder/bellatrix/Scroller.spin +++ b/source/boulder/bellatrix/Scroller.spin @@ -1 +1,1332 @@ -' This cog takes care of the smooth scrolling and animates animated objects.' Also:' - flashes the screen when the game target is reached' - signals about new life with random background patternvar long x, y, nx, ny long scroll_addr long tile_addr long palette_addr long stack[12] long rockford_dir long random_addr long vsync_addr byte flash_cnt byte new_life_cnt byte tapping byte blinking byte wall_millingpub start(video_params, rnd_addr) x := 0 y := 0 vsync_addr := long[video_params + constant(6 * 4)] random_addr := rnd_addr palette_addr := long[video_params + constant(5 * 4)] + constant(40 * 28) scroll_addr := palette_addr + 4 tile_addr := scroll_addr + constant(4 + 4 + 20 * 2) rockford_dir := 0 flash_cnt := 0 new_life_cnt := 0 blinking := 0 tapping := 0 wall_milling := 0 cognew(process, @stack)pub scroll_to(sx, sy) nx := sx ny := sypub rockford_reset blinking := 0 tapping := 0pub rockford_go(dir) rockford_dir := dir if rockford_dir <> 0 blinking := 0 tapping := 0pub flash flash_cnt := 6pub new_life new_life_cnt := 400pub milling_on wall_milling := 1pub milling_off wall_milling := 0pub process | i, n, cp, temp n := 0 i := 0 repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if x <> nx or y <> ny if x > nx x := x - 1 elseif x < nx x := x + 1 if y > ny y := y - 2 elseif y < ny y := y + 2 long[scroll_addr] := (x << 16) + y if i == 0 'rockford if rockford_dir > 0 cp := @rockford_right + n elseif rockford_dir < 0 cp := @rockford_left + n else cp := @rockford if n == 0 if (byte[random_addr] & $03) == 0 blinking := 1 else blinking := 0 if (byte[random_addr] & $0F) == 0 tapping ^= 1 ifnot blinking or tapping wordmove(tile_addr + constant(32 * $38), cp, 16) wordmove(tile_addr + constant(32 * $39), cp, 16) else if blinking cp := @rockford_bored + n wordmove(tile_addr + constant(32 * $38), cp, 8) ' top part only wordmove(tile_addr + constant(32 * $39), cp, 8) if tapping cp := @rockford_bored + 16 + n wordmove(tile_addr + constant(32 * $38 + 16), cp, 8) ' bottom part only wordmove(tile_addr + constant(32 * $39 + 16), cp, 8) ' diamonds cp := @diamonds + n wordmove(tile_addr + constant(32 * $14), cp, 16) ' update all 4 variants wordmove(tile_addr + constant(32 * $15), cp, 16) wordmove(tile_addr + constant(32 * $16), cp, 16) wordmove(tile_addr + constant(32 * $17), cp, 16) ' fireflies cp := @firefly + n wordmove(tile_addr + constant(32 * $08), cp, 16) ' update all 8 variants wordmove(tile_addr + constant(32 * $09), cp, 16) wordmove(tile_addr + constant(32 * $0A), cp, 16) wordmove(tile_addr + constant(32 * $0B), cp, 16) wordmove(tile_addr + constant(32 * $0C), cp, 16) wordmove(tile_addr + constant(32 * $0D), cp, 16) wordmove(tile_addr + constant(32 * $0E), cp, 16) wordmove(tile_addr + constant(32 * $0F), cp, 16) ' butterflies cp := @butterfly + n wordmove(tile_addr + constant(32 * $30), cp, 16) ' update all 8 variants wordmove(tile_addr + constant(32 * $31), cp, 16) wordmove(tile_addr + constant(32 * $32), cp, 16) wordmove(tile_addr + constant(32 * $33), cp, 16) wordmove(tile_addr + constant(32 * $34), cp, 16) wordmove(tile_addr + constant(32 * $35), cp, 16) wordmove(tile_addr + constant(32 * $36), cp, 16) wordmove(tile_addr + constant(32 * $37), cp, 16) ' amoeba cp := @amoeba + n wordmove(tile_addr + constant(32 * $3A), cp, 16) wordmove(tile_addr + constant(32 * $3B), cp, 16) ' magic wall if wall_milling wordmove(tile_addr + constant(32 * $03), @magic_wall + (n & $60), 16) else wordmove(tile_addr + constant(32 * $03), @wall, 16) ' flashing door if n & 128 wordmove(tile_addr + constant(32 * $05), @door_frame, 16) wordmove(tile_addr + constant(32 * $25), @door_frame, 16) else wordmove(tile_addr + constant(32 * $05), tile_addr + constant(32 * $07), 16) wordmove(tile_addr + constant(32 * $25), tile_addr + constant(32 * $07), 16) n += 32 if n => constant(32 * 8) n := 0 i ^= 1 ' scrolling steel wall cp := tile_addr + constant(32 * $3C) temp := word[cp] wordmove(cp, cp + 2, 15) word[cp + 31] := temp if flash_cnt > 0 if --flash_cnt > 0 byte[palette_addr + 0] := $07 else byte[palette_addr + 0] := $02 if i == 0 and new_life_cnt > 0 if new_life_cnt-- == 1 wordfill(tile_addr, $00, 16) else cp := byte[random_addr] byte[tile_addr] := cp byte[tile_addr + 9] := cp cp := byte[random_addr] byte[tile_addr + 8] := cp byte[tile_addr + 1] := cp cp := byte[random_addr] byte[tile_addr + 16] := cp byte[tile_addr + 25] := cp cp := byte[random_addr] byte[tile_addr + 24] := cp byte[tile_addr + 17] := cpdat' animated creatures, 8 frames per each' -- amoebaamoeba word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%0_2_3_3_3_2_2_0 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%0_2_3_3_3_2_2_0 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_2_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_2_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3' -- firefliesfirefly word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3' -- diamondsdiamonds word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_2_2_2_2_2_3_0 word %%0_1_1_1_1_1_2_0 word %%2_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%2_1_1_1_1_1_1_3 word %%1_2_2_2_2_2_2_2 word %%0_2_3_3_3_3_3_0 word %%0_1_3_3_3_3_2_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_2_1_1_1_1_3_0 word %%0_1_0_0_0_0_2_0 word %%2_0_0_0_0_0_0_3 word %%1_1_1_1_1_1_1_2 word %%2_2_2_2_2_2_2_3 word %%1_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_0 word %%0_1_2_2_2_2_2_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_2_0_0_0_0_3_0 word %%0_1_0_0_0_0_2_0 word %%2_1_1_1_1_1_1_3 word %%1_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_3 word %%1_3_3_3_3_3_3_2 word %%0_2_2_2_2_2_3_0 word %%0_1_1_1_1_1_2_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_2_0_0_0_0_3_0 word %%0_1_1_1_1_1_2_0 word %%2_2_2_2_2_2_2_3 word %%1_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%1_2_2_2_2_2_2_2 word %%0_2_1_1_1_1_3_0 word %%0_1_0_0_0_0_2_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_2_1_1_1_1_3_0 word %%0_1_2_2_2_2_2_0 word %%2_3_3_3_3_3_3_3 word %%1_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_3 word %%1_1_1_1_1_1_1_2 word %%0_2_0_0_0_0_3_0 word %%0_1_0_0_0_0_2_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_2_2_2_2_2_3_0 word %%0_1_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_3 word %%1_2_2_2_2_2_2_2 word %%2_1_1_1_1_1_1_3 word %%1_0_0_0_0_0_0_2 word %%0_2_0_0_0_0_3_0 word %%0_1_1_1_1_1_2_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_2_3_3_3_3_3_0 word %%0_1_3_3_3_3_2_0 word %%2_2_2_2_2_2_2_3 word %%1_1_1_1_1_1_1_2 word %%2_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%0_2_1_1_1_1_3_0 word %%0_1_2_2_2_2_2_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_2_3_3_3_3_3_0 word %%0_1_2_2_2_2_2_0 word %%2_1_1_1_1_1_1_3 word %%1_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_3 word %%1_1_1_1_1_1_1_2 word %%0_2_2_2_2_2_3_0 word %%0_1_3_3_3_3_2_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0' -- butterfliesbutterfly word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%0_3_0_0_0_0_2_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_1_0 word %%0_2_3_0_0_2_2_0 word %%0_1_2_0_0_1_1_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_1_1_3_2_1_1_0 word %%0_2_2_2_1_2_2_0 word %%0_3_3_0_0_2_3_0 word %%0_3_2_0_0_1_3_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_2_0 word %%0_1_0_0_0_0_1_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_0_0_0_0_2_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_1_0 word %%0_2_3_0_0_2_2_0 word %%0_1_2_0_0_1_1_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_1_1_3_2_1_1_0 word %%0_2_2_2_1_2_2_0 word %%0_3_3_0_0_2_3_0 word %%0_3_2_0_0_1_3_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_2_0 word %%0_1_0_0_0_0_1_0 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1' rockford' walking leftrockford_left word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_1_0 word %%0_1_0_0_0_0_0_3 word %%0_1_0_0_0_0_0_3 word %%3_3_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_1_0 word %%0_1_0_0_0_0_0_3 word %%0_1_0_0_0_0_0_3 word %%3_3_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_1_3 word %%0_0_1_0_0_0_0_3 word %%0_3_3_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_0_0_0 word %%0_0_1_0_1_1_1_0 word %%0_0_1_0_0_1_3_0 word %%0_3_3_0_0_0_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_1_1_3_0_0 word %%0_0_3_3_0_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_3_3_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_0_0_0 word %%0_0_1_0_1_1_1_0 word %%0_0_1_0_0_1_3_0 word %%0_3_3_0_0_0_3_0' walking rightrockford_right word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_1_1_3_3_1_0_0 word %%3_0_0_0_0_0_1_0 word %%3_0_0_0_0_0_1_0 word %%0_0_0_0_0_0_3_3 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_1_1_3_3_1_0_0 word %%3_0_0_0_0_0_1_0 word %%3_0_0_0_0_0_1_0 word %%0_0_0_0_0_0_3_3 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%3_1_1_1_0_1_0_0 word %%3_0_0_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_1_0_0 word %%0_1_1_1_0_1_0_0 word %%0_3_1_0_0_1_0_0 word %%0_3_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_3_1_1_0_0_0 word %%0_0_3_0_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_3_3_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_1_0_0 word %%0_1_1_1_0_1_0_0 word %%0_3_1_0_0_1_0_0 word %%0_3_0_0_0_3_3_0' blinking eyes / tapping footrockford_bored word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0' rockford, standingrockford word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_3_0_2_2_0_3_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0' diamond frame word %%0_0_0_1_1_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_3_0_0_3_0_0 word %%0_1_0_0_0_0_1_0 word %%0_3_0_0_0_0_3_0 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%3_0_0_0_0_0_0_3 word %%0_1_0_0_0_0_2_0 word %%0_3_0_0_0_0_3_0 word %%0_0_1_0_0_2_0_0 word %%0_0_3_0_0_3_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_3_3_0_0_0' dummy word %%3_3_0_0_0_0_3_3 word %%0_3_3_3_3_3_3_0 word %%3_3_2_3_3_2_3_3 word %%3_3_2_3_3_2_3_3 word %%3_3_3_3_3_3_3_3 word %%0_3_3_0_0_3_3_0 word %%0_0_3_3_0_3_0_0 word %%0_0_2_2_2_2_0_0 word %%1_1_2_2_2_2_1_0 word %%1_0_2_2_2_2_0_1 word %%0_0_2_2_2_2_1_0 word %%0_3_3_3_3_3_3_0 word %%0_3_3_0_0_3_3_0 word %%0_3_0_0_0_0_3_0 word %%3_3_0_0_0_0_3_0 word %%0_0_0_0_0_0_3_3' wallwall word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_2_0_2_2_2 word %%0_0_0_0_0_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_2_0_2_2_2_0_2 word %%0_0_0_0_0_0_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_2_0_2_2_2 word %%0_0_0_0_0_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_2_0_2_2_2_0_2 word %%0_0_0_0_0_0_0_0' door framedoor_frame word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2' magic wallmagic_wall word %%3_3_3_3_3_3_3_3 word %%3_2_3_3_3_2_3_3 word %%3_2_2_2_3_2_2_2 word %%3_0_0_0_3_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_3_3_3_0_3 word %%2_2_0_3_2_2_0_3 word %%0_0_0_3_0_0_0_3 word %%3_3_3_3_3_3_3_3 word %%3_2_3_3_3_2_3_3 word %%3_2_2_2_3_2_2_2 word %%3_0_0_0_3_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_3_3_3_0_3 word %%2_2_0_3_2_2_0_3 word %%0_0_0_3_0_0_0_3 word %%0_3_3_3_0_3_3_3 word %%0_3_3_3_0_3_3_3 word %%0_3_2_2_0_3_2_2 word %%0_3_0_0_0_3_0_0 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_3_3_3_2 word %%2_2_3_2_2_2_3_2 word %%0_0_3_0_0_0_3_0 word %%0_3_3_3_0_3_3_3 word %%0_3_3_3_0_3_3_3 word %%0_3_2_2_0_3_2_2 word %%0_3_0_0_0_3_0_0 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_3_3_3_2 word %%2_2_3_2_2_2_3_2 word %%0_0_3_0_0_0_3_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_3_2_0_2_3_2 word %%0_0_3_0_0_0_3_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_3_0_2_2_3_0_2 word %%0_3_0_0_0_3_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_3_2_0_2_3_2 word %%0_0_3_0_0_0_3_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_3_0_2_2_3_0_2 word %%0_3_0_0_0_3_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_3_0_2_2_3 word %%0_0_0_3_0_0_0_3 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%3_2_0_2_3_2_0_2 word %%3_0_0_0_3_0_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_3_0_2_2_3 word %%0_0_0_3_0_0_0_3 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%3_2_0_2_3_2_0_2 word %%3_0_0_0_3_0_0_0 \ No newline at end of file +' This cog takes care of the smooth scrolling and animates animated objects. +' Also: +' - flashes the screen when the game target is reached +' - signals about new life with random background pattern + +var + long x, y, nx, ny + long scroll_addr + long tile_addr + long palette_addr + long stack[12] + long rockford_dir + long random_addr + long vsync_addr + byte flash_cnt + byte new_life_cnt + byte tapping + byte blinking + byte wall_milling + +pub start(video_params, rnd_addr) + + x := 0 + y := 0 + + vsync_addr := long[video_params + constant(6 * 4)] + random_addr := rnd_addr + palette_addr := long[video_params + constant(5 * 4)] + constant(40 * 28) + scroll_addr := palette_addr + 4 + tile_addr := scroll_addr + constant(4 + 4 + 20 * 2) + + rockford_dir := 0 + flash_cnt := 0 + new_life_cnt := 0 + blinking := 0 + tapping := 0 + wall_milling := 0 + cognew(process, @stack) + +pub scroll_to(sx, sy) + + nx := sx + ny := sy + +pub rockford_reset + + blinking := 0 + tapping := 0 + +pub rockford_go(dir) + + rockford_dir := dir + if rockford_dir <> 0 + blinking := 0 + tapping := 0 + +pub flash + + flash_cnt := 6 + +pub new_life + + new_life_cnt := 400 + +pub milling_on + + wall_milling := 1 + +pub milling_off + + wall_milling := 0 + +pub process | i, n, cp, temp + + n := 0 + i := 0 + + repeat + + 'wait for vsync + repeat while byte[vsync_addr] == 0 + repeat while byte[vsync_addr] <> 0 + + if x <> nx or y <> ny + if x > nx + x := x - 1 + elseif x < nx + x := x + 1 + if y > ny + y := y - 2 + elseif y < ny + y := y + 2 + long[scroll_addr] := (x << 16) + y + + if i == 0 + 'rockford + if rockford_dir > 0 + cp := @rockford_right + n + elseif rockford_dir < 0 + cp := @rockford_left + n + else + cp := @rockford + if n == 0 + if (byte[random_addr] & $03) == 0 + blinking := 1 + else + blinking := 0 + if (byte[random_addr] & $0F) == 0 + tapping ^= 1 + ifnot blinking or tapping + wordmove(tile_addr + constant(32 * $38), cp, 16) + wordmove(tile_addr + constant(32 * $39), cp, 16) + else + if blinking + cp := @rockford_bored + n + wordmove(tile_addr + constant(32 * $38), cp, 8) ' top part only + wordmove(tile_addr + constant(32 * $39), cp, 8) + if tapping + cp := @rockford_bored + 16 + n + wordmove(tile_addr + constant(32 * $38 + 16), cp, 8) ' bottom part only + wordmove(tile_addr + constant(32 * $39 + 16), cp, 8) + + ' diamonds + cp := @diamonds + n + wordmove(tile_addr + constant(32 * $14), cp, 16) ' update all 4 variants + wordmove(tile_addr + constant(32 * $15), cp, 16) + wordmove(tile_addr + constant(32 * $16), cp, 16) + wordmove(tile_addr + constant(32 * $17), cp, 16) + ' fireflies + cp := @firefly + n + wordmove(tile_addr + constant(32 * $08), cp, 16) ' update all 8 variants + wordmove(tile_addr + constant(32 * $09), cp, 16) + wordmove(tile_addr + constant(32 * $0A), cp, 16) + wordmove(tile_addr + constant(32 * $0B), cp, 16) + wordmove(tile_addr + constant(32 * $0C), cp, 16) + wordmove(tile_addr + constant(32 * $0D), cp, 16) + wordmove(tile_addr + constant(32 * $0E), cp, 16) + wordmove(tile_addr + constant(32 * $0F), cp, 16) + ' butterflies + cp := @butterfly + n + wordmove(tile_addr + constant(32 * $30), cp, 16) ' update all 8 variants + wordmove(tile_addr + constant(32 * $31), cp, 16) + wordmove(tile_addr + constant(32 * $32), cp, 16) + wordmove(tile_addr + constant(32 * $33), cp, 16) + wordmove(tile_addr + constant(32 * $34), cp, 16) + wordmove(tile_addr + constant(32 * $35), cp, 16) + wordmove(tile_addr + constant(32 * $36), cp, 16) + wordmove(tile_addr + constant(32 * $37), cp, 16) + ' amoeba + cp := @amoeba + n + wordmove(tile_addr + constant(32 * $3A), cp, 16) + wordmove(tile_addr + constant(32 * $3B), cp, 16) + ' magic wall + if wall_milling + wordmove(tile_addr + constant(32 * $03), @magic_wall + (n & $60), 16) + else + wordmove(tile_addr + constant(32 * $03), @wall, 16) + ' flashing door + if n & 128 + wordmove(tile_addr + constant(32 * $05), @door_frame, 16) + wordmove(tile_addr + constant(32 * $25), @door_frame, 16) + else + wordmove(tile_addr + constant(32 * $05), tile_addr + constant(32 * $07), 16) + wordmove(tile_addr + constant(32 * $25), tile_addr + constant(32 * $07), 16) + + n += 32 + if n => constant(32 * 8) + n := 0 + i ^= 1 + + ' scrolling steel wall + cp := tile_addr + constant(32 * $3C) + temp := word[cp] + wordmove(cp, cp + 2, 15) + word[cp + 31] := temp + + if flash_cnt > 0 + if --flash_cnt > 0 + byte[palette_addr + 0] := $07 + else + byte[palette_addr + 0] := $02 + + if i == 0 and new_life_cnt > 0 + if new_life_cnt-- == 1 + wordfill(tile_addr, $00, 16) + else + cp := byte[random_addr] + byte[tile_addr] := cp + byte[tile_addr + 9] := cp + cp := byte[random_addr] + byte[tile_addr + 8] := cp + byte[tile_addr + 1] := cp + cp := byte[random_addr] + byte[tile_addr + 16] := cp + byte[tile_addr + 25] := cp + cp := byte[random_addr] + byte[tile_addr + 24] := cp + byte[tile_addr + 17] := cp + +dat + +' animated creatures, 8 frames per each +' -- amoeba +amoeba + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_3 + word %%0_2_3_3_3_3_3_2 + word %%0_2_3_3_3_3_3_2 + word %%0_2_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_2 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%2_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_3 + word %%0_2_3_3_3_3_3_2 + word %%0_2_3_3_3_3_3_2 + word %%0_2_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_2 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%2_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_2_0_2_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_2_0 + word %%0_2_3_3_3_2_2_0 + word %%2_3_3_3_3_3_2_0 + word %%3_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_2 + word %%0_2_3_3_3_3_2_0 + word %%2_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_2_0_2_3_3 + + word %%3_3_3_2_0_2_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_2_0 + word %%0_2_3_3_3_2_2_0 + word %%2_3_3_3_3_3_2_0 + word %%3_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_2 + word %%0_2_3_3_3_3_2_0 + word %%2_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_2_0_2_3_3 + + word %%3_3_2_0_0_0_2_3 + word %%3_3_3_2_0_2_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_2_0 + word %%3_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_2_0_2_3_3 + word %%3_3_2_0_0_0_2_3 + + word %%3_3_2_0_0_0_2_3 + word %%3_3_3_2_0_2_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_2_0 + word %%3_3_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_2_0_2_3_3 + word %%3_3_2_0_0_0_2_3 + + word %%3_3_3_2_0_2_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_3 + word %%0_2_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_2_3_3_3_3_3_2 + word %%0_2_3_3_3_3_2_0 + word %%2_2_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_2_0_2_3_3 + + word %%3_3_3_2_0_2_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_3_3_3_3_3_3_3 + word %%0_2_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%2_2_3_3_3_3_3_2 + word %%0_2_3_3_3_3_2_0 + word %%2_2_3_3_3_3_3_2 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_2_3_3_3 + word %%3_3_3_2_0_2_3_3 + +' -- fireflies +firefly + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_3_3_2_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_2_2_2_2_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_2_2_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_3_3_3_3_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_0_0_2_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_2_2_2_2_3_2 + word %%2_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_2_2_2_2_2_2_3 + word %%3_2_2_2_2_2_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_2_2_2_2_2_3 + word %%3_2_2_2_2_2_2_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_2_2_2_2_2_2_3 + word %%3_2_2_2_2_2_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_2_2_0_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_0_0_0_0_2_3 + word %%3_2_2_2_2_2_2_3 + word %%3_2_2_2_2_2_2_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + +' -- diamonds +diamonds + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_2_2_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_2_2_2_0_0 + word %%0_2_1_1_1_1_3_0 + word %%0_1_0_0_0_0_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_1_1_1_1_1_1_2 + word %%2_2_2_2_2_2_2_3 + word %%1_3_3_3_3_3_3_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_2_2_2_2_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_0_0_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_2_2_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_2_0_0_0_0_3_0 + word %%0_1_0_0_0_0_2_0 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%2_3_3_3_3_3_3_3 + word %%1_3_3_3_3_3_3_2 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%0_0_2_0_0_3_0_0 + word %%0_0_1_0_0_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_0_0_2_0_0 + word %%0_2_0_0_0_0_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_2_2_2_2_2_2_3 + word %%1_3_3_3_3_3_3_2 + word %%2_3_3_3_3_3_3_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_1_1_1_1_3_0 + word %%0_1_0_0_0_0_2_0 + word %%0_0_2_0_0_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_0_0_3_0_0 + word %%0_0_1_0_0_2_0_0 + word %%0_2_1_1_1_1_3_0 + word %%0_1_2_2_2_2_2_0 + word %%2_3_3_3_3_3_3_3 + word %%1_3_3_3_3_3_3_2 + word %%2_2_2_2_2_2_2_3 + word %%1_1_1_1_1_1_1_2 + word %%0_2_0_0_0_0_3_0 + word %%0_1_0_0_0_0_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_2_2_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_0_0_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_3_3_3_3_2_0 + word %%2_3_3_3_3_3_3_3 + word %%1_2_2_2_2_2_2_2 + word %%2_1_1_1_1_1_1_3 + word %%1_0_0_0_0_0_0_2 + word %%0_2_0_0_0_0_3_0 + word %%0_1_1_1_1_1_2_0 + word %%0_0_2_2_2_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_2_2_2_0_0 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%2_2_2_2_2_2_2_3 + word %%1_1_1_1_1_1_1_2 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%0_2_1_1_1_1_3_0 + word %%0_1_2_2_2_2_2_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_2_2_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_3_3_3_3_3_0 + word %%0_1_2_2_2_2_2_0 + word %%2_1_1_1_1_1_1_3 + word %%1_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_3 + word %%1_1_1_1_1_1_1_2 + word %%0_2_2_2_2_2_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_2_2_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + +' -- butterflies +butterfly + word %%3_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_1 + word %%3_3_0_0_0_0_2_3 + word %%3_2_0_0_0_0_1_3 + word %%2_2_3_0_0_2_2_2 + word %%1_1_2_0_0_1_1_1 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%1_1_1_3_2_1_1_1 + word %%2_2_2_2_1_2_2_2 + word %%3_3_3_0_0_2_3_3 + word %%3_3_2_0_0_1_3_3 + word %%2_3_0_0_0_0_2_2 + word %%1_2_0_0_0_0_1_1 + word %%2_0_0_0_0_0_0_1 + word %%1_0_0_0_0_0_0_1 + + word %%3_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_1 + word %%3_3_0_0_0_0_2_3 + word %%3_2_0_0_0_0_1_3 + word %%2_2_3_0_0_2_2_2 + word %%1_1_2_0_0_1_1_1 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%1_1_1_3_2_1_1_1 + word %%2_2_2_2_1_2_2_2 + word %%3_3_3_0_0_2_3_3 + word %%3_3_2_0_0_1_3_3 + word %%2_3_0_0_0_0_2_2 + word %%1_2_0_0_0_0_1_1 + word %%2_0_0_0_0_0_0_1 + word %%1_0_0_0_0_0_0_1 + + word %%0_3_0_0_0_0_2_0 + word %%0_3_0_0_0_0_2_0 + word %%0_2_0_0_0_0_1_0 + word %%0_2_0_0_0_0_1_0 + word %%0_2_3_0_0_2_2_0 + word %%0_1_2_0_0_1_1_0 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%0_1_1_3_2_1_1_0 + word %%0_2_2_2_1_2_2_0 + word %%0_3_3_0_0_2_3_0 + word %%0_3_2_0_0_1_3_0 + word %%0_3_0_0_0_0_2_0 + word %%0_2_0_0_0_0_1_0 + word %%0_2_0_0_0_0_2_0 + word %%0_1_0_0_0_0_1_0 + + word %%0_0_3_0_0_2_0_0 + word %%0_0_2_0_0_1_0_0 + word %%0_0_3_0_0_2_0_0 + word %%0_0_2_0_0_1_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + + word %%0_0_3_0_0_2_0_0 + word %%0_0_2_0_0_1_0_0 + word %%0_0_3_0_0_2_0_0 + word %%0_0_2_0_0_1_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_1_0_0_1_0_0 + + word %%0_3_0_0_0_0_2_0 + word %%0_3_0_0_0_0_2_0 + word %%0_2_0_0_0_0_1_0 + word %%0_2_0_0_0_0_1_0 + word %%0_2_3_0_0_2_2_0 + word %%0_1_2_0_0_1_1_0 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%0_1_1_3_2_1_1_0 + word %%0_2_2_2_1_2_2_0 + word %%0_3_3_0_0_2_3_0 + word %%0_3_2_0_0_1_3_0 + word %%0_3_0_0_0_0_2_0 + word %%0_2_0_0_0_0_1_0 + word %%0_2_0_0_0_0_2_0 + word %%0_1_0_0_0_0_1_0 + + word %%3_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_1 + word %%3_3_0_0_0_0_2_3 + word %%3_2_0_0_0_0_1_3 + word %%2_2_3_0_0_2_2_2 + word %%1_1_2_0_0_1_1_1 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%1_1_1_3_2_1_1_1 + word %%2_2_2_2_1_2_2_2 + word %%3_3_3_0_0_2_3_3 + word %%3_3_2_0_0_1_3_3 + word %%2_3_0_0_0_0_2_2 + word %%1_2_0_0_0_0_1_1 + word %%2_0_0_0_0_0_0_1 + word %%1_0_0_0_0_0_0_1 + + word %%3_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_1 + word %%3_3_0_0_0_0_2_3 + word %%3_2_0_0_0_0_1_3 + word %%2_2_3_0_0_2_2_2 + word %%1_1_2_0_0_1_1_1 + word %%0_0_0_3_2_0_0_0 + word %%0_0_0_2_1_0_0_0 + word %%1_1_1_3_2_1_1_1 + word %%2_2_2_2_1_2_2_2 + word %%3_3_3_0_0_2_3_3 + word %%3_3_2_0_0_1_3_3 + word %%2_3_0_0_0_0_2_2 + word %%1_2_0_0_0_0_1_1 + word %%2_0_0_0_0_0_0_1 + word %%1_0_0_0_0_0_0_1 + +' rockford +' walking left +rockford_left + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_1_0 + word %%0_1_0_0_0_0_0_3 + word %%0_1_0_0_0_0_0_3 + word %%3_3_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_1_0 + word %%0_1_0_0_0_0_0_3 + word %%0_1_0_0_0_0_0_3 + word %%3_3_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_1_3 + word %%0_0_1_0_0_0_0_3 + word %%0_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_0_0_0 + word %%0_0_1_0_1_1_1_0 + word %%0_0_1_0_0_1_3_0 + word %%0_3_3_0_0_0_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_1_1_0_0_0 + word %%0_0_0_1_1_3_0_0 + word %%0_0_3_3_0_3_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_1_1_0_0_0 + word %%0_0_1_1_1_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_1_1_0_0_0 + word %%0_0_1_1_1_0_0_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_2_0_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_0_0_0 + word %%0_0_1_0_1_1_1_0 + word %%0_0_1_0_0_1_3_0 + word %%0_3_3_0_0_0_3_0 + +' walking right +rockford_right + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_1_1_3_3_1_0_0 + word %%3_0_0_0_0_0_1_0 + word %%3_0_0_0_0_0_1_0 + word %%0_0_0_0_0_0_3_3 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_1_1_3_3_1_0_0 + word %%3_0_0_0_0_0_1_0 + word %%3_0_0_0_0_0_1_0 + word %%0_0_0_0_0_0_3_3 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%3_1_1_1_0_1_0_0 + word %%3_0_0_0_0_1_0_0 + word %%0_0_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_1_0_0 + word %%0_1_1_1_0_1_0_0 + word %%0_3_1_0_0_1_0_0 + word %%0_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_1_1_0_0_0 + word %%0_0_3_1_1_0_0_0 + word %%0_0_3_0_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_1_1_1_0_0 + word %%0_0_0_1_1_1_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_1_1_1_0_0 + word %%0_0_0_1_1_1_0_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_3_3_1_0_0 + word %%0_1_1_1_0_1_0_0 + word %%0_3_1_0_0_1_0_0 + word %%0_3_0_0_0_3_3_0 + +' blinking eyes / tapping foot +rockford_bored + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_1_0_0 + word %%0_0_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_1_0_0 + word %%0_0_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_1_0_0 + word %%0_0_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_1_0_0 + word %%0_0_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + +' rockford, standing +rockford + word %%0_0_0_0_0_0_0_0 + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_3_0_2_2_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + +' diamond frame + word %%0_0_0_1_1_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_3_0_0_3_0_0 + word %%0_1_0_0_0_0_1_0 + word %%0_3_0_0_0_0_3_0 + word %%1_0_0_0_0_0_0_1 + word %%3_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%3_0_0_0_0_0_0_3 + word %%0_1_0_0_0_0_2_0 + word %%0_3_0_0_0_0_3_0 + word %%0_0_1_0_0_2_0_0 + word %%0_0_3_0_0_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + +' dummy + word %%3_3_0_0_0_0_3_3 + word %%0_3_3_3_3_3_3_0 + word %%3_3_2_3_3_2_3_3 + word %%3_3_2_3_3_2_3_3 + word %%3_3_3_3_3_3_3_3 + word %%0_3_3_0_0_3_3_0 + word %%0_0_3_3_0_3_0_0 + word %%0_0_2_2_2_2_0_0 + word %%1_1_2_2_2_2_1_0 + word %%1_0_2_2_2_2_0_1 + word %%0_0_2_2_2_2_1_0 + word %%0_3_3_3_3_3_3_0 + word %%0_3_3_0_0_3_3_0 + word %%0_3_0_0_0_0_3_0 + word %%3_3_0_0_0_0_3_0 + word %%0_0_0_0_0_0_3_3 + +' wall +wall + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + +' door frame +door_frame + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_2_2_2_2_2_2_2 + +' magic wall +magic_wall + word %%3_3_3_3_3_3_3_3 + word %%3_2_3_3_3_2_3_3 + word %%3_2_2_2_3_2_2_2 + word %%3_0_0_0_3_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_3_3_3_0_3 + word %%2_2_0_3_2_2_0_3 + word %%0_0_0_3_0_0_0_3 + word %%3_3_3_3_3_3_3_3 + word %%3_2_3_3_3_2_3_3 + word %%3_2_2_2_3_2_2_2 + word %%3_0_0_0_3_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_3_3_3_0_3 + word %%2_2_0_3_2_2_0_3 + word %%0_0_0_3_0_0_0_3 + + word %%0_3_3_3_0_3_3_3 + word %%0_3_3_3_0_3_3_3 + word %%0_3_2_2_0_3_2_2 + word %%0_3_0_0_0_3_0_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_2_3_3_3_2 + word %%2_2_3_2_2_2_3_2 + word %%0_0_3_0_0_0_3_0 + word %%0_3_3_3_0_3_3_3 + word %%0_3_3_3_0_3_3_3 + word %%0_3_2_2_0_3_2_2 + word %%0_3_0_0_0_3_0_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_2_3_3_3_2 + word %%2_2_3_2_2_2_3_2 + word %%0_0_3_0_0_0_3_0 + + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_3_2_0_2_3_2 + word %%0_0_3_0_0_0_3_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_3_0_2_2_3_0_2 + word %%0_3_0_0_0_3_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_3_2_0_2_3_2 + word %%0_0_3_0_0_0_3_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_3_0_2_2_3_0_2 + word %%0_3_0_0_0_3_0_0 + + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_3_0_2_2_3 + word %%0_0_0_3_0_0_0_3 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%3_2_0_2_3_2_0_2 + word %%3_0_0_0_3_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_3_0_2_2_3 + word %%0_0_0_3_0_0_0_3 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%3_2_0_2_3_2_0_2 + word %%3_0_0_0_3_0_0_0 + \ No newline at end of file diff --git a/source/boulder/bellatrix/Status.spin b/source/boulder/bellatrix/Status.spin index dd1fb5c..0e435fc 100644 --- a/source/boulder/bellatrix/Status.spin +++ b/source/boulder/bellatrix/Status.spin @@ -1 +1,220 @@ -' This cog handles the status line.' Also keeps the real-time countercon STATUS_NONE, STATUS_PRE, STATUS_GAME, STATUS_PAUSE, STATUS_OUT_OF_TIME, STATUS_GAME_OVERvar long status_addr long stack[20] long vsync_addr long score byte ticks_per_sec byte tick_count byte time byte diamond_count byte diamond_value byte diamonds_needed byte player byte men byte cave byte level byte status_mode byte update byte status_temp[20*2] byte toggle byte decbuf[6]pub start(video_params) vsync_addr := long[video_params + constant(6 * 4)] status_addr := long[video_params + constant(5 * 4)] + constant(40 * 28 + 4 + 4) time := 0 status_mode := STATUS_NONE update := true toggle := 0 if long[video_params + constant(4 * 4)] == 0 ticks_per_sec := 60 'NTSC else ticks_per_sec := 50 'PAL cognew(process, @stack)pub player_params(p, m, c, l, s) player := p men := m cave := c level := l score := s pub cave_params(dn, dv, t) diamonds_needed := dn diamond_value := dv diamond_count := 0 time := t tick_count := ticks_per_secpub set_time(t) tick_count := ticks_per_sec time := t update := truepub get_time return timepub set_mode(m) status_mode := m update := truepub set_score(s) score := s update := truepub set_diamond_value(dv) diamond_value := dv update := truepub set_diamond_count(n) diamond_count := n update := truepub process repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if update update := false if status_mode == STATUS_NONE long[status_addr] &= !1 else long[status_addr] |= 1 if toggle longmove(status_addr, @status_temp, 10) toggle := 0 if status_mode == STATUS_PRE bytefill(status_addr + constant(4 + 20), $06, 20) if cave > 16 text_out(status_addr + 4, @bonus_life, 20) else text_out(status_addr + 4, @pre, 20) byte[status_addr + constant(4 + 8)] := player + $80 byte[status_addr + constant(4 + 11)] := men + $80 byte[status_addr + constant(4 + 17)] := cave + $90 byte[status_addr + constant(4 + 19)] := level + $81 elseif status_mode == STATUS_GAME byte[status_addr + constant(4 + 0)] := $90 if diamond_count => diamonds_needed byte[status_addr + constant(4 + 1)] := $AC byte[status_addr + constant(4 + 2)] := $AC byte[status_addr + constant(4 + 21)] := $06 byte[status_addr + constant(4 + 22)] := $06 else convert_to_dec(diamonds_needed, 2) byte[status_addr + constant(4 + 1)] := decbuf[1] byte[status_addr + constant(4 + 2)] := decbuf[0] byte[status_addr + constant(4 + 21)] := $9D byte[status_addr + constant(4 + 22)] := $9D byte[status_addr + constant(4 + 3)] := $AC convert_to_dec(diamond_value, 2) byte[status_addr + constant(4 + 4)] := decbuf[1] byte[status_addr + constant(4 + 5)] := decbuf[0] byte[status_addr + constant(4 + 6)] := $90 convert_to_dec(diamond_count, 2) byte[status_addr + constant(4 + 7)] := decbuf[1] byte[status_addr + constant(4 + 8)] := decbuf[0] byte[status_addr + constant(4 + 9)] := $90 convert_to_dec(time, 3) byte[status_addr + constant(4 + 10)] := decbuf[2] byte[status_addr + constant(4 + 11)] := decbuf[1] byte[status_addr + constant(4 + 12)] := decbuf[0] byte[status_addr + constant(4 + 13)] := $90 convert_to_dec(score, 6) byte[status_addr + constant(4 + 14)] := decbuf[5] byte[status_addr + constant(4 + 15)] := decbuf[4] byte[status_addr + constant(4 + 16)] := decbuf[3] byte[status_addr + constant(4 + 17)] := decbuf[2] byte[status_addr + constant(4 + 18)] := decbuf[1] byte[status_addr + constant(4 + 19)] := decbuf[0] byte[status_addr + constant(4 + 27)] := $9D byte[status_addr + constant(4 + 28)] := $9D elseif status_mode == STATUS_GAME_OVER bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @game_over, 20) if --tick_count == 0 tick_count := ticks_per_sec if status_mode == STATUS_GAME if time > 0 convert_to_dec(--time, 3) byte[status_addr + constant(4 + 10)] := decbuf[2] byte[status_addr + constant(4 + 11)] := decbuf[1] byte[status_addr + constant(4 + 12)] := decbuf[0] elseif status_mode == STATUS_PAUSE if toggle longmove(status_addr, @status_temp, 10) toggle := 0 else longmove(@status_temp, status_addr, 10) bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @pause, 20) toggle := 1 elseif status_mode == STATUS_OUT_OF_TIME 'out of time if toggle longmove(status_addr, @status_temp, 10) toggle := 0 else longmove(@status_temp, status_addr, 10) bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @out_of_time, 20) toggle := 1pub convert_to_dec(val, len) | i repeat i from 0 to len-1 decbuf[i] := val // 10 + $80 val /= 10 pub text_out(addr, str, len) | i, c repeat i from 0 to len-1 c := byte[str + i] if c == $20 byte[addr + i] := $90 elseif c == $2C byte[addr + i] := $AF elseif c == $2F byte[addr + i] := $8C else byte[addr + i] := c + $50 datpre byte " PLAYER , MEN / "out_of_time byte " OUT OF TIME "pause byte " SPACEBAR TO RESUME "bonus_life byte " B O N U S L I F E "game_over byte " G A M E O V E R " \ No newline at end of file +' This cog handles the status line. +' Also keeps the real-time counter + +con + + STATUS_NONE, STATUS_PRE, STATUS_GAME, STATUS_PAUSE, STATUS_OUT_OF_TIME, STATUS_GAME_OVER + +var + long status_addr + long stack[20] + long vsync_addr + long score + byte ticks_per_sec + byte tick_count + byte time + byte diamond_count + byte diamond_value + byte diamonds_needed + byte player + byte men + byte cave + byte level + byte status_mode + byte update + byte status_temp[20*2] + byte toggle + byte decbuf[6] + +pub start(video_params) + + vsync_addr := long[video_params + constant(6 * 4)] + status_addr := long[video_params + constant(5 * 4)] + constant(40 * 28 + 4 + 4) + + time := 0 + status_mode := STATUS_NONE + update := true + toggle := 0 + + if long[video_params + constant(4 * 4)] == 0 + ticks_per_sec := 60 'NTSC + else + ticks_per_sec := 50 'PAL + + cognew(process, @stack) + +pub player_params(p, m, c, l, s) + + player := p + men := m + cave := c + level := l + score := s + +pub cave_params(dn, dv, t) + + diamonds_needed := dn + diamond_value := dv + diamond_count := 0 + time := t + tick_count := ticks_per_sec + +pub set_time(t) + + tick_count := ticks_per_sec + time := t + update := true + +pub get_time + + return time + +pub set_mode(m) + + status_mode := m + update := true + +pub set_score(s) + + score := s + update := true + +pub set_diamond_value(dv) + + diamond_value := dv + update := true + +pub set_diamond_count(n) + + diamond_count := n + update := true + +pub process + + repeat + + 'wait for vsync + repeat while byte[vsync_addr] == 0 + repeat while byte[vsync_addr] <> 0 + + if update + update := false + + if status_mode == STATUS_NONE + long[status_addr] &= !1 + else + long[status_addr] |= 1 + + if toggle + longmove(status_addr, @status_temp, 10) + toggle := 0 + + if status_mode == STATUS_PRE + bytefill(status_addr + constant(4 + 20), $06, 20) + if cave > 16 + text_out(status_addr + 4, @bonus_life, 20) + else + text_out(status_addr + 4, @pre, 20) + byte[status_addr + constant(4 + 8)] := player + $80 + byte[status_addr + constant(4 + 11)] := men + $80 + byte[status_addr + constant(4 + 17)] := cave + $90 + byte[status_addr + constant(4 + 19)] := level + $81 + + elseif status_mode == STATUS_GAME + byte[status_addr + constant(4 + 0)] := $90 + if diamond_count => diamonds_needed + byte[status_addr + constant(4 + 1)] := $AC + byte[status_addr + constant(4 + 2)] := $AC + byte[status_addr + constant(4 + 21)] := $06 + byte[status_addr + constant(4 + 22)] := $06 + else + convert_to_dec(diamonds_needed, 2) + byte[status_addr + constant(4 + 1)] := decbuf[1] + byte[status_addr + constant(4 + 2)] := decbuf[0] + byte[status_addr + constant(4 + 21)] := $9D + byte[status_addr + constant(4 + 22)] := $9D + + byte[status_addr + constant(4 + 3)] := $AC + convert_to_dec(diamond_value, 2) + byte[status_addr + constant(4 + 4)] := decbuf[1] + byte[status_addr + constant(4 + 5)] := decbuf[0] + byte[status_addr + constant(4 + 6)] := $90 + convert_to_dec(diamond_count, 2) + byte[status_addr + constant(4 + 7)] := decbuf[1] + byte[status_addr + constant(4 + 8)] := decbuf[0] + byte[status_addr + constant(4 + 9)] := $90 + convert_to_dec(time, 3) + byte[status_addr + constant(4 + 10)] := decbuf[2] + byte[status_addr + constant(4 + 11)] := decbuf[1] + byte[status_addr + constant(4 + 12)] := decbuf[0] + byte[status_addr + constant(4 + 13)] := $90 + convert_to_dec(score, 6) + byte[status_addr + constant(4 + 14)] := decbuf[5] + byte[status_addr + constant(4 + 15)] := decbuf[4] + byte[status_addr + constant(4 + 16)] := decbuf[3] + byte[status_addr + constant(4 + 17)] := decbuf[2] + byte[status_addr + constant(4 + 18)] := decbuf[1] + byte[status_addr + constant(4 + 19)] := decbuf[0] + + byte[status_addr + constant(4 + 27)] := $9D + byte[status_addr + constant(4 + 28)] := $9D + + elseif status_mode == STATUS_GAME_OVER + bytefill(status_addr + constant(4 + 20), $06, 20) + text_out(status_addr + 4, @game_over, 20) + + if --tick_count == 0 + tick_count := ticks_per_sec + + if status_mode == STATUS_GAME + if time > 0 + convert_to_dec(--time, 3) + byte[status_addr + constant(4 + 10)] := decbuf[2] + byte[status_addr + constant(4 + 11)] := decbuf[1] + byte[status_addr + constant(4 + 12)] := decbuf[0] + + elseif status_mode == STATUS_PAUSE + if toggle + longmove(status_addr, @status_temp, 10) + toggle := 0 + else + longmove(@status_temp, status_addr, 10) + bytefill(status_addr + constant(4 + 20), $06, 20) + text_out(status_addr + 4, @pause, 20) + toggle := 1 + + elseif status_mode == STATUS_OUT_OF_TIME + 'out of time + if toggle + longmove(status_addr, @status_temp, 10) + toggle := 0 + else + longmove(@status_temp, status_addr, 10) + bytefill(status_addr + constant(4 + 20), $06, 20) + text_out(status_addr + 4, @out_of_time, 20) + toggle := 1 + +pub convert_to_dec(val, len) | i + repeat i from 0 to len-1 + decbuf[i] := val // 10 + $80 + val /= 10 + +pub text_out(addr, str, len) | i, c + repeat i from 0 to len-1 + c := byte[str + i] + if c == $20 + byte[addr + i] := $90 + elseif c == $2C + byte[addr + i] := $AF + elseif c == $2F + byte[addr + i] := $8C + else + byte[addr + i] := c + $50 + +dat + +pre byte " PLAYER , MEN / " +out_of_time byte " OUT OF TIME " +pause byte " SPACEBAR TO RESUME " +bonus_life byte " B O N U S L I F E " +game_over byte " G A M E O V E R " \ No newline at end of file diff --git a/source/boulder/bellatrix/bd_ntsc.spin b/source/boulder/bellatrix/bd_ntsc.spin deleted file mode 100644 index 3cf8733..0000000 --- a/source/boulder/bellatrix/bd_ntsc.spin +++ /dev/null @@ -1,3812 +0,0 @@ -'Boulderdash, for Hydra or Demo Board. -'Version 0.95 -'Released to the public domain. - -' Changes: -' 2009-11-10 - Modified for the Demo Board. -' - Added 'readkey' routine to allow playing the game from the keyboard. -' - Rockford now can be moved around and the screen scrolls automatically. -' 2009-11-12 - Halved tile horizontal resolution to eliminate redundant pixel pairs -' (and BoulderDash uses 8x16 tiles anyway). This also halves tile memory -' requirements. -' - The scroller now runs in a separate cog. -' 2009-11-13 - Changed pixel clock settings in order to display 20 tiles per line, -' as in the classic C64/Atari BoulderDash I. -' - Added code to handle boulders and diamonds. Rockford cannot push yet -' boulders or pick-up diamonds. -' 2009-11-14 - Reversed pixel order in video driver in order to avoid having to define -' mirrored tiles. -' - Added more tiles, hopefully all the characters are there. -' - The scroller cog now also handles animated characters. -' - Rockford can pick-up diamonds and the screen flashes when diamond count -' reaches the target. -' - Rockford now walks facing in the right direction and gets "bored". -' 2009-11-15 - Added an optional status line. -' - Added a character font for the status line. -' - Main game loop moved to a separate routine. -' - Boulders can be pushed around. -' - New routines to cover and uncover the screen. -' - Added an infinite loop to the main routine, pressing ESC restarts the -' game. -' 2009-11-16 - Inbox now morphs into Rockford. -' - Rockford can exit through the Outbox. -' 2009-11-17 - Added hardware detection feature (Hydra, Demo Board, etc.) Video driver -' changed accordingly. Not sure if keyboard will work on Hydra. -' - Falling boulders and diamonds now can kill Rockford. -' - Added PAL timings table to video driver, but PAL mode is not working yet. -' 2009-11-18 - Synchronized scroller to vertical sync, scrolling is totally smooth now. -' - PAL mode now works. -' 2009-11-25 - Started adding support for fireflies and butterflies. Had to split the -' case statement in the main game loop into sections due to poor performance. -' - Added code to decode raw cave data of original Atari/C64 BoulderDash I. -' You can now import your favorite caves :) -' 2009-11-26 - Fireflies and butterflies now explode in contact with Rockford. -' - Time counts down, but there is no "out of time" condition yet. -' 2009-11-27 - Implemented the "pick without moving" Rockford trick (use left CTRL key). -' - Stop cave when time runs out. -' - Do not advance to next cave until current one is successfully completed. -' Game is now playable! Use LeftCtrl + LeftShift as a "cheat" to move to -' next cave without finishing the current one. The Escape key restarts the -' current cave. Sorry, no score points yet. -' 2009-11-28 - Status line now handled by a separate cog. -' - Flashing "Out of time" message when time runs out. -' - Space bar now pauses game. -' - Score points implemented. -' - No more unlimited lifes, sorry ;))) -' - New life every 500 points. -' 2009-11-29 - Using a table of codes to reset the 'scanned' flag avoids a second case -' statement and improves performance. -' - Implemented amoebas and magic wall. Now all the original caves work! -' - Added all the original BoulderDash I caves (except the intermissions) -' - Added a Level variable. After successfully finishing the last cave the -' game starts again from the first one of the next difficulty level. -' 2009-11-30 - Fixed a bug in amoeba handling that caused cave M to crash. -' 2009-12-02 - Game controller apparently does not like to be read too fast. -' - Added intermission caves. -' 2009-12-04 - Aborting the current cave will cost you a life. -' - Restart (or exit) automatically the cave if "Out of time" has been -' flashing for more than a minute without user input. -' - Throtle down Rockford a bit in levels 1 and 2 (is running too fast!) -' 2009-12-05 - Added the title screen (had a hard time scrolling the background behind -' those big letters!). -' - Starting cave and level can be selected from the title screen. -' - Run a demo if the title screen has been inactive for about a minute. -' 2009-12-06 - Fixed boulder/diamond rolling off: they must move to the side first, -' not directly diagonally. -' - Added a preliminary sound object. Nothing there yet. -' - Bonus points at the end of the cave increase with difficulty level. -' 2009-12-07 - First steps towards SID emulation via PWM. Single voice waveform generation -' already works (well, sort of). No envelope control yet. -' 2009-12-08 - SID emulator: noise waveform, amplitude control, 3 voices. Envelope -' control using a separate cog (see the ChangeLog in the SIDemu.spin file). -' 2009-12-09 - Integrated the SID emulator into the game, running out of cogs. -' - Got the main tune working. -' - Added a few other sound/noise effects the game. -' - Boulder noise interfers with diamond pick up sound. Which one has the -' preference? -' 2009-12-12 - Added the cover/uncover screen sound. -' - Added the bonus points sound. -' - Added amoeba and magic wall sound. -' -' TODO: -' - Finish it :) -' - Add broadcast TV mode with sound carrier to use the TV antenna input (like in old times :)) -' -' -' Anpassungen f?r den Hive -' -' 09-01-2010 - Entfernung der Hardwareerkennung -' - Anpassung Konfiguration an Hive/Bellatrix -' - Gamecontr. entfernt -' - Auskommentierung Sound -' 12-01-2010 - Scrolltext im Titelscreen -' - Optimierung Soundobjekt - -con - - _clkmode = xtal1 + pll16x - _xinfreq = 5_000_000 - - ' The supported video modes - TV_NTSC = 0 - TV_PAL = 1 - - TV_MODE = TV_NTSC ' <--- Select your TV system here -- NTSC or PAL ---<<< - - ' Game controller codes - GP_RIGHT = %00000001 '(Right arrow) Move right - GP_LEFT = %00000010 '(Left arrow) Move left - GP_DOWN = %00000100 '(Down arrow) Move down - GP_UP = %00001000 '(Up arrow) Move up - GP_START = %00010000 '(Left Shift) Start game. Together with GP_SELECT: go to next cave (cheat) - GP_SELECT = %00100000 '(Left Ctrl) Pick - GP_B = %01000000 '(Space) Pause - GP_A = %10000000 '(Escape) Abort and restart current cave - -var - long nes - long last_dir - long cave_addr - long random_ptr - long screen_height - long sx, sy - long video_params[7] - long sound_pin - long Score - long NextLife - byte temp_cave[40*22] - byte HWType - byte Cave - byte Level - byte CaveNumber - byte DiamondCount - byte DiamondsNeeded - byte DiamondValue - byte ExtraValue - byte CaveTime - byte Men - byte Alive - byte MagicWallStatus - byte MagicWallTime - byte AmoebaStatus - byte AmoebaTime - byte target - byte vsync - byte door_x, door_y - -obj - tv: "Boulderdash_Tile_TV" - kb: "Keyboard" - sc: "Scroller" - st: "Status" - rr: "RealRandom" - sn: "Sounds" - -pub main | success - - video_params[0] := %0_11_101_000 ' Set Mode for VCFG - video_params[1] := 2 ' Set Pingroup used by TV driver. - video_params[2] := %0111_0000 ' Set Pinmask for VCFG pins. - video_params[3] := %0000_0111<<20 ' Set Pinmask for output pins. - - video_params[4] := TV_MODE - video_params[5] := @screen - video_params[6] := @vsync - - if video_params[4] == TV_NTSC - screen_height := 12 - else - screen_height := 14 - - rr.start 'start the real random number generator - random_ptr := rr.random_ptr - - bytefill(@screen, $00, constant(40 * 22)) 'clear screen - - tv.start(@video_params) 'start the TV driver - sc.start(@video_params, random_ptr) 'start the scroller - st.start(@video_params) 'start the status line handler - kb.start(17, 16) 'start the keyboard driver - sn.start 'start the sound engine - - cave_addr := @screen - - repeat - - repeat - success := TitleScreen - - palette.byte[1] := $04 - palette.byte[2] := $4B - palette.byte[3] := $06 - bytefill(@screen, $3C, constant(40 * 22)) 'fill the screen with the scrolling pattern - status := 0 - - Score := 0 - Men := 3 - - if success - quit - else - Demo - - repeat - - sn.music_off - - CaveNumber := byte[@@caves[Cave]] - st.player_params(1, Men, CaveNumber, Level, Score) - st.set_mode(st#STATUS_PRE) - - CreateCave(@@caves[Cave], @temp_cave) - st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) - - last_dir := -1 'last rockford direction - sc.rockford_go(0) 'rockford initially stands still - sc.milling_off - - if CaveNumber > 16 - 'intermission - sx := 0 - sy := 0 - else - 'normal cave - sx := door_x - 10 - sx <#= constant(40 - 20) - sx #>= 0 - sy := door_y - screen_height / 2 - sy <#= 22 - screen_height - sy #>= 0 - sc.scroll_to(sx * 8, sy * 16) - - Uncover 'uncover screen - success := GameLoop - - if not success - if --Men == 0 - st.set_mode(st#STATUS_GAME_OVER) - waitcnt(clkfreq + cnt) - Cover - quit - - if success or CaveNumber > 16 - 'go to next cave only if current one was completed - 'but never restart intermissions - if success and CaveNumber > 16 and Men < 9 - ++Men 'the promised bonus life - if caves[++Cave] == 0 - if Level < 4 - ++Level - Cave := 0 - - st.player_params(1, Men, CaveNumber, Level, Score) - st.set_mode(st#STATUS_PRE) - Cover 'cover screen with scrolling pattern - - -pub TitleScreen | x, y, h, t, i, j, lk, ticks, count, scr - - if TV_MODE == TV_NTSC - h := 24 - t := 2 - ticks := constant(60 * 130 / 2) 'dr235 - else - h := 28 - t := 4 - ticks := constant(50 * 130 / 2) - - scr := 0 - - bytefill(@screen, $00, constant(40 * 28)) 'clear screen - palette.byte[1] := $FC - palette.byte[2] := $FB - palette.byte[3] := $06 - st.set_mode(st#STATUS_NONE) - - Cave := 0 - Level := 0 - CaveNumber := byte[@@caves[Cave]] - - repeat x from 0 to 19 - byte[@screen + x] := $B1 - byte[@screen + x + (h - 6) * 40] := $B1 - repeat y from 1 to h - 7 - byte[@screen + y * 40] := $B5 - repeat x from 1 to 18 - byte[@screen + x + y * 40] := $B0 - byte[@screen + 19 + y * 40] := $B6 - - i := 0 - repeat y from t to t + 6 - repeat x from 1 to 18 - byte[@screen + x + y * 40] := big_boulder.byte[i++] - - i := 0 - repeat y from t + 8 to t + 14 - repeat x from 3 to 15 - byte[@screen + x + y * 40] := big_dash.byte[i++] - - status := 2 - scroll := 0 - 'st.text_out(@screen + (h - 4) * 40, @str1, 20) - scr++ - repeat i from 0 to 19 - 'j := str1.byte[i] - j := scr1.byte[i + scr] - if j == $20 - byte[@screen + (h - 4) * 40 + i] := $90 - else - byte[@screen + (h - 4) * 40 + i] := j + $A0 - st.text_out(@screen + (h - 3) * 40, @str2, 20) - st.text_out(@screen + (h - 2) * 40, @str3, 20) - st.text_out(@screen + (h - 1) * 40, @str4, 20) - - screen.byte[(h - 2) * 40] := $D1 'player(s) - screen.byte[(h - 2) * 40 + 10] := $D1 'joystick(s) - screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 - screen.byte[(h - 1) * 40 + 17] := Level + $D1 - - lk := 0 'last key - count := ticks - - sn.music_on - - repeat while count > 0 - - 'wait for vsync, count every other tick - repeat while vsync == 0 - repeat while vsync <> 0 - repeat while vsync == 0 - repeat while vsync <> 0 - --count - - 'scrolltext - scr++ - if (scr>>2) > 318 '(scr2 - scr1) - scr := 0 - repeat i from 0 to 19 - j := scr1.byte[i + (scr>>2)] - if j == $20 - byte[@screen + (h - 4) * 40 + i] := $90 - else - byte[@screen + (h - 4) * 40 + i] := j + $A0 - - ' scrolling background - x := @tiles + constant(16 * $B0) - y := word[x] - wordmove(x, x + 2, 7) - word[x + 15] := y - - repeat i from 0 to 5 - repeat y from 0 to 14 step 2 - x := @tiles + constant(16 * $B0) + y - t := @tiles + constant(16 * $BD) + y + 16 * i - j := @tiles + constant(16 * $B3) + y + 16 * i - word[j] := word[x] | word[t] - repeat y from 0 to 14 step 2 - x := @tiles + constant(16 * $B0) + y - t := @tiles + constant(16 * $C3) + y - j := @tiles + constant(16 * $B9) + y - word[j] := (word[x] & $00FF) | word[t] - repeat y from 0 to 14 step 2 - x := @tiles + constant(16 * $B0) + y - t := @tiles + constant(16 * $C4) + y - j := @tiles + constant(16 * $BA) + y - word[j] := (word[x] & $FF00) | word[t] - repeat y from 0 to 14 step 2 - x := @tiles + constant(16 * $B0) + y - t := @tiles + constant(16 * $C5) + y - j := @tiles + constant(16 * $BB) + y - word[j] := (word[x] & $FF00) | word[t] - - i := read_input - if i <> lk - count := ticks 'reset countdown - if i & GP_START - sn.music_off - return 1 - elseif i & GP_LEFT - if Cave => 5 - Cave -= 5 - CaveNumber := byte[@@caves[Cave]] - screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 - elseif i & GP_RIGHT - if Cave =< 10 - Cave += 5 - CaveNumber := byte[@@caves[Cave]] - screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 - elseif i & GP_UP - if Level < 4 - ++Level - screen.byte[(h - 1) * 40 + 17] := Level + $D1 - elseif i & GP_DOWN - if Level > 0 - --Level - screen.byte[(h - 1) * 40 + 17] := Level + $D1 - lk := i - - sn.music_off - return 0 - -dat - -big_boulder - byte $B2, $B1, $B7, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 - byte $B2, $B0, $B9, $B2, $B1, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7, $B2, $B1, $BA, $B1, $B7 - byte $B2, $B1, $B8, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9 - byte $B2, $B1, $B7, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B5, $BA, $B1, $B8 - byte $B2, $B0, $B9, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7 - byte $B2, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B5, $B9 - byte $B2, $B1, $B8, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B8, $B2, $B1, $BA, $B5, $B9 - -big_dash - byte $BA, $B1, $B3, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 - byte $BA, $B5, $BA, $B0, $B2, $B7, $B2, $B1, $BA, $B5, $BA, $BB, $BC - byte $BA, $B5, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $BA, $B0, $B0 - byte $BA, $B5, $BA, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B1, $B0, $B0 - byte $BA, $B5, $BA, $BA, $B5, $B9, $B0, $B2, $BA, $B5, $BA, $B0, $B0 - byte $BA, $B1, $B1, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 - byte $BA, $B1, $B4, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 - -str1 byte " HIVE VERSION " -str2 byte "PRESS BUTTON TO PLAY" -str3 byte " PLAYER JOYSTICK" -str4 byte " CAVE: LEVEL: " - -scr1 byte " " - byte "THANKS :SPORK FROGS: :HPG: :AHLE2: AND THE OTHER PROPELLERHEADS FOR THE BASECODE" - byte " " - byte "THANKS PEX :MAHONEY: TUFVESSON FOR THE COOL MUSIC" - byte " " - byte "GRUSS AN ALLE HIVE-DROHNEN" - byte " " - byte "HIVE: WE ARE BORG - RESISTANCE IS FUTILE" - byte " " - byte "DROHNE235: HIVE-VERSION 2010" - byte " " -scr2 byte 0 - -pub Demo - - Score := 0 - Cave := 0 'demo happens on cave A - Level := 0 - CaveNumber := byte[@@caves[Cave]] - st.player_params(1, Men, CaveNumber, Level, Score) - st.set_mode(st#STATUS_PRE) - - CreateCave(@@caves[Cave], @temp_cave) - st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) - - last_dir := -1 'last rockford direction - sc.rockford_go(0) 'rockford initially stands still - sc.milling_off - - sx := door_x - 10 - sx <#= constant(40 - 20) - sx #>= 0 - sy := door_y - screen_height / 2 - sy <#= 22 - screen_height - sy #>= 0 - sc.scroll_to(sx * 8, sy * 16) - - demo_ptr := @demo_data 'set demo data pointer - kcount := 0 - - Uncover 'uncover screen - GameLoop 'play the demo - Cover 'cover screen back - -var - - long demo_ptr - byte kcount, last_key - -dat - -' The low nibble of each byte is the direction of movement: -' $x0 = no movement -' $x1 = Right -' $x2 = Left -' $x3 = Down -' $x4 = Up -' bit 3 ($x8) set means GP_SELECT is pressed (not used here anyway) -' The high nibble is the number of scan frames to apply the movement. -' $00 means end of demo data. - -demo_data - byte $F0, $10, $14, $71, $23, $91, $40, $23 - byte $41, $34, $12, $40, $14, $B1, $13, $21 - byte $40, $63, $11, $43, $32, $40, $13, $12 - byte $41, $32, $40, $44, $52, $34, $52, $43 - byte $32, $50, $34, $A2, $14, $32, $13, $62 - byte $43, $11, $40, $33, $41, $43, $42, $24 - byte $21, $34, $A1, $A1, $13, $41, $13, $41 - byte $23, $50, $51, $44, $51, $60, $13, $00 - -pub readkey : key - - if demo_ptr - if kcount > 0 - --kcount - return last_key - else - key := byte[demo_ptr++] - if key == $00 - demo_ptr := 0 - else - kcount := key / 16 - 1 - case key & $07 - $0: last_key := 0 - $1: last_key := GP_RIGHT - $2: last_key := GP_LEFT - $3: last_key := GP_DOWN - $4: last_key := GP_UP - if key & $08 - last_key |= GP_SELECT - return last_key - - key := 0 - if kb.keystate($C0) - key |= GP_LEFT - if kb.keystate($C1) - key |= GP_RIGHT - if kb.keystate($C2) - key |= GP_UP - if kb.keystate($C3) - key |= GP_DOWN - if kb.keystate($F2) 'left control key - key |= GP_SELECT - if kb.keystate($CB) 'escape key - key |= GP_A - if kb.keystate($20) 'space key - key |= GP_B - if kb.keystate($F0) 'left shift - key |= GP_START - if kb.keystate($0D) 'or enter - key |= GP_START - -pub read_input - - return readkey - - -var - byte RandSeed1, RandSeed2 - -pub GetRandom | temp1, temp2, temp3, cy, r - -'' Generate a pseudo-random number, given a seed -'' The output matches the one used in the original BoulderDash I - - temp1 := (RandSeed1 & 1) << 7 - temp2 := (RandSeed2 & 1) << 7 - temp3 := (RandSeed2 >> 1) & $7F - - r := RandSeed2 + temp2 - if r > $FF - cy := 1 - r &= $FF - else - cy := 0 - - r += cy + $13 - if r > $FF - cy := 1 - r &= $FF - else - cy := 0 - - RandSeed2 := r - - r := RandSeed1 + cy + temp1 - if r > $FF - cy := 1 - r &= $FF - else - cy := 0 - - r += cy + temp3 - RandSeed1 := r & $FF - -dat - -caves long @cave_A, @cave_B, @cave_C, @cave_D, @inter_1 - long @cave_E, @cave_F, @cave_G, @cave_H, @inter_2 - long @cave_I, @cave_J, @cave_K, @cave_L, @inter_3 - long @cave_M, @cave_N, @cave_O, @cave_P, @inter_4 - long 0 - -cave_A byte 1 'cave number - byte 20 'magic wall/amoeba time - byte 10 'initial diamond value - byte 15 'extra diamond value - byte 10, 11, 12, 13, 14 'randomizer seed per level - byte 12, 12, 12, 12, 12 'diamonds needed per level - byte 150, 110, 70, 40, 30 'time per level - byte $08, $0B, $09, $D4, $20 'bg color 1, bg color 2, fg color - byte $00, $10, $14, $00 'random objects - byte $3C, $32, $09, $00 'probability of object - byte $42, $01, $09, $1E, $02 'raw cave data - byte $42, $09, $10, $1E, $02 - byte $25, $03, $04 - byte $04, $26, $12 - byte $FF - -cave_B byte 2 - byte 20 - byte 20, 50 - byte $03, $00, $01, $57, $58 - byte $0A, $0C, $09, $0D, $0A - byte $96, $6E, $46, $46, $46 - byte $0A, $04, $09, $00, $00 - byte $00, $10, $14, $08 - byte $3C, $32, $09, $02 - byte $42, $01, $08, $26, $02, $42, $01, $0F, $26, $02, $42, $08, $03, $14, $04, $42 - byte $10, $03, $14, $04, $42, $18, $03, $14, $04, $42, $20, $03, $14, $04, $40, $01 - byte $05, $26, $02, $40, $01, $0B, $26, $02, $40, $01, $12, $26, $02, $40, $14, $03 - byte $14, $04, $25, $12, $15, $04, $12, $16, $FF - -cave_C byte 3 - byte $00 - byte $0F, $00 - byte $00, $32, $36, $34, $37 - byte $18, $17, $18, $17, $15 - byte $96, $64, $5A, $50, $46 - byte $09, $08, $09, $04, $00 - byte $02, $10, $14, $00 - byte $64, $32, $09, $00 - byte $25, $03, $04, $04, $27, $14, $FF - -cave_D byte 4 - byte $14 - byte $05, $14 - byte $00, $6E, $70, $73, $77 - byte $24, $24, $24, $24, $24 - byte $78, $64, $50, $3C, $32 - byte $04, $08, $09, $00, $00 - byte $10, $00, $00, $00 - byte $14, $00, $00, $00 - byte $25, $01, $03, $04, $26, $16, $81, $08, $0A, $04, $04, $00, $30, $0A, $0B, $81 - byte $10, $0A, $04, $04, $00, $30, $12, $0B, $81, $18, $0A, $04, $04, $00, $30, $1A - byte $0B, $81, $20, $0A, $04, $04, $00, $30, $22, $0B, $FF - -cave_E byte $05, $14, $32, $5A - byte $00, $00, $00, $00, $00 - byte $04, $05, $06, $07, $08 - byte $96, $78, $5A, $3C, $1E - byte $09, $0A, $09, $00, $00 - byte $00, $00, $00, $00 - byte $00, $00, $00, $00 - byte $25, $01, $03, $04, $27, $16, $80, $08, $0A, $03, $03, $00, $80, $10, $0A, $03 - byte $03, $00, $80, $18, $0A, $03, $03, $00, $80, $20, $0A, $03, $03, $00, $14, $09 - byte $0C, $08, $0A, $0A, $14, $11, $0C, $08, $12, $0A, $14, $19, $0C, $08, $1A, $0A - byte $14, $21, $0C, $08, $22, $0A, $80, $08, $10, $03, $03, $00, $80, $10, $10, $03 - byte $03, $00, $80, $18, $10, $03, $03, $00, $80, $20, $10, $03, $03, $00, $14, $09 - byte $12, $08, $0A, $10, $14, $11, $12, $08, $12, $10, $14, $19, $12, $08, $1A, $10 - byte $14, $21, $12, $08, $22, $10, $FF - -cave_F byte $06, $14, $28, $3C - byte $00, $14, $15, $16, $17 - byte $04, $06, $07, $08, $08 - byte $96, $78, $64, $5A, $50 - byte $0E, $0A, $09, $00, $00 - byte $10, $00, $00, $00 - byte $32, $00, $00, $00 - byte $82, $01, $03, $0A, $04, $00, $82, $01, $06, $0A, $04, $00, $82, $01, $09, $0A - byte $04, $00, $82, $01, $0C, $0A, $04, $00, $41, $0A, $03, $0D, $04, $14, $03, $05 - byte $08, $04, $05, $14, $03, $08, $08, $04, $08, $14, $03, $0B, $08, $04, $0B, $14 - byte $03, $0E, $08, $04, $0E, $82, $1D, $03, $0A, $04, $00, $82, $1D, $06, $0A, $04 - byte $00, $82, $1D, $09, $0A, $04, $00, $82, $1D, $0C, $0A, $04, $00, $41, $1D, $03 - byte $0D, $04, $14, $24, $05, $08, $23, $05, $14, $24, $08, $08, $23, $08, $14, $24 - byte $0B, $08, $23, $0B, $14, $24, $0E, $08, $23, $0E, $25, $03, $14, $04, $26, $14 - byte $FF - -cave_G byte $07, $4B, $0A, $14 - byte $02, $07, $08, $0A, $09 - byte $0F, $14, $19, $19, $19 - byte $78, $78, $78, $78, $78 - byte $09, $0A, $0D, $00, $00 - byte $00, $10, $08, $00 - byte $64, $28, $02, $00 - byte $42, $01, $07, $0C, $02, $42, $1C, $05, $0B, $02, $7A, $13, $15, $02, $02, $14 - byte $04, $06, $14, $04, $0E, $14, $04, $16, $14, $22, $04, $14, $22, $0C, $14, $22 - byte $16, $25, $14, $03, $04, $27, $07, $FF - -cave_H byte $08, $14, $0A, $14 - byte $01, $03, $04, $05, $06 - byte $0A, $0F, $14, $14, $14 - byte $78, $6E, $64, $5A, $50 - byte $02, $0E, $09, $00, $00 - byte $00, $10, $08, $00 - byte $5A, $32, $02, $00 - byte $14, $04, $06, $14, $22, $04, $14, $22, $0C, $04, $00, $05, $25, $14, $03, $42 - byte $01, $07, $0C, $02, $42, $01, $0F, $0C, $02, $42, $1C, $05, $0B, $02, $42, $1C - byte $0D, $0B, $02, $43, $0E, $11, $08, $02, $14, $0C, $10, $00, $0E, $12, $14, $13 - byte $12, $41, $0E, $0F, $08, $02, $FF - -cave_I byte $09, $14, $05, $0A - byte $64, $89, $8C, $FB, $33 - byte $4B, $4B, $50, $55, $5A - byte $96, $96, $82, $82, $78 - byte $08, $04, $09, $00, $00 - byte $10, $14, $00, $00 - byte $F0, $78, $00, $00 - byte $82, $05, $0A, $0D, $0D, $00, $01, $0C, $0A, $82, $19, $0A, $0D, $0D, $00, $01 - byte $1F, $0A, $42, $11, $12, $09, $02, $40, $11, $13, $09, $02, $25, $07, $0C, $04 - byte $08, $0C, $FF - -cave_J byte $0A, $14, $19, $3C - byte $00, $00, $00, $00, $00 - byte $0C, $0C, $0C, $0C, $0C - byte $96, $82, $78, $6E, $64 - byte $06, $08, $09, $00, $00 - byte $00, $00, $00, $00 - byte $00, $00, $00, $00 - byte $25, $0D, $03, $04, $27, $16, $54, $05, $04, $11, $03, $54, $15, $04, $11, $05 - byte $80, $05, $0B, $11, $03, $08, $C2, $01, $04, $15, $11, $00, $0D, $04, $C2, $07 - byte $06, $0D, $0D, $00, $0D, $06, $C2, $09, $08, $09, $09, $00, $0D, $08, $C2, $0B - byte $0A, $05, $05, $00, $0D, $0A, $82, $03, $06, $03, $0F, $08, $00, $04, $06, $54 - byte $04, $10, $04, $04, $FF - -cave_K byte $0B, $14, $32, $00 - byte $00, $04, $66, $97, $64 - byte $06, $06, $06, $06, $06 - byte $78, $78, $96, $96, $F0 - byte $0B, $08, $09, $00, $00 - byte $00, $10, $08, $00 - byte $64, $50, $02, $00 - byte $42, $0A, $03, $09, $04, $42, $14, $03, $09, $04, $42, $1E, $03, $09, $04, $42 - byte $09, $16, $09, $00, $42, $0C, $0F, $11, $02, $42, $05, $0B, $09, $02, $42, $0F - byte $0B, $09, $02, $42, $19, $0B, $09, $02, $42, $1C, $13, $0B, $01, $14, $04, $03 - byte $14, $0E, $03, $14, $18, $03, $14, $22, $03, $14, $04, $16, $14, $23, $15, $25 - byte $14, $14, $04, $26, $11, $FF - -cave_L byte $0C, $14, $14, $00 - byte $00, $3C, $02, $3B, $66 - byte $13, $13, $0E, $10, $15 - byte $B4, $AA, $A0, $A0, $A0 - byte $0C, $0A, $09, $00, $00 - byte $00, $10, $14, $00 - byte $3C, $32, $09, $00 - byte $42, $0A, $05, $12, $04, $42, $0E, $05, $12, $04, $42, $12, $05, $12, $04, $42 - byte $16, $05, $12, $04, $42, $02, $06, $0B, $02, $42, $02, $0A, $0B, $02, $42, $02 - byte $0E, $0F, $02, $42, $02, $12, $0B, $02, $81, $1E, $04, $04, $04, $00, $08, $20 - byte $05, $81, $1E, $09, $04, $04, $00, $08, $20, $0A, $81, $1E, $0E, $04, $04, $00 - byte $08, $20, $0F, $25, $03, $14, $04, $27, $16, $FF - -cave_M byte $0D, $8C, $05, $08 - byte $00, $01, $02, $03, $04 - byte $32, $37, $3C, $46, $50 - byte $A0, $9B, $96, $91, $8C - byte $06, $08, $0D, $00, $00 - byte $10, $00, $00, $00 - byte $28, $00, $00, $00 - byte $25, $12, $03, $04, $0A, $03, $3A, $14, $03, $42, $05, $12, $1E, $02, $70, $05 - byte $13, $1E, $02, $50, $05, $14, $1E, $02, $C1, $05, $15, $1E, $02, $FF - -cave_N byte $0E, $14, $0A, $14 - byte $00, $00, $00, $00, $00 - byte $1E, $23, $28, $2A, $2D - byte $96, $91, $8C, $87, $82 - byte $0C, $08, $09, $00, $00 - byte $10, $00, $00, $00 - byte $00, $00, $00, $00 - byte $81, $0A, $0A, $0D, $0D, $00, $70, $0B, $0B, $0C, $03, $C1, $0C, $0A, $03, $0D - byte $C1, $10, $0A, $03, $0D, $C1, $14, $0A, $03, $0D, $50, $16, $08, $0C, $02, $48 - byte $16, $07, $0C, $02, $C1, $17, $06, $03, $04, $C1, $1B, $06, $03, $04, $C1, $1F - byte $06, $03, $04, $25, $03, $03, $04, $27, $14, $FF - -cave_O byte $0F, $08, $0A, $14 - byte $01, $1D, $1E, $1F, $20 - byte $0F, $14, $14, $19, $1E - byte $78, $78, $78, $78, $8C - byte $08, $0E, $09, $00, $00 - byte $00, $10, $08, $00 - byte $64, $50, $02, $00 - byte $42, $02, $04, $0A, $03, $42, $0F, $0D, $0A, $01, $41, $0C, $0E, $03, $02, $43 - byte $0C, $0F, $03, $02, $04, $14, $16, $25, $14, $03, $FF - -cave_P byte $10, $14, $0A, $14 - byte $01, $78, $81, $7E, $7B - byte $0C, $0F, $0F, $0F, $0C - byte $96, $96, $96, $96, $96 - byte $09, $0A, $09, $00, $00 - byte $10, $00, $00, $00 - byte $32, $00, $00, $00 - byte $25, $01, $03, $04, $27, $04, $81, $08, $13, $04, $04, $00, $08, $0A, $14, $C2 - byte $07, $0A, $06, $08, $43, $07, $0A, $06, $02, $81, $10, $13, $04, $04, $00, $08 - byte $12, $14, $C2, $0F, $0A, $06, $08, $43, $0F, $0A, $06, $02, $81, $18, $13, $04 - byte $04, $00, $08, $1A, $14, $81, $20, $13, $04, $04, $00, $08, $22, $14, $FF - -inter_1 byte $11, $14, $1E, $00 - byte $0A, $0B, $0C, $0D, $0E - byte $06, $06, $06, $06, $06 - byte $0A, $0A, $0A, $0A, $0A - byte $0E, $02, $09, $00, $00 - byte $00, $14, $00, $00 - byte $FF, $09, $00, $00 - byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $32, $0A, $0C, $10 - byte $0A, $04, $01, $0A, $05, $25, $03, $05, $04, $12, $0C, $FF - -inter_2 byte $12, $14, $0A, $00 - byte $0A, $0B, $0C, $0D, $0E - byte $10, $10, $10, $10, $10 - byte $0F, $0F, $0F, $0F, $0F - byte $06, $0F, $09, $00, $00 - byte $00, $00, $00, $00 - byte $00, $00, $00, $00 - byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $50, $01, $03, $09 - byte $03, $48, $02, $03, $08, $03, $54, $01, $05, $08, $03, $50, $01, $06, $07, $03 - byte $50, $12, $03, $09, $05, $54, $12, $05, $08, $05, $50, $12, $06, $07, $05, $25 - byte $01, $04, $04, $12, $04, $FF - -inter_3 byte $13, $04, $0A, $00 - byte $0A, $0B, $0C, $0D, $0E - byte $0E, $0E, $0E, $0E, $0E - byte $14, $14, $14, $14, $14 - byte $06, $08, $09, $00, $00 - byte $00, $00, $00, $00 - byte $00, $00, $00, $00 - byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $54, $01, $0C, $12 - byte $02, $88, $0F, $09, $04, $04, $08, $25, $08, $03, $04, $12, $07, $FF - -inter_4 byte $14, $03, $1E, $00 - byte $00, $00, $00, $00, $00 - byte $06, $06, $06, $06, $06 - byte $14, $14, $14, $14, $14 - byte $06, $08, $09, $00, $00 - byte $00, $00, $00, $00 - byte $00, $00, $00, $00 - byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $D0, $0B, $03, $03 - byte $02, $80, $0B, $07, $03, $06, $00, $43, $0B, $06, $03, $02, $43, $0B, $0A, $03 - byte $02, $50, $08, $07, $03, $03, $25, $03, $03, $04, $09, $0A, $FF - -dat - -' C64 color table approximation. Not the most accurate one, but gives the desired effect. - -ctable byte $02, $06, $4B, $BC, $2B, $9C, $EB, $7D - byte $4B, $4A, $4B, $04, $04, $9D, $0B, $04 - -pub CreateCave(raw_cave, dest) | i, j, k, cx, cy, ci, co, dir, len - -'' Create cave contents from the description array - - CaveNumber := byte[raw_cave] - - RandSeed1 := 0 - RandSeed2 := byte[raw_cave + 4 + Level] - - ' Set colors - palette.byte[1] := ctable.byte[byte[raw_cave + 20]] - palette.byte[2] := ctable.byte[byte[raw_cave + 19]] - palette.byte[3] := ctable.byte[byte[raw_cave + 21] - 8] - - ' Place random objects - repeat cy from 1 to 21 - repeat cx from 0 to 39 - co := $01 ' dirt - GetRandom - repeat ci from 0 to 3 - if RandSeed1 < byte[raw_cave + 28 + ci] - co := byte[raw_cave + 24 + ci] - byte[dest + cx + cy * 40] := co - - ' Steel bounds - repeat cx from 0 to 39 - byte[dest + cx] := $07 - byte[dest + cx + 21 * 40] := $07 - repeat cy from 0 to 21 - byte[dest + cy * 40] := $07 - byte[dest + 39 + cy * 40] := $07 - - 'Decode raw data - i := raw_cave + 32 - repeat - ci := byte[i++] - cx := byte[i++] - cy := byte[i++] - 2 - if ci == $FF - quit - case ci & $C0 - $00: - byte[dest + cx + cy * 40] := ci & $3F - if (ci & $3F) == $25 - door_x := cx - door_y := cy - $40: - len := byte[i++] - dir := byte[i++] - repeat - byte[dest + cx + cy * 40] := ci & $3F - case dir - 0: --cy - 1: --cy - ++cx - 2: ++cx - 3: ++cy - ++cx - 4: ++cy - 5: ++cy - --cx - 6: --cx - 7: --cy - --cx - while --len > 0 - $80: - len := byte[i++] - 1 'width - dir := byte[i++] - 1 'height - co := byte[i++] - repeat j from 0 to len - byte[dest + cx + j + cy * 40] := ci & $3F - byte[dest + cx + j + (cy + dir) * 40] := ci & $3F - repeat j from 1 to dir - 1 - byte[dest + cx + (cy + j) * 40] := ci & $3F - repeat k from 1 to len - 1 - byte[dest + cx + k + (cy + j) * 40] := co - byte[dest + cx + len + (cy + j) * 40] := ci & $3F - $C0: - len := byte[i++] - 1 'width - dir := byte[i++] - 1 'height - repeat j from 0 to len - byte[dest + cx + j + cy * 40] := ci & $3F - byte[dest + cx + j + (cy + dir) * 40] := ci & $3F - repeat j from 0 to dir - byte[dest + cx + (cy + j) * 40] := ci & $3F - byte[dest + cx + len + (cy + j) * 40] := ci & $3F - - DiamondsNeeded := byte[raw_cave + 9 + Level] - CaveTime := byte[raw_cave + 14 + Level] - MagicWallTime := byte[raw_cave + 1] - if MagicWallTime > CaveTime - AmoebaTime := CaveTime - else - AmoebaTime := CaveTime - MagicWallTime - DiamondValue := byte[raw_cave + 2] - ExtraValue := byte[raw_cave + 3] - DiamondCount := 0 - -pub Cover | n, cell - -'' Ramdomly cover the screen with a scrolling pattern - - n := 0 - repeat while n <> constant(40 * 22) - cell := ||long[random_ptr] // constant(40 * 22) - if byte[cave_addr + cell] <> $3C - byte[cave_addr + cell] := $3C - ++n - sn.cover_sound - waitcnt(clkfreq / 1000 + cnt) - -pub Uncover | n, cell - -'' Ramdomly uncover the screen - - n := 0 - repeat while n <> constant(40 * 22) - cell := ||long[random_ptr] // constant(40 * 22) - if byte[cave_addr + cell] == $3C - byte[cave_addr + cell] := temp_cave[cell] - ++n - sn.cover_sound - waitcnt(clkfreq / 1000 + cnt) - -dat - -reset byte $00, $01, $02, $03, $04, $05, $06, $07 - byte $08, $09, $0A, $0B, $08, $09, $0A, $0B - byte $10, $10, $12, $12, $14, $14, $16, $16 - byte $18, $19, $1A, $1B, $1C, $1D, $1E, $1F - byte $20, $21, $22, $23, $24, $25, $26, $27 - byte $28, $29, $2A, $2B, $2C, $2D, $2E, $2F - byte $30, $31, $32, $33, $30, $31, $32, $33 - byte $38, $38, $3A, $3B, $3C, $3D, $3E, $3F - -dirs long 1, 40, -1, -40 - -pub GameLoop | cx, cy, ca, cn, ob, o1, o2, ready, count, amoebas, enclosed - -'' Main game loop. Everything happens here. - - target := 0 - count := 0 'scans before rockford is born - ready := 0 - - NextLife := ((Score / 500) + 1) * 500 - MagicWallStatus := 0 'dormant - AmoebaStatus := 0 'growing slowly - - ' game loop - repeat - Alive := false - amoebas := 0 - enclosed := true - repeat cy from 1 to 21 - repeat cx from 0 to 39 - ca := cave_addr + cx + cy * 40 'address of current object - - 'large case statements execute rather slowly to the point - 'that the game becomes unplayable, so we have to split the - 'case into sections (too bad there is no indirect function - 'call in Spin) - - ob := byte[ca] - if ob < $10 - case ob - $04: 'out door - if target - byte[ca] := $05 - $08: 'firefly facing left - if CheckAround(ca) - ExplodeCenter(ca, $1B) - else - if byte[ca + 40] == $00 - byte[ca + 40] := $0F - byte[ca] := $00 - elseif byte[ca - 1] == $00 - byte[ca - 1] := $0C - byte[ca] := $00 - else - byte[ca] := $0D - $09: 'firefly facing up - if CheckAround(ca) - ExplodeCenter(ca, $1B) - else - if byte[ca - 1] == $00 - byte[ca - 1] := $0C - byte[ca] := $00 - elseif byte[ca - 40] == $00 - byte[ca - 40] := $0D - byte[ca] := $00 - else - byte[ca] := $0E - $0A: 'firefly facing right - if CheckAround(ca) - ExplodeCenter(ca, $1B) - else - if byte[ca - 40] == $00 - byte[ca - 40] := $0D - byte[ca] := $00 - elseif byte[ca + 1] == $00 - byte[ca + 1] := $0E - byte[ca] := $00 - else - byte[ca] := $0F - $0B: 'firefly facing down - if CheckAround(ca) - ExplodeCenter(ca, $1B) - else - if byte[ca + 1] == $00 - byte[ca + 1] := $0E - byte[ca] := $00 - elseif byte[ca + 40] == $00 - byte[ca + 40] := $0F - byte[ca] := $00 - else - byte[ca] := $0C - - elseif ob < $20 - case ob - $10: 'boulder - case byte[ca + 40] 'check object below - $00: - 'boulder can fall - byte[ca] := $00 - byte[ca + 40] := $13 'falling boulder, scanned - sn.boulder_sound - $02, $10, $14: 'wall, boulder or diamond - if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 - 'boulder can roll left - byte[ca] := $00 - byte[ca - 1] := $13 'falling boulder, scanned - sn.boulder_sound - elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 - 'boulder can roll right - byte[ca] := $00 - byte[ca + 1] := $13 'falling boulder, scanned - sn.boulder_sound - $12: 'falling boulder - case byte[ca + 40] 'check object below - $00: - 'boulder can continue falling - byte[ca] := $00 - byte[ca + 40] := $13 'falling boulder, scanned - $03: 'magic wall - byte[ca] := $00 - if MagicWallStatus < 2 'dormant or milling - if MagicWallStatus == 0 - MagicWallStatus := 1 - cn := st.get_time #> MagicWallTime - MagicWallTime := cn - MagicWallTime - sc.milling_on - sn.magic_wall_sound_on - if byte[ca + constant(40 * 2)] == $00 - byte[ca + constant(40 * 2)] := $17 'falling diamond, scanned - sn.diamond_sound - $02, $10, $14: 'wall, boulder or diamond - 'we hit something - sn.boulder_sound - if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 - 'boulder can roll left - byte[ca] := $00 - byte[ca - 1] := $13 'falling boulder, scanned - elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 - 'boulder can roll right - byte[ca] := $00 - byte[ca + 1] := $13 'falling boulder, scanned - else - 'boulder came to a stop - byte[ca] := $11 'stationary boulder, scanned - $38: 'rockford? - 'explode - ExplodeBelow(ca, $1B) - $08, $09, $0A, $0B: 'firefly? - ExplodeBelow(ca, $1B) - $30, $31, $32, $33: 'butterfly? - ExplodeBelow(ca, $20) - other: - 'boulder came to a stop - byte[ca] := $11 'stationary boulder, scanned - sn.boulder_sound - $14: 'diamond - case byte[ca + 40] 'check object below - $00: - 'diamond can fall - byte[ca] := $00 - byte[ca + 40] := $17 'falling diamond, scanned - sn.diamond_sound - $02, $10, $14: 'wall, boulder or diamond - if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 - 'diamond can roll left - byte[ca] := $00 - byte[ca - 1] := $17 'falling diamond, scanned - sn.diamond_sound - elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 - 'diamond can roll right - byte[ca] := $00 - byte[ca + 1] := $17 'falling diamond, scanned - sn.diamond_sound - $16: 'falling diamond - case byte[ca + 40] 'check object below - $00: - 'diamond can continue falling - byte[ca] := $00 - byte[ca + 40] := $17 'falling diamond, scanned - $03: 'magic wall - byte[ca] := $00 - if MagicWallStatus < 2 'dormant or milling - if MagicWallStatus == 0 - MagicWallStatus := 1 - cn := st.get_time #> MagicWallTime - MagicWallTime := cn - MagicWallTime - sc.milling_on - sn.magic_wall_sound_on - if byte[ca + constant(40 * 2)] == $00 - byte[ca + constant(40 * 2)] := $13 'falling boulder, scanned - sn.boulder_sound - $02, $10, $14: 'wall, boulder or diamond - 'we hit something - sn.diamond_sound - if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 - 'diamond can roll left - byte[ca] := $00 - byte[ca - 1] := $17 'falling diamond, scanned - elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 - 'diamond can roll right - byte[ca] := $00 - byte[ca + 1] := $17 'falling diamond, scanned - else - 'diamond came to a stop - byte[ca] := $15 'stationary diamond, scanned - $38: 'rockford? - 'explode - ExplodeBelow(ca, $1B) - $08, $09, $0A, $0B: 'firefly - ExplodeBelow(ca, $1B) - $30, $31, $32, $33: 'butterfly - ExplodeBelow(ca, $20) - other: - 'diamond came to a stop - byte[ca] := $15 'stationary diamond, scanned - sn.diamond_sound - $1B, $1C, $1D, $1E: 'explosion stages - byte[ca]++ - $1F: 'explosion to space, final stage - byte[ca] := $00 - - elseif ob < $30 - case ob - $20, $21, $22, $23: 'explosion stages - byte[ca]++ - $24: 'explosion to diamonds, final stage - byte[ca] := $15 - $25: 'inbox - Alive := true - if count++ == 20 - byte[ca] := $26 - sn.crack_sound - $26, $27: - Alive := true - byte[ca]++ - $28: - Alive := true - byte[ca] := $38 'rockford is born - sc.rockford_reset - st.set_time(CaveTime) - st.set_mode(st#STATUS_GAME) - ready := 1 - - elseif ob < $40 - case ob - $30: 'butterfly facing down - if CheckAround(ca) - ExplodeCenter(ca, $20) - else - if byte[ca - 1] == $00 - byte[ca - 1] := $35 - byte[ca] := $00 - elseif byte[ca + 40] == $00 - byte[ca + 40] := $34 - byte[ca] := $00 - else - byte[ca] := $37 - $31: 'butterfly facing left - if CheckAround(ca) - ExplodeCenter(ca, $20) - else - if byte[ca - 40] == $00 - byte[ca - 40] := $36 - byte[ca] := $00 - elseif byte[ca - 1] == $00 - byte[ca - 1] := $35 - byte[ca] := $00 - else - byte[ca] := $34 - $32: 'butterfly facing up - if CheckAround(ca) - ExplodeCenter(ca, $20) - else - if byte[ca + 1] == $00 - byte[ca + 1] := $37 - byte[ca] := $00 - elseif byte[ca - 40] == $00 - byte[ca - 40] := $36 - byte[ca] := $00 - else - byte[ca] := $35 - $33: 'butterfly facing right - if CheckAround(ca) - ExplodeCenter(ca, $20) - else - if byte[ca + 40] == $00 - byte[ca + 40] := $34 - byte[ca] := $00 - elseif byte[ca + 1] == $00 - byte[ca + 1] := $37 - byte[ca] := $00 - else - byte[ca] := $36 - - $38: 'rockford - Alive := true - nes := read_input - cn := 0 - if nes - if nes & GP_RIGHT - last_dir := 1 - sc.rockford_go(last_dir) - cn := ca + 1 - elseif nes & GP_LEFT - last_dir := -1 - sc.rockford_go(last_dir) - cn := ca - 1 - elseif nes & GP_UP - sc.rockford_go(last_dir) - cn := ca - 40 - elseif nes & GP_DOWN - sc.rockford_go(last_dir) - cn := ca + 40 - - if cn - if nes & GP_SELECT - o1 := $39 - o2 := $00 - else - o1 := $00 - o2 := $39 - case byte[cn] - $00, $01: 'empty or dirt - sn.moving_sound(byte[cn]) - byte[ca] := o1 - byte[cn] := o2 - $05: 'out door - sn.magic_wall_sound_off - sn.amoeba_sound_off - byte[ca] := o1 - byte[cn] := o2 - AddBonusPoints - waitcnt(clkfreq + cnt) '1 second delay - return true 'means cave succesfully completed - $10, $11: 'boulder, stationary - if (nes & GP_RIGHT) and (byte[cn + 1] == $00) and ((long[random_ptr] & $03) == 0) - 'boulder can be pushed - byte[cn + 1] := byte[cn] - byte[ca] := o1 - byte[cn] := o2 - sn.boulder_sound - elseif (nes & GP_LEFT) and (byte[cn - 1] == $00) and ((long[random_ptr] & $03) == 0) - 'boulder can be pushed - byte[cn - 1] := byte[cn] - byte[ca] := o1 - byte[cn] := o2 - sn.boulder_sound - $14, $15, $16, $17: 'diamond - byte[ca] := o1 - byte[cn] := o2 - sn.pick_sound - st.set_diamond_count(++DiamondCount) - IncrementScore(DiamondValue) - if DiamondCount == DiamondsNeeded and not target - 'flash screen when target is reached - sc.flash - sn.crack_sound - DiamondValue := ExtraValue - st.set_diamond_value(DiamondValue) - target := 1 - - else - sc.rockford_go(0) - - 'screen may need scrolling - if CaveNumber > 16 - 'do not scroll intermission caves - sx := 0 - sy := 0 - else - if cx - sx > constant(20 - 6) - sx += constant(10 - 5) - sx <#= constant(40 - 20) - elseif cx - sx < 5 - sx -= constant(10 - 5) - sx #>= 0 - if cy - sy > screen_height - 4 - sy += screen_height / 2 - 3 - sy <#= 22 - screen_height - elseif cy - sy < 3 - sy -= screen_height / 2 - 3 - sy #>= 0 - sc.scroll_to(sx * 8, sy * 16) - - $3A: 'amoeba - if ready - sn.amoeba_sound_on - if AmoebaStatus == 2 - 'turn into stone - byte[ca] := $10 'stationary boulder - elseif AmoebaStatus == 3 - 'turn into diamond - byte[ca] := $14 'stationary diamond - else - ++amoebas - if enclosed - enclosed := CheckEnclosed(ca) - cn := long[random_ptr] - if AmoebaStatus == 0 - cn &= $7F - else - cn &= $0F - if cn =< 3 - cn := ca + dirs[cn & $03] - ob := byte[cn] - if ob == $00 or ob == $01 - byte[cn] := $3A - - 'reset scanned flag - cn := ca - constant(40 + 1) - byte[cn] := reset.byte[byte[cn]] - - if MagicWallStatus == 1 - if st.get_time < MagicWallTime - MagicWallStatus := 2 'expired - sc.milling_off - sn.magic_wall_sound_off - - if AmoebaStatus == 0 - if st.get_time < AmoebaTime - AmoebaStatus := 1 'growing fast - if amoebas > 200 - AmoebaStatus := 2 'grew too big, turn into stones - elseif enclosed - AmoebaStatus := 3 'fully enclosed, turn into diamonds - if amoebas == 0 - sn.amoeba_sound_off - - if demo_ptr - nes := 0 - else - nes := read_input - if nes & GP_A - st.set_time(0) 'stop the time - sn.magic_wall_sound_off - sn.amoeba_sound_off - return false 'not completed, restart the same level - - elseif nes & GP_B - 'pause game - st.set_mode(st#STATUS_PAUSE) - repeat while nes & GP_B - nes := read_input - repeat while (nes & GP_B) == 0 - nes := read_input - if ready - st.set_mode(st#STATUS_GAME) - else - st.set_mode(st#STATUS_PRE) - repeat while nes & GP_B - nes := read_input - - elseif (nes & GP_SELECT) and (nes & GP_START) - st.set_time(0) - sn.magic_wall_sound_off - sn.amoeba_sound_off - return true '*cheat* go to the next level - - cn := st.get_time - if cn < 10 - sn.time_ending_sound(cn) - - if ready and (cn == 0) - 'out of time - sn.magic_wall_sound_off - sn.amoeba_sound_off - st.set_mode(st#STATUS_OUT_OF_TIME) - count := 60 * 60 'approx 1 minute - repeat while count > 0 - repeat while vsync == 0 - repeat while vsync <> 0 - --count - nes := read_input - if nes & GP_A - return false 'not completed, restart the same level - elseif (nes & GP_SELECT) and (nes & GP_START) - return true '*cheat* go to the next level - return false - - if Level < 2 - waitcnt(clkfreq / 50 + cnt) - -pub ExplodeBelow(cell, towhat) - if byte[cell - 1] <> $07 - byte[cell - 1] := towhat + 1 - if byte[cell] <> $07 - byte[cell] := towhat + 1 - if byte[cell + 1] <> $07 - byte[cell + 1] := towhat - if byte[cell + constant(40 - 1)] <> $07 - byte[cell + constant(40 - 1)] := towhat - if byte[cell + 40] <> $07 - byte[cell + 40] := towhat - if byte[cell + constant(40 + 1)] <> $07 - byte[cell + constant(40 + 1)] := towhat - if byte[cell + constant(40 * 2 - 1)] <> $07 - byte[cell + constant(40 * 2 - 1)] := towhat - if byte[cell + constant(40 * 2)] <> $07 - byte[cell + constant(40 * 2)] := towhat - if byte[cell + constant(40 * 2 + 1)] <> $07 - byte[cell + constant(40 * 2 + 1)] := towhat - sn.explosion_sound - -pub ExplodeCenter(cell, towhat) - if byte[cell - constant(40 + 1)] <> $07 - byte[cell - constant(40 + 1)] := towhat + 1 - if byte[cell - 40] <> $07 - byte[cell - 40] := towhat + 1 - if byte[cell - constant(40 - 1)] <> $07 - byte[cell - constant(40 - 1)] := towhat + 1 - if byte[cell - 1] <> $07 - byte[cell - 1] := towhat + 1 - if byte[cell] <> $07 - byte[cell] := towhat + 1 - if byte[cell + 1] <> $07 - byte[cell + 1] := towhat - if byte[cell + constant(40 - 1)] <> $07 - byte[cell + constant(40 - 1)] := towhat - if byte[cell + 40] <> $07 - byte[cell + 40] := towhat - if byte[cell + constant(40 + 1)] <> $07 - byte[cell + constant(40 + 1)] := towhat - sn.explosion_sound - -pub CheckAround(cell) | ob - ob := byte[cell - 40] - if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not - return true - ob := byte[cell - 1] - if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not - return true - ob := byte[cell + 1] - if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not - return true - ob := byte[cell + 40] - if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not - return true - return false - -pub CheckEnclosed(cell) | ob, i - repeat i from 0 to 3 - ob := byte[cell + dirs[i]] - if ob == $00 or ob == $01 - return false - return true - -pub IncrementScore(amount) - Score += amount - st.set_score(Score) - if Score => NextLife and Men < 9 - ++Men - sc.new_life - NextLife += 500 - -pub AddBonusPoints | i, j - - i := j := st.get_time - repeat while i > 0 - st.set_time(--i) - IncrementScore(Level + 1) - if i < 10 - sn.time_ending_sound(i) - waitcnt(clkfreq / 32 + cnt) - else - sn.bonus_point_sound(j - i) - -dat - - long 0 'align - - ' screen array -screen byte $00[40*28] - -' color index 3 1 2 0 -palette long $06_6B_04_02 - -' -x- -y- -scroll long $0000_0000 - -status long 1 'set this to 1 to show the status line at the top - - ' status line - byte $90[20] - - ' foreground color for status line characters - byte $06[20] - - ' tiles -tiles word %%0_0_0_0_0_0_0_0 ' $00 space - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_1_0_0_1_0_1 ' $01 dirt - word %%1_1_0_0_1_0_0_1 - word %%0_1_2_1_0_1_2_0 - word %%1_1_0_1_1_1_0_1 - word %%1_0_1_1_1_0_1_1 - word %%0_2_1_0_1_2_1_0 - word %%2_1_1_2_2_0_1_1 - word %%1_0_1_1_1_1_2_0 - word %%0_1_1_1_2_1_1_1 - word %%1_2_0_1_1_1_2_0 - word %%1_2_1_0_2_1_0_1 - word %%0_2_1_1_0_1_2_1 - word %%1_0_1_0_1_0_1_0 - word %%1_1_0_0_1_1_0_1 - word %%1_0_1_2_0_1_0_0 - word %%0_1_0_0_1_0_1_0 - - word %%0_3_3_3_0_3_3_3 ' $02 brick wall - word %%0_2_3_3_0_2_3_3 - word %%0_2_2_2_0_2_2_2 - word %%0_0_0_0_0_0_0_0 - word %%3_3_0_3_3_3_0_3 - word %%3_3_0_2_3_3_0_2 - word %%2_2_0_2_2_2_0_2 - word %%0_0_0_0_0_0_0_0 - word %%0_3_3_3_0_3_3_3 - word %%0_2_3_3_0_2_3_3 - word %%0_2_2_2_0_2_2_2 - word %%0_0_0_0_0_0_0_0 - word %%3_3_0_3_3_3_0_3 - word %%3_3_0_2_3_3_0_2 - word %%2_2_0_2_2_2_0_2 - word %%0_0_0_0_0_0_0_0 - - word %%0_3_3_3_0_3_3_3 ' $03 magic wall - word %%0_2_3_3_0_2_2_2 - word %%0_2_2_2_0_2_2_2 - word %%0_0_0_0_0_0_0_0 - word %%3_3_0_3_3_3_0_3 - word %%3_3_0_2_3_3_0_3 - word %%2_2_0_2_2_2_0_2 - word %%0_0_0_0_0_0_0_0 - word %%0_3_3_3_0_3_3_3 - word %%0_2_3_3_0_2_3_3 - word %%0_2_2_2_0_2_2_2 - word %%0_0_0_0_0_0_0_0 - word %%3_3_0_3_3_3_0_3 - word %%3_3_0_2_3_3_0_2 - word %%2_2_0_2_2_2_0_2 - word %%0_0_0_0_0_0_0_0 - - word %%2_2_2_2_2_2_2_2 ' $04 out door (invisible) - word %%2_2_2_2_2_2_2_2 - word %%2_0_0_2_2_0_0_2 - word %%2_2_0_2_2_2_0_2 - word %%2_3_0_2_2_3_0_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_0_0_2_2_0_0_2 - word %%2_2_0_2_2_2_0_2 - word %%2_3_0_2_2_3_0_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - - word %%0_0_0_0_0_0_0_0 ' $05 out door (flashing) - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $06 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%2_2_2_2_2_2_2_2 ' $07 steel wall - word %%2_2_2_2_2_2_2_2 - word %%2_0_0_2_2_0_0_2 - word %%2_2_0_2_2_2_0_2 - word %%2_3_0_2_2_3_0_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_0_0_2_2_0_0_2 - word %%2_2_0_2_2_2_0_2 - word %%2_3_0_2_2_3_0_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - - word %%0_0_0_0_0_0_0_0 ' $08 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $09 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $0A - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $0B - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $0C - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $0D - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $0E - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $0F - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_3_3_3_0_0_0 ' $10 boulder stationary - word %%0_3_2_3_1_3_0_0 - word %%3_1_3_2_3_3_3_0 - word %%2_3_1_2_1_3_3_3 - word %%2_2_2_1_2_3_3_3 - word %%2_1_2_2_2_1_2_3 - word %%2_2_1_1_2_2_3_3 - word %%2_2_2_2_2_1_2_3 - word %%2_0_2_2_2_2_2_1 - word %%2_2_0_2_2_1_2_1 - word %%2_0_2_2_2_2_2_2 - word %%2_2_0_2_2_2_2_2 - word %%2_2_2_0_2_2_2_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_2_0_1_2_0_0 - word %%0_0_0_2_2_0_0_0 - - word %%0_0_3_3_3_0_0_0 ' $11 boulder stationary, scanned this frame - word %%0_3_2_3_1_3_0_0 - word %%3_1_3_2_3_3_3_0 - word %%2_3_1_2_1_3_3_3 - word %%2_2_2_1_2_3_3_3 - word %%2_1_2_2_2_1_2_3 - word %%2_2_1_1_2_2_3_3 - word %%2_2_2_2_2_1_2_3 - word %%2_0_2_2_2_2_2_1 - word %%2_2_0_2_2_1_2_1 - word %%2_0_2_2_2_2_2_2 - word %%2_2_0_2_2_2_2_2 - word %%2_2_2_0_2_2_2_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_2_0_1_2_0_0 - word %%0_0_0_2_2_0_0_0 - - word %%0_0_3_3_3_0_0_0 ' $12 boulder falling - word %%0_3_2_3_1_3_0_0 - word %%3_1_3_2_3_3_3_0 - word %%2_3_1_2_1_3_3_3 - word %%2_2_2_1_2_3_3_3 - word %%2_1_2_2_2_1_2_3 - word %%2_2_1_1_2_2_3_3 - word %%2_2_2_2_2_1_2_3 - word %%2_0_2_2_2_2_2_1 - word %%2_2_0_2_2_1_2_1 - word %%2_0_2_2_2_2_2_2 - word %%2_2_0_2_2_2_2_2 - word %%2_2_2_0_2_2_2_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_2_0_1_2_0_0 - word %%0_0_0_2_2_0_0_0 - - word %%0_0_3_3_3_0_0_0 ' $13 boulder falling, scanned this frame - word %%0_3_2_3_1_3_0_0 - word %%3_1_3_2_3_3_3_0 - word %%2_3_1_2_1_3_3_3 - word %%2_2_2_1_2_3_3_3 - word %%2_1_2_2_2_1_2_3 - word %%2_2_1_1_2_2_3_3 - word %%2_2_2_2_2_1_2_3 - word %%2_0_2_2_2_2_2_1 - word %%2_2_0_2_2_1_2_1 - word %%2_0_2_2_2_2_2_2 - word %%2_2_0_2_2_2_2_2 - word %%2_2_2_0_2_2_2_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_2_0_1_2_0_0 - word %%0_0_0_2_2_0_0_0 - - word %%0_0_0_2_3_0_0_0 ' $14 diamond stationary - word %%0_0_0_1_2_0_0_0 - word %%0_0_2_3_3_3_0_0 - word %%0_0_1_3_3_2_0_0 - word %%0_2_2_2_2_2_3_0 - word %%0_1_1_1_1_1_2_0 - word %%2_0_0_0_0_0_0_3 - word %%1_0_0_0_0_0_0_2 - word %%2_1_1_1_1_1_1_3 - word %%1_2_2_2_2_2_2_2 - word %%0_2_3_3_3_3_3_0 - word %%0_1_3_3_3_3_2_0 - word %%0_0_2_1_1_3_0_0 - word %%0_0_1_1_1_2_0_0 - word %%0_0_0_1_2_0_0_0 - word %%0_0_0_1_1_0_0_0 - - word %%0_0_0_2_3_0_0_0 ' $15 diamond stationary, scanned - word %%0_0_0_1_2_0_0_0 - word %%0_0_2_3_3_3_0_0 - word %%0_0_1_3_3_2_0_0 - word %%0_2_2_2_2_2_3_0 - word %%0_1_1_1_1_1_2_0 - word %%2_0_0_0_0_0_0_3 - word %%1_0_0_0_0_0_0_2 - word %%2_1_1_1_1_1_1_3 - word %%1_2_2_2_2_2_2_2 - word %%0_2_3_3_3_3_3_0 - word %%0_1_3_3_3_3_2_0 - word %%0_0_2_1_1_3_0_0 - word %%0_0_1_1_1_2_0_0 - word %%0_0_0_1_2_0_0_0 - word %%0_0_0_1_1_0_0_0 - - word %%0_0_0_2_3_0_0_0 ' $16 diamond falling - word %%0_0_0_1_2_0_0_0 - word %%0_0_2_3_3_3_0_0 - word %%0_0_1_3_3_2_0_0 - word %%0_2_2_2_2_2_3_0 - word %%0_1_1_1_1_1_2_0 - word %%2_0_0_0_0_0_0_3 - word %%1_0_0_0_0_0_0_2 - word %%2_1_1_1_1_1_1_3 - word %%1_2_2_2_2_2_2_2 - word %%0_2_3_3_3_3_3_0 - word %%0_1_3_3_3_3_2_0 - word %%0_0_2_1_1_3_0_0 - word %%0_0_1_1_1_2_0_0 - word %%0_0_0_1_2_0_0_0 - word %%0_0_0_1_1_0_0_0 - - word %%0_0_0_2_3_0_0_0 ' $17 diamond falling, scanned - word %%0_0_0_1_2_0_0_0 - word %%0_0_2_3_3_3_0_0 - word %%0_0_1_3_3_2_0_0 - word %%0_2_2_2_2_2_3_0 - word %%0_1_1_1_1_1_2_0 - word %%2_0_0_0_0_0_0_3 - word %%1_0_0_0_0_0_0_2 - word %%2_1_1_1_1_1_1_3 - word %%1_2_2_2_2_2_2_2 - word %%0_2_3_3_3_3_3_0 - word %%0_1_3_3_3_3_2_0 - word %%0_0_2_1_1_3_0_0 - word %%0_0_1_1_1_2_0_0 - word %%0_0_0_1_2_0_0_0 - word %%0_0_0_1_1_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $18 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $19 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $1A - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $1B explode to space frame 1 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_3_0_0_0 - word %%0_0_0_3_0_0_3_0 - word %%0_0_0_0_3_0_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_0_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $1C explode to space frame 2 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_0_3_0_1_0_0 - word %%0_3_1_0_0_0_3_0 - word %%0_1_0_0_1_3_1_0 - word %%0_3_0_1_0_0_1_0 - word %%0_0_0_0_1_3_0_0 - word %%0_3_1_0_1_0_0_0 - word %%0_1_0_1_0_1_0_0 - word %%0_0_3_1_1_0_3_0 - word %%0_0_3_0_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $1D explode to space frame 3 - word %%0_0_0_0_0_0_0_0 - word %%0_3_0_0_3_0_3_0 - word %%0_0_0_3_0_2_0_0 - word %%0_3_0_1_0_1_3_0 - word %%0_1_2_0_0_0_1_0 - word %%0_2_0_0_2_1_2_0 - word %%3_1_0_2_0_0_2_0 - word %%0_0_0_0_1_1_0_0 - word %%3_1_2_0_1_0_3_0 - word %%0_2_0_2_0_1_0_0 - word %%0_0_1_2_1_0_1_0 - word %%3_0_1_0_1_0_3_0 - word %%0_0_0_3_3_0_0_0 - word %%0_3_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $1E explode to space frame 4, same as frame 2 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_0_3_0_1_0_0 - word %%0_3_1_0_0_0_3_0 - word %%0_1_0_0_1_3_1_0 - word %%0_3_0_1_0_0_1_0 - word %%0_0_0_0_1_3_0_0 - word %%0_3_1_0_1_0_0_0 - word %%0_1_0_1_0_1_0_0 - word %%0_0_3_1_1_0_3_0 - word %%0_0_3_0_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $1F explode to space frame 5, same as frame 1 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_3_0_0_0 - word %%0_0_0_3_0_0_3_0 - word %%0_0_0_0_3_0_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_0_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $20 explode to diamond frame 1 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_3_0_0_0 - word %%0_0_0_3_0_0_3_0 - word %%0_0_0_0_3_0_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_0_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_3_0_0_0 ' $21 explode to diamond frame 2 - word %%3_0_3_0_0_0_3_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_3_0_3_0_3_0 - word %%0_3_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%3_0_0_0_0_0_0_3 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%3_0_0_0_0_0_3_0 - word %%0_0_0_0_0_0_0_0 - word %%0_3_0_0_3_0_0_3 - word %%0_0_0_3_0_0_0_0 - word %%3_0_0_0_0_0_3_0 - word %%0_0_3_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_1_1_0_0_0 ' $22 explode to diamond frame 3 - word %%0_3_0_3_0_0_0_0 - word %%0_0_1_0_0_1_0_3 - word %%0_0_3_0_2_3_0_0 - word %%0_0_0_2_0_0_1_0 - word %%0_0_0_0_0_0_3_0 - word %%1_0_2_0_0_2_0_1 - word %%3_0_0_0_0_0_0_3 - word %%1_0_0_0_0_0_0_2 - word %%3_0_2_0_0_0_0_3 - word %%0_0_0_0_0_2_2_0 - word %%0_3_0_2_0_0_3_0 - word %%0_0_1_0_1_2_0_0 - word %%0_0_3_0_0_0_0_3 - word %%0_3_0_1_2_0_0_0 - word %%0_0_0_3_3_0_0_0 - - word %%0_0_0_1_1_0_0_0 ' $23 explode to diamond frame 4 - word %%0_0_0_3_3_0_0_0 - word %%0_0_1_0_0_1_0_0 - word %%0_0_3_0_2_3_0_0 - word %%0_1_0_2_0_0_1_0 - word %%0_3_0_0_3_0_3_0 - word %%1_0_2_3_1_2_0_1 - word %%3_1_0_2_2_0_2_3 - word %%1_0_0_3_0_1_1_2 - word %%3_0_2_0_2_0_0_3 - word %%0_1_1_0_0_3_2_0 - word %%0_3_0_2_2_0_3_0 - word %%0_0_1_3_0_2_0_0 - word %%0_0_3_0_1_3_0_0 - word %%0_0_0_1_2_0_0_0 - word %%0_0_0_3_3_0_0_0 - - word %%0_0_0_1_1_0_0_0 ' $24 explode to diamond frame 5 - word %%0_0_0_3_3_0_0_0 - word %%0_0_1_2_1_1_0_0 - word %%0_0_3_2_2_3_0_0 - word %%0_1_1_3_3_2_1_0 - word %%0_3_2_3_2_2_3_0 - word %%1_2_3_1_1_3_3_1 - word %%3_3_2_3_3_2_1_3 - word %%1_2_2_3_2_3_1_2 - word %%3_2_3_1_3_1_1_3 - word %%0_1_2_3_1_3_2_0 - word %%0_3_2_1_2_1_3_0 - word %%0_0_1_3_3_2_0_0 - word %%0_0_3_2_1_3_0_0 - word %%0_0_0_1_2_0_0_0 - word %%0_0_0_3_3_0_0_0 - - word %%2_2_2_2_2_2_2_2 ' $25 inbox, flashing - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_0_0_0_0_0_0_2 - word %%2_2_2_2_2_2_2_2 - - word %%0_0_0_0_0_0_0_0 ' $26 inbox morphing into rockford, same as explode to space frame 1 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_3_0_0_0 - word %%0_0_0_3_0_0_3_0 - word %%0_0_0_0_3_0_0_0 - word %%0_0_3_0_0_0_0_0 - word %%0_3_0_0_0_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $27 inbox morphing into rockford, same as explode to space frame 2 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_3_0_0 - word %%0_0_0_3_0_1_0_0 - word %%0_3_1_0_0_0_3_0 - word %%0_1_0_0_1_3_1_0 - word %%0_3_0_1_0_0_1_0 - word %%0_0_0_0_1_3_0_0 - word %%0_3_1_0_1_0_0_0 - word %%0_1_0_1_0_1_0_0 - word %%0_0_3_1_1_0_3_0 - word %%0_0_3_0_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $28 inbox morphing into rockford, same as explode to space frame 3 - word %%0_0_0_0_0_0_0_0 - word %%0_3_0_0_3_0_3_0 - word %%0_0_0_3_0_2_0_0 - word %%0_3_0_1_0_1_3_0 - word %%0_1_2_0_0_0_1_0 - word %%0_2_0_0_2_1_2_0 - word %%3_1_0_2_0_0_2_0 - word %%0_0_0_0_1_1_0_0 - word %%3_1_2_0_1_0_3_0 - word %%0_2_0_2_0_1_0_0 - word %%0_0_1_2_1_0_1_0 - word %%3_0_1_0_1_0_3_0 - word %%0_0_0_3_3_0_0_0 - word %%0_3_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $29 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $2A - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $2B - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $2C - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $2D - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $2E - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $2F - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $30 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $31 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $32 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $33 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $34 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $35 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $36 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $37 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $38 rockford - word %%0_0_2_0_0_2_0_0 - word %%0_0_2_2_2_2_0_0 - word %%0_2_0_2_2_0_2_0 - word %%0_2_0_2_2_0_2_0 - word %%0_0_2_2_2_2_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_2_2_0_0 - word %%0_2_0_3_3_0_2_0 - word %%0_0_3_2_2_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_1_3_3_1_0_0 - word %%0_0_1_0_0_1_0_0 - word %%0_0_1_0_0_1_0_0 - word %%0_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $39 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $3A - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $3B - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%2_2_2_2_2_2_2_2 ' $3C - word %%2_2_2_2_2_2_2_2 - word %%2_0_0_2_2_0_0_2 - word %%2_2_0_2_2_2_0_2 - word %%2_3_0_2_2_3_0_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_0_0_2_2_0_0_2 - word %%2_2_0_2_2_2_0_2 - word %%2_3_0_2_2_3_0_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_2_2_2_2_2_2 - - word %%0_0_0_0_0_0_0_0 ' $3D - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $3E - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $3F - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - -' chargen - - word %%0_0_0_0_0_0_0_0 ' $80 '0' - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $81 '1' - word %%0_0_0_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $82 '2' - word %%0_3_3_3_3_3_0_0 - word %%3_3_0_0_3_3_3_0 - word %%0_0_0_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_3_3_3_0_0_0_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $83 - word %%0_3_3_3_3_3_3_0 - word %%0_0_0_0_3_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $84 - word %%3_3_0_0_0_0_0_0 - word %%3_3_0_0_0_0_0_0 - word %%3_3_0_3_3_3_0_0 - word %%3_3_3_3_3_3_3_0 - word %%0_0_0_3_3_3_0_0 - word %%0_0_0_3_3_3_0_0 - word %%0_0_0_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $85 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_0_0 - word %%0_0_0_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $86 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $87 - word %%3_3_3_3_3_3_3_0 - word %%3_0_0_0_3_3_3_0 - word %%0_0_0_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_3_3_3_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $88 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $89 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%0_3_3_3_3_3_3_0 - word %%0_0_0_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_3_3_3_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $8A ':' - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $8B ';' - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_3_3_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $8C '/' - word %%0_0_0_0_0_0_3_0 - word %%0_0_0_0_0_3_3_0 - word %%0_0_0_0_3_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_3_3_0_0_0_0 - word %%0_3_3_0_0_0_0_0 - word %%3_3_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $8D - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $8E - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $8F - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $90 space - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $91 'A' - word %%0_0_3_3_3_0_0_0 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $92 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $93 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $94 - word %%3_3_3_3_3_0_0_0 - word %%3_3_3_0_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_3_3_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_3_3_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $95 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $96 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $97 - word %%0_3_3_3_3_3_3_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_3_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $98 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $99 - word %%0_3_3_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_3_3_3_3_3_0_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $9A - word %%0_0_0_0_0_3_3_0 - word %%0_0_0_0_0_3_3_0 - word %%0_0_0_0_0_3_3_0 - word %%0_0_0_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%0_3_3_3_3_3_3_0 - word %%0_0_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $9B - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_3_3_0_0 - word %%3_3_3_3_3_0_0_0 - word %%3_3_3_3_3_0_0_0 - word %%3_3_3_0_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $9C - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $9D - word %%3_3_0_0_0_3_3_0 - word %%3_3_3_0_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_0_3_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $9E - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_3_3_3_0 - word %%3_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $9F - word %%0_3_3_3_3_3_0_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $A0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $A1 - word %%0_0_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_3_3_0_0 - word %%0_3_3_3_3_3_3_0 - word %%0_0_3_3_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $A2 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $A3 - word %%0_3_3_3_3_3_0_0 - word %%3_3_3_0_0_0_0_0 - word %%0_3_3_3_3_3_0_0 - word %%0_0_0_0_0_3_3_0 - word %%0_0_0_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $A4 - word %%3_3_3_3_3_3_3_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $A5 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $A6 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%0_3_3_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $A7 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_3_0_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_0_3_3_3_0 - word %%3_3_0_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $A8 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%0_0_3_3_3_3_0_0 - word %%0_0_3_3_3_3_0_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - word %%3_3_3_0_0_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $A9 - word %%3_3_0_0_0_3_3_0 - word %%3_3_0_0_0_3_3_0 - word %%0_3_3_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_0_3_3_3_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $AA - word %%3_3_3_3_3_3_3_0 - word %%0_0_0_3_3_3_0_0 - word %%0_0_3_3_3_0_0_0 - word %%0_3_3_3_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_0 - - word %%0_0_0_0_0_0_0_0 ' $AB '(' - word %%0_0_0_0_3_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_0_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $AC diamond - word %%0_0_0_3_0_0_0_0 - word %%0_0_3_0_3_0_0_0 - word %%0_3_3_3_3_3_0_0 - word %%3_0_0_0_0_0_3_0 - word %%0_3_3_3_3_3_0_0 - word %%0_0_3_0_3_0_0_0 - word %%0_0_0_3_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $AD ')' - word %%0_0_3_3_0_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_3_3_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $AE - word %%0_0_3_0_0_3_0_0 - word %%0_0_3_3_3_3_0_0 - word %%0_3_0_3_3_0_3_0 - word %%0_3_0_3_3_0_3_0 - word %%0_0_3_3_3_3_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_3_3_3_3_0_0 - - word %%0_0_0_0_0_0_0_0 ' $AF ',' - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_0_3_3_0_0_0 - word %%0_0_3_3_0_0_0_0 - - word %%1_3_2_2_1_3_2_2 ' $B0 scrolling bgnd of the title screen - word %%1_2_2_2_1_2_2_2 - word %%0_1_2_2_0_1_2_2 - word %%2_2_2_2_2_2_2_2 - word %%2_2_1_3_2_2_1_3 - word %%2_2_1_2_2_2_1_2 - word %%2_2_0_1_2_2_0_1 - word %%2_2_2_2_2_2_2_2 - - word %%3_3_3_3_3_3_3_3 ' $B1 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - - word %%1_2_3_3_3_3_3_3 ' $B2 - word %%1_2_3_3_3_3_3_3 - word %%1_2_3_3_3_3_3_3 - word %%1_2_3_3_3_3_3_3 - word %%1_2_3_3_3_3_3_3 - word %%1_2_3_3_3_3_3_3 - word %%1_2_3_3_3_3_3_3 - word %%1_2_3_3_3_3_3_3 - - word %%3_3_3_3_0_0_0_0 ' $B3 - word %%3_3_3_3_3_0_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - - word %%3_3_3_3_3_3_3_3 ' $B4 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_3_3_0_0_0 - - word %%3_3_3_3_0_0_0_0 ' $B5 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - - word %%0_0_0_0_3_3_3_3 ' $B6 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - - word %%0_0_0_0_0_0_0_0 ' $B7 - word %%3_0_0_0_0_0_0_0 - word %%3_3_0_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - - word %%3_3_3_3_0_0_0_0 ' $B8 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_0_0_0_0_0_0 - word %%3_0_0_0_0_0_0_0 - - word %%1_2_3_3_0_0_0_0 ' $B9 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - - word %%0_0_0_0_1_2_3_3 ' $BA - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - - word %%0_0_0_0_1_2_3_3 ' $BB - word %%0_0_0_0_1_2_2_2 - word %%0_0_0_0_1_2_2_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_3 - - word %%3_3_3_3_3_3_3_3 ' $BC - word %%2_3_2_3_3_3_2_3 - word %%2_3_2_2_3_2_2_3 - word %%3_3_2_2_2_2_2_3 - word %%3_3_2_3_2_3_2_3 - word %%3_3_2_3_3_3_2_3 - word %%3_3_2_3_3_3_2_3 - word %%3_3_3_3_3_3_3_3 - - word %%3_3_3_3_0_0_0_0 ' $BD - word %%3_3_3_3_3_0_0_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - - word %%3_3_3_3_3_3_3_3 ' $BE - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_3 - word %%3_3_3_3_3_3_3_0 - word %%3_3_3_3_3_3_0_0 - word %%3_3_3_3_3_0_0_0 - - word %%3_3_3_3_0_0_0_0 ' $BF - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - - word %%0_0_0_0_3_3_3_3 ' $C0 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - word %%0_0_0_0_3_3_3_3 - - word %%0_0_0_0_0_0_0_0 ' $C1 - word %%3_0_0_0_0_0_0_0 - word %%3_3_0_0_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - - word %%3_3_3_3_0_0_0_0 ' $C2 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_3_0_0_0_0 - word %%3_3_3_0_0_0_0_0 - word %%3_3_0_0_0_0_0_0 - word %%3_0_0_0_0_0_0_0 - - word %%1_2_3_3_0_0_0_0 ' $C3 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - word %%1_2_3_3_0_0_0_0 - - word %%0_0_0_0_1_2_3_3 ' $C4 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - word %%0_0_0_0_1_2_3_3 - - word %%0_0_0_0_1_2_3_3 ' $C5 - word %%0_0_0_0_1_2_2_2 - word %%0_0_0_0_1_2_2_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_2 - word %%0_0_0_0_1_2_3_3 - - word %%0_0_0_0_0_0_0_0 ' $C6 unused... padding for second chargen (see below) - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $C7 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $C8 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $C9 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $CA - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $CB - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $CC - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $CD - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $CE - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $CF - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - -' this is basically the same character generator, but using -' a different color (I need this for the title screen). Either -' this, or separate color attributes for each cell of the -' screen. We have still some space here, so... - - word %%0_0_0_0_0_0_0_0 ' $D0 '0' - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D1 '1' - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $D2 '2' - word %%0_2_2_2_2_2_0_0 - word %%2_2_0_0_2_2_2_0 - word %%0_0_0_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_2_2_2_0_0_0_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $D3 - word %%0_2_2_2_2_2_2_0 - word %%0_0_0_0_2_2_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_0_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D4 - word %%2_2_0_0_0_0_0_0 - word %%2_2_0_0_0_0_0_0 - word %%2_2_0_2_2_2_0_0 - word %%2_2_2_2_2_2_2_0 - word %%0_0_0_2_2_2_0_0 - word %%0_0_0_2_2_2_0_0 - word %%0_0_0_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D5 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_0_0 - word %%0_0_0_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D6 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D7 - word %%2_2_2_2_2_2_2_0 - word %%2_0_0_0_2_2_2_0 - word %%0_0_0_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_2_2_2_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D8 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $D9 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_0_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_2_2_2_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $DA ':' - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $DB ';' - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $DC '/' - word %%0_0_0_0_0_0_2_0 - word %%0_0_0_0_0_2_2_0 - word %%0_0_0_0_2_2_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_0_0_0_0 - word %%0_2_2_0_0_0_0_0 - word %%2_2_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $DD - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $DE - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $DF - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $E0 space - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $E1 'A' - word %%0_0_2_2_2_0_0_0 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $E2 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $E3 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $E4 - word %%2_2_2_2_2_0_0_0 - word %%2_2_2_0_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_2_2_0_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_2_2_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $E5 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $E6 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $E7 - word %%0_2_2_2_2_2_2_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_2_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $E8 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $E9 - word %%0_2_2_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_2_2_2_2_2_0_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $EA - word %%0_0_0_0_0_2_2_0 - word %%0_0_0_0_0_2_2_0 - word %%0_0_0_0_0_2_2_0 - word %%0_0_0_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $EB - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_2_2_0_0 - word %%2_2_2_2_2_0_0_0 - word %%2_2_2_2_2_0_0_0 - word %%2_2_2_0_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $EC - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $ED - word %%2_2_0_0_0_2_2_0 - word %%2_2_2_0_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_0_2_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $EE - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_2_2_2_0 - word %%2_2_2_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $EF - word %%0_2_2_2_2_2_0_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $F0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $F1 - word %%0_0_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_2_2_0_0 - word %%0_2_2_2_2_2_2_0 - word %%0_0_2_2_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $F2 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $F3 - word %%0_2_2_2_2_2_0_0 - word %%2_2_2_0_0_0_0_0 - word %%0_2_2_2_2_2_0_0 - word %%0_0_0_0_0_2_2_0 - word %%0_0_0_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $F4 - word %%2_2_2_2_2_2_2_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $F5 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $F6 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%0_2_2_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $F7 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_2_0_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_0_2_2_2_0 - word %%2_2_0_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $F8 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%0_0_2_2_2_2_0_0 - word %%0_0_2_2_2_2_0_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - word %%2_2_2_0_0_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $F9 - word %%2_2_0_0_0_2_2_0 - word %%2_2_0_0_0_2_2_0 - word %%0_2_2_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_0_2_2_2_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $FA - word %%2_2_2_2_2_2_2_0 - word %%0_0_0_2_2_2_0_0 - word %%0_0_2_2_2_0_0_0 - word %%0_2_2_2_0_0_0_0 - word %%2_2_2_0_0_0_0_0 - word %%2_2_2_2_2_2_2_0 - word %%2_2_2_2_2_2_2_0 - - word %%0_0_0_0_0_0_0_0 ' $FB '(' - word %%0_0_0_0_2_2_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_0_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $FC diamond - word %%0_0_0_2_0_0_0_0 - word %%0_0_2_0_2_0_0_0 - word %%0_2_2_2_2_2_0_0 - word %%2_0_0_0_0_0_2_0 - word %%0_2_2_2_2_2_0_0 - word %%0_0_2_0_2_0_0_0 - word %%0_0_0_2_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $FD ')' - word %%0_0_2_2_0_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_0_0_0_0 - - word %%0_0_0_0_0_0_0_0 ' $FE - word %%0_0_2_0_0_2_0_0 - word %%0_0_2_2_2_2_0_0 - word %%0_2_0_2_2_0_2_0 - word %%0_2_0_2_2_0_2_0 - word %%0_0_2_2_2_2_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_2_2_0_0 - - word %%0_0_0_0_0_0_0_0 ' $FF ',' - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_0_0_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_0_2_2_0_0_0 - word %%0_0_2_2_0_0_0_0 - diff --git a/source/boulder/bellatrix/bd_pal.spin b/source/boulder/bellatrix/bd_tv.spin similarity index 99% rename from source/boulder/bellatrix/bd_pal.spin rename to source/boulder/bellatrix/bd_tv.spin index beb6379..cc74aaa 100644 --- a/source/boulder/bellatrix/bd_pal.spin +++ b/source/boulder/bellatrix/bd_tv.spin @@ -111,7 +111,11 @@ con TV_NTSC = 0 TV_PAL = 1 - TV_MODE = TV_PAL ' <--- Select your TV system here -- NTSC or PAL ---<<< +#ifdef __TV_NTSC + TV_MODE = TV_NTSC +#else + TV_MODE = TV_PAL +#endif ' Game controller codes GP_RIGHT = %00000001 '(Right arrow) Move right @@ -3809,4 +3813,4 @@ tiles word %%0_0_0_0_0_0_0_0 ' $00 space word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_0_0_0_0 - \ No newline at end of file + diff --git a/source/shoot/bellatrix/_readme_.txt b/source/shoot/bellatrix/_readme_.txt deleted file mode 100644 index 3bb0f77..0000000 --- a/source/shoot/bellatrix/_readme_.txt +++ /dev/null @@ -1,23 +0,0 @@ -BST Propeller Archive -Created by Brads Spin Tool Compiler v0.15.4-pre5 - Copyright 2008,2009,2010 All rights reserved -Compiled for i386 Win32 at 14:24:31 on 2010/03/10 - -Archive Created at 15:34:27 On 01/05/10 -Included Objects : -shoot1 - | - +--tv - | - +--graphics - | - +--mouse - | - +--yma_hss_v1.2 - -, - - shoot1.spin - - TV.spin - - Graphics.spin - - Mouse.spin - - yma_hss_v1.2.spin -, diff --git a/source/stracker/bellatrix/stkeyb.spin b/source/stracker/bellatrix/stkeyb.spin deleted file mode 100644 index 49aadfb..0000000 --- a/source/stracker/bellatrix/stkeyb.spin +++ /dev/null @@ -1,738 +0,0 @@ -''*************************************** -''* PS/2 Keyboard Driver v1.0.1 * -''* Author: Chip Gracey * -''* Copyright (c) 2004 Parallax, Inc. * -''* See end of file for terms of use. * -''*************************************** - -{-----------------REVISION HISTORY----------------- - v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96} - -VAR - - long cog - - long par_tail 'key buffer tail read/write (19 contiguous longs) - long par_head 'key buffer head read-only - long par_present 'keyboard present read-only - long par_states[8] 'key states (256 bits) read-only - long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters) - - -PUB start(dpin, cpin) : okay - -'' Start keyboard driver - starts a cog -'' returns false if no cog available -'' -'' dpin = data signal on PS/2 jack -'' cpin = clock signal on PS/2 jack -'' -'' use 100-ohm resistors between pins and jack -'' use 10K-ohm resistors to pull jack-side signals to VDD -'' connect jack-power to 5V, jack-gnd to VSS -'' -'' all lock-keys will be enabled, NumLock will be initially 'on', -'' and auto-repeat will be set to 15cps with a delay of .5s - - okay := startx(dpin, cpin, %0_000_000, %01_01000) - - -PUB startx(dpin, cpin, locks, auto) : okay - -'' Like start, but allows you to specify lock settings and auto-repeat -'' -'' locks = lock setup -'' bit 6 disallows shift-alphas (case set soley by CapsLock) -'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state -'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock -'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') -'' -'' auto = auto-repeat setup -'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) -'' bits 4..0 specify repeat rate (0=30cps..31=2cps) -'' (eg %01_00000 = .5s delay, 30cps repeat) - - stop - longmove(@par_keys, @dpin, 4) - okay := cog := cognew(@entry, @par_tail) + 1 - - -PUB stop - -'' Stop keyboard driver - frees a cog - - if cog - cogstop(cog~ - 1) - longfill(@par_tail, 0, 19) - - -PUB present : truefalse - -'' Check if keyboard present - valid ~2s after start -'' returns t|f - - truefalse := -par_present - - -PUB key : keycode - -'' Get key (never waits) -'' returns key (0 if buffer empty) - - if par_tail <> par_head - keycode := par_keys.word[par_tail] - par_tail := ++par_tail & $F - - -PUB getkey : keycode - -'' Get next key (may wait for keypress) -'' returns key - - repeat until (keycode := key) - - -PUB newkey : keycode - -'' Clear buffer and get new key (always waits for keypress) -'' returns key - - par_tail := par_head - keycode := getkey - - -PUB gotkey : truefalse - -'' Check if any key in buffer -'' returns t|f - - truefalse := par_tail <> par_head - - -PUB clearkeys - -'' Clear key buffer - - par_tail := par_head - - -PUB keystate(k) : state - -'' Get the state of a particular key -'' returns t|f - - state := -(par_states[k >> 5] >> k & 1) - - -DAT - -'****************************************** -'* Assembly language PS/2 keyboard driver * -'****************************************** - - org -' -' -' Entry -' -entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto - mov x,par - add x,#11*4 - mov y,#4 -:par rdlong 0,x - add :par,dlsb - add x,#4 - djnz y,#:par - - mov dmask,#1 'set pin masks - shl dmask,_dpin - mov cmask,#1 - shl cmask,_cpin - - test _dpin,#$20 wc 'modify port registers within code - muxc _d1,dlsb - muxc _d2,dlsb - muxc _d3,#1 - muxc _d4,#1 - test _cpin,#$20 wc - muxc _c1,dlsb - muxc _c2,dlsb - muxc _c3,#1 - - mov _head,#0 'reset output parameter _head -' -' -' Reset keyboard -' -reset mov dira,#0 'reset directions - mov dirb,#0 - - movd :par,#_present 'reset output parameters _present/_states[8] - mov x,#1+8 -:par mov 0,#0 - add :par,dlsb - djnz x,#:par - - mov stat,#8 'set reset flag -' -' -' Update parameters -' -update movd :par,#_head 'update output parameters _head/_present/_states[8] - mov x,par - add x,#1*4 - mov y,#1+1+8 -:par wrlong 0,x - add :par,dlsb - add x,#4 - djnz y,#:par - - test stat,#8 wc 'if reset flag, transmit reset command - if_c mov data,#$FF - if_c call #transmit -' -' -' Get scancode -' -newcode mov stat,#0 'reset state - -:same call #receive 'receive byte from keyboard - - cmp data,#$83+1 wc 'scancode? - - if_nc cmp data,#$AA wz 'powerup/reset? - if_nc_and_z jmp #configure - - if_nc cmp data,#$E0 wz 'extended? - if_nc_and_z or stat,#1 - if_nc_and_z jmp #:same - - if_nc cmp data,#$F0 wz 'released? - if_nc_and_z or stat,#2 - if_nc_and_z jmp #:same - - if_nc jmp #newcode 'unknown, ignore -' -' -' Translate scancode and enter into buffer -' - test stat,#1 wc 'lookup code with extended flag - rcl data,#1 - call #look - - cmp data,#0 wz 'if unknown, ignore - if_z jmp #newcode - - mov t,_states+6 'remember lock keys in _states - - mov x,data 'set/clear key bit in _states - shr x,#5 - add x,#_states - movd :reg,x - mov y,#1 - shl y,data - test stat,#2 wc -:reg muxnc 0,y - - if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done - if_c jmp #update - - mov y,_states+7 'get shift/ctrl/alt/win bit pairs - shr y,#16 - - cmpsub data,#$E0 wc 'translate keypad, considering numlock - if_c test _locks,#%100 wz - if_c_and_z add data,#@keypad1-@table - if_c_and_nz add data,#@keypad2-@table - if_c call #look - if_c jmp #:flags - - cmpsub data,#$DD wc 'handle scrlock/capslock/numlock - if_c mov x,#%001_000 - if_c shl x,data - if_c andn x,_locks - if_c shr x,#3 - if_c shr t,#29 'ignore auto-repeat - if_c andn x,t wz - if_c xor _locks,x - if_c add data,#$DD - if_c_and_nz or stat,#4 'if change, set configure flag to update leds - - test y,#%11 wz 'get shift into nz - - if_nz cmp data,#$60+1 wc 'check shift1 - if_nz_and_c cmpsub data,#$5B wc - if_nz_and_c add data,#@shift1-@table - if_nz_and_c call #look - if_nz_and_c andn y,#%11 - - if_nz cmp data,#$3D+1 wc 'check shift2 - if_nz_and_c cmpsub data,#$27 wc - if_nz_and_c add data,#@shift2-@table - if_nz_and_c call #look - if_nz_and_c andn y,#%11 - - test _locks,#%010 wc 'check shift-alpha, considering capslock - muxnc :shift,#$20 - test _locks,#$40 wc - if_nz_and_nc xor :shift,#$20 - cmp data,#"z"+1 wc - if_c cmpsub data,#"a" wc -:shift if_c add data,#"A" - if_c andn y,#%11 - -:flags ror data,#8 'add shift/ctrl/alt/win flags - mov x,#4 '+$100 if shift -:loop test y,#%11 wz '+$200 if ctrl - shr y,#2 '+$400 if alt - if_nz or data,#1 '+$800 if win - ror data,#1 - djnz x,#:loop - rol data,#12 - - rdlong x,par 'if room in buffer and key valid, enter - sub x,#1 - and x,#$F - cmp x,_head wz - if_nz test data,#$FF wz - if_nz mov x,par - if_nz add x,#11*4 - if_nz add x,_head - if_nz add x,_head - if_nz wrword data,x - if_nz add _head,#1 - if_nz and _head,#$F - - test stat,#4 wc 'if not configure flag, done - if_nc jmp #update 'else configure to update leds -' -' -' Configure keyboard -' -configure mov data,#$F3 'set keyboard auto-repeat - call #transmit - mov data,_auto - and data,#%11_11111 - call #transmit - - mov data,#$ED 'set keyboard lock-leds - call #transmit - mov data,_locks - rev data,#-3 & $1F - test data,#%100 wc - rcl data,#1 - and data,#%111 - call #transmit - - mov x,_locks 'insert locks into _states - and x,#%111 - shl _states+7,#3 - or _states+7,x - ror _states+7,#3 - - mov _present,#1 'set _present - - jmp #update 'done -' -' -' Lookup byte in table -' -look ror data,#2 'perform lookup - movs :reg,data - add :reg,#table - shr data,#27 - mov x,data -:reg mov data,0 - shr data,x - - jmp #rand 'isolate byte -' -' -' Transmit byte to keyboard -' -transmit -_c1 or dira,cmask 'pull clock low - movs napshr,#13 'hold clock for ~128us (must be >100us) - call #nap -_d1 or dira,dmask 'pull data low - movs napshr,#18 'hold data for ~4us - call #nap -_c2 xor dira,cmask 'release clock - - test data,#$0FF wc 'append parity and stop bits to byte - muxnc data,#$100 - or data,dlsb - - mov x,#10 'ready 10 bits -transmit_bit call #wait_c0 'wait until clock low - shr data,#1 wc 'output data bit -_d2 muxnc dira,dmask - mov wcond,c1 'wait until clock high - call #wait - djnz x,#transmit_bit 'another bit? - - mov wcond,c0d0 'wait until clock and data low - call #wait - mov wcond,c1d1 'wait until clock and data high - call #wait - - call #receive_ack 'receive ack byte with timed wait - cmp data,#$FA wz 'if ack error, reset keyboard - if_nz jmp #reset - -transmit_ret ret -' -' -' Receive byte from keyboard -' -receive test _cpin,#$20 wc 'wait indefinitely for initial clock low - waitpne cmask,cmask -receive_ack - mov x,#11 'ready 11 bits -receive_bit call #wait_c0 'wait until clock low - movs napshr,#16 'pause ~16us - call #nap -_d3 test dmask,ina wc 'input data bit - rcr data,#1 - mov wcond,c1 'wait until clock high - call #wait - djnz x,#receive_bit 'another bit? - - shr data,#22 'align byte - test data,#$1FF wc 'if parity error, reset keyboard - if_nc jmp #reset -rand and data,#$FF 'isolate byte - -look_ret -receive_ack_ret -receive_ret ret -' -' -' Wait for clock/data to be in required state(s) -' -wait_c0 mov wcond,c0 '(wait until clock low) - -wait mov y,tenms 'set timeout to 10ms - -wloop movs napshr,#18 'nap ~4us - call #nap -_c3 test cmask,ina wc 'check required state(s) -_d4 test dmask,ina wz 'loop until got state(s) or timeout -wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) - - tjz y,#reset 'if timeout, reset keyboard -wait_ret -wait_c0_ret ret - - -c0 if_c djnz y,#wloop '(if_never replacements) -c1 if_nc djnz y,#wloop -c0d0 if_c_or_nz djnz y,#wloop -c1d1 if_nc_or_z djnz y,#wloop -' -' -' Nap -' -nap rdlong t,#0 'get clkfreq -napshr shr t,#18/16/13 'shr scales time - min t,#3 'ensure waitcnt won't snag - add t,cnt 'add cnt to time - waitcnt t,#0 'wait until time elapses (nap) - -nap_ret ret -' -' -' Initialized data -' -' -dlsb long 1 << 9 -tenms long 10_000 / 4 -' -' -' Lookup table -' ascii scan extkey regkey ()=keypad -' -table word $0000 '00 - word $00D8 '01 F9 - word $0000 '02 - word $00D4 '03 F5 - word $00D2 '04 F3 - word $00D0 '05 F1 - word $00D1 '06 F2 - word $00DB '07 F12 - word $0000 '08 - word $00D9 '09 F10 - word $00D7 '0A F8 - word $00D5 '0B F6 - word $00D3 '0C F4 - word $0009 '0D Tab - word $0060 '0E ` - word $0000 '0F - word $0000 '10 - word $F5F4 '11 Alt-R Alt-L - word $00F0 '12 Shift-L - word $0000 '13 - word $F3F2 '14 Ctrl-R Ctrl-L - word $0071 '15 q - word $0031 '16 1 - word $0000 '17 - word $0000 '18 - word $0000 '19 - word $0079 '1A z y - word $0073 '1B s - word $0061 '1C a - word $0077 '1D w - word $0032 '1E 2 - word $F600 '1F Win-L - word $0000 '20 - word $0063 '21 c - word $0078 '22 x - word $0064 '23 d - word $0065 '24 e - word $0034 '25 4 - word $0033 '26 3 - word $F700 '27 Win-R - word $0000 '28 - word $0020 '29 Space - word $0076 '2A v - word $0066 '2B f - word $0074 '2C t - word $0072 '2D r - word $0035 '2E 5 - word $CC00 '2F Apps - word $0000 '30 - word $006E '31 n - word $0062 '32 b - word $0068 '33 h - word $0067 '34 g - word $007A '35 y z - word $0036 '36 6 - word $CD00 '37 Power - word $0000 '38 - word $002C '39 , - word $006D '3A m - word $006A '3B j - word $0075 '3C u - word $0037 '3D 7 - word $0038 '3E 8 - word $CE00 '3F Sleep - word $0000 '40 - word $002C '41 , - word $006B '42 k - word $0069 '43 i - word $006F '44 o - word $0030 '45 0 - word $0039 '46 9 - word $0000 '47 - word $0000 '48 - word $002E '49 . - word $002D '4A (/) / - - word $006C '4B l - word $007B '4C } ö - word $0070 '4D p - word $002B '4E + - word $0000 '4F - word $0000 '50 - word $0000 '51 - word $007D '52 { ä - word $0000 '53 - word $005B '54 [ Ü - word $003D '55 = - word $0000 '56 - word $0000 '57 - word $00DE '58 CapsLock - word $00F1 '59 Shift-R - word $EB0D '5A (Enter) Enter - word $005D '5B ] - word $0000 '5C - word $0023 '5D \ # - word $CF00 '5E WakeUp - word $0000 '5F - word $0000 '60 - word $003C '61 < - word $0000 '62 - word $0000 '63 - word $0000 '64 - word $0000 '65 - word $00C8 '66 BackSpace - word $0000 '67 - word $0000 '68 - word $C5E1 '69 End (1) - word $0000 '6A - word $C0E4 '6B Left (4) - word $C4E7 '6C Home (7) - word $0000 '6D - word $0000 '6E - word $0000 '6F - word $CAE0 '70 Insert (0) - word $C9EA '71 Delete (.) - word $C3E2 '72 Down (2) - word $00E5 '73 (5) - word $C1E6 '74 Right (6) - word $C2E8 '75 Up (8) - word $00CB '76 Esc - word $00DF '77 NumLock - word $00DA '78 F11 - word $00EC '79 (+) - word $C7E3 '7A PageDn (3) - word $00ED '7B (-) - word $DCEE '7C PrScr (*) - word $C6E9 '7D PageUp (9) - word $00DD '7E ScrLock - word $0000 '7F - word $0000 '80 - word $0000 '81 - word $0000 '82 - word $00D6 '83 F7 - -keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" - -keypad2 byte "0123456789.", $0D, "+-*/" - -shift1 byte "{|}__°________" '5B..60 - '"{|}", 0, 0, "~" - -shift2 byte "}___*;_:?=!",$22,"@$%&/()eÖ>+" '24..3D - '$22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" -' -' -' Uninitialized data -' -dmask res 1 -cmask res 1 -stat res 1 -data res 1 -x res 1 -y res 1 -t res 1 - -_head res 1 'write-only -_present res 1 'write-only -_states res 8 'write-only -_dpin res 1 'read-only at start -_cpin res 1 'read-only at start -_locks res 1 'read-only at start -_auto res 1 'read-only at start - -'' -'' -'' _________ -'' Key Codes -'' -'' 00..DF = keypress and keystate -'' E0..FF = keystate only -'' -'' -'' 09 Tab -'' 0D Enter -'' 20 Space -'' 21 ! -'' 22 " -'' 23 # -'' 24 $ -'' 25 % -'' 26 & -'' 27 ' -'' 28 ( -'' 29 ) -'' 2A * -'' 2B + -'' 2C , -'' 2D - -'' 2E . -'' 2F / -'' 30 0..9 -'' 3A : -'' 3B ; -'' 3C < -'' 3D = -'' 3E > -'' 3F ? -'' 40 @ -'' 41..5A A..Z -'' 5B [ -'' 5C \ -'' 5D ] -'' 5E ^ -'' 5F _ -'' 60 ` -'' 61..7A a..z -'' 7B { -'' 7C | -'' 7D } -'' 7E ~ -'' -'' 80-BF (future international character support) -'' -'' C0 Left Arrow -'' C1 Right Arrow -'' C2 Up Arrow -'' C3 Down Arrow -'' C4 Home -'' C5 End -'' C6 Page Up -'' C7 Page Down -'' C8 Backspace -'' C9 Delete -'' CA Insert -'' CB Esc -'' CC Apps -'' CD Power -'' CE Sleep -'' CF Wakeup -'' -'' D0..DB F1..F12 -'' DC Print Screen -'' DD Scroll Lock -'' DE Caps Lock -'' DF Num Lock -'' -'' E0..E9 Keypad 0..9 -'' EA Keypad . -'' EB Keypad Enter -'' EC Keypad + -'' ED Keypad - -'' EE Keypad * -'' EF Keypad / -'' -'' F0 Left Shift -'' F1 Right Shift -'' F2 Left Ctrl -'' F3 Right Ctrl -'' F4 Left Alt -'' F5 Right Alt -'' F6 Left Win -'' F7 Right Win -'' -'' FD Scroll Lock State -'' FE Caps Lock State -'' FF Num Lock State -'' -'' +100 if Shift -'' +200 if Ctrl -'' +400 if Alt -'' +800 if Win -'' -'' eg. Ctrl-Alt-Delete = $6C9 -'' -'' -'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. - -{{ - -┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ TERMS OF USE: MIT License │ -├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ -│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ -│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ -│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ -│is furnished to do so, subject to the following conditions: │ -│ │ -│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ -│ │ -│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ -│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ -│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ -│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ -└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -}} \ No newline at end of file diff --git a/source/stracker/bellatrix/stmouse.spin b/source/stracker/bellatrix/stmouse.spin deleted file mode 100644 index cbcee65..0000000 --- a/source/stracker/bellatrix/stmouse.spin +++ /dev/null @@ -1,470 +0,0 @@ -''***************************** -''* PS/2 Mouse Driver v1.1 * -''* (C) 2006 Parallax, Inc. * -''***************************** - -' v1.0 - 01 May 2006 - original version -' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects - - -VAR - - long cog - - long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs) - - long par_x 'absolute x read-only (7 contiguous longs) - long par_y 'absolute y read-only - long par_z 'absolute z read-only - long par_buttons 'button states read-only - long par_present 'mouse present read-only - long par_dpin 'data pin write-only - long par_cpin 'clock pin write-only - - long bx_min, by_min, bz_min 'min/max must be contiguous - long bx_max, by_max, bz_max - long bx_div, by_div, bz_div - long bx_acc, by_acc, bz_acc - - -PUB start(dpin, cpin) : okay - -'' Start mouse driver - starts a cog -'' returns false if no cog available -'' -'' dpin = data signal on PS/2 jack -'' cpin = clock signal on PS/2 jack -'' -'' use 100-ohm resistors between pins and jack -'' use 10K-ohm resistors to pull jack-side signals to VDD -'' connect jack-power to 5V, jack-gnd to VSS - - stop - par_dpin := dpin - par_cpin := cpin - okay := cog := cognew(@entry, @par_x) + 1 - - -PUB stop - -'' Stop mouse driver - frees a cog - - if cog - cogstop(cog~ - 1) - longfill(@oldx, 0, 10) - - -PUB present : type - -'' Check if mouse present - valid ~2s after start -'' returns mouse type: -'' -'' 3 = five-button scrollwheel mouse -'' 2 = three-button scrollwheel mouse -'' 1 = two-button or three-button mouse -'' 0 = no mouse connected - - type := par_present - - -PUB button(b) : state - -'' Get the state of a particular button -'' returns t|f - - state := -(par_buttons >> b & 1) - - -PUB buttons : states - -'' Get the states of all buttons -'' returns buttons: -'' -'' bit4 = right-side button -'' bit3 = left-side button -'' bit2 = center/scrollwheel button -'' bit1 = right button -'' bit0 = left button - - states := par_buttons - - -PUB abs_x : x - -'' Get absolute-x - - x := par_x - - -PUB abs_y : y - -'' Get absolute-y - - y := par_y - - -PUB abs_z : z - -'' Get absolute-z (scrollwheel) - - z := par_z - - -PUB delta_reset - -'' Reset deltas - - oldx := par_x - oldy := par_y - oldz := par_z - - -PUB delta_x : x | newx - -'' Get delta-x - - newx := par_x - x := newx - oldx - oldx := newx - - -PUB delta_y : y | newy - -'' Get delta-y - - newy := par_y - y := newy - oldy - oldy := newy - - -PUB delta_z : z | newz - -'' Get delta-z (scrollwheel) - - newz := par_z - z := newz - oldz - oldz := newz - - -PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i - -'' Set bounding limits - - longmove(@bx_min, @xmin, 6) - - -PUB bound_scales(x_scale, y_scale, z_scale) - -'' Set bounding scales (usually +/-1's, bigger values divide) - - longmove(@bx_div, @x_scale, 3) - - -PUB bound_preset(x, y, z) | i, d - -'' Preset bound coordinates - - repeat i from 0 to 2 - d := ||bx_div[i] - bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1 - - -PUB bound_x : x - -'' Get bound-x - - x := bound(0, delta_x) - - -PUB bound_y : y - -'' Get bound-y - - y := bound(1, delta_y) - - -PUB bound_z : z - -'' Get bound-z - - z := bound(2, delta_z) - - -PRI bound(i, delta) : b | d - - d := bx_div[i] - b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d - - -DAT - -'*************************************** -'* Assembly language PS/2 mouse driver * -'*************************************** - - org -' -' -' Entry -' -entry mov p,par 'load input parameters: - add p,#5*4 '_dpin/_cpin - rdlong _dpin,p - add p,#4 - rdlong _cpin,p - - mov dmask,#1 'set pin masks - shl dmask,_dpin - mov cmask,#1 - shl cmask,_cpin - - test _dpin,#$20 wc 'modify port registers within code - muxc _d1,dlsb - muxc _d2,dlsb - muxc _d3,#1 - muxc _d4,#1 - test _cpin,#$20 wc - muxc _c1,dlsb - muxc _c2,dlsb - muxc _c3,#1 - - movd :par,#_x 'reset output parameters: - mov p,#5 '_x/_y/_z/_buttons/_present -:par mov 0,#0 - add :par,dlsb - djnz p,#:par -' -' -' Reset mouse -' -reset mov dira,#0 'reset directions - mov dirb,#0 - - mov stat,#1 'set reset flag -' -' -' Update parameters -' -update movd :par,#_x 'update output parameters: - mov p,par '_x/_y/_z/_buttons/_present - mov q,#5 -:par wrlong 0,p - add :par,dlsb - add p,#4 - djnz q,#:par - - test stat,#1 wc 'if reset flag, transmit reset command - if_c mov data,#$FF - if_c call #transmit -' -' -' Get data packet -' - mov stat,#0 'reset state - - call #receive 'receive first byte - - cmp data,#$AA wz 'powerup/reset? - if_z jmp #init - - mov _buttons,data 'data packet, save buttons - - call #receive 'receive second byte - - test _buttons,#$10 wc 'adjust _x - muxc data,signext - add _x,data - - call #receive 'receive third byte - - test _buttons,#$20 wc 'adjust _y - muxc data,signext - add _y,data - - and _buttons,#%111 'trim buttons - - cmp _present,#2 wc 'if not scrollwheel mouse, update parameters - if_c jmp #update - - - call #receive 'scrollwheel mouse, receive fourth byte - - cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons - if_z test data,#$10 wc - if_z_and_c or _buttons,#%01000 - if_z test data,#$20 wc - if_z_and_c or _buttons,#%10000 - - shl data,#28 'adjust _z - sar data,#28 - sub _z,data - - jmp #update 'update parameters -' -' -' Initialize mouse -' -init call #receive '$AA received, receive id - - movs crate,#100 'try to enable 3-button scrollwheel type - call #checktype - movs crate,#200 'try to enable 5-button scrollwheel type - call #checktype - shr data,#1 'if neither, 3-button type - add data,#1 - mov _present,data - - movs srate,#200 'set 200 samples per second - call #setrate - - mov data,#$F4 'enable data reporting - call #transmit - - jmp #update -' -' -' Check mouse type -' -checktype movs srate,#200 'perform "knock" sequence to enable - call #setrate '..scrollwheel and extra buttons - -crate movs srate,#200/100 - call #setrate - - movs srate,#80 - call #setrate - - mov data,#$F2 'read type - call #transmit - call #receive - -checktype_ret ret -' -' -' Set sample rate -' -setrate mov data,#$F3 - call #transmit -srate mov data,#0 - call #transmit - -setrate_ret ret -' -' -' Transmit byte to mouse -' -transmit -_c1 or dira,cmask 'pull clock low - movs napshr,#13 'hold clock for ~128us (must be >100us) - call #nap -_d1 or dira,dmask 'pull data low - movs napshr,#18 'hold data for ~4us - call #nap -_c2 xor dira,cmask 'release clock - - test data,#$0FF wc 'append parity and stop bits to byte - muxnc data,#$100 - or data,dlsb - - mov p,#10 'ready 10 bits -transmit_bit call #wait_c0 'wait until clock low - shr data,#1 wc 'output data bit -_d2 muxnc dira,dmask - mov wcond,c1 'wait until clock high - call #wait - djnz p,#transmit_bit 'another bit? - - mov wcond,c0d0 'wait until clock and data low - call #wait - mov wcond,c1d1 'wait until clock and data high - call #wait - - call #receive_ack 'receive ack byte with timed wait - cmp data,#$FA wz 'if ack error, reset mouse - if_nz jmp #reset - -transmit_ret ret -' -' -' Receive byte from mouse -' -receive test _cpin,#$20 wc 'wait indefinitely for initial clock low - waitpne cmask,cmask -receive_ack - mov p,#11 'ready 11 bits -receive_bit call #wait_c0 'wait until clock low - movs napshr,#16 'pause ~16us - call #nap -_d3 test dmask,ina wc 'input data bit - rcr data,#1 - mov wcond,c1 'wait until clock high - call #wait - djnz p,#receive_bit 'another bit? - - shr data,#22 'align byte - test data,#$1FF wc 'if parity error, reset mouse - if_nc jmp #reset - and data,#$FF 'isolate byte - -receive_ack_ret -receive_ret ret -' -' -' Wait for clock/data to be in required state(s) -' -wait_c0 mov wcond,c0 '(wait until clock low) - -wait mov q,tenms 'set timeout to 10ms - -wloop movs napshr,#18 'nap ~4us - call #nap -_c3 test cmask,ina wc 'check required state(s) -_d4 test dmask,ina wz 'loop until got state(s) or timeout -wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1) - - tjz q,#reset 'if timeout, reset mouse -wait_ret -wait_c0_ret ret - - -c0 if_c djnz q,#wloop '(if_never replacements) -c1 if_nc djnz q,#wloop -c0d0 if_c_or_nz djnz q,#wloop -c1d1 if_nc_or_z djnz q,#wloop -' -' -' Nap -' -nap rdlong t,#0 'get clkfreq -napshr shr t,#18/16/13 'shr scales time - min t,#3 'ensure waitcnt won't snag - add t,cnt 'add cnt to time - waitcnt t,#0 'wait until time elapses (nap) - -nap_ret ret -' -' -' Initialized data -' -dlsb long 1 << 9 -tenms long 10_000 / 4 -signext long $FFFFFF00 -' -' -' Uninitialized data -' -dmask res 1 -cmask res 1 -stat res 1 -data res 1 -p res 1 -q res 1 -t res 1 - -_x res 1 'write-only -_y res 1 'write-only -_z res 1 'write-only -_buttons res 1 'write-only -_present res 1 'write-only -_dpin res 1 'read-only -_cpin res 1 'read-only \ No newline at end of file diff --git a/source/stracker/bellatrix/stvga.spin b/source/stracker/bellatrix/stvga.spin deleted file mode 100644 index 2a7841d..0000000 --- a/source/stracker/bellatrix/stvga.spin +++ /dev/null @@ -1,543 +0,0 @@ -{{ -┌────────────────────────────────────────┬────────────────┬────────────────────────┬──────────────────┐ -│ VGA 1024x768 Tile Driver v0.9 │ by Chip Gracey │ (C)2006 Parallax, Inc. │ 11 November 2006 │ -├────────────────────────────────────────┴────────────────┴────────────────────────┴──────────────────┤ -│ │ -│ This object generates a 1024x768 VGA display from a 64x48 array of 16x16-pixel 4-color tiles. │ -│ It requires two cogs (or three with optional cursor enabled) and at least 80 MHz. │ -│ │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────┘ - -}} -CON - -' 1024 x 768 @ 60Hz settings - - hp = 1024 'horizontal pixels - vp = 768 'vertical pixels - hf = 24 'horizontal front porch pixels - hs = 136 'horizontal sync pixels - hb = 160 'horizontal back porch pixels - vf = 3 'vertical front porch lines - vs = 6 'vertical sync lines - vb = 29 'vertical back porch lines - pr = 65 'pixel rate in MHz at 80MHz system clock (5MHz granularity) - - ht = hp + hf + hs + hb 'total scan line pixels - -' Tile array - - xtiles = hp / 16 - ytiles = vp / 16 - - -VAR - - long cog[3] - - long dira_ '9 contiguous longs - long dirb_ - long vcfg_ - long cnt_ - long array_ptr_ - long color_ptr_ - long cursor_ptr_ - long sync_ptr_ - long mode_ - - -PUB start(base_pin, array_ptr, color_ptr, cursor_ptr, sync_ptr, mode) : okay | i, j - -'' Start driver - starts two or three cogs -'' returns false if cogs not available -'' -'' base_pin = First of eight VGA pins, must be a multiple of eight (0, 8, 16, 24, etc): -'' -'' 240Ω 240Ω 240Ω 240Ω -'' +7 ───┳─ Red +5 ───┳─ Green +3 ───┳─ Blue +1 ── H -'' 470Ω │ 470Ω │ 470Ω │ 240Ω -'' +6 ───┘ +4 ───┘ +2 ───┘ +0 ── V -'' -'' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down, -'' which will serve as the tile array. Each word specifies a tile bitmap and -'' a color palette for its tile area. The top 10 bits of each word form the -'' base address of a 16-long tile bitmap, while the lower 6 bits select a -'' color palette for the bitmap. For example, $B2E5 would specify the tile -'' bitmap spanning $B2C0..$B2FF and color palette $25. -'' -'' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data -'' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0 -'' providing the color data for pixel values %11..%00, respectively: -'' -'' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold -'' -'' cursor_ptr = Pointer to 4 longs which will control the cursor, or 0 to disable the -'' cursor. If a pointer is given, an extra cog will be started to generate -'' the cursor overlay. Here are the 4 longs that control the cursor: -'' -'' cursor_x - X position of cursor: ..0..1023.. (left to right) -'' cursor_y - Y position of cursor: ..0..767.. (bottom to top) -'' -'' cursor_color - Cursor color to be OR'd to background color as %%RGBx: -'' %%3330=white, %%2220 or %%1110=translucent, %%0000=off -'' -'' cursor_shape - 0 for arrow, 1 for crosshair, or pointer to a cursor -'' definition. A cursor definition consists of 32 longs -'' containing a 32x32 pixel cursor image, followed by two -'' bytes which define the X and Y center-pixel offsets -'' within the image. -'' -'' sync_ptr = Pointer to a long which will be set to -1 after each refresh, or 0 to -'' disable this function. This is useful in advanced applications where -'' awareness of display timing is important. -'' -'' mode = 0 for normal 16x16 pixel tiles or 1 for taller 16x32 pixel tiles. Mode 1 -'' is useful for displaying the internal font while requiring half the array -'' memory; however, the 3-D bevel characters will not be usable because of -'' the larger vertical tile granularity of this mode. - - 'If driver is already running, stop it - stop - - 'Ready i/o settings - i := $FF << (base_pin & %011000) - j := base_pin & %100000 == 0 - dira_ := i & j - dirb_ := i & !j - vcfg_ := $300000FF + (base_pin & %111000) << 6 - - 'Ready cnt value to sync cogs by - cnt_ := cnt + $100000 - - 'Ready pointers and mode - longmove(@array_ptr_, @array_ptr, 5) - - 'Launch cogs, abort if error - repeat i from 0 to 2 - if i == 2 'cursor cog? - ifnot cursor_ptr 'cursor enabled? - quit 'if not, quit loop - waitcnt($2000 + cnt) 'cursor cog, allow prior cog to launch - vcfg_ ^= $10000000 'set two-color mode - array_ptr_~ 'flag cursor function - ifnot cog[i] := cognew(@entry, @dira_ + i << 15) + 1 - stop - return {false} - - 'Successful - return true - - -PUB stop | i - -'' Stop driver - frees cogs - - 'If already running, stop any VGA cogs - repeat i from 0 to 2 - if cog[i] - cogstop(cog[i]~ - 1) - - -DAT - -' ┌─────────────────────────────┐ -' │ Initialization - all cogs │ -' └─────────────────────────────┘ - - org - -' Move field loop into position - -entry mov field,field_code - add entry,d0s0_ - djnz regs,#entry - -' Acquire settings - - mov regs,par 'dira_ ─ dira - cmpsub regs,bit15 wc 'dirb_ ─ dirb -:next movd :read,sprs 'vcfg_ ─ vcfg - or :read,d8_d4 'cnt_ ─ cnt - shr sprs,#4 'array_ptr_ ─ ctrb -:read rdlong dira,regs 'color_ptr_ ─ frqb - add regs,#4 'cursor_ptr_ ─ vscl - tjnz sprs,#:next 'sync_ptr_ ─ phsb - - sumc vf_lines,#2 'alter scan line settings by cog - sumnc vb_lines,#2 - sumnc tile_line,#2 * 4 - - rdlong regs,regs wz 'if mode not 0, set tile size to 16 x 32 pixels - if_nz movs tile_bytes,#32 * 4 - if_nz shr array_bytes,#1 - - mov regs,vscl 'save cursor pointer - -' Synchronize all cogs' video circuits so that waitvid's will be pixel-locked - - movi frqa,#(pr / 5) << 2 'set pixel rate (VCO runs at 2x) - mov vscl,#1 'set video shifter to reload on every pixel - waitcnt cnt,d8_d4 'wait for sync count, add ~3ms - cogs locked! - movi ctra,#%00001_110 'enable PLLs now - NCOs locked! - waitcnt cnt,#0 'wait ~3ms for PLLs to stabilize - PLLs locked! - mov vscl,#100 'subsequent WAITVIDs will now be pixel-locked! - -' Determine if this cog is to perform one of two field functions or the cursor function - - tjnz ctrb,#vsync 'if array ptr, jump to field function - 'else, cursor function follows - -' ┌─────────────────────────┐ -' │ Cursor Loop - one cog │ -' └─────────────────────────┘ - -' Do vertical sync lines minus three - -cursor mov par,#vf + vs + vb - 6 - -:loop mov vscl,vscl_line -:vsync waitvid ccolor,#0 - djnz par,#:vsync - -' Do three lines minus horizontal back porch pixels to buy a big block of time - - mov vscl,vscl_three_lines_mhb - waitvid ccolor,#0 - -' Get cursor data - - rdlong cx,regs 'get cursor x - add regs,#4 - rdlong cy,regs 'get cursor y - add regs,#4 - rdlong ccolor,regs 'get cursor color - add regs,#4 - rdlong cshape,regs 'get cursor shape - sub regs,#3 * 4 - - and ccolor,#$FC 'trim and justify cursor color - shl ccolor,#8 - -' Build cursor pixels - - mov par,#32 'ready for 32 cursor segments - movd :pix,#cpix - mov cnt,cshape - -:pixloop cmp cnt,#1 wc, wz 'arrow, crosshair, or custom cursor? - if_a jmp #:custom - if_e jmp #:crosshair - - cmp par,#32 wz 'arrow - cmp par,#32-21 wc - if_z mov cseg,h80000000 - if_nz_and_nc sar cseg,#1 - if_nz_and_c shl cseg,#2 - mov coff,#0 - jmp #:pix - -:crosshair cmp par,#32-15 wz 'crosshair - if_ne mov cseg,h00010000 - if_e neg cseg,#2 - cmp par,#1 wz - if_e mov cseg,#0 - mov coff,h00000F0F - jmp #:pix - -:custom rdlong cseg,cshape 'custom - add cshape,#4 - rdlong coff,cshape - -:pix mov cpix,cseg 'save segment into pixels - add :pix,d0 - - djnz par,#:pixloop 'another segment? - -' Compute cursor position - - mov cseg,coff 'apply cursor center-pixel offsets - and cseg,#$FF - sub cx,cseg - shr coff,#8 - and coff,#$FF - add cy,coff - - cmps cx,neg31 wc 'if x out of range, hide cursor via y - if_nc cmps pixels_m1,cx wc - if_c neg cy,#1 - - mov cshr,#0 'adjust for left-edge clipping - cmps cx,#0 wc - if_c neg cshr,cx - if_c mov cx,#0 - - mov cshl,#0 'adjust for right-edge clipping - cmpsub cx,pixels_m32 wc - if_c mov cshl,cx - if_c mov cx,pixels_m32 - - add cx,#hb 'bias x and y for display - sub cy,lines_m1 - -' Do visible lines with cursor - - mov par,lines 'ready for visible scan lines - -:line andn cy,#$1F wz, nr 'check if scan line in cursor range - - if_z movs :seg,cy 'if in range, get cursor pixels - if_z add :seg,#cpix - if_nz mov cseg,#0 'if out of range, use blank pixels -:seg if_z mov cseg,cpix - if_z rev cseg,#0 'reverse pixels so they map sensibly - if_z shr cseg,cshr 'perform any edge clipping on pixels - if_z shl cseg,cshl - - mov vscl,cx 'do left blank pixels (hb+cx) - waitvid ccolor,#0 - - mov vscl,vscl_cursor 'do cursor pixels (32) - waitvid ccolor,cseg - - mov vscl,vscl_line_m32 'do right blank pixels (hp+hf+hs-32-cx) - sub vscl,cx - waitvid ccolor,#0 - - add cy,#1 'another scan line? - djnz par,#:line - -' Do horizontal back porch pixels and loop - - mov vscl,#hb - waitvid ccolor,#0 - - mov par,#vf + vs + vb - 3 'ready to do vertical sync lines - jmp #:loop - -' Cursor data - -vscl_line long ht 'total pixels per scan line -vscl_three_lines_mhb long ht * 3 - hb 'total pixels per three scan lines minus hb -vscl_line_m32 long ht - 32 'total pixels per scan line minus 32 -vscl_cursor long 1 << 12 + 32 '32 pixels per cursor with 1 clock per pixel -lines long vp 'visible scan lines -lines_m1 long vp - 1 'visible scan lines minus 1 -pixels_m1 long hp - 1 'visible pixels minus 1 -pixels_m32 long hp - 32 'visible pixels minus 32 -neg31 long -31 - -h80000000 long $80000000 'arrow/crosshair cursor data -h00010000 long $00010000 -h00000F0F long $00000F0F - -' Initialization data - -d0s0_ long 1 << 9 + 1 'd and s field increments -regs long $1F0 - field 'number of registers in field loop space -sprs long $DFB91E76 'phsb/vscl/frqb/ctrb/cnt/vcfg/dirb/dira nibbles -bit15 long $8000 'bit15 mask used to differentiate cogs in par -d8_d4 long $0003E000 'bit8..bit4 mask for d field - -field_code 'field loop code begins at this offset - -' Undefined cursor data - -cx res 1 -cy res 1 -ccolor res 1 -cshape res 1 -coff res 1 -cseg res 1 -cshr res 1 -cshl res 1 -cpix res 32 - - -' ┌─────────────────────────┐ -' │ Field Loop - two cogs │ -' └─────────────────────────┘ - - org - -' Allocate buffers - -palettes res 64 'palettes of colors -colors res xtiles 'colors for tile row -pixels0 res xtiles 'pixels for tile row line +0 -pixels1 res xtiles 'pixels for tile row line +1 -pixels2 res xtiles 'pixels for tile row line +2 -pixels3 res xtiles 'pixels for tile row line +3 - -' Each cog alternately builds and displays four scan lines - -field mov cnt,#ytiles * 4 / 2 'ready number of four-scan-line builds/displays - -' Build four scan lines - -build_4y movd col0,#colors+0 'reset pointers for scan line buffers - movd col1,#colors+1 - movd pix0,#pixels0+0 - movd pix1,#pixels1+0 - movd pix2,#pixels2+0 - movd pix3,#pixels3+0 - movd pix4,#pixels0+1 - movd pix5,#pixels1+1 - movd pix6,#pixels2+1 - movd pix7,#pixels3+1 - - mov ina,#2 'four scan lines require two waitvid's - -build_32x mov vscl,vscl_two_lines 'output lows for two scan lines so other cog -:zero waitvid :zero,#0 '..can display while this cog builds (twice) - - mov inb,#xtiles / 2 / 2 'build four scan lines for half a row - -build_2x rdlong vscl,ctrb 'get pair of words from the tile array - - movs col0,vscl 'get color bits from even tile - andn col0,#$1C0 - - andn vscl,#$3F 'strip color bits and add tile line offset - add vscl,tile_line - -col0 mov colors+0,palettes 'get even tile color - add col0,d1 - -pix0 rdlong pixels0+0,vscl 'get line +0 even tile pixels - add pix0,d1 - add vscl,#4 - -pix1 rdlong pixels1+0,vscl 'get line +1 even tile pixels - add pix1,d1 - add vscl,#4 - -pix2 rdlong pixels2+0,vscl 'get line +2 even tile pixels - add pix2,d1 - add vscl,#4 - -pix3 rdlong pixels3+0,vscl 'get line +3 even tile pixels - add pix3,d1 - - add ctrb,#2 * 2 'point to next pair of tile words - shr vscl,#16 'shift odd tile word into position - - movs col1,vscl 'get color bits from odd tile - andn col1,#$1C0 - - andn vscl,#$3F 'strip color bits and add tile line offset - add vscl,tile_line - -col1 mov colors+1,palettes 'get odd tile color - add col1,d1 - -pix4 rdlong pixels0+1,vscl 'get line +0 odd tile pixels - add pix4,d1 - add vscl,#4 - -pix5 rdlong pixels1+1,vscl 'get line +1 odd tile pixels - add pix5,d1 - add vscl,#4 - -pix6 rdlong pixels2+1,vscl 'get line +2 odd tile pixels - add pix6,d1 - add vscl,#4 - -pix7 rdlong pixels3+1,vscl 'get line +3 odd tile pixels - add pix7,d1 - djnz inb,#build_2x 'loop for next tile pair (48 inst/loop) - - djnz ina,#build_32x 'if first half done, loop for 2nd waitvid - - sub ctrb,#xtiles * 2 'back up to start of same row - -' Display four scan lines - - mov inb,#4 'ready for four scan lines - movs :waitvid,#pixels0 'reset waitvid pixel pointer - -:line mov ina,#xtiles 'ready for tiles - movd :waitvid,#colors 'reset waitvid color pointer - mov vscl,vscl_tile 'set pixel rate for tiles - -:tile cmp ina,#1 wz 'check if last tile - add :waitvid,d0s0 'advance pointers (waitvid already read) -:waitvid waitvid colors,pixels0 'do tile slice - if_nz djnz ina,#:tile 'strange loop allows hsync timing and ina=1 - - call #hsync 'do horizontal sync (ina=1) - - djnz inb,#:line 'another scan line? - -' Another four scan lines? - - add tile_line,#8 * 4 'advance eight scan lines within tile row -tile_bytes cmpsub tile_line,#16 * 4 wc 'tile row done? (# doubled for mode 1) - if_c add ctrb,#xtiles * 2 'if done, advance array pointer to next row - - djnz cnt,#build_4y 'another four scan lines? - - sub ctrb,array_bytes 'display done, reset array pointer to top row - -' Visible section done, handle sync indicator - - cmp cnt,phsb wz 'sync enabled? (cnt=0) - if_nz wrlong neg1,phsb 'if so, write -1 to sync indicator - -' Do vertical sync lines and loop - -vf_lines mov ina,#vf + 2 'do vertical front porch lines (adjusted ±2) - call #blank - -vsync mov ina,#vs 'do vertical sync lines - call #blank_vsync - -vb_lines mov ina,#vb - 2 'do vertical back porch lines (adjusted ±2) - movs blank_vsync_ret,#field '(loop to field, blank_vsync follows) - -' Subroutine - do blank lines - -blank_vsync xor hv_sync,#$0101 'flip vertical sync bits - -blank mov vscl,vscl_blank 'do horizontal blank pixels - waitvid hv_sync,#0 - -hsync mov vscl,#hf 'do horizontal front porch pixels - waitvid hv_sync,#0 - - mov vscl,#hs 'do horizontal sync pixels - waitvid hv_sync,#1 - - rdlong vscl,frqb 'update another palette - and vscl,color_mask -:palette mov palettes,vscl - add :palette,d0 - add frqb,#4 - add par,count_64 wc - if_c movd :palette,#palettes - if_c sub frqb,#64 * 4 - - mov vscl,#hb 'do horizontal back porch pixels - waitvid hv_sync,#0 - - djnz ina,#blank 'another blank line? -hsync_ret -blank_ret -blank_vsync_ret ret - -' Data - -d0s0 long 1 << 9 + 1 'd and s field increments -d0 long 1 << 9 'd field increment -d1 long 2 << 9 'd field double increment - -tile_line long 2 * 4 'tile line offset (adjusted ±2 * 4) -array_bytes long xtiles * ytiles * 2 'number of bytes in tile array - -vscl_two_lines long ht * 2 'total pixels per two scan lines -vscl_tile long 1 << 12 + 16 '16 pixels per tile with 1 clock per pixel -vscl_blank long hp 'visible pixels per scan line - -hv_sync long $0200 '+/-H,-V states -count_64 long $04000000 'addend that sets carry every 64th addition -color_mask long $FCFCFCFC 'mask to isolate R,G,B bits from H,V -neg1 long $FFFFFFFF 'negative 1 to be written to sync indicator \ No newline at end of file