From 091d171f02f034c4c4af3e95ada5e6d1083c2d7e Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Sun, 11 Mar 2018 17:35:04 -0700 Subject: [PATCH] Finalize v2.9.1 Prerelease 0 Added character attributes on propeller-based consoles. --- Doc/ChangeLog.txt | 1 + ReadMe.txt | 2 +- Source/CBIOS/ver.inc | 2 +- Source/HBIOS/ver.inc | 2 +- .../Experimental/PropIO2_test/PropIO2.eeprom | Bin 32768 -> 0 bytes .../Experimental/PropIO2_test/Spin/Build.cmd | 2 - .../PropIO2_test/Spin/E555_SPKEngine.spin | 1 - .../PropIO2_test/Spin/Keyboard.spin | Bin 60850 -> 0 bytes .../Spin/Parallax Serial Terminal.spin | Bin 39560 -> 0 bytes .../PropIO2_test/Spin/PropIO2.list | 6939 ----------------- .../PropIO2_test/Spin/PropIO2.spin | Bin 34026 -> 0 bytes .../PropIO2_test/Spin/safe_spi.spin | 920 --- .../Experimental/PropIO2_test/Spin/vt100.spin | 1198 --- Source/Hardware/Experimental/vga2/Build.cmd | 1 - Source/Hardware/Experimental/vga2/Makefile | 17 - Source/Hardware/Experimental/vga2/bstc.exe | Bin 120320 -> 0 bytes .../Hardware/Experimental/vga2/vga8x8d.spin | 619 -- .../Hardware/Experimental/vga2/vgacolour.spin | 602 -- .../Hardware/Experimental/vga2/vgademo.eeprom | Bin 32768 -> 0 bytes .../Hardware/Experimental/vga2/vgademo.list | 3019 ------- .../Hardware/Experimental/vga2/vgademo.spin | 102 - Source/Hardware/Experimental/vga2/vt100.spin | 1198 --- Source/Hardware/Prop/Spin/AnsiTerm.spin | 535 ++ Source/Hardware/Prop/Spin/E555_SPKEngine.spin | 101 +- .../Hardware/Prop/Spin/FullDuplexSerial.spin | Bin 24008 -> 12819 bytes .../Prop/Spin/FullDuplexSerialNull.spin | Bin 574 -> 286 bytes Source/Hardware/Prop/Spin/Keyboard.spin | Bin 60850 -> 31240 bytes Source/Hardware/Prop/Spin/ParPortProp.spin | Bin 49604 -> 25179 bytes .../Spin/Parallax Serial Terminal Null.spin | Bin 1214 -> 606 bytes .../Prop/Spin/Parallax Serial Terminal.spin | Bin 39544 -> 20650 bytes Source/Hardware/Prop/Spin/PropIO.spin | Bin 32980 -> 16842 bytes Source/Hardware/Prop/Spin/PropIO2.spin | Bin 32154 -> 16423 bytes Source/Hardware/Prop/Spin/VGA_1024.spin | 2 +- Source/Hardware/Prop/Spin/VGA_HiRes_Text.spin | Bin 54408 -> 28019 bytes .../PropIO2_test => Prop}/Spin/vga8x8d.spin | 1238 +-- .../PropIO2_test => Prop}/Spin/vgacolour.spin | 1206 +-- 36 files changed, 1862 insertions(+), 15845 deletions(-) delete mode 100644 Source/Hardware/Experimental/PropIO2_test/PropIO2.eeprom delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/Build.cmd delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/E555_SPKEngine.spin delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/Keyboard.spin delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/Parallax Serial Terminal.spin delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/PropIO2.list delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/PropIO2.spin delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/safe_spi.spin delete mode 100644 Source/Hardware/Experimental/PropIO2_test/Spin/vt100.spin delete mode 100644 Source/Hardware/Experimental/vga2/Build.cmd delete mode 100644 Source/Hardware/Experimental/vga2/Makefile delete mode 100644 Source/Hardware/Experimental/vga2/bstc.exe delete mode 100644 Source/Hardware/Experimental/vga2/vga8x8d.spin delete mode 100644 Source/Hardware/Experimental/vga2/vgacolour.spin delete mode 100644 Source/Hardware/Experimental/vga2/vgademo.eeprom delete mode 100644 Source/Hardware/Experimental/vga2/vgademo.list delete mode 100644 Source/Hardware/Experimental/vga2/vgademo.spin delete mode 100644 Source/Hardware/Experimental/vga2/vt100.spin create mode 100644 Source/Hardware/Prop/Spin/AnsiTerm.spin rename Source/Hardware/{Experimental/PropIO2_test => Prop}/Spin/vga8x8d.spin (97%) rename Source/Hardware/{Experimental/PropIO2_test => Prop}/Spin/vgacolour.spin (97%) diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index aaa73fe0..6ae0fa14 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -3,6 +3,7 @@ Version 2.9.1 - E?B: Added support for RC2014 RTC - WBW: Converted PTXPLAY to TUNE (now plays PT2/PT3/MYM sounds files) - WBW: Updated Win32DiskImager to v1.0 +- WBW: Implemented character attributes on Propeller based consoles Version 2.9.0 ------------- diff --git a/ReadMe.txt b/ReadMe.txt index ab5a7edf..865b29d5 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -7,7 +7,7 @@ *********************************************************************** Wayne Warthen (wwarthen@gmail.com) -Version 2.9.1 (developmental), 2018-01-26 +Version 2.9.1-pre.0, 2018-03-11 https://www.retrobrewcomputers.org/ RomWBW is a ROM-based implementation of CP/M-80 2.2 and Z-System for diff --git a/Source/CBIOS/ver.inc b/Source/CBIOS/ver.inc index 15d6e568..f0a6efbd 100644 --- a/Source/CBIOS/ver.inc +++ b/Source/CBIOS/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 9 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "2.9.1-dev.0" +#DEFINE BIOSVER "2.9.1-pre.0" diff --git a/Source/HBIOS/ver.inc b/Source/HBIOS/ver.inc index 15d6e568..f0a6efbd 100644 --- a/Source/HBIOS/ver.inc +++ b/Source/HBIOS/ver.inc @@ -2,4 +2,4 @@ #DEFINE RMN 9 #DEFINE RUP 1 #DEFINE RTP 0 -#DEFINE BIOSVER "2.9.1-dev.0" +#DEFINE BIOSVER "2.9.1-pre.0" diff --git a/Source/Hardware/Experimental/PropIO2_test/PropIO2.eeprom b/Source/Hardware/Experimental/PropIO2_test/PropIO2.eeprom deleted file mode 100644 index 31d6879ef3f13c906378c9cecb1088cbf25771b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 diff --git a/Source/Hardware/Experimental/PropIO2_test/Spin/Build.cmd b/Source/Hardware/Experimental/PropIO2_test/Spin/Build.cmd deleted file mode 100644 index 1e147539..00000000 --- a/Source/Hardware/Experimental/PropIO2_test/Spin/Build.cmd +++ /dev/null @@ -1,2 +0,0 @@ -rem ..\..\..\Tools\bst\bstc -Ox -ls -e -p0 -dCOM5: PropIO2.spin -..\..\..\Tools\bst\bstc -Ox -ls -e PropIO2.spin diff --git a/Source/Hardware/Experimental/PropIO2_test/Spin/E555_SPKEngine.spin b/Source/Hardware/Experimental/PropIO2_test/Spin/E555_SPKEngine.spin deleted file mode 100644 index 02e55e87..00000000 --- a/Source/Hardware/Experimental/PropIO2_test/Spin/E555_SPKEngine.spin +++ /dev/null @@ -1 +0,0 @@ -{{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // E555 Speaker Engine // // Author: Kwabena W. Agyeman // Updated: 7/27/2010 // Designed For: P8X32A // Version: 1.1 // // Copyright (c) 2010 Kwabena W. Agyeman // See end of file for terms of use. // // Update History: // // v1.0 - Original release - 8/26/2009. // v1.1 - Added support for variable pin assignments - 7/27/2010. // // For each included copy of this object only one spin interpreter should access it at a time. // // Nyamekye, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Speaker Circuit: // // SpeakerPinNumber --- Speaker Driver (Active High). // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }} PUB speakerFrequency(newFrequency, speakerPinNumber) '' 10 Stack Longs '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// '' // Changes the speaker frequency using the SPIN interpreter's counter modules. '' // '' // NewFrequency - The new frequency. Between 0 Hz and 80MHz @ 80MHz. -1 to reset the pin and counter modules. '' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// speakerSetup((newFrequency <> -1), speakerPinNumber) newFrequency := ((newFrequency <# clkfreq) #> 0) result := 1 repeat 32 newFrequency <<= 1 result <-= 1 if(newFrequency => clkfreq) newFrequency -= clkfreq result += 1 frqa := result~ phsb := 0 PUB speakerVolume(newVolume, speakerPinNumber) '' 10 Stack Longs '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// '' // Changes the speaker volume using the SPIN interpreter's counter modules. '' // '' // NewVolume - The new volume. Between 0% and 100%. -1 to reset the pin and counter modules. '' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// speakerSetup((newVolume <> -1), speakerPinNumber) frqb := (((100 - ((newVolume <# 100) #> 0)) * constant(posx / 50)) | $7) PRI speakerSetup(activeOrInactive, speakerPinNumber) ' 5 Stack Longs speakerPinNumber := ((speakerPinNumber <# 31) #> 0) dira[speakerPinNumber] := activeOrInactive outa[speakerPinNumber] := false ctra := ((constant(%0_0100 << 26) + speakerPinNumber) & activeOrInactive) ctrb := ((constant(%0_0110 << 26) + speakerPinNumber) & activeOrInactive) {{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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/Hardware/Experimental/PropIO2_test/Spin/Keyboard.spin b/Source/Hardware/Experimental/PropIO2_test/Spin/Keyboard.spin deleted file mode 100644 index 29025a99689e5fc04d794a2e281e42ace8c1d4b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60850 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 bits 2,1,0 -1354(0007) 07 A6 FC 60 | and TempAdr, #$07 ' isolate the 3 bits -1358(0008) 0C A6 FC 80 | add TempAdr,#JmpTable -135C(0009) 53 16 BC 50 | movs JmpCmd,TempAdr -1360(000A) 00 00 00 00 | nop -1364(000B) 00 00 7C 5C | JmpCmd jmp #0-0 -1368(000C) 15 00 7C 5C | JmpTable jmp #TermStatus -136C(000D) 1D 00 7C 5C | jmp #TermRead -1370(000E) 31 00 7C 5C | jmp #DiskStatus -1374(000F) 35 00 7C 5C | jmp #DiskRead -1378(0010) 14 00 7C 5C | jmp #TermCommand -137C(0011) 24 00 7C 5C | jmp #TermWrite -1380(0012) 2A 00 7C 5C | jmp #DiskCommand -1384(0013) 3C 00 7C 5C | jmp #DiskWrite -1388(0014) | TermCommand ' receive terminal command byte from host -1388(0014) 4A 00 3C 5C | jmp LoopRet -138C(0015) | TermStatus ' send terminal status byte to host -138C(0015) 42 A4 BC 00 | rdbyte TempVal, TermStatKbdAdr ' get kbd status -1390(0016) 00 E8 FF A0 | mov outa, #0 -1394(0017) 52 E8 BF 68 | or outa, TempVal ' combine it -1398(0018) 43 A4 BC 00 | rdbyte TempVal, TermStatDspAdr ' get display status -139C(0019) 52 E8 BF 68 | or outa, TempVal ' combine it -13A0(001A) 30 E8 FF 6C | xor outa, #TRMST_ACTMASK ' convert 'active' bits to 'ready' bits for host -13A4(001B) 4B EC BF 68 | or dira, BitsData ' set D0-D7 to output -13A8(001C) 4A 00 3C 5C | jmp LoopRet -13AC(001D) | TermRead ' return byte in key buf to host -13AC(001D) 44 A4 BC 00 | rdbyte TempVal,TermKbdBufAdr ' get the byte from the buffer -13B0(001E) 52 E8 BF A0 | mov outa,TempVal ' output byte to port -13B4(001F) 42 A4 BC 00 | rdbyte TempVal, TermStatKbdAdr -13B8(0020) 20 A4 FC 68 | or TempVal, #TRMST_KBDACT -13BC(0021) 42 A4 3C 00 | wrbyte TempVal, TermStatKbdAdr -13C0(0022) 4B EC BF 68 | or dira, BitsData ' set D0-D7 to output -13C4(0023) 4A 00 3C 5C | jmp LoopRet -13C8(0024) | TermWrite ' accept byte from host into screen buf -13C8(0024) F2 A5 BC A0 | mov TempVal, ina ' input byte from port -13CC(0025) 45 A4 3C 00 | wrbyte TempVal,TermDspBufAdr ' put the byte into the buffer -13D0(0026) 43 A4 BC 00 | rdbyte TempVal, TermStatDspAdr ' get current display status -13D4(0027) 10 A4 FC 68 | or TempVal, #TRMST_DSPACT ' set the active bit -13D8(0028) 43 A4 3C 00 | wrbyte TempVal, TermStatDspAdr ' store the updated status -13DC(0029) 4A 00 3C 5C | jmp LoopRet -13E0(002A) | DiskCommand ' receive disk command byte from host -13E0(002A) F2 A5 BC A0 | mov TempVal, ina ' input command byte from port -13E4(002B) 47 A4 3C 00 | wrbyte TempVal, DiskCmdAdr ' store command byte to global memory -13E8(002C) 46 A4 BC 00 | rdbyte TempVal, DiskStatAdr ' get current disk status -13EC(002D) 80 A4 FC 68 | or TempVal, #DSKST_ACT ' set the active bit -13F0(002E) 46 A4 3C 00 | wrbyte TempVal, DiskStatAdr ' store updated disk status -13F4(002F) 00 92 FC A0 | mov DiskBufIdx, #0 ' reset buf index on any incoming command -13F8(0030) 4A 00 3C 5C | jmp LoopRet -13FC(0031) | DiskStatus ' send disk status byte to host -13FC(0031) 46 A4 BC 00 | rdbyte TempVal, DiskStatAdr ' get status byte from global memory -1400(0032) 52 E8 BF A0 | mov outa, TempVal ' output byte to port -1404(0033) 4B EC BF 68 | or dira, BitsData ' set D0-D7 to output -1408(0034) 4A 00 3C 5C | jmp LoopRet -140C(0035) | DiskRead ' send bytes from sector buffer to host -140C(0035) 48 A6 BC A0 | mov TempAdr,DiskBufAdr ' get pointer to sector buffer -1410(0036) 49 A6 BC 80 | add TempAdr,DiskBufIdx ' increment pointer by current index value -1414(0037) 53 A4 BC 00 | rdbyte TempVal,TempAdr ' get the byte from the buffer -1418(0038) 52 E8 BF A0 | mov outa,TempVal ' output byte to port -141C(0039) 01 92 FC 80 | add DiskBufIdx,#1 ' increment index for the next read -1420(003A) 4B EC BF 68 | or dira, BitsData ' set D0-D7 to output -1424(003B) 4A 00 3C 5C | jmp LoopRet -1428(003C) | DiskWrite ' fill bytes of sector buffer from host -1428(003C) 48 A6 BC A0 | mov TempAdr,DiskBufAdr ' get pointer to sector buffer -142C(003D) 49 A6 BC 80 | add TempAdr,DiskBufIdx ' increment pointer by current index value -1430(003E) F2 A5 BC A0 | mov TempVal, ina ' input byte from port -1434(003F) 53 A4 3C 00 | wrbyte TempVal,TempAdr ' put the byte into the buffer -1438(0040) 01 92 FC 80 | add DiskBufIdx,#1 ' increment the index for the next write -143C(0041) 4A 00 3C 5C | jmp LoopRet -1440(0042) 00 00 00 00 | TermStatKbdAdr long 0 -1444(0043) 00 00 00 00 | TermStatDspAdr long 0 -1448(0044) 00 00 00 00 | TermKbdBufAdr long 0 -144C(0045) 00 00 00 00 | TermDspBufAdr long 0 -1450(0046) 00 00 00 00 | DiskStatAdr long 0 -1454(0047) 00 00 00 00 | DiskCmdAdr long 0 -1458(0048) 00 00 00 00 | DiskBufAdr long 0 -145C(0049) 00 00 00 00 | DiskBufIdx long 0 -1460(004A) 00 00 00 00 | LoopRet long PortIO -1464(004B) FF 00 00 00 | BitsData long $00FF -1468(004C) 00 00 00 00 | Zero long $0000 -146C(004D) 00 01 00 00 | MaskCS long $0100 -1470(004E) 00 01 00 00 | BitCS long $0100 -1474(004F) 00 10 00 00 | BitCLR long $1000 -1478(0050) 00 10 00 00 | DirMask long $1000 -147C(0051) 00 11 00 00 | WaitMask long $1100 -1480(0052) | TempVal res 1 -1480(0053) | TempAdr res 1 -1480(0054) | fit -1480(0054) | There are 412 ($19C) Longs left in the cog -|===========================================================================| -|===========================================================================| -Spin Block main with 0 Parameters and 0 Extra Stack Longs. Method 1 -PUB main - -Local Parameter DBASE:0000 - Result -|===========================================================================| -113 VidRdy := false -Addr : 1480: 35 : Constant 1 $00000000 -Addr : 1481: 89 82 66 : Memory Op Byte VBASE + WRITE Address = 0266 -114 dbg.Start(115200) -Addr : 1484: 01 : Drop Anchor -Addr : 1485: 3A 01 C2 00 : Constant 3 Bytes - 01 C2 00 -Addr : 1489: 06 15 01 : Call Obj.Sub 21 1 -116 MsgStr(string("Starting PropIO...")) -Addr : 148C: 01 : Drop Anchor -Addr : 148D: PBASE Constant Address of Label0002 -Addr : 148D: 87 96 34 : Memory Op Byte PBASE + ADDRESS Address = 1634 -Addr : 1490: 05 08 : Call Sub 8 -117 MsgNewLine -Addr : 1492: 01 : Drop Anchor -Addr : 1493: 05 07 : Call Sub 7 -132 MsgStr(string("Initializing Video...")) -Addr : 1495: 01 : Drop Anchor -Addr : 1496: PBASE Constant Address of Label0003 -Addr : 1496: 87 96 47 : Memory Op Byte PBASE + ADDRESS Address = 1647 -Addr : 1499: 05 08 : Call Sub 8 -133 Result := vga.start(16, @screen, @cursor, @sync) -Addr : 149B: 00 : Drop Anchor Push -Addr : 149C: 37 03 : Constant Mask Y=3 00000010 -Addr : 149E: A7 5C : Memory Op Word PBASE + ADDRESS Address = 005C -Addr : 14A0: 87 93 1C : Memory Op Byte PBASE + ADDRESS Address = 131C -Addr : 14A3: C7 93 24 : Memory Op Long PBASE + ADDRESS Address = 1324 -Addr : 14A6: 06 10 01 : Call Obj.Sub 16 1 -Addr : 14A9: 61 : Variable Operation Local Offset - 0 Write -134 if (Result < 0) -Addr : 14AA: 60 : Variable Operation Local Offset - 0 Read -Addr : 14AB: 35 : Constant 1 $00000000 -Addr : 14AC: F9 : Math Op < -Addr : 14AD: JZ Label0004 -Addr : 14AD: 0A 10 : jz Address = 14BF 16 -135 MsgStr(string(" Failed! Error: ")) -Addr : 14AF: 01 : Drop Anchor -Addr : 14B0: PBASE Constant Address of Label0006 -Addr : 14B0: 87 96 5D : Memory Op Byte PBASE + ADDRESS Address = 165D -Addr : 14B3: 05 08 : Call Sub 8 -136 MsgDec(Result) -Addr : 14B5: 01 : Drop Anchor -Addr : 14B6: 60 : Variable Operation Local Offset - 0 Read -Addr : 14B7: 05 09 : Call Sub 9 -137 MsgNewLine -Addr : 14B9: 01 : Drop Anchor -Addr : 14BA: 05 07 : Call Sub 7 -Addr : 14BC: JMP Label0005 -Addr : 14BC: 04 80 5F : Jmp 151E 95 -Addr : 14BF: Label0004 -139 MsgStr(string(" OK")) -Addr : 14BF: 01 : Drop Anchor -Addr : 14C0: PBASE Constant Address of Label0008 -Addr : 14C0: 87 96 70 : Memory Op Byte PBASE + ADDRESS Address = 1670 -Addr : 14C3: 05 08 : Call Sub 8 -140 MsgNewLine -Addr : 14C5: 01 : Drop Anchor -Addr : 14C6: 05 07 : Call Sub 7 -141 params[0] := @command -Addr : 14C8: C7 58 : Memory Op Long PBASE + ADDRESS Address = 0058 -Addr : 14CA: 35 : Constant 1 $00000000 -Addr : 14CB: D9 82 48 : Memory Op Long VBASE + POP Index WRITE Address = 0248 -142 params[1] := @screen -Addr : 14CE: A7 5C : Memory Op Word PBASE + ADDRESS Address = 005C -Addr : 14D0: 36 : Constant 2 $00000001 -Addr : 14D1: D9 82 48 : Memory Op Long VBASE + POP Index WRITE Address = 0248 -143 params[2] := @cursor -Addr : 14D4: 87 93 1C : Memory Op Byte PBASE + ADDRESS Address = 131C -Addr : 14D7: 37 00 : Constant Mask Y=0 00000002 -Addr : 14D9: D9 82 48 : Memory Op Long VBASE + POP Index WRITE Address = 0248 -144 params[3] := @sync -Addr : 14DC: C7 93 24 : Memory Op Long PBASE + ADDRESS Address = 1324 -Addr : 14DF: 37 21 : Constant Mask Y=33 Decrement 00000003 -Addr : 14E1: D9 82 48 : Memory Op Long VBASE + POP Index WRITE Address = 0248 -145 params[4] := CHAR_W -Addr : 14E4: 38 50 : Constant 1 Bytes - 50 -Addr : 14E6: 37 01 : Constant Mask Y=1 00000004 -Addr : 14E8: D9 82 48 : Memory Op Long VBASE + POP Index WRITE Address = 0248 -146 params[5] := CHAR_H -Addr : 14EB: 38 1E : Constant 1 Bytes - 1E -Addr : 14ED: 38 05 : Constant 1 Bytes - 05 -Addr : 14EF: D9 82 48 : Memory Op Long VBASE + POP Index WRITE Address = 0248 -148 MsgStr(string("Initializing Emulation...")) -Addr : 14F2: 01 : Drop Anchor -Addr : 14F3: PBASE Constant Address of Label0009 -Addr : 14F3: 87 96 74 : Memory Op Byte PBASE + ADDRESS Address = 1674 -Addr : 14F6: 05 08 : Call Sub 8 -149 Result := vt100.start(@params) -Addr : 14F8: 00 : Drop Anchor Push -Addr : 14F9: CB 82 48 : Memory Op Long VBASE + ADDRESS Address = 0248 -Addr : 14FC: 06 11 01 : Call Obj.Sub 17 1 -Addr : 14FF: 61 : Variable Operation Local Offset - 0 Write -150 if (Result < 0) -Addr : 1500: 60 : Variable Operation Local Offset - 0 Read -Addr : 1501: 35 : Constant 1 $00000000 -Addr : 1502: F9 : Math Op < -Addr : 1503: JZ Label000A -Addr : 1503: 0A 0C : jz Address = 1511 12 -151 MsgStr(string(" Failed! Error: ")) -Addr : 1505: 01 : Drop Anchor -Addr : 1506: PBASE Constant Address of Label000C -Addr : 1506: 87 96 8E : Memory Op Byte PBASE + ADDRESS Address = 168E -Addr : 1509: 05 08 : Call Sub 8 -152 MsgDec(Result) -Addr : 150B: 01 : Drop Anchor -Addr : 150C: 60 : Variable Operation Local Offset - 0 Read -Addr : 150D: 05 09 : Call Sub 9 -Addr : 150F: JMP Label000B -Addr : 150F: 04 0A : Jmp 151B 10 -Addr : 1511: Label000A -154 MsgStr(string(" OK")) -Addr : 1511: 01 : Drop Anchor -Addr : 1512: PBASE Constant Address of Label000E -Addr : 1512: 87 96 A1 : Memory Op Byte PBASE + ADDRESS Address = 16A1 -Addr : 1515: 05 08 : Call Sub 8 -155 VidRdy := true -Addr : 1517: 34 : Constant 0 $FFFFFFFF -Addr : 1518: 89 82 66 : Memory Op Byte VBASE + WRITE Address = 0266 -Addr : 151B: Label000D -Addr : 151B: Label000B -156 MsgNewLine -Addr : 151B: 01 : Drop Anchor -Addr : 151C: 05 07 : Call Sub 7 -Addr : 151E: Label0007 -Addr : 151E: Label0005 -158 TimerCount := SLEEP -Addr : 151E: 39 01 2C : Constant 2 Bytes - 01 2C -Addr : 1521: C9 82 44 : Memory Op Long VBASE + WRITE Address = 0244 -161 MsgStr(string("Initializing PropIO...")) -Addr : 1524: 01 : Drop Anchor -Addr : 1525: PBASE Constant Address of Label000F -Addr : 1525: 87 96 A5 : Memory Op Byte PBASE + ADDRESS Address = 16A5 -Addr : 1528: 05 08 : Call Sub 8 -163 TermStatKbdAdr := @TermStatKbd -Addr : 152A: 8B 82 60 : Memory Op Byte VBASE + ADDRESS Address = 0260 -Addr : 152D: C5 94 30 : Memory Op Long PBASE + WRITE Address = 1430 -164 TermStatDspAdr := @TermStatDsp -Addr : 1530: 8B 82 61 : Memory Op Byte VBASE + ADDRESS Address = 0261 -Addr : 1533: C5 94 34 : Memory Op Long PBASE + WRITE Address = 1434 -165 TermKbdBufAdr := @TermKbdBuf -Addr : 1536: 8B 82 62 : Memory Op Byte VBASE + ADDRESS Address = 0262 -Addr : 1539: C5 94 38 : Memory Op Long PBASE + WRITE Address = 1438 -166 TermDspBufAdr := @TermScrBuf -Addr : 153C: 8B 82 63 : Memory Op Byte VBASE + ADDRESS Address = 0263 -Addr : 153F: C5 94 3C : Memory Op Long PBASE + WRITE Address = 143C -167 DiskStatAdr := @DiskStat -Addr : 1542: 8B 82 64 : Memory Op Byte VBASE + ADDRESS Address = 0264 -Addr : 1545: C5 94 40 : Memory Op Long PBASE + WRITE Address = 1440 -168 DiskCmdAdr := @DiskCmd -Addr : 1548: 8B 82 65 : Memory Op Byte VBASE + ADDRESS Address = 0265 -Addr : 154B: C5 94 44 : Memory Op Long PBASE + WRITE Address = 1444 -169 DiskBufAdr := @DiskBuf -Addr : 154E: 47 : Variable Operation Global Offset - 1 Address -Addr : 154F: C5 94 48 : Memory Op Long PBASE + WRITE Address = 1448 -171 DiskBufIdx := 0 -Addr : 1552: 35 : Constant 1 $00000000 -Addr : 1553: C5 94 4C : Memory Op Long PBASE + WRITE Address = 144C -172 TermStatKbd := TRMST_KBDACT -Addr : 1556: 37 04 : Constant Mask Y=4 00000020 -Addr : 1558: 89 82 60 : Memory Op Byte VBASE + WRITE Address = 0260 -173 TermStatDsp := 0 -Addr : 155B: 35 : Constant 1 $00000000 -Addr : 155C: 89 82 61 : Memory Op Byte VBASE + WRITE Address = 0261 -174 DiskStat := 0 -Addr : 155F: 35 : Constant 1 $00000000 -Addr : 1560: 89 82 64 : Memory Op Byte VBASE + WRITE Address = 0264 -176 ByteFill(@DiskBuf, $00, 512) -Addr : 1563: 47 : Variable Operation Global Offset - 1 Address -Addr : 1564: 35 : Constant 1 $00000000 -Addr : 1565: 37 08 : Constant Mask Y=8 00000200 -Addr : 1567: 18 : ByteFill(Start, Value, Count) -178 MsgStr(string(" OK")) -Addr : 1568: 01 : Drop Anchor -Addr : 1569: PBASE Constant Address of Label0010 -Addr : 1569: 87 96 BC : Memory Op Byte PBASE + ADDRESS Address = 16BC -Addr : 156C: 05 08 : Call Sub 8 -179 MsgNewLine -Addr : 156E: 01 : Drop Anchor -Addr : 156F: 05 07 : Call Sub 7 -181 MsgStr(string("Initializing Keyboard...")) -Addr : 1571: 01 : Drop Anchor -Addr : 1572: PBASE Constant Address of Label0011 -Addr : 1572: 87 96 C0 : Memory Op Byte PBASE + ADDRESS Address = 16C0 -Addr : 1575: 05 08 : Call Sub 8 -182 Result := kbd.Start(KBD_BASE, KBD_BASE + 1) -Addr : 1577: 00 : Drop Anchor Push -Addr : 1578: 38 0E : Constant 1 Bytes - 0E -Addr : 157A: 38 0E : Constant 1 Bytes - 0E -Addr : 157C: 36 : Constant 2 $00000001 -Addr : 157D: EC : Math Op + -Addr : 157E: 06 12 01 : Call Obj.Sub 18 1 -Addr : 1581: 61 : Variable Operation Local Offset - 0 Write -183 if (Result < 0) -Addr : 1582: 60 : Variable Operation Local Offset - 0 Read -Addr : 1583: 35 : Constant 1 $00000000 -Addr : 1584: F9 : Math Op < -Addr : 1585: JZ Label0012 -Addr : 1585: 0A 0C : jz Address = 1593 12 -184 MsgStr(string(" Failed! Error: ")) -Addr : 1587: 01 : Drop Anchor -Addr : 1588: PBASE Constant Address of Label0014 -Addr : 1588: 87 96 D9 : Memory Op Byte PBASE + ADDRESS Address = 16D9 -Addr : 158B: 05 08 : Call Sub 8 -185 MsgDec(Result) -Addr : 158D: 01 : Drop Anchor -Addr : 158E: 60 : Variable Operation Local Offset - 0 Read -Addr : 158F: 05 09 : Call Sub 9 -Addr : 1591: JMP Label0013 -Addr : 1591: 04 06 : Jmp 1599 6 -Addr : 1593: Label0012 -187 MsgStr(string(" OK")) -Addr : 1593: 01 : Drop Anchor -Addr : 1594: PBASE Constant Address of Label0016 -Addr : 1594: 87 96 EC : Memory Op Byte PBASE + ADDRESS Address = 16EC -Addr : 1597: 05 08 : Call Sub 8 -Addr : 1599: Label0015 -Addr : 1599: Label0013 -188 MsgNewLine -Addr : 1599: 01 : Drop Anchor -Addr : 159A: 05 07 : Call Sub 7 -199 MsgStr(string("Starting PortIO cog...")) -Addr : 159C: 01 : Drop Anchor -Addr : 159D: PBASE Constant Address of Label0017 -Addr : 159D: 87 96 F0 : Memory Op Byte PBASE + ADDRESS Address = 16F0 -Addr : 15A0: 05 08 : Call Sub 8 -200 Result := cognew(@PortIO, 0) + 1 -Addr : 15A2: 34 : Constant 0 $FFFFFFFF -Addr : 15A3: C7 93 28 : Memory Op Long PBASE + ADDRESS Address = 1328 -Addr : 15A6: 35 : Constant 1 $00000000 -Addr : 15A7: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 15A8: 36 : Constant 2 $00000001 -Addr : 15A9: EC : Math Op + -Addr : 15AA: 61 : Variable Operation Local Offset - 0 Write -201 if (Result < 0) -Addr : 15AB: 60 : Variable Operation Local Offset - 0 Read -Addr : 15AC: 35 : Constant 1 $00000000 -Addr : 15AD: F9 : Math Op < -Addr : 15AE: JZ Label0018 -Addr : 15AE: 0A 0C : jz Address = 15BC 12 -202 MsgStr(string(" Failed! Error: ")) -Addr : 15B0: 01 : Drop Anchor -Addr : 15B1: PBASE Constant Address of Label001A -Addr : 15B1: 87 97 07 : Memory Op Byte PBASE + ADDRESS Address = 1707 -Addr : 15B4: 05 08 : Call Sub 8 -203 MsgDec(Result) -Addr : 15B6: 01 : Drop Anchor -Addr : 15B7: 60 : Variable Operation Local Offset - 0 Read -Addr : 15B8: 05 09 : Call Sub 9 -Addr : 15BA: JMP Label0019 -Addr : 15BA: 04 06 : Jmp 15C2 6 -Addr : 15BC: Label0018 -205 MsgStr(string(" OK")) -Addr : 15BC: 01 : Drop Anchor -Addr : 15BD: PBASE Constant Address of Label001C -Addr : 15BD: 87 97 1A : Memory Op Byte PBASE + ADDRESS Address = 171A -Addr : 15C0: 05 08 : Call Sub 8 -Addr : 15C2: Label001B -Addr : 15C2: Label0019 -206 MsgNewLine -Addr : 15C2: 01 : Drop Anchor -Addr : 15C3: 05 07 : Call Sub 7 -208 spk.speakerFrequency(1000, SPK_BASE) -Addr : 15C5: 01 : Drop Anchor -Addr : 15C6: 39 03 E8 : Constant 2 Bytes - 03 E8 -Addr : 15C9: 38 0D : Constant 1 Bytes - 0D -Addr : 15CB: 06 14 01 : Call Obj.Sub 20 1 -209 waitcnt((clkfreq >> 4) + cnt) -Addr : 15CE: 35 : Constant 1 $00000000 -Addr : 15CF: C0 : Memory Op Long POP Address READ -Addr : 15D0: 37 01 : Constant Mask Y=1 00000004 -Addr : 15D2: E2 : Math Op >> -Addr : 15D3: 3F 91 : Register op CNT Read -Addr : 15D5: EC : Math Op + -Addr : 15D6: 23 : WaitCnt(count) -210 spk.speakerFrequency(-1, SPK_BASE) -Addr : 15D7: 01 : Drop Anchor -Addr : 15D8: 34 : Constant 0 $FFFFFFFF -Addr : 15D9: 38 0D : Constant 1 Bytes - 0D -Addr : 15DB: 06 14 01 : Call Obj.Sub 20 1 -212 MsgStr(string("PropIO Ready!")) -Addr : 15DE: 01 : Drop Anchor -Addr : 15DF: PBASE Constant Address of Label001D -Addr : 15DF: 87 97 1E : Memory Op Byte PBASE + ADDRESS Address = 171E -Addr : 15E2: 05 08 : Call Sub 8 -213 MsgNewLine -Addr : 15E4: 01 : Drop Anchor -Addr : 15E5: 05 07 : Call Sub 7 -Addr : 15E7: Label001E -216 if (DiskStat & DSKST_ACT) -Addr : 15E7: 88 82 64 : Memory Op Byte VBASE + READ Address = 0264 -Addr : 15EA: 37 06 : Constant Mask Y=6 00000080 -Addr : 15EC: E8 : Math Op & -Addr : 15ED: JZ Label0021 -Addr : 15ED: 0A 0E : jz Address = 15FD 14 -217 ProcessDiskCmd -Addr : 15EF: 01 : Drop Anchor -Addr : 15F0: 05 03 : Call Sub 3 -218 DiskCmd := 0 -Addr : 15F2: 35 : Constant 1 $00000000 -Addr : 15F3: 89 82 65 : Memory Op Byte VBASE + WRITE Address = 0265 -219 DiskStat &= !DSKST_ACT -Addr : 15F6: 37 06 : Constant Mask Y=6 00000080 -Addr : 15F8: E7 : Math Op ! -Addr : 15F9: 8A 82 64 48 : Memory Op Byte VBASE + ASSIGN Address = 0264 BitMathop & -Addr : 15FD: Label0021 -Addr : 15FD: Label0022 -221 if (TermStatDsp & TRMST_DSPACT) -Addr : 15FD: 88 82 61 : Memory Op Byte VBASE + READ Address = 0261 -Addr : 1600: 37 03 : Constant Mask Y=3 00000010 -Addr : 1602: E8 : Math Op & -Addr : 1603: JZ Label0023 -Addr : 1603: 0A 10 : jz Address = 1615 16 -223 DispChar(TermScrBuf) -Addr : 1605: 01 : Drop Anchor -Addr : 1606: 88 82 63 : Memory Op Byte VBASE + READ Address = 0263 -Addr : 1609: 05 0D : Call Sub 13 -224 Activity -Addr : 160B: 01 : Drop Anchor -Addr : 160C: 05 0C : Call Sub 12 -225 TermStatDsp &= !TRMST_DSPACT -Addr : 160E: 37 03 : Constant Mask Y=3 00000010 -Addr : 1610: E7 : Math Op ! -Addr : 1611: 8A 82 61 48 : Memory Op Byte VBASE + ASSIGN Address = 0261 BitMathop & -Addr : 1615: Label0023 -Addr : 1615: Label0024 -227 if (TermStatKbd & TRMST_KBDACT) -Addr : 1615: 88 82 60 : Memory Op Byte VBASE + READ Address = 0260 -Addr : 1618: 37 04 : Constant Mask Y=4 00000020 -Addr : 161A: E8 : Math Op & -Addr : 161B: JZ Label0025 -Addr : 161B: 0A 17 : jz Address = 1634 23 -228 if (kbd.GotKey) -Addr : 161D: 00 : Drop Anchor Push -Addr : 161E: 06 12 08 : Call Obj.Sub 18 8 -Addr : 1621: JZ Label0027 -Addr : 1621: 0A 11 : jz Address = 1634 17 -229 TermKbdBuf := kbd.GetKey -Addr : 1623: 00 : Drop Anchor Push -Addr : 1624: 06 12 06 : Call Obj.Sub 18 6 -Addr : 1627: 89 82 62 : Memory Op Byte VBASE + WRITE Address = 0262 -230 Activity -Addr : 162A: 01 : Drop Anchor -Addr : 162B: 05 0C : Call Sub 12 -231 TermStatKbd &= !TRMST_KBDACT -Addr : 162D: 37 04 : Constant Mask Y=4 00000020 -Addr : 162F: E7 : Math Op ! -Addr : 1630: 8A 82 60 48 : Memory Op Byte VBASE + ASSIGN Address = 0260 BitMathop & -Addr : 1634: Label0027 -Addr : 1634: Label0028 -Addr : 1634: Label0025 -Addr : 1634: Label0026 -Addr : 1634: Label001F -Addr : 1634: JMP Label001E -Addr : 1634: 04 FF B0 : Jmp 15E7 -80 -Addr : 1637: Label0020 -233 MsgNewLine -Addr : 1637: 01 : Drop Anchor -Addr : 1638: 05 07 : Call Sub 7 -234 MsgStr(string("PropIO Shutdown!")) -Addr : 163A: 01 : Drop Anchor -Addr : 163B: PBASE Constant Address of Label0029 -Addr : 163B: 87 97 2C : Memory Op Byte PBASE + ADDRESS Address = 172C -Addr : 163E: 05 08 : Call Sub 8 -235 MsgNewLine -Addr : 1640: 01 : Drop Anchor -Addr : 1641: 05 07 : Call Sub 7 -Addr : 1643: 32 : Return -Addr : 1644: Label0002 -Addr : 1644: Data : 53 74 61 72 74 69 6E 67 Starting -Addr : 164C: Data : 20 50 72 6F 70 49 4F 2E PropIO. -Addr : 1654: Data : 2E 2E 00 ... -Addr : 1657: Label0003 -Addr : 1657: Data : 49 6E 69 74 69 61 6C 69 Initiali -Addr : 165F: Data : 7A 69 6E 67 20 56 69 64 zing Vid -Addr : 1667: Data : 65 6F 2E 2E 2E 00 eo.... -Addr : 166D: Label0006 -Addr : 166D: Data : 20 46 61 69 6C 65 64 21 Failed! -Addr : 1675: Data : 20 20 20 45 72 72 6F 72 Error -Addr : 167D: Data : 3A 20 00 : . -Addr : 1680: Label0008 -Addr : 1680: Data : 20 4F 4B 00 OK. -Addr : 1684: Label0009 -Addr : 1684: Data : 49 6E 69 74 69 61 6C 69 Initiali -Addr : 168C: Data : 7A 69 6E 67 20 45 6D 75 zing Emu -Addr : 1694: Data : 6C 61 74 69 6F 6E 2E 2E lation.. -Addr : 169C: Data : 2E 00 .. -Addr : 169E: Label000C -Addr : 169E: Data : 20 46 61 69 6C 65 64 21 Failed! -Addr : 16A6: Data : 20 20 20 45 72 72 6F 72 Error -Addr : 16AE: Data : 3A 20 00 : . -Addr : 16B1: Label000E -Addr : 16B1: Data : 20 4F 4B 00 OK. -Addr : 16B5: Label000F -Addr : 16B5: Data : 49 6E 69 74 69 61 6C 69 Initiali -Addr : 16BD: Data : 7A 69 6E 67 20 50 72 6F zing Pro -Addr : 16C5: Data : 70 49 4F 2E 2E 2E 00 pIO.... -Addr : 16CC: Label0010 -Addr : 16CC: Data : 20 4F 4B 00 OK. -Addr : 16D0: Label0011 -Addr : 16D0: Data : 49 6E 69 74 69 61 6C 69 Initiali -Addr : 16D8: Data : 7A 69 6E 67 20 4B 65 79 zing Key -Addr : 16E0: Data : 62 6F 61 72 64 2E 2E 2E board... -Addr : 16E8: Data : 00 . -Addr : 16E9: Label0014 -Addr : 16E9: Data : 20 46 61 69 6C 65 64 21 Failed! -Addr : 16F1: Data : 20 20 20 45 72 72 6F 72 Error -Addr : 16F9: Data : 3A 20 00 : . -Addr : 16FC: Label0016 -Addr : 16FC: Data : 20 4F 4B 00 OK. -Addr : 1700: Label0017 -Addr : 1700: Data : 53 74 61 72 74 69 6E 67 Starting -Addr : 1708: Data : 20 50 6F 72 74 49 4F 20 PortIO -Addr : 1710: Data : 63 6F 67 2E 2E 2E 00 cog.... -Addr : 1717: Label001A -Addr : 1717: Data : 20 46 61 69 6C 65 64 21 Failed! -Addr : 171F: Data : 20 20 20 45 72 72 6F 72 Error -Addr : 1727: Data : 3A 20 00 : . -Addr : 172A: Label001C -Addr : 172A: Data : 20 4F 4B 00 OK. -Addr : 172E: Label001D -Addr : 172E: Data : 50 72 6F 70 49 4F 20 52 PropIO R -Addr : 1736: Data : 65 61 64 79 21 00 eady!. -Addr : 173C: Label0029 -Addr : 173C: Data : 50 72 6F 70 49 4F 20 53 PropIO S -Addr : 1744: Data : 68 75 74 64 6F 77 6E 21 hutdown! -Addr : 174C: Data : 00 . -|===========================================================================| -Spin Block DispHex with 2 Parameters and 0 Extra Stack Longs. Method 2 -PUB DispHex(value, digits) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - value -Local Parameter DBASE:0008 - digits -|===========================================================================| -383 repeat while digits > 8 -Addr : 174D: Label0002 -Addr : 174D: 68 : Variable Operation Local Offset - 2 Read -Addr : 174E: 37 02 : Constant Mask Y=2 00000008 -Addr : 1750: FA : Math Op > -Addr : 1751: JZ Label0004 -Addr : 1751: 0A 09 : jz Address = 175C 9 -384 DispChar("0") -Addr : 1753: 01 : Drop Anchor -Addr : 1754: 38 30 : Constant 1 Bytes - 30 -Addr : 1756: 05 0D : Call Sub 13 -385 digits-- -Addr : 1758: 6A 3E : Variable Operation Local Offset - 2 Assign VAR-- post-dec Long -Addr : 175A: Label0003 -Addr : 175A: JMP Label0002 -Addr : 175A: 04 71 : Jmp 174D -15 -Addr : 175C: Label0004 -387 value <<= (8 - digits) << 2 -Addr : 175C: 37 02 : Constant Mask Y=2 00000008 -Addr : 175E: 68 : Variable Operation Local Offset - 2 Read -Addr : 175F: ED : Math Op - -Addr : 1760: 37 00 : Constant Mask Y=0 00000002 -Addr : 1762: E3 : Math Op << -Addr : 1763: 66 43 : Variable Operation Local Offset - 1 Assign ByteMathop << -389 repeat digits -Addr : 1765: 68 : Variable Operation Local Offset - 2 Read -Addr : 1766: TJZ Label0007 -Addr : 1766: 08 1B : tjz Address = 1783 27 -Addr : 1768: Label0005 -390 DispChar(lookupz((value <-= 4) & $f : "0".."9", "A".."F")) -Addr : 1768: 01 : Drop Anchor -Addr : 1769: 35 : Constant 1 $00000000 -Addr : 176A: Constant Address of Label0008 -Addr : 176A: 39 17 6F : Constant 2 Bytes - 17 6F -Addr : 176D: 37 01 : Constant Mask Y=1 00000004 -Addr : 176F: 66 C1 : Variable Operation Local Offset - 1 Assign BitMathop -< Push -Addr : 1771: 37 23 : Constant Mask Y=35 Decrement 0000000F -Addr : 1773: E8 : Math Op & -Addr : 1774: 38 30 : Constant 1 Bytes - 30 -Addr : 1776: 38 39 : Constant 1 Bytes - 39 -Addr : 1778: 12 : Range LookUp -Addr : 1779: 38 41 : Constant 1 Bytes - 41 -Addr : 177B: 38 46 : Constant 1 Bytes - 46 -Addr : 177D: 12 : Range LookUp -Addr : 177E: 0F : Lookdone -Addr : 177F: Label0008 -Addr : 177F: 05 0D : Call Sub 13 -Addr : 1781: Label0006 -Addr : 1781: DJNZ Label0005 -Addr : 1781: 09 65 : djnz Address = 1768 -27 -Addr : 1783: Label0007 -Addr : 1783: 32 : Return -|===========================================================================| -Spin Block ProcessDiskCmd with 0 Parameters and 1 Extra Stack Longs. Method 3 -PRI ProcessDiskCmd | rsp - -Local Parameter DBASE:0000 - Result -Local Variable DBASE:0004 - rsp -|===========================================================================| -243 if (DiskCmd == DSKCMD_RESET) -Addr : 1784: 88 82 65 : Memory Op Byte VBASE + READ Address = 0265 -Addr : 1787: 37 03 : Constant Mask Y=3 00000010 -Addr : 1789: FC : Math Op == -Addr : 178A: JZ Label0002 -Addr : 178A: 0A 0A : jz Address = 1796 10 -244 DiskBlk := -1 -Addr : 178C: 34 : Constant 0 $FFFFFFFF -Addr : 178D: 41 : Variable Operation Global Offset - 0 Write -245 DiskStat := DSKST_ACT -Addr : 178E: 37 06 : Constant Mask Y=6 00000080 -Addr : 1790: 89 82 64 : Memory Op Byte VBASE + WRITE Address = 0264 -Addr : 1793: JMP Label0003 -Addr : 1793: 04 80 7A : Jmp 1810 122 -Addr : 1796: Label0002 -247 elseif (DiskCmd == DSKCMD_INIT) -Addr : 1796: 88 82 65 : Memory Op Byte VBASE + READ Address = 0265 -Addr : 1799: 37 04 : Constant Mask Y=4 00000020 -Addr : 179B: FC : Math Op == -Addr : 179C: JZ Label0004 -Addr : 179C: 0A 19 : jz Address = 17B7 25 -248 rsp := InitCard -Addr : 179E: 00 : Drop Anchor Push -Addr : 179F: 05 04 : Call Sub 4 -Addr : 17A1: 65 : Variable Operation Local Offset - 1 Write -249 if (rsp < 0) -Addr : 17A2: 64 : Variable Operation Local Offset - 1 Read -Addr : 17A3: 35 : Constant 1 $00000000 -Addr : 17A4: F9 : Math Op < -Addr : 17A5: JZ Label0005 -Addr : 17A5: 0A 0D : jz Address = 17B4 13 -250 DiskStat := (DiskStat | DSKST_ERR) -Addr : 17A7: 88 82 64 : Memory Op Byte VBASE + READ Address = 0264 -Addr : 17AA: 37 05 : Constant Mask Y=5 00000040 -Addr : 17AC: EA : Math Op | -Addr : 17AD: 89 82 64 : Memory Op Byte VBASE + WRITE Address = 0264 -251 DiskBuf[0] := rsp -Addr : 17B0: 64 : Variable Operation Local Offset - 1 Read -Addr : 17B1: 35 : Constant 1 $00000000 -Addr : 17B2: D9 04 : Memory Op Long VBASE + POP Index WRITE Address = 0004 -Addr : 17B4: Label0005 -Addr : 17B4: Label0006 -Addr : 17B4: JMP Label0003 -Addr : 17B4: 04 80 59 : Jmp 1810 89 -Addr : 17B7: Label0004 -253 elseif (DiskCmd == DSKCMD_READBLK) -Addr : 17B7: 88 82 65 : Memory Op Byte VBASE + READ Address = 0265 -Addr : 17BA: 38 30 : Constant 1 Bytes - 30 -Addr : 17BC: FC : Math Op == -Addr : 17BD: JZ Label0007 -Addr : 17BD: 0A 1E : jz Address = 17DD 30 -254 DiskBlk := DiskBuf[0] -Addr : 17BF: 35 : Constant 1 $00000000 -Addr : 17C0: D8 04 : Memory Op Long VBASE + POP Index READ Address = 0004 -Addr : 17C2: 41 : Variable Operation Global Offset - 0 Write -255 rsp := ReadSector(DiskBlk, @DiskBuf) -Addr : 17C3: 00 : Drop Anchor Push -Addr : 17C4: 40 : Variable Operation Global Offset - 0 Read -Addr : 17C5: 47 : Variable Operation Global Offset - 1 Address -Addr : 17C6: 05 05 : Call Sub 5 -Addr : 17C8: 65 : Variable Operation Local Offset - 1 Write -256 if (rsp < 0) -Addr : 17C9: 64 : Variable Operation Local Offset - 1 Read -Addr : 17CA: 35 : Constant 1 $00000000 -Addr : 17CB: F9 : Math Op < -Addr : 17CC: JZ Label0008 -Addr : 17CC: 0A 0D : jz Address = 17DB 13 -257 DiskStat := (DiskStat | DSKST_ERR) -Addr : 17CE: 88 82 64 : Memory Op Byte VBASE + READ Address = 0264 -Addr : 17D1: 37 05 : Constant Mask Y=5 00000040 -Addr : 17D3: EA : Math Op | -Addr : 17D4: 89 82 64 : Memory Op Byte VBASE + WRITE Address = 0264 -258 DiskBuf[0] := rsp -Addr : 17D7: 64 : Variable Operation Local Offset - 1 Read -Addr : 17D8: 35 : Constant 1 $00000000 -Addr : 17D9: D9 04 : Memory Op Long VBASE + POP Index WRITE Address = 0004 -Addr : 17DB: Label0008 -Addr : 17DB: Label0009 -Addr : 17DB: JMP Label0003 -Addr : 17DB: 04 33 : Jmp 1810 51 -Addr : 17DD: Label0007 -260 elseif (DiskCmd == DSKCMD_PREPARE) -Addr : 17DD: 88 82 65 : Memory Op Byte VBASE + READ Address = 0265 -Addr : 17E0: 37 05 : Constant Mask Y=5 00000040 -Addr : 17E2: FC : Math Op == -Addr : 17E3: JZ Label000A -Addr : 17E3: 0A 0B : jz Address = 17F0 11 -261 DiskBlk := DiskBuf[0] -Addr : 17E5: 35 : Constant 1 $00000000 -Addr : 17E6: D8 04 : Memory Op Long VBASE + POP Index READ Address = 0004 -Addr : 17E8: 41 : Variable Operation Global Offset - 0 Write -262 ByteFill(@DiskBuf, $00, 512) -Addr : 17E9: 47 : Variable Operation Global Offset - 1 Address -Addr : 17EA: 35 : Constant 1 $00000000 -Addr : 17EB: 37 08 : Constant Mask Y=8 00000200 -Addr : 17ED: 18 : ByteFill(Start, Value, Count) -Addr : 17EE: JMP Label0003 -Addr : 17EE: 04 20 : Jmp 1810 32 -Addr : 17F0: Label000A -264 elseif (DiskCmd == DSKCMD_WRITEBLK) -Addr : 17F0: 88 82 65 : Memory Op Byte VBASE + READ Address = 0265 -Addr : 17F3: 38 50 : Constant 1 Bytes - 50 -Addr : 17F5: FC : Math Op == -Addr : 17F6: JZ Label000B -Addr : 17F6: 0A 18 : jz Address = 1810 24 -265 rsp := WriteSector(DiskBlk, @DiskBuf) -Addr : 17F8: 00 : Drop Anchor Push -Addr : 17F9: 40 : Variable Operation Global Offset - 0 Read -Addr : 17FA: 47 : Variable Operation Global Offset - 1 Address -Addr : 17FB: 05 06 : Call Sub 6 -Addr : 17FD: 65 : Variable Operation Local Offset - 1 Write -266 if (rsp < 0) -Addr : 17FE: 64 : Variable Operation Local Offset - 1 Read -Addr : 17FF: 35 : Constant 1 $00000000 -Addr : 1800: F9 : Math Op < -Addr : 1801: JZ Label000C -Addr : 1801: 0A 0D : jz Address = 1810 13 -267 DiskStat := (DiskStat | DSKST_ERR) -Addr : 1803: 88 82 64 : Memory Op Byte VBASE + READ Address = 0264 -Addr : 1806: 37 05 : Constant Mask Y=5 00000040 -Addr : 1808: EA : Math Op | -Addr : 1809: 89 82 64 : Memory Op Byte VBASE + WRITE Address = 0264 -268 DiskBuf[0] := rsp -Addr : 180C: 64 : Variable Operation Local Offset - 1 Read -Addr : 180D: 35 : Constant 1 $00000000 -Addr : 180E: D9 04 : Memory Op Long VBASE + POP Index WRITE Address = 0004 -Addr : 1810: Label000C -Addr : 1810: Label000D -Addr : 1810: Label000B -Addr : 1810: Label0003 -Addr : 1810: 32 : Return -|===========================================================================| -Spin Block InitCard with 0 Parameters and 0 Extra Stack Longs. Method 4 -PRI InitCard - -Local Parameter DBASE:0000 - Result -|===========================================================================| -277 Result := \sdc.Start(SD_BASE) -Addr : 1811: 02 : Drop Anchor Push Try -Addr : 1812: 38 18 : Constant 1 Bytes - 18 -Addr : 1814: 06 13 01 : Call Obj.Sub 19 1 -Addr : 1817: 61 : Variable Operation Local Offset - 0 Write -Addr : 1818: 32 : Return -|===========================================================================| -Spin Block ReadSector with 2 Parameters and 0 Extra Stack Longs. Method 5 -PRI ReadSector(Sector, Buffer) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - Sector -Local Parameter DBASE:0008 - Buffer -|===========================================================================| -284 Result := \sdc.ReadBlock(Sector, Buffer) -Addr : 1819: 02 : Drop Anchor Push Try -Addr : 181A: 64 : Variable Operation Local Offset - 1 Read -Addr : 181B: 68 : Variable Operation Local Offset - 2 Read -Addr : 181C: 06 13 02 : Call Obj.Sub 19 2 -Addr : 181F: 61 : Variable Operation Local Offset - 0 Write -Addr : 1820: 32 : Return -|===========================================================================| -Spin Block WriteSector with 2 Parameters and 0 Extra Stack Longs. Method 6 -PRI WriteSector(Sector, Buffer) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - Sector -Local Parameter DBASE:0008 - Buffer -|===========================================================================| -293 Result := \sdc.WriteBlock(Sector, Buffer) -Addr : 1821: 02 : Drop Anchor Push Try -Addr : 1822: 64 : Variable Operation Local Offset - 1 Read -Addr : 1823: 68 : Variable Operation Local Offset - 2 Read -Addr : 1824: 06 13 03 : Call Obj.Sub 19 3 -Addr : 1827: 61 : Variable Operation Local Offset - 0 Write -Addr : 1828: 32 : Return -|===========================================================================| -Spin Block MsgNewLine with 0 Parameters and 0 Extra Stack Longs. Method 7 -PRI MsgNewLine - -Local Parameter DBASE:0000 - Result -|===========================================================================| -301 dbg.NewLine -Addr : 1829: 01 : Drop Anchor -Addr : 182A: 06 15 17 : Call Obj.Sub 21 23 -302 if (VidRdy) -Addr : 182D: 88 82 66 : Memory Op Byte VBASE + READ Address = 0266 -Addr : 1830: JZ Label0002 -Addr : 1830: 0A 0A : jz Address = 183C 10 -304 DispChar(13) -Addr : 1832: 01 : Drop Anchor -Addr : 1833: 38 0D : Constant 1 Bytes - 0D -Addr : 1835: 05 0D : Call Sub 13 -306 DispChar(10) -Addr : 1837: 01 : Drop Anchor -Addr : 1838: 38 0A : Constant 1 Bytes - 0A -Addr : 183A: 05 0D : Call Sub 13 -Addr : 183C: Label0002 -Addr : 183C: Label0003 -Addr : 183C: 32 : Return -|===========================================================================| -Spin Block MsgStr with 1 Parameters and 0 Extra Stack Longs. Method 8 -PRI MsgStr(StrPtr) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - StrPtr -|===========================================================================| -309 dbg.Str(StrPtr) -Addr : 183D: 01 : Drop Anchor -Addr : 183E: 64 : Variable Operation Local Offset - 1 Read -Addr : 183F: 06 15 07 : Call Obj.Sub 21 7 -310 if (VidRdy) -Addr : 1842: 88 82 66 : Memory Op Byte VBASE + READ Address = 0266 -Addr : 1845: JZ Label0002 -Addr : 1845: 0A 04 : jz Address = 184B 4 -312 DispStr(StrPtr) -Addr : 1847: 01 : Drop Anchor -Addr : 1848: 64 : Variable Operation Local Offset - 1 Read -Addr : 1849: 05 0E : Call Sub 14 -Addr : 184B: Label0002 -Addr : 184B: Label0003 -Addr : 184B: 32 : Return -|===========================================================================| -Spin Block MsgDec with 1 Parameters and 0 Extra Stack Longs. Method 9 -PRI MsgDec(Val) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - Val -|===========================================================================| -315 dbg.Dec(Val) -Addr : 184C: 01 : Drop Anchor -Addr : 184D: 64 : Variable Operation Local Offset - 1 Read -Addr : 184E: 06 15 0A : Call Obj.Sub 21 10 -316 if (VidRdy) -Addr : 1851: 88 82 66 : Memory Op Byte VBASE + READ Address = 0266 -Addr : 1854: JZ Label0002 -Addr : 1854: 0A 04 : jz Address = 185A 4 -318 DispDec(Val) -Addr : 1856: 01 : Drop Anchor -Addr : 1857: 64 : Variable Operation Local Offset - 1 Read -Addr : 1858: 05 0F : Call Sub 15 -Addr : 185A: Label0002 -Addr : 185A: Label0003 -Addr : 185A: 32 : Return -|===========================================================================| -Spin Block MsgHex with 2 Parameters and 0 Extra Stack Longs. Method 10 -PRI MsgHex(Val, Digits) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - Val -Local Parameter DBASE:0008 - Digits -|===========================================================================| -321 dbg.Hex(Val, Digits) -Addr : 185B: 01 : Drop Anchor -Addr : 185C: 64 : Variable Operation Local Offset - 1 Read -Addr : 185D: 68 : Variable Operation Local Offset - 2 Read -Addr : 185E: 06 15 0E : Call Obj.Sub 21 14 -322 if (VidRdy) -Addr : 1861: 88 82 66 : Memory Op Byte VBASE + READ Address = 0266 -Addr : 1864: JZ Label0002 -Addr : 1864: 0A 05 : jz Address = 186B 5 -324 DispHex(Val, Digits) -Addr : 1866: 01 : Drop Anchor -Addr : 1867: 64 : Variable Operation Local Offset - 1 Read -Addr : 1868: 68 : Variable Operation Local Offset - 2 Read -Addr : 1869: 05 02 : Call Sub 2 -Addr : 186B: Label0002 -Addr : 186B: Label0003 -Addr : 186B: 32 : Return -|===========================================================================| -Spin Block Timer with 0 Parameters and 0 Extra Stack Longs. Method 11 -PRI Timer - -Local Parameter DBASE:0000 - Result -|===========================================================================| -327 TimerCount := SLEEP -Addr : 186C: 39 01 2C : Constant 2 Bytes - 01 2C -Addr : 186F: C9 82 44 : Memory Op Long VBASE + WRITE Address = 0244 -Addr : 1872: Label0002 -329 waitcnt(clkfreq * 1 + cnt) -Addr : 1872: 35 : Constant 1 $00000000 -Addr : 1873: C0 : Memory Op Long POP Address READ -Addr : 1874: 36 : Constant 2 $00000001 -Addr : 1875: F4 : Math Op * -Addr : 1876: 3F 91 : Register op CNT Read -Addr : 1878: EC : Math Op + -Addr : 1879: 23 : WaitCnt(count) -330 if (TimerCount > 0) -Addr : 187A: C8 82 44 : Memory Op Long VBASE + READ Address = 0244 -Addr : 187D: 35 : Constant 1 $00000000 -Addr : 187E: FA : Math Op > -Addr : 187F: JZ Label0005 -Addr : 187F: 0A 0B : jz Address = 188C 11 -331 if (TimerCount == 1) -Addr : 1881: C8 82 44 : Memory Op Long VBASE + READ Address = 0244 -Addr : 1884: 36 : Constant 2 $00000001 -Addr : 1885: FC : Math Op == -Addr : 1886: JZ Label0007 -Addr : 1886: 0A 00 : jz Address = 1888 0 -Addr : 1888: Label0007 -Addr : 1888: Label0008 -333 TimerCount-- -Addr : 1888: CA 82 44 3E : Memory Op Long VBASE + ASSIGN Address = 0244 VAR-- post-dec Long -Addr : 188C: Label0005 -Addr : 188C: Label0006 -Addr : 188C: Label0003 -Addr : 188C: JMP Label0002 -Addr : 188C: 04 64 : Jmp 1872 -28 -Addr : 188E: Label0004 -Addr : 188E: 32 : Return -|===========================================================================| -Spin Block Activity with 0 Parameters and 0 Extra Stack Longs. Method 12 -PRI Activity - -Local Parameter DBASE:0000 - Result -|===========================================================================| -336 if (TimerCount == 0) -Addr : 188F: C8 82 44 : Memory Op Long VBASE + READ Address = 0244 -Addr : 1892: 35 : Constant 1 $00000000 -Addr : 1893: FC : Math Op == -Addr : 1894: JZ Label0002 -Addr : 1894: 0A 00 : jz Address = 1896 0 -Addr : 1896: Label0002 -Addr : 1896: Label0003 -338 TimerCount := SLEEP -Addr : 1896: 39 01 2C : Constant 2 Bytes - 01 2C -Addr : 1899: C9 82 44 : Memory Op Long VBASE + WRITE Address = 0244 -Addr : 189C: 32 : Return -|===========================================================================| -Spin Block DispChar with 1 Parameters and 0 Extra Stack Longs. Method 13 -PRI DispChar(c) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - c -|===========================================================================| -353 command := $100 | c -Addr : 189D: 37 07 : Constant Mask Y=7 00000100 -Addr : 189F: 64 : Variable Operation Local Offset - 1 Read -Addr : 18A0: EA : Math Op | -Addr : 18A1: C5 58 : Memory Op Long PBASE + WRITE Address = 0058 -Addr : 18A3: Label0002 -354 repeat while command -Addr : 18A3: C4 58 : Memory Op Long PBASE + READ Address = 0058 -Addr : 18A5: JZ Label0004 -Addr : 18A5: 0A 02 : jz Address = 18A9 2 -Addr : 18A7: Label0003 -Addr : 18A7: JMP Label0002 -Addr : 18A7: 04 7A : Jmp 18A3 -6 -Addr : 18A9: Label0004 -Addr : 18A9: 32 : Return -|===========================================================================| -Spin Block DispStr with 1 Parameters and 1 Extra Stack Longs. Method 14 -PRI DispStr(strptr) | i - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - strptr -Local Variable DBASE:0008 - i -|===========================================================================| -357 repeat i from 0 to strsize(strptr) -Addr : 18AA: 35 : Constant 1 $00000000 -Addr : 18AB: 69 : Variable Operation Local Offset - 2 Write -Addr : 18AC: Label0002 -358 DispChar(byte[strptr][i]) -Addr : 18AC: 01 : Drop Anchor -Addr : 18AD: 64 : Variable Operation Local Offset - 1 Read -Addr : 18AE: 68 : Variable Operation Local Offset - 2 Read -Addr : 18AF: 90 : Memory Op Byte POP Address POP Index READ -Addr : 18B0: 05 0D : Call Sub 13 -Addr : 18B2: Label0003 -357 repeat i from 0 to strsize(strptr) -Addr : 18B2: 35 : Constant 1 $00000000 -Addr : 18B3: 64 : Variable Operation Local Offset - 1 Read -Addr : 18B4: 16 : StrSize(String) -Addr : 18B5: Repeat i Step Label0002 -Addr : 18B5: 6A 02 74 : Variable Operation Local Offset - 2 Assign Repeat-Var loop Address= 18AC -12 -Addr : 18B8: Label0004 -Addr : 18B8: 32 : Return -|===========================================================================| -Spin Block DispDec with 1 Parameters and 1 Extra Stack Longs. Method 15 -PRI DispDec(value) | i - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - value -Local Variable DBASE:0008 - i -|===========================================================================| -364 if value < 0 -Addr : 18B9: 64 : Variable Operation Local Offset - 1 Read -Addr : 18BA: 35 : Constant 1 $00000000 -Addr : 18BB: F9 : Math Op < -Addr : 18BC: JZ Label0002 -Addr : 18BC: 0A 07 : jz Address = 18C5 7 -365 -value -Addr : 18BE: 66 46 : Variable Operation Local Offset - 1 Assign LongMathop - -366 DispChar("-") -Addr : 18C0: 01 : Drop Anchor -Addr : 18C1: 38 2D : Constant 1 Bytes - 2D -Addr : 18C3: 05 0D : Call Sub 13 -Addr : 18C5: Label0002 -Addr : 18C5: Label0003 -368 i := 1_000_000_000 -Addr : 18C5: 3B 3B 9A CA 00 : Constant 4 Bytes - 3B 9A CA 00 -Addr : 18CA: 69 : Variable Operation Local Offset - 2 Write -370 repeat 10 -Addr : 18CB: 38 0A : Constant 1 Bytes - 0A -Addr : 18CD: TJZ Label0006 -Addr : 18CD: 08 27 : tjz Address = 18F6 39 -Addr : 18CF: Label0004 -371 if value => i -Addr : 18CF: 64 : Variable Operation Local Offset - 1 Read -Addr : 18D0: 68 : Variable Operation Local Offset - 2 Read -Addr : 18D1: FE : Math Op => -Addr : 18D2: JZ Label0007 -Addr : 18D2: 0A 10 : jz Address = 18E4 16 -372 DispChar(value/i + "0") -Addr : 18D4: 01 : Drop Anchor -Addr : 18D5: 64 : Variable Operation Local Offset - 1 Read -Addr : 18D6: 68 : Variable Operation Local Offset - 2 Read -Addr : 18D7: F6 : Math Op / -Addr : 18D8: 38 30 : Constant 1 Bytes - 30 -Addr : 18DA: EC : Math Op + -Addr : 18DB: 05 0D : Call Sub 13 -373 value //= i -Addr : 18DD: 68 : Variable Operation Local Offset - 2 Read -Addr : 18DE: 66 57 : Variable Operation Local Offset - 1 Assign LongMathop // -374 result~~ -Addr : 18E0: 62 1C : Variable Operation Local Offset - 0 Assign VAR~~ Post-set -Addr : 18E2: JMP Label0008 -Addr : 18E2: 04 0C : Jmp 18F0 12 -Addr : 18E4: Label0007 -375 elseif result or i == 1 -Addr : 18E4: 60 : Variable Operation Local Offset - 0 Read -Addr : 18E5: 68 : Variable Operation Local Offset - 2 Read -Addr : 18E6: 36 : Constant 2 $00000001 -Addr : 18E7: FC : Math Op == -Addr : 18E8: F2 : Math Op OR -Addr : 18E9: JZ Label0009 -Addr : 18E9: 0A 05 : jz Address = 18F0 5 -376 DispChar("0") -Addr : 18EB: 01 : Drop Anchor -Addr : 18EC: 38 30 : Constant 1 Bytes - 30 -Addr : 18EE: 05 0D : Call Sub 13 -Addr : 18F0: Label0009 -Addr : 18F0: Label0008 -377 i /= 10 -Addr : 18F0: 38 0A : Constant 1 Bytes - 0A -Addr : 18F2: 6A 56 : Variable Operation Local Offset - 2 Assign LongMathop / -Addr : 18F4: Label0005 -Addr : 18F4: DJNZ Label0004 -Addr : 18F4: 09 59 : djnz Address = 18CF -39 -Addr : 18F6: Label0006 -Addr : 18F6: 32 : Return -|===========================================================================| -Object vgacolour -Object Base is 18F8 -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0008 Variable cog -|===========================================================================| -Object DAT Blocks -|===========================================================================| -1904(0000) | org 0 ' set origin to $000 for start of program -1904(0000) 00 02 00 00 | d0 long 1 << 9 ' d0 always resides here at $000, executes as NOP -1908(0001) D1 DE BF A0 | :move mov $1EF, main_begin + main_size - 1 -190C(0002) 18 02 BC 84 | sub :move,d0s0 ' (do reverse move to avoid overwrite) -1910(0003) 01 34 FC E4 | djnz main_ctr,#:move -1914(0004) 1C 42 BD A0 | :waitvid mov scancode+0, i0 ' org scancode -1918(0005) 1D 44 BD A0 | :shr mov scancode+1, i1 ' waitvid colorbuff+0, scanbuff+0 -191C(0006) 19 08 BC 80 | add :waitvid, d1 ' shr scanbuff+0,#8 -1920(0007) 19 0A BC 80 | add :shr, d1 ' waitvid colorbuff+1, scanbuff+1 -1924(0008) 18 38 BC 80 | add i0, d0s0 ' shr scanbuff+1,#8 -1928(0009) 00 3A BC 80 | add i1, d0 ' ... -192C(000A) 04 36 FC E4 | djnz scan_ctr, #:waitvid ' waitvid colorbuff+cols-1, scanbuff+cols-1 -1930(000B) 1E 80 BE A0 | mov scancode+cols*2-1, i2 ' mov vscl,#hf -1934(000C) 1F 82 BE A0 | mov scancode+cols*2+0, i3 ' waitvid hvsync,#0 -1938(000D) 20 84 BE A0 | mov scancode+cols*2+1, i4 ' jmp #scanret -193C(000E) 21 EC BF A0 | mov dira, reg_dira ' set pin directions -1940(000F) 22 EE BF A0 | mov dirb, reg_dirb -1944(0010) 18 F4 FF 58 | movi frqa, #(pr / 5) << 2 ' set pixel rate -1948(0011) 23 FC BF A0 | mov vcfg, reg_vcfg ' set video configuration -194C(0012) 01 FE FF A0 | mov vscl, #1 ' set video to reload on every pixel -1950(0013) A7 49 BC F8 | waitcnt sync_cnt, colormask ' wait for start value in cnt, add ~1ms -1954(0014) 0E F0 FF 58 | movi ctra, #%00001_110 ' COGs in sync! enable PLLs now - NCOs locked! -1958(0015) 00 48 FC F8 | waitcnt sync_cnt, #0 ' wait ~1ms for PLLs to stabilize - PLLs locked! -195C(0016) 64 FE FF A0 | mov vscl, #100 ' insure initial WAITVIDs lock cleanly -1960(0017) 43 01 7C 5C | jmp #vsync ' jump to vsync - WAITVIDs will now be locked! -1964(0018) 01 02 00 00 | d0s0 long 1 << 9 + 1 -1968(0019) 00 04 00 00 | d1 long 1 << 10 -196C(001A) AD 00 00 00 | main_ctr long main_size -1970(001B) 50 00 00 00 | scan_ctr long cols -1974(001C) 01 A2 3C FC | i0 waitvid colorbuff+0, scanbuff+0 -1978(001D) 08 02 FC 28 | i1 shr scanbuff+0, #8 -197C(001E) 18 FE FF A0 | i2 mov vscl, #hf -1980(001F) 00 5A 7F FC | i3 waitvid hvsync, #0 -1984(0020) 85 01 7C 5C | i4 jmp #scanret -1988(0021) 00 00 00 00 | reg_dira long 0 ' set at runtime -198C(0022) 00 00 00 00 | reg_dirb long 0 ' set at runtime -1990(0023) 00 00 00 00 | reg_vcfg long 0 ' set at runtime -1994(0024) 00 00 00 00 | sync_cnt long 0 ' set at runtime -1998(0025) | fit scancode ' make sure initialization code and data fit -1998(0025) | There are 124 ($07C) Longs left in the cog -1998(0025) | main_begin org maincode ' main code follows (gets moved into maincode) -1998(0143) 03 A0 FF A0 | vsync mov x, #vs ' do vertical sync lines -199C(0144) 94 3D FF 5C | call #blank_vsync -19A0(0145) 11 A0 FF A0 | vb_lines mov x, #vb ' do vertical back porch lines (# set at runtime) -19A4(0146) 94 3D FF 5C | call #blank_vsync -19A8(0147) 9F 9D BF A0 | mov screen_ptr, screen_base ' reset screen pointer to upper-left character -19AC(0148) 00 AA FF A0 | mov row, #0 ' reset row counter for cursor insertion -19B0(0149) 3C AC FF A0 | mov fours, #rows * 4 / 2 ' set number of 4-line builds for whole screen -19B4(014A) A2 9F BF A0 | fourline mov font_ptr, font_part ' get address of appropriate font section -19B8(014B) 0A 9E FF 2C | shl font_ptr, #8+2 -19BC(014C) A1 9F BF 80 | add font_ptr, font_base -19C0(014D) 00 B6 FE 54 | movd :pixa, #scanbuff-1 ' reset scanbuff address (pre-decremented) -19C4(014E) 50 CA FE 54 | movd :cola, #colorbuff-1 ' reset colorbuff address (pre-decremented) -19C8(014F) 50 CC FE 54 | movd :colb, #colorbuff-1 -19CC(0150) 02 A2 FF A0 | mov y, #2 ' must build scanbuff in two sections because -19D0(0151) A5 FF BF A0 | mov vscl, vscl_line2x ' ..pixel counter is limited to twelve bits -19D4(0152) 00 56 7F FC | :halfrow waitvid underscore, #0 ' output lows to let other COG drive VGA pins -19D8(0153) 28 A0 FF A0 | mov x, #cols/2 ' ..for 2 scan lines, ready for half a row -19DC(0154) CE A5 BF 04 | :column rdword z, screen_ptr ' get character and colors from screen memory -19E0(0155) D2 A9 BF A0 | mov bg, z -19E4(0156) FF A4 FF 60 | and z, #$ff ' mask character code -19E8(0157) 02 A4 FF 2C | shl z, #2 ' * 4 -19EC(0158) CF A5 BF 80 | add z, font_ptr ' add font section address to point to 8*4 pixels -19F0(0159) 00 B6 BE 80 | add :pixa, d0 ' increment scanbuff destination addresses -19F4(015A) 02 9C FF 80 | add screen_ptr, #2 ' increment screen memory address -19F8(015B) D2 03 BC 08 | :pixa rdlong scanbuff, z ' read pixel long (8*4) into scanbuff -19FC(015C) 0C A8 FF 20 | ror bg, #12 ' background color in bits 3..0 -1A00(015D) D4 A7 BF A0 | mov fg, bg ' foreground color in bits 31..28 -1A04(015E) 1C A6 FF 28 | shr fg, #28 ' bits 3..0 -1A08(015F) BE A7 FF 80 | add fg, #fg_clut ' + offset to foreground CLUT -1A0C(0160) D3 CB BE 50 | movs :cola, fg -1A10(0161) 00 CA BE 80 | add :cola, d0 -1A14(0162) AE A9 FF 80 | add bg, #bg_clut ' + offset to background CLUT -1A18(0163) D4 CD BE 50 | movs :colb, bg -1A1C(0164) 00 CC BE 80 | add :colb, d0 -1A20(0165) 00 A2 BC A0 | :cola mov colorbuff, 0-0 -1A24(0166) 00 A2 BC 68 | :colb or colorbuff, 0-0 -1A28(0167) 54 A1 FF E4 | djnz x, #:column ' another character in this half-row? -1A2C(0168) 52 A3 FF E4 | djnz y, #:halfrow ' loop to do 2nd half-row, time for 2nd WAITVID -1A30(0169) A0 9C FF 84 | sub screen_ptr, #2*cols ' back up to start of same row in screen memory -1A34(016A) 02 A4 FF A0 | mov z, #2 ' ready for two cursors -1A38(016B) A0 A1 BF 00 | :cursor rdbyte x, cursor_base ' x in range? -1A3C(016C) 01 40 FF 80 | add cursor_base, #1 -1A40(016D) 50 A0 7F 85 | cmp x, #cols wc -1A44(016E) A0 A3 BF 00 | rdbyte y, cursor_base ' y match? -1A48(016F) 01 40 FF 80 | add cursor_base, #1 -1A4C(0170) D5 A3 3F 86 | cmp y, row wz -1A50(0171) A0 A3 BF 00 | rdbyte y, cursor_base ' get cursor mode -1A54(0172) 01 40 FF 80 | add cursor_base, #1 -1A58(0173) 80 01 5C 5C | if_nc_or_nz jmp #:nocursor ' if cursor not in scanbuff, no cursor -1A5C(0174) 01 A0 FF 80 | add x, #scanbuff ' cursor in scanbuff, set scanbuff address -1A60(0175) D0 FF BE 54 | movd :xor, x -1A64(0176) 02 A2 7F 61 | test y, #%010 wc ' get mode bits into flags -1A68(0177) 01 A2 7F 62 | test y, #%001 wz -1A6C(0178) 80 01 48 5C | if_nc_and_z jmp #:nocursor ' if cursor disabled, no cursor -1A70(0179) F1 53 23 61 | if_c_and_z test slowbit, cnt wc ' if blink mode, get blink state -1A74(017A) F1 55 13 61 | if_c_and_nz test fastbit, cnt wc -1A78(017B) 04 A2 7F 62 | test y, #%100 wz ' get box or underscore cursor piece -1A7C(017C) A8 A1 AB A0 | if_z mov x, longmask -1A80(017D) AB A1 97 A0 | if_nz mov x, underscore -1A84(017E) 03 44 57 86 | if_nz cmp font_part, #3 wz ' if underscore, must be last font section -1A88(017F) D0 03 88 6C | :xor if_nc_and_z xor scanbuff, x ' conditionally xor cursor into scanbuff -1A8C(0180) 6B A5 FF E4 | :nocursor djnz z, #:cursor ' second cursor? -1A90(0181) 06 40 FF 84 | sub cursor_base, #3*2 ' restore cursor base -1A94(0182) 04 A2 FF A0 | mov y, #4 ' ready for four scan lines -1A98(0183) A6 FF BF A0 | scanline mov vscl, vscl_chr ' set pixel rate for characters -1A9C(0184) A1 00 7C 5C | jmp #scancode ' jump to scanbuff display routine in scancode -1AA0(0185) 28 FE FF A0 | scanret mov vscl, #hs ' do horizontal sync pixels -1AA4(0186) 01 5A 7F FC | waitvid hvsync, #1 ' #1 makes hsync active -1AA8(0187) 80 FE FF A0 | mov vscl, #hb ' do horizontal back porch pixels -1AAC(0188) 00 5A 7F FC | waitvid hvsync, #0 ' #0 makes hsync inactive -1AB0(0189) 08 A0 FC 28 | shr scanbuff+cols-1, #8 ' shift last column's pixels right by 8 -1AB4(018A) 83 A3 FF E4 | djnz y, #scanline ' another scan line? -1AB8(018B) 02 44 FF 80 | add font_part, #2 ' if font_part + 2 => 4, subtract 4 (new row) -1ABC(018C) 04 44 FF E1 | cmpsub font_part, #4 wc ' c=0 for same row, c=1 for new row -1AC0(018D) A0 9C F3 80 | if_c add screen_ptr, #2*cols ' if new row, advance screen pointer -1AC4(018E) 01 AA F3 80 | if_c add row, #1 ' if new row, increment row counter -1AC8(018F) 4A AD FF E4 | djnz fours, #fourline ' another 4-line build/display? -1ACC(0190) F0 51 3F 08 | wrlong longmask,par ' write -1 to refresh indicator -1AD0(0191) 14 A0 FF A0 | vf_lines mov x,#vf ' do vertical front porch lines (# set at runtime) -1AD4(0192) 95 3D FF 5C | call #blank -1AD8(0193) 43 01 7C 5C | jmp #vsync ' new field, loop to vsync -1ADC(0194) 01 5B FF 6C | blank_vsync xor hvsync,#$101 ' flip vertical sync bits -1AE0(0195) A3 FF BF A0 | blank mov vscl, hx ' do blank pixels -1AE4(0196) 00 5A 7F FC | waitvid hvsync, #0 -1AE8(0197) 18 FE FF A0 | mov vscl, #hf ' do horizontal front porch pixels -1AEC(0198) 00 5A 7F FC | waitvid hvsync, #0 -1AF0(0199) 28 FE FF A0 | mov vscl, #hs ' do horizontal sync pixels -1AF4(019A) 01 5A 7F FC | waitvid hvsync, #1 -1AF8(019B) 80 FE FF A0 | mov vscl, #hb ' do horizontal back porch pixels -1AFC(019C) 00 5A 7F FC | waitvid hvsync, #0 -1B00(019D) 95 A1 FF E4 | djnz x,#blank ' another line? -1B04(019E) | blank_ret -1B04(019E) | blank_vsync_ret -1B04(019E) 00 00 7C 5C | ret -1B08(019F) 00 00 00 00 | screen_base long 0 ' set at runtime (3 contiguous longs) -1B0C(01A0) 00 00 00 00 | cursor_base long 0 ' set at runtime -1B10(01A1) 00 00 00 00 | font_base long 0 ' set at runtime -1B14(01A2) 00 00 00 00 | font_part long 0 ' set at runtime -1B18(01A3) 80 02 00 00 | hx long hp ' visible pixels per scan line -1B1C(01A4) 40 03 00 00 | vscl_line long hp + hf + hs + hb ' total number of pixels per scan line -1B20(01A5) 80 06 00 00 | vscl_line2x long (hp + hf + hs + hb) * 2 ' total number of pixels per 2 scan lines -1B24(01A6) 08 10 00 00 | vscl_chr long 1 << 12 + 8 ' 1 clock per pixel and 8 pixels per set -1B28(01A7) FC FC 00 00 | colormask long $FCFC ' mask to isolate R,G,B bits from H,V -1B2C(01A8) FF FF FF FF | longmask long $FFFFFFFF ' all bits set -1B30(01A9) 00 00 00 02 | slowbit long 1 << 25 ' cnt mask for slow cursor blink -1B34(01AA) 00 00 00 01 | fastbit long 1 << 24 ' cnt mask for fast cursor blink -1B38(01AB) 00 00 FF FF | underscore long $FFFF0000 ' underscore cursor pattern -1B3C(01AC) 03 03 00 00 | hv long hv_inactive ' -H,-V states -1B40(01AD) 03 01 00 00 | hvsync long hv_inactive ^ $200 ' +/-H,-V states -1B44(01AE) 03 03 00 00 | bg_clut long %00000011_00000011 ' black -1B48(01AF) 0B 03 00 00 | long %00000011_00001011 ' dark blue -1B4C(01B0) 23 03 00 00 | long %00000011_00100011 ' dark green -1B50(01B1) 2B 03 00 00 | long %00000011_00101011 ' dark cyan -1B54(01B2) 83 03 00 00 | long %00000011_10000011 ' dark red -1B58(01B3) 8B 03 00 00 | long %00000011_10001011 ' dark magenta -1B5C(01B4) A3 03 00 00 | long %00000011_10100011 ' brown -1B60(01B5) AB 03 00 00 | long %00000011_10101011 ' light gray -1B64(01B6) 57 03 00 00 | long %00000011_01010111 ' dark gray -1B68(01B7) 0F 03 00 00 | long %00000011_00001111 ' light blue -1B6C(01B8) 33 03 00 00 | long %00000011_00110011 ' light green -1B70(01B9) 3F 03 00 00 | long %00000011_00111111 ' light cyan -1B74(01BA) C3 03 00 00 | long %00000011_11000011 ' light red -1B78(01BB) CF 03 00 00 | long %00000011_11001111 ' light magenta -1B7C(01BC) F3 03 00 00 | long %00000011_11110011 ' light yellow -1B80(01BD) FF 03 00 00 | long %00000011_11111111 ' white -1B84(01BE) 03 03 00 00 | fg_clut long %00000011_00000011 ' black -1B88(01BF) 03 07 00 00 | long %00000111_00000011 ' dark blue -1B8C(01C0) 03 13 00 00 | long %00010011_00000011 ' dark green -1B90(01C1) 03 17 00 00 | long %00010111_00000011 ' dark cyan -1B94(01C2) 03 43 00 00 | long %01000011_00000011 ' dark red -1B98(01C3) 03 47 00 00 | long %01000111_00000011 ' dark magenta -1B9C(01C4) 03 53 00 00 | long %01010011_00000011 ' brown -1BA0(01C5) 03 AB 00 00 | long %10101011_00000011 ' light gray -1BA4(01C6) 03 57 00 00 | long %01010111_00000011 ' dark gray -1BA8(01C7) 03 0B 00 00 | long %00001011_00000011 ' blue -1BAC(01C8) 03 23 00 00 | long %00100011_00000011 ' green -1BB0(01C9) 03 2B 00 00 | long %00101011_00000011 ' cyan -1BB4(01CA) 03 83 00 00 | long %10000011_00000011 ' red -1BB8(01CB) 03 8B 00 00 | long %10001011_00000011 ' magenta -1BBC(01CC) 03 A3 00 00 | long %10100011_00000011 ' yellow -1BC0(01CD) 03 FF 00 00 | long %11111111_00000011 ' white -1BC4(01CE) | screen_ptr res 1 -1BC4(01CF) | font_ptr res 1 -1BC4(01D0) | x res 1 -1BC4(01D1) | y res 1 -1BC4(01D2) | z res 1 -1BC4(01D3) | fg res 1 -1BC4(01D4) | bg res 1 -1BC4(01D5) | row res 1 -1BC4(01D6) | fours res 1 -1BC4(01D7) | fit $1f0 -1BC4(01D7) | There are 25 ($019) Longs left in the cog -1BC4(01D7) 00 00 00 00 | font long -1BC4(01D7) 00 BA 82 00 | long $0082ba00,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 -1BC8(01D8) 00 00 00 00 | -1BCC(01D9) 00 2A 55 2A | -1BD0(01DA) 00 00 36 36 | -1BD4(01DB) 00 00 1E 06 | -1BD8(01DC) 00 00 1C 06 | -1BDC(01DD) 00 00 06 06 | -1BE0(01DE) 00 00 00 3C | -1BE4(01DF) 00 00 00 00 | long $00000000,$6e660000,$66660000,$18181818,$00000000,$00000000,$18181818,$18181818 -1BE8(01E0) 00 00 66 6E | -1BEC(01E1) 00 00 66 66 | -1BF0(01E2) 18 18 18 18 | -1BF4(01E3) 00 00 00 00 | -1BF8(01E4) 00 00 00 00 | -1BFC(01E5) 18 18 18 18 | -1C00(01E6) 18 18 18 18 | -1C04(01E7) FF FF 00 00 | long $0000ffff,$00000000,$00000000,$00000000,$00000000,$18181818,$18181818,$18181818 -1C08(01E8) 00 00 00 00 | -1C0C(01E9) 00 00 00 00 | -1C10(01EA) 00 00 00 00 | -1C14(01EB) 00 00 00 00 | -1C18(01EC) 18 18 18 18 | -1C1C(01ED) 18 18 18 18 | -1C20(01EE) 18 18 18 18 | -1C24(01EF) 00 00 00 00 | long $00000000,$18181818,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 -1C28(01F0) 18 18 18 18 | -1C2C(01F1) 00 00 00 60 | -1C30(01F2) 00 00 00 06 | -1C34(01F3) 00 00 00 00 | -1C38(01F4) 00 00 00 00 | -1C3C(01F5) 00 00 00 38 | -1C40(01F6) 00 00 00 00 | -1C44(01F7) 00 00 00 00 | long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 -1C48(01F8) 00 00 00 18 | -1C4C(01F9) 00 00 00 36 | -1C50(01FA) 00 00 00 24 | -1C54(01FB) 00 00 00 18 | -1C58(01FC) 00 00 00 4E | -1C5C(01FD) 00 00 00 1C | -1C60(01FE) 00 00 00 18 | -1C64(01FF) 00 00 00 30 | long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 -1C68(0200) 00 00 00 0C | -1C6C(0201) 00 00 00 00 | -1C70(0202) 00 00 00 00 | -1C74(0203) 00 00 00 00 | -1C78(0204) 00 00 00 00 | -1C7C(0205) 00 00 00 00 | -1C80(0206) 00 00 00 60 | -1C84(0207) 00 00 00 18 | long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 -1C88(0208) 00 00 00 18 | -1C8C(0209) 00 00 00 3C | -1C90(020A) 00 00 00 7E | -1C94(020B) 00 00 00 60 | -1C98(020C) 00 00 00 7E | -1C9C(020D) 00 00 00 3C | -1CA0(020E) 00 00 00 7E | -1CA4(020F) 00 00 00 3C | long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 -1CA8(0210) 00 00 00 3C | -1CAC(0211) 00 00 00 00 | -1CB0(0212) 00 00 00 00 | -1CB4(0213) 00 00 00 60 | -1CB8(0214) 00 00 00 00 | -1CBC(0215) 00 00 00 06 | -1CC0(0216) 00 00 00 3C | -1CC4(0217) 00 00 00 3C | long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 -1CC8(0218) 00 00 00 3C | -1CCC(0219) 00 00 00 3E | -1CD0(021A) 00 00 00 3C | -1CD4(021B) 00 00 00 3E | -1CD8(021C) 00 00 00 7E | -1CDC(021D) 00 00 00 7E | -1CE0(021E) 00 00 00 3C | -1CE4(021F) 00 00 00 66 | long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 -1CE8(0220) 00 00 00 7E | -1CEC(0221) 00 00 00 60 | -1CF0(0222) 00 00 00 46 | -1CF4(0223) 00 00 00 06 | -1CF8(0224) 00 00 00 42 | -1CFC(0225) 00 00 00 66 | -1D00(0226) 00 00 00 3C | -1D04(0227) 00 00 00 3E | long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 -1D08(0228) 00 00 00 3C | -1D0C(0229) 00 00 00 3E | -1D10(022A) 00 00 00 3C | -1D14(022B) 00 00 00 7E | -1D18(022C) 00 00 00 66 | -1D1C(022D) 00 00 00 66 | -1D20(022E) 00 00 00 66 | -1D24(022F) 00 00 00 42 | long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 -1D28(0230) 00 00 00 66 | -1D2C(0231) 00 00 00 7E | -1D30(0232) 00 00 00 3C | -1D34(0233) 00 00 00 06 | -1D38(0234) 00 00 00 3C | -1D3C(0235) 00 00 00 18 | -1D40(0236) 00 00 00 00 | -1D44(0237) 00 00 0C 18 | long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 -1D48(0238) 00 00 00 00 | -1D4C(0239) 00 00 00 06 | -1D50(023A) 00 00 00 00 | -1D54(023B) 00 00 00 60 | -1D58(023C) 00 00 00 00 | -1D5C(023D) 00 00 00 38 | -1D60(023E) 00 00 00 00 | -1D64(023F) 00 00 00 06 | long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 -1D68(0240) 00 00 00 18 | -1D6C(0241) 00 00 00 60 | -1D70(0242) 00 00 00 06 | -1D74(0243) 00 00 00 1C | -1D78(0244) 00 00 00 00 | -1D7C(0245) 00 00 00 00 | -1D80(0246) 00 00 00 00 | -1D84(0247) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -1D88(0248) 00 00 00 00 | -1D8C(0249) 00 00 00 00 | -1D90(024A) 00 00 00 00 | -1D94(024B) 00 00 00 00 | -1D98(024C) 00 00 00 00 | -1D9C(024D) 00 00 00 00 | -1DA0(024E) 00 00 00 00 | -1DA4(024F) 00 00 00 00 | long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 -1DA8(0250) 00 00 00 00 | -1DAC(0251) 00 00 00 00 | -1DB0(0252) 00 00 00 38 | -1DB4(0253) 00 00 00 18 | -1DB8(0254) 00 00 00 1C | -1DBC(0255) 00 00 00 4C | -1DC0(0256) 55 AA 55 AA | -1DC4(0257) 00 00 00 00 | long $00000000,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 -1DC8(0258) 00 00 00 00 | -1DCC(0259) 00 2A 55 2A | -1DD0(025A) 00 00 36 36 | -1DD4(025B) 00 00 1E 06 | -1DD8(025C) 00 00 1C 06 | -1DDC(025D) 00 00 06 06 | -1DE0(025E) 00 00 00 3C | -1DE4(025F) 00 00 00 00 | long $00000000,$6e660000,$66660000,$24242424,$00000000,$00000000,$24242424,$24242424 -1DE8(0260) 00 00 66 6E | -1DEC(0261) 00 00 66 66 | -1DF0(0262) 24 24 24 24 | -1DF4(0263) 00 00 00 00 | -1DF8(0264) 00 00 00 00 | -1DFC(0265) 24 24 24 24 | -1E00(0266) 24 24 24 24 | -1E04(0267) FF 00 FF 00 | long $00ff00ff,$ff000000,$00000000,$00000000,$00000000,$24242424,$24242424,$24242424 -1E08(0268) 00 00 00 FF | -1E0C(0269) 00 00 00 00 | -1E10(026A) 00 00 00 00 | -1E14(026B) 00 00 00 00 | -1E18(026C) 24 24 24 24 | -1E1C(026D) 24 24 24 24 | -1E20(026E) 24 24 24 24 | -1E24(026F) 00 00 00 00 | long $00000000,$24242424,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 -1E28(0270) 24 24 24 24 | -1E2C(0271) 00 00 00 60 | -1E30(0272) 00 00 00 06 | -1E34(0273) 00 00 00 00 | -1E38(0274) 00 00 00 00 | -1E3C(0275) 00 00 00 38 | -1E40(0276) 00 00 00 00 | -1E44(0277) 00 00 00 00 | long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 -1E48(0278) 00 00 00 18 | -1E4C(0279) 00 00 00 36 | -1E50(027A) 00 00 00 24 | -1E54(027B) 00 00 00 18 | -1E58(027C) 00 00 00 4E | -1E5C(027D) 00 00 00 1C | -1E60(027E) 00 00 00 18 | -1E64(027F) 00 00 00 30 | long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 -1E68(0280) 00 00 00 0C | -1E6C(0281) 00 00 00 00 | -1E70(0282) 00 00 00 00 | -1E74(0283) 00 00 00 00 | -1E78(0284) 00 00 00 00 | -1E7C(0285) 00 00 00 00 | -1E80(0286) 00 00 00 60 | -1E84(0287) 00 00 00 18 | long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 -1E88(0288) 00 00 00 18 | -1E8C(0289) 00 00 00 3C | -1E90(028A) 00 00 00 7E | -1E94(028B) 00 00 00 60 | -1E98(028C) 00 00 00 7E | -1E9C(028D) 00 00 00 3C | -1EA0(028E) 00 00 00 7E | -1EA4(028F) 00 00 00 3C | long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 -1EA8(0290) 00 00 00 3C | -1EAC(0291) 00 00 00 00 | -1EB0(0292) 00 00 00 00 | -1EB4(0293) 00 00 00 60 | -1EB8(0294) 00 00 00 00 | -1EBC(0295) 00 00 00 06 | -1EC0(0296) 00 00 00 3C | -1EC4(0297) 00 00 00 3C | long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 -1EC8(0298) 00 00 00 3C | -1ECC(0299) 00 00 00 3E | -1ED0(029A) 00 00 00 3C | -1ED4(029B) 00 00 00 3E | -1ED8(029C) 00 00 00 7E | -1EDC(029D) 00 00 00 7E | -1EE0(029E) 00 00 00 3C | -1EE4(029F) 00 00 00 66 | long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 -1EE8(02A0) 00 00 00 7E | -1EEC(02A1) 00 00 00 60 | -1EF0(02A2) 00 00 00 46 | -1EF4(02A3) 00 00 00 06 | -1EF8(02A4) 00 00 00 42 | -1EFC(02A5) 00 00 00 66 | -1F00(02A6) 00 00 00 3C | -1F04(02A7) 00 00 00 3E | long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 -1F08(02A8) 00 00 00 3C | -1F0C(02A9) 00 00 00 3E | -1F10(02AA) 00 00 00 3C | -1F14(02AB) 00 00 00 7E | -1F18(02AC) 00 00 00 66 | -1F1C(02AD) 00 00 00 66 | -1F20(02AE) 00 00 00 66 | -1F24(02AF) 00 00 00 42 | long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 -1F28(02B0) 00 00 00 66 | -1F2C(02B1) 00 00 00 7E | -1F30(02B2) 00 00 00 3C | -1F34(02B3) 00 00 00 06 | -1F38(02B4) 00 00 00 3C | -1F3C(02B5) 00 00 00 18 | -1F40(02B6) 00 00 00 00 | -1F44(02B7) 00 00 0C 18 | long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 -1F48(02B8) 00 00 00 00 | -1F4C(02B9) 00 00 00 06 | -1F50(02BA) 00 00 00 00 | -1F54(02BB) 00 00 00 60 | -1F58(02BC) 00 00 00 00 | -1F5C(02BD) 00 00 00 38 | -1F60(02BE) 00 00 00 00 | -1F64(02BF) 00 00 00 06 | long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 -1F68(02C0) 00 00 00 18 | -1F6C(02C1) 00 00 00 60 | -1F70(02C2) 00 00 00 06 | -1F74(02C3) 00 00 00 1C | -1F78(02C4) 00 00 00 00 | -1F7C(02C5) 00 00 00 00 | -1F80(02C6) 00 00 00 00 | -1F84(02C7) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -1F88(02C8) 00 00 00 00 | -1F8C(02C9) 00 00 00 00 | -1F90(02CA) 00 00 00 00 | -1F94(02CB) 00 00 00 00 | -1F98(02CC) 00 00 00 00 | -1F9C(02CD) 00 00 00 00 | -1FA0(02CE) 00 00 00 00 | -1FA4(02CF) 00 00 00 00 | long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 -1FA8(02D0) 00 00 00 00 | -1FAC(02D1) 00 00 00 00 | -1FB0(02D2) 00 00 00 38 | -1FB4(02D3) 00 00 00 18 | -1FB8(02D4) 00 00 00 1C | -1FBC(02D5) 00 00 00 4C | -1FC0(02D6) 55 AA 55 AA | -1FC4(02D7) 82 82 00 82 | long $82008282,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 -1FC8(02D8) 00 00 18 3C | -1FCC(02D9) 55 2A 55 2A | -1FD0(02DA) 3E 36 36 00 | -1FD4(02DB) 0E 06 06 00 | -1FD8(02DC) 06 06 1C 00 | -1FDC(02DD) 06 06 1E 00 | -1FE0(02DE) 66 66 3C 00 | -1FE4(02DF) 18 18 7E 18 | long $187e1818,$0066767e,$00183c24,$1f181818,$1f000000,$f8000000,$f8181818,$ff181818 -1FE8(02E0) 7E 76 66 00 | -1FEC(02E1) 24 3C 18 00 | -1FF0(02E2) 18 18 18 1F | -1FF4(02E3) 00 00 00 1F | -1FF8(02E4) 00 00 00 F8 | -1FFC(02E5) 18 18 18 F8 | -2000(02E6) 18 18 18 FF | -2004(02E7) 00 00 00 00 | long $00000000,$0000ffff,$00000000,$00000000,$00000000,$f8181818,$1f181818,$ff181818 -2008(02E8) FF FF 00 00 | -200C(02E9) 00 00 00 00 | -2010(02EA) 00 00 00 00 | -2014(02EB) 00 00 00 00 | -2018(02EC) 18 18 18 F8 | -201C(02ED) 18 18 18 1F | -2020(02EE) 18 18 18 FF | -2024(02EF) 00 00 00 FF | long $ff000000,$18181818,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 -2028(02F0) 18 18 18 18 | -202C(02F1) 30 0C 06 0C | -2030(02F2) 0C 30 60 30 | -2034(02F3) 00 00 7E 66 | -2038(02F4) 30 30 7E 18 | -203C(02F5) 6C 0C 0C 3E | -2040(02F6) 00 00 18 18 | -2044(02F7) 00 00 00 00 | long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 -2048(02F8) 18 18 18 18 | -204C(02F9) 36 36 00 00 | -2050(02FA) 24 7E 7E 24 | -2054(02FB) 3C 5A 1A 3C | -2058(02FC) 6A 2E 30 18 | -205C(02FD) 36 36 36 1C | -2060(02FE) 18 18 18 00 | -2064(02FF) 18 18 0C 0C | long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 -2068(0300) 18 18 30 30 | -206C(0301) 00 24 18 7E | -2070(0302) 00 18 18 7E | -2074(0303) 00 00 00 00 | -2078(0304) 00 00 00 00 | -207C(0305) 00 00 00 00 | -2080(0306) 60 30 30 18 | -2084(0307) 24 66 66 66 | long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 -2088(0308) 1C 1A 18 18 | -208C(0309) 66 66 60 38 | -2090(030A) 60 30 18 3C | -2094(030B) 70 78 6C 66 | -2098(030C) 06 06 3E 66 | -209C(030D) 66 06 06 3E | -20A0(030E) 60 60 30 30 | -20A4(030F) 66 66 66 3C | long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 -20A8(0310) 66 66 66 7C | -20AC(0311) 00 18 3C 18 | -20B0(0312) 00 18 3C 18 | -20B4(0313) 30 18 0C 06 | -20B8(0314) 00 00 7E 00 | -20BC(0315) 0C 18 30 60 | -20C0(0316) 66 66 60 38 | -20C4(0317) 62 62 7A 6A | long $6a7a6262,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 -20C8(0318) 66 66 66 7E | -20CC(0319) 66 66 66 3E | -20D0(031A) 66 06 06 06 | -20D4(031B) 66 66 66 66 | -20D8(031C) 06 06 06 3E | -20DC(031D) 06 06 06 3E | -20E0(031E) 66 06 06 76 | -20E4(031F) 66 66 66 7E | long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 -20E8(0320) 18 18 18 18 | -20EC(0321) 60 60 60 60 | -20F0(0322) 66 36 1E 0E | -20F4(0323) 06 06 06 06 | -20F8(0324) 66 7E 7E 66 | -20FC(0325) 66 6E 6E 7E | -2100(0326) 66 66 66 66 | -2104(0327) 66 66 66 3E | long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 -2108(0328) 66 66 66 66 | -210C(0329) 66 66 66 3E | -2110(032A) 66 06 06 3C | -2114(032B) 18 18 18 18 | -2118(032C) 66 66 66 66 | -211C(032D) 66 66 24 24 | -2120(032E) 66 66 66 66 | -2124(032F) 66 24 3C 18 | long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 -2128(0330) 66 3C 3C 18 | -212C(0331) 60 60 30 18 | -2130(0332) 0C 0C 0C 0C | -2134(0333) 06 0C 0C 18 | -2138(0334) 30 30 30 30 | -213C(0335) 3C 66 42 00 | -2140(0336) 00 00 00 00 | -2144(0337) 30 00 00 00 | long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 -2148(0338) 00 00 3C 60 | -214C(0339) 06 06 3E 66 | -2150(033A) 00 00 3C 66 | -2154(033B) 60 60 7C 66 | -2158(033C) 00 00 3C 66 | -215C(033D) 6C 0C 0C 1E | -2160(033E) 00 00 5C 66 | -2164(033F) 06 06 3E 66 | long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 -2168(0340) 18 00 1C 18 | -216C(0341) 60 00 60 60 | -2170(0342) 06 06 66 36 | -2174(0343) 18 18 18 18 | -2178(0344) 00 00 6A FE | -217C(0345) 00 00 3E 66 | -2180(0346) 00 00 3C 66 | -2184(0347) 00 00 3E 66 | long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 -2188(0348) 00 00 7C 66 | -218C(0349) 00 00 3E 66 | -2190(034A) 00 00 3C 66 | -2194(034B) 0C 0C 3E 0C | -2198(034C) 00 00 66 66 | -219C(034D) 00 00 66 66 | -21A0(034E) 00 00 66 66 | -21A4(034F) 00 00 66 66 | long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 -21A8(0350) 00 00 66 66 | -21AC(0351) 00 00 7E 60 | -21B0(0352) 0C 0C 18 0C | -21B4(0353) 18 18 18 18 | -21B8(0354) 30 30 18 30 | -21BC(0355) 7E 32 00 00 | -21C0(0356) 55 AA 55 AA | -21C4(0357) 00 00 00 00 | long $00000000,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 -21C8(0358) 00 00 18 3C | -21CC(0359) 55 2A 55 2A | -21D0(035A) 3E 36 36 00 | -21D4(035B) 0E 06 06 00 | -21D8(035C) 06 06 1C 00 | -21DC(035D) 06 06 1E 00 | -21E0(035E) 66 66 3C 00 | -21E4(035F) 18 18 7E 18 | long $187e1818,$0066767e,$00183c24,$20272424,$203f0000,$04fc0000,$04e42424,$00e72424 -21E8(0360) 7E 76 66 00 | -21EC(0361) 24 3C 18 00 | -21F0(0362) 24 24 27 20 | -21F4(0363) 00 00 3F 20 | -21F8(0364) 00 00 FC 04 | -21FC(0365) 24 24 E4 04 | -2200(0366) 24 24 E7 00 | -2204(0367) 00 00 00 00 | long $00000000,$0000ff00,$ff000000,$00000000,$00000000,$04e42424,$20272424,$00e72424 -2208(0368) 00 FF 00 00 | -220C(0369) 00 00 00 FF | -2210(036A) 00 00 00 00 | -2214(036B) 00 00 00 00 | -2218(036C) 24 24 E4 04 | -221C(036D) 24 24 27 20 | -2220(036E) 24 24 E7 00 | -2224(036F) 00 00 FF 00 | long $00ff0000,$24242424,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 -2228(0370) 24 24 24 24 | -222C(0371) 30 0C 06 0C | -2230(0372) 0C 30 60 30 | -2234(0373) 00 00 7E 66 | -2238(0374) 30 30 7E 18 | -223C(0375) 6C 0C 0C 3E | -2240(0376) 00 00 18 18 | -2244(0377) 00 00 00 00 | long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 -2248(0378) 18 18 18 18 | -224C(0379) 36 36 00 00 | -2250(037A) 24 7E 7E 24 | -2254(037B) 3C 5A 1A 3C | -2258(037C) 6A 2E 30 18 | -225C(037D) 36 36 36 1C | -2260(037E) 18 18 18 00 | -2264(037F) 18 18 0C 0C | long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 -2268(0380) 18 18 30 30 | -226C(0381) 00 24 18 7E | -2270(0382) 00 18 18 7E | -2274(0383) 00 00 00 00 | -2278(0384) 00 00 00 00 | -227C(0385) 00 00 00 00 | -2280(0386) 60 30 30 18 | -2284(0387) 24 66 66 66 | long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 -2288(0388) 1C 1A 18 18 | -228C(0389) 66 66 60 38 | -2290(038A) 60 30 18 3C | -2294(038B) 70 78 6C 66 | -2298(038C) 06 06 3E 66 | -229C(038D) 66 06 06 3E | -22A0(038E) 60 60 30 30 | -22A4(038F) 66 66 66 3C | long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 -22A8(0390) 66 66 66 7C | -22AC(0391) 00 18 3C 18 | -22B0(0392) 00 18 3C 18 | -22B4(0393) 30 18 0C 06 | -22B8(0394) 00 00 7E 00 | -22BC(0395) 0C 18 30 60 | -22C0(0396) 66 66 60 38 | -22C4(0397) 66 66 76 76 | long $76766666,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 -22C8(0398) 66 66 66 7E | -22CC(0399) 66 66 66 3E | -22D0(039A) 66 06 06 06 | -22D4(039B) 66 66 66 66 | -22D8(039C) 06 06 06 3E | -22DC(039D) 06 06 06 3E | -22E0(039E) 66 06 06 76 | -22E4(039F) 66 66 66 7E | long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 -22E8(03A0) 18 18 18 18 | -22EC(03A1) 60 60 60 60 | -22F0(03A2) 66 36 1E 0E | -22F4(03A3) 06 06 06 06 | -22F8(03A4) 66 7E 7E 66 | -22FC(03A5) 66 6E 6E 7E | -2300(03A6) 66 66 66 66 | -2304(03A7) 66 66 66 3E | long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 -2308(03A8) 66 66 66 66 | -230C(03A9) 66 66 66 3E | -2310(03AA) 66 06 06 3C | -2314(03AB) 18 18 18 18 | -2318(03AC) 66 66 66 66 | -231C(03AD) 66 66 24 24 | -2320(03AE) 66 66 66 66 | -2324(03AF) 66 24 3C 18 | long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 -2328(03B0) 66 3C 3C 18 | -232C(03B1) 60 60 30 18 | -2330(03B2) 0C 0C 0C 0C | -2334(03B3) 06 0C 0C 18 | -2338(03B4) 30 30 30 30 | -233C(03B5) 3C 66 42 00 | -2340(03B6) 00 00 00 00 | -2344(03B7) 30 00 00 00 | long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 -2348(03B8) 00 00 3C 60 | -234C(03B9) 06 06 3E 66 | -2350(03BA) 00 00 3C 66 | -2354(03BB) 60 60 7C 66 | -2358(03BC) 00 00 3C 66 | -235C(03BD) 6C 0C 0C 1E | -2360(03BE) 00 00 5C 66 | -2364(03BF) 06 06 3E 66 | long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 -2368(03C0) 18 00 1C 18 | -236C(03C1) 60 00 60 60 | -2370(03C2) 06 06 66 36 | -2374(03C3) 18 18 18 18 | -2378(03C4) 00 00 6A FE | -237C(03C5) 00 00 3E 66 | -2380(03C6) 00 00 3C 66 | -2384(03C7) 00 00 3E 66 | long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 -2388(03C8) 00 00 7C 66 | -238C(03C9) 00 00 3E 66 | -2390(03CA) 00 00 3C 66 | -2394(03CB) 0C 0C 3E 0C | -2398(03CC) 00 00 66 66 | -239C(03CD) 00 00 66 66 | -23A0(03CE) 00 00 66 66 | -23A4(03CF) 00 00 66 66 | long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 -23A8(03D0) 00 00 66 66 | -23AC(03D1) 00 00 7E 60 | -23B0(03D2) 0C 0C 18 0C | -23B4(03D3) 18 18 18 18 | -23B8(03D4) 30 30 18 30 | -23BC(03D5) 7E 32 00 00 | -23C0(03D6) 55 AA 55 AA | -23C4(03D7) 82 00 82 82 | long $82820082,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 -23C8(03D8) 7E 3C 18 00 | -23CC(03D9) 55 2A 55 2A | -23D0(03DA) 78 30 30 30 | -23D4(03DB) 78 18 38 18 | -23D8(03DC) 38 58 38 58 | -23DC(03DD) 78 18 38 18 | -23E0(03DE) 00 00 00 00 | -23E4(03DF) 18 00 7E 00 | long $007e0018,$18181818,$30303078,$0000001f,$1818181f,$181818f8,$000000f8,$181818ff -23E8(03E0) 18 18 18 18 | -23EC(03E1) 78 30 30 30 | -23F0(03E2) 1F 00 00 00 | -23F4(03E3) 1F 18 18 18 | -23F8(03E4) F8 18 18 18 | -23FC(03E5) F8 00 00 00 | -2400(03E6) FF 18 18 18 | -2404(03E7) 00 00 00 00 | long $00000000,$00000000,$0000ffff,$ff000000,$00000000,$181818f8,$1818181f,$000000ff -2408(03E8) 00 00 00 00 | -240C(03E9) FF FF 00 00 | -2410(03EA) 00 00 00 FF | -2414(03EB) 00 00 00 00 | -2418(03EC) F8 18 18 18 | -241C(03ED) 1F 18 18 18 | -2420(03EE) FF 00 00 00 | -2424(03EF) FF 18 18 18 | long $181818ff,$18181818,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 -2428(03F0) 18 18 18 18 | -242C(03F1) 30 60 00 7E | -2430(03F2) 0C 06 00 7E | -2434(03F3) 66 66 66 66 | -2438(03F4) 18 7E 0C 0C | -243C(03F5) 0C 0C 6C 3A | -2440(03F6) 00 00 00 00 | -2444(03F7) 00 00 00 00 | long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 -2448(03F8) 18 00 18 18 | -244C(03F9) 00 00 00 00 | -2450(03FA) 7E 7E 24 24 | -2454(03FB) 58 5A 3C 18 | -2458(03FC) 0C 74 56 72 | -245C(03FD) 56 76 36 5C | -2460(03FE) 00 00 00 00 | -2464(03FF) 0C 18 18 30 | long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c -2468(0400) 30 18 18 0C | -246C(0401) 7E 18 24 00 | -2470(0402) 7E 18 18 00 | -2474(0403) 00 38 38 18 | -2478(0404) 7E 00 00 00 | -247C(0405) 00 00 18 3C | -2480(0406) 0C 0C 06 06 | -2484(0407) 66 66 24 18 | long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 -2488(0408) 18 18 18 7E | -248C(0409) 0C 06 06 7E | -2490(040A) 60 60 66 3C | -2494(040B) 66 7E 60 60 | -2498(040C) 60 60 66 3C | -249C(040D) 66 66 66 3C | -24A0(040E) 18 18 0C 0C | -24A4(040F) 66 66 66 3C | long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 -24A8(0410) 60 60 66 3C | -24AC(0411) 00 00 18 3C | -24B0(0412) 00 38 38 18 | -24B4(0413) 0C 18 30 60 | -24B8(0414) 00 7E 00 00 | -24BC(0415) 30 18 0C 06 | -24C0(0416) 18 00 18 18 | -24C4(0417) 7A 02 62 3C | long $3c62027a,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 -24C8(0418) 66 66 66 66 | -24CC(0419) 66 66 66 3E | -24D0(041A) 06 06 66 3C | -24D4(041B) 66 66 66 3E | -24D8(041C) 06 06 06 7E | -24DC(041D) 06 06 06 06 | -24E0(041E) 66 66 66 7C | -24E4(041F) 66 66 66 66 | long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 -24E8(0420) 18 18 18 7E | -24EC(0421) 60 60 66 3C | -24F0(0422) 1E 36 66 46 | -24F4(0423) 06 06 06 7E | -24F8(0424) 66 66 66 66 | -24FC(0425) 76 76 66 66 | -2500(0426) 66 66 66 3C | -2504(0427) 06 06 06 06 | long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e -2508(0428) 66 6E 76 3C | -250C(0429) 1E 36 66 46 | -2510(042A) 60 60 66 3C | -2514(042B) 18 18 18 18 | -2518(042C) 66 66 66 3C | -251C(042D) 3C 18 18 18 | -2520(042E) 7E 7E 66 42 | -2524(042F) 3C 24 66 42 | long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 -2528(0430) 18 18 18 18 | -252C(0431) 0C 06 06 7E | -2530(0432) 0C 0C 0C 3C | -2534(0433) 30 30 60 60 | -2538(0434) 30 30 30 3C | -253C(0435) 00 00 00 00 | -2540(0436) 00 00 00 FE | -2544(0437) 00 00 00 00 | long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 -2548(0438) 7C 66 66 7C | -254C(0439) 66 66 66 3E | -2550(043A) 06 06 66 3C | -2554(043B) 66 66 66 7C | -2558(043C) 7E 06 66 3C | -255C(043D) 0C 0C 0C 0C | -2560(043E) 66 3C 06 3C | -2564(043F) 66 66 66 66 | long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 -2568(0440) 18 18 18 7E | -256C(0441) 60 60 60 60 | -2570(0442) 1E 1E 36 66 | -2574(0443) 18 18 18 7E | -2578(0444) D6 D6 C6 C6 | -257C(0445) 66 66 66 66 | -2580(0446) 66 66 66 3C | -2584(0447) 66 66 3E 06 | long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 -2588(0448) 66 66 7C 60 | -258C(0449) 06 06 06 06 | -2590(044A) 0C 30 66 3C | -2594(044B) 0C 0C 6C 38 | -2598(044C) 66 66 66 7C | -259C(044D) 66 3C 3C 18 | -25A0(044E) 66 7E 7E 24 | -25A4(044F) 3C 3C 66 66 | long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 -25A8(0450) 66 66 7C 60 | -25AC(0451) 30 0C 06 7E | -25B0(0452) 18 0C 0C 38 | -25B4(0453) 18 18 18 18 | -25B8(0454) 18 30 30 1C | -25BC(0455) 00 00 00 00 | -25C0(0456) 55 AA 55 AA | -25C4(0457) 00 00 00 00 | long $00000000,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 -25C8(0458) 7E 3C 18 00 | -25CC(0459) 55 2A 55 2A | -25D0(045A) 78 30 30 30 | -25D4(045B) 78 18 38 18 | -25D8(045C) 38 58 38 58 | -25DC(045D) 78 18 38 18 | -25E0(045E) 00 00 00 00 | -25E4(045F) 18 00 7E 00 | long $007e0018,$18181818,$30303078,$00003f20,$24242720,$2424e404,$0000fc04,$2424e700 -25E8(0460) 18 18 18 18 | -25EC(0461) 78 30 30 30 | -25F0(0462) 20 3F 00 00 | -25F4(0463) 20 27 24 24 | -25F8(0464) 04 E4 24 24 | -25FC(0465) 04 FC 00 00 | -2600(0466) 00 E7 24 24 | -2604(0467) 00 00 00 00 | long $00000000,$00000000,$0000ff00,$00ff0000,$00000000,$2424e404,$24242720,$0000ff00 -2608(0468) 00 00 00 00 | -260C(0469) 00 FF 00 00 | -2610(046A) 00 00 FF 00 | -2614(046B) 00 00 00 00 | -2618(046C) 04 E4 24 24 | -261C(046D) 20 27 24 24 | -2620(046E) 00 FF 00 00 | -2624(046F) 00 E7 24 24 | long $2424e700,$24242424,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 -2628(0470) 24 24 24 24 | -262C(0471) 30 60 00 7E | -2630(0472) 0C 06 00 7E | -2634(0473) 66 66 66 66 | -2638(0474) 18 7E 0C 0C | -263C(0475) 0C 0C 6C 3A | -2640(0476) 00 00 00 00 | -2644(0477) 00 00 00 00 | long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 -2648(0478) 18 00 18 18 | -264C(0479) 00 00 00 00 | -2650(047A) 7E 7E 24 24 | -2654(047B) 58 5A 3C 18 | -2658(047C) 0C 74 56 72 | -265C(047D) 56 76 36 5C | -2660(047E) 00 00 00 00 | -2664(047F) 0C 18 18 30 | long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c -2668(0480) 30 18 18 0C | -266C(0481) 7E 18 24 00 | -2670(0482) 7E 18 18 00 | -2674(0483) 00 38 38 18 | -2678(0484) 7E 00 00 00 | -267C(0485) 00 00 18 3C | -2680(0486) 0C 0C 06 06 | -2684(0487) 66 66 24 18 | long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 -2688(0488) 18 18 18 7E | -268C(0489) 0C 06 06 7E | -2690(048A) 60 60 66 3C | -2694(048B) 66 7E 60 60 | -2698(048C) 60 60 66 3C | -269C(048D) 66 66 66 3C | -26A0(048E) 18 18 0C 0C | -26A4(048F) 66 66 66 3C | long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 -26A8(0490) 60 60 66 3C | -26AC(0491) 00 00 18 3C | -26B0(0492) 00 38 38 18 | -26B4(0493) 0C 18 30 60 | -26B8(0494) 00 7E 00 00 | -26BC(0495) 30 18 0C 06 | -26C0(0496) 18 00 18 18 | -26C4(0497) 76 06 66 3C | long $3c660676,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 -26C8(0498) 66 66 66 66 | -26CC(0499) 66 66 66 3E | -26D0(049A) 06 06 66 3C | -26D4(049B) 66 66 66 3E | -26D8(049C) 06 06 06 7E | -26DC(049D) 06 06 06 06 | -26E0(049E) 66 66 66 7C | -26E4(049F) 66 66 66 66 | long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 -26E8(04A0) 18 18 18 7E | -26EC(04A1) 60 60 66 3C | -26F0(04A2) 1E 36 66 46 | -26F4(04A3) 06 06 06 7E | -26F8(04A4) 66 66 66 66 | -26FC(04A5) 76 76 66 66 | -2700(04A6) 66 66 66 3C | -2704(04A7) 06 06 06 06 | long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e -2708(04A8) 66 6E 76 3C | -270C(04A9) 1E 36 66 46 | -2710(04AA) 60 60 66 3C | -2714(04AB) 18 18 18 18 | -2718(04AC) 66 66 66 3C | -271C(04AD) 3C 18 18 18 | -2720(04AE) 7E 7E 66 42 | -2724(04AF) 3C 24 66 42 | long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 -2728(04B0) 18 18 18 18 | -272C(04B1) 0C 06 06 7E | -2730(04B2) 0C 0C 0C 3C | -2734(04B3) 30 30 60 60 | -2738(04B4) 30 30 30 3C | -273C(04B5) 00 00 00 00 | -2740(04B6) 00 00 00 FE | -2744(04B7) 00 00 00 00 | long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 -2748(04B8) 7C 66 66 7C | -274C(04B9) 66 66 66 3E | -2750(04BA) 06 06 66 3C | -2754(04BB) 66 66 66 7C | -2758(04BC) 7E 06 66 3C | -275C(04BD) 0C 0C 0C 0C | -2760(04BE) 66 3C 06 3C | -2764(04BF) 66 66 66 66 | long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 -2768(04C0) 18 18 18 7E | -276C(04C1) 60 60 60 60 | -2770(04C2) 1E 1E 36 66 | -2774(04C3) 18 18 18 7E | -2778(04C4) D6 D6 C6 C6 | -277C(04C5) 66 66 66 66 | -2780(04C6) 66 66 66 3C | -2784(04C7) 66 66 3E 06 | long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 -2788(04C8) 66 66 7C 60 | -278C(04C9) 06 06 06 06 | -2790(04CA) 0C 30 66 3C | -2794(04CB) 0C 0C 6C 38 | -2798(04CC) 66 66 66 7C | -279C(04CD) 66 3C 3C 18 | -27A0(04CE) 66 7E 7E 24 | -27A4(04CF) 3C 3C 66 66 | long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 -27A8(04D0) 66 66 7C 60 | -27AC(04D1) 30 0C 06 7E | -27B0(04D2) 18 0C 0C 38 | -27B4(04D3) 18 18 18 18 | -27B8(04D4) 18 30 30 1C | -27BC(04D5) 00 00 00 00 | -27C0(04D6) 55 AA 55 AA | -27C4(04D7) 00 82 BA 00 | long $00ba8200,$00000000,$00002a55,$00000030,$00000018,$00000058,$00000018,$00000000 -27C8(04D8) 00 00 00 00 | -27CC(04D9) 55 2A 00 00 | -27D0(04DA) 30 00 00 00 | -27D4(04DB) 18 00 00 00 | -27D8(04DC) 58 00 00 00 | -27DC(04DD) 18 00 00 00 | -27E0(04DE) 00 00 00 00 | -27E4(04DF) 00 00 00 00 | long $00000000,$00000078,$00000030,$00000000,$18181818,$18181818,$00000000,$18181818 -27E8(04E0) 78 00 00 00 | -27EC(04E1) 30 00 00 00 | -27F0(04E2) 00 00 00 00 | -27F4(04E3) 18 18 18 18 | -27F8(04E4) 18 18 18 18 | -27FC(04E5) 00 00 00 00 | -2800(04E6) 18 18 18 18 | -2804(04E7) 00 00 00 00 | long $00000000,$00000000,$00000000,$000000ff,$ffff0000,$18181818,$18181818,$00000000 -2808(04E8) 00 00 00 00 | -280C(04E9) 00 00 00 00 | -2810(04EA) FF 00 00 00 | -2814(04EB) 00 00 FF FF | -2818(04EC) 18 18 18 18 | -281C(04ED) 18 18 18 18 | -2820(04EE) 00 00 00 00 | -2824(04EF) 18 18 18 18 | long $18181818,$18181818,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2828(04F0) 18 18 18 18 | -282C(04F1) 00 00 00 00 | -2830(04F2) 00 00 00 00 | -2834(04F3) 00 00 00 00 | -2838(04F4) 00 00 00 00 | -283C(04F5) 00 00 00 00 | -2840(04F6) 00 00 00 00 | -2844(04F7) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2848(04F8) 00 00 00 00 | -284C(04F9) 00 00 00 00 | -2850(04FA) 00 00 00 00 | -2854(04FB) 00 00 00 00 | -2858(04FC) 00 00 00 00 | -285C(04FD) 00 00 00 00 | -2860(04FE) 00 00 00 00 | -2864(04FF) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$0000000c,$00000000,$00000018,$00000000 -2868(0500) 00 00 00 00 | -286C(0501) 00 00 00 00 | -2870(0502) 00 00 00 00 | -2874(0503) 0C 00 00 00 | -2878(0504) 00 00 00 00 | -287C(0505) 18 00 00 00 | -2880(0506) 00 00 00 00 | -2884(0507) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2888(0508) 00 00 00 00 | -288C(0509) 00 00 00 00 | -2890(050A) 00 00 00 00 | -2894(050B) 00 00 00 00 | -2898(050C) 00 00 00 00 | -289C(050D) 00 00 00 00 | -28A0(050E) 00 00 00 00 | -28A4(050F) 00 00 00 00 | long $00000000,$00000000,$00000018,$0000000c,$00000000,$00000000,$00000000,$00000000 -28A8(0510) 00 00 00 00 | -28AC(0511) 18 00 00 00 | -28B0(0512) 0C 00 00 00 | -28B4(0513) 00 00 00 00 | -28B8(0514) 00 00 00 00 | -28BC(0515) 00 00 00 00 | -28C0(0516) 00 00 00 00 | -28C4(0517) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -28C8(0518) 00 00 00 00 | -28CC(0519) 00 00 00 00 | -28D0(051A) 00 00 00 00 | -28D4(051B) 00 00 00 00 | -28D8(051C) 00 00 00 00 | -28DC(051D) 00 00 00 00 | -28E0(051E) 00 00 00 00 | -28E4(051F) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -28E8(0520) 00 00 00 00 | -28EC(0521) 00 00 00 00 | -28F0(0522) 00 00 00 00 | -28F4(0523) 00 00 00 00 | -28F8(0524) 00 00 00 00 | -28FC(0525) 00 00 00 00 | -2900(0526) 00 00 00 00 | -2904(0527) 00 00 00 00 | long $00000000,$00000060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2908(0528) 60 00 00 00 | -290C(0529) 00 00 00 00 | -2910(052A) 00 00 00 00 | -2914(052B) 00 00 00 00 | -2918(052C) 00 00 00 00 | -291C(052D) 00 00 00 00 | -2920(052E) 00 00 00 00 | -2924(052F) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$000000fe -2928(0530) 00 00 00 00 | -292C(0531) 00 00 00 00 | -2930(0532) 00 00 00 00 | -2934(0533) 00 00 00 00 | -2938(0534) 00 00 00 00 | -293C(0535) 00 00 00 00 | -2940(0536) FE 00 00 00 | -2944(0537) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00003c66 -2948(0538) 00 00 00 00 | -294C(0539) 00 00 00 00 | -2950(053A) 00 00 00 00 | -2954(053B) 00 00 00 00 | -2958(053C) 00 00 00 00 | -295C(053D) 00 00 00 00 | -2960(053E) 66 3C 00 00 | -2964(053F) 00 00 00 00 | long $00000000,$00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000 -2968(0540) 00 00 00 00 | -296C(0541) 66 3C 00 00 | -2970(0542) 00 00 00 00 | -2974(0543) 00 00 00 00 | -2978(0544) 00 00 00 00 | -297C(0545) 00 00 00 00 | -2980(0546) 00 00 00 00 | -2984(0547) 06 06 00 00 | long $00000606,$00006060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2988(0548) 60 60 00 00 | -298C(0549) 00 00 00 00 | -2990(054A) 00 00 00 00 | -2994(054B) 00 00 00 00 | -2998(054C) 00 00 00 00 | -299C(054D) 00 00 00 00 | -29A0(054E) 00 00 00 00 | -29A4(054F) 00 00 00 00 | long $00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000,$aa55aa55 -29A8(0550) 66 3C 00 00 | -29AC(0551) 00 00 00 00 | -29B0(0552) 00 00 00 00 | -29B4(0553) 00 00 00 00 | -29B8(0554) 00 00 00 00 | -29BC(0555) 00 00 00 00 | -29C0(0556) 55 AA 55 AA | -29C4(0557) 00 00 00 FF | long $ff000000,$ff000000,$ff002a55,$ff000030,$ff000018,$ff000058,$ff000018,$ff000000 -29C8(0558) 00 00 00 FF | -29CC(0559) 55 2A 00 FF | -29D0(055A) 30 00 00 FF | -29D4(055B) 18 00 00 FF | -29D8(055C) 58 00 00 FF | -29DC(055D) 18 00 00 FF | -29E0(055E) 00 00 00 FF | -29E4(055F) 00 00 00 FF | long $ff000000,$ff000078,$ff000030,$00000000,$24242424,$24242424,$00000000,$24242424 -29E8(0560) 78 00 00 FF | -29EC(0561) 30 00 00 FF | -29F0(0562) 00 00 00 00 | -29F4(0563) 24 24 24 24 | -29F8(0564) 24 24 24 24 | -29FC(0565) 00 00 00 00 | -2A00(0566) 24 24 24 24 | -2A04(0567) 00 00 00 00 | long $00000000,$00000000,$00000000,$000000ff,$ff00ff00,$24242424,$24242424,$00000000 -2A08(0568) 00 00 00 00 | -2A0C(0569) 00 00 00 00 | -2A10(056A) FF 00 00 00 | -2A14(056B) 00 FF 00 FF | -2A18(056C) 24 24 24 24 | -2A1C(056D) 24 24 24 24 | -2A20(056E) 00 00 00 00 | -2A24(056F) 24 24 24 24 | long $24242424,$24242424,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2A28(0570) 24 24 24 24 | -2A2C(0571) 00 00 00 FF | -2A30(0572) 00 00 00 FF | -2A34(0573) 00 00 00 FF | -2A38(0574) 00 00 00 FF | -2A3C(0575) 00 00 00 FF | -2A40(0576) 00 00 00 FF | -2A44(0577) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2A48(0578) 00 00 00 FF | -2A4C(0579) 00 00 00 FF | -2A50(057A) 00 00 00 FF | -2A54(057B) 00 00 00 FF | -2A58(057C) 00 00 00 FF | -2A5C(057D) 00 00 00 FF | -2A60(057E) 00 00 00 FF | -2A64(057F) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff00000c,$ff000000,$ff000018,$ff000000 -2A68(0580) 00 00 00 FF | -2A6C(0581) 00 00 00 FF | -2A70(0582) 00 00 00 FF | -2A74(0583) 0C 00 00 FF | -2A78(0584) 00 00 00 FF | -2A7C(0585) 18 00 00 FF | -2A80(0586) 00 00 00 FF | -2A84(0587) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2A88(0588) 00 00 00 FF | -2A8C(0589) 00 00 00 FF | -2A90(058A) 00 00 00 FF | -2A94(058B) 00 00 00 FF | -2A98(058C) 00 00 00 FF | -2A9C(058D) 00 00 00 FF | -2AA0(058E) 00 00 00 FF | -2AA4(058F) 00 00 00 FF | long $ff000000,$ff000000,$ff000018,$ff00000c,$ff000000,$ff000000,$ff000000,$ff000000 -2AA8(0590) 00 00 00 FF | -2AAC(0591) 18 00 00 FF | -2AB0(0592) 0C 00 00 FF | -2AB4(0593) 00 00 00 FF | -2AB8(0594) 00 00 00 FF | -2ABC(0595) 00 00 00 FF | -2AC0(0596) 00 00 00 FF | -2AC4(0597) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2AC8(0598) 00 00 00 FF | -2ACC(0599) 00 00 00 FF | -2AD0(059A) 00 00 00 FF | -2AD4(059B) 00 00 00 FF | -2AD8(059C) 00 00 00 FF | -2ADC(059D) 00 00 00 FF | -2AE0(059E) 00 00 00 FF | -2AE4(059F) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2AE8(05A0) 00 00 00 FF | -2AEC(05A1) 00 00 00 FF | -2AF0(05A2) 00 00 00 FF | -2AF4(05A3) 00 00 00 FF | -2AF8(05A4) 00 00 00 FF | -2AFC(05A5) 00 00 00 FF | -2B00(05A6) 00 00 00 FF | -2B04(05A7) 00 00 00 FF | long $ff000000,$ff000060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2B08(05A8) 60 00 00 FF | -2B0C(05A9) 00 00 00 FF | -2B10(05AA) 00 00 00 FF | -2B14(05AB) 00 00 00 FF | -2B18(05AC) 00 00 00 FF | -2B1C(05AD) 00 00 00 FF | -2B20(05AE) 00 00 00 FF | -2B24(05AF) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff0000fe -2B28(05B0) 00 00 00 FF | -2B2C(05B1) 00 00 00 FF | -2B30(05B2) 00 00 00 FF | -2B34(05B3) 00 00 00 FF | -2B38(05B4) 00 00 00 FF | -2B3C(05B5) 00 00 00 FF | -2B40(05B6) FE 00 00 FF | -2B44(05B7) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff003c66 -2B48(05B8) 00 00 00 FF | -2B4C(05B9) 00 00 00 FF | -2B50(05BA) 00 00 00 FF | -2B54(05BB) 00 00 00 FF | -2B58(05BC) 00 00 00 FF | -2B5C(05BD) 00 00 00 FF | -2B60(05BE) 66 3C 00 FF | -2B64(05BF) 00 00 00 FF | long $ff000000,$ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2B68(05C0) 00 00 00 FF | -2B6C(05C1) 66 3C 00 FF | -2B70(05C2) 00 00 00 FF | -2B74(05C3) 00 00 00 FF | -2B78(05C4) 00 00 00 FF | -2B7C(05C5) 00 00 00 FF | -2B80(05C6) 00 00 00 FF | -2B84(05C7) 06 06 00 FF | long $ff000606,$ff006060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2B88(05C8) 60 60 00 FF | -2B8C(05C9) 00 00 00 FF | -2B90(05CA) 00 00 00 FF | -2B94(05CB) 00 00 00 FF | -2B98(05CC) 00 00 00 FF | -2B9C(05CD) 00 00 00 FF | -2BA0(05CE) 00 00 00 FF | -2BA4(05CF) 00 00 00 FF | long $ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff55aa55 -2BA8(05D0) 66 3C 00 FF | -2BAC(05D1) 00 00 00 FF | -2BB0(05D2) 00 00 00 FF | -2BB4(05D3) 00 00 00 FF | -2BB8(05D4) 00 00 00 FF | -2BBC(05D5) 00 00 00 FF | -2BC0(05D6) 55 AA 55 FF | -|===========================================================================| -|===========================================================================| -Spin Block start with 4 Parameters and 2 Extra Stack Longs. Method 1 -PUB start(BasePin, ScreenPtr, CursorPtr, SyncPtr) : okay | i, j - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - BasePin -Local Parameter DBASE:0008 - ScreenPtr -Local Parameter DBASE:000C - CursorPtr -Local Parameter DBASE:0010 - SyncPtr -Local Variable DBASE:0014 - i -Local Variable DBASE:0018 - j -|===========================================================================| -85 stop -Addr : 2BC4: 01 : Drop Anchor -Addr : 2BC5: 05 02 : Call Sub 2 -88 reg_vcfg := $200000FF + (BasePin & %111000) << 6 -Addr : 2BC7: 3B 20 00 00 FF : Constant 4 Bytes - 20 00 00 FF -Addr : 2BCC: 64 : Variable Operation Local Offset - 1 Read -Addr : 2BCD: 38 38 : Constant 1 Bytes - 38 -Addr : 2BCF: E8 : Math Op & -Addr : 2BD0: 38 06 : Constant 1 Bytes - 06 -Addr : 2BD2: E3 : Math Op << -Addr : 2BD3: EC : Math Op + -Addr : 2BD4: C5 80 98 : Memory Op Long PBASE + WRITE Address = 0098 -89 i := $FF << (BasePin & %011000) -Addr : 2BD7: 37 27 : Constant Mask Y=39 Decrement 000000FF -Addr : 2BD9: 64 : Variable Operation Local Offset - 1 Read -Addr : 2BDA: 38 18 : Constant 1 Bytes - 18 -Addr : 2BDC: E8 : Math Op & -Addr : 2BDD: E3 : Math Op << -Addr : 2BDE: 75 : Variable Operation Local Offset - 5 Write -90 j := BasePin & %100000 == 0 -Addr : 2BDF: 64 : Variable Operation Local Offset - 1 Read -Addr : 2BE0: 37 04 : Constant Mask Y=4 00000020 -Addr : 2BE2: E8 : Math Op & -Addr : 2BE3: 35 : Constant 1 $00000000 -Addr : 2BE4: FC : Math Op == -Addr : 2BE5: 79 : Variable Operation Local Offset - 6 Write -91 reg_dira := i & j -Addr : 2BE6: 74 : Variable Operation Local Offset - 5 Read -Addr : 2BE7: 78 : Variable Operation Local Offset - 6 Read -Addr : 2BE8: E8 : Math Op & -Addr : 2BE9: C5 80 90 : Memory Op Long PBASE + WRITE Address = 0090 -92 reg_dirb := i & !j -Addr : 2BEC: 74 : Variable Operation Local Offset - 5 Read -Addr : 2BED: 78 : Variable Operation Local Offset - 6 Read -Addr : 2BEE: E7 : Math Op ! -Addr : 2BEF: E8 : Math Op & -Addr : 2BF0: C5 80 94 : Memory Op Long PBASE + WRITE Address = 0094 -95 sync_cnt := cnt + $10000 -Addr : 2BF3: 3F 91 : Register op CNT Read -Addr : 2BF5: 37 0F : Constant Mask Y=15 00010000 -Addr : 2BF7: EC : Math Op + -Addr : 2BF8: C5 80 9C : Memory Op Long PBASE + WRITE Address = 009C -98 longmove(@screen_base, @ScreenPtr, 2) -Addr : 2BFB: C7 82 10 : Memory Op Long PBASE + ADDRESS Address = 0210 -Addr : 2BFE: 6B : Variable Operation Local Offset - 2 Address -Addr : 2BFF: 37 00 : Constant Mask Y=0 00000002 -Addr : 2C01: 1E : LongMove(To, From, Count) -99 font_base := @font -Addr : 2C02: C7 82 CC : Memory Op Long PBASE + ADDRESS Address = 02CC -Addr : 2C05: C5 82 18 : Memory Op Long PBASE + WRITE Address = 0218 -102 vf_lines.byte := vf -Addr : 2C08: 38 14 : Constant 1 Bytes - 14 -Addr : 2C0A: 85 81 D8 : Memory Op Byte PBASE + WRITE Address = 01D8 -103 vb_lines.byte := vb -Addr : 2C0D: 38 11 : Constant 1 Bytes - 11 -Addr : 2C0F: 85 80 A8 : Memory Op Byte PBASE + WRITE Address = 00A8 -104 font_part := 1 -Addr : 2C12: 36 : Constant 2 $00000001 -Addr : 2C13: C5 82 1C : Memory Op Long PBASE + WRITE Address = 021C -105 cog[1] := cognew(@d0, SyncPtr) + 1 -Addr : 2C16: 34 : Constant 0 $FFFFFFFF -Addr : 2C17: C7 0C : Memory Op Long PBASE + ADDRESS Address = 000C -Addr : 2C19: 70 : Variable Operation Local Offset - 4 Read -Addr : 2C1A: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 2C1B: 36 : Constant 2 $00000001 -Addr : 2C1C: EC : Math Op + -Addr : 2C1D: 36 : Constant 2 $00000001 -Addr : 2C1E: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -108 waitcnt($2000 + cnt) -Addr : 2C20: 37 0C : Constant Mask Y=12 00002000 -Addr : 2C22: 3F 91 : Register op CNT Read -Addr : 2C24: EC : Math Op + -Addr : 2C25: 23 : WaitCnt(count) -111 vf_lines.byte := vf+4 -Addr : 2C26: 38 14 : Constant 1 Bytes - 14 -Addr : 2C28: 37 01 : Constant Mask Y=1 00000004 -Addr : 2C2A: EC : Math Op + -Addr : 2C2B: 85 81 D8 : Memory Op Byte PBASE + WRITE Address = 01D8 -112 vb_lines.byte := vb-4 -Addr : 2C2E: 38 11 : Constant 1 Bytes - 11 -Addr : 2C30: 37 01 : Constant Mask Y=1 00000004 -Addr : 2C32: ED : Math Op - -Addr : 2C33: 85 80 A8 : Memory Op Byte PBASE + WRITE Address = 00A8 -113 font_part := 0 -Addr : 2C36: 35 : Constant 1 $00000000 -Addr : 2C37: C5 82 1C : Memory Op Long PBASE + WRITE Address = 021C -114 cog[0] := cognew(@d0, SyncPtr) + 1 -Addr : 2C3A: 34 : Constant 0 $FFFFFFFF -Addr : 2C3B: C7 0C : Memory Op Long PBASE + ADDRESS Address = 000C -Addr : 2C3D: 70 : Variable Operation Local Offset - 4 Read -Addr : 2C3E: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 2C3F: 36 : Constant 2 $00000001 -Addr : 2C40: EC : Math Op + -Addr : 2C41: 35 : Constant 1 $00000000 -Addr : 2C42: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -117 if cog[0] and cog[1] -Addr : 2C44: 35 : Constant 1 $00000000 -Addr : 2C45: D8 00 : Memory Op Long VBASE + POP Index READ Address = 0000 -Addr : 2C47: 36 : Constant 2 $00000001 -Addr : 2C48: D8 00 : Memory Op Long VBASE + POP Index READ Address = 0000 -Addr : 2C4A: F0 : Math Op AND -Addr : 2C4B: JZ Label0008 -Addr : 2C4B: 0A 02 : jz Address = 2C4F 2 -119 return 0 -Addr : 2C4D: 35 : Constant 1 $00000000 -Addr : 2C4E: 33 : Return value -Addr : 2C4F: Label0008 -Addr : 2C4F: Label0009 -122 stop -Addr : 2C4F: 01 : Drop Anchor -Addr : 2C50: 05 02 : Call Sub 2 -Addr : 2C52: 32 : Return -|===========================================================================| -Spin Block stop with 0 Parameters and 1 Extra Stack Longs. Method 2 -PUB stop | i - -Local Parameter DBASE:0000 - Result -Local Variable DBASE:0004 - i -|===========================================================================| -129 repeat i from 0 to 1 -Addr : 2C53: 35 : Constant 1 $00000000 -Addr : 2C54: 65 : Variable Operation Local Offset - 1 Write -Addr : 2C55: Label0008 -Addr : 2C55: Label0009 -Addr : 2C55: 35 : Constant 1 $00000000 -Addr : 2C56: 36 : Constant 2 $00000001 -Addr : 2C57: Repeat i Step Label0008 -Addr : 2C57: 66 02 7B : Variable Operation Local Offset - 1 Assign Repeat-Var loop Address= 2C55 -5 -Addr : 2C5A: Label000A -130 if cog[i] -Addr : 2C5A: 64 : Variable Operation Local Offset - 1 Read -Addr : 2C5B: D8 00 : Memory Op Long VBASE + POP Index READ Address = 0000 -Addr : 2C5D: JZ Label000B -Addr : 2C5D: 0A 00 : jz Address = 2C5F 0 -Addr : 2C5F: Label000B -Addr : 2C5F: Label000C -131 cogstop(cog[i]~ - 1) -Addr : 2C5F: 64 : Variable Operation Local Offset - 1 Read -Addr : 2C60: DA 00 98 : Memory Op Long VBASE + POP Index ASSIGN Address = 0000 VAR~ Post-clear Push -Addr : 2C63: 36 : Constant 2 $00000001 -Addr : 2C64: ED : Math Op - -Addr : 2C65: 21 : CogStop(id) -Addr : 2C66: 32 : Return -|===========================================================================| -Object vt100 -Object Base is 2C68 -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0004 Variable cog -|===========================================================================| -Object DAT Blocks -|===========================================================================| -2C74(0000) | org 0 -2C74(0000) | entry -2C74(0000) F0 69 BC A0 | command_ptr mov t1, PAR -2C78(0001) 34 00 BC 08 | cmd rdlong command_ptr, t1 ' parameter 0 -2C7C(0002) 04 68 FC 80 | screen_ptr add t1, #4 -2C80(0003) 34 04 BC 08 | screen_end rdlong screen_ptr, t1 ' parameter 1 -2C84(0004) 04 68 FC 80 | cursor_ptr add t1, #4 -2C88(0005) 34 08 BC 08 | vsync_ptr rdlong cursor_ptr, t1 ' parameter 2 -2C8C(0006) 04 68 FC 80 | screen_w add t1, #4 -2C90(0007) 34 0A BC 08 | screen_w2 rdlong vsync_ptr, t1 ' parameter 3 -2C94(0008) 04 68 FC 80 | screen_h add t1, #4 -2C98(0009) 34 0C BC 08 | cur_ptr rdlong screen_w, t1 ' parameter 4 -2C9C(000A) 04 68 FC 80 | scroll_top add t1, #4 -2CA0(000B) 34 10 BC 08 | scroll_bot rdlong screen_h, t1 ' parameter 5 -2CA4(000C) 06 0E BC A0 | dst mov screen_w2, screen_w -2CA8(000D) 01 0E FC 28 | src shr screen_w2, #1 ' screen width / 2 -2CAC(000E) 06 68 BC A0 | end mov t1, screen_w -2CB0(000F) 08 6A BC A0 | data mov t2, screen_h -2CB4(0010) 79 FF FE 5C | cols call #mul16x16 -2CB8(0011) 35 06 BC A0 | rows mov screen_end, t2 ' result in t2 -2CBC(0012) 35 06 BC 80 | lmm_pc add screen_end, t2 ' * 2 -2CC0(0013) 02 06 BC 80 | cur_x_save add screen_end, screen_ptr -2CC4(0014) 00 14 FC A0 | cur_y_save mov scroll_top, #0 -2CC8(0015) 08 16 BC A0 | new_x_save mov scroll_bot, screen_h -2CCC(0016) F1 47 BC A0 | attr_save mov cur_delay, CNT -2CD0(0017) 45 00 7C 5C | jmp #startup -2CD4(0018) A8 32 00 00 | control_ptr long @@@control_table -2CD8(0019) E8 32 00 00 | csi_cmds_ptr long @@@csi_cmds -2CDC(001A) 20 00 20 00 | x00200020 long $00200020 -2CE0(001B) 5F 00 00 00 | cur_block long $5f -2CE4(001C) 00 00 00 00 | inverse long 0 -2CE8(001D) 00 00 00 00 | cur_x long 0 -2CEC(001E) 00 00 00 00 | new_x long 0 -2CF0(001F) 00 00 00 00 | cur_y long 0 -2CF4(0020) 00 00 00 00 | attr long 0 ' attribute mode -2CF8(0021) 24 00 00 00 | flags long flag_decom | flag_decawm -2CFC(0022) 00 00 00 00 | cur_char long 0 -2D00(0023) 00 00 00 00 | cur_delay long 0 -2D04(0024) 07 00 00 00 | fgcol long %0111 ' foreground color -2D08(0025) 00 00 00 00 | bgcol long %0000 ' background color -2D0C(0026) 00 07 00 00 | color long %00000111_00000000 ' composed fore- and background -2D10(0027) 00 00 00 00 | esc_mode long 0 -2D14(0028) 00 00 00 00 | csi_mode long 0 -2D18(0029) 00 00 00 00 | csi_argc long 0 -2D1C(002A) 00 00 00 00 | csi_argf long 0 -2D20(002B) 00 00 00 00 | csi_args long 0,0,0,0,0,0,0,0 -2D24(002C) 00 00 00 00 | -2D28(002D) 00 00 00 00 | -2D2C(002E) 00 00 00 00 | -2D30(002F) 00 00 00 00 | -2D34(0030) 00 00 00 00 | -2D38(0031) 00 00 00 00 | -2D3C(0032) 00 00 00 00 | -2D40(0033) 00 00 00 00 | question_mark long 0 -2D44(0034) 00 00 00 00 | t1 long 0 -2D48(0035) 00 00 00 00 | t2 long 0 -2D4C(0036) 00 00 00 00 | t3 long 0 -2D50(0037) | goto_xay -2D50(0037) 0A 3E BC 80 | add cur_y, scroll_top -2D54(0038) | validate_cursor -2D54(0038) 1D 3A BC A1 | mov cur_x, cur_x WC ' negative x? -2D58(0039) 00 3A F0 A0 | if_c mov cur_x, #0 ' yes, clip to 0 -2D5C(003A) 06 3A 3C 87 | cmp cur_x, screen_w WZ, WC -2D60(003B) 06 3A 8C A0 | if_ae mov cur_x, screen_w ' stay inside the boundaries -2D64(003C) 01 3A CC 84 | if_ae sub cur_x, #1 -2D68(003D) 1D 3C BC A0 | mov new_x, cur_x -2D6C(003E) 1F 3E BC A1 | mov cur_y, cur_y WC ' negative y? -2D70(003F) 00 3E F0 A0 | if_c mov cur_y, #0 ' yes, clip to 0 -2D74(0040) 08 3E 3C 87 | cmp cur_y, screen_h WZ, WC -2D78(0041) 08 3E 8C A0 | if_ae mov cur_y, screen_h ' stay inside the boundaries -2D7C(0042) 01 3E CC 84 | if_ae sub cur_y, #1 -2D80(0043) | cmdloop -2D80(0043) 00 02 FC A0 | mov cmd, #0 -2D84(0044) 00 02 3C 08 | wrlong cmd, command_ptr -2D88(0045) | startup -2D88(0045) 4C 08 7C EC | :loop tjz cursor_ptr, #:cursor ' skip if cursor_ptr is null -2D8C(0046) 04 3C 3C 00 | wrbyte new_x, cursor_ptr ' write the (new) cursor position -2D90(0047) 01 08 FC 80 | add cursor_ptr, #1 -2D94(0048) 04 3E 3C 00 | wrbyte cur_y, cursor_ptr ' and the cursor row, too -2D98(0049) 01 08 FC 84 | sub cursor_ptr, #1 -2D9C(004A) 5A C3 FE 5C | call #calc_cursor -2DA0(004B) 5B 00 7C 5C | jmp #:check_cmd -2DA4(004C) 23 68 BC A0 | :cursor mov t1, cur_delay ' software cursor -2DA8(004D) F1 69 BC 84 | sub t1, CNT -2DAC(004E) 00 68 7C C3 | cmps t1, #0 WZ, WC -2DB0(004F) 5B 00 4C 5C | if_ae jmp #:check_cmd -2DB4(0050) 00 68 FC 08 | rdlong t1, #0 ' get clkfreq -2DB8(0051) 02 68 FC 28 | shr t1, #2 ' / 4 -2DBC(0052) 34 46 BC 80 | add cur_delay, t1 ' next cursor flash event -2DC0(0053) 5A C3 FE 5C | call #calc_cursor -2DC4(0054) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC ' new_x beyond last column? -2DC8(0055) 5B 00 4C 5C | if_ae jmp #:check_cmd -2DCC(0056) 22 68 BC A2 | mov t1, cur_char WZ ' get saved character -2DD0(0057) 09 44 A8 00 | if_z rdbyte cur_char, cur_ptr ' none: save character under cursor -2DD4(0058) 09 36 28 00 | if_z wrbyte cur_block, cur_ptr ' display a cursor block -2DD8(0059) 00 44 D4 A0 | if_nz mov cur_char, #0 ' reset saved character -2DDC(005A) 09 68 14 00 | if_nz wrbyte t1, cur_ptr ' restore saved character in screen buffer -2DE0(005B) 00 02 BC 0A | :check_cmd rdlong cmd, command_ptr WZ -2DE4(005C) 45 00 68 5C | if_z jmp #:loop -2DE8(005D) 22 68 BC A2 | mov t1, cur_char WZ ' get saved character -2DEC(005E) 03 12 14 85 | if_nz cmp cur_ptr, screen_end WC -2DF0(005F) 00 44 D0 A0 | if_nz_and_c mov cur_char, #0 ' reset saved character -2DF4(0060) 09 68 10 00 | if_nz_and_c wrbyte t1, cur_ptr ' restore saved character in screen buffer -2DF8(0061) FF 02 FC 60 | and cmd, #$ff -2DFC(0062) 88 50 7C E8 | tjnz csi_mode, #csi ' go to CSI decoding if enabled -2E00(0063) 7F 4E 7C E8 | tjnz esc_mode, #esc ' go to ESC decoding if enabled -2E04(0064) 20 02 7C 87 | cmp cmd, #$20 WZ, WC ' other control characters? -2E08(0065) 6A 00 4C 5C | if_ae jmp #do_emit ' no, just emit to the screen buffer -2E0C(0066) 01 02 FC 2C | shl cmd, #1 -2E10(0067) 18 02 BC 80 | add cmd, control_ptr -2E14(0068) 01 02 BC 04 | rdword cmd, cmd -2E18(0069) 01 00 3C 5C | jmp cmd ' dispatch on control_table -2E1C(006A) 4A B3 FE 5C | do_emit call #emit -2E20(006B) 43 00 7C 5C | jmp #cmdloop -2E24(006C) | do_nul ' NUL - null character -2E24(006C) | do_soh ' SOH - start of header -2E24(006C) | do_stx ' STX - start of text -2E24(006C) | do_etx ' ETX - end of text -2E24(006C) | do_eot ' EOT - end of transmission -2E24(006C) | do_enq ' ENQ - enquiry -2E24(006C) | do_ack ' ACK - acknowledgement -2E24(006C) | do_bel ' BEL - bell -2E24(006C) | do_dle ' DLE - data link escape -2E24(006C) | do_dc1 ' DC1 - device control 1 (XON) -2E24(006C) | do_dc2 ' DC2 - device control 2 -2E24(006C) | do_dc3 ' DC3 - device control 3 (XOFF) -2E24(006C) | do_dc4 ' DC4 - device control 4 -2E24(006C) | do_nak ' NAK - negative acknowledgement -2E24(006C) | do_syn ' SYN - synchronous idle -2E24(006C) | do_etb ' ETB - end of transmission block -2E24(006C) | do_em ' EM - end of medium -2E24(006C) | do_sub ' SUB - substitute -2E24(006C) | do_fs ' FS - file separator -2E24(006C) | do_gs ' GS - group separator -2E24(006C) | do_rs ' RS - request to send -2E24(006C) | do_us ' US - unit separator -2E24(006C) 43 00 7C 5C | jmp #cmdloop -2E28(006D) C4 8C FD 5C | do_cr call #cr -2E2C(006E) 43 00 7C 5C | jmp #cmdloop -2E30(006F) C7 9A FD 5C | do_bs call #bs -2E34(0070) 43 00 7C 5C | jmp #cmdloop -2E38(0071) D2 AC FD 5C | do_ht call #ht -2E3C(0072) 43 00 7C 5C | jmp #cmdloop -2E40(0073) D7 04 FE 5C | do_lf call #lf -2E44(0074) 43 00 7C 5C | jmp #cmdloop -2E48(0075) 03 59 FE 5C | do_vt call #vt -2E4C(0076) 43 00 7C 5C | jmp #cmdloop -2E50(0077) 2D 73 FE 5C | do_ff call #ff -2E54(0078) 43 00 7C 5C | jmp #cmdloop -2E58(0079) | do_so ' ??? -2E58(0079) 43 00 7C 5C | jmp #cmdloop -2E5C(007A) | do_si ' ??? -2E5C(007A) 43 00 7C 5C | jmp #cmdloop -2E60(007B) | do_can ' CAN - cancel -2E60(007B) 3E 93 FE 5C | call #can -2E64(007C) 43 00 7C 5C | jmp #cmdloop -2E68(007D) | do_esc -2E68(007D) 01 4E FC A0 | mov esc_mode, #1 -2E6C(007E) 43 00 7C 5C | jmp #cmdloop -2E70(007F) | esc -2E70(007F) 00 4E FC A0 | mov esc_mode, #0 -2E74(0080) 5B 02 7C 86 | cmp cmd, #"[" WZ -2E78(0081) 83 00 68 5C | if_z jmp #:csi -2E7C(0082) 43 00 7C 5C | jmp #cmdloop -2E80(0083) | :csi -2E80(0083) 01 50 FC A0 | mov csi_mode, #1 ' start CSI mode -2E84(0084) 00 52 FC A0 | mov csi_argc, #0 ' argument count = 0 -2E88(0085) 00 54 FC A0 | mov csi_argf, #0 ' argument flag = 0 -2E8C(0086) 00 56 FC A0 | mov csi_args, #0 ' first argument = 0 -2E90(0087) 43 00 7C 5C | jmp #cmdloop -2E94(0088) | csi -2E94(0088) 01 50 7C 86 | cmp csi_mode, #1 WZ ' first character after "["? -2E98(0089) 8E 00 54 5C | if_nz jmp #:not_question ' no, check arguments -2E9C(008A) 02 50 FC A0 | mov csi_mode, #2 ' skip this test in the future -2EA0(008B) 3F 02 7C 86 | cmp cmd, #"?" WZ ' "[?" mode? -2EA4(008C) 01 66 FC 78 | muxz question_mark, #1 -2EA8(008D) 43 00 68 5C | if_z jmp #cmdloop -2EAC(008E) | :not_question -2EAC(008E) 30 02 7C 87 | cmp cmd, #"0" WZ, WC -2EB0(008F) A0 00 70 5C | if_b jmp #:not_numeric -2EB4(0090) 39 02 7C 87 | cmp cmd, #"9" WZ, WC -2EB8(0091) A0 00 44 5C | if_a jmp #:not_numeric -2EBC(0092) 29 68 BC A0 | mov t1, csi_argc -2EC0(0093) 2B 68 FC 80 | add t1, #csi_args -2EC4(0094) 34 2E BD 50 | movs :get_arg, t1 -2EC8(0095) 34 3C BD 54 | movd :put_arg, t1 -2ECC(0096) 01 54 FC A0 | mov csi_argf, #1 ' set the "seen arguments" flag -2ED0(0097) 00 68 BC A0 | :get_arg mov t1, 0-0 ' get csi_args[csi_argc] -2ED4(0098) 34 6A BC A0 | mov t2, t1 ' to t2 also -2ED8(0099) 02 68 FC 2C | shl t1, #2 ' * 4 -2EDC(009A) 35 68 BC 80 | add t1, t2 ' * 5 -2EE0(009B) 01 68 FC 2C | shl t1, #1 ' * 10 -2EE4(009C) 01 68 BC 80 | add t1, cmd ' + digit -2EE8(009D) 30 68 FC 84 | sub t1, #"0" ' - ASCII for "0" -2EEC(009E) 34 00 BC A0 | :put_arg mov 0-0, t1 ' put csi_args[csi_argc] -2EF0(009F) 43 00 7C 5C | jmp #cmdloop -2EF4(00A0) | :not_numeric -2EF4(00A0) 3B 02 7C 86 | cmp cmd, #";" WZ ' next argument delimiter? -2EF8(00A1) AA 00 54 5C | if_nz jmp #:not_delimiter -2EFC(00A2) 07 52 7C 86 | cmp csi_argc, #7 WZ ' reached maximum number of arguments? -2F00(00A3) 01 52 D4 80 | if_nz add csi_argc, #1 ' no, use next slot -2F04(00A4) 29 68 BC A0 | mov t1, csi_argc -2F08(00A5) 2B 68 FC 80 | add t1, #csi_args -2F0C(00A6) 34 50 BD 54 | movd :clr_arg, t1 -2F10(00A7) 00 00 00 00 | nop -2F14(00A8) 00 00 FC A0 | :clr_arg mov 0-0, #0 ' preset csi_args[csi_argc] to 0 -2F18(00A9) 43 00 7C 5C | jmp #cmdloop -2F1C(00AA) | :not_delimiter -2F1C(00AA) 00 50 FC A0 | mov csi_mode, #0 ' end CSI mode -2F20(00AB) 2A 52 BC 80 | add csi_argc, csi_argf ' incr. argument count, if any arguments were specified -2F24(00AC) 40 02 7C 87 | cmp cmd, #"@" WZ, WC ' below @? -2F28(00AD) 43 00 70 5C | if_b jmp #cmdloop -2F2C(00AE) 7A 02 7C 87 | cmp cmd, #"z" WZ, WC ' above z? -2F30(00AF) 43 00 4C 5C | if_ae jmp #cmdloop -2F34(00B0) 40 02 FC 84 | sub cmd, #"@" -2F38(00B1) 01 02 FC 2C | shl cmd, #1 ' function word index -2F3C(00B2) 19 02 BC 80 | add cmd, csi_cmds_ptr -2F40(00B3) 01 02 BC 04 | rdword cmd, cmd ' get function pointer -2F44(00B4) FF 03 7C 66 | testn cmd, #$1ff WZ ' any bits outside the cog? -2F48(00B5) 01 00 28 5C | if_z jmp cmd ' cog function -2F4C(00B6) 01 24 BC A0 | mov lmm_pc, cmd ' otherwise it's an LMM address -2F50(00B7) 80 01 7C 5C | jmp #lmm_loop ' execute LMM code -2F54(00B8) | non_zero_args -2F54(00B8) BA 56 7C E8 | tjnz csi_args, #non_zero_args_ret -2F58(00B9) 01 56 FC 80 | add csi_args, #1 -2F5C(00BA) | non_zero_args_ret -2F5C(00BA) 00 00 7C 5C | ret -2F60(00BB) | shift_csi_args -2F60(00BB) 2C 56 BC A0 | mov csi_args, csi_args + 1 -2F64(00BC) 2D 58 BC A0 | mov csi_args + 1, csi_args + 2 -2F68(00BD) 2E 5A BC A0 | mov csi_args + 2, csi_args + 3 -2F6C(00BE) 2F 5C BC A0 | mov csi_args + 3, csi_args + 4 -2F70(00BF) 30 5E BC A0 | mov csi_args + 4, csi_args + 5 -2F74(00C0) 31 60 BC A0 | mov csi_args + 5, csi_args + 6 -2F78(00C1) 32 62 BC A0 | mov csi_args + 6, csi_args + 7 -2F7C(00C2) 00 64 FC A0 | mov csi_args + 7, #0 -2F80(00C3) | shift_csi_args_ret -2F80(00C3) 00 00 7C 5C | ret -2F84(00C4) | cr -2F84(00C4) 00 3A FC A0 | mov cur_x, #0 -2F88(00C5) 00 3C FC A0 | mov new_x, #0 -2F8C(00C6) | cr_ret -2F8C(00C6) 00 00 7C 5C | ret -2F90(00C7) | bs -2F90(00C7) 00 3C 7C 86 | cmp new_x, #0 WZ -2F94(00C8) 01 3C D4 84 | if_nz sub new_x, #1 -2F98(00C9) CD 00 54 5C | if_nz jmp #bs_ret -2F9C(00CA) 06 3C BC A0 | mov new_x, screen_w -2FA0(00CB) 01 3C FC 84 | sub new_x, #1 -2FA4(00CC) 03 59 FE 5C | call #vt -2FA8(00CD) | bs_ret -2FA8(00CD) 00 00 7C 5C | ret -2FAC(00CE) | fs -2FAC(00CE) 01 3A FC 80 | add cur_x, #1 -2FB0(00CF) 06 3A 3C 86 | cmp cur_x, screen_w WZ -2FB4(00D0) 01 3A E8 84 | if_z sub cur_x, #1 ' stay in last column -2FB8(00D1) | fs_ret -2FB8(00D1) 00 00 7C 5C | ret -2FBC(00D2) | ht -2FBC(00D2) 20 02 FC A0 | mov cmd, #$20 -2FC0(00D3) 4A B3 FE 5C | call #emit -2FC4(00D4) 07 3C 7C 62 | test new_x, #7 WZ -2FC8(00D5) D2 00 54 5C | if_nz jmp #ht -2FCC(00D6) | ht_ret -2FCC(00D6) 00 00 7C 5C | ret -2FD0(00D7) | lf -2FD0(00D7) 01 3E FC 80 | add cur_y, #1 -2FD4(00D8) 04 42 7C 62 | test flags, #flag_decom WZ ' origin mode enabled? -2FD8(00D9) E2 00 54 5C | if_nz jmp #:origin ' yes, check cursor in scroll range -2FDC(00DA) 08 3E 3C 87 | :screen cmp cur_y, screen_h WZ, WC ' no, check cursor in screen range -2FE0(00DB) 02 01 70 5C | if_b jmp #lf_ret -2FE4(00DC) 08 3E BC A0 | mov cur_y, screen_h -2FE8(00DD) 01 3E FC 84 | sub cur_y, #1 -2FEC(00DE) 02 18 BC A0 | mov dst, screen_ptr ' destination = screen buffer -2FF0(00DF) 02 1A BC A0 | mov src, screen_ptr ' source = dito -2FF4(00E0) 08 22 BC A0 | mov rows, screen_h ' screen height -2FF8(00E1) EF 00 7C 5C | jmp #scroll_up_1 ' scroll the entire screen -2FFC(00E2) 0B 3E 3C 87 | :origin cmp cur_y, scroll_bot WZ, WC -3000(00E3) 02 01 70 5C | if_b jmp #lf_ret -3004(00E4) 0B 3E BC A0 | mov cur_y, scroll_bot -3008(00E5) 01 3E FC 84 | sub cur_y, #1 -300C(00E6) | scroll_up -300C(00E6) 0A 68 BC A0 | mov t1, scroll_top -3010(00E7) 06 6A BC A0 | mov t2, screen_w -3014(00E8) 79 FF FE 5C | call #mul16x16 -3018(00E9) 01 6A FC 2C | shl t2, #1 -301C(00EA) 02 6A BC 80 | add t2, screen_ptr -3020(00EB) 35 18 BC A0 | mov dst, t2 ' destination = scroll_top of screen buffer -3024(00EC) 35 1A BC A0 | mov src, t2 ' source = dito -3028(00ED) 0B 22 BC A0 | mov rows, scroll_bot ' scroll range height -302C(00EE) 0A 22 BC 84 | sub rows, scroll_top -3030(00EF) | scroll_up_1 -3030(00EF) 06 1A BC 80 | add src, screen_w ' copy from one line below -3034(00F0) 06 1A BC 80 | add src, screen_w -3038(00F1) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 rows to move -303C(00F2) FA 00 78 5C | if_be jmp #:fill ' nothing left to scroll? -3040(00F3) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3044(00F4) 0D 1E BC 08 | :cols rdlong data, src -3048(00F5) 04 1A FC 80 | add src, #4 -304C(00F6) 0C 1E 3C 08 | wrlong data, dst -3050(00F7) 04 18 FC 80 | add dst, #4 -3054(00F8) F4 20 FC E4 | djnz cols, #:cols -3058(00F9) F3 22 FC E4 | djnz rows, #:rows -305C(00FA) 07 20 BC A0 | :fill mov cols, screen_w2 ' columns = screen width / 2 -3060(00FB) 1A 68 BC A0 | mov t1, x00200020 -3064(00FC) 26 68 BC 68 | or t1, color -3068(00FD) 10 68 FC 24 | rol t1, #16 -306C(00FE) 26 68 BC 68 | or t1, color -3070(00FF) 0C 68 3C 08 | :blank wrlong t1, dst ' fill 4 spaces -3074(0100) 04 18 FC 80 | add dst, #4 -3078(0101) FF 20 FC E4 | djnz cols, #:blank -307C(0102) | scroll_up_ret -307C(0102) | lf_ret -307C(0102) 00 00 7C 5C | ret -3080(0103) | vt -3080(0103) 01 3E FC 84 | sub cur_y, #1 -3084(0104) 04 42 7C 62 | test flags, #flag_decom WZ ' origin mode enabled? -3088(0105) 0D 01 54 5C | if_nz jmp #:origin ' yes, check cursor in scroll range -308C(0106) | :screen ' no, check cursor in screen range -308C(0106) 00 3E 7C C3 | cmps cur_y, #0 WZ, WC ' < 0? -3090(0107) 2C 01 4C 5C | if_ae jmp #vt_ret ' in range -3094(0108) 00 3E FC A0 | mov cur_y, #0 ' stay in line 0 -3098(0109) 03 1A BC A0 | mov src, screen_end -309C(010A) 03 18 BC A0 | mov dst, screen_end -30A0(010B) 08 22 BC A0 | mov rows, screen_h -30A4(010C) 19 01 7C 5C | jmp #scroll_down_1 -30A8(010D) | :origin -30A8(010D) 0A 3E 3C C3 | cmps cur_y, scroll_top WZ, WC -30AC(010E) 2C 01 4C 5C | if_ae jmp #vt_ret -30B0(010F) 0A 3E BC A0 | mov cur_y, scroll_top -30B4(0110) | scroll_down -30B4(0110) 0B 68 BC A0 | mov t1, scroll_bot -30B8(0111) 06 6A BC A0 | mov t2, screen_w -30BC(0112) 79 FF FE 5C | call #mul16x16 -30C0(0113) 01 6A FC 2C | shl t2, #1 -30C4(0114) 02 6A BC 80 | add t2, screen_ptr -30C8(0115) 35 18 BC A0 | mov dst, t2 ' destination = end of scroll range buffer -30CC(0116) 35 1A BC A0 | mov src, t2 ' source = last row of scroll range buffer -30D0(0117) 0B 22 BC A0 | mov rows, scroll_bot ' scroll range height -30D4(0118) 0A 22 BC 84 | sub rows, scroll_top -30D8(0119) | scroll_down_1 -30D8(0119) 06 1A BC 84 | sub src, screen_w -30DC(011A) 06 1A BC 84 | sub src, screen_w -30E0(011B) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 rows to move -30E4(011C) 24 01 78 5C | if_be jmp #:fill ' nothing left to scroll? -30E8(011D) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -30EC(011E) 04 1A FC 84 | :cols sub src, #4 ' pre decrement source -30F0(011F) 0D 1E BC 08 | rdlong data, src -30F4(0120) 04 18 FC 84 | sub dst, #4 ' pre decrement destination -30F8(0121) 0C 1E 3C 08 | wrlong data, dst -30FC(0122) 1E 21 FC E4 | djnz cols, #:cols ' for all columns -3100(0123) 1D 23 FC E4 | djnz rows, #:rows ' for all rows -3104(0124) 1A 68 BC A0 | :fill mov t1, x00200020 -3108(0125) 26 68 BC 68 | or t1, color -310C(0126) 10 68 FC 24 | rol t1, #16 -3110(0127) 26 68 BC 68 | or t1, color -3114(0128) 07 20 BC A0 | mov cols, screen_w2 ' columns = screen width / 2 -3118(0129) 04 18 FC 84 | :blank sub dst, #4 -311C(012A) 0C 68 3C 08 | wrlong t1, dst -3120(012B) 29 21 FC E4 | djnz cols, #:blank -3124(012C) | scroll_down_ret -3124(012C) | vt_ret -3124(012C) 00 00 7C 5C | ret -3128(012D) | ff -3128(012D) 02 18 BC A0 | mov dst, screen_ptr -312C(012E) 08 22 BC A0 | mov rows, screen_h ' screen height rows -3130(012F) 1A 68 BC A0 | mov t1, x00200020 -3134(0130) 26 68 BC 68 | or t1, color -3138(0131) 10 68 FC 24 | rol t1, #16 -313C(0132) 26 68 BC 68 | or t1, color -3140(0133) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3144(0134) 0C 68 3C 08 | :cols wrlong t1, dst ' fill with 4 blanks -3148(0135) 04 18 FC 80 | add dst, #4 -314C(0136) 34 21 FC E4 | djnz cols, #:cols ' for all columns -3150(0137) 33 23 FC E4 | djnz rows, #:rows ' for all rows -3154(0138) 3A 7B FE 5C | call #home -3158(0139) | ff_ret -3158(0139) 00 00 7C 5C | ret -315C(013A) | home -315C(013A) 00 3A FC A0 | mov cur_x, #0 -3160(013B) 00 3C FC A0 | mov new_x, #0 -3164(013C) 00 3E FC A0 | mov cur_y, #0 -3168(013D) | home_ret -3168(013D) 00 00 7C 5C | ret -316C(013E) | can -316C(013E) 09 18 BC A0 | mov dst, cur_ptr -3170(013F) 06 20 BC A0 | mov cols, screen_w -3174(0140) 1E 20 BC 87 | sub cols, new_x WZ, WC -3178(0141) 49 01 78 5C | if_be jmp #can_ret -317C(0142) 1A 68 BC A0 | mov t1, x00200020 -3180(0143) 26 68 BC 68 | or t1, color -3184(0144) 10 68 FC 24 | rol t1, #16 -3188(0145) 26 68 BC 68 | or t1, color -318C(0146) 0C 68 3C 04 | :fill wrword t1, dst -3190(0147) 02 18 FC 80 | add dst, #2 -3194(0148) 46 21 FC E4 | djnz cols, #:fill -3198(0149) | can_ret -3198(0149) 00 00 7C 5C | ret -319C(014A) | emit -319C(014A) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC ' reached end of line? -31A0(014B) 50 01 70 5C | if_b jmp #:in_bounds -31A4(014C) 20 42 7C 62 | test flags, #flag_decawm WZ ' auto wrap mode active? -31A8(014D) 59 01 68 5C | if_z jmp #emit_ret ' no, don't emit character -31AC(014E) C4 8C FD 5C | call #cr -31B0(014F) D7 04 FE 5C | call #lf -31B4(0150) 1E 3A BC A0 | :in_bounds mov cur_x, new_x -31B8(0151) 5A C3 FE 5C | call #calc_cursor -31BC(0152) 26 02 BC 68 | or cmd, color -31C0(0153) 02 40 7C 62 | test attr, #attr_underline WZ -31C4(0154) 80 02 FC 7C | muxnz cmd, #$80 -31C8(0155) 09 02 3C 04 | wrword cmd, cur_ptr ' write character to screen RAM -31CC(0156) 1D 3C BC A0 | mov new_x, cur_x -31D0(0157) 01 3C FC 80 | add new_x, #1 -31D4(0158) 02 12 FC 80 | add cur_ptr, #2 -31D8(0159) | emit_ret -31D8(0159) 00 00 7C 5C | ret -31DC(015A) | calc_cursor -31DC(015A) 1F 68 BC A0 | mov t1, cur_y ' cursor row -31E0(015B) 06 6A BC A0 | mov t2, screen_w ' * screen width -31E4(015C) 79 FF FE 5C | call #mul16x16 -31E8(015D) 35 12 BC A0 | mov cur_ptr, t2 ' product in cur_ptr -31EC(015E) 1E 12 BC 80 | add cur_ptr, new_x ' + new cursor column -31F0(015F) 01 12 FC 2C | shl cur_ptr, #1 ' * 2 -31F4(0160) 02 12 BC 80 | add cur_ptr, screen_ptr ' + screen buffer address -31F8(0161) | calc_cursor_ret -31F8(0161) 00 00 7C 5C | ret -31FC(0162) | enable_cursor -31FC(0162) 43 08 7C EC | tjz cursor_ptr, #cmdloop -3200(0163) 01 42 7C 62 | test flags, #flag_deccm WZ ' cursor enabled? -3204(0164) 00 68 E8 A0 | if_z mov t1, #%000 ' cursor off -3208(0165) 06 68 D4 A0 | if_nz mov t1, #%110 ' cursor on, blink slow -320C(0166) 02 08 FC 80 | add cursor_ptr, #2 ' cursor control -3210(0167) 04 68 3C 00 | wrbyte t1, cursor_ptr -3214(0168) 02 08 FC 84 | sub cursor_ptr, #2 -3218(0169) 43 00 7C 5C | jmp #cmdloop -321C(016A) | set_color -321C(016A) 04 40 7C 62 | test attr, #attr_inverse WZ -3220(016B) 70 01 68 5C | if_z jmp #:default -3224(016C) | :inverse -3224(016C) 24 4C BC A0 | mov color, fgcol ' compose inverse color -3228(016D) 04 4C FC 2C | shl color, #4 -322C(016E) 25 4C BC 68 | or color, bgcol -3230(016F) 73 01 7C 5C | jmp #:cont -3234(0170) | :default -3234(0170) 25 4C BC A0 | mov color, bgcol ' compose default color -3238(0171) 04 4C FC 2C | shl color, #4 -323C(0172) 24 4C BC 68 | or color, fgcol -3240(0173) | :cont -3240(0173) 01 40 7C 62 | test attr, #attr_highlite WZ -3244(0174) 08 4C FC 7C | muxnz color, #$08 -3248(0175) 08 40 7C 62 | test attr, #attr_blinking WZ -324C(0176) 80 4C FC 7C | muxnz color, #$80 -3250(0177) 08 4C FC 2C | shl color, #8 ' in bits 15..8 -3254(0178) 43 00 7C 5C | jmp #cmdloop -3258(0179) | mul16x16 -3258(0179) 10 68 FC 2C | shl t1, #16 ' multiplicand in bits 31..16 -325C(017A) 10 6C FC A0 | mov t3, #16 ' loop 16 times -3260(017B) 01 6A FC 29 | shr t2, #1 WC ' get initial multiplier bit in carry -3264(017C) 34 6A B0 81 | :loop if_c add t2, t1 WC ' if carry set, add multiplicand to product -3268(017D) 01 6A FC 31 | rcr t2, #1 WC ' next multiplier bit to carry, shift product -326C(017E) 7C 6D FC E4 | djnz t3, #:loop ' until done -3270(017F) | mul16x16_ret -3270(017F) 00 00 7C 5C | ret -3274(0180) | lmm_loop -3274(0180) 12 04 BF 08 | rdlong :op1, lmm_pc -3278(0181) 04 24 FC 80 | add lmm_pc, #4 -327C(0182) 00 00 00 00 | :op1 nop -3280(0183) 12 0A BF 08 | rdlong :op2, lmm_pc -3284(0184) 04 24 FC 80 | add lmm_pc, #4 -3288(0185) 00 00 00 00 | :op2 nop -328C(0186) 12 10 BF 08 | rdlong :op3, lmm_pc -3290(0187) 04 24 FC 80 | add lmm_pc, #4 -3294(0188) 00 00 00 00 | :op3 nop -3298(0189) 12 16 BF 08 | rdlong :op4, lmm_pc -329C(018A) 04 24 FC 80 | add lmm_pc, #4 -32A0(018B) 00 00 00 00 | :op4 nop -32A4(018C) 80 01 7C 5C | jmp #lmm_loop -32A8(018D) | fit $1f0 -32A8(018D) | There are 99 ($063) Longs left in the cog -32A8(018D) 6C 00 | control_table word do_nul, do_soh, do_stx, do_etx, do_eot, do_enq, do_ack, do_bel -32AA(018D) 6C 00 | -32AC(018E) 6C 00 | -32AE(018E) 6C 00 | -32B0(018F) 6C 00 | -32B2(018F) 6C 00 | -32B4(0190) 6C 00 | -32B6(0190) 6C 00 | -32B8(0191) 6F 00 | word do_bs, do_ht, do_lf, do_vt, do_ff, do_cr, do_so, do_si -32BA(0191) 71 00 | -32BC(0192) 73 00 | -32BE(0192) 75 00 | -32C0(0193) 77 00 | -32C2(0193) 6D 00 | -32C4(0194) 79 00 | -32C6(0194) 7A 00 | -32C8(0195) 6C 00 | word do_dle, do_dc1, do_dc2, do_dc3, do_dc4, do_nak, do_syn, do_etb -32CA(0195) 6C 00 | -32CC(0196) 6C 00 | -32CE(0196) 6C 00 | -32D0(0197) 6C 00 | -32D2(0197) 6C 00 | -32D4(0198) 6C 00 | -32D6(0198) 6C 00 | -32D8(0199) 7B 00 | word do_can, do_em, do_sub, do_esc, do_fs, do_gs, do_rs, do_us -32DA(0199) 6C 00 | -32DC(019A) 6C 00 | -32DE(019A) 7D 00 | -32E0(019B) 6C 00 | -32E2(019B) 6C 00 | -32E4(019C) 6C 00 | -32E6(019C) 6C 00 | -32E8(019D) 5E 33 | csi_cmds word @@@do_insert_char ' [...@ -32EA(019D) D8 33 | word @@@do_cursor_up ' [...A -32EC(019E) EC 33 | word @@@do_cursor_down ' [...B -32EE(019E) FC 33 | word @@@do_cursor_left ' [...C -32F0(019F) 10 34 | word @@@do_cursor_right ' [...D -32F2(019F) 20 34 | word @@@do_rows_up ' [...E -32F4(01A0) 38 34 | word @@@do_rows_down ' [...F -32F6(01A0) 70 34 | word @@@do_cursor_column ' [...G -32F8(01A1) 4C 34 | word @@@do_cursor_address ' [...H -32FA(01A1) 43 00 | word cmdloop ' I unused? -32FC(01A2) 80 34 | word @@@do_clear_screen ' [...J -32FE(01A2) E0 34 | word @@@do_clear_row ' [...K -3300(01A3) 54 35 | word @@@do_insert_line ' [...L -3302(01A3) C8 35 | word @@@do_delete_line ' [...M -3304(01A4) 43 00 | word cmdloop ' N unused? -3306(01A4) 43 00 | word cmdloop ' O unused? -3308(01A5) 54 36 | word @@@do_delete_char ' P unused? -330A(01A5) 43 00 | word cmdloop ' Q unused? -330C(01A6) 43 00 | word cmdloop ' R unused? -330E(01A6) 43 00 | word cmdloop ' S unused? -3310(01A7) 43 00 | word cmdloop ' T unused? -3312(01A7) 43 00 | word cmdloop ' U unused? -3314(01A8) 43 00 | word cmdloop ' V unused? -3316(01A8) 43 00 | word cmdloop ' W unused? -3318(01A9) CC 36 | word @@@do_blank_chars ' [...X -331A(01A9) 43 00 | word cmdloop ' Y unused? -331C(01AA) 43 00 | word cmdloop ' Z unused? -331E(01AA) 43 00 | word cmdloop ' [ unused -3320(01AB) 43 00 | word cmdloop ' \ unused -3322(01AB) 43 00 | word cmdloop ' ] unused -3324(01AC) 43 00 | word cmdloop ' ^ unused -3326(01AC) 43 00 | word cmdloop ' _ unused -3328(01AD) 70 34 | word @@@do_cursor_column ' [...` alternate form for [...G -332A(01AD) 43 00 | word cmdloop ' a unused? -332C(01AE) 43 00 | word cmdloop ' b unused? -332E(01AE) 43 00 | word cmdloop ' c unused? -3330(01AF) 43 00 | word cmdloop ' d unused? -3332(01AF) 43 00 | word cmdloop ' e unused? -3334(01B0) 4C 34 | word @@@do_cursor_address ' [...f alternate form for [...H -3336(01B0) 43 00 | word cmdloop ' g unused? -3338(01B1) 0C 37 | word @@@do_flag_set ' h unused? -333A(01B1) 43 00 | word cmdloop ' i unused? -333C(01B2) 43 00 | word cmdloop ' j unused? -333E(01B2) 43 00 | word cmdloop ' k unused? -3340(01B3) 7C 37 | word @@@do_flag_res ' h unused? -3342(01B3) EC 37 | word @@@do_mode_attributes ' [...m -3344(01B4) 43 00 | word cmdloop ' n unused? -3346(01B4) 43 00 | word cmdloop ' o unused? -3348(01B5) 43 00 | word cmdloop ' p unused? -334A(01B5) 43 00 | word cmdloop ' q unused? -334C(01B6) 2C 39 | word @@@do_scroll_range ' [...r -334E(01B6) 7C 39 | word @@@do_save_cursor ' [?...s -3350(01B7) 43 00 | word cmdloop ' t unused? -3352(01B7) 90 39 | word @@@do_restore_cursor ' [?...u -3354(01B8) 43 00 | word cmdloop ' v unused? -3356(01B8) 43 00 | word cmdloop ' w unused? -3358(01B9) 43 00 | word cmdloop ' x unused? -335A(01B9) 43 00 | word cmdloop ' y unused? -335C(01BA) 43 00 | word cmdloop ' z unused? -335E(01BA) | do_insert_char -335E(01BA) B8 74 FD 5C | call #non_zero_args -3364(01BC) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC -3368(01BD) 43 00 4C 5C | if_ae jmp #cmdloop -336C(01BE) 1F 68 BC A0 | :loop mov t1, cur_y -3370(01BF) 06 6A BC A0 | mov t2, screen_w -3374(01C0) 79 FF FE 5C | call #mul16x16 -3378(01C1) 1E 6A BC 80 | add t2, new_x -337C(01C2) 01 6A FC 2C | shl t2, #1 -3380(01C3) 02 6A BC 80 | add t2, screen_ptr -3384(01C4) 35 18 BC A0 | mov dst, t2 -3388(01C5) 02 18 FC 80 | add dst, #2 -338C(01C6) 35 1A BC A0 | mov src, t2 -3390(01C7) 06 20 BC A0 | mov cols, screen_w -3394(01C8) 1E 20 BC 84 | sub cols, new_x -3398(01C9) 01 20 FC 87 | sub cols, #1 WZ, WC -339C(01CA) 28 24 F8 80 | if_be add lmm_pc, #4*(:blank - $ - 1) -33A0(01CB) 0D 1E BC 04 | :insert rdword data, src -33A4(01CC) 02 1A FC 80 | add src, #2 -33A8(01CD) 0C 1E 3C 04 | wrword data, dst -33AC(01CE) 02 18 FC 80 | add dst, #2 -33B0(01CF) 01 20 FC 86 | sub cols, #1 WZ -33B4(01D0) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :insert) -33B8(01D1) 1A 68 BC A0 | mov t1, x00200020 -33BC(01D2) 26 68 BC 68 | or t1, color -33C0(01D3) 10 68 FC 24 | rol t1, #16 -33C4(01D4) 26 68 BC 68 | or t1, color -33C8(01D5) 35 68 3C 04 | :blank wrword t1, t2 -33CC(01D6) 01 56 FC 86 | sub csi_args, #1 WZ -33D0(01D7) 68 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -33D4(01D8) 43 00 7C 5C | jmp #cmdloop -33D8(01D9) | do_cursor_up -33D8(01D9) B8 74 FD 5C | call #non_zero_args -33DC(01DA) 03 59 FE 5C | :loop call #vt -33E0(01DB) 01 56 FC 86 | sub csi_args, #1 WZ -33E4(01DC) 0C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -33E8(01DD) 43 00 7C 5C | jmp #cmdloop -33EC(01DE) | do_cursor_down -33EC(01DE) B8 74 FD 5C | call #non_zero_args -33F0(01DF) D7 04 FE 5C | :loop call #lf -33F4(01E0) DF 57 FC E4 | djnz csi_args, #:loop -33F8(01E1) 43 00 7C 5C | jmp #cmdloop -33FC(01E2) | do_cursor_left -33FC(01E2) B8 74 FD 5C | call #non_zero_args -3400(01E3) 1E 3A BC A0 | mov cur_x, new_x -3404(01E4) 2B 3A BC 85 | sub cur_x, csi_args WC -3408(01E5) 00 3A F0 A0 | if_c mov cur_x, #0 -340C(01E6) 38 00 7C 5C | jmp #validate_cursor -3410(01E7) | do_cursor_right -3410(01E7) B8 74 FD 5C | call #non_zero_args -3414(01E8) 1E 3A BC A0 | mov cur_x, new_x -3418(01E9) 2B 3A BC 80 | add cur_x, csi_args -341C(01EA) 38 00 7C 5C | jmp #validate_cursor -3420(01EB) | do_rows_up -3420(01EB) B8 74 FD 5C | call #non_zero_args -3424(01EC) 00 3A FC A0 | mov cur_x, #0 -3428(01ED) 00 3C FC A0 | mov new_x, #0 -342C(01EE) 2B 3E BC 85 | sub cur_y, csi_args WC -3430(01EF) 00 3E F0 A0 | if_c mov cur_y, #0 -3434(01F0) 38 00 7C 5C | jmp #validate_cursor -3438(01F1) | do_rows_down -3438(01F1) B8 74 FD 5C | call #non_zero_args -343C(01F2) 00 3A FC A0 | mov cur_x, #0 -3440(01F3) 00 3C FC A0 | mov new_x, #0 -3444(01F4) 2B 3E BC 80 | add cur_y, csi_args -3448(01F5) 38 00 7C 5C | jmp #validate_cursor -344C(01F6) | do_cursor_address -344C(01F6) 00 54 7C 86 | cmp csi_argf, #0 WZ ' nor arguments at all? -3450(01F7) 3A 7B EA 5C | if_z call #home -3454(01F8) 43 00 68 5C | if_z jmp #cmdloop -3458(01F9) B8 74 FD 5C | call #non_zero_args -345C(01FA) 2B 3E BC A0 | mov cur_y, csi_args -3460(01FB) 01 3E FC 84 | sub cur_y, #1 -3464(01FC) 01 52 7C 87 | cmp csi_argc, #1 WZ, WC ' the caller specified just a row? -3468(01FD) 38 00 78 5C | if_be jmp #validate_cursor -346C(01FE) BB 86 FD 5C | call #shift_csi_args -3470(01FF) | do_cursor_column -3470(01FF) B8 74 FD 5C | call #non_zero_args -3474(0200) 2B 3A BC A0 | mov cur_x, csi_args -3478(0201) 01 3A FC 84 | sub cur_x, #1 -347C(0202) 38 00 7C 5C | jmp #validate_cursor -3480(0203) | do_clear_screen -3480(0203) 5A C3 FE 5C | call #calc_cursor -3484(0204) 00 56 7C 86 | cmp csi_args, #0 WZ ' cursor to end of screen? -3488(0205) 0C 24 D4 80 | if_nz add lmm_pc, #4*(:not_0 - $ - 1) -348C(0206) 09 18 BC A0 | mov dst, cur_ptr -3490(0207) 03 1C BC A0 | mov end, screen_end -3494(0208) 24 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -3498(0209) 01 56 7C 86 | :not_0 cmp csi_args, #1 WZ ' start of screen to cursor? -349C(020A) 0C 24 D4 80 | if_nz add lmm_pc, #4*(:not_1 - $ - 1) -34A0(020B) 02 18 BC A0 | mov dst, screen_ptr -34A4(020C) 09 1C BC A0 | mov end, cur_ptr -34A8(020D) 10 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -34AC(020E) 02 56 7C 86 | :not_1 cmp csi_args, #2 WZ ' entire screen? -34B0(020F) 43 00 54 5C | if_nz jmp #cmdloop ' invalid argument -34B4(0210) 02 18 BC A0 | mov dst, screen_ptr ' default = entire screen -34B8(0211) 03 1C BC A0 | mov end, screen_end -34BC(0212) 1A 68 BC A0 | :fill mov t1, x00200020 -34C0(0213) 26 68 BC 68 | or t1, color -34C4(0214) 10 68 FC 24 | rol t1, #16 -34C8(0215) 26 68 BC 68 | or t1, color -34CC(0216) 0C 68 3C 04 | :loop wrword t1, dst ' fill a word -34D0(0217) 02 18 FC 80 | add dst, #2 -34D4(0218) 0E 18 3C 87 | cmp dst, end WZ, WC -34D8(0219) 10 24 F0 84 | if_b sub lmm_pc, #4*($ + 1 - :loop) -34DC(021A) 43 00 7C 5C | jmp #cmdloop -34E0(021B) | do_clear_row -34E0(021B) 5A C3 FE 5C | call #calc_cursor -34E4(021C) 00 56 7C 86 | cmp csi_args, #0 WZ ' cursor to end of row? -34E8(021D) 14 24 D4 80 | if_nz add lmm_pc, #4*(:not_0 - $ - 1) -34EC(021E) 09 18 BC A0 | mov dst, cur_ptr ' default = cursor to end of row -34F0(021F) 09 1C BC A0 | mov end, cur_ptr -34F4(0220) 1E 1C BC 84 | sub end, new_x -34F8(0221) 06 1C BC 80 | add end, screen_w ' end of row -34FC(0222) 30 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -3500(0223) 01 56 7C 86 | :not_0 cmp csi_args, #1 WZ ' start of row to cursor? -3504(0224) 10 24 D4 80 | if_nz add lmm_pc, #4*(:not_1 - $ - 1) -3508(0225) 09 18 BC A0 | mov dst, cur_ptr -350C(0226) 1E 18 BC 84 | sub dst, new_x ' start of row -3510(0227) 09 1C BC A0 | mov end, cur_ptr ' to cursor -3514(0228) 18 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -3518(0229) 02 56 7C 86 | :not_1 cmp csi_args, #2 WZ ' entire row? -351C(022A) 43 00 54 5C | if_nz jmp #cmdloop ' invalid argument -3520(022B) 09 18 BC A0 | mov dst, cur_ptr -3524(022C) 1E 18 BC 84 | sub dst, new_x ' start of row -3528(022D) 0C 1C BC A0 | mov end, dst -352C(022E) 06 1C BC 80 | add end, screen_w ' end of row -3530(022F) 1A 68 BC A0 | :fill mov t1, x00200020 -3534(0230) 26 68 BC 68 | or t1, color -3538(0231) 10 68 FC 24 | rol t1, #16 -353C(0232) 26 68 BC 68 | or t1, color -3540(0233) 0C 68 3C 04 | :loop wrword t1, dst ' fill a word -3544(0234) 02 18 FC 80 | add dst, #2 -3548(0235) 0E 18 3C 87 | cmp dst, end WZ, WC -354C(0236) 10 24 F0 84 | if_b sub lmm_pc, #4*($ + 1 - :loop) -3550(0237) 43 00 7C 5C | jmp #cmdloop -3554(0238) | do_insert_line -3554(0238) B8 74 FD 5C | call #non_zero_args -3558(0239) 03 18 BC A0 | :loop mov dst, screen_end -355C(023A) 03 1A BC A0 | mov src, screen_end -3560(023B) 06 1A BC 84 | sub src, screen_w -3564(023C) 08 22 BC A0 | mov rows, screen_h ' screen rows -3568(023D) 1F 22 BC 84 | sub rows, cur_y ' - cursor row -356C(023E) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 -3570(023F) 24 24 F8 80 | if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -3574(0240) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3578(0241) 04 1A FC 84 | :cols sub src, #4 -357C(0242) 0D 1E BC 08 | rdlong data, src -3580(0243) 04 18 FC 84 | sub dst, #4 -3584(0244) 0C 1E 3C 08 | wrlong data, dst -3588(0245) 01 20 FC 86 | sub cols, #1 WZ -358C(0246) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :cols) -3590(0247) 01 22 FC 86 | sub rows, #1 WZ -3594(0248) 24 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :rows) -3598(0249) 1A 68 BC A0 | :fill mov t1, x00200020 -359C(024A) 26 68 BC 68 | or t1, color -35A0(024B) 10 68 FC 24 | rol t1, #16 -35A4(024C) 26 68 BC 68 | or t1, color -35A8(024D) 07 20 BC A0 | mov cols, screen_w2 ' columns = screen width / 2 -35AC(024E) 04 18 FC 84 | :blank sub dst, #4 -35B0(024F) 0C 68 3C 08 | wrlong t1, dst -35B4(0250) 01 20 FC 86 | sub cols, #1 WZ -35B8(0251) 10 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns -35BC(0252) 01 56 FC 86 | sub csi_args, #1 WZ ' more lines to insert? -35C0(0253) 6C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -35C4(0254) 43 00 7C 5C | jmp #cmdloop -35C8(0255) | do_delete_line -35C8(0255) B8 74 FD 5C | call #non_zero_args -35CC(0256) 1F 68 BC A0 | :loop mov t1, cur_y -35D0(0257) 06 6A BC A0 | mov t2, screen_w -35D4(0258) 79 FF FE 5C | call #mul16x16 -35D8(0259) 01 6A FC 2C | shl t2, #1 -35DC(025A) 02 6A BC 80 | add t2, screen_ptr ' cursor row address -35E0(025B) 35 18 BC A0 | mov dst, t2 -35E4(025C) 35 1A BC A0 | mov src, t2 -35E8(025D) 06 1A BC 80 | add src, screen_w ' one row down -35EC(025E) 06 1A BC 80 | add src, screen_w -35F0(025F) 08 22 BC A0 | mov rows, screen_h ' screen rows -35F4(0260) 1F 22 BC 84 | sub rows, cur_y ' - cursor row -35F8(0261) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 -35FC(0262) 24 24 F8 80 | if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -3600(0263) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3604(0264) 0D 1E BC 08 | :cols rdlong data, src -3608(0265) 04 1A FC 80 | add src, #4 -360C(0266) 0C 1E 3C 08 | wrlong data, dst -3610(0267) 04 18 FC 80 | add dst, #4 -3614(0268) 01 20 FC 86 | sub cols, #1 WZ -3618(0269) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :cols) -361C(026A) 01 22 FC 86 | sub rows, #1 WZ -3620(026B) 24 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :rows) -3624(026C) 1A 68 BC A0 | :fill mov t1, x00200020 -3628(026D) 26 68 BC 68 | or t1, color -362C(026E) 10 68 FC 24 | rol t1, #16 -3630(026F) 26 68 BC 68 | or t1, color -3634(0270) 07 20 BC A0 | mov cols, screen_w2 ' columns = screen width / 2 -3638(0271) 0C 68 3C 08 | :blank wrlong t1, dst -363C(0272) 04 18 FC 80 | add dst, #4 -3640(0273) 01 20 FC 86 | sub cols, #1 WZ -3644(0274) 10 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns -3648(0275) 01 56 FC 86 | sub csi_args, #1 WZ ' more lines to insert? -364C(0276) 84 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -3650(0277) 43 00 7C 5C | jmp #cmdloop -3654(0278) | do_delete_char -3654(0278) B8 74 FD 5C | call #non_zero_args -3658(0279) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC -365C(027A) 43 00 4C 5C | if_ae jmp #cmdloop ' can't delete beyond last column -3660(027B) 1F 68 BC A0 | :loop mov t1, cur_y -3664(027C) 06 6A BC A0 | mov t2, screen_w -3668(027D) 79 FF FE 5C | call #mul16x16 -366C(027E) 1E 6A BC 80 | add t2, new_x -3670(027F) 01 6A FC 2C | shl t2, #1 -3674(0280) 02 6A BC 80 | add t2, screen_ptr -3678(0281) 35 18 BC A0 | mov dst, t2 -367C(0282) 35 1A BC A0 | mov src, t2 -3680(0283) 02 1A FC 80 | add src, #2 -3684(0284) 06 20 BC A0 | mov cols, screen_w -3688(0285) 1E 20 BC 84 | sub cols, new_x -368C(0286) 01 20 FC 87 | sub cols, #1 WZ, WC -3690(0287) 18 24 F8 80 | if_be add lmm_pc, #4*(:blank - $ - 1) ' new_x is beyond the last column -3694(0288) 0D 1E BC 04 | :insert rdword data, src -3698(0289) 02 1A FC 80 | add src, #2 -369C(028A) 0C 1E 3C 04 | wrword data, dst -36A0(028B) 02 18 FC 80 | add dst, #2 -36A4(028C) 01 20 FC 86 | sub cols, #1 WZ -36A8(028D) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :insert) -36AC(028E) 1A 68 BC A0 | :blank mov t1, x00200020 -36B0(028F) 26 68 BC 68 | or t1, color -36B4(0290) 10 68 FC 24 | rol t1, #16 -36B8(0291) 26 68 BC 68 | or t1, color -36BC(0292) 0C 68 3C 04 | wrword t1, dst ' clear the last character in the row -36C0(0293) 01 56 FC 86 | sub csi_args, #1 WZ -36C4(0294) 68 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -36C8(0295) 43 00 7C 5C | jmp #cmdloop -36CC(0296) | do_blank_chars -36CC(0296) B8 74 FD 5C | call #non_zero_args -36D0(0297) 09 18 BC A0 | mov dst, cur_ptr -36D4(0298) 06 20 BC A0 | mov cols, screen_w -36D8(0299) 1E 20 BC 87 | sub cols, new_x WZ, WC -36DC(029A) 43 00 78 5C | if_be jmp #cmdloop -36E0(029B) 1A 68 BC A0 | mov t1, x00200020 -36E4(029C) 26 68 BC 68 | or t1, color -36E8(029D) 10 68 FC 24 | rol t1, #16 -36EC(029E) 26 68 BC 68 | or t1, color -36F0(029F) 0C 68 3C 04 | :fill wrword t1, dst -36F4(02A0) 02 18 FC 80 | add dst, #2 -36F8(02A1) 01 56 FC 86 | sub csi_args, #1 WZ -36FC(02A2) 43 00 68 5C | if_z jmp #cmdloop -3700(02A3) 01 20 FC 86 | sub cols, #1 WZ -3704(02A4) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :fill) -3708(02A5) 43 00 7C 5C | jmp #cmdloop -370C(02A6) | do_flag_set -370C(02A6) | :loop -370C(02A6) 2B 02 BC A0 | mov cmd, csi_args -3710(02A7) 01 66 7C 86 | cmp question_mark, #1 WZ ' [? sequence? -3714(02A8) 1C 24 E8 80 | if_z add lmm_pc, #4*(:ques - $ - 1) -3718(02A9) 03 02 7C 86 | cmp cmd, #3 WZ ' [3h - display control characters -371C(02AA) 00 43 E8 68 | if_z or flags, #flag_ctrl -3720(02AB) 04 02 7C 86 | cmp cmd, #4 WZ ' [4h - set insert mode -3724(02AC) 02 42 E8 68 | if_z or flags, #flag_decim -3728(02AD) 14 02 7C 86 | cmp cmd, #20 WZ ' [20h - set auto CR mode -372C(02AE) 08 42 E8 68 | if_z or flags, #flag_deccr -3730(02AF) 30 24 FC 80 | add lmm_pc, #4*(:next - $ - 1) -3734(02B0) | :ques -3734(02B0) 01 02 7C 86 | cmp cmd, #1 WZ ' [?1h - enable cursor keys -3738(02B1) 10 42 E8 68 | if_z or flags, #flag_decck -373C(02B2) 05 02 7C 86 | cmp cmd, #5 WZ ' [?5h - inverse terminal on -3740(02B3) 01 38 E8 68 | if_z or inverse, #1 -3744(02B4) 06 02 7C 86 | cmp cmd, #6 WZ ' [?6h - enable origin mode -3748(02B5) 04 42 E8 68 | if_z or flags, #flag_decom -374C(02B6) 07 02 7C 86 | cmp cmd, #7 WZ ' [?7h - enable auto wrap mode -3750(02B7) 20 42 E8 68 | if_z or flags, #flag_decawm -3754(02B8) 08 02 7C 86 | cmp cmd, #8 WZ ' [?8h - enable auto repeat mode -3758(02B9) 40 42 E8 68 | if_z or flags, #flag_decarm -375C(02BA) 19 02 7C 86 | cmp cmd, #25 WZ ' [?25h - enable cursor -3760(02BB) 01 42 E8 68 | if_z or flags, #flag_deccm -3764(02BC) | :next -3764(02BC) 00 54 7C 86 | cmp csi_argf, #0 WZ ' no arguments specified? -3768(02BD) 43 00 68 5C | if_z jmp #cmdloop -376C(02BE) BB 86 FD 5C | call #shift_csi_args -3770(02BF) 01 52 FC 86 | sub csi_argc, #1 WZ -3774(02C0) 6C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -3778(02C1) 62 01 7C 5C | jmp #enable_cursor -377C(02C2) | do_flag_res -377C(02C2) | :loop -377C(02C2) 2B 02 BC A0 | mov cmd, csi_args -3780(02C3) 01 66 7C 86 | cmp question_mark, #1 WZ ' [? sequence? -3784(02C4) 1C 24 E8 80 | if_z add lmm_pc, #4*(:ques - $ - 1) -3788(02C5) 03 02 7C 86 | cmp cmd, #3 WZ ' [3l - don't display control characters -378C(02C6) 00 43 E8 64 | if_z andn flags, #flag_ctrl -3790(02C7) 04 02 7C 86 | cmp cmd, #4 WZ ' [4l - reset insert mode -3794(02C8) 02 42 E8 64 | if_z andn flags, #flag_decim -3798(02C9) 14 02 7C 86 | cmp cmd, #20 WZ ' [20l - reset auto CR mode -379C(02CA) 08 42 E8 64 | if_z andn flags, #flag_deccr -37A0(02CB) 30 24 FC 80 | add lmm_pc, #4*(:next - $ - 1) -37A4(02CC) | :ques -37A4(02CC) 01 02 7C 86 | cmp cmd, #1 WZ ' [?1l - disable cursor keys -37A8(02CD) 10 42 E8 64 | if_z andn flags, #flag_decck -37AC(02CE) 05 02 7C 86 | cmp cmd, #5 WZ ' [?5l - inverse terminal off -37B0(02CF) 01 38 E8 64 | if_z andn inverse, #1 -37B4(02D0) 06 02 7C 86 | cmp cmd, #6 WZ ' [?6l - disable origin mode -37B8(02D1) 04 42 E8 64 | if_z andn flags, #flag_decom -37BC(02D2) 07 02 7C 86 | cmp cmd, #7 WZ ' [?7l - disable auto wrap mode -37C0(02D3) 20 42 E8 64 | if_z andn flags, #flag_decawm -37C4(02D4) 08 02 7C 86 | cmp cmd, #8 WZ ' [?8l - disable auto repeat mode -37C8(02D5) 40 42 E8 64 | if_z andn flags, #flag_decarm -37CC(02D6) 19 02 7C 86 | cmp cmd, #25 WZ ' [?25l - disable cursor -37D0(02D7) 01 42 E8 64 | if_z andn flags, #flag_deccm -37D4(02D8) | :next -37D4(02D8) 00 54 7C 86 | cmp csi_argf, #0 WZ ' no arguments specified? -37D8(02D9) 43 00 68 5C | if_z jmp #cmdloop -37DC(02DA) BB 86 FD 5C | call #shift_csi_args -37E0(02DB) 01 52 FC 86 | sub csi_argc, #1 WZ -37E4(02DC) 6C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -37E8(02DD) 62 01 7C 5C | jmp #enable_cursor -37EC(02DE) | do_mode_attributes -37EC(02DE) 2B 02 BC A0 | :get_arg mov cmd, csi_args ' get next argument -37F0(02DF) 00 02 7C 86 | cmp cmd, #0 WZ ' 0 = reset all attributes -37F4(02E0) 00 40 E8 A0 | if_z mov attr, #0 -37F8(02E1) 00 4A E8 A0 | if_z mov bgcol, #%0000 -37FC(02E2) 07 48 E8 A0 | if_z mov fgcol, #%0111 -3800(02E3) 01 02 7C 86 | cmp cmd, #1 WZ ' 1 = highlight on -3804(02E4) 01 40 E8 68 | if_z or attr, #attr_highlite -3808(02E5) 02 02 7C 86 | cmp cmd, #2 WZ ' 2 = highlight off -380C(02E6) 01 40 E8 64 | if_z andn attr, #attr_highlite -3810(02E7) 04 02 7C 86 | cmp cmd, #4 WZ ' 4 = underline on -3814(02E8) 02 40 E8 68 | if_z or attr, #attr_underline -3818(02E9) 05 02 7C 86 | cmp cmd, #5 WZ ' 5 = blinking on -381C(02EA) 08 40 E8 68 | if_z or attr, #attr_blinking -3820(02EB) 07 02 7C 86 | cmp cmd, #7 WZ ' 7 = inverse on -3824(02EC) 04 40 E8 68 | if_z or attr, #attr_inverse -3828(02ED) 0A 02 7C 86 | cmp cmd, #10 WZ ' 10 = primary font, no ctrl, no meta -382C(02EE) 00 43 E8 64 | if_z andn flags, #flag_ctrl -3830(02EF) 80 42 E8 64 | if_z andn flags, #flag_meta -3834(02F0) 0B 02 7C 86 | cmp cmd, #11 WZ ' 11 = alternate font, ctrl chars, low half, meta off -3838(02F1) 00 43 E8 68 | if_z or flags, #flag_ctrl -383C(02F2) 80 42 E8 64 | if_z andn flags, #flag_meta -3840(02F3) 0C 02 7C 86 | cmp cmd, #12 WZ ' 12 = alternate font, ctrl chars, low half, meta on -3844(02F4) 00 43 E8 68 | if_z or flags, #flag_ctrl -3848(02F5) 80 42 E8 68 | if_z or flags, #flag_meta -384C(02F6) 15 02 7C 86 | cmp cmd, #21 WZ ' 21 = highlight on -3850(02F7) 01 40 E8 68 | if_z or attr, #attr_highlite -3854(02F8) 16 02 7C 86 | cmp cmd, #22 WZ ' 22 = highlight on -3858(02F9) 01 40 E8 68 | if_z or attr, #attr_highlite -385C(02FA) 18 02 7C 86 | cmp cmd, #24 WZ ' 24 = underline off -3860(02FB) 02 40 E8 64 | if_z andn attr, #attr_underline -3864(02FC) 19 02 7C 86 | cmp cmd, #25 WZ ' 25 = blinking off -3868(02FD) 08 40 E8 64 | if_z andn attr, #attr_blinking -386C(02FE) 1B 02 7C 86 | cmp cmd, #27 WZ ' 27 = inverse off -3870(02FF) 04 40 E8 64 | if_z andn attr, #attr_inverse -3874(0300) 1E 02 7C 86 | cmp cmd, #30 WZ ' 30 = foreground color 0 -3878(0301) 00 48 E8 A0 | if_z mov fgcol, #%0000 -387C(0302) 1F 02 7C 86 | cmp cmd, #31 WZ ' 31 = foreground color 1 -3880(0303) 01 48 E8 A0 | if_z mov fgcol, #%0001 -3884(0304) 20 02 7C 86 | cmp cmd, #32 WZ ' 32 = foreground color 2 -3888(0305) 02 48 E8 A0 | if_z mov fgcol, #%0010 -388C(0306) 21 02 7C 86 | cmp cmd, #33 WZ ' 33 = foreground color 3 -3890(0307) 03 48 E8 A0 | if_z mov fgcol, #%0011 -3894(0308) 22 02 7C 86 | cmp cmd, #34 WZ ' 34 = foreground color 4 -3898(0309) 04 48 E8 A0 | if_z mov fgcol, #%0100 -389C(030A) 23 02 7C 86 | cmp cmd, #35 WZ ' 35 = foreground color 5 -38A0(030B) 05 48 E8 A0 | if_z mov fgcol, #%0101 -38A4(030C) 24 02 7C 86 | cmp cmd, #36 WZ ' 36 = foreground color 6 -38A8(030D) 06 48 E8 A0 | if_z mov fgcol, #%0110 -38AC(030E) 25 02 7C 86 | cmp cmd, #37 WZ ' 37 = foreground color 7 -38B0(030F) 07 48 E8 A0 | if_z mov fgcol, #%0111 -38B4(0310) 26 02 7C 86 | cmp cmd, #38 WZ ' 38 = default color and underline on -38B8(0311) 07 48 E8 A0 | if_z mov fgcol, #%0111 -38BC(0312) 02 40 E8 68 | if_z or attr, #attr_underline -38C0(0313) 27 02 7C 86 | cmp cmd, #39 WZ ' 39 = default color and underline off -38C4(0314) 07 48 E8 A0 | if_z mov fgcol, #%0111 -38C8(0315) 02 40 E8 64 | if_z andn attr, #attr_underline -38CC(0316) 28 02 7C 86 | cmp cmd, #40 WZ ' 40 = default background -38D0(0317) 00 4A E8 A0 | if_z mov bgcol, #%0000 ' black -38D4(0318) 29 02 7C 86 | cmp cmd, #41 WZ ' 41 = background color 1 -38D8(0319) 01 4A E8 A0 | if_z mov bgcol, #%0001 -38DC(031A) 2A 02 7C 86 | cmp cmd, #42 WZ ' 42 = background color 2 -38E0(031B) 02 4A E8 A0 | if_z mov bgcol, #%0010 -38E4(031C) 2B 02 7C 86 | cmp cmd, #43 WZ ' 43 = background color 3 -38E8(031D) 03 4A E8 A0 | if_z mov bgcol, #%0011 -38EC(031E) 2C 02 7C 86 | cmp cmd, #44 WZ ' 44 = background color 4 -38F0(031F) 04 4A E8 A0 | if_z mov bgcol, #%0100 -38F4(0320) 2D 02 7C 86 | cmp cmd, #45 WZ ' 45 = background color 5 -38F8(0321) 05 4A E8 A0 | if_z mov bgcol, #%0101 -38FC(0322) 2E 02 7C 86 | cmp cmd, #46 WZ ' 46 = background color 6 -3900(0323) 06 4A E8 A0 | if_z mov bgcol, #%0110 -3904(0324) 2F 02 7C 86 | cmp cmd, #47 WZ ' 47 = background color 7 -3908(0325) 07 4A E8 A0 | if_z mov bgcol, #%0111 -390C(0326) 31 02 7C 86 | cmp cmd, #49 WZ ' 49 = default background -3910(0327) 00 4A E8 A0 | if_z mov bgcol, #%0000 ' black -3914(0328) 00 54 7C 86 | cmp csi_argf, #0 WZ ' no arguments specified? -3918(0329) 43 00 68 5C | if_z jmp #cmdloop -391C(032A) BB 86 FD 5C | call #shift_csi_args -3920(032B) 01 52 FC 86 | sub csi_argc, #1 WZ -3924(032C) 3C 25 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :get_arg) -3928(032D) 6A 01 7C 5C | jmp #set_color -392C(032E) | do_scroll_range -392C(032E) 02 52 7C 87 | cmp csi_argc, #2 WZ, WC ' 2 arguments specified? -3930(032F) 0C 24 CC 80 | if_ae add lmm_pc, #4*(:set_range - $ - 1) -3934(0330) 01 14 FC A0 | mov scroll_top, #1 -3938(0331) 08 16 BC A0 | mov scroll_bot, screen_h -393C(0332) 2C 24 FC 80 | add lmm_pc, #4*(:bottom_ok - $ - 1) -3940(0333) | :set_range -3940(0333) 2B 14 BC A0 | mov scroll_top, csi_args -3944(0334) 2C 16 BC A0 | mov scroll_bot, csi_args + 1 -3948(0335) 0B 14 3C 87 | cmp scroll_top, scroll_bot WZ, WC ' bottom => top? -394C(0336) 0C 24 F8 80 | if_be add lmm_pc, #4*(:order_ok - $ - 1) -3950(0337) 01 14 FC A0 | mov scroll_top, #1 -3954(0338) 08 16 BC A0 | mov scroll_bot, screen_h -3958(0339) 10 24 FC 80 | add lmm_pc, #4*(:bottom_ok - $ - 1) -395C(033A) | :order_ok -395C(033A) 08 16 3C 87 | cmp scroll_bot, screen_h WZ, WC ' bottom > screen height? -3960(033B) 08 24 F8 80 | if_be add lmm_pc, #4*(:bottom_ok - $ - 1) -3964(033C) 01 14 FC A0 | mov scroll_top, #1 -3968(033D) 08 16 BC A0 | mov scroll_bot, screen_h -396C(033E) | :bottom_ok -396C(033E) 01 14 FC 84 | sub scroll_top, #1 -3970(033F) 00 3A FC A0 | mov cur_x, #0 -3974(0340) 00 3E FC A0 | mov cur_y, #0 -3978(0341) 37 00 7C 5C | jmp #goto_xay -397C(0342) | do_save_cursor -397C(0342) 1D 26 BC A0 | mov cur_x_save, cur_x -3980(0343) 1E 2A BC A0 | mov new_x_save, new_x -3984(0344) 1F 28 BC A0 | mov cur_y_save, cur_y -3988(0345) 20 2C BC A0 | mov attr_save, attr -398C(0346) 43 00 7C 5C | jmp #cmdloop -3990(0347) | do_restore_cursor -3990(0347) 13 3A BC A0 | mov cur_x, cur_x_save -3994(0348) 15 3C BC A0 | mov new_x, new_x_save -3998(0349) 14 3E BC A0 | mov cur_y, cur_y_save -399C(034A) 16 40 BC A0 | mov attr, attr_save -39A0(034B) 43 00 7C 5C | jmp #cmdloop -|===========================================================================| -|===========================================================================| -Spin Block start with 1 Parameters and 0 Extra Stack Longs. Method 1 -PUB start(params) : okay - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - params -|===========================================================================| -29 stop -Addr : 39A4: 01 : Drop Anchor -Addr : 39A5: 05 02 : Call Sub 2 -30 okay := cog := COGNEW(@entry, params) + 1 -Addr : 39A7: 34 : Constant 0 $FFFFFFFF -Addr : 39A8: C7 0C : Memory Op Long PBASE + ADDRESS Address = 000C -Addr : 39AA: 64 : Variable Operation Local Offset - 1 Read -Addr : 39AB: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 39AC: 36 : Constant 2 $00000001 -Addr : 39AD: EC : Math Op + -Addr : 39AE: 42 80 : Variable Operation Global Offset - 0 Assign Write Push -Addr : 39B0: 61 : Variable Operation Local Offset - 0 Write -Addr : 39B1: 32 : Return -|===========================================================================| -Spin Block stop with 0 Parameters and 0 Extra Stack Longs. Method 2 -PUB stop : okay - -Local Parameter DBASE:0000 - Result -|===========================================================================| -33 if cog -Addr : 39B2: 40 : Variable Operation Global Offset - 0 Read -Addr : 39B3: JZ Label0008 -Addr : 39B3: 0A 05 : jz Address = 39BA 5 -34 COGSTOP(cog~~ - 1) -Addr : 39B5: 42 9C : Variable Operation Global Offset - 0 Assign VAR~~ Post-set Push -Addr : 39B7: 36 : Constant 2 $00000001 -Addr : 39B8: ED : Math Op - -Addr : 39B9: 21 : CogStop(id) -Addr : 39BA: Label0008 -Addr : 39BA: Label0009 -Addr : 39BA: 32 : Return -|===========================================================================| -Object Keyboard -Object Base is 39BC -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0004 Variable cog -VBASE : 0004 LONG Size 0004 Variable par_tail -VBASE : 0008 LONG Size 0004 Variable par_head -VBASE : 000C LONG Size 0004 Variable par_present -VBASE : 0010 LONG Size 0020 Variable par_states -VBASE : 0030 LONG Size 0020 Variable par_keys -VBASE : 0050 LONG Size 0004 Variable nkey -VBASE : 0054 LONG Size 0004 Variable dkeyhd -VBASE : 0058 LONG Size 0004 Variable dkeytail -VBASE : 005C BYTE Size 0010 Variable dkeys -|===========================================================================| -Object DAT Blocks -|===========================================================================| -39F4(0000) | org -39F4(0000) 3D 09 FC 54 | entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto -39F8(0001) F0 61 BE A0 | mov x,par -39FC(0002) 2C 60 FE 80 | add x,#11*4 -3A00(0003) 04 62 FE A0 | mov y,#4 -3A04(0004) 30 01 BC 08 | :par rdlong 0,x -3A08(0005) D8 08 BC 80 | add :par,dlsb -3A0C(0006) 04 60 FE 80 | add x,#4 -3A10(0007) 04 62 FE E4 | djnz y,#:par -3A14(0008) 01 58 FE A0 | mov dmask,#1 'set pin masks -3A18(0009) 3D 59 BE 2C | shl dmask,_dpin -3A1C(000A) 01 5A FE A0 | mov cmask,#1 -3A20(000B) 3E 5B BE 2C | shl cmask,_cpin -3A24(000C) 20 7A 7E 61 | test _dpin,#$20 wc 'modify port registers within code -3A28(000D) D8 3E BD 70 | muxc _d1,dlsb -3A2C(000E) D8 52 BD 70 | muxc _d2,dlsb -3A30(000F) 01 76 FD 70 | muxc _d3,#1 -3A34(0010) 01 94 FD 70 | muxc _d4,#1 -3A38(0011) 20 7C 7E 61 | test _cpin,#$20 wc -3A3C(0012) D8 38 BD 70 | muxc _c1,dlsb -3A40(0013) D8 44 BD 70 | muxc _c2,dlsb -3A44(0014) 01 92 FD 70 | muxc _c3,#1 -3A48(0015) 00 66 FE A0 | mov _head,#0 'reset output parameter _head -3A4C(0016) 00 EC FF A0 | reset mov dira,#0 'reset directions -3A50(0017) 00 EE FF A0 | mov dirb,#0 -3A54(0018) 34 35 FC 54 | movd :par,#_present 'reset output parameters _present/_states[8] -3A58(0019) 09 60 FE A0 | mov x,#1+8 -3A5C(001A) 00 00 FC A0 | :par mov 0,#0 -3A60(001B) D8 34 BC 80 | add :par,dlsb -3A64(001C) 1A 60 FE E4 | djnz x,#:par -3A68(001D) 08 5C FE A0 | mov stat,#8 'set reset flag -3A6C(001E) 33 45 FC 54 | update movd :par,#_head 'update output parameters _head/_present/_states[8] -3A70(001F) F0 61 BE A0 | mov x,par -3A74(0020) 04 60 FE 80 | add x,#1*4 -3A78(0021) 0A 62 FE A0 | mov y,#1+1+8 -3A7C(0022) 30 01 3C 08 | :par wrlong 0,x -3A80(0023) D8 44 BC 80 | add :par,dlsb -3A84(0024) 04 60 FE 80 | add x,#4 -3A88(0025) 22 62 FE E4 | djnz y,#:par -3A8C(0026) 08 5C 7E 61 | test stat,#8 wc 'if reset flag, transmit reset command -3A90(0027) FF 5E F2 A0 | if_c mov data,#$FF -3A94(0028) 9C 68 F1 5C | if_c call #transmit -3A98(0029) 00 5C FE A0 | newcode mov stat,#0 'reset state -3A9C(002A) B5 88 FD 5C | :same call #receive 'receive byte from keyboard -3AA0(002B) 84 5E 7E 85 | cmp data,#$83+1 wc 'scancode? -3AA4(002C) AA 5E 4E 86 | if_nc cmp data,#$AA wz 'powerup/reset? -3AA8(002D) 80 00 48 5C | if_nc_and_z jmp #configure -3AAC(002E) E0 5E 4E 86 | if_nc cmp data,#$E0 wz 'extended? -3AB0(002F) 01 5C CA 68 | if_nc_and_z or stat,#1 -3AB4(0030) 2A 00 48 5C | if_nc_and_z jmp #:same -3AB8(0031) F0 5E 4E 86 | if_nc cmp data,#$F0 wz 'released? -3ABC(0032) 02 5C CA 68 | if_nc_and_z or stat,#2 -3AC0(0033) 2A 00 48 5C | if_nc_and_z jmp #:same -3AC4(0034) 29 00 4C 5C | if_nc jmp #newcode 'unknown, ignore -3AC8(0035) 01 5C 7E 61 | test stat,#1 wc 'lookup code with extended flag -3ACC(0036) 01 5E FE 34 | rcl data,#1 -3AD0(0037) 94 88 FD 5C | call #look -3AD4(0038) 00 5E 7E 86 | cmp data,#0 wz 'if unknown, ignore -3AD8(0039) 29 00 68 5C | if_z jmp #newcode -3ADC(003A) 3B 65 BE A0 | mov t,_states+6 'remember lock keys in _states -3AE0(003B) 2F 61 BE A0 | mov x,data 'set/clear key bit in _states -3AE4(003C) 05 60 FE 28 | shr x,#5 -3AE8(003D) 35 61 FE 80 | add x,#_states -3AEC(003E) 30 85 BC 54 | movd :reg,x -3AF0(003F) 01 62 FE A0 | mov y,#1 -3AF4(0040) 2F 63 BE 2C | shl y,data -3AF8(0041) 02 5C 7E 61 | test stat,#2 wc -3AFC(0042) 31 01 BC 74 | :reg muxnc 0,y -3B00(0043) F0 5E CE E1 | if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done -3B04(0044) 1E 00 70 5C | if_c jmp #update -3B08(0045) 3C 63 BE A0 | mov y,_states+7 'get shift/ctrl/alt/win bit pairs -3B0C(0046) 10 62 FE 28 | shr y,#16 -3B10(0047) E0 5E FE E1 | cmpsub data,#$E0 wc 'translate keypad, considering numlock -3B14(0048) 04 7E 72 62 | if_c test _locks,#%100 wz -3B18(0049) 08 5F E2 80 | if_c_and_z add data,#@keypad1-@table -3B1C(004A) 18 5F D2 80 | if_c_and_nz add data,#@keypad2-@table -3B20(004B) 94 88 F1 5C | if_c call #look -3B24(004C) 6A 00 70 5C | if_c jmp #:flags -3B28(004D) DD 5E FE E1 | cmpsub data,#$DD wc 'handle scrlock/capslock/numlock -3B2C(004E) 08 60 F2 A0 | if_c mov x,#%001_000 -3B30(004F) 2F 61 B2 2C | if_c shl x,data -3B34(0050) 3F 61 B2 64 | if_c andn x,_locks -3B38(0051) 03 60 F2 28 | if_c shr x,#3 -3B3C(0052) 1D 64 F2 28 | if_c shr t,#29 'ignore auto-repeat -3B40(0053) 32 61 B2 66 | if_c andn x,t wz -3B44(0054) 30 7F B2 6C | if_c xor _locks,x -3B48(0055) DD 5E F2 80 | if_c add data,#$DD -3B4C(0056) 04 5C D2 68 | if_c_and_nz or stat,#4 'if change, set configure flag to update leds -3B50(0057) 03 62 7E 62 | test y,#%11 wz 'get shift into nz -3B54(0058) 61 5E 56 85 | if_nz cmp data,#$60+1 wc 'check shift1 -3B58(0059) 5B 5E D2 E1 | if_nz_and_c cmpsub data,#$5B wc -3B5C(005A) 28 5F D2 80 | if_nz_and_c add data,#@shift1-@table -3B60(005B) 94 88 D1 5C | if_nz_and_c call #look -3B64(005C) 03 62 D2 64 | if_nz_and_c andn y,#%11 -3B68(005D) 3E 5E 56 85 | if_nz cmp data,#$3D+1 wc 'check shift2 -3B6C(005E) 27 5E D2 E1 | if_nz_and_c cmpsub data,#$27 wc -3B70(005F) 2E 5F D2 80 | if_nz_and_c add data,#@shift2-@table -3B74(0060) 94 88 D1 5C | if_nz_and_c call #look -3B78(0061) 03 62 D2 64 | if_nz_and_c andn y,#%11 -3B7C(0062) 02 7E 7E 61 | test _locks,#%010 wc 'check shift-alpha, considering capslock -3B80(0063) 20 D0 FC 74 | muxnc :shift,#$20 -3B84(0064) 40 7E 7E 61 | test _locks,#$40 wc -3B88(0065) 20 D0 C4 6C | if_nz_and_nc xor :shift,#$20 -3B8C(0066) 7B 5E 7E 85 | cmp data,#"z"+1 wc -3B90(0067) 61 5E F2 E1 | if_c cmpsub data,#"a" wc -3B94(0068) 41 5E F2 80 | :shift if_c add data,#"A" -3B98(0069) 03 62 F2 64 | if_c andn y,#%11 -3B9C(006A) 08 5E FE 20 | :flags ror data,#8 'add shift/ctrl/alt/win flags -3BA0(006B) 04 60 FE A0 | mov x,#4 '+$100 if shift -3BA4(006C) 03 62 7E 62 | :loop test y,#%11 wz '+$200 if ctrl -3BA8(006D) 02 62 FE 28 | shr y,#2 '+$400 if alt -3BAC(006E) 01 5E D6 68 | if_nz or data,#1 '+$800 if win -3BB0(006F) 01 5E FE 20 | ror data,#1 -3BB4(0070) 6C 60 FE E4 | djnz x,#:loop -3BB8(0071) 0C 5E FE 24 | rol data,#12 -3BBC(0072) F0 61 BE 08 | rdlong x,par 'if room in buffer and key valid, enter -3BC0(0073) 01 60 FE 84 | sub x,#1 -3BC4(0074) 0F 60 FE 60 | and x,#$F -3BC8(0075) 33 61 3E 86 | cmp x,_head wz -3BCC(0076) FF 5E 56 62 | if_nz test data,#$FF wz -3BD0(0077) F0 61 96 A0 | if_nz mov x,par -3BD4(0078) 2C 60 D6 80 | if_nz add x,#11*4 -3BD8(0079) 33 61 96 80 | if_nz add x,_head -3BDC(007A) 33 61 96 80 | if_nz add x,_head -3BE0(007B) 30 5F 16 04 | if_nz wrword data,x -3BE4(007C) 01 66 D6 80 | if_nz add _head,#1 -3BE8(007D) 0F 66 D6 60 | if_nz and _head,#$F -3BEC(007E) 04 5C 7E 61 | test stat,#4 wc 'if not configure flag, done -3BF0(007F) 1E 00 4C 5C | if_nc jmp #update 'else configure to update leds -3BF4(0080) F3 5E FE A0 | configure mov data,#$F3 'set keyboard auto-repeat -3BF8(0081) 9C 68 FD 5C | call #transmit -3BFC(0082) 40 5F BE A0 | mov data,_auto -3C00(0083) 7F 5E FE 60 | and data,#%11_11111 -3C04(0084) 9C 68 FD 5C | call #transmit -3C08(0085) ED 5E FE A0 | mov data,#$ED 'set keyboard lock-leds -3C0C(0086) 9C 68 FD 5C | call #transmit -3C10(0087) 3F 5F BE A0 | mov data,_locks -3C14(0088) 1D 5E FE 3C | rev data,#-3 & $1F -3C18(0089) 04 5E 7E 61 | test data,#%100 wc -3C1C(008A) 01 5E FE 34 | rcl data,#1 -3C20(008B) 07 5E FE 60 | and data,#%111 -3C24(008C) 9C 68 FD 5C | call #transmit -3C28(008D) 3F 61 BE A0 | mov x,_locks 'insert locks into _states -3C2C(008E) 07 60 FE 60 | and x,#%111 -3C30(008F) 03 78 FE 2C | shl _states+7,#3 -3C34(0090) 30 79 BE 68 | or _states+7,x -3C38(0091) 03 78 FE 20 | ror _states+7,#3 -3C3C(0092) 01 68 FE A0 | mov _present,#1 'set _present -3C40(0093) 1E 00 7C 5C | jmp #update 'done -3C44(0094) 02 5E FE 20 | look ror data,#2 'perform lookup -3C48(0095) 2F 33 BD 50 | movs :reg,data -3C4C(0096) DA 32 FD 80 | add :reg,#table -3C50(0097) 1B 5E FE 28 | shr data,#27 -3C54(0098) 2F 61 BE A0 | mov x,data -3C58(0099) 00 5E BE A0 | :reg mov data,0 -3C5C(009A) 30 5F BE 28 | shr data,x -3C60(009B) C3 00 7C 5C | jmp #rand 'isolate byte -3C64(009C) | transmit -3C64(009C) 2D ED BF 68 | _c1 or dira,cmask 'pull clock low -3C68(009D) 0D A6 FD 50 | movs napshr,#13 'hold clock for ~128us (must be >100us) -3C6C(009E) D2 AE FD 5C | call #nap -3C70(009F) 2C ED BF 68 | _d1 or dira,dmask 'pull data low -3C74(00A0) 12 A6 FD 50 | movs napshr,#18 'hold data for ~4us -3C78(00A1) D2 AE FD 5C | call #nap -3C7C(00A2) 2D ED BF 6C | _c2 xor dira,cmask 'release clock -3C80(00A3) FF 5E 7E 61 | test data,#$0FF wc 'append parity and stop bits to byte -3C84(00A4) 00 5F FE 74 | muxnc data,#$100 -3C88(00A5) D8 5E BE 68 | or data,dlsb -3C8C(00A6) 0A 60 FE A0 | mov x,#10 'ready 10 bits -3C90(00A7) C5 9A FD 5C | transmit_bit call #wait_c0 'wait until clock low -3C94(00A8) 01 5E FE 29 | shr data,#1 wc 'output data bit -3C98(00A9) 2C ED BF 74 | _d2 muxnc dira,dmask -3C9C(00AA) CF 96 BD A0 | mov wcond,c1 'wait until clock high -3CA0(00AB) C6 9A FD 5C | call #wait -3CA4(00AC) A7 60 FE E4 | djnz x,#transmit_bit 'another bit? -3CA8(00AD) D0 96 BD A0 | mov wcond,c0d0 'wait until clock and data low -3CAC(00AE) C6 9A FD 5C | call #wait -3CB0(00AF) D1 96 BD A0 | mov wcond,c1d1 'wait until clock and data high -3CB4(00B0) C6 9A FD 5C | call #wait -3CB8(00B1) B7 88 FD 5C | call #receive_ack 'receive ack byte with timed wait -3CBC(00B2) FA 5E 7E 86 | cmp data,#$FA wz 'if ack error, reset keyboard -3CC0(00B3) 16 00 54 5C | if_nz jmp #reset -3CC4(00B4) 00 00 7C 5C | transmit_ret ret -3CC8(00B5) 20 7C 7E 61 | receive test _cpin,#$20 wc 'wait indefinitely for initial clock low -3CCC(00B6) 2D 5B 3E F4 | waitpne cmask,cmask -3CD0(00B7) | receive_ack -3CD0(00B7) 0B 60 FE A0 | mov x,#11 'ready 11 bits -3CD4(00B8) C5 9A FD 5C | receive_bit call #wait_c0 'wait until clock low -3CD8(00B9) 10 A6 FD 50 | movs napshr,#16 'pause ~16us -3CDC(00BA) D2 AE FD 5C | call #nap -3CE0(00BB) F2 59 3E 61 | _d3 test dmask,ina wc 'input data bit -3CE4(00BC) 01 5E FE 30 | rcr data,#1 -3CE8(00BD) CF 96 BD A0 | mov wcond,c1 'wait until clock high -3CEC(00BE) C6 9A FD 5C | call #wait -3CF0(00BF) B8 60 FE E4 | djnz x,#receive_bit 'another bit? -3CF4(00C0) 16 5E FE 28 | shr data,#22 'align byte -3CF8(00C1) FF 5F 7E 61 | test data,#$1FF wc 'if parity error, reset keyboard -3CFC(00C2) 16 00 4C 5C | if_nc jmp #reset -3D00(00C3) FF 5E FE 60 | rand and data,#$FF 'isolate byte -3D04(00C4) | look_ret -3D04(00C4) | receive_ack_ret -3D04(00C4) 00 00 7C 5C | receive_ret ret -3D08(00C5) CE 96 BD A0 | wait_c0 mov wcond,c0 '(wait until clock low) -3D0C(00C6) D9 62 BE A0 | wait mov y,tenms 'set timeout to 10ms -3D10(00C7) 12 A6 FD 50 | wloop movs napshr,#18 'nap ~4us -3D14(00C8) D2 AE FD 5C | call #nap -3D18(00C9) F2 5B 3E 61 | _c3 test cmask,ina wc 'check required state(s) -3D1C(00CA) F2 59 3E 62 | _d4 test dmask,ina wz 'loop until got state(s) or timeout -3D20(00CB) C7 62 C2 E4 | wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) -3D24(00CC) 16 62 7E EC | tjz y,#reset 'if timeout, reset keyboard -3D28(00CD) | wait_ret -3D28(00CD) 00 00 7C 5C | wait_c0_ret ret -3D2C(00CE) C7 62 F2 E4 | c0 if_c djnz y,#wloop '(if_never replacements) -3D30(00CF) C7 62 CE E4 | c1 if_nc djnz y,#wloop -3D34(00D0) C7 62 F6 E4 | c0d0 if_c_or_nz djnz y,#wloop -3D38(00D1) C7 62 EE E4 | c1d1 if_nc_or_z djnz y,#wloop -3D3C(00D2) 00 64 FE 08 | nap rdlong t,#0 'get clkfreq -3D40(00D3) 00 64 FE 28 | napshr shr t,#18/16/13 'shr scales time -3D44(00D4) 03 64 FE 48 | min t,#3 'ensure waitcnt won't snag -3D48(00D5) F1 65 BE 80 | add t,cnt 'add cnt to time -3D4C(00D6) 00 64 FE F8 | waitcnt t,#0 'wait until time elapses (nap) -3D50(00D7) 00 00 7C 5C | nap_ret ret -3D54(00D8) 00 02 00 00 | dlsb long 1 << 9 -3D58(00D9) C4 09 00 00 | tenms long 10_000 / 4 -3D5C(00DA) 00 00 | table word $0000 '00 -3D5E(00DA) D8 00 | word $00D8 '01 F9 -3D60(00DB) 00 00 | word $0000 '02 -3D62(00DB) D4 00 | word $00D4 '03 F5 -3D64(00DC) D2 00 | word $00D2 '04 F3 -3D66(00DC) D0 00 | word $00D0 '05 F1 -3D68(00DD) D1 00 | word $00D1 '06 F2 -3D6A(00DD) DB 00 | word $00DB '07 F12 -3D6C(00DE) 00 00 | word $0000 '08 -3D6E(00DE) D9 00 | word $00D9 '09 F10 -3D70(00DF) D7 00 | word $00D7 '0A F8 -3D72(00DF) D5 00 | word $00D5 '0B F6 -3D74(00E0) D3 00 | word $00D3 '0C F4 -3D76(00E0) 09 00 | word $0009 '0D Tab -3D78(00E1) 60 00 | word $0060 '0E ` -3D7A(00E1) 00 00 | word $0000 '0F -3D7C(00E2) 00 00 | word $0000 '10 -3D7E(00E2) F4 F5 | word $F5F4 '11 Alt-R Alt-L -3D80(00E3) F0 00 | word $00F0 '12 Shift-L -3D82(00E3) 00 00 | word $0000 '13 -3D84(00E4) F2 F3 | word $F3F2 '14 Ctrl-R Ctrl-L -3D86(00E4) 71 00 | word $0071 '15 q -3D88(00E5) 31 00 | word $0031 '16 1 -3D8A(00E5) 00 00 | word $0000 '17 -3D8C(00E6) 00 00 | word $0000 '18 -3D8E(00E6) 00 00 | word $0000 '19 -3D90(00E7) 7A 00 | word $007A '1A z -3D92(00E7) 73 00 | word $0073 '1B s -3D94(00E8) 61 00 | word $0061 '1C a -3D96(00E8) 77 00 | word $0077 '1D w -3D98(00E9) 32 00 | word $0032 '1E 2 -3D9A(00E9) 00 F6 | word $F600 '1F Win-L -3D9C(00EA) 00 00 | word $0000 '20 -3D9E(00EA) 63 00 | word $0063 '21 c -3DA0(00EB) 78 00 | word $0078 '22 x -3DA2(00EB) 64 00 | word $0064 '23 d -3DA4(00EC) 65 00 | word $0065 '24 e -3DA6(00EC) 34 00 | word $0034 '25 4 -3DA8(00ED) 33 00 | word $0033 '26 3 -3DAA(00ED) 00 F7 | word $F700 '27 Win-R -3DAC(00EE) 00 00 | word $0000 '28 -3DAE(00EE) 20 00 | word $0020 '29 Space -3DB0(00EF) 76 00 | word $0076 '2A v -3DB2(00EF) 66 00 | word $0066 '2B f -3DB4(00F0) 74 00 | word $0074 '2C t -3DB6(00F0) 72 00 | word $0072 '2D r -3DB8(00F1) 35 00 | word $0035 '2E 5 -3DBA(00F1) 00 CC | word $CC00 '2F Apps -3DBC(00F2) 00 00 | word $0000 '30 -3DBE(00F2) 6E 00 | word $006E '31 n -3DC0(00F3) 62 00 | word $0062 '32 b -3DC2(00F3) 68 00 | word $0068 '33 h -3DC4(00F4) 67 00 | word $0067 '34 g -3DC6(00F4) 79 00 | word $0079 '35 y -3DC8(00F5) 36 00 | word $0036 '36 6 -3DCA(00F5) 00 CD | word $CD00 '37 Power -3DCC(00F6) 00 00 | word $0000 '38 -3DCE(00F6) 00 00 | word $0000 '39 -3DD0(00F7) 6D 00 | word $006D '3A m -3DD2(00F7) 6A 00 | word $006A '3B j -3DD4(00F8) 75 00 | word $0075 '3C u -3DD6(00F8) 37 00 | word $0037 '3D 7 -3DD8(00F9) 38 00 | word $0038 '3E 8 -3DDA(00F9) 00 CE | word $CE00 '3F Sleep -3DDC(00FA) 00 00 | word $0000 '40 -3DDE(00FA) 2C 00 | word $002C '41 , -3DE0(00FB) 6B 00 | word $006B '42 k -3DE2(00FB) 69 00 | word $0069 '43 i -3DE4(00FC) 6F 00 | word $006F '44 o -3DE6(00FC) 30 00 | word $0030 '45 0 -3DE8(00FD) 39 00 | word $0039 '46 9 -3DEA(00FD) 00 00 | word $0000 '47 -3DEC(00FE) 00 00 | word $0000 '48 -3DEE(00FE) 2E 00 | word $002E '49 . -3DF0(00FF) 2F EF | word $EF2F '4A (/) / -3DF2(00FF) 6C 00 | word $006C '4B l -3DF4(0100) 3B 00 | word $003B '4C ; -3DF6(0100) 70 00 | word $0070 '4D p -3DF8(0101) 2D 00 | word $002D '4E - -3DFA(0101) 00 00 | word $0000 '4F -3DFC(0102) 00 00 | word $0000 '50 -3DFE(0102) 00 00 | word $0000 '51 -3E00(0103) 27 00 | word $0027 '52 ' -3E02(0103) 00 00 | word $0000 '53 -3E04(0104) 5B 00 | word $005B '54 [ -3E06(0104) 3D 00 | word $003D '55 = -3E08(0105) 00 00 | word $0000 '56 -3E0A(0105) 00 00 | word $0000 '57 -3E0C(0106) DE 00 | word $00DE '58 CapsLock -3E0E(0106) F1 00 | word $00F1 '59 Shift-R -3E10(0107) 0D EB | word $EB0D '5A (Enter) Enter -3E12(0107) 5D 00 | word $005D '5B ] -3E14(0108) 00 00 | word $0000 '5C -3E16(0108) 5C 00 | word $005C '5D \ -3E18(0109) 00 CF | word $CF00 '5E WakeUp -3E1A(0109) 00 00 | word $0000 '5F -3E1C(010A) 00 00 | word $0000 '60 -3E1E(010A) 00 00 | word $0000 '61 -3E20(010B) 00 00 | word $0000 '62 -3E22(010B) 00 00 | word $0000 '63 -3E24(010C) 00 00 | word $0000 '64 -3E26(010C) 00 00 | word $0000 '65 -3E28(010D) C8 00 | word $00C8 '66 BackSpace -3E2A(010D) 00 00 | word $0000 '67 -3E2C(010E) 00 00 | word $0000 '68 -3E2E(010E) E1 C5 | word $C5E1 '69 End (1) -3E30(010F) 00 00 | word $0000 '6A -3E32(010F) E4 C0 | word $C0E4 '6B Left (4) -3E34(0110) E7 C4 | word $C4E7 '6C Home (7) -3E36(0110) 00 00 | word $0000 '6D -3E38(0111) 00 00 | word $0000 '6E -3E3A(0111) 00 00 | word $0000 '6F -3E3C(0112) E0 CA | word $CAE0 '70 Insert (0) -3E3E(0112) EA C9 | word $C9EA '71 Delete (.) -3E40(0113) E2 C3 | word $C3E2 '72 Down (2) -3E42(0113) E5 00 | word $00E5 '73 (5) -3E44(0114) E6 C1 | word $C1E6 '74 Right (6) -3E46(0114) E8 C2 | word $C2E8 '75 Up (8) -3E48(0115) CB 00 | word $00CB '76 Esc -3E4A(0115) DF 00 | word $00DF '77 NumLock -3E4C(0116) DA 00 | word $00DA '78 F11 -3E4E(0116) EC 00 | word $00EC '79 (+) -3E50(0117) E3 C7 | word $C7E3 '7A PageDn (3) -3E52(0117) ED 00 | word $00ED '7B (-) -3E54(0118) EE DC | word $DCEE '7C PrScr (*) -3E56(0118) E9 C6 | word $C6E9 '7D PageUp (9) -3E58(0119) DD 00 | word $00DD '7E ScrLock -3E5A(0119) 00 00 | word $0000 '7F -3E5C(011A) 00 00 | word $0000 '80 -3E5E(011A) 00 00 | word $0000 '81 -3E60(011B) 00 00 | word $0000 '82 -3E62(011B) D6 00 | word $00D6 '83 F7 -3E64(011C) CA | keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" -3E65(011C) C5 | -3E66(011C) C3 | -3E67(011C) C7 | -3E68(011D) C0 | -3E69(011D) 00 | -3E6A(011D) C1 | -3E6B(011D) C4 | -3E6C(011E) C2 | -3E6D(011E) C6 | -3E6E(011E) C9 | -3E6F(011E) 0D | -3E70(011F) 2B | -3E71(011F) 2D | -3E72(011F) 2A | -3E73(011F) 2F | -3E74(0120) 30 | keypad2 byte "0123456789.", $0D, "+-*/" -3E75(0120) 31 | -3E76(0120) 32 | -3E77(0120) 33 | -3E78(0121) 34 | -3E79(0121) 35 | -3E7A(0121) 36 | -3E7B(0121) 37 | -3E7C(0122) 38 | -3E7D(0122) 39 | -3E7E(0122) 2E | -3E7F(0122) 0D | -3E80(0123) 2B | -3E81(0123) 2D | -3E82(0123) 2A | -3E83(0123) 2F | -3E84(0124) 7B | shift1 byte "{|}", 0, 0, "~" -3E85(0124) 7C | -3E86(0124) 7D | -3E87(0124) 00 | -3E88(0125) 00 | -3E89(0125) 7E | -3E8A(0125) 22 | shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" -3E8B(0125) 00 | -3E8C(0126) 00 | -3E8D(0126) 00 | -3E8E(0126) 00 | -3E8F(0126) 3C | -3E90(0127) 5F | -3E91(0127) 3E | -3E92(0127) 3F | -3E93(0127) 29 | -3E94(0128) 21 | -3E95(0128) 40 | -3E96(0128) 23 | -3E97(0128) 24 | -3E98(0129) 25 | -3E99(0129) 5E | -3E9A(0129) 26 | -3E9B(0129) 2A | -3E9C(012A) 28 | -3E9D(012A) 00 | -3E9E(012A) 3A | -3E9F(012A) 00 | -3EA0(012B) 2B | -3EA1(012B) | dmask res 1 -3EA4(012D) | cmask res 1 -3EA4(012E) | stat res 1 -3EA4(012F) | data res 1 -3EA4(0130) | x res 1 -3EA4(0131) | y res 1 -3EA4(0132) | t res 1 -3EA4(0133) | _head res 1 'write-only -3EA4(0134) | _present res 1 'write-only -3EA4(0135) | _states res 8 'write-only -3EA4(013D) | _dpin res 1 'read-only at start -3EA4(013E) | _cpin res 1 'read-only at start -3EA4(013F) | _locks res 1 'read-only at start -3EA4(0140) | _auto res 1 'read-only at start -|===========================================================================| -|===========================================================================| -Spin Block start with 2 Parameters and 0 Extra Stack Longs. Method 1 -PUB start(dpin, cpin) : okay - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - dpin -Local Parameter DBASE:0008 - cpin -|===========================================================================| -40 okay := startx(dpin, cpin, %0_000_100, %01_01000) -Addr : 3EA4: 00 : Drop Anchor Push -Addr : 3EA5: 64 : Variable Operation Local Offset - 1 Read -Addr : 3EA6: 68 : Variable Operation Local Offset - 2 Read -Addr : 3EA7: 37 01 : Constant Mask Y=1 00000004 -Addr : 3EA9: 38 28 : Constant 1 Bytes - 28 -Addr : 3EAB: 05 02 : Call Sub 2 -Addr : 3EAD: 61 : Variable Operation Local Offset - 0 Write -41 nkey := dkeyhd := dkeytail := 0 -Addr : 3EAE: 35 : Constant 1 $00000000 -Addr : 3EAF: CA 58 80 : Memory Op Long VBASE + ASSIGN Address = 0058 Write Push -Addr : 3EB2: CA 54 80 : Memory Op Long VBASE + ASSIGN Address = 0054 Write Push -Addr : 3EB5: C9 50 : Memory Op Long VBASE + WRITE Address = 0050 -Addr : 3EB7: 32 : Return -|===========================================================================| -Spin Block startx with 4 Parameters and 0 Extra Stack Longs. Method 2 -PUB startx(dpin, cpin, locks, auto) : okay - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - dpin -Local Parameter DBASE:0008 - cpin -Local Parameter DBASE:000C - locks -Local Parameter DBASE:0010 - auto -|===========================================================================| -59 stop -Addr : 3EB8: 01 : Drop Anchor -Addr : 3EB9: 05 03 : Call Sub 3 -60 longmove(@par_keys, @dpin, 4) -Addr : 3EBB: CB 30 : Memory Op Long VBASE + ADDRESS Address = 0030 -Addr : 3EBD: 67 : Variable Operation Local Offset - 1 Address -Addr : 3EBE: 37 01 : Constant Mask Y=1 00000004 -Addr : 3EC0: 1E : LongMove(To, From, Count) -61 okay := cog := cognew(@entry, @par_tail) + 1 -Addr : 3EC1: 34 : Constant 0 $FFFFFFFF -Addr : 3EC2: C7 38 : Memory Op Long PBASE + ADDRESS Address = 0038 -Addr : 3EC4: 47 : Variable Operation Global Offset - 1 Address -Addr : 3EC5: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 3EC6: 36 : Constant 2 $00000001 -Addr : 3EC7: EC : Math Op + -Addr : 3EC8: 42 80 : Variable Operation Global Offset - 0 Assign Write Push -Addr : 3ECA: 61 : Variable Operation Local Offset - 0 Write -Addr : 3ECB: 32 : Return -|===========================================================================| -Spin Block stop with 0 Parameters and 0 Extra Stack Longs. Method 3 -PUB stop - -Local Parameter DBASE:0000 - Result -|===========================================================================| -68 if cog -Addr : 3ECC: 40 : Variable Operation Global Offset - 0 Read -Addr : 3ECD: JZ Label0002 -Addr : 3ECD: 0A 05 : jz Address = 3ED4 5 -69 cogstop(cog~ - 1) -Addr : 3ECF: 42 98 : Variable Operation Global Offset - 0 Assign VAR~ Post-clear Push -Addr : 3ED1: 36 : Constant 2 $00000001 -Addr : 3ED2: ED : Math Op - -Addr : 3ED3: 21 : CogStop(id) -Addr : 3ED4: Label0002 -Addr : 3ED4: Label0003 -70 longfill(@par_tail, 0, 19) -Addr : 3ED4: 47 : Variable Operation Global Offset - 1 Address -Addr : 3ED5: 35 : Constant 1 $00000000 -Addr : 3ED6: 38 13 : Constant 1 Bytes - 13 -Addr : 3ED8: 1A : LongFill(Start, Value, Count) -Addr : 3ED9: 32 : Return -|===========================================================================| -Spin Block present with 0 Parameters and 0 Extra Stack Longs. Method 4 -PUB present : truefalse - -Local Parameter DBASE:0000 - Result -|===========================================================================| -78 truefalse := -par_present -Addr : 3EDA: 4C : Variable Operation Global Offset - 3 Read -Addr : 3EDB: E6 : Math Op - -Addr : 3EDC: 61 : Variable Operation Local Offset - 0 Write -Addr : 3EDD: 32 : Return -|===========================================================================| -Spin Block key with 0 Parameters and 0 Extra Stack Longs. Method 5 -PUB key : keycode - -Local Parameter DBASE:0000 - Result -|===========================================================================| -93 if par_tail <> par_head -Addr : 3EDE: 44 : Variable Operation Global Offset - 1 Read -Addr : 3EDF: 48 : Variable Operation Global Offset - 2 Read -Addr : 3EE0: FB : Math Op <> -Addr : 3EE1: JZ Label0002 -Addr : 3EE1: 0A 0A : jz Address = 3EED 10 -94 keycode := par_keys.word[par_tail] -Addr : 3EE3: 44 : Variable Operation Global Offset - 1 Read -Addr : 3EE4: B8 30 : Memory Op Word VBASE + POP Index READ Address = 0030 -Addr : 3EE6: 61 : Variable Operation Local Offset - 0 Write -95 par_tail := ++par_tail & $F -Addr : 3EE7: 46 A6 : Variable Operation Global Offset - 1 Assign ++VAR pre-inc Long Push -Addr : 3EE9: 37 23 : Constant Mask Y=35 Decrement 0000000F -Addr : 3EEB: E8 : Math Op & -Addr : 3EEC: 45 : Variable Operation Global Offset - 1 Write -Addr : 3EED: Label0002 -Addr : 3EED: Label0003 -Addr : 3EED: 32 : Return -|===========================================================================| -Spin Block getkey with 0 Parameters and 1 Extra Stack Longs. Method 6 -PUB getkey : keycode | temp - -Local Parameter DBASE:0000 - Result -Local Variable DBASE:0004 - temp -|===========================================================================| -160 temp := key -Addr : 3EEE: 00 : Drop Anchor Push -Addr : 3EEF: 05 05 : Call Sub 5 -Addr : 3EF1: 65 : Variable Operation Local Offset - 1 Write -162 if temp > 0 -Addr : 3EF2: 64 : Variable Operation Local Offset - 1 Read -Addr : 3EF3: 35 : Constant 1 $00000000 -Addr : 3EF4: FA : Math Op > -Addr : 3EF5: JZ Label0002 -Addr : 3EF5: 0A 04 : jz Address = 3EFB 4 -163 decode_key(temp) -Addr : 3EF7: 01 : Drop Anchor -Addr : 3EF8: 64 : Variable Operation Local Offset - 1 Read -Addr : 3EF9: 05 0D : Call Sub 13 -Addr : 3EFB: Label0002 -Addr : 3EFB: Label0003 -165 keycode := 0 -Addr : 3EFB: 35 : Constant 1 $00000000 -Addr : 3EFC: 61 : Variable Operation Local Offset - 0 Write -166 if nkey -Addr : 3EFD: C8 50 : Memory Op Long VBASE + READ Address = 0050 -Addr : 3EFF: JZ Label0004 -Addr : 3EFF: 0A 14 : jz Address = 3F15 20 -167 nkey -= 1 -Addr : 3F01: 36 : Constant 2 $00000001 -Addr : 3F02: CA 50 4D : Memory Op Long VBASE + ASSIGN Address = 0050 WordMathop - -168 keycode := dkeys[dkeytail] -Addr : 3F05: C8 58 : Memory Op Long VBASE + READ Address = 0058 -Addr : 3F07: 98 5C : Memory Op Byte VBASE + POP Index READ Address = 005C -Addr : 3F09: 61 : Variable Operation Local Offset - 0 Write -169 dkeys[dkeytail++] := 0 -Addr : 3F0A: 35 : Constant 1 $00000000 -Addr : 3F0B: CA 58 AE : Memory Op Long VBASE + ASSIGN Address = 0058 VAR++ post inc Long Push -Addr : 3F0E: 99 5C : Memory Op Byte VBASE + POP Index WRITE Address = 005C -170 dkeytail &= $F -Addr : 3F10: 37 23 : Constant Mask Y=35 Decrement 0000000F -Addr : 3F12: CA 58 48 : Memory Op Long VBASE + ASSIGN Address = 0058 BitMathop & -Addr : 3F15: Label0004 -Addr : 3F15: Label0005 -Addr : 3F15: 32 : Return -|===========================================================================| -Spin Block newkey with 0 Parameters and 0 Extra Stack Longs. Method 7 -PUB newkey : keycode - -Local Parameter DBASE:0000 - Result -|===========================================================================| -178 par_tail := par_head -Addr : 3F16: 48 : Variable Operation Global Offset - 2 Read -Addr : 3F17: 45 : Variable Operation Global Offset - 1 Write -179 keycode := getkey -Addr : 3F18: 00 : Drop Anchor Push -Addr : 3F19: 05 06 : Call Sub 6 -Addr : 3F1B: 61 : Variable Operation Local Offset - 0 Write -Addr : 3F1C: 32 : Return -|===========================================================================| -Spin Block gotkey with 0 Parameters and 1 Extra Stack Longs. Method 8 -PUB gotkey : truefalse | temp - -Local Parameter DBASE:0000 - Result -Local Variable DBASE:0004 - temp -|===========================================================================| -190 temp := key -Addr : 3F1D: 00 : Drop Anchor Push -Addr : 3F1E: 05 05 : Call Sub 5 -Addr : 3F20: 65 : Variable Operation Local Offset - 1 Write -192 if temp > 0 -Addr : 3F21: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F22: 35 : Constant 1 $00000000 -Addr : 3F23: FA : Math Op > -Addr : 3F24: JZ Label0002 -Addr : 3F24: 0A 04 : jz Address = 3F2A 4 -193 decode_key(temp) -Addr : 3F26: 01 : Drop Anchor -Addr : 3F27: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F28: 05 0D : Call Sub 13 -Addr : 3F2A: Label0002 -Addr : 3F2A: Label0003 -195 return nkey -Addr : 3F2A: C8 50 : Memory Op Long VBASE + READ Address = 0050 -Addr : 3F2C: 33 : Return value -Addr : 3F2D: Data : 32 2 -|===========================================================================| -Spin Block clearkeys with 0 Parameters and 0 Extra Stack Longs. Method 9 -PUB clearkeys - -Local Parameter DBASE:0000 - Result -|===========================================================================| -201 par_tail := par_head -Addr : 3F2E: 48 : Variable Operation Global Offset - 2 Read -Addr : 3F2F: 45 : Variable Operation Global Offset - 1 Write -Addr : 3F30: 32 : Return -|===========================================================================| -Spin Block keystate with 1 Parameters and 0 Extra Stack Longs. Method 10 -PUB keystate(k) : state - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - k -|===========================================================================| -209 state := -(par_states[k >> 5] >> k & 1) -Addr : 3F31: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F32: 38 05 : Constant 1 Bytes - 05 -Addr : 3F34: E2 : Math Op >> -Addr : 3F35: D8 10 : Memory Op Long VBASE + POP Index READ Address = 0010 -Addr : 3F37: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F38: E2 : Math Op >> -Addr : 3F39: 36 : Constant 2 $00000001 -Addr : 3F3A: E8 : Math Op & -Addr : 3F3B: E6 : Math Op - -Addr : 3F3C: 61 : Variable Operation Local Offset - 0 Write -Addr : 3F3D: 32 : Return -|===========================================================================| -Spin Block enqueue with 1 Parameters and 0 Extra Stack Longs. Method 11 -PRI enqueue(c) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - c -|===========================================================================| -82 if nkey == 16 -Addr : 3F3E: C8 50 : Memory Op Long VBASE + READ Address = 0050 -Addr : 3F40: 37 03 : Constant Mask Y=3 00000010 -Addr : 3F42: FC : Math Op == -Addr : 3F43: JZ Label0002 -Addr : 3F43: 0A 01 : jz Address = 3F46 1 -83 return -Addr : 3F45: 32 : Return -Addr : 3F46: Label0002 -Addr : 3F46: Label0003 -84 dkeys[dkeyhd++] := c -Addr : 3F46: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F47: CA 54 AE : Memory Op Long VBASE + ASSIGN Address = 0054 VAR++ post inc Long Push -Addr : 3F4A: 99 5C : Memory Op Byte VBASE + POP Index WRITE Address = 005C -85 nkey += 1 -Addr : 3F4C: 36 : Constant 2 $00000001 -Addr : 3F4D: CA 50 4C : Memory Op Long VBASE + ASSIGN Address = 0050 WordMathop + -86 dkeyhd &=$F -Addr : 3F50: 37 23 : Constant Mask Y=35 Decrement 0000000F -Addr : 3F52: CA 54 48 : Memory Op Long VBASE + ASSIGN Address = 0054 BitMathop & -Addr : 3F55: 32 : Return -|===========================================================================| -Spin Block escstr with 1 Parameters and 1 Extra Stack Longs. Method 12 -PRI escstr(s) | xx - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - s -Local Variable DBASE:0008 - xx -|===========================================================================| -98 enqueue($1B) -Addr : 3F56: 01 : Drop Anchor -Addr : 3F57: 38 1B : Constant 1 Bytes - 1B -Addr : 3F59: 05 0B : Call Sub 11 -99 repeat xx from 0 to STRSIZE(s) - 1 -Addr : 3F5B: 35 : Constant 1 $00000000 -Addr : 3F5C: 69 : Variable Operation Local Offset - 2 Write -Addr : 3F5D: Label0002 -100 enqueue(BYTE[s][xx]) -Addr : 3F5D: 01 : Drop Anchor -Addr : 3F5E: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F5F: 68 : Variable Operation Local Offset - 2 Read -Addr : 3F60: 90 : Memory Op Byte POP Address POP Index READ -Addr : 3F61: 05 0B : Call Sub 11 -Addr : 3F63: Label0003 -99 repeat xx from 0 to STRSIZE(s) - 1 -Addr : 3F63: 35 : Constant 1 $00000000 -Addr : 3F64: 64 : Variable Operation Local Offset - 1 Read -Addr : 3F65: 16 : StrSize(String) -Addr : 3F66: 36 : Constant 2 $00000001 -Addr : 3F67: ED : Math Op - -Addr : 3F68: Repeat xx Step Label0002 -Addr : 3F68: 6A 02 72 : Variable Operation Local Offset - 2 Assign Repeat-Var loop Address= 3F5D -14 -Addr : 3F6B: Label0004 -Addr : 3F6B: 32 : Return -|===========================================================================| -Spin Block decode_key with 1 Parameters and 1 Extra Stack Longs. Method 13 -PRI decode_key(scode) | s - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - scode -Local Variable DBASE:0008 - s -|===========================================================================| -104 case scode -Addr : 3F6C: Constant Address of Label0002 -Addr : 3F6C: 39 06 47 : Constant 2 Bytes - 06 47 -Addr : 3F6F: 64 : Variable Operation Local Offset - 1 Read -106 $C0: 'LEFT -Addr : 3F70: 38 C0 : Constant 1 Bytes - C0 -Addr : 3F72: Case_Value Label0003 -Addr : 3F72: 0D 80 5C : Value Case Address = 3FD1 92 -109 $C1: 'RIGHT -Addr : 3F75: 38 C1 : Constant 1 Bytes - C1 -Addr : 3F77: Case_Value Label0005 -Addr : 3F77: 0D 80 5C : Value Case Address = 3FD6 92 -112 $C2: 'UP -Addr : 3F7A: 38 C2 : Constant 1 Bytes - C2 -Addr : 3F7C: Case_Value Label0007 -Addr : 3F7C: 0D 80 5C : Value Case Address = 3FDB 92 -115 $C3: 'DOWN -Addr : 3F7F: 38 C3 : Constant 1 Bytes - C3 -Addr : 3F81: Case_Value Label0009 -Addr : 3F81: 0D 80 5C : Value Case Address = 3FE0 92 -118 $C4: 'Home -Addr : 3F84: 38 C4 : Constant 1 Bytes - C4 -Addr : 3F86: Case_Value Label000B -Addr : 3F86: 0D 80 5C : Value Case Address = 3FE5 92 -121 $C5: 'End -Addr : 3F89: 38 C5 : Constant 1 Bytes - C5 -Addr : 3F8B: Case_Value Label000D -Addr : 3F8B: 0D 80 5C : Value Case Address = 3FEA 92 -124 $C6: 'Page Up -Addr : 3F8E: 38 C6 : Constant 1 Bytes - C6 -Addr : 3F90: Case_Value Label000F -Addr : 3F90: 0D 80 5C : Value Case Address = 3FEF 92 -127 $C7: 'Page Dn -Addr : 3F93: 38 C7 : Constant 1 Bytes - C7 -Addr : 3F95: Case_Value Label0011 -Addr : 3F95: 0D 80 5C : Value Case Address = 3FF4 92 -130 $C9: 'Delete -Addr : 3F98: 38 C9 : Constant 1 Bytes - C9 -Addr : 3F9A: Case_Value Label0013 -Addr : 3F9A: 0D 80 5C : Value Case Address = 3FF9 92 -133 $CA: 'Insert -Addr : 3F9D: 38 CA : Constant 1 Bytes - CA -Addr : 3F9F: Case_Value Label0015 -Addr : 3F9F: 0D 80 5C : Value Case Address = 3FFE 92 -138 if scode == $CB -Addr : 3FA2: 64 : Variable Operation Local Offset - 1 Read -Addr : 3FA3: 38 CB : Constant 1 Bytes - CB -Addr : 3FA5: FC : Math Op == -Addr : 3FA6: JZ Label0017 -Addr : 3FA6: 0A 03 : jz Address = 3FAB 3 -139 scode := $1B -Addr : 3FA8: 38 1B : Constant 1 Bytes - 1B -Addr : 3FAA: 65 : Variable Operation Local Offset - 1 Write -Addr : 3FAB: Label0017 -Addr : 3FAB: Label0018 -140 if scode == $C8 -Addr : 3FAB: 64 : Variable Operation Local Offset - 1 Read -Addr : 3FAC: 38 C8 : Constant 1 Bytes - C8 -Addr : 3FAE: FC : Math Op == -Addr : 3FAF: JZ Label0019 -Addr : 3FAF: 0A 03 : jz Address = 3FB4 3 -141 scode := $08 -Addr : 3FB1: 37 02 : Constant Mask Y=2 00000008 -Addr : 3FB3: 65 : Variable Operation Local Offset - 1 Write -Addr : 3FB4: Label0019 -Addr : 3FB4: Label001A -143 if (scode > $260) AND (scode < $27B) -Addr : 3FB4: 64 : Variable Operation Local Offset - 1 Read -Addr : 3FB5: 39 02 60 : Constant 2 Bytes - 02 60 -Addr : 3FB8: FA : Math Op > -Addr : 3FB9: 64 : Variable Operation Local Offset - 1 Read -Addr : 3FBA: 39 02 7B : Constant 2 Bytes - 02 7B -Addr : 3FBD: F9 : Math Op < -Addr : 3FBE: F0 : Math Op AND -Addr : 3FBF: JZ Label001B -Addr : 3FBF: 0A 04 : jz Address = 3FC5 4 -144 scode &= $1F -Addr : 3FC1: 37 24 : Constant Mask Y=36 Decrement 0000001F -Addr : 3FC3: 66 48 : Variable Operation Local Offset - 1 Assign BitMathop & -Addr : 3FC5: Label001B -Addr : 3FC5: Label001C -146 if (scode < $80) -Addr : 3FC5: 64 : Variable Operation Local Offset - 1 Read -Addr : 3FC6: 37 06 : Constant Mask Y=6 00000080 -Addr : 3FC8: F9 : Math Op < -Addr : 3FC9: JZ Label001D -Addr : 3FC9: 0A 04 : jz Address = 3FCF 4 -147 enqueue(scode) -Addr : 3FCB: 01 : Drop Anchor -Addr : 3FCC: 64 : Variable Operation Local Offset - 1 Read -Addr : 3FCD: 05 0B : Call Sub 11 -Addr : 3FCF: Label001D -Addr : 3FCF: Label001E -149 return -Addr : 3FCF: 32 : Return -Addr : 3FD0: CaseDone Label0015 -Addr : 3FD0: 0C : Casedone -Addr : 3FD1: Label0003 -Addr : 3FD1: PBASE Constant Address of Label0004 -Addr : 3FD1: 87 86 4C : Memory Op Byte PBASE + ADDRESS Address = 064C -107 s := string("[D") -Addr : 3FD4: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FD5: CaseDone Label0003 -Addr : 3FD5: 0C : Casedone -Addr : 3FD6: Label0005 -Addr : 3FD6: PBASE Constant Address of Label0006 -Addr : 3FD6: 87 86 4F : Memory Op Byte PBASE + ADDRESS Address = 064F -110 s := string("[C") -Addr : 3FD9: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FDA: CaseDone Label0005 -Addr : 3FDA: 0C : Casedone -Addr : 3FDB: Label0007 -Addr : 3FDB: PBASE Constant Address of Label0008 -Addr : 3FDB: 87 86 52 : Memory Op Byte PBASE + ADDRESS Address = 0652 -113 s := string("[A") -Addr : 3FDE: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FDF: CaseDone Label0007 -Addr : 3FDF: 0C : Casedone -Addr : 3FE0: Label0009 -Addr : 3FE0: PBASE Constant Address of Label000A -Addr : 3FE0: 87 86 55 : Memory Op Byte PBASE + ADDRESS Address = 0655 -116 s := string("[B") -Addr : 3FE3: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FE4: CaseDone Label0009 -Addr : 3FE4: 0C : Casedone -Addr : 3FE5: Label000B -Addr : 3FE5: PBASE Constant Address of Label000C -Addr : 3FE5: 87 86 58 : Memory Op Byte PBASE + ADDRESS Address = 0658 -119 s := string("OH") -Addr : 3FE8: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FE9: CaseDone Label000B -Addr : 3FE9: 0C : Casedone -Addr : 3FEA: Label000D -Addr : 3FEA: PBASE Constant Address of Label000E -Addr : 3FEA: 87 86 5B : Memory Op Byte PBASE + ADDRESS Address = 065B -122 s := string("OF") -Addr : 3FED: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FEE: CaseDone Label000D -Addr : 3FEE: 0C : Casedone -Addr : 3FEF: Label000F -Addr : 3FEF: PBASE Constant Address of Label0010 -Addr : 3FEF: 87 86 5E : Memory Op Byte PBASE + ADDRESS Address = 065E -125 s := string("[5~") -Addr : 3FF2: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FF3: CaseDone Label000F -Addr : 3FF3: 0C : Casedone -Addr : 3FF4: Label0011 -Addr : 3FF4: PBASE Constant Address of Label0012 -Addr : 3FF4: 87 86 62 : Memory Op Byte PBASE + ADDRESS Address = 0662 -128 s := string("[6~") -Addr : 3FF7: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FF8: CaseDone Label0011 -Addr : 3FF8: 0C : Casedone -Addr : 3FF9: Label0013 -Addr : 3FF9: PBASE Constant Address of Label0014 -Addr : 3FF9: 87 86 66 : Memory Op Byte PBASE + ADDRESS Address = 0666 -131 s := string("[3~") -Addr : 3FFC: 69 : Variable Operation Local Offset - 2 Write -Addr : 3FFD: CaseDone Label0013 -Addr : 3FFD: 0C : Casedone -Addr : 3FFE: Label0015 -Addr : 3FFE: PBASE Constant Address of Label0016 -Addr : 3FFE: 87 86 6A : Memory Op Byte PBASE + ADDRESS Address = 066A -134 s := string("[2~") -Addr : 4001: 69 : Variable Operation Local Offset - 2 Write -Addr : 4002: CaseDone Label0015 -Addr : 4002: 0C : Casedone -Addr : 4003: Label0002 -151 escstr(s) -Addr : 4003: 01 : Drop Anchor -Addr : 4004: 68 : Variable Operation Local Offset - 2 Read -Addr : 4005: 05 0C : Call Sub 12 -Addr : 4007: 32 : Return -Addr : 4008: Label0004 -Addr : 4008: Data : 5B 44 00 [D. -Addr : 400B: Label0006 -Addr : 400B: Data : 5B 43 00 [C. -Addr : 400E: Label0008 -Addr : 400E: Data : 5B 41 00 [A. -Addr : 4011: Label000A -Addr : 4011: Data : 5B 42 00 [B. -Addr : 4014: Label000C -Addr : 4014: Data : 4F 48 00 OH. -Addr : 4017: Label000E -Addr : 4017: Data : 4F 46 00 OF. -Addr : 401A: Label0010 -Addr : 401A: Data : 5B 35 7E 00 [5~. -Addr : 401E: Label0012 -Addr : 401E: Data : 5B 36 7E 00 [6~. -Addr : 4022: Label0014 -Addr : 4022: Data : 5B 33 7E 00 [3~. -Addr : 4026: Label0016 -Addr : 4026: Data : 5B 32 7E 00 [2~. -|===========================================================================| -Object safe_spi -Object Base is 402C -|===========================================================================| -Object Constants -|===========================================================================| -Object DAT Blocks -|===========================================================================| -4064(0000) 00 00 00 00 | SPI_engine_cog long 0 -4068(0001) 00 00 00 00 | SPI_command long 0 ' "t", "r", "w", 0 =>done, <0 => error | unused -406C(0002) 00 00 00 00 | SPI_block_index long 0 ' which 512-byte block to read/write | cnt at init -4070(0003) 00 00 00 00 | SPI_buffer_address long 0 ' where to get/put the data in Hub RAM | unused -4074(0004) | ORG 0 -4074(0000) | SPI_engine_entry -4074(0000) 2F F1 BF A0 | mov ctra,writeMode -4078(0001) 31 F3 BF A0 | mov ctrb,clockLineMode -407C(0002) 2B ED BF A0 | mov dira,maskAll -4080(0003) 01 80 FE A4 | neg user_request,#1 -4084(0004) F0 81 3E 08 | wrlong user_request,par -4088(0005) F1 8B BE A0 | mov last_time,cnt -408C(0006) | waiting_for_command -408C(0006) A4 66 FD 5C | call #handle_time -4090(0007) F0 81 BE 08 | rdlong user_request,par -4094(0008) 00 80 7E C3 | cmps user_request,#0 wz,wc -4098(0009) 06 00 78 5C | if_be jmp #waiting_for_command -409C(000A) 72 80 7E 86 | cmp user_request,#"r" wz -40A0(000B) 1D 00 68 5C | if_z jmp #read_ahead -40A4(000C) 77 80 7E 86 | cmp user_request,#"w" wz -40A8(000D) 2D 00 68 5C | if_z jmp #write_behind -40AC(000E) 7A 80 7E 86 | cmp user_request,#"z" wz -40B0(000F) 16 00 68 5C | if_z jmp #release_card -40B4(0010) 74 80 7E 86 | cmp user_request,#"t" wz ' time -40B8(0011) 2E 6F 2A 08 | if_z wrlong seconds,sdAdr ' seconds goes into the SD index register -40BC(0012) 2D 71 2A 08 | if_z wrlong dtime,bufAdr ' the remainder goes into the buffer address register -40C0(0013) 00 80 FE A0 | mov user_request,#0 -40C4(0014) F0 81 3E 08 | wrlong user_request,par -40C8(0015) 06 00 7C 5C | jmp #waiting_for_command -40CC(0016) | release_card -40CC(0016) 7A 82 FE A0 | mov user_cmd,#"z" ' request a release -40D0(0017) 01 76 FE A4 | neg lastIndexPlus,#1 ' reset the last block index -40D4(0018) 01 84 FE A4 | neg user_idx,#1 ' and make this match it -40D8(0019) 35 96 FC 5C | call #handle_command -40DC(001A) 41 81 BE A0 | mov user_request,user_cmd -40E0(001B) F0 81 3E 08 | wrlong user_request,par -40E4(001C) 06 00 7C 5C | jmp #waiting_for_command -40E8(001D) | read_ahead -40E8(001D) 2E 85 BE 08 | rdlong user_idx,sdAdr -40EC(001E) 42 7F BE A0 | mov tmp1,user_idx -40F0(001F) 01 7E FE 80 | add tmp1,#1 -40F4(0020) 3B 7F 3E 86 | cmp tmp1,lastIndexPlus wz -40F8(0021) 72 78 6A 86 | if_z cmp lastCommand,#"r" wz -40FC(0022) 25 00 68 5C | if_z jmp #:get_on_with_it -4100(0023) 72 82 FE A0 | mov user_cmd,#"r" -4104(0024) 35 96 FC 5C | call #handle_command -4108(0025) | :get_on_with_it -4108(0025) 10 78 FD 58 | movi transfer_long,#%000010_000 'set to wrlong -410C(0026) B4 8A FD 5C | call #hub_cog_transfer -4110(0027) 41 81 BE A0 | mov user_request,user_cmd -4114(0028) F0 81 3E 08 | wrlong user_request,par -4118(0029) 72 82 FE A0 | mov user_cmd,#"r" -411C(002A) 01 84 FE 80 | add user_idx,#1 -4120(002B) 35 96 FC 5C | call #handle_command -4124(002C) 06 00 7C 5C | jmp #waiting_for_command -4128(002D) | write_behind -4128(002D) 2E 85 BE 08 | rdlong user_idx,sdAdr -412C(002E) 11 78 FD 58 | movi transfer_long,#%000010_001 'set to rdlong -4130(002F) B4 8A FD 5C | call #hub_cog_transfer -4134(0030) 41 81 BE A0 | mov user_request,user_cmd -4138(0031) F0 81 3E 08 | wrlong user_request,par -413C(0032) 77 82 FE A0 | mov user_cmd,#"w" -4140(0033) 35 96 FC 5C | call #handle_command -4144(0034) 06 00 7C 5C | jmp #waiting_for_command -4148(0035) | handle_command -4148(0035) 42 77 3E 86 | cmp lastIndexPlus,user_idx wz -414C(0036) 3C 83 2A 86 | if_z cmp user_cmd,lastCommand wz -4150(0037) 42 00 68 5C | if_z jmp #:execute_block_command -4154(0038) 77 78 7E 86 | cmp lastCommand,#"w" wz -4158(0039) 5A C4 E8 5C | if_z call #stop_mb_write -415C(003A) 72 78 7E 86 | cmp lastCommand,#"r" wz -4160(003B) 53 AC E8 5C | if_z call #stop_mb_read -4164(003C) 77 82 7E 86 | cmp user_cmd,#"w" wz -4168(003D) 57 B2 E8 5C | if_z call #start_mb_write -416C(003E) 72 82 7E 86 | cmp user_cmd,#"r" wz -4170(003F) 50 A4 E8 5C | if_z call #start_mb_read -4174(0040) 7A 82 7E 86 | cmp user_cmd,#"z" wz -4178(0041) 4C 9E E8 5C | if_z call #release_DO -417C(0042) | :execute_block_command -417C(0042) 42 77 BE A0 | mov lastIndexPlus,user_idx -4180(0043) 01 76 FE 80 | add lastIndexPlus,#1 -4184(0044) 41 79 BE A0 | mov lastCommand,user_cmd -4188(0045) 77 82 7E 86 | cmp user_cmd,#"w" wz -418C(0046) F0 48 EA 5C | if_z call #write_single_block -4190(0047) 72 82 7E 86 | cmp user_cmd,#"r" wz -4194(0048) C6 DE E9 5C | if_z call #read_single_block -4198(0049) 7A 82 7E 86 | cmp user_cmd,#"z" wz -419C(004A) 00 82 EA A0 | if_z mov user_cmd,#0 -41A0(004B) | handle_command_ret -41A0(004B) 00 00 7C 5C | ret -41A4(004C) | release_DO -41A4(004C) 2A E9 BF 68 | or outa,maskCS -41A8(004D) 8D 46 FD 5C | call #in8 -41AC(004E) 8D 46 FD 5C | call #in8 -41B0(004F) | release_DO_ret -41B0(004F) 00 00 7C 5C | ret -41B4(0050) | start_mb_read -41B4(0050) A4 86 FE 58 | movi block_cmd,#CMD18<<1 -41B8(0051) 63 F6 FC 5C | call #send_SPI_command_fast -41BC(0052) | start_mb_read_ret -41BC(0052) 00 00 7C 5C | ret -41C0(0053) | stop_mb_read -41C0(0053) 98 86 FE 58 | movi block_cmd,#CMD12<<1 -41C4(0054) 63 F6 FC 5C | call #send_SPI_command_fast -41C8(0055) 7C 00 FD 5C | call #busy_fast -41CC(0056) | stop_mb_read_ret -41CC(0056) 00 00 7C 5C | ret -41D0(0057) | start_mb_write -41D0(0057) B2 86 FE 58 | movi block_cmd,#CMD25<<1 -41D4(0058) 63 F6 FC 5C | call #send_SPI_command_fast -41D8(0059) | start_mb_write_ret -41D8(0059) 00 00 7C 5C | ret -41DC(005A) | stop_mb_write -41DC(005A) 7C 00 FD 5C | call #busy_fast -41E0(005B) 10 7E FE A0 | mov tmp1,#16 -41E4(005C) | :loopity -41E4(005C) 8D 46 FD 5C | call #in8 -41E8(005D) 5C 7E FE E4 | djnz tmp1,#:loopity -41EC(005E) FA F9 FF 58 | movi phsa,#$FD<<1 -41F0(005F) 81 18 FD 5C | call #out8 -41F4(0060) 8D 46 FD 5C | call #in8 ' stuff byte -41F8(0061) 7C 00 FD 5C | call #busy_fast -41FC(0062) | stop_mb_write_ret -41FC(0062) 00 00 7C 5C | ret -4200(0063) | send_SPI_command_fast -4200(0063) 2B ED BF A0 | mov dira,maskAll -4204(0064) 2A E9 BF 68 | or outa,maskCS -4208(0065) 2A E9 BF 64 | andn outa,maskCS -420C(0066) 8D 46 FD 5C | call #in8 -4210(0067) 43 F9 BF A0 | mov phsa,block_cmd ' do which ever block command this is (already in the top 8 bits) -4214(0068) 81 18 FD 5C | call #out8 ' write the byte -4218(0069) 42 F9 BF A0 | mov phsa,user_idx ' read in the desired block index -421C(006A) 2C F9 BF 2C | shl phsa,adrShift ' this will multiply by 512 (bytes/sector) for MMC and SD -4220(006B) 81 18 FD 5C | call #out8 ' move out the 1st MSB ' -4224(006C) 01 F8 FF 24 | rol phsa,#1 -4228(006D) 81 18 FD 5C | call #out8 ' move out the 1st MSB ' -422C(006E) 01 F8 FF 24 | rol phsa,#1 -4230(006F) 81 18 FD 5C | call #out8 ' move out the 1st MSB ' -4234(0070) 01 F8 FF 24 | rol phsa,#1 -4238(0071) 81 18 FD 5C | call #out8 ' move out the 1st MSB ' -423C(0072) 8D 46 FD 5C | call #in8 ' in8 looks like out8 with $FF -4240(0073) 18 86 FE 28 | shr block_cmd,#24 -4244(0074) 4C 86 7E 86 | cmp block_cmd,#CMD12 wz -4248(0075) 8D 46 E9 5C | if_z call #in8 ' 8 clocks -424C(0076) 09 7E FE A0 | mov tmp1,#9 -4250(0077) | :cmd_response -4250(0077) 8D 46 FD 5C | call #in8 -4254(0078) 80 7C 7E 63 | test readback,#$80 wc,wz -4258(0079) 77 7E F2 E4 | if_c djnz tmp1,#:cmd_response -425C(007A) 3E 83 96 A4 | if_nz neg user_cmd,readback -4260(007B) | send_SPI_command_fast_ret -4260(007B) 00 00 7C 5C | ret -4264(007C) | busy_fast -4264(007C) 30 7F BE A0 | mov tmp1,N_in8_500ms -4268(007D) | :still_busy -4268(007D) 8D 46 FD 5C | call #in8 -426C(007E) FF 7C 7E 86 | cmp readback,#$FF wz -4270(007F) 7D 7E D6 E4 | if_nz djnz tmp1,#:still_busy -4274(0080) | busy_fast_ret -4274(0080) 00 00 7C 5C | ret -4278(0081) | out8 -4278(0081) 29 E9 BF 64 | andn outa,maskDI -427C(0082) 00 FA FF A0 | mov phsb,#0 -4280(0083) 80 F6 FF 58 | movi frqb,#%01_0000000 -4284(0084) 01 F8 FF 24 | rol phsa,#1 -4288(0085) 01 F8 FF 24 | rol phsa,#1 -428C(0086) 01 F8 FF 24 | rol phsa,#1 -4290(0087) 01 F8 FF 24 | rol phsa,#1 -4294(0088) 01 F8 FF 24 | rol phsa,#1 -4298(0089) 01 F8 FF 24 | rol phsa,#1 -429C(008A) 01 F8 FF 24 | rol phsa,#1 -42A0(008B) 00 F6 FF A0 | mov frqb,#0 -42A4(008C) | out8_ret -42A4(008C) 00 00 7C 5C | ret -42A8(008D) | in8 -42A8(008D) 01 F8 FF A4 | neg phsa,#1' DI high -42AC(008E) 00 7C FE A0 | mov readback,#0 -42B0(008F) C0 FA FF 58 | movi phsb,#%011_000000 -42B4(0090) 40 F6 FF 58 | movi frqb,#%001_000000 -42B8(0091) F2 51 3E 61 | test maskDO,ina wc -42BC(0092) 01 7C FE 34 | rcl readback,#1 -42C0(0093) F2 51 3E 61 | test maskDO,ina wc -42C4(0094) 01 7C FE 34 | rcl readback,#1 -42C8(0095) F2 51 3E 61 | test maskDO,ina wc -42CC(0096) 01 7C FE 34 | rcl readback,#1 -42D0(0097) F2 51 3E 61 | test maskDO,ina wc -42D4(0098) 01 7C FE 34 | rcl readback,#1 -42D8(0099) F2 51 3E 61 | test maskDO,ina wc -42DC(009A) 01 7C FE 34 | rcl readback,#1 -42E0(009B) F2 51 3E 61 | test maskDO,ina wc -42E4(009C) 01 7C FE 34 | rcl readback,#1 -42E8(009D) F2 51 3E 61 | test maskDO,ina wc -42EC(009E) 01 7C FE 34 | rcl readback,#1 -42F0(009F) F2 51 3E 61 | test maskDO,ina wc -42F4(00A0) 00 F6 FF A0 | mov frqb,#0 ' stop the clock -42F8(00A1) 01 7C FE 34 | rcl readback,#1 -42FC(00A2) 00 F8 FF A0 | mov phsa,#0 'DI low -4300(00A3) | in8_ret -4300(00A3) 00 00 7C 5C | ret -4304(00A4) | handle_time -4304(00A4) F1 7F BE A0 | mov tmp1,cnt ' get the current timestamp -4308(00A5) 3F 73 BE 80 | add idle_time,tmp1 ' add the current time to my idle time counter -430C(00A6) 45 73 BE 84 | sub idle_time,last_time ' subtract the last time from my idle counter (hence delta) -4310(00A7) 3F 71 BE 80 | add dtime,tmp1 ' add to my accumulator, -4314(00A8) 45 71 BE 84 | sub dtime,last_time ' and subtract the old (adding delta) -4318(00A9) 3F 8B BE A0 | mov last_time,tmp1 ' update my "last timestamp" -431C(00AA) 00 7E FE 08 | rdlong tmp1,#0 ' what is the clock frequency? -4320(00AB) 3F 71 BE E1 | cmpsub dtime,tmp1 wc ' if I have more than a second in my accumulator -4324(00AC) 00 6E FE C8 | addx seconds,#0 ' then add it to "seconds" -4328(00AD) 3A 73 3E 87 | cmp idle_time,idle_limit wz,wc -432C(00AE) B3 00 70 5C | if_b jmp #handle_time_ret ' don't clear if we haven't hit the limit -4330(00AF) 7A 82 FE A0 | mov user_cmd,#"z" ' we can't overdo it, the command handler makes sure -4334(00B0) 01 76 FE A4 | neg lastIndexPlus,#1 ' reset the last block index -4338(00B1) 01 84 FE A4 | neg user_idx,#1 ' and make this match it -433C(00B2) 35 96 FC 5C | call #handle_command ' release the card, but don't mess with the user's request register -4340(00B3) | handle_time_ret -4340(00B3) 00 00 7C 5C | ret -4344(00B4) | hub_cog_transfer -4344(00B4) 32 F3 BF A0 | mov ctrb,clockXferMode -4348(00B5) 01 F6 FF A0 | mov frqb,#1 -434C(00B6) 2D 89 BE 08 | rdlong buf_ptr,bufAdr -4350(00B7) 04 7A FE A0 | mov ops_left,#4 -4354(00B8) 46 79 FD 54 | movd transfer_long,#speed_buf -4358(00B9) | four_transfer_passes -4358(00B9) 3F 7F BE 08 | rdlong tmp1,tmp1 -435C(00BA) 20 7E FE A0 | mov tmp1,#(512 / 4 / 4) -4360(00BB) 44 FB BF A0 | mov phsb,buf_ptr -4364(00BC) | transfer_long -4364(00BC) FD 01 BC 08 | rdlong 0-0,phsb -4368(00BD) 35 79 BD 80 | add transfer_long,incDest4 -436C(00BE) BC 7E FE E4 | djnz tmp1,#transfer_long -4370(00BF) 36 79 BD 84 | sub transfer_long,decDestNminus1 -4374(00C0) 04 88 FE 80 | add buf_ptr,#4 -4378(00C1) B9 7A FE E4 | djnz ops_left,#four_transfer_passes -437C(00C2) 00 F6 FF A0 | mov frqb,#0 -4380(00C3) 00 FA FF A0 | mov phsb,#0 -4384(00C4) 31 F3 BF A0 | mov ctrb,clockLineMode -4388(00C5) | hub_cog_transfer_ret -4388(00C5) 00 00 7C 5C | ret -438C(00C6) | read_single_block -438C(00C6) 46 CD FD 54 | movd :store_read_long,#speed_buf -4390(00C7) 80 7A FE A0 | mov ops_left,#128 -4394(00C8) 30 7F BE A0 | mov tmp1,N_in8_500ms -4398(00C9) | :get_resp -4398(00C9) 8D 46 FD 5C | call #in8 -439C(00CA) FE 7C 7E 86 | cmp readback,#$FE wz -43A0(00CB) C9 7E D6 E4 | if_nz djnz tmp1,#:get_resp -43A4(00CC) 64 82 D6 A4 | if_nz neg user_cmd,#ERR_ASM_NO_READ_TOKEN -43A8(00CD) EF 00 54 5C | if_nz jmp #read_single_block_ret -43AC(00CE) 01 F8 FF A4 | neg phsa,#1 -43B0(00CF) 80 7A FE A0 | mov ops_left,#128 -43B4(00D0) | :read_loop -43B4(00D0) 04 7E FE A0 | mov tmp1,#4 -43B8(00D1) C0 FA FF 58 | movi phsb,#%011_000000 -43BC(00D2) | :in_byte -43BC(00D2) 40 F6 FF 58 | movi frqb,#%001_000000 -43C0(00D3) F2 51 3E 61 | test maskDO,ina wc -43C4(00D4) 08 7C FE 34 | rcl readback,#8 -43C8(00D5) F2 51 3E 61 | test maskDO,ina wc -43CC(00D6) 02 7C FE 70 | muxc readback,#2 -43D0(00D7) F2 51 3E 61 | test maskDO,ina wc -43D4(00D8) 04 7C FE 70 | muxc readback,#4 -43D8(00D9) F2 51 3E 61 | test maskDO,ina wc -43DC(00DA) 08 7C FE 70 | muxc readback,#8 -43E0(00DB) F2 51 3E 61 | test maskDO,ina wc -43E4(00DC) 10 7C FE 70 | muxc readback,#16 -43E8(00DD) F2 51 3E 61 | test maskDO,ina wc -43EC(00DE) 20 7C FE 70 | muxc readback,#32 -43F0(00DF) F2 51 3E 61 | test maskDO,ina wc -43F4(00E0) 40 7C FE 70 | muxc readback,#64 -43F8(00E1) F2 51 3E 61 | test maskDO,ina wc -43FC(00E2) 00 F6 FF A0 | mov frqb,#0 ' stop the clock -4400(00E3) 80 7C FE 70 | muxc readback,#128 -4404(00E4) D2 7E FE E4 | djnz tmp1,#:in_byte -4408(00E5) 00 7C FE 3C | rev readback,#0 -440C(00E6) | :store_read_long -440C(00E6) 3E 01 BC A0 | mov 0-0,readback ' due to some counter weirdness, we need this mov -4410(00E7) 33 CD BD 80 | add :store_read_long,const512 -4414(00E8) D0 7A FE E4 | djnz ops_left,#:read_loop -4418(00E9) 00 F8 FF A0 | mov phsa,#0 -441C(00EA) 8D 46 FD 5C | call #in8 ' out8 is 2x faster than in8 -4420(00EB) 8D 46 FD 5C | call #in8 ' and I'm not using the CRC anyway -4424(00EC) 8D 46 FD 5C | call #in8 ' in8 looks like out8($FF) -4428(00ED) 00 72 FE A0 | mov idle_time,#0 -442C(00EE) 00 82 FE A0 | mov user_cmd,#0 -4430(00EF) | read_single_block_ret -4430(00EF) 00 00 7C 5C | ret -4434(00F0) | write_single_block -4434(00F0) 46 ED FD 50 | movs :write_loop,#speed_buf -4438(00F1) 80 7A FE A0 | mov ops_left,#128 -443C(00F2) 7C 00 FD 5C | call #busy_fast -4440(00F3) F8 F9 FF 58 | movi phsa,#$FC<<1 -4444(00F4) 81 18 FD 5C | call #out8 -4448(00F5) 00 FA FF A0 | mov phsb,#0 ' make sure my clock accumulator is right -444C(00F6) | :write_loop -444C(00F6) 46 F9 BF A0 | mov phsa,speed_buf -4450(00F7) 01 EC FD 80 | add :write_loop,#1 -4454(00F8) 18 F8 FF 24 | rol phsa,#24 ' move A7 into position, so I can do the swizzled version -4458(00F9) 80 F6 FF 58 | movi frqb,#%010000000 ' start the clock (remember A7 is already in place) -445C(00FA) 01 F8 FF 24 | rol phsa,#1 ' A7 is going out, at the end of this instr, A6 is in place -4460(00FB) 01 F8 FF 24 | rol phsa,#1 ' A5 -4464(00FC) 01 F8 FF 24 | rol phsa,#1 ' A4 -4468(00FD) 01 F8 FF 24 | rol phsa,#1 ' A3 -446C(00FE) 01 F8 FF 24 | rol phsa,#1 ' A2 -4470(00FF) 01 F8 FF 24 | rol phsa,#1 ' A1 -4474(0100) 01 F8 FF 24 | rol phsa,#1 ' A0 -4478(0101) 11 F8 FF 24 | rol phsa,#17 ' B7 -447C(0102) 01 F8 FF 24 | rol phsa,#1 ' B6 -4480(0103) 01 F8 FF 24 | rol phsa,#1 ' B5 -4484(0104) 01 F8 FF 24 | rol phsa,#1 ' B4 -4488(0105) 01 F8 FF 24 | rol phsa,#1 ' B3 -448C(0106) 01 F8 FF 24 | rol phsa,#1 ' B2 -4490(0107) 01 F8 FF 24 | rol phsa,#1 ' B1 -4494(0108) 01 F8 FF 24 | rol phsa,#1 ' B0 -4498(0109) 11 F8 FF 24 | rol phsa,#17 ' C7 -449C(010A) 01 F8 FF 24 | rol phsa,#1 ' C6 -44A0(010B) 01 F8 FF 24 | rol phsa,#1 ' C5 -44A4(010C) 01 F8 FF 24 | rol phsa,#1 ' C4 -44A8(010D) 01 F8 FF 24 | rol phsa,#1 ' C3 -44AC(010E) 01 F8 FF 24 | rol phsa,#1 ' C2 -44B0(010F) 01 F8 FF 24 | rol phsa,#1 ' C1 -44B4(0110) 01 F8 FF 24 | rol phsa,#1 ' C0 -44B8(0111) 11 F8 FF 24 | rol phsa,#17 ' D7 -44BC(0112) 01 F8 FF 24 | rol phsa,#1 ' D6 -44C0(0113) 01 F8 FF 24 | rol phsa,#1 ' D5 -44C4(0114) 01 F8 FF 24 | rol phsa,#1 ' D4 -44C8(0115) 01 F8 FF 24 | rol phsa,#1 ' D3 -44CC(0116) 01 F8 FF 24 | rol phsa,#1 ' D2 -44D0(0117) 01 F8 FF 24 | rol phsa,#1 ' D1 -44D4(0118) 01 F8 FF 24 | rol phsa,#1 ' D0 will be in place _after_ this instruction -44D8(0119) 00 F6 FF A0 | mov frqb,#0 ' shuts the clock off, _after_ this instruction -44DC(011A) F6 7A FE E4 | djnz ops_left,#:write_loop -44E0(011B) 8D 46 FD 5C | call #in8 -44E4(011C) 8D 46 FD 5C | call #in8 -44E8(011D) 8D 46 FD 5C | call #in8 -44EC(011E) 1F 7C FE 60 | and readback,#$1F -44F0(011F) 05 7C 7E 86 | cmp readback,#5 wz -44F4(0120) 00 82 EA A0 | if_z mov user_cmd,#0 ' great -44F8(0121) 65 82 D6 A4 | if_nz neg user_cmd,#ERR_ASM_BLOCK_NOT_WRITTEN ' oops -44FC(0122) 8D 46 FD 5C | call #in8 -4500(0123) 00 72 FE A0 | mov idle_time,#0 -4504(0124) | write_single_block_ret -4504(0124) 00 00 7C 5C | ret -4508(0125) 00 00 00 00 | pinDO long 0 ' pin is controlled by a counter -450C(0126) 00 00 00 00 | pinCLK long 0 ' pin is controlled by a counter -4510(0127) 00 00 00 00 | pinDI long 0 ' pin is controlled by a counter -4514(0128) 00 00 00 00 | maskDO long 0 ' mask for reading the DO line from the card -4518(0129) 00 00 00 00 | maskDI long 0 ' mask for setting the pin high while reading -451C(012A) 00 00 00 00 | maskCS long 0 ' mask = (1<>8) + cnt ) -Addr : 4625: 39 01 F4 : Constant 2 Bytes - 01 F4 -Addr : 4628: 35 : Constant 1 $00000000 -Addr : 4629: C0 : Memory Op Long POP Address READ -Addr : 462A: 37 02 : Constant Mask Y=2 00000008 -Addr : 462C: E2 : Math Op >> -Addr : 462D: EC : Math Op + -Addr : 462E: 3F 91 : Register op CNT Read -Addr : 4630: EC : Math Op + -Addr : 4631: 23 : WaitCnt(count) -151 pinDO := DO -Addr : 4632: 64 : Variable Operation Local Offset - 1 Read -Addr : 4633: C5 84 DC : Memory Op Long PBASE + WRITE Address = 04DC -152 maskDO := |< DO -Addr : 4636: 64 : Variable Operation Local Offset - 1 Read -Addr : 4637: F3 : Math Op |< -Addr : 4638: C5 84 E8 : Memory Op Long PBASE + WRITE Address = 04E8 -153 pinCLK := CLK -Addr : 463B: 68 : Variable Operation Local Offset - 2 Read -Addr : 463C: C5 84 E0 : Memory Op Long PBASE + WRITE Address = 04E0 -154 pinDI := DI -Addr : 463F: 6C : Variable Operation Local Offset - 3 Read -Addr : 4640: C5 84 E4 : Memory Op Long PBASE + WRITE Address = 04E4 -155 maskDI := |< DI -Addr : 4643: 6C : Variable Operation Local Offset - 3 Read -Addr : 4644: F3 : Math Op |< -Addr : 4645: C5 84 EC : Memory Op Long PBASE + WRITE Address = 04EC -156 maskCS := |< CS -Addr : 4648: 70 : Variable Operation Local Offset - 4 Read -Addr : 4649: F3 : Math Op |< -Addr : 464A: C5 84 F0 : Memory Op Long PBASE + WRITE Address = 04F0 -157 adrShift := 9 ' block = 512 * index, and 512 = 1<<9 -Addr : 464D: 38 09 : Constant 1 Bytes - 09 -Addr : 464F: C5 84 F8 : Memory Op Long PBASE + WRITE Address = 04F8 -159 maskAll := maskCS | (| 1 -Addr : 4683: 74 : Variable Operation Local Offset - 5 Read -Addr : 4684: 36 : Constant 2 $00000001 -Addr : 4685: FB : Math Op <> -Addr : 4686: JZ Label0008 -Addr : 4686: 0A 3B : jz Address = 46C3 59 -172 tmp := send_cmd_slow( CMD0, 0, $95 ) -Addr : 4688: 00 : Drop Anchor Push -Addr : 4689: 37 05 : Constant Mask Y=5 00000040 -Addr : 468B: 35 : Constant 1 $00000000 -Addr : 468C: 38 95 : Constant 1 Bytes - 95 -Addr : 468E: 05 0A : Call Sub 10 -Addr : 4690: 75 : Variable Operation Local Offset - 5 Write -173 if (tmp & 4) -Addr : 4691: 74 : Variable Operation Local Offset - 5 Read -Addr : 4692: 37 01 : Constant Mask Y=1 00000004 -Addr : 4694: E8 : Math Op & -Addr : 4695: JZ Label000A -Addr : 4695: 0A 2C : jz Address = 46C3 44 -175 if i & 1 -Addr : 4697: 78 : Variable Operation Local Offset - 6 Read -Addr : 4698: 36 : Constant 2 $00000001 -Addr : 4699: E8 : Math Op & -Addr : 469A: JZ Label000C -Addr : 469A: 0A 1F : jz Address = 46BB 31 -177 repeat 4 -Addr : 469C: 37 01 : Constant Mask Y=1 00000004 -Addr : 469E: TJZ Label0010 -Addr : 469E: 08 05 : tjz Address = 46A5 5 -Addr : 46A0: Label000E -178 read_32_slow ' these extra clocks are required for some MMC cards -Addr : 46A0: 01 : Drop Anchor -Addr : 46A1: 05 0C : Call Sub 12 -Addr : 46A3: Label000F -Addr : 46A3: DJNZ Label000E -Addr : 46A3: 09 7B : djnz Address = 46A0 -5 -Addr : 46A5: Label0010 -179 send_slow( $FD, 8 ) ' stop token -Addr : 46A5: 01 : Drop Anchor -Addr : 46A6: 38 FD : Constant 1 Bytes - FD -Addr : 46A8: 37 02 : Constant Mask Y=2 00000008 -Addr : 46AA: 05 0B : Call Sub 11 -180 read_32_slow -Addr : 46AC: 01 : Drop Anchor -Addr : 46AD: 05 0C : Call Sub 12 -Addr : 46AF: Label0011 -181 repeat while read_slow <> $FF -Addr : 46AF: 00 : Drop Anchor Push -Addr : 46B0: 05 0D : Call Sub 13 -Addr : 46B2: 37 27 : Constant Mask Y=39 Decrement 000000FF -Addr : 46B4: FB : Math Op <> -Addr : 46B5: JZ Label0013 -Addr : 46B5: 0A 02 : jz Address = 46B9 2 -Addr : 46B7: Label0012 -Addr : 46B7: JMP Label0011 -Addr : 46B7: 04 76 : Jmp 46AF -10 -Addr : 46B9: Label0013 -Addr : 46B9: JMP Label000D -Addr : 46B9: 04 08 : Jmp 46C3 8 -Addr : 46BB: Label000C -184 send_cmd_slow( CMD12, 0, $61 ) -Addr : 46BB: 01 : Drop Anchor -Addr : 46BC: 38 4C : Constant 1 Bytes - 4C -Addr : 46BE: 35 : Constant 1 $00000000 -Addr : 46BF: 38 61 : Constant 1 Bytes - 61 -Addr : 46C1: 05 0A : Call Sub 10 -Addr : 46C3: Label0014 -Addr : 46C3: Label000D -Addr : 46C3: Label000A -Addr : 46C3: Label000B -Addr : 46C3: Label0008 -Addr : 46C3: Label0009 -Addr : 46C3: Label0006 -170 repeat i from 0 to 9 -Addr : 46C3: 35 : Constant 1 $00000000 -Addr : 46C4: 38 09 : Constant 1 Bytes - 09 -Addr : 46C6: Repeat i Step Label0005 -Addr : 46C6: 7A 02 FF B9 : Variable Operation Local Offset - 6 Assign Repeat-Var loop Address= 4683 -71 -Addr : 46CA: Label0007 -185 if tmp <> 1 -Addr : 46CA: 74 : Variable Operation Local Offset - 5 Read -Addr : 46CB: 36 : Constant 2 $00000001 -Addr : 46CC: FB : Math Op <> -Addr : 46CD: JZ Label0015 -Addr : 46CD: 0A 04 : jz Address = 46D3 4 -187 crash( ERR_CARD_NOT_RESET ) -Addr : 46CF: 01 : Drop Anchor -Addr : 46D0: 34 : Constant 0 $FFFFFFFF -Addr : 46D1: 05 09 : Call Sub 9 -Addr : 46D3: Label0015 -Addr : 46D3: Label0016 -189 if send_cmd_slow( CMD8, $1AA, $87 ) == 1 -Addr : 46D3: 00 : Drop Anchor Push -Addr : 46D4: 38 48 : Constant 1 Bytes - 48 -Addr : 46D6: 39 01 AA : Constant 2 Bytes - 01 AA -Addr : 46D9: 38 87 : Constant 1 Bytes - 87 -Addr : 46DB: 05 0A : Call Sub 10 -Addr : 46DD: 36 : Constant 2 $00000001 -Addr : 46DE: FC : Math Op == -Addr : 46DF: JZ Label0017 -Addr : 46DF: 0A 80 4B : jz Address = 472D 75 -191 tmp := read_32_slow -Addr : 46E2: 00 : Drop Anchor Push -Addr : 46E3: 05 0C : Call Sub 12 -Addr : 46E5: 75 : Variable Operation Local Offset - 5 Write -193 if (tmp & $1FF) <> $1AA -Addr : 46E6: 74 : Variable Operation Local Offset - 5 Read -Addr : 46E7: 37 28 : Constant Mask Y=40 Decrement 000001FF -Addr : 46E9: E8 : Math Op & -Addr : 46EA: 39 01 AA : Constant 2 Bytes - 01 AA -Addr : 46ED: FB : Math Op <> -Addr : 46EE: JZ Label0019 -Addr : 46EE: 0A 05 : jz Address = 46F5 5 -194 crash( ERR_3v3_NOT_SUPPORTED ) -Addr : 46F0: 01 : Drop Anchor -Addr : 46F1: 37 60 : Constant Mask Y=96 Decrement Invert FFFFFFFE -Addr : 46F3: 05 09 : Call Sub 9 -Addr : 46F5: Label0019 -Addr : 46F5: Label001A -Addr : 46F5: Label001B -196 repeat while send_cmd_slow( ACMD41, |<30, $77 ) -Addr : 46F5: 00 : Drop Anchor Push -Addr : 46F6: 38 E9 : Constant 1 Bytes - E9 -Addr : 46F8: 38 1E : Constant 1 Bytes - 1E -Addr : 46FA: F3 : Math Op |< -Addr : 46FB: 38 77 : Constant 1 Bytes - 77 -Addr : 46FD: 05 0A : Call Sub 10 -Addr : 46FF: JZ Label001D -Addr : 46FF: 0A 02 : jz Address = 4703 2 -Addr : 4701: Label001C -Addr : 4701: JMP Label001B -Addr : 4701: 04 72 : Jmp 46F5 -14 -Addr : 4703: Label001D -198 if send_cmd_slow( CMD58, 0, $FD ) <> 0 -Addr : 4703: 00 : Drop Anchor Push -Addr : 4704: 38 7A : Constant 1 Bytes - 7A -Addr : 4706: 35 : Constant 1 $00000000 -Addr : 4707: 38 FD : Constant 1 Bytes - FD -Addr : 4709: 05 0A : Call Sub 10 -Addr : 470B: 35 : Constant 1 $00000000 -Addr : 470C: FB : Math Op <> -Addr : 470D: JZ Label001E -Addr : 470D: 0A 05 : jz Address = 4714 5 -199 crash( ERR_OCR_FAILED ) -Addr : 470F: 01 : Drop Anchor -Addr : 4710: 37 40 : Constant Mask Y=64 Invert FFFFFFFD -Addr : 4712: 05 09 : Call Sub 9 -Addr : 4714: Label001E -Addr : 4714: Label001F -201 tmp := read_32_slow -Addr : 4714: 00 : Drop Anchor Push -Addr : 4715: 05 0C : Call Sub 12 -Addr : 4717: 75 : Variable Operation Local Offset - 5 Write -203 if tmp & |<30 -Addr : 4718: 74 : Variable Operation Local Offset - 5 Read -Addr : 4719: 38 1E : Constant 1 Bytes - 1E -Addr : 471B: F3 : Math Op |< -Addr : 471C: E8 : Math Op & -Addr : 471D: JZ Label0020 -Addr : 471D: 0A 09 : jz Address = 4728 9 -204 card_type := type_SDHC -Addr : 471F: 37 21 : Constant Mask Y=33 Decrement 00000003 -Addr : 4721: 61 : Variable Operation Local Offset - 0 Write -205 adrShift := 0 -Addr : 4722: 35 : Constant 1 $00000000 -Addr : 4723: C5 84 F8 : Memory Op Long PBASE + WRITE Address = 04F8 -Addr : 4726: JMP Label0021 -Addr : 4726: 04 03 : Jmp 472B 3 -Addr : 4728: Label0020 -207 card_type := type_SD -Addr : 4728: 37 00 : Constant Mask Y=0 00000002 -Addr : 472A: 61 : Variable Operation Local Offset - 0 Write -Addr : 472B: Label0022 -Addr : 472B: Label0021 -Addr : 472B: JMP Label0018 -Addr : 472B: 04 35 : Jmp 4762 53 -Addr : 472D: Label0017 -210 if send_cmd_slow( ACMD41, 0, $E5 ) < 2 -Addr : 472D: 00 : Drop Anchor Push -Addr : 472E: 38 E9 : Constant 1 Bytes - E9 -Addr : 4730: 35 : Constant 1 $00000000 -Addr : 4731: 38 E5 : Constant 1 Bytes - E5 -Addr : 4733: 05 0A : Call Sub 10 -Addr : 4735: 37 00 : Constant Mask Y=0 00000002 -Addr : 4737: F9 : Math Op < -Addr : 4738: JZ Label0024 -Addr : 4738: 0A 11 : jz Address = 474B 17 -212 card_type := type_SD -Addr : 473A: 37 00 : Constant Mask Y=0 00000002 -Addr : 473C: 61 : Variable Operation Local Offset - 0 Write -Addr : 473D: Label0026 -213 repeat while send_cmd_slow( ACMD41, 0, $E5 ) -Addr : 473D: 00 : Drop Anchor Push -Addr : 473E: 38 E9 : Constant 1 Bytes - E9 -Addr : 4740: 35 : Constant 1 $00000000 -Addr : 4741: 38 E5 : Constant 1 Bytes - E5 -Addr : 4743: 05 0A : Call Sub 10 -Addr : 4745: JZ Label0028 -Addr : 4745: 0A 02 : jz Address = 4749 2 -Addr : 4747: Label0027 -Addr : 4747: JMP Label0026 -Addr : 4747: 04 74 : Jmp 473D -12 -Addr : 4749: Label0028 -Addr : 4749: JMP Label0025 -Addr : 4749: 04 0E : Jmp 4759 14 -Addr : 474B: Label0024 -216 card_type := type_MMC -Addr : 474B: 36 : Constant 2 $00000001 -Addr : 474C: 61 : Variable Operation Local Offset - 0 Write -Addr : 474D: Label002A -217 repeat while send_cmd_slow( CMD1, 0, $F9 ) -Addr : 474D: 00 : Drop Anchor Push -Addr : 474E: 38 41 : Constant 1 Bytes - 41 -Addr : 4750: 35 : Constant 1 $00000000 -Addr : 4751: 38 F9 : Constant 1 Bytes - F9 -Addr : 4753: 05 0A : Call Sub 10 -Addr : 4755: JZ Label002C -Addr : 4755: 0A 02 : jz Address = 4759 2 -Addr : 4757: Label002B -Addr : 4757: JMP Label002A -Addr : 4757: 04 74 : Jmp 474D -12 -Addr : 4759: Label002C -Addr : 4759: Label0029 -Addr : 4759: Label0025 -219 send_cmd_slow( CMD16, 512, $15 ) -Addr : 4759: 01 : Drop Anchor -Addr : 475A: 38 50 : Constant 1 Bytes - 50 -Addr : 475C: 37 08 : Constant Mask Y=8 00000200 -Addr : 475E: 38 15 : Constant 1 Bytes - 15 -Addr : 4760: 05 0A : Call Sub 10 -Addr : 4762: Label0023 -Addr : 4762: Label0018 -221 send_cmd_slow( CMD59, 0, $91 ) -Addr : 4762: 01 : Drop Anchor -Addr : 4763: 38 7B : Constant 1 Bytes - 7B -Addr : 4765: 35 : Constant 1 $00000000 -Addr : 4766: 38 91 : Constant 1 Bytes - 91 -Addr : 4768: 05 0A : Call Sub 10 -225 outa |= maskCS -Addr : 476A: C4 84 F0 : Memory Op Long PBASE + READ Address = 04F0 -Addr : 476D: 3F D4 4A : Register op OUTA ByteMathop | -228 writeMode := (%00100 << 26) | (DI << 0) -Addr : 4770: 37 01 : Constant Mask Y=1 00000004 -Addr : 4772: 38 1A : Constant 1 Bytes - 1A -Addr : 4774: E3 : Math Op << -Addr : 4775: 6C : Variable Operation Local Offset - 3 Read -Addr : 4776: 35 : Constant 1 $00000000 -Addr : 4777: E3 : Math Op << -Addr : 4778: EA : Math Op | -Addr : 4779: C5 85 04 : Memory Op Long PBASE + WRITE Address = 0504 -234 clockLineMode := (%00100 << 26) | (CLK << 0) ' NCO, 50% duty cycle -Addr : 477C: 37 01 : Constant Mask Y=1 00000004 -Addr : 477E: 38 1A : Constant 1 Bytes - 1A -Addr : 4780: E3 : Math Op << -Addr : 4781: 68 : Variable Operation Local Offset - 2 Read -Addr : 4782: 35 : Constant 1 $00000000 -Addr : 4783: E3 : Math Op << -Addr : 4784: EA : Math Op | -Addr : 4785: C5 85 0C : Memory Op Long PBASE + WRITE Address = 050C -236 N_in8_500ms := clkfreq >> constant(1+2+3) -Addr : 4788: 35 : Constant 1 $00000000 -Addr : 4789: C0 : Memory Op Long POP Address READ -Addr : 478A: 38 06 : Constant 1 Bytes - 06 -Addr : 478C: E2 : Math Op >> -Addr : 478D: C5 85 08 : Memory Op Long PBASE + WRITE Address = 0508 -238 idle_limit := 125 ' ms, NEVER make this > 1000 -Addr : 4790: 38 7D : Constant 1 Bytes - 7D -Addr : 4792: C5 85 30 : Memory Op Long PBASE + WRITE Address = 0530 -239 idle_limit := clkfreq / (1000 / idle_limit) ' convert to counts -Addr : 4795: 35 : Constant 1 $00000000 -Addr : 4796: C0 : Memory Op Long POP Address READ -Addr : 4797: 39 03 E8 : Constant 2 Bytes - 03 E8 -Addr : 479A: C4 85 30 : Memory Op Long PBASE + READ Address = 0530 -Addr : 479D: F6 : Math Op / -Addr : 479E: F6 : Math Op / -Addr : 479F: C5 85 30 : Memory Op Long PBASE + WRITE Address = 0530 -241 bufAdr := @SPI_buffer_address -Addr : 47A2: C7 44 : Memory Op Long PBASE + ADDRESS Address = 0044 -Addr : 47A4: C5 84 FC : Memory Op Long PBASE + WRITE Address = 04FC -242 sdAdr := @SPI_block_index -Addr : 47A7: C7 40 : Memory Op Long PBASE + ADDRESS Address = 0040 -Addr : 47A9: C5 85 00 : Memory Op Long PBASE + WRITE Address = 0500 -243 SPI_command := 0 ' just make sure it's not 1 -Addr : 47AC: 35 : Constant 1 $00000000 -Addr : 47AD: C5 3C : Memory Op Long PBASE + WRITE Address = 003C -245 SPI_engine_cog := cognew( @SPI_engine_entry, @SPI_command ) + 1 -Addr : 47AF: 34 : Constant 0 $FFFFFFFF -Addr : 47B0: C7 48 : Memory Op Long PBASE + ADDRESS Address = 0048 -Addr : 47B2: C7 3C : Memory Op Long PBASE + ADDRESS Address = 003C -Addr : 47B4: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 47B5: 36 : Constant 2 $00000001 -Addr : 47B6: EC : Math Op + -Addr : 47B7: C5 38 : Memory Op Long PBASE + WRITE Address = 0038 -246 if( SPI_engine_cog == 0 ) -Addr : 47B9: C4 38 : Memory Op Long PBASE + READ Address = 0038 -Addr : 47BB: 35 : Constant 1 $00000000 -Addr : 47BC: FC : Math Op == -Addr : 47BD: JZ Label002D -Addr : 47BD: 0A 07 : jz Address = 47C6 7 -247 crash( ERR_SPI_ENGINE_NOT_RUNNING ) -Addr : 47BF: 01 : Drop Anchor -Addr : 47C0: 39 03 E6 : Constant 2 Bytes - 03 E6 -Addr : 47C3: E7 : Math Op ! -Addr : 47C4: 05 09 : Call Sub 9 -Addr : 47C6: Label002D -Addr : 47C6: Label002E -Addr : 47C6: Label002F -248 repeat while SPI_command <> -1 -Addr : 47C6: C4 3C : Memory Op Long PBASE + READ Address = 003C -Addr : 47C8: 34 : Constant 0 $FFFFFFFF -Addr : 47C9: FB : Math Op <> -Addr : 47CA: JZ Label0031 -Addr : 47CA: 0A 02 : jz Address = 47CE 2 -Addr : 47CC: Label0030 -Addr : 47CC: JMP Label002F -Addr : 47CC: 04 78 : Jmp 47C6 -8 -Addr : 47CE: Label0031 -250 dira &= !maskAll -Addr : 47CE: C4 84 F4 : Memory Op Long PBASE + READ Address = 04F4 -Addr : 47D1: E7 : Math Op ! -Addr : 47D2: 3F D6 48 : Register op DIRA BitMathop & -Addr : 47D5: 32 : Return -|===========================================================================| -Spin Block release with 0 Parameters and 0 Extra Stack Longs. Method 7 -PUB release - -Local Parameter DBASE:0000 - Result -|===========================================================================| -259 if SPI_engine_cog -Addr : 47D6: C4 38 : Memory Op Long PBASE + READ Address = 0038 -Addr : 47D8: JZ Label0002 -Addr : 47D8: 0A 0D : jz Address = 47E7 13 -260 SPI_command := "z" -Addr : 47DA: 38 7A : Constant 1 Bytes - 7A -Addr : 47DC: C5 3C : Memory Op Long PBASE + WRITE Address = 003C -Addr : 47DE: Label0004 -261 repeat while SPI_command == "z" -Addr : 47DE: C4 3C : Memory Op Long PBASE + READ Address = 003C -Addr : 47E0: 38 7A : Constant 1 Bytes - 7A -Addr : 47E2: FC : Math Op == -Addr : 47E3: JZ Label0006 -Addr : 47E3: 0A 02 : jz Address = 47E7 2 -Addr : 47E5: Label0005 -Addr : 47E5: JMP Label0004 -Addr : 47E5: 04 77 : Jmp 47DE -9 -Addr : 47E7: Label0006 -Addr : 47E7: Label0002 -Addr : 47E7: Label0003 -Addr : 47E7: 32 : Return -|===========================================================================| -Spin Block stop with 0 Parameters and 0 Extra Stack Longs. Method 8 -PUB stop - -Local Parameter DBASE:0000 - Result -|===========================================================================| -267 release -Addr : 47E8: 01 : Drop Anchor -Addr : 47E9: 05 07 : Call Sub 7 -268 if SPI_engine_cog -Addr : 47EB: C4 38 : Memory Op Long PBASE + READ Address = 0038 -Addr : 47ED: JZ Label0002 -Addr : 47ED: 0A 06 : jz Address = 47F5 6 -269 cogstop( SPI_engine_cog~ - 1 ) -Addr : 47EF: C6 38 98 : Memory Op Long PBASE + ASSIGN Address = 0038 VAR~ Post-clear Push -Addr : 47F2: 36 : Constant 2 $00000001 -Addr : 47F3: ED : Math Op - -Addr : 47F4: 21 : CogStop(id) -Addr : 47F5: Label0002 -Addr : 47F5: Label0003 -Addr : 47F5: 32 : Return -|===========================================================================| -Spin Block crash with 1 Parameters and 0 Extra Stack Longs. Method 9 -PRI crash( abort_code ) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - abort_code -|===========================================================================| -277 dira &= !maskAll -Addr : 47F6: C4 84 F4 : Memory Op Long PBASE + READ Address = 04F4 -Addr : 47F9: E7 : Math Op ! -Addr : 47FA: 3F D6 48 : Register op DIRA BitMathop & -279 abort abort_code -Addr : 47FD: 64 : Variable Operation Local Offset - 1 Read -Addr : 47FE: 31 : Abort value -Addr : 47FF: Data : 32 2 -|===========================================================================| -Spin Block send_cmd_slow with 3 Parameters and 1 Extra Stack Longs. Method 10 -PRI send_cmd_slow( cmd, val, crc ) : reply | time_stamp - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - cmd -Local Parameter DBASE:0008 - val -Local Parameter DBASE:000C - crc -Local Variable DBASE:0010 - time_stamp -|===========================================================================| -293 if (cmd & $80) -Addr : 4800: 64 : Variable Operation Local Offset - 1 Read -Addr : 4801: 37 06 : Constant Mask Y=6 00000080 -Addr : 4803: E8 : Math Op & -Addr : 4804: JZ Label0002 -Addr : 4804: 0A 14 : jz Address = 481A 20 -295 cmd &= $7F -Addr : 4806: 37 26 : Constant Mask Y=38 Decrement 0000007F -Addr : 4808: 66 48 : Variable Operation Local Offset - 1 Assign BitMathop & -296 reply := send_cmd_slow( CMD55, 0, $65 ) -Addr : 480A: 00 : Drop Anchor Push -Addr : 480B: 38 77 : Constant 1 Bytes - 77 -Addr : 480D: 35 : Constant 1 $00000000 -Addr : 480E: 38 65 : Constant 1 Bytes - 65 -Addr : 4810: 05 0A : Call Sub 10 -Addr : 4812: 61 : Variable Operation Local Offset - 0 Write -297 if (reply > 1) -Addr : 4813: 60 : Variable Operation Local Offset - 0 Read -Addr : 4814: 36 : Constant 2 $00000001 -Addr : 4815: FA : Math Op > -Addr : 4816: JZ Label0004 -Addr : 4816: 0A 02 : jz Address = 481A 2 -298 return reply -Addr : 4818: 60 : Variable Operation Local Offset - 0 Read -Addr : 4819: 33 : Return value -Addr : 481A: Label0004 -Addr : 481A: Label0005 -Addr : 481A: Label0002 -Addr : 481A: Label0003 -300 outa |= maskCS -Addr : 481A: C4 84 F0 : Memory Op Long PBASE + READ Address = 04F0 -Addr : 481D: 3F D4 4A : Register op OUTA ByteMathop | -301 outa &= !maskCS -Addr : 4820: C4 84 F0 : Memory Op Long PBASE + READ Address = 04F0 -Addr : 4823: E7 : Math Op ! -Addr : 4824: 3F D4 48 : Register op OUTA BitMathop & -303 read_32_slow -Addr : 4827: 01 : Drop Anchor -Addr : 4828: 05 0C : Call Sub 12 -305 send_slow( cmd, 8 ) -Addr : 482A: 01 : Drop Anchor -Addr : 482B: 64 : Variable Operation Local Offset - 1 Read -Addr : 482C: 37 02 : Constant Mask Y=2 00000008 -Addr : 482E: 05 0B : Call Sub 11 -307 send_slow( val, 32 ) -Addr : 4830: 01 : Drop Anchor -Addr : 4831: 68 : Variable Operation Local Offset - 2 Read -Addr : 4832: 37 04 : Constant Mask Y=4 00000020 -Addr : 4834: 05 0B : Call Sub 11 -309 send_slow( crc, 8 ) -Addr : 4836: 01 : Drop Anchor -Addr : 4837: 6C : Variable Operation Local Offset - 3 Read -Addr : 4838: 37 02 : Constant Mask Y=2 00000008 -Addr : 483A: 05 0B : Call Sub 11 -311 if cmd == CMD12 -Addr : 483C: 64 : Variable Operation Local Offset - 1 Read -Addr : 483D: 38 4C : Constant 1 Bytes - 4C -Addr : 483F: FC : Math Op == -Addr : 4840: JZ Label0006 -Addr : 4840: 0A 03 : jz Address = 4845 3 -312 read_slow -Addr : 4842: 01 : Drop Anchor -Addr : 4843: 05 0D : Call Sub 13 -Addr : 4845: Label0006 -Addr : 4845: Label0007 -314 time_stamp := 9 -Addr : 4845: 38 09 : Constant 1 Bytes - 09 -Addr : 4847: 71 : Variable Operation Local Offset - 4 Write -Addr : 4848: Label0008 -316 reply := read_slow -Addr : 4848: 00 : Drop Anchor Push -Addr : 4849: 05 0D : Call Sub 13 -Addr : 484B: 61 : Variable Operation Local Offset - 0 Write -Addr : 484C: Label0009 -317 while( reply & $80 ) and ( time_stamp-- ) -Addr : 484C: 60 : Variable Operation Local Offset - 0 Read -Addr : 484D: 37 06 : Constant Mask Y=6 00000080 -Addr : 484F: E8 : Math Op & -Addr : 4850: 72 BE : Variable Operation Local Offset - 4 Assign VAR-- post-dec Long Push -Addr : 4852: F0 : Math Op AND -Addr : 4853: JNZ Label0008 -Addr : 4853: 0B 73 : jnz Address = 4848 -13 -Addr : 4855: Label000A -Addr : 4855: 32 : Return -|===========================================================================| -Spin Block send_slow with 2 Parameters and 0 Extra Stack Longs. Method 11 -PRI send_slow( value, bits_to_send ) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - value -Local Parameter DBASE:0008 - bits_to_send -|===========================================================================| -330 value ><= bits_to_send -Addr : 4856: 68 : Variable Operation Local Offset - 2 Read -Addr : 4857: 66 4F : Variable Operation Local Offset - 1 Assign LongMathop >< -331 repeat bits_to_send -Addr : 4859: 68 : Variable Operation Local Offset - 2 Read -Addr : 485A: TJZ Label0004 -Addr : 485A: 08 17 : tjz Address = 4873 23 -Addr : 485C: Label0002 -332 outa[pinCLK]~ -Addr : 485C: C4 84 E0 : Memory Op Long PBASE + READ Address = 04E0 -Addr : 485F: 3D D4 18 : Register [Bit] op OUTA VAR~ Post-clear -333 outa[pinDI] := value -Addr : 4862: 64 : Variable Operation Local Offset - 1 Read -Addr : 4863: C4 84 E4 : Memory Op Long PBASE + READ Address = 04E4 -Addr : 4866: 3D B4 : Register [Bit] op OUTA Write -334 value >>= 1 -Addr : 4868: 36 : Constant 2 $00000001 -Addr : 4869: 66 42 : Variable Operation Local Offset - 1 Assign ByteMathop >> -335 outa[pinCLK]~~ -Addr : 486B: C4 84 E0 : Memory Op Long PBASE + READ Address = 04E0 -Addr : 486E: 3D D4 1C : Register [Bit] op OUTA VAR~~ Post-set -Addr : 4871: Label0003 -Addr : 4871: DJNZ Label0002 -Addr : 4871: 09 69 : djnz Address = 485C -23 -Addr : 4873: Label0004 -Addr : 4873: 32 : Return -|===========================================================================| -Spin Block read_32_slow with 0 Parameters and 0 Extra Stack Longs. Method 12 -PRI read_32_slow : r - -Local Parameter DBASE:0000 - Result -|===========================================================================| -338 repeat 4 -Addr : 4874: 37 01 : Constant Mask Y=1 00000004 -Addr : 4876: TJZ Label0004 -Addr : 4876: 08 0B : tjz Address = 4883 11 -Addr : 4878: Label0002 -339 r <<= 8 -Addr : 4878: 37 02 : Constant Mask Y=2 00000008 -Addr : 487A: 62 43 : Variable Operation Local Offset - 0 Assign ByteMathop << -340 r |= read_slow -Addr : 487C: 00 : Drop Anchor Push -Addr : 487D: 05 0D : Call Sub 13 -Addr : 487F: 62 4A : Variable Operation Local Offset - 0 Assign ByteMathop | -Addr : 4881: Label0003 -Addr : 4881: DJNZ Label0002 -Addr : 4881: 09 75 : djnz Address = 4878 -11 -Addr : 4883: Label0004 -Addr : 4883: 32 : Return -|===========================================================================| -Spin Block read_slow with 0 Parameters and 0 Extra Stack Longs. Method 13 -PRI read_slow : r - -Local Parameter DBASE:0000 - Result -|===========================================================================| -347 outa[pinDI]~~ -Addr : 4884: C4 84 E4 : Memory Op Long PBASE + READ Address = 04E4 -Addr : 4887: 3D D4 1C : Register [Bit] op OUTA VAR~~ Post-set -349 repeat 8 -Addr : 488A: 37 02 : Constant Mask Y=2 00000008 -Addr : 488C: TJZ Label0004 -Addr : 488C: 08 17 : tjz Address = 48A5 23 -Addr : 488E: Label0002 -350 outa[pinCLK]~ -Addr : 488E: C4 84 E0 : Memory Op Long PBASE + READ Address = 04E0 -Addr : 4891: 3D D4 18 : Register [Bit] op OUTA VAR~ Post-clear -351 outa[pinCLK]~~ -Addr : 4894: C4 84 E0 : Memory Op Long PBASE + READ Address = 04E0 -Addr : 4897: 3D D4 1C : Register [Bit] op OUTA VAR~~ Post-set -352 r += r + ina[pinDO] -Addr : 489A: 60 : Variable Operation Local Offset - 0 Read -Addr : 489B: C4 84 DC : Memory Op Long PBASE + READ Address = 04DC -Addr : 489E: 3D 92 : Register [Bit] op INA Read -Addr : 48A0: EC : Math Op + -Addr : 48A1: 62 4C : Variable Operation Local Offset - 0 Assign WordMathop + -Addr : 48A3: Label0003 -Addr : 48A3: DJNZ Label0002 -Addr : 48A3: 09 69 : djnz Address = 488E -23 -Addr : 48A5: Label0004 -354 if( (cnt - SPI_block_index) > (clkfreq << 2) ) -Addr : 48A5: 3F 91 : Register op CNT Read -Addr : 48A7: C4 40 : Memory Op Long PBASE + READ Address = 0040 -Addr : 48A9: ED : Math Op - -Addr : 48AA: 35 : Constant 1 $00000000 -Addr : 48AB: C0 : Memory Op Long POP Address READ -Addr : 48AC: 37 00 : Constant Mask Y=0 00000002 -Addr : 48AE: E3 : Math Op << -Addr : 48AF: FA : Math Op > -Addr : 48B0: JZ Label0005 -Addr : 48B0: 0A 07 : jz Address = 48B9 7 -355 crash( ERR_CARD_BUSY_TIMEOUT ) -Addr : 48B2: 01 : Drop Anchor -Addr : 48B3: 39 03 E7 : Constant 2 Bytes - 03 E7 -Addr : 48B6: E7 : Math Op ! -Addr : 48B7: 05 09 : Call Sub 9 -Addr : 48B9: Label0005 -Addr : 48B9: Label0006 -Addr : 48B9: 32 : Return -|===========================================================================| -Object E555_SPKEngine -Object Base is 48BC -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -Spin Block speakerFrequency with 2 Parameters and 0 Extra Stack Longs. Method 1 -PUB speakerFrequency(newFrequency, speakerPinNumber) '' 10 Stack Longs - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - newFrequency -Local Parameter DBASE:0008 - speakerPinNumber -|===========================================================================| -40 speakerSetup((newFrequency <> -1), speakerPinNumber) -Addr : 48CC: 01 : Drop Anchor -Addr : 48CD: 64 : Variable Operation Local Offset - 1 Read -Addr : 48CE: 34 : Constant 0 $FFFFFFFF -Addr : 48CF: FB : Math Op <> -Addr : 48D0: 68 : Variable Operation Local Offset - 2 Read -Addr : 48D1: 05 03 : Call Sub 3 -42 newFrequency := ((newFrequency <# clkfreq) #> 0) -Addr : 48D3: 64 : Variable Operation Local Offset - 1 Read -Addr : 48D4: 35 : Constant 1 $00000000 -Addr : 48D5: C0 : Memory Op Long POP Address READ -Addr : 48D6: E5 : Math Op <# -Addr : 48D7: 35 : Constant 1 $00000000 -Addr : 48D8: E4 : Math Op #> -Addr : 48D9: 65 : Variable Operation Local Offset - 1 Write -44 result := 1 -Addr : 48DA: 36 : Constant 2 $00000001 -Addr : 48DB: 61 : Variable Operation Local Offset - 0 Write -46 repeat 32 -Addr : 48DC: 37 04 : Constant Mask Y=4 00000020 -Addr : 48DE: TJZ Label0004 -Addr : 48DE: 08 15 : tjz Address = 48F5 21 -Addr : 48E0: Label0002 -47 newFrequency <<= 1 -Addr : 48E0: 36 : Constant 2 $00000001 -Addr : 48E1: 66 43 : Variable Operation Local Offset - 1 Assign ByteMathop << -48 result <-= 1 -Addr : 48E3: 36 : Constant 2 $00000001 -Addr : 48E4: 62 41 : Variable Operation Local Offset - 0 Assign BitMathop -< -49 if(newFrequency => clkfreq) -Addr : 48E6: 64 : Variable Operation Local Offset - 1 Read -Addr : 48E7: 35 : Constant 1 $00000000 -Addr : 48E8: C0 : Memory Op Long POP Address READ -Addr : 48E9: FE : Math Op => -Addr : 48EA: JZ Label0005 -Addr : 48EA: 0A 07 : jz Address = 48F3 7 -50 newFrequency -= clkfreq -Addr : 48EC: 35 : Constant 1 $00000000 -Addr : 48ED: C0 : Memory Op Long POP Address READ -Addr : 48EE: 66 4D : Variable Operation Local Offset - 1 Assign WordMathop - -51 result += 1 -Addr : 48F0: 36 : Constant 2 $00000001 -Addr : 48F1: 62 4C : Variable Operation Local Offset - 0 Assign WordMathop + -Addr : 48F3: Label0005 -Addr : 48F3: Label0006 -Addr : 48F3: Label0003 -Addr : 48F3: DJNZ Label0002 -Addr : 48F3: 09 6B : djnz Address = 48E0 -21 -Addr : 48F5: Label0004 -53 frqa := result~ -Addr : 48F5: 62 98 : Variable Operation Local Offset - 0 Assign VAR~ Post-clear Push -Addr : 48F7: 3F BA : Register op FRQA Write -55 phsb := 0 -Addr : 48F9: 35 : Constant 1 $00000000 -Addr : 48FA: 3F BD : Register op PHSB Write -Addr : 48FC: 32 : Return -|===========================================================================| -Spin Block speakerVolume with 2 Parameters and 0 Extra Stack Longs. Method 2 -PUB speakerVolume(newVolume, speakerPinNumber) '' 10 Stack Longs - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - newVolume -Local Parameter DBASE:0008 - speakerPinNumber -|===========================================================================| -66 speakerSetup((newVolume <> -1), speakerPinNumber) -Addr : 48FD: 01 : Drop Anchor -Addr : 48FE: 64 : Variable Operation Local Offset - 1 Read -Addr : 48FF: 34 : Constant 0 $FFFFFFFF -Addr : 4900: FB : Math Op <> -Addr : 4901: 68 : Variable Operation Local Offset - 2 Read -Addr : 4902: 05 03 : Call Sub 3 -68 frqb := (((100 - ((newVolume <# 100) #> 0)) * constant(posx / 50)) | $7) -Addr : 4904: 38 64 : Constant 1 Bytes - 64 -Addr : 4906: 64 : Variable Operation Local Offset - 1 Read -Addr : 4907: 38 64 : Constant 1 Bytes - 64 -Addr : 4909: E5 : Math Op <# -Addr : 490A: 35 : Constant 1 $00000000 -Addr : 490B: E4 : Math Op #> -Addr : 490C: ED : Math Op - -Addr : 490D: 3B 02 8F 5C 28 : Constant 4 Bytes - 02 8F 5C 28 -Addr : 4912: F4 : Math Op * -Addr : 4913: 37 22 : Constant Mask Y=34 Decrement 00000007 -Addr : 4915: EA : Math Op | -Addr : 4916: 3F BB : Register op FRQB Write -Addr : 4918: 32 : Return -|===========================================================================| -Spin Block speakerSetup with 2 Parameters and 0 Extra Stack Longs. Method 3 -PRI speakerSetup(activeOrInactive, speakerPinNumber) ' 5 Stack Longs - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - activeOrInactive -Local Parameter DBASE:0008 - speakerPinNumber -|===========================================================================| -72 speakerPinNumber := ((speakerPinNumber <# 31) #> 0) -Addr : 4919: 68 : Variable Operation Local Offset - 2 Read -Addr : 491A: 37 24 : Constant Mask Y=36 Decrement 0000001F -Addr : 491C: E5 : Math Op <# -Addr : 491D: 35 : Constant 1 $00000000 -Addr : 491E: E4 : Math Op #> -Addr : 491F: 69 : Variable Operation Local Offset - 2 Write -74 dira[speakerPinNumber] := activeOrInactive -Addr : 4920: 64 : Variable Operation Local Offset - 1 Read -Addr : 4921: 68 : Variable Operation Local Offset - 2 Read -Addr : 4922: 3D B6 : Register [Bit] op DIRA Write -76 outa[speakerPinNumber] := false -Addr : 4924: 35 : Constant 1 $00000000 -Addr : 4925: 68 : Variable Operation Local Offset - 2 Read -Addr : 4926: 3D B4 : Register [Bit] op OUTA Write -78 ctra := ((constant(%0_0100 << 26) + speakerPinNumber) & activeOrInactive) -Addr : 4928: 37 1B : Constant Mask Y=27 10000000 -Addr : 492A: 68 : Variable Operation Local Offset - 2 Read -Addr : 492B: EC : Math Op + -Addr : 492C: 64 : Variable Operation Local Offset - 1 Read -Addr : 492D: E8 : Math Op & -Addr : 492E: 3F B8 : Register op CTRA Write -80 ctrb := ((constant(%0_0110 << 26) + speakerPinNumber) & activeOrInactive) -Addr : 4930: 3B 18 00 00 00 : Constant 4 Bytes - 18 00 00 00 -Addr : 4935: 68 : Variable Operation Local Offset - 2 Read -Addr : 4936: EC : Math Op + -Addr : 4937: 64 : Variable Operation Local Offset - 1 Read -Addr : 4938: E8 : Math Op & -Addr : 4939: 3F B9 : Register op CTRB Write -Addr : 493B: 32 : Return -|===========================================================================| -Object Parallax Serial Terminal -Object Base is 493C -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0004 Variable cog -VBASE : 0004 LONG Size 0004 Variable rx_head -VBASE : 0008 LONG Size 0004 Variable rx_tail -VBASE : 000C LONG Size 0004 Variable tx_head -VBASE : 0010 LONG Size 0004 Variable tx_tail -VBASE : 0014 LONG Size 0004 Variable rx_pin -VBASE : 0018 LONG Size 0004 Variable tx_pin -VBASE : 001C LONG Size 0004 Variable rxtx_mode -VBASE : 0020 LONG Size 0004 Variable bit_ticks -VBASE : 0024 LONG Size 0004 Variable buffer_ptr -VBASE : 0028 BYTE Size 0040 Variable rx_buffer -VBASE : 0068 BYTE Size 0040 Variable tx_buffer -VBASE : 00A8 BYTE Size 0032 Variable str_buffer -|===========================================================================| -Object DAT Blocks -|===========================================================================| -49CC(0000) | org -49CC(0000) F0 A9 BC A0 | entry mov t1,par 'get structure address -49D0(0001) 10 A8 FC 80 | add t1,#4 << 2 'skip past heads and tails -49D4(0002) 54 AA BC 08 | rdlong t2,t1 'get rx_pin -49D8(0003) 01 B2 FC A0 | mov rxmask,#1 -49DC(0004) 55 B2 BC 2C | shl rxmask,t2 -49E0(0005) 04 A8 FC 80 | add t1,#4 'get tx_pin -49E4(0006) 54 AA BC 08 | rdlong t2,t1 -49E8(0007) 01 BE FC A0 | mov txmask,#1 -49EC(0008) 55 BE BC 2C | shl txmask,t2 -49F0(0009) 04 A8 FC 80 | add t1,#4 'get rxtx_mode -49F4(000A) 54 AE BC 08 | rdlong rxtxmode,t1 -49F8(000B) 04 A8 FC 80 | add t1,#4 'get bit_ticks -49FC(000C) 54 B0 BC 08 | rdlong bitticks,t1 -4A00(000D) 04 A8 FC 80 | add t1,#4 'get buffer_ptr -4A04(000E) 54 B4 BC 08 | rdlong rxbuff,t1 -4A08(000F) 5A C0 BC A0 | mov txbuff,rxbuff -4A0C(0010) 40 C0 FC 80 | add txbuff,#BUFFER_LENGTH -4A10(0011) 04 AE 7C 62 | test rxtxmode,#%100 wz 'init tx pin according to mode -4A14(0012) 02 AE 7C 61 | test rxtxmode,#%010 wc -4A18(0013) 5F E8 9B 68 | if_z_ne_c or outa,txmask -4A1C(0014) 5F EC AB 68 | if_z or dira,txmask -4A20(0015) 33 C8 FC A0 | mov txcode,#transmit 'initialize ping-pong multitasking -4A24(0016) 64 BC BC 5C | receive jmpret rxcode,txcode 'run chunk of tx code, then return -4A28(0017) 01 AE 7C 62 | test rxtxmode,#%001 wz 'wait for start bit on rx pin -4A2C(0018) F2 B3 3C 61 | test rxmask,ina wc -4A30(0019) 16 00 64 5C | if_z_eq_c jmp #receive -4A34(001A) 09 B8 FC A0 | mov rxbits,#9 'ready to receive byte -4A38(001B) 58 BA BC A0 | mov rxcnt,bitticks -4A3C(001C) 01 BA FC 28 | shr rxcnt,#1 -4A40(001D) F1 BB BC 80 | add rxcnt,cnt -4A44(001E) 58 BA BC 80 | :bit add rxcnt,bitticks 'ready next bit period -4A48(001F) 64 BC BC 5C | :wait jmpret rxcode,txcode 'run chunk of tx code, then return -4A4C(0020) 5D A8 BC A0 | mov t1,rxcnt 'check if bit receive period done -4A50(0021) F1 A9 BC 84 | sub t1,cnt -4A54(0022) 00 A8 7C C1 | cmps t1,#0 wc -4A58(0023) 1F 00 4C 5C | if_nc jmp #:wait -4A5C(0024) F2 B3 3C 61 | test rxmask,ina wc 'receive bit on rx pin -4A60(0025) 01 B6 FC 30 | rcr rxdata,#1 -4A64(0026) 1E B8 FC E4 | djnz rxbits,#:bit -4A68(0027) 17 B6 FC 28 | shr rxdata,#32-9 'justify and trim received byte -4A6C(0028) FF B6 FC 60 | and rxdata,#$FF -4A70(0029) 01 AE 7C 62 | test rxtxmode,#%001 wz 'if rx inverted, invert byte -4A74(002A) FF B6 D4 6C | if_nz xor rxdata,#$FF -4A78(002B) F0 AB BC 08 | rdlong t2,par 'save received byte and inc head -4A7C(002C) 5A AA BC 80 | add t2,rxbuff -4A80(002D) 55 B6 3C 00 | wrbyte rxdata,t2 -4A84(002E) 5A AA BC 84 | sub t2,rxbuff -4A88(002F) 01 AA FC 80 | add t2,#1 -4A8C(0030) 3F AA FC 60 | and t2,#BUFFER_MASK -4A90(0031) F0 AB 3C 08 | wrlong t2,par -4A94(0032) 16 00 7C 5C | jmp #receive 'byte done, receive next byte -4A98(0033) 5E C8 BC 5C | transmit jmpret txcode,rxcode 'run chunk of rx code, then return -4A9C(0034) F0 A9 BC A0 | mov t1,par 'check for head <> tail -4AA0(0035) 08 A8 FC 80 | add t1,#2 << 2 -4AA4(0036) 54 AA BC 08 | rdlong t2,t1 -4AA8(0037) 04 A8 FC 80 | add t1,#1 << 2 -4AAC(0038) 54 AC BC 08 | rdlong t3,t1 -4AB0(0039) 56 AA 3C 86 | cmp t2,t3 wz -4AB4(003A) 33 00 68 5C | if_z jmp #transmit -4AB8(003B) 60 AC BC 80 | add t3,txbuff 'get byte and inc tail -4ABC(003C) 56 C2 BC 00 | rdbyte txdata,t3 -4AC0(003D) 60 AC BC 84 | sub t3,txbuff -4AC4(003E) 01 AC FC 80 | add t3,#1 -4AC8(003F) 3F AC FC 60 | and t3,#BUFFER_MASK -4ACC(0040) 54 AC 3C 08 | wrlong t3,t1 -4AD0(0041) 00 C3 FC 68 | or txdata,#$100 'ready byte to transmit -4AD4(0042) 02 C2 FC 2C | shl txdata,#2 -4AD8(0043) 01 C2 FC 68 | or txdata,#1 -4ADC(0044) 0B C4 FC A0 | mov txbits,#11 -4AE0(0045) F1 C7 BC A0 | mov txcnt,cnt -4AE4(0046) 04 AE 7C 62 | :bit test rxtxmode,#%100 wz 'output bit on tx pin -4AE8(0047) 02 AE 7C 61 | test rxtxmode,#%010 wc 'according to mode -4AEC(0048) 01 C2 E0 6C | if_z_and_c xor txdata,#1 -4AF0(0049) 01 C2 FC 29 | shr txdata,#1 wc -4AF4(004A) 5F E8 AB 70 | if_z muxc outa,txmask -4AF8(004B) 5F EC 97 74 | if_nz muxnc dira,txmask -4AFC(004C) 58 C6 BC 80 | add txcnt,bitticks 'ready next cnt -4B00(004D) 5E C8 BC 5C | :wait jmpret txcode,rxcode 'run chunk of rx code, then return -4B04(004E) 63 A8 BC A0 | mov t1,txcnt 'check if bit transmit period done -4B08(004F) F1 A9 BC 84 | sub t1,cnt -4B0C(0050) 00 A8 7C C1 | cmps t1,#0 wc -4B10(0051) 4D 00 4C 5C | if_nc jmp #:wait -4B14(0052) 46 C4 FC E4 | djnz txbits,#:bit 'another bit to transmit? -4B18(0053) 33 00 7C 5C | jmp #transmit 'byte done, transmit next byte -4B1C(0054) | t1 res 1 -4B1C(0055) | t2 res 1 -4B1C(0056) | t3 res 1 -4B1C(0057) | rxtxmode res 1 -4B1C(0058) | bitticks res 1 -4B1C(0059) | rxmask res 1 -4B1C(005A) | rxbuff res 1 -4B1C(005B) | rxdata res 1 -4B1C(005C) | rxbits res 1 -4B1C(005D) | rxcnt res 1 -4B1C(005E) | rxcode res 1 -4B1C(005F) | txmask res 1 -4B1C(0060) | txbuff res 1 -4B1C(0061) | txdata res 1 -4B1C(0062) | txbits res 1 -4B1C(0063) | txcnt res 1 -4B1C(0064) | txcode res 1 -|===========================================================================| -|===========================================================================| -Spin Block Start with 1 Parameters and 0 Extra Stack Longs. Method 1 -PUB Start(baudrate) : okay - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - baudrate -|===========================================================================| -85 okay := StartRxTx(31, 30, 0, baudrate) -Addr : 4B1C: 00 : Drop Anchor Push -Addr : 4B1D: 37 24 : Constant Mask Y=36 Decrement 0000001F -Addr : 4B1F: 38 1E : Constant 1 Bytes - 1E -Addr : 4B21: 35 : Constant 1 $00000000 -Addr : 4B22: 64 : Variable Operation Local Offset - 1 Read -Addr : 4B23: 05 02 : Call Sub 2 -Addr : 4B25: 61 : Variable Operation Local Offset - 0 Write -86 waitcnt(clkfreq + cnt) 'Wait 1 second for PST -Addr : 4B26: 35 : Constant 1 $00000000 -Addr : 4B27: C0 : Memory Op Long POP Address READ -Addr : 4B28: 3F 91 : Register op CNT Read -Addr : 4B2A: EC : Math Op + -Addr : 4B2B: 23 : WaitCnt(count) -87 Clear 'Clear display -Addr : 4B2C: 01 : Drop Anchor -Addr : 4B2D: 05 10 : Call Sub 16 -Addr : 4B2F: 32 : Return -|===========================================================================| -Spin Block StartRxTx with 4 Parameters and 0 Extra Stack Longs. Method 2 -PUB StartRxTx(rxpin, txpin, mode, baudrate) : okay - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - rxpin -Local Parameter DBASE:0008 - txpin -Local Parameter DBASE:000C - mode -Local Parameter DBASE:0010 - baudrate -|===========================================================================| -102 stop -Addr : 4B30: 01 : Drop Anchor -Addr : 4B31: 05 03 : Call Sub 3 -103 longfill(@rx_head, 0, 4) -Addr : 4B33: 47 : Variable Operation Global Offset - 1 Address -Addr : 4B34: 35 : Constant 1 $00000000 -Addr : 4B35: 37 01 : Constant Mask Y=1 00000004 -Addr : 4B37: 1A : LongFill(Start, Value, Count) -104 longmove(@rx_pin, @rxpin, 3) -Addr : 4B38: 57 : Variable Operation Global Offset - 5 Address -Addr : 4B39: 67 : Variable Operation Local Offset - 1 Address -Addr : 4B3A: 37 21 : Constant Mask Y=33 Decrement 00000003 -Addr : 4B3C: 1E : LongMove(To, From, Count) -105 bit_ticks := clkfreq / baudrate -Addr : 4B3D: 35 : Constant 1 $00000000 -Addr : 4B3E: C0 : Memory Op Long POP Address READ -Addr : 4B3F: 70 : Variable Operation Local Offset - 4 Read -Addr : 4B40: F6 : Math Op / -Addr : 4B41: C9 20 : Memory Op Long VBASE + WRITE Address = 0020 -106 buffer_ptr := @rx_buffer -Addr : 4B43: 8B 28 : Memory Op Byte VBASE + ADDRESS Address = 0028 -Addr : 4B45: C9 24 : Memory Op Long VBASE + WRITE Address = 0024 -107 okay := cog := cognew(@entry, @rx_head) + 1 -Addr : 4B47: 34 : Constant 0 $FFFFFFFF -Addr : 4B48: C7 80 90 : Memory Op Long PBASE + ADDRESS Address = 0090 -Addr : 4B4B: 47 : Variable Operation Global Offset - 1 Address -Addr : 4B4C: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 4B4D: 36 : Constant 2 $00000001 -Addr : 4B4E: EC : Math Op + -Addr : 4B4F: 42 80 : Variable Operation Global Offset - 0 Assign Write Push -Addr : 4B51: 61 : Variable Operation Local Offset - 0 Write -Addr : 4B52: 32 : Return -|===========================================================================| -Spin Block Stop with 0 Parameters and 0 Extra Stack Longs. Method 3 -PUB Stop - -Local Parameter DBASE:0000 - Result -|===========================================================================| -112 if cog -Addr : 4B53: 40 : Variable Operation Global Offset - 0 Read -Addr : 4B54: JZ Label0002 -Addr : 4B54: 0A 05 : jz Address = 4B5B 5 -113 cogstop(cog~ - 1) -Addr : 4B56: 42 98 : Variable Operation Global Offset - 0 Assign VAR~ Post-clear Push -Addr : 4B58: 36 : Constant 2 $00000001 -Addr : 4B59: ED : Math Op - -Addr : 4B5A: 21 : CogStop(id) -Addr : 4B5B: Label0002 -Addr : 4B5B: Label0003 -114 longfill(@rx_head, 0, 9) -Addr : 4B5B: 47 : Variable Operation Global Offset - 1 Address -Addr : 4B5C: 35 : Constant 1 $00000000 -Addr : 4B5D: 38 09 : Constant 1 Bytes - 09 -Addr : 4B5F: 1A : LongFill(Start, Value, Count) -Addr : 4B60: 32 : Return -|===========================================================================| -Spin Block Char with 1 Parameters and 0 Extra Stack Longs. Method 4 -PUB Char(bytechr) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - bytechr -|===========================================================================| -121 repeat until (tx_tail <> ((tx_head + 1) & BUFFER_MASK)) -Addr : 4B61: Label0002 -Addr : 4B61: 50 : Variable Operation Global Offset - 4 Read -Addr : 4B62: 4C : Variable Operation Global Offset - 3 Read -Addr : 4B63: 36 : Constant 2 $00000001 -Addr : 4B64: EC : Math Op + -Addr : 4B65: 37 25 : Constant Mask Y=37 Decrement 0000003F -Addr : 4B67: E8 : Math Op & -Addr : 4B68: FB : Math Op <> -Addr : 4B69: JNZ Label0004 -Addr : 4B69: 0B 02 : jnz Address = 4B6D 2 -Addr : 4B6B: Label0003 -Addr : 4B6B: JMP Label0002 -Addr : 4B6B: 04 74 : Jmp 4B61 -12 -Addr : 4B6D: Label0004 -122 tx_buffer[tx_head] := bytechr -Addr : 4B6D: 64 : Variable Operation Local Offset - 1 Read -Addr : 4B6E: 4C : Variable Operation Global Offset - 3 Read -Addr : 4B6F: 99 68 : Memory Op Byte VBASE + POP Index WRITE Address = 0068 -123 tx_head := (tx_head + 1) & BUFFER_MASK -Addr : 4B71: 4C : Variable Operation Global Offset - 3 Read -Addr : 4B72: 36 : Constant 2 $00000001 -Addr : 4B73: EC : Math Op + -Addr : 4B74: 37 25 : Constant Mask Y=37 Decrement 0000003F -Addr : 4B76: E8 : Math Op & -Addr : 4B77: 4D : Variable Operation Global Offset - 3 Write -125 if rxtx_mode & %1000 -Addr : 4B78: 5C : Variable Operation Global Offset - 7 Read -Addr : 4B79: 37 02 : Constant Mask Y=2 00000008 -Addr : 4B7B: E8 : Math Op & -Addr : 4B7C: JZ Label0005 -Addr : 4B7C: 0A 03 : jz Address = 4B81 3 -126 CharIn -Addr : 4B7E: 01 : Drop Anchor -Addr : 4B7F: 05 06 : Call Sub 6 -Addr : 4B81: Label0005 -Addr : 4B81: Label0006 -Addr : 4B81: 32 : Return -|===========================================================================| -Spin Block Chars with 2 Parameters and 0 Extra Stack Longs. Method 5 -PUB Chars(bytechr, count) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - bytechr -Local Parameter DBASE:0008 - count -|===========================================================================| -134 repeat count -Addr : 4B82: 68 : Variable Operation Local Offset - 2 Read -Addr : 4B83: TJZ Label0004 -Addr : 4B83: 08 06 : tjz Address = 4B8B 6 -Addr : 4B85: Label0002 -135 Char(bytechr) -Addr : 4B85: 01 : Drop Anchor -Addr : 4B86: 64 : Variable Operation Local Offset - 1 Read -Addr : 4B87: 05 04 : Call Sub 4 -Addr : 4B89: Label0003 -Addr : 4B89: DJNZ Label0002 -Addr : 4B89: 09 7A : djnz Address = 4B85 -6 -Addr : 4B8B: Label0004 -Addr : 4B8B: 32 : Return -|===========================================================================| -Spin Block CharIn with 0 Parameters and 0 Extra Stack Longs. Method 6 -PUB CharIn : bytechr - -Local Parameter DBASE:0000 - Result -|===========================================================================| -141 repeat while (bytechr := RxCheck) < 0 -Addr : 4B8C: Label0002 -Addr : 4B8C: 00 : Drop Anchor Push -Addr : 4B8D: 05 22 : Call Sub 34 -Addr : 4B8F: 62 80 : Variable Operation Local Offset - 0 Assign Write Push -Addr : 4B91: 35 : Constant 1 $00000000 -Addr : 4B92: F9 : Math Op < -Addr : 4B93: JZ Label0004 -Addr : 4B93: 0A 02 : jz Address = 4B97 2 -Addr : 4B95: Label0003 -Addr : 4B95: JMP Label0002 -Addr : 4B95: 04 75 : Jmp 4B8C -11 -Addr : 4B97: Label0004 -Addr : 4B97: 32 : Return -|===========================================================================| -Spin Block Str with 1 Parameters and 0 Extra Stack Longs. Method 7 -PUB Str(stringptr) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - stringptr -|===========================================================================| -148 repeat strsize(stringptr) -Addr : 4B98: 64 : Variable Operation Local Offset - 1 Read -Addr : 4B99: 16 : StrSize(String) -Addr : 4B9A: TJZ Label0004 -Addr : 4B9A: 08 08 : tjz Address = 4BA4 8 -Addr : 4B9C: Label0002 -149 Char(byte[stringptr++]) -Addr : 4B9C: 01 : Drop Anchor -Addr : 4B9D: 66 AE : Variable Operation Local Offset - 1 Assign VAR++ post inc Long Push -Addr : 4B9F: 80 : Memory Op Byte POP Address READ -Addr : 4BA0: 05 04 : Call Sub 4 -Addr : 4BA2: Label0003 -Addr : 4BA2: DJNZ Label0002 -Addr : 4BA2: 09 78 : djnz Address = 4B9C -8 -Addr : 4BA4: Label0004 -Addr : 4BA4: 32 : Return -|===========================================================================| -Spin Block StrIn with 1 Parameters and 0 Extra Stack Longs. Method 8 -PUB StrIn(stringptr) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - stringptr -|===========================================================================| -158 StrInMax(stringptr, -1) -Addr : 4BA5: 01 : Drop Anchor -Addr : 4BA6: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BA7: 34 : Constant 0 $FFFFFFFF -Addr : 4BA8: 05 09 : Call Sub 9 -Addr : 4BAA: 32 : Return -|===========================================================================| -Spin Block StrInMax with 2 Parameters and 0 Extra Stack Longs. Method 9 -PUB StrInMax(stringptr, maxcount) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - stringptr -Local Parameter DBASE:0008 - maxcount -|===========================================================================| -168 repeat while (maxcount--) 'While maxcount not reached -Addr : 4BAB: Label0002 -Addr : 4BAB: 6A BE : Variable Operation Local Offset - 2 Assign VAR-- post-dec Long Push -Addr : 4BAD: JZ Label0004 -Addr : 4BAD: 0A 10 : jz Address = 4BBF 16 -169 if (byte[stringptr++] := CharIn) == NL 'Get chars until NL -Addr : 4BAF: 00 : Drop Anchor Push -Addr : 4BB0: 05 06 : Call Sub 6 -Addr : 4BB2: 66 AE : Variable Operation Local Offset - 1 Assign VAR++ post inc Long Push -Addr : 4BB4: 82 80 : Memory Op Byte POP Address ASSIGN Write Push -Addr : 4BB6: 38 0D : Constant 1 Bytes - 0D -Addr : 4BB8: FC : Math Op == -Addr : 4BB9: JZ Label0005 -Addr : 4BB9: 0A 02 : jz Address = 4BBD 2 -170 quit -Addr : 4BBB: JMP Label0004 -Addr : 4BBB: 04 02 : Jmp 4BBF 2 -Addr : 4BBD: Label0005 -Addr : 4BBD: Label0006 -Addr : 4BBD: Label0003 -Addr : 4BBD: JMP Label0002 -Addr : 4BBD: 04 6C : Jmp 4BAB -20 -Addr : 4BBF: Label0004 -171 byte[stringptr+(byte[stringptr-1] == NL)]~ 'Zero terminate string; overwrite NL or append 0 char -Addr : 4BBF: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BC0: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BC1: 36 : Constant 2 $00000001 -Addr : 4BC2: ED : Math Op - -Addr : 4BC3: 80 : Memory Op Byte POP Address READ -Addr : 4BC4: 38 0D : Constant 1 Bytes - 0D -Addr : 4BC6: FC : Math Op == -Addr : 4BC7: EC : Math Op + -Addr : 4BC8: 82 18 : Memory Op Byte POP Address ASSIGN VAR~ Post-clear -Addr : 4BCA: 32 : Return -|===========================================================================| -Spin Block Dec with 1 Parameters and 2 Extra Stack Longs. Method 10 -PUB Dec(value) | i, x - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - value -Local Variable DBASE:0008 - i -Local Variable DBASE:000C - x -|===========================================================================| -178 x := value == NEGX 'Check for max negative -Addr : 4BCB: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BCC: 37 1E : Constant Mask Y=30 80000000 -Addr : 4BCE: FC : Math Op == -Addr : 4BCF: 6D : Variable Operation Local Offset - 3 Write -179 if value < 0 -Addr : 4BD0: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BD1: 35 : Constant 1 $00000000 -Addr : 4BD2: F9 : Math Op < -Addr : 4BD3: JZ Label0002 -Addr : 4BD3: 0A 0A : jz Address = 4BDF 10 -180 value := ||(value+x) 'If negative, make positive; adjust for max negative -Addr : 4BD5: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BD6: 6C : Variable Operation Local Offset - 3 Read -Addr : 4BD7: EC : Math Op + -Addr : 4BD8: E9 : Math Op || -Addr : 4BD9: 65 : Variable Operation Local Offset - 1 Write -181 Char("-") 'and output sign -Addr : 4BDA: 01 : Drop Anchor -Addr : 4BDB: 38 2D : Constant 1 Bytes - 2D -Addr : 4BDD: 05 04 : Call Sub 4 -Addr : 4BDF: Label0002 -Addr : 4BDF: Label0003 -183 i := 1_000_000_000 'Initialize divisor -Addr : 4BDF: 3B 3B 9A CA 00 : Constant 4 Bytes - 3B 9A CA 00 -Addr : 4BE4: 69 : Variable Operation Local Offset - 2 Write -185 repeat 10 'Loop for 10 digits -Addr : 4BE5: 38 0A : Constant 1 Bytes - 0A -Addr : 4BE7: TJZ Label0006 -Addr : 4BE7: 08 2D : tjz Address = 4C16 45 -Addr : 4BE9: Label0004 -186 if value => i -Addr : 4BE9: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BEA: 68 : Variable Operation Local Offset - 2 Read -Addr : 4BEB: FE : Math Op => -Addr : 4BEC: JZ Label0007 -Addr : 4BEC: 0A 16 : jz Address = 4C04 22 -187 Char(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative -Addr : 4BEE: 01 : Drop Anchor -Addr : 4BEF: 64 : Variable Operation Local Offset - 1 Read -Addr : 4BF0: 68 : Variable Operation Local Offset - 2 Read -Addr : 4BF1: F6 : Math Op / -Addr : 4BF2: 38 30 : Constant 1 Bytes - 30 -Addr : 4BF4: EC : Math Op + -Addr : 4BF5: 6C : Variable Operation Local Offset - 3 Read -Addr : 4BF6: 68 : Variable Operation Local Offset - 2 Read -Addr : 4BF7: 36 : Constant 2 $00000001 -Addr : 4BF8: FC : Math Op == -Addr : 4BF9: F4 : Math Op * -Addr : 4BFA: EC : Math Op + -Addr : 4BFB: 05 04 : Call Sub 4 -188 value //= i 'and digit from value -Addr : 4BFD: 68 : Variable Operation Local Offset - 2 Read -Addr : 4BFE: 66 57 : Variable Operation Local Offset - 1 Assign LongMathop // -189 result~~ 'flag non-zero found -Addr : 4C00: 62 1C : Variable Operation Local Offset - 0 Assign VAR~~ Post-set -Addr : 4C02: JMP Label0008 -Addr : 4C02: 04 0C : Jmp 4C10 12 -Addr : 4C04: Label0007 -190 elseif result or i == 1 -Addr : 4C04: 60 : Variable Operation Local Offset - 0 Read -Addr : 4C05: 68 : Variable Operation Local Offset - 2 Read -Addr : 4C06: 36 : Constant 2 $00000001 -Addr : 4C07: FC : Math Op == -Addr : 4C08: F2 : Math Op OR -Addr : 4C09: JZ Label0009 -Addr : 4C09: 0A 05 : jz Address = 4C10 5 -191 Char("0") 'If zero digit (or only digit) output it -Addr : 4C0B: 01 : Drop Anchor -Addr : 4C0C: 38 30 : Constant 1 Bytes - 30 -Addr : 4C0E: 05 04 : Call Sub 4 -Addr : 4C10: Label0009 -Addr : 4C10: Label0008 -192 i /= 10 'Update divisor -Addr : 4C10: 38 0A : Constant 1 Bytes - 0A -Addr : 4C12: 6A 56 : Variable Operation Local Offset - 2 Assign LongMathop / -Addr : 4C14: Label0005 -Addr : 4C14: DJNZ Label0004 -Addr : 4C14: 09 53 : djnz Address = 4BE9 -45 -Addr : 4C16: Label0006 -Addr : 4C16: 32 : Return -|===========================================================================| -Spin Block DecIn with 0 Parameters and 0 Extra Stack Longs. Method 11 -PUB DecIn : value - -Local Parameter DBASE:0000 - Result -|===========================================================================| -198 StrInMax(@str_buffer, MAXSTR_LENGTH) -Addr : 4C17: 01 : Drop Anchor -Addr : 4C18: 8B 80 A8 : Memory Op Byte VBASE + ADDRESS Address = 00A8 -Addr : 4C1B: 38 31 : Constant 1 Bytes - 31 -Addr : 4C1D: 05 09 : Call Sub 9 -199 value := StrToBase(@str_buffer, 10) -Addr : 4C1F: 00 : Drop Anchor Push -Addr : 4C20: 8B 80 A8 : Memory Op Byte VBASE + ADDRESS Address = 00A8 -Addr : 4C23: 38 0A : Constant 1 Bytes - 0A -Addr : 4C25: 05 23 : Call Sub 35 -Addr : 4C27: 61 : Variable Operation Local Offset - 0 Write -Addr : 4C28: 32 : Return -|===========================================================================| -Spin Block Bin with 2 Parameters and 0 Extra Stack Longs. Method 12 -PUB Bin(value, digits) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - value -Local Parameter DBASE:0008 - digits -|===========================================================================| -207 value <<= 32 - digits -Addr : 4C29: 37 04 : Constant Mask Y=4 00000020 -Addr : 4C2B: 68 : Variable Operation Local Offset - 2 Read -Addr : 4C2C: ED : Math Op - -Addr : 4C2D: 66 43 : Variable Operation Local Offset - 1 Assign ByteMathop << -208 repeat digits -Addr : 4C2F: 68 : Variable Operation Local Offset - 2 Read -Addr : 4C30: TJZ Label0004 -Addr : 4C30: 08 0D : tjz Address = 4C3F 13 -Addr : 4C32: Label0002 -209 Char((value <-= 1) & 1 + "0") -Addr : 4C32: 01 : Drop Anchor -Addr : 4C33: 36 : Constant 2 $00000001 -Addr : 4C34: 66 C1 : Variable Operation Local Offset - 1 Assign BitMathop -< Push -Addr : 4C36: 36 : Constant 2 $00000001 -Addr : 4C37: E8 : Math Op & -Addr : 4C38: 38 30 : Constant 1 Bytes - 30 -Addr : 4C3A: EC : Math Op + -Addr : 4C3B: 05 04 : Call Sub 4 -Addr : 4C3D: Label0003 -Addr : 4C3D: DJNZ Label0002 -Addr : 4C3D: 09 73 : djnz Address = 4C32 -13 -Addr : 4C3F: Label0004 -Addr : 4C3F: 32 : Return -|===========================================================================| -Spin Block BinIn with 0 Parameters and 0 Extra Stack Longs. Method 13 -PUB BinIn : value - -Local Parameter DBASE:0000 - Result -|===========================================================================| -215 StrInMax(@str_buffer, MAXSTR_LENGTH) -Addr : 4C40: 01 : Drop Anchor -Addr : 4C41: 8B 80 A8 : Memory Op Byte VBASE + ADDRESS Address = 00A8 -Addr : 4C44: 38 31 : Constant 1 Bytes - 31 -Addr : 4C46: 05 09 : Call Sub 9 -216 value := StrToBase(@str_buffer, 2) -Addr : 4C48: 00 : Drop Anchor Push -Addr : 4C49: 8B 80 A8 : Memory Op Byte VBASE + ADDRESS Address = 00A8 -Addr : 4C4C: 37 00 : Constant Mask Y=0 00000002 -Addr : 4C4E: 05 23 : Call Sub 35 -Addr : 4C50: 61 : Variable Operation Local Offset - 0 Write -Addr : 4C51: 32 : Return -|===========================================================================| -Spin Block Hex with 2 Parameters and 0 Extra Stack Longs. Method 14 -PUB Hex(value, digits) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - value -Local Parameter DBASE:0008 - digits -|===========================================================================| -224 value <<= (8 - digits) << 2 -Addr : 4C52: 37 02 : Constant Mask Y=2 00000008 -Addr : 4C54: 68 : Variable Operation Local Offset - 2 Read -Addr : 4C55: ED : Math Op - -Addr : 4C56: 37 00 : Constant Mask Y=0 00000002 -Addr : 4C58: E3 : Math Op << -Addr : 4C59: 66 43 : Variable Operation Local Offset - 1 Assign ByteMathop << -225 repeat digits -Addr : 4C5B: 68 : Variable Operation Local Offset - 2 Read -Addr : 4C5C: TJZ Label0004 -Addr : 4C5C: 08 1B : tjz Address = 4C79 27 -Addr : 4C5E: Label0002 -226 Char(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) -Addr : 4C5E: 01 : Drop Anchor -Addr : 4C5F: 35 : Constant 1 $00000000 -Addr : 4C60: Constant Address of Label0005 -Addr : 4C60: 39 03 39 : Constant 2 Bytes - 03 39 -Addr : 4C63: 37 01 : Constant Mask Y=1 00000004 -Addr : 4C65: 66 C1 : Variable Operation Local Offset - 1 Assign BitMathop -< Push -Addr : 4C67: 37 23 : Constant Mask Y=35 Decrement 0000000F -Addr : 4C69: E8 : Math Op & -Addr : 4C6A: 38 30 : Constant 1 Bytes - 30 -Addr : 4C6C: 38 39 : Constant 1 Bytes - 39 -Addr : 4C6E: 12 : Range LookUp -Addr : 4C6F: 38 41 : Constant 1 Bytes - 41 -Addr : 4C71: 38 46 : Constant 1 Bytes - 46 -Addr : 4C73: 12 : Range LookUp -Addr : 4C74: 0F : Lookdone -Addr : 4C75: Label0005 -Addr : 4C75: 05 04 : Call Sub 4 -Addr : 4C77: Label0003 -Addr : 4C77: DJNZ Label0002 -Addr : 4C77: 09 65 : djnz Address = 4C5E -27 -Addr : 4C79: Label0004 -Addr : 4C79: 32 : Return -|===========================================================================| -Spin Block HexIn with 0 Parameters and 0 Extra Stack Longs. Method 15 -PUB HexIn : value - -Local Parameter DBASE:0000 - Result -|===========================================================================| -232 StrInMax(@str_buffer, MAXSTR_LENGTH) -Addr : 4C7A: 01 : Drop Anchor -Addr : 4C7B: 8B 80 A8 : Memory Op Byte VBASE + ADDRESS Address = 00A8 -Addr : 4C7E: 38 31 : Constant 1 Bytes - 31 -Addr : 4C80: 05 09 : Call Sub 9 -233 value := StrToBase(@str_buffer, 16) -Addr : 4C82: 00 : Drop Anchor Push -Addr : 4C83: 8B 80 A8 : Memory Op Byte VBASE + ADDRESS Address = 00A8 -Addr : 4C86: 37 03 : Constant Mask Y=3 00000010 -Addr : 4C88: 05 23 : Call Sub 35 -Addr : 4C8A: 61 : Variable Operation Local Offset - 0 Write -Addr : 4C8B: 32 : Return -|===========================================================================| -Spin Block Clear with 0 Parameters and 0 Extra Stack Longs. Method 16 -PUB Clear - -Local Parameter DBASE:0000 - Result -|===========================================================================| -238 Char(CS) -Addr : 4C8C: 01 : Drop Anchor -Addr : 4C8D: 37 03 : Constant Mask Y=3 00000010 -Addr : 4C8F: 05 04 : Call Sub 4 -Addr : 4C91: 32 : Return -|===========================================================================| -Spin Block ClearEnd with 0 Parameters and 0 Extra Stack Longs. Method 17 -PUB ClearEnd - -Local Parameter DBASE:0000 - Result -|===========================================================================| -243 Char(CE) -Addr : 4C92: 01 : Drop Anchor -Addr : 4C93: 38 0B : Constant 1 Bytes - 0B -Addr : 4C95: 05 04 : Call Sub 4 -Addr : 4C97: 32 : Return -|===========================================================================| -Spin Block ClearBelow with 0 Parameters and 0 Extra Stack Longs. Method 18 -PUB ClearBelow - -Local Parameter DBASE:0000 - Result -|===========================================================================| -248 Char(CB) -Addr : 4C98: 01 : Drop Anchor -Addr : 4C99: 38 0C : Constant 1 Bytes - 0C -Addr : 4C9B: 05 04 : Call Sub 4 -Addr : 4C9D: 32 : Return -|===========================================================================| -Spin Block Home with 0 Parameters and 0 Extra Stack Longs. Method 19 -PUB Home - -Local Parameter DBASE:0000 - Result -|===========================================================================| -253 Char(HM) -Addr : 4C9E: 01 : Drop Anchor -Addr : 4C9F: 36 : Constant 2 $00000001 -Addr : 4CA0: 05 04 : Call Sub 4 -Addr : 4CA2: 32 : Return -|===========================================================================| -Spin Block Position with 2 Parameters and 0 Extra Stack Longs. Method 20 -PUB Position(x, y) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - x -Local Parameter DBASE:0008 - y -|===========================================================================| -258 Char(PC) -Addr : 4CA3: 01 : Drop Anchor -Addr : 4CA4: 37 00 : Constant Mask Y=0 00000002 -Addr : 4CA6: 05 04 : Call Sub 4 -259 Char(x) -Addr : 4CA8: 01 : Drop Anchor -Addr : 4CA9: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CAA: 05 04 : Call Sub 4 -260 Char(y) -Addr : 4CAC: 01 : Drop Anchor -Addr : 4CAD: 68 : Variable Operation Local Offset - 2 Read -Addr : 4CAE: 05 04 : Call Sub 4 -Addr : 4CB0: 32 : Return -|===========================================================================| -Spin Block PositionX with 1 Parameters and 0 Extra Stack Longs. Method 21 -PUB PositionX(x) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - x -|===========================================================================| -264 Char(PX) -Addr : 4CB1: 01 : Drop Anchor -Addr : 4CB2: 38 0E : Constant 1 Bytes - 0E -Addr : 4CB4: 05 04 : Call Sub 4 -265 Char(x) -Addr : 4CB6: 01 : Drop Anchor -Addr : 4CB7: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CB8: 05 04 : Call Sub 4 -Addr : 4CBA: 32 : Return -|===========================================================================| -Spin Block PositionY with 1 Parameters and 0 Extra Stack Longs. Method 22 -PUB PositionY(y) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - y -|===========================================================================| -269 Char(PY) -Addr : 4CBB: 01 : Drop Anchor -Addr : 4CBC: 37 23 : Constant Mask Y=35 Decrement 0000000F -Addr : 4CBE: 05 04 : Call Sub 4 -270 Char(y) -Addr : 4CC0: 01 : Drop Anchor -Addr : 4CC1: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CC2: 05 04 : Call Sub 4 -Addr : 4CC4: 32 : Return -|===========================================================================| -Spin Block NewLine with 0 Parameters and 0 Extra Stack Longs. Method 23 -PUB NewLine - -Local Parameter DBASE:0000 - Result -|===========================================================================| -274 Char(NL) -Addr : 4CC5: 01 : Drop Anchor -Addr : 4CC6: 38 0D : Constant 1 Bytes - 0D -Addr : 4CC8: 05 04 : Call Sub 4 -275 Char(LF) -Addr : 4CCA: 01 : Drop Anchor -Addr : 4CCB: 38 0A : Constant 1 Bytes - 0A -Addr : 4CCD: 05 04 : Call Sub 4 -Addr : 4CCF: 32 : Return -|===========================================================================| -Spin Block LineFeed with 0 Parameters and 0 Extra Stack Longs. Method 24 -PUB LineFeed - -Local Parameter DBASE:0000 - Result -|===========================================================================| -280 Char(LF) -Addr : 4CD0: 01 : Drop Anchor -Addr : 4CD1: 38 0A : Constant 1 Bytes - 0A -Addr : 4CD3: 05 04 : Call Sub 4 -Addr : 4CD5: 32 : Return -|===========================================================================| -Spin Block MoveLeft with 1 Parameters and 0 Extra Stack Longs. Method 25 -PUB MoveLeft(x) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - x -|===========================================================================| -285 repeat x -Addr : 4CD6: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CD7: TJZ Label0004 -Addr : 4CD7: 08 07 : tjz Address = 4CE0 7 -Addr : 4CD9: Label0002 -286 Char(ML) -Addr : 4CD9: 01 : Drop Anchor -Addr : 4CDA: 37 21 : Constant Mask Y=33 Decrement 00000003 -Addr : 4CDC: 05 04 : Call Sub 4 -Addr : 4CDE: Label0003 -Addr : 4CDE: DJNZ Label0002 -Addr : 4CDE: 09 79 : djnz Address = 4CD9 -7 -Addr : 4CE0: Label0004 -Addr : 4CE0: 32 : Return -|===========================================================================| -Spin Block MoveRight with 1 Parameters and 0 Extra Stack Longs. Method 26 -PUB MoveRight(x) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - x -|===========================================================================| -291 repeat x -Addr : 4CE1: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CE2: TJZ Label0004 -Addr : 4CE2: 08 07 : tjz Address = 4CEB 7 -Addr : 4CE4: Label0002 -292 Char(MR) -Addr : 4CE4: 01 : Drop Anchor -Addr : 4CE5: 37 01 : Constant Mask Y=1 00000004 -Addr : 4CE7: 05 04 : Call Sub 4 -Addr : 4CE9: Label0003 -Addr : 4CE9: DJNZ Label0002 -Addr : 4CE9: 09 79 : djnz Address = 4CE4 -7 -Addr : 4CEB: Label0004 -Addr : 4CEB: 32 : Return -|===========================================================================| -Spin Block MoveUp with 1 Parameters and 0 Extra Stack Longs. Method 27 -PUB MoveUp(y) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - y -|===========================================================================| -297 repeat y -Addr : 4CEC: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CED: TJZ Label0004 -Addr : 4CED: 08 07 : tjz Address = 4CF6 7 -Addr : 4CEF: Label0002 -298 Char(MU) -Addr : 4CEF: 01 : Drop Anchor -Addr : 4CF0: 38 05 : Constant 1 Bytes - 05 -Addr : 4CF2: 05 04 : Call Sub 4 -Addr : 4CF4: Label0003 -Addr : 4CF4: DJNZ Label0002 -Addr : 4CF4: 09 79 : djnz Address = 4CEF -7 -Addr : 4CF6: Label0004 -Addr : 4CF6: 32 : Return -|===========================================================================| -Spin Block MoveDown with 1 Parameters and 0 Extra Stack Longs. Method 28 -PUB MoveDown(y) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - y -|===========================================================================| -303 repeat y -Addr : 4CF7: 64 : Variable Operation Local Offset - 1 Read -Addr : 4CF8: TJZ Label0004 -Addr : 4CF8: 08 07 : tjz Address = 4D01 7 -Addr : 4CFA: Label0002 -304 Char(MD) -Addr : 4CFA: 01 : Drop Anchor -Addr : 4CFB: 38 06 : Constant 1 Bytes - 06 -Addr : 4CFD: 05 04 : Call Sub 4 -Addr : 4CFF: Label0003 -Addr : 4CFF: DJNZ Label0002 -Addr : 4CFF: 09 79 : djnz Address = 4CFA -7 -Addr : 4D01: Label0004 -Addr : 4D01: 32 : Return -|===========================================================================| -Spin Block Tab with 0 Parameters and 0 Extra Stack Longs. Method 29 -PUB Tab - -Local Parameter DBASE:0000 - Result -|===========================================================================| -309 Char(TB) -Addr : 4D02: 01 : Drop Anchor -Addr : 4D03: 38 09 : Constant 1 Bytes - 09 -Addr : 4D05: 05 04 : Call Sub 4 -Addr : 4D07: 32 : Return -|===========================================================================| -Spin Block Backspace with 0 Parameters and 0 Extra Stack Longs. Method 30 -PUB Backspace - -Local Parameter DBASE:0000 - Result -|===========================================================================| -314 Char(BS) -Addr : 4D08: 01 : Drop Anchor -Addr : 4D09: 37 02 : Constant Mask Y=2 00000008 -Addr : 4D0B: 05 04 : Call Sub 4 -Addr : 4D0D: 32 : Return -|===========================================================================| -Spin Block Beep with 0 Parameters and 0 Extra Stack Longs. Method 31 -PUB Beep - -Local Parameter DBASE:0000 - Result -|===========================================================================| -319 Char(BP) -Addr : 4D0E: 01 : Drop Anchor -Addr : 4D0F: 37 22 : Constant Mask Y=34 Decrement 00000007 -Addr : 4D11: 05 04 : Call Sub 4 -Addr : 4D13: 32 : Return -|===========================================================================| -Spin Block RxCount with 0 Parameters and 0 Extra Stack Longs. Method 32 -PUB RxCount : count - -Local Parameter DBASE:0000 - Result -|===========================================================================| -325 count := rx_head - rx_tail -Addr : 4D14: 44 : Variable Operation Global Offset - 1 Read -Addr : 4D15: 48 : Variable Operation Global Offset - 2 Read -Addr : 4D16: ED : Math Op - -Addr : 4D17: 61 : Variable Operation Local Offset - 0 Write -326 count -= BUFFER_LENGTH*(count < 0) -Addr : 4D18: 37 05 : Constant Mask Y=5 00000040 -Addr : 4D1A: 60 : Variable Operation Local Offset - 0 Read -Addr : 4D1B: 35 : Constant 1 $00000000 -Addr : 4D1C: F9 : Math Op < -Addr : 4D1D: F4 : Math Op * -Addr : 4D1E: 62 4D : Variable Operation Local Offset - 0 Assign WordMathop - -Addr : 4D20: 32 : Return -|===========================================================================| -Spin Block RxFlush with 0 Parameters and 0 Extra Stack Longs. Method 33 -PUB RxFlush - -Local Parameter DBASE:0000 - Result -|===========================================================================| -331 repeat while rxcheck => 0 -Addr : 4D21: Label0002 -Addr : 4D21: 00 : Drop Anchor Push -Addr : 4D22: 05 22 : Call Sub 34 -Addr : 4D24: 35 : Constant 1 $00000000 -Addr : 4D25: FE : Math Op => -Addr : 4D26: JZ Label0004 -Addr : 4D26: 0A 02 : jz Address = 4D2A 2 -Addr : 4D28: Label0003 -Addr : 4D28: JMP Label0002 -Addr : 4D28: 04 77 : Jmp 4D21 -9 -Addr : 4D2A: Label0004 -Addr : 4D2A: 32 : Return -|===========================================================================| -Spin Block RxCheck with 0 Parameters and 0 Extra Stack Longs. Method 34 -PRI RxCheck : bytechr - -Local Parameter DBASE:0000 - Result -|===========================================================================| -337 bytechr~~ -Addr : 4D2B: 62 1C : Variable Operation Local Offset - 0 Assign VAR~~ Post-set -338 if rx_tail <> rx_head -Addr : 4D2D: 48 : Variable Operation Global Offset - 2 Read -Addr : 4D2E: 44 : Variable Operation Global Offset - 1 Read -Addr : 4D2F: FB : Math Op <> -Addr : 4D30: JZ Label0002 -Addr : 4D30: 0A 0B : jz Address = 4D3D 11 -339 bytechr := rx_buffer[rx_tail] -Addr : 4D32: 48 : Variable Operation Global Offset - 2 Read -Addr : 4D33: 98 28 : Memory Op Byte VBASE + POP Index READ Address = 0028 -Addr : 4D35: 61 : Variable Operation Local Offset - 0 Write -340 rx_tail := (rx_tail + 1) & BUFFER_MASK -Addr : 4D36: 48 : Variable Operation Global Offset - 2 Read -Addr : 4D37: 36 : Constant 2 $00000001 -Addr : 4D38: EC : Math Op + -Addr : 4D39: 37 25 : Constant Mask Y=37 Decrement 0000003F -Addr : 4D3B: E8 : Math Op & -Addr : 4D3C: 49 : Variable Operation Global Offset - 2 Write -Addr : 4D3D: Label0002 -Addr : 4D3D: Label0003 -Addr : 4D3D: 32 : Return -|===========================================================================| -Spin Block StrToBase with 2 Parameters and 2 Extra Stack Longs. Method 35 -PRI StrToBase(stringptr, base) : value | chr, index - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - stringptr -Local Parameter DBASE:0008 - base -Local Variable DBASE:000C - chr -Local Variable DBASE:0010 - index -|===========================================================================| -346 value := index := 0 -Addr : 4D3E: 35 : Constant 1 $00000000 -Addr : 4D3F: 72 80 : Variable Operation Local Offset - 4 Assign Write Push -Addr : 4D41: 61 : Variable Operation Local Offset - 0 Write -Addr : 4D42: Label0002 -347 repeat until ((chr := byte[stringptr][index++]) == 0) -Addr : 4D42: 64 : Variable Operation Local Offset - 1 Read -Addr : 4D43: 72 AE : Variable Operation Local Offset - 4 Assign VAR++ post inc Long Push -Addr : 4D45: 90 : Memory Op Byte POP Address POP Index READ -Addr : 4D46: 6E 80 : Variable Operation Local Offset - 3 Assign Write Push -Addr : 4D48: 35 : Constant 1 $00000000 -Addr : 4D49: FC : Math Op == -Addr : 4D4A: JNZ Label0004 -Addr : 4D4A: 0B 23 : jnz Address = 4D6F 35 -348 chr := -15 + --chr & %11011111 + 39*(chr > 56) 'Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range -Addr : 4D4C: 38 0E : Constant 1 Bytes - 0E -Addr : 4D4E: E7 : Math Op ! -Addr : 4D4F: 6E B6 : Variable Operation Local Offset - 3 Assign --VAR pre-dec Long Push -Addr : 4D51: 38 DF : Constant 1 Bytes - DF -Addr : 4D53: E8 : Math Op & -Addr : 4D54: EC : Math Op + -Addr : 4D55: 38 27 : Constant 1 Bytes - 27 -Addr : 4D57: 6C : Variable Operation Local Offset - 3 Read -Addr : 4D58: 38 38 : Constant 1 Bytes - 38 -Addr : 4D5A: FA : Math Op > -Addr : 4D5B: F4 : Math Op * -Addr : 4D5C: EC : Math Op + -Addr : 4D5D: 6D : Variable Operation Local Offset - 3 Write -349 if (chr > -1) and (chr < base) 'Accumulate valid values into result; ignore others -Addr : 4D5E: 6C : Variable Operation Local Offset - 3 Read -Addr : 4D5F: 34 : Constant 0 $FFFFFFFF -Addr : 4D60: FA : Math Op > -Addr : 4D61: 6C : Variable Operation Local Offset - 3 Read -Addr : 4D62: 68 : Variable Operation Local Offset - 2 Read -Addr : 4D63: F9 : Math Op < -Addr : 4D64: F0 : Math Op AND -Addr : 4D65: JZ Label0005 -Addr : 4D65: 0A 06 : jz Address = 4D6D 6 -350 value := value * base + chr -Addr : 4D67: 60 : Variable Operation Local Offset - 0 Read -Addr : 4D68: 68 : Variable Operation Local Offset - 2 Read -Addr : 4D69: F4 : Math Op * -Addr : 4D6A: 6C : Variable Operation Local Offset - 3 Read -Addr : 4D6B: EC : Math Op + -Addr : 4D6C: 61 : Variable Operation Local Offset - 0 Write -Addr : 4D6D: Label0005 -Addr : 4D6D: Label0006 -Addr : 4D6D: Label0003 -Addr : 4D6D: JMP Label0002 -Addr : 4D6D: 04 53 : Jmp 4D42 -45 -Addr : 4D6F: Label0004 -351 if (base == 10) and (byte[stringptr] == "-") 'If decimal, address negative sign; ignore otherwise -Addr : 4D6F: 68 : Variable Operation Local Offset - 2 Read -Addr : 4D70: 38 0A : Constant 1 Bytes - 0A -Addr : 4D72: FC : Math Op == -Addr : 4D73: 64 : Variable Operation Local Offset - 1 Read -Addr : 4D74: 80 : Memory Op Byte POP Address READ -Addr : 4D75: 38 2D : Constant 1 Bytes - 2D -Addr : 4D77: FC : Math Op == -Addr : 4D78: F0 : Math Op AND -Addr : 4D79: JZ Label0007 -Addr : 4D79: 0A 03 : jz Address = 4D7E 3 -352 value := - value -Addr : 4D7B: 60 : Variable Operation Local Offset - 0 Read -Addr : 4D7C: E6 : Math Op - -Addr : 4D7D: 61 : Variable Operation Local Offset - 0 Write -Addr : 4D7E: Label0007 -Addr : 4D7E: Label0008 -Addr : 4D7E: 32 : Return diff --git a/Source/Hardware/Experimental/PropIO2_test/Spin/PropIO2.spin b/Source/Hardware/Experimental/PropIO2_test/Spin/PropIO2.spin deleted file mode 100644 index f3bd8e597e4b7dcbb20eacc3d902a1b8bc4c11f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34026 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 diff --git a/Source/Hardware/Experimental/PropIO2_test/Spin/safe_spi.spin b/Source/Hardware/Experimental/PropIO2_test/Spin/safe_spi.spin deleted file mode 100644 index a63cb229..00000000 --- a/Source/Hardware/Experimental/PropIO2_test/Spin/safe_spi.spin +++ /dev/null @@ -1,920 +0,0 @@ -{{ - SPI interface routines for SD & SDHC & MMC cards - - Jonathan "lonesock" Dummer - version 0.3.0 2009 July 19 - - Using multiblock SPI mode exclusively. - - This is the "SAFE" version...uses - * 1 instruction per bit writes - * 2 instructions per bit reads - - For the fsrw project: - fsrw.sf.net -}} - -CON - ' possible card types - type_MMC = 1 - type_SD = 2 - type_SDHC = 3 - - ' Error codes - ERR_CARD_NOT_RESET = -1 - ERR_3v3_NOT_SUPPORTED = -2 - ERR_OCR_FAILED = -3 - ERR_BLOCK_NOT_LONG_ALIGNED = -4 - '... - ' These errors are for the assembly engine...they are negated inside, and need to be <= 511 - ERR_ASM_NO_READ_TOKEN = 100 - ERR_ASM_BLOCK_NOT_WRITTEN = 101 - ' NOTE: errors -128 to -255 are reserved for reporting R1 response errors - '... - ERR_SPI_ENGINE_NOT_RUNNING = -999 - ERR_CARD_BUSY_TIMEOUT = -1000 - - ' SDHC/SD/MMC command set for SPI - CMD0 = $40+0 ' GO_IDLE_STATE - CMD1 = $40+1 ' SEND_OP_COND (MMC) - ACMD41 = $C0+41 ' SEND_OP_COND (SDC) - CMD8 = $40+8 ' SEND_IF_COND - CMD9 = $40+9 ' SEND_CSD - CMD10 = $40+10 ' SEND_CID - CMD12 = $40+12 ' STOP_TRANSMISSION - CMD13 = $40+13 ' SEND_STATUS - ACMD13 = $C0+13 ' SD_STATUS (SDC) - CMD16 = $40+16 ' SET_BLOCKLEN - CMD17 = $40+17 ' READ_SINGLE_BLOCK - CMD18 = $40+18 ' READ_MULTIPLE_BLOCK - CMD23 = $40+23 ' SET_BLOCK_COUNT (MMC) - ACMD23 = $C0+23 ' SET_WR_BLK_ERASE_COUNT (SDC) - CMD24 = $40+24 ' WRITE_BLOCK - CMD25 = $40+25 ' WRITE_MULTIPLE_BLOCK - CMD55 = $40+55 ' APP_CMD - CMD58 = $40+58 ' READ_OCR - CMD59 = $40+59 ' CRC_ON_OFF - - ' buffer size for my debug cmd log - 'LOG_SIZE = 256<<1 - -{ -VAR - long SPI_engine_cog - ' these are used for interfacing with the assembly engine | temporary initialization usage - long SPI_command ' "t", "r", "w", 0 =>done, <0 => error | pin mask - long SPI_block_index ' which 512-byte block to read/write | cnt at init - long SPI_buffer_address ' where to get/put the data in Hub RAM | unused -'} -DAT -'' I'm placing these variables in a DAT section to make this driver a singleton. -'' If for some reason you really need more than one driver (e.g. if you have more -'' than a single SD socket), move these back into VAR. -SPI_engine_cog long 0 -' these are used for interfacing with the assembly engine | temporary initialization usage -SPI_command long 0 ' "t", "r", "w", 0 =>done, <0 => error | unused -SPI_block_index long 0 ' which 512-byte block to read/write | cnt at init -SPI_buffer_address long 0 ' where to get/put the data in Hub RAM | unused - -{ -VAR - ' for debug ONLY - byte log_cmd_resp[LOG_SIZE+1] -PUB get_log_pointer - return @log_cmd_resp -'} - -PUB start( basepin ) -{{ - This is a compatibility wrapper, and requires that the pins be - both consecutive, and in the order DO CLK DI CS. -}} - return start_explicit( basepin, basepin+1, basepin+2, basepin+3 ) - -PUB readblock( block_index, buffer_address ) - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - if (buffer_address & 3) - abort ERR_BLOCK_NOT_LONG_ALIGNED - SPI_block_index := block_index - SPI_buffer_address := buffer_address - SPI_command := "r" - repeat while SPI_command == "r" - if SPI_command < 0 - abort SPI_command - -PUB writeblock( block_index, buffer_address ) - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - if (buffer_address & 3) - abort ERR_BLOCK_NOT_LONG_ALIGNED - SPI_block_index := block_index - SPI_buffer_address := buffer_address - SPI_command := "w" - repeat while SPI_command == "w" - if SPI_command < 0 - abort SPI_command - -PUB get_seconds - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - SPI_command := "t" - repeat while SPI_command == "t" - ' secods are in SPI_block_index, remainder is in SPI_buffer_address - return SPI_block_index - -PUB get_milliseconds : ms - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - SPI_command := "t" - repeat while SPI_command == "t" - ' secods are in SPI_block_index, remainder is in SPI_buffer_address - ms := SPI_block_index * 1000 - ms += SPI_buffer_address * 1000 / clkfreq - -PUB start_explicit( DO, CLK, DI, CS ) : card_type | tmp, i -{{ - Do all of the card initialization in SPIN, then hand off the pin - information to the assembly cog for hot SPI block R/W action! -}} - ' Start from scratch - stop - ' clear my log buffer - { - bytefill( @log_cmd_resp, 0, LOG_SIZE+1 ) - dbg_ptr := @log_cmd_resp - dbg_end := dbg_ptr + LOG_SIZE - '} - ' wait ~4 milliseconds - waitcnt( 500 + (clkfreq>>8) + cnt ) - ' (start with cog variables, _BEFORE_ loading the cog) - pinDO := DO - maskDO := |< DO - pinCLK := CLK - pinDI := DI - maskDI := |< DI - maskCS := |< CS - adrShift := 9 ' block = 512 * index, and 512 = 1<<9 - ' pass the output pin mask via the command register - maskAll := maskCS | (| 74 clocks - outa |= maskAll - repeat 4096 - outa[CLK]~~ - outa[CLK]~ - ' time-hack - SPI_block_index := cnt - ' reset the card - tmp~ - repeat i from 0 to 9 - if tmp <> 1 - tmp := send_cmd_slow( CMD0, 0, $95 ) - if (tmp & 4) - ' the card said CMD0 ("go idle") was invalid, so we're possibly stuck in read or write mode - if i & 1 - ' exit multiblock read mode - repeat 4 - read_32_slow ' these extra clocks are required for some MMC cards - send_slow( $FD, 8 ) ' stop token - read_32_slow - repeat while read_slow <> $FF - else - ' exit multiblock read mode - send_cmd_slow( CMD12, 0, $61 ) - if tmp <> 1 - ' the reset command failed! - crash( ERR_CARD_NOT_RESET ) - ' Is this a SD type 2 card? - if send_cmd_slow( CMD8, $1AA, $87 ) == 1 - ' Type2 SD, check to see if it's a SDHC card - tmp := read_32_slow - ' check the supported voltage - if (tmp & $1FF) <> $1AA - crash( ERR_3v3_NOT_SUPPORTED ) - ' try to initialize the type 2 card with the High Capacity bit - repeat while send_cmd_slow( ACMD41, |<30, $77 ) - ' the card is initialized, let's read back the High Capacity bit - if send_cmd_slow( CMD58, 0, $FD ) <> 0 - crash( ERR_OCR_FAILED ) - ' get back the data - tmp := read_32_slow - ' check the bit - if tmp & |<30 - card_type := type_SDHC - adrShift := 0 - else - card_type := type_SD - else - ' Either a type 1 SD card, or it's MMC, try SD 1st - if send_cmd_slow( ACMD41, 0, $E5 ) < 2 - ' this is a type 1 SD card (1 means busy, 0 means done initializing) - card_type := type_SD - repeat while send_cmd_slow( ACMD41, 0, $E5 ) - else - ' mark that it's MMC, and try to initialize - card_type := type_MMC - repeat while send_cmd_slow( CMD1, 0, $F9 ) - ' some SD or MMC cards may have the wrong block size, set it here - send_cmd_slow( CMD16, 512, $15 ) - ' card is mounted, make sure the CRC is turned off - send_cmd_slow( CMD59, 0, $91 ) - ' check the status - 'send_cmd_slow( CMD13, 0, $0D ) - ' done with the SPI bus for now - outa |= maskCS - ' set my counter modes for super fast SPI operation - ' writing: NCO single-ended mode, output on DI - writeMode := (%00100 << 26) | (DI << 0) - ' reading - 'readMode := (%11000 << 26) | (DO << 0) | (CLK << 9) - ' clock - 'clockLineMode := (%00110 << 26) | (CLK << 0) ' DUTY, 25% duty cycle - ' clock - clockLineMode := (%00100 << 26) | (CLK << 0) ' NCO, 50% duty cycle - ' how many bytes (8 clocks, >>3) fit into 1/2 of a second (>>1), 4 clocks per instruction (>>2)? - N_in8_500ms := clkfreq >> constant(1+2+3) - ' how long should we wait before auto-exiting any multiblock mode? - idle_limit := 125 ' ms, NEVER make this > 1000 - idle_limit := clkfreq / (1000 / idle_limit) ' convert to counts - ' Hand off control to the assembly engine's cog - bufAdr := @SPI_buffer_address - sdAdr := @SPI_block_index - SPI_command := 0 ' just make sure it's not 1 - ' start my driver cog and wait till I hear back that it's done - SPI_engine_cog := cognew( @SPI_engine_entry, @SPI_command ) + 1 - if( SPI_engine_cog == 0 ) - crash( ERR_SPI_ENGINE_NOT_RUNNING ) - repeat while SPI_command <> -1 - ' and we no longer need to control any pins from here - dira &= !maskAll - ' the return variable is card_type - -PUB release -{{ - I do not want to abort if the cog is not - running, as this is called from stop, which - is called from start/ [8^) -}} - if SPI_engine_cog - SPI_command := "z" - repeat while SPI_command == "z" - -PUB stop -{{ - kill the assembly driver cog. -}} - release - if SPI_engine_cog - cogstop( SPI_engine_cog~ - 1 ) - -PRI crash( abort_code ) -{{ - In case of Bad Things(TM) happening, - exit as gracefully as possible. -}} - ' and we no longer need to control any pins from here - dira &= !maskAll - ' and report our error - abort abort_code - -PRI send_cmd_slow( cmd, val, crc ) : reply | time_stamp -{{ - Send down a command and return the reply. - Note: slow is an understatement! - Note: this uses the assembly DAT variables for pin IDs, - which means that if you run this multiple times (say for - multiple SD cards), these values will change for each one. - But this is OK as all of these functions will be called - during the initialization only, before the PASM engine is - running. -}} - ' if this is an application specific command, handle it - if (cmd & $80) - ' ACMD is the command sequense of CMD55-CMD - cmd &= $7F - reply := send_cmd_slow( CMD55, 0, $65 ) - if (reply > 1) - return reply - ' the CS line needs to go low during this operation - outa |= maskCS - outa &= !maskCS - ' give the card a few cocks to finish whatever it was doing - read_32_slow - ' send the command byte - send_slow( cmd, 8 ) - ' send the value long - send_slow( val, 32 ) - ' send the CRC byte - send_slow( crc, 8 ) - ' is this a CMD12?, if so, stuff byte - if cmd == CMD12 - read_slow - ' read back the response (spec declares 1-8 reads max for SD, MMC is 0-8) - time_stamp := 9 - repeat - reply := read_slow - while( reply & $80 ) and ( time_stamp-- ) - ' done, and 'reply' is already pre-loaded - { - if dbg_ptr < (dbg_end-1) - byte[dbg_ptr++] := cmd - byte[dbg_ptr++] := reply - if (cmd&63) == 13 - ' get the second byte - byte[dbg_ptr++] := cmd - byte[dbg_ptr++] := read_slow - '} - -PRI send_slow( value, bits_to_send ) - value ><= bits_to_send - repeat bits_to_send - outa[pinCLK]~ - outa[pinDI] := value - value >>= 1 - outa[pinCLK]~~ - -PRI read_32_slow : r - repeat 4 - r <<= 8 - r |= read_slow - -PRI read_slow : r -{{ - Read back 8 bits from the card -}} - ' we need the DI line high so a read can occur - outa[pinDI]~~ - ' get 8 bits (remember, r is initialized to 0 by SPIN) - repeat 8 - outa[pinCLK]~ - outa[pinCLK]~~ - r += r + ina[pinDO] - ' error check - if( (cnt - SPI_block_index) > (clkfreq << 2) ) - crash( ERR_CARD_BUSY_TIMEOUT ) - -DAT -{{ - This is the assembly engine for doing fast block - reads and writes. This is *ALL* it does! -}} -ORG 0 -SPI_engine_entry - ' Counter A drives data out - mov ctra,writeMode - ' Counter B will always drive my clock line - mov ctrb,clockLineMode - ' set our output pins to match the pin mask - mov dira,maskAll - ' handshake that we now control the pins - neg user_request,#1 - wrlong user_request,par - ' start my seconds' counter here - mov last_time,cnt - -waiting_for_command - ' update my seconds counter, but also track the idle - ' time so we can to release the card after timeout. - call #handle_time - ' read the command, and make sure it's from the user (> 0) - rdlong user_request,par - cmps user_request,#0 wz,wc -if_be jmp #waiting_for_command - ' handle our card based commands - cmp user_request,#"r" wz -if_z jmp #read_ahead - cmp user_request,#"w" wz -if_z jmp #write_behind - cmp user_request,#"z" wz -if_z jmp #release_card - ' time requests are handled differently - cmp user_request,#"t" wz ' time -if_z wrlong seconds,sdAdr ' seconds goes into the SD index register -if_z wrlong dtime,bufAdr ' the remainder goes into the buffer address register - ' in all other cases, clear the user's request - mov user_request,#0 - wrlong user_request,par - jmp #waiting_for_command - - -release_card - mov user_cmd,#"z" ' request a release - neg lastIndexPlus,#1 ' reset the last block index - neg user_idx,#1 ' and make this match it - call #handle_command - mov user_request,user_cmd - wrlong user_request,par - jmp #waiting_for_command - -read_ahead - rdlong user_idx,sdAdr - ' if the correct block is not already loaded, load it - mov tmp1,user_idx - add tmp1,#1 - cmp tmp1,lastIndexPlus wz -if_z cmp lastCommand,#"r" wz -if_z jmp #:get_on_with_it - mov user_cmd,#"r" - call #handle_command -:get_on_with_it - ' copy the data up into Hub RAM - movi transfer_long,#%000010_000 'set to wrlong - call #hub_cog_transfer - ' signify that the data is ready, Spin can continue - mov user_request,user_cmd - wrlong user_request,par - ' request the next block - mov user_cmd,#"r" - add user_idx,#1 - call #handle_command - ' done - jmp #waiting_for_command - -write_behind - rdlong user_idx,sdAdr - ' copy data in from Hub RAM - movi transfer_long,#%000010_001 'set to rdlong - call #hub_cog_transfer - ' signify that we have the data, Spin can continue - mov user_request,user_cmd - wrlong user_request,par - ' write out the block - mov user_cmd,#"w" - call #handle_command - ' done - jmp #waiting_for_command - -{{ - Set user_cmd and user_idx before calling this -}} -handle_command - ' Can we stay in the old mode? (address = old_address+1) && (old mode == new_mode) - cmp lastIndexPlus,user_idx wz -if_z cmp user_cmd,lastCommand wz -if_z jmp #:execute_block_command - ' we fell through, must exit the old mode! (except if the old mode was "release") - cmp lastCommand,#"w" wz -if_z call #stop_mb_write - cmp lastCommand,#"r" wz -if_z call #stop_mb_read - ' and start up the new mode! - cmp user_cmd,#"w" wz -if_z call #start_mb_write - cmp user_cmd,#"r" wz -if_z call #start_mb_read - cmp user_cmd,#"z" wz -if_z call #release_DO -:execute_block_command - ' track the (new) last index and command - mov lastIndexPlus,user_idx - add lastIndexPlus,#1 - mov lastCommand,user_cmd - ' do the block read or write or terminate! - cmp user_cmd,#"w" wz -if_z call #write_single_block - cmp user_cmd,#"r" wz -if_z call #read_single_block - cmp user_cmd,#"z" wz -if_z mov user_cmd,#0 - ' done -handle_command_ret - ret - -{=== these PASM functions get me in and out of multiblock mode ===} -release_DO - ' we're already out of multiblock mode, so - ' deselect the card and send out some clocks - or outa,maskCS - call #in8 - call #in8 - ' if you are using pull-up resistors, and need all - ' lines tristated, then uncomment the following line. - ' for Cluso99 - 'mov dira,#0 -release_DO_ret - ret - -start_mb_read - movi block_cmd,#CMD18<<1 - call #send_SPI_command_fast -start_mb_read_ret - ret - -stop_mb_read - movi block_cmd,#CMD12<<1 - call #send_SPI_command_fast - call #busy_fast -stop_mb_read_ret - ret - -start_mb_write - movi block_cmd,#CMD25<<1 - call #send_SPI_command_fast -start_mb_write_ret - ret - -stop_mb_write - call #busy_fast - ' only some cards need these extra clocks - mov tmp1,#16 -:loopity - call #in8 - djnz tmp1,#:loopity - ' done with hack - movi phsa,#$FD<<1 - call #out8 - call #in8 ' stuff byte - call #busy_fast -stop_mb_write_ret - ret - -send_SPI_command_fast - ' make sure we have control of the output lines - mov dira,maskAll - ' make sure the CS line transitions low - or outa,maskCS - andn outa,maskCS - ' 8 clocks - call #in8 - ' send the data - mov phsa,block_cmd ' do which ever block command this is (already in the top 8 bits) - call #out8 ' write the byte - mov phsa,user_idx ' read in the desired block index - shl phsa,adrShift ' this will multiply by 512 (bytes/sector) for MMC and SD - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - ' bogus CRC value - call #in8 ' in8 looks like out8 with $FF - ' CMD12 requires a stuff byte - shr block_cmd,#24 - cmp block_cmd,#CMD12 wz -if_z call #in8 ' 8 clocks - ' get the response - mov tmp1,#9 -:cmd_response - call #in8 - test readback,#$80 wc,wz -if_c djnz tmp1,#:cmd_response -if_nz neg user_cmd,readback - ' done -send_SPI_command_fast_ret - ret - - -busy_fast - mov tmp1,N_in8_500ms -:still_busy - call #in8 - cmp readback,#$FF wz -if_nz djnz tmp1,#:still_busy -busy_fast_ret - ret - - -out8 - andn outa,maskDI - 'movi phsb,#%11_0000000 - mov phsb,#0 - movi frqb,#%01_0000000 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - mov frqb,#0 - ' don't shift out the final bit...already sent, but be aware - ' of this when sending consecutive bytes (send_cmd, for e.g.) -out8_ret - ret - -{ -in8 - or outa,maskDI - mov ctra,readMode - ' Start my clock - mov frqa,#1<<7 - mov phsa,#0 - movi phsb,#%11_0000000 - movi frqb,#%01_0000000 - ' keep reading in my value, one bit at a time! (Kuneko - "Wh) - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - mov frqb,#0 ' stop the clock - mov readback,phsa - mov frqa,#0 - mov ctra,writeMode -in8_ret - ret -} -in8 - neg phsa,#1' DI high - mov readback,#0 - ' set up my clock, and start it - movi phsb,#%011_000000 - movi frqb,#%001_000000 - ' keep reading in my value - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - mov frqb,#0 ' stop the clock - rcl readback,#1 - mov phsa,#0 'DI low -in8_ret - ret - - -' this is called more frequently than 1 Hz, and -' is only called when the user command is 0. -handle_time - mov tmp1,cnt ' get the current timestamp - add idle_time,tmp1 ' add the current time to my idle time counter - sub idle_time,last_time ' subtract the last time from my idle counter (hence delta) - add dtime,tmp1 ' add to my accumulator, - sub dtime,last_time ' and subtract the old (adding delta) - mov last_time,tmp1 ' update my "last timestamp" - rdlong tmp1,#0 ' what is the clock frequency? - cmpsub dtime,tmp1 wc ' if I have more than a second in my accumulator - addx seconds,#0 ' then add it to "seconds" - ' this part is to auto-release the card after a timeout - cmp idle_time,idle_limit wz,wc -if_b jmp #handle_time_ret ' don't clear if we haven't hit the limit - mov user_cmd,#"z" ' we can't overdo it, the command handler makes sure - neg lastIndexPlus,#1 ' reset the last block index - neg user_idx,#1 ' and make this match it - call #handle_command ' release the card, but don't mess with the user's request register -handle_time_ret - ret - -hub_cog_transfer -' setup for all 4 passes - mov ctrb,clockXferMode - mov frqb,#1 - rdlong buf_ptr,bufAdr - mov ops_left,#4 - movd transfer_long,#speed_buf -four_transfer_passes - ' sync to the Hub RAM access - rdlong tmp1,tmp1 - ' how many long to move on this pass? (512 bytes / 4)longs / 4 passes - mov tmp1,#(512 / 4 / 4) - ' get my starting address right (phsb is incremented 1 per clock, so 16 each Hub access) - mov phsb,buf_ptr - ' write the longs, stride 4...low 2 bits of phsb are ignored -transfer_long - rdlong 0-0,phsb - add transfer_long,incDest4 - djnz tmp1,#transfer_long - ' go back to where I started, but advanced 1 long - sub transfer_long,decDestNminus1 - ' offset my Hub pointer by one long per pass - add buf_ptr,#4 - ' do all 4 passes - djnz ops_left,#four_transfer_passes - ' restore the counter mode - mov frqb,#0 - mov phsb,#0 - mov ctrb,clockLineMode -hub_cog_transfer_ret - ret - - -read_single_block - ' where am I sending the data? - movd :store_read_long,#speed_buf - mov ops_left,#128 - ' wait until the card is ready - mov tmp1,N_in8_500ms -:get_resp - call #in8 - cmp readback,#$FE wz -if_nz djnz tmp1,#:get_resp -if_nz neg user_cmd,#ERR_ASM_NO_READ_TOKEN -if_nz jmp #read_single_block_ret - ' set DI high - neg phsa,#1 - ' read the data - mov ops_left,#128 -:read_loop - mov tmp1,#4 - movi phsb,#%011_000000 -:in_byte - ' Start my clock - movi frqb,#%001_000000 - ' keep reading in my value, BACKWARDS! (Brilliant idea by Tom Rokicki!) - test maskDO,ina wc - rcl readback,#8 - test maskDO,ina wc - muxc readback,#2 - test maskDO,ina wc - muxc readback,#4 - test maskDO,ina wc - muxc readback,#8 - test maskDO,ina wc - muxc readback,#16 - test maskDO,ina wc - muxc readback,#32 - test maskDO,ina wc - muxc readback,#64 - test maskDO,ina wc - mov frqb,#0 ' stop the clock - muxc readback,#128 - ' go back for more - djnz tmp1,#:in_byte - ' make it...NOT backwards [8^) - rev readback,#0 -:store_read_long - mov 0-0,readback ' due to some counter weirdness, we need this mov - add :store_read_long,const512 - djnz ops_left,#:read_loop - - ' set DI low - mov phsa,#0 - - ' now read 2 trailing bytes (CRC) - call #in8 ' out8 is 2x faster than in8 - call #in8 ' and I'm not using the CRC anyway - ' give an extra 8 clocks in case we pause for a long time - call #in8 ' in8 looks like out8($FF) - - ' all done successfully - mov idle_time,#0 - mov user_cmd,#0 -read_single_block_ret - ret - -write_single_block - ' where am I getting the data? (all 512 bytes / 128 longs of it?) - movs :write_loop,#speed_buf - ' read in 512 bytes (128 longs) from Hub RAM and write it to the card - mov ops_left,#128 - ' just hold your horses - call #busy_fast - ' $FC for multiblock, $FE for single block - movi phsa,#$FC<<1 - call #out8 - mov phsb,#0 ' make sure my clock accumulator is right - 'movi phsb,#%11_0000000 -:write_loop - ' read 4 bytes - mov phsa,speed_buf - add :write_loop,#1 - ' a long in LE order is DCBA - rol phsa,#24 ' move A7 into position, so I can do the swizzled version - movi frqb,#%010000000 ' start the clock (remember A7 is already in place) - rol phsa,#1 ' A7 is going out, at the end of this instr, A6 is in place - rol phsa,#1 ' A5 - rol phsa,#1 ' A4 - rol phsa,#1 ' A3 - rol phsa,#1 ' A2 - rol phsa,#1 ' A1 - rol phsa,#1 ' A0 - rol phsa,#17 ' B7 - rol phsa,#1 ' B6 - rol phsa,#1 ' B5 - rol phsa,#1 ' B4 - rol phsa,#1 ' B3 - rol phsa,#1 ' B2 - rol phsa,#1 ' B1 - rol phsa,#1 ' B0 - rol phsa,#17 ' C7 - rol phsa,#1 ' C6 - rol phsa,#1 ' C5 - rol phsa,#1 ' C4 - rol phsa,#1 ' C3 - rol phsa,#1 ' C2 - rol phsa,#1 ' C1 - rol phsa,#1 ' C0 - rol phsa,#17 ' D7 - rol phsa,#1 ' D6 - rol phsa,#1 ' D5 - rol phsa,#1 ' D4 - rol phsa,#1 ' D3 - rol phsa,#1 ' D2 - rol phsa,#1 ' D1 - rol phsa,#1 ' D0 will be in place _after_ this instruction - mov frqb,#0 ' shuts the clock off, _after_ this instruction - djnz ops_left,#:write_loop - ' write out my two (bogus, using $FF) CRC bytes - call #in8 - call #in8 - ' now read response (I need this response, so can't spoof using out8) - call #in8 - and readback,#$1F - cmp readback,#5 wz -if_z mov user_cmd,#0 ' great -if_nz neg user_cmd,#ERR_ASM_BLOCK_NOT_WRITTEN ' oops - ' send out another 8 clocks - call #in8 - ' all done - mov idle_time,#0 -write_single_block_ret - ret - - -{=== Assembly Interface Variables ===} -pinDO long 0 ' pin is controlled by a counter -pinCLK long 0 ' pin is controlled by a counter -pinDI long 0 ' pin is controlled by a counter -maskDO long 0 ' mask for reading the DO line from the card -maskDI long 0 ' mask for setting the pin high while reading -maskCS long 0 ' mask = (1< -'* -'* $Id: vt100.spin,v 1.6 2010-04-17 13:48:13 pm Exp $ -'****************************************************************************** -CON - attr_highlite = %00000001 - attr_underline = %00000010 - attr_inverse = %00000100 - attr_blinking = %00001000 - - flag_deccm = %0_00000001 ' DEC cursor mode (0: off, 1: on) - flag_decim = %0_00000010 ' DEC insert mode - flag_decom = %0_00000100 ' DEC origin mode - flag_deccr = %0_00001000 ' DEC send CRLF or LF (0: LF, 1: CRLF) - flag_decck = %0_00010000 ' DEC send cursor keys - flag_decawm = %0_00100000 ' DEC auto wrap mode - flag_decarm = %0_01000000 ' DEC auto repeat mode - flag_meta = %0_10000000 ' meta character toggle - flag_ctrl = %1_00000000 ' display control characters - flag_decrm = 1<<10 ' DEC report mouse - -VAR - long cog - -PUB start(params) : okay - stop - okay := cog := COGNEW(@entry, params) + 1 - -PUB stop : okay - if cog - COGSTOP(cog~~ - 1) - -DAT - org 0 -entry -command_ptr mov t1, PAR -cmd rdlong command_ptr, t1 ' parameter 0 -screen_ptr add t1, #4 -screen_end rdlong screen_ptr, t1 ' parameter 1 -cursor_ptr add t1, #4 -vsync_ptr rdlong cursor_ptr, t1 ' parameter 2 -screen_w add t1, #4 -screen_w2 rdlong vsync_ptr, t1 ' parameter 3 -screen_h add t1, #4 -cur_ptr rdlong screen_w, t1 ' parameter 4 -scroll_top add t1, #4 -scroll_bot rdlong screen_h, t1 ' parameter 5 -dst mov screen_w2, screen_w -src shr screen_w2, #1 ' screen width / 2 -end mov t1, screen_w -data mov t2, screen_h -cols call #mul16x16 -rows mov screen_end, t2 ' result in t2 -lmm_pc add screen_end, t2 ' * 2 -cur_x_save add screen_end, screen_ptr -cur_y_save mov scroll_top, #0 -new_x_save mov scroll_bot, screen_h -attr_save mov cur_delay, CNT - jmp #startup -control_ptr long @@@control_table -csi_cmds_ptr long @@@csi_cmds -x00200020 long $00200020 -cur_block long $5f - -inverse long 0 -cur_x long 0 -new_x long 0 -cur_y long 0 -attr long 0 ' attribute mode -flags long flag_decom | flag_decawm -cur_char long 0 -cur_delay long 0 -fgcol long %0111 ' foreground color -bgcol long %0000 ' background color -color long %00000111_00000000 ' composed fore- and background -esc_mode long 0 -csi_mode long 0 -csi_argc long 0 -csi_argf long 0 -csi_args long 0,0,0,0,0,0,0,0 -question_mark long 0 - -t1 long 0 -t2 long 0 -t3 long 0 - -goto_xay - ' TODO: check origin mode flag - add cur_y, scroll_top -validate_cursor - mov cur_x, cur_x WC ' negative x? - if_c mov cur_x, #0 ' yes, clip to 0 - cmp cur_x, screen_w WZ, WC - if_ae mov cur_x, screen_w ' stay inside the boundaries - if_ae sub cur_x, #1 - mov new_x, cur_x - mov cur_y, cur_y WC ' negative y? - if_c mov cur_y, #0 ' yes, clip to 0 - cmp cur_y, screen_h WZ, WC - if_ae mov cur_y, screen_h ' stay inside the boundaries - if_ae sub cur_y, #1 -cmdloop - mov cmd, #0 - wrlong cmd, command_ptr -startup -:loop tjz cursor_ptr, #:cursor ' skip if cursor_ptr is null - wrbyte new_x, cursor_ptr ' write the (new) cursor position - add cursor_ptr, #1 - wrbyte cur_y, cursor_ptr ' and the cursor row, too - sub cursor_ptr, #1 - call #calc_cursor - jmp #:check_cmd -:cursor mov t1, cur_delay ' software cursor - sub t1, CNT - cmps t1, #0 WZ, WC - if_ae jmp #:check_cmd - rdlong t1, #0 ' get clkfreq - shr t1, #2 ' / 4 - add cur_delay, t1 ' next cursor flash event - call #calc_cursor - cmp new_x, screen_w WZ, WC ' new_x beyond last column? - if_ae jmp #:check_cmd - mov t1, cur_char WZ ' get saved character - if_z rdbyte cur_char, cur_ptr ' none: save character under cursor - if_z wrbyte cur_block, cur_ptr ' display a cursor block - if_nz mov cur_char, #0 ' reset saved character - if_nz wrbyte t1, cur_ptr ' restore saved character in screen buffer -:check_cmd rdlong cmd, command_ptr WZ - if_z jmp #:loop - - mov t1, cur_char WZ ' get saved character - if_nz cmp cur_ptr, screen_end WC - if_nz_and_c mov cur_char, #0 ' reset saved character - if_nz_and_c wrbyte t1, cur_ptr ' restore saved character in screen buffer - - and cmd, #$ff - tjnz csi_mode, #csi ' go to CSI decoding if enabled - tjnz esc_mode, #esc ' go to ESC decoding if enabled - cmp cmd, #$20 WZ, WC ' other control characters? - if_ae jmp #do_emit ' no, just emit to the screen buffer - shl cmd, #1 - add cmd, control_ptr - rdword cmd, cmd - jmp cmd ' dispatch on control_table - -do_emit call #emit - jmp #cmdloop - -do_nul ' NUL - null character -do_soh ' SOH - start of header -do_stx ' STX - start of text -do_etx ' ETX - end of text -do_eot ' EOT - end of transmission -do_enq ' ENQ - enquiry -do_ack ' ACK - acknowledgement -do_bel ' BEL - bell -do_dle ' DLE - data link escape -do_dc1 ' DC1 - device control 1 (XON) -do_dc2 ' DC2 - device control 2 -do_dc3 ' DC3 - device control 3 (XOFF) -do_dc4 ' DC4 - device control 4 -do_nak ' NAK - negative acknowledgement -do_syn ' SYN - synchronous idle -do_etb ' ETB - end of transmission block -do_em ' EM - end of medium -do_sub ' SUB - substitute -do_fs ' FS - file separator -do_gs ' GS - group separator -do_rs ' RS - request to send -do_us ' US - unit separator - jmp #cmdloop - -do_cr call #cr - jmp #cmdloop - -do_bs call #bs - jmp #cmdloop - -do_ht call #ht - jmp #cmdloop - -do_lf call #lf - jmp #cmdloop - -do_vt call #vt - jmp #cmdloop - -do_ff call #ff - jmp #cmdloop - -do_so ' ??? - jmp #cmdloop - -do_si ' ??? - jmp #cmdloop - -do_can ' CAN - cancel - call #can - jmp #cmdloop -do_esc - mov esc_mode, #1 - jmp #cmdloop -esc - mov esc_mode, #0 - cmp cmd, #"[" WZ - if_z jmp #:csi - ' TODO: non-CSI escape sequences - jmp #cmdloop -:csi - mov csi_mode, #1 ' start CSI mode - mov csi_argc, #0 ' argument count = 0 - mov csi_argf, #0 ' argument flag = 0 - mov csi_args, #0 ' first argument = 0 - jmp #cmdloop - -csi - cmp csi_mode, #1 WZ ' first character after "["? - if_nz jmp #:not_question ' no, check arguments - mov csi_mode, #2 ' skip this test in the future - cmp cmd, #"?" WZ ' "[?" mode? - muxz question_mark, #1 - if_z jmp #cmdloop - -:not_question - cmp cmd, #"0" WZ, WC - if_b jmp #:not_numeric - cmp cmd, #"9" WZ, WC - if_a jmp #:not_numeric - mov t1, csi_argc - add t1, #csi_args - movs :get_arg, t1 - movd :put_arg, t1 - mov csi_argf, #1 ' set the "seen arguments" flag -:get_arg mov t1, 0-0 ' get csi_args[csi_argc] - mov t2, t1 ' to t2 also - shl t1, #2 ' * 4 - add t1, t2 ' * 5 - shl t1, #1 ' * 10 - add t1, cmd ' + digit - sub t1, #"0" ' - ASCII for "0" -:put_arg mov 0-0, t1 ' put csi_args[csi_argc] - jmp #cmdloop - -:not_numeric - cmp cmd, #";" WZ ' next argument delimiter? - if_nz jmp #:not_delimiter - cmp csi_argc, #7 WZ ' reached maximum number of arguments? - if_nz add csi_argc, #1 ' no, use next slot - mov t1, csi_argc - add t1, #csi_args - movd :clr_arg, t1 - nop -:clr_arg mov 0-0, #0 ' preset csi_args[csi_argc] to 0 - jmp #cmdloop - -:not_delimiter - mov csi_mode, #0 ' end CSI mode - add csi_argc, csi_argf ' incr. argument count, if any arguments were specified - - cmp cmd, #"@" WZ, WC ' below @? - if_b jmp #cmdloop - cmp cmd, #"z" WZ, WC ' above z? - if_ae jmp #cmdloop - sub cmd, #"@" - shl cmd, #1 ' function word index - add cmd, csi_cmds_ptr - rdword cmd, cmd ' get function pointer - testn cmd, #$1ff WZ ' any bits outside the cog? - if_z jmp cmd ' cog function - mov lmm_pc, cmd ' otherwise it's an LMM address - jmp #lmm_loop ' execute LMM code - -'******************************************************************************************** -' non_zero_args - make sure the first argument is at least 1 -' -non_zero_args - tjnz csi_args, #non_zero_args_ret - add csi_args, #1 -non_zero_args_ret - ret - -'******************************************************************************************** -' shift_csi_args - remove the first value from the list of arguments, pad with 0 -' -shift_csi_args - mov csi_args, csi_args + 1 - mov csi_args + 1, csi_args + 2 - mov csi_args + 2, csi_args + 3 - mov csi_args + 3, csi_args + 4 - mov csi_args + 4, csi_args + 5 - mov csi_args + 5, csi_args + 6 - mov csi_args + 6, csi_args + 7 - mov csi_args + 7, #0 -shift_csi_args_ret - ret - -'******************************************************************************************** -' cr - carriage return -' -cr - mov cur_x, #0 - mov new_x, #0 -cr_ret - ret - -'******************************************************************************************** -' bs - back space -' -bs - cmp new_x, #0 WZ - if_nz sub new_x, #1 - if_nz jmp #bs_ret - mov new_x, screen_w - sub new_x, #1 - call #vt -bs_ret - ret - -'******************************************************************************************** -' fs - forward space -' -fs - add cur_x, #1 - cmp cur_x, screen_w WZ - if_z sub cur_x, #1 ' stay in last column -fs_ret - ret - -'******************************************************************************************** -' ht - horizontal tabulator -' -ht - mov cmd, #$20 - call #emit - test new_x, #7 WZ - if_nz jmp #ht -ht_ret - ret -'******************************************************************************************** -' lf - line feed -' -lf - add cur_y, #1 - test flags, #flag_decom WZ ' origin mode enabled? - if_nz jmp #:origin ' yes, check cursor in scroll range - -:screen cmp cur_y, screen_h WZ, WC ' no, check cursor in screen range - if_b jmp #lf_ret - mov cur_y, screen_h - sub cur_y, #1 - mov dst, screen_ptr ' destination = screen buffer - mov src, screen_ptr ' source = dito - mov rows, screen_h ' screen height - jmp #scroll_up_1 ' scroll the entire screen - -:origin cmp cur_y, scroll_bot WZ, WC - if_b jmp #lf_ret - mov cur_y, scroll_bot - sub cur_y, #1 -scroll_up - mov t1, scroll_top - mov t2, screen_w - call #mul16x16 - shl t2, #1 - add t2, screen_ptr - mov dst, t2 ' destination = scroll_top of screen buffer - mov src, t2 ' source = dito - mov rows, scroll_bot ' scroll range height - sub rows, scroll_top -scroll_up_1 - add src, screen_w ' copy from one line below - add src, screen_w - sub rows, #1 WZ, WC ' - 1 rows to move - if_be jmp #:fill ' nothing left to scroll? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols rdlong data, src - add src, #4 - wrlong data, dst - add dst, #4 - djnz cols, #:cols - djnz rows, #:rows -:fill mov cols, screen_w2 ' columns = screen width / 2 - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:blank wrlong t1, dst ' fill 4 spaces - add dst, #4 - djnz cols, #:blank -scroll_up_ret -lf_ret - ret - -'******************************************************************************************** -' vt - vertical tab (inverse line feed) -' -vt - sub cur_y, #1 - test flags, #flag_decom WZ ' origin mode enabled? - if_nz jmp #:origin ' yes, check cursor in scroll range - -:screen ' no, check cursor in screen range - cmps cur_y, #0 WZ, WC ' < 0? - if_ae jmp #vt_ret ' in range - mov cur_y, #0 ' stay in line 0 - mov src, screen_end - mov dst, screen_end - mov rows, screen_h - jmp #scroll_down_1 -:origin - cmps cur_y, scroll_top WZ, WC - if_ae jmp #vt_ret - mov cur_y, scroll_top -scroll_down - mov t1, scroll_bot - mov t2, screen_w - call #mul16x16 - shl t2, #1 - add t2, screen_ptr - mov dst, t2 ' destination = end of scroll range buffer - mov src, t2 ' source = last row of scroll range buffer - mov rows, scroll_bot ' scroll range height - sub rows, scroll_top -scroll_down_1 - sub src, screen_w - sub src, screen_w - sub rows, #1 WZ, WC ' - 1 rows to move - if_be jmp #:fill ' nothing left to scroll? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols sub src, #4 ' pre decrement source - rdlong data, src - sub dst, #4 ' pre decrement destination - wrlong data, dst - djnz cols, #:cols ' for all columns - djnz rows, #:rows ' for all rows -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - mov cols, screen_w2 ' columns = screen width / 2 -:blank sub dst, #4 - wrlong t1, dst - djnz cols, #:blank -scroll_down_ret -vt_ret - ret - -'******************************************************************************************** -' ff - form feed (clear screen) -' -ff - mov dst, screen_ptr - mov rows, screen_h ' screen height rows - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols wrlong t1, dst ' fill with 4 blanks - add dst, #4 - djnz cols, #:cols ' for all columns - djnz rows, #:rows ' for all rows - call #home -ff_ret - ret - -'******************************************************************************************** -' home - cursor home -' -home - mov cur_x, #0 - mov new_x, #0 - mov cur_y, #0 -home_ret - ret - -'******************************************************************************************** -' can - clear from cursor to end of line -' -can - mov dst, cur_ptr - mov cols, screen_w - sub cols, new_x WZ, WC - if_be jmp #can_ret - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:fill wrword t1, dst - add dst, #2 - djnz cols, #:fill -can_ret - ret - -'******************************************************************************************** -' emit - emit character to cursor and advance cursor position -' -emit - cmp new_x, screen_w WZ, WC ' reached end of line? - if_b jmp #:in_bounds - test flags, #flag_decawm WZ ' auto wrap mode active? - if_z jmp #emit_ret ' no, don't emit character - call #cr - call #lf -:in_bounds mov cur_x, new_x - call #calc_cursor - or cmd, color - test attr, #attr_underline WZ - muxnz cmd, #$80 - wrword cmd, cur_ptr ' write character to screen RAM - mov new_x, cur_x - add new_x, #1 - add cur_ptr, #2 -emit_ret - ret - -'******************************************************************************************** -' calc_cursor - compute cursor address in cur_ptr -' -calc_cursor - mov t1, cur_y ' cursor row - mov t2, screen_w ' * screen width - call #mul16x16 - mov cur_ptr, t2 ' product in cur_ptr - add cur_ptr, new_x ' + new cursor column - shl cur_ptr, #1 ' * 2 - add cur_ptr, screen_ptr ' + screen buffer address -calc_cursor_ret - ret - -'******************************************************************************************** -' enable_cursor - enable or disable the cursor depending on the deccm flag -' -enable_cursor - tjz cursor_ptr, #cmdloop - test flags, #flag_deccm WZ ' cursor enabled? - if_z mov t1, #%000 ' cursor off - if_nz mov t1, #%110 ' cursor on, blink slow - add cursor_ptr, #2 ' cursor control - wrbyte t1, cursor_ptr - sub cursor_ptr, #2 - jmp #cmdloop - -'******************************************************************************************** -' set_color - combine background and foreground color and write the table -' -set_color - test attr, #attr_inverse WZ - if_z jmp #:default -:inverse - mov color, fgcol ' compose inverse color - shl color, #4 - or color, bgcol - jmp #:cont -:default - mov color, bgcol ' compose default color - shl color, #4 - or color, fgcol -:cont - test attr, #attr_highlite WZ - muxnz color, #$08 - test attr, #attr_blinking WZ - muxnz color, #$80 - shl color, #8 ' in bits 15..8 - jmp #cmdloop - -'******************************************************************************************** -' mul16x16 - multiply 16 bits in t1 by 16 bits in t2, result in t2 -' -mul16x16 - shl t1, #16 ' multiplicand in bits 31..16 - mov t3, #16 ' loop 16 times - shr t2, #1 WC ' get initial multiplier bit in carry -:loop if_c add t2, t1 WC ' if carry set, add multiplicand to product - rcr t2, #1 WC ' next multiplier bit to carry, shift product - djnz t3, #:loop ' until done -mul16x16_ret - ret - -lmm_loop - rdlong :op1, lmm_pc - add lmm_pc, #4 -:op1 nop - rdlong :op2, lmm_pc - add lmm_pc, #4 -:op2 nop - rdlong :op3, lmm_pc - add lmm_pc, #4 -:op3 nop - rdlong :op4, lmm_pc - add lmm_pc, #4 -:op4 nop - jmp #lmm_loop - - fit $1f0 - -control_table word do_nul, do_soh, do_stx, do_etx, do_eot, do_enq, do_ack, do_bel - word do_bs, do_ht, do_lf, do_vt, do_ff, do_cr, do_so, do_si - word do_dle, do_dc1, do_dc2, do_dc3, do_dc4, do_nak, do_syn, do_etb - word do_can, do_em, do_sub, do_esc, do_fs, do_gs, do_rs, do_us - -csi_cmds word @@@do_insert_char ' [...@ - word @@@do_cursor_up ' [...A - word @@@do_cursor_down ' [...B - word @@@do_cursor_left ' [...C - word @@@do_cursor_right ' [...D - word @@@do_rows_up ' [...E - word @@@do_rows_down ' [...F - word @@@do_cursor_column ' [...G - word @@@do_cursor_address ' [...H - word cmdloop ' I unused? - word @@@do_clear_screen ' [...J - word @@@do_clear_row ' [...K - word @@@do_insert_line ' [...L - word @@@do_delete_line ' [...M - word cmdloop ' N unused? - word cmdloop ' O unused? - word @@@do_delete_char ' P unused? - word cmdloop ' Q unused? - word cmdloop ' R unused? - word cmdloop ' S unused? - word cmdloop ' T unused? - word cmdloop ' U unused? - word cmdloop ' V unused? - word cmdloop ' W unused? - word @@@do_blank_chars ' [...X - word cmdloop ' Y unused? - word cmdloop ' Z unused? - word cmdloop ' [ unused - word cmdloop ' \ unused - word cmdloop ' ] unused - word cmdloop ' ^ unused - word cmdloop ' _ unused - word @@@do_cursor_column ' [...` alternate form for [...G - word cmdloop ' a unused? - word cmdloop ' b unused? - word cmdloop ' c unused? - word cmdloop ' d unused? - word cmdloop ' e unused? - word @@@do_cursor_address ' [...f alternate form for [...H - word cmdloop ' g unused? - word @@@do_flag_set ' h unused? - word cmdloop ' i unused? - word cmdloop ' j unused? - word cmdloop ' k unused? - word @@@do_flag_res ' h unused? - word @@@do_mode_attributes ' [...m - word cmdloop ' n unused? - word cmdloop ' o unused? - word cmdloop ' p unused? - word cmdloop ' q unused? - word @@@do_scroll_range ' [...r - word @@@do_save_cursor ' [?...s - word cmdloop ' t unused? - word @@@do_restore_cursor ' [?...u - word cmdloop ' v unused? - word cmdloop ' w unused? - word cmdloop ' x unused? - word cmdloop ' y unused? - word cmdloop ' z unused? - -'******************************************************************************************** -' -' LMM code fragments following -' -'******************************************************************************************** - -'******************************************************************************************** -' [...@ - insert n spaces at the cursor position -' -do_insert_char - call #non_zero_args - cmp new_x, screen_w WZ, WC - if_ae jmp #cmdloop -:loop mov t1, cur_y - mov t2, screen_w - call #mul16x16 - add t2, new_x - shl t2, #1 - add t2, screen_ptr - mov dst, t2 - add dst, #2 - mov src, t2 - mov cols, screen_w - sub cols, new_x - sub cols, #1 WZ, WC - if_be add lmm_pc, #4*(:blank - $ - 1) -:insert rdword data, src - add src, #2 - wrword data, dst - add dst, #2 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :insert) - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:blank wrword t1, t2 - sub csi_args, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...A - cursor up -' -do_cursor_up - call #non_zero_args -:loop call #vt - sub csi_args, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...B - cursor down -' -do_cursor_down - call #non_zero_args -:loop call #lf - djnz csi_args, #:loop - jmp #cmdloop - -'******************************************************************************************** -' [...C - cursor left -' -do_cursor_left - call #non_zero_args - mov cur_x, new_x - sub cur_x, csi_args WC - if_c mov cur_x, #0 - jmp #validate_cursor - -'******************************************************************************************** -' [...D - cursor right -' -do_cursor_right - call #non_zero_args - mov cur_x, new_x - add cur_x, csi_args - jmp #validate_cursor - -'******************************************************************************************** -' [...E - rows up, cursor column = 0 -' -do_rows_up - call #non_zero_args - mov cur_x, #0 - mov new_x, #0 - sub cur_y, csi_args WC - if_c mov cur_y, #0 - jmp #validate_cursor - -'******************************************************************************************** -' [...F - rows down, cursor column = 0 -' -do_rows_down - call #non_zero_args - mov cur_x, #0 - mov new_x, #0 - add cur_y, csi_args - jmp #validate_cursor - -'******************************************************************************************** -' [...H - cursor address - row, column -' -do_cursor_address - cmp csi_argf, #0 WZ ' nor arguments at all? - if_z call #home - if_z jmp #cmdloop - call #non_zero_args - mov cur_y, csi_args - sub cur_y, #1 - cmp csi_argc, #1 WZ, WC ' the caller specified just a row? - if_be jmp #validate_cursor - call #shift_csi_args - ' fall through -'******************************************************************************************** -' [...G - cursor column -' -do_cursor_column - call #non_zero_args - mov cur_x, csi_args - sub cur_x, #1 - jmp #validate_cursor - -'******************************************************************************************** -' [...J - clear screen -' -do_clear_screen - call #calc_cursor - cmp csi_args, #0 WZ ' cursor to end of screen? - if_nz add lmm_pc, #4*(:not_0 - $ - 1) - mov dst, cur_ptr - mov end, screen_end - add lmm_pc, #4*(:fill - $ - 1) -:not_0 cmp csi_args, #1 WZ ' start of screen to cursor? - if_nz add lmm_pc, #4*(:not_1 - $ - 1) - mov dst, screen_ptr - mov end, cur_ptr - add lmm_pc, #4*(:fill - $ - 1) -:not_1 cmp csi_args, #2 WZ ' entire screen? - if_nz jmp #cmdloop ' invalid argument - mov dst, screen_ptr ' default = entire screen - mov end, screen_end -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:loop wrword t1, dst ' fill a word - add dst, #2 - cmp dst, end WZ, WC - if_b sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...K - clear cursor row -' -do_clear_row - call #calc_cursor - cmp csi_args, #0 WZ ' cursor to end of row? - if_nz add lmm_pc, #4*(:not_0 - $ - 1) - mov dst, cur_ptr ' default = cursor to end of row - mov end, cur_ptr - sub end, new_x - add end, screen_w ' end of row - add lmm_pc, #4*(:fill - $ - 1) -:not_0 cmp csi_args, #1 WZ ' start of row to cursor? - if_nz add lmm_pc, #4*(:not_1 - $ - 1) - mov dst, cur_ptr - sub dst, new_x ' start of row - mov end, cur_ptr ' to cursor - add lmm_pc, #4*(:fill - $ - 1) -:not_1 cmp csi_args, #2 WZ ' entire row? - if_nz jmp #cmdloop ' invalid argument - mov dst, cur_ptr - sub dst, new_x ' start of row - mov end, dst - add end, screen_w ' end of row -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:loop wrword t1, dst ' fill a word - add dst, #2 - cmp dst, end WZ, WC - if_b sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...L - insert line(s) -' -do_insert_line - call #non_zero_args -:loop mov dst, screen_end - mov src, screen_end - sub src, screen_w - mov rows, screen_h ' screen rows - sub rows, cur_y ' - cursor row - sub rows, #1 WZ, WC ' - 1 - if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols sub src, #4 - rdlong data, src - sub dst, #4 - wrlong data, dst - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :cols) - sub rows, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :rows) -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - mov cols, screen_w2 ' columns = screen width / 2 -:blank sub dst, #4 - wrlong t1, dst - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns - sub csi_args, #1 WZ ' more lines to insert? - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...M - delete line(s) -' -do_delete_line - call #non_zero_args -:loop mov t1, cur_y - mov t2, screen_w - call #mul16x16 - shl t2, #1 - add t2, screen_ptr ' cursor row address - mov dst, t2 - mov src, t2 - add src, screen_w ' one row down - add src, screen_w - mov rows, screen_h ' screen rows - sub rows, cur_y ' - cursor row - sub rows, #1 WZ, WC ' - 1 - if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols rdlong data, src - add src, #4 - wrlong data, dst - add dst, #4 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :cols) - sub rows, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :rows) -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - mov cols, screen_w2 ' columns = screen width / 2 -:blank wrlong t1, dst - add dst, #4 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns - sub csi_args, #1 WZ ' more lines to insert? - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...P - delete n characters at the cursor position -' -do_delete_char - call #non_zero_args - cmp new_x, screen_w WZ, WC - if_ae jmp #cmdloop ' can't delete beyond last column -:loop mov t1, cur_y - mov t2, screen_w - call #mul16x16 - add t2, new_x - shl t2, #1 - add t2, screen_ptr - mov dst, t2 - mov src, t2 - add src, #2 - mov cols, screen_w - sub cols, new_x - sub cols, #1 WZ, WC - if_be add lmm_pc, #4*(:blank - $ - 1) ' new_x is beyond the last column -:insert rdword data, src - add src, #2 - wrword data, dst - add dst, #2 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :insert) -:blank mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - wrword t1, dst ' clear the last character in the row - sub csi_args, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...X - blank characters -' -do_blank_chars - call #non_zero_args - mov dst, cur_ptr - mov cols, screen_w - sub cols, new_x WZ, WC - if_be jmp #cmdloop - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:fill wrword t1, dst - add dst, #2 - sub csi_args, #1 WZ - if_z jmp #cmdloop - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :fill) - jmp #cmdloop - -'******************************************************************************************** -' [...h - set flag(s) -' -do_flag_set -:loop - mov cmd, csi_args - cmp question_mark, #1 WZ ' [? sequence? - if_z add lmm_pc, #4*(:ques - $ - 1) - cmp cmd, #3 WZ ' [3h - display control characters - if_z or flags, #flag_ctrl - cmp cmd, #4 WZ ' [4h - set insert mode - if_z or flags, #flag_decim - cmp cmd, #20 WZ ' [20h - set auto CR mode - if_z or flags, #flag_deccr - add lmm_pc, #4*(:next - $ - 1) -:ques - cmp cmd, #1 WZ ' [?1h - enable cursor keys - if_z or flags, #flag_decck -' cmp cmd, #2 WZ ' [?2h - enable 132 column mode -' if_z or flags, #flag_decck - cmp cmd, #5 WZ ' [?5h - inverse terminal on - if_z or inverse, #1 - cmp cmd, #6 WZ ' [?6h - enable origin mode - if_z or flags, #flag_decom - cmp cmd, #7 WZ ' [?7h - enable auto wrap mode - if_z or flags, #flag_decawm - cmp cmd, #8 WZ ' [?8h - enable auto repeat mode - if_z or flags, #flag_decarm -' cmp cmd, #9 WZ ' [?9h - enable report mouse mode -' if_z or flags, #flag_decrm - cmp cmd, #25 WZ ' [?25h - enable cursor - if_z or flags, #flag_deccm -:next - cmp csi_argf, #0 WZ ' no arguments specified? - if_z jmp #cmdloop - - call #shift_csi_args - sub csi_argc, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #enable_cursor - -'******************************************************************************************** -' [...l - reset flag(s) -' -do_flag_res -:loop - mov cmd, csi_args - cmp question_mark, #1 WZ ' [? sequence? - if_z add lmm_pc, #4*(:ques - $ - 1) - cmp cmd, #3 WZ ' [3l - don't display control characters - if_z andn flags, #flag_ctrl - cmp cmd, #4 WZ ' [4l - reset insert mode - if_z andn flags, #flag_decim - cmp cmd, #20 WZ ' [20l - reset auto CR mode - if_z andn flags, #flag_deccr - add lmm_pc, #4*(:next - $ - 1) -:ques - cmp cmd, #1 WZ ' [?1l - disable cursor keys - if_z andn flags, #flag_decck -' cmp cmd, #2 WZ ' [?2l - disable 132 column mode -' if_z andn flags, #flag_decck - cmp cmd, #5 WZ ' [?5l - inverse terminal off - if_z andn inverse, #1 - cmp cmd, #6 WZ ' [?6l - disable origin mode - if_z andn flags, #flag_decom - cmp cmd, #7 WZ ' [?7l - disable auto wrap mode - if_z andn flags, #flag_decawm - cmp cmd, #8 WZ ' [?8l - disable auto repeat mode - if_z andn flags, #flag_decarm -' cmp cmd, #9 WZ ' [?9l - disable report mouse mode -' if_z andn flags, #flag_decrm - cmp cmd, #25 WZ ' [?25l - disable cursor - if_z andn flags, #flag_deccm -:next - cmp csi_argf, #0 WZ ' no arguments specified? - if_z jmp #cmdloop - - call #shift_csi_args - sub csi_argc, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #enable_cursor - - -'******************************************************************************************** -' [...m - set mode attributes -' -do_mode_attributes -:get_arg mov cmd, csi_args ' get next argument - cmp cmd, #0 WZ ' 0 = reset all attributes - if_z mov attr, #0 - if_z mov bgcol, #%0000 - if_z mov fgcol, #%0111 - cmp cmd, #1 WZ ' 1 = highlight on - if_z or attr, #attr_highlite - cmp cmd, #2 WZ ' 2 = highlight off - if_z andn attr, #attr_highlite - cmp cmd, #4 WZ ' 4 = underline on - if_z or attr, #attr_underline - cmp cmd, #5 WZ ' 5 = blinking on - if_z or attr, #attr_blinking - cmp cmd, #7 WZ ' 7 = inverse on - if_z or attr, #attr_inverse - cmp cmd, #10 WZ ' 10 = primary font, no ctrl, no meta - if_z andn flags, #flag_ctrl - if_z andn flags, #flag_meta - cmp cmd, #11 WZ ' 11 = alternate font, ctrl chars, low half, meta off - if_z or flags, #flag_ctrl - if_z andn flags, #flag_meta - cmp cmd, #12 WZ ' 12 = alternate font, ctrl chars, low half, meta on - if_z or flags, #flag_ctrl - if_z or flags, #flag_meta - cmp cmd, #21 WZ ' 21 = highlight on - if_z or attr, #attr_highlite - cmp cmd, #22 WZ ' 22 = highlight on - if_z or attr, #attr_highlite - cmp cmd, #24 WZ ' 24 = underline off - if_z andn attr, #attr_underline - cmp cmd, #25 WZ ' 25 = blinking off - if_z andn attr, #attr_blinking - cmp cmd, #27 WZ ' 27 = inverse off - if_z andn attr, #attr_inverse - cmp cmd, #30 WZ ' 30 = foreground color 0 - if_z mov fgcol, #%0000 - cmp cmd, #31 WZ ' 31 = foreground color 1 - if_z mov fgcol, #%0001 - cmp cmd, #32 WZ ' 32 = foreground color 2 - if_z mov fgcol, #%0010 - cmp cmd, #33 WZ ' 33 = foreground color 3 - if_z mov fgcol, #%0011 - cmp cmd, #34 WZ ' 34 = foreground color 4 - if_z mov fgcol, #%0100 - cmp cmd, #35 WZ ' 35 = foreground color 5 - if_z mov fgcol, #%0101 - cmp cmd, #36 WZ ' 36 = foreground color 6 - if_z mov fgcol, #%0110 - cmp cmd, #37 WZ ' 37 = foreground color 7 - if_z mov fgcol, #%0111 - cmp cmd, #38 WZ ' 38 = default color and underline on - if_z mov fgcol, #%0111 - if_z or attr, #attr_underline - cmp cmd, #39 WZ ' 39 = default color and underline off - if_z mov fgcol, #%0111 - if_z andn attr, #attr_underline - cmp cmd, #40 WZ ' 40 = default background - if_z mov bgcol, #%0000 ' black - cmp cmd, #41 WZ ' 41 = background color 1 - if_z mov bgcol, #%0001 - cmp cmd, #42 WZ ' 42 = background color 2 - if_z mov bgcol, #%0010 - cmp cmd, #43 WZ ' 43 = background color 3 - if_z mov bgcol, #%0011 - cmp cmd, #44 WZ ' 44 = background color 4 - if_z mov bgcol, #%0100 - cmp cmd, #45 WZ ' 45 = background color 5 - if_z mov bgcol, #%0101 - cmp cmd, #46 WZ ' 46 = background color 6 - if_z mov bgcol, #%0110 - cmp cmd, #47 WZ ' 47 = background color 7 - if_z mov bgcol, #%0111 - cmp cmd, #49 WZ ' 49 = default background - if_z mov bgcol, #%0000 ' black - - cmp csi_argf, #0 WZ ' no arguments specified? - if_z jmp #cmdloop - - call #shift_csi_args - sub csi_argc, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :get_arg) - jmp #set_color - -'******************************************************************************************** -' [...r - set scroll range -' -do_scroll_range - cmp csi_argc, #2 WZ, WC ' 2 arguments specified? - if_ae add lmm_pc, #4*(:set_range - $ - 1) - mov scroll_top, #1 - mov scroll_bot, screen_h - add lmm_pc, #4*(:bottom_ok - $ - 1) -:set_range - mov scroll_top, csi_args - mov scroll_bot, csi_args + 1 - cmp scroll_top, scroll_bot WZ, WC ' bottom => top? - if_be add lmm_pc, #4*(:order_ok - $ - 1) - mov scroll_top, #1 - mov scroll_bot, screen_h - add lmm_pc, #4*(:bottom_ok - $ - 1) -:order_ok - cmp scroll_bot, screen_h WZ, WC ' bottom > screen height? - if_be add lmm_pc, #4*(:bottom_ok - $ - 1) - mov scroll_top, #1 - mov scroll_bot, screen_h -:bottom_ok - sub scroll_top, #1 - mov cur_x, #0 - mov cur_y, #0 - jmp #goto_xay - -'******************************************************************************************** -' [?...s - save cursor position and attributes -' -do_save_cursor - mov cur_x_save, cur_x - mov new_x_save, new_x - mov cur_y_save, cur_y - mov attr_save, attr - jmp #cmdloop - - -'******************************************************************************************** -' [?...u - restore cursor position and attributes -' -do_restore_cursor - mov cur_x, cur_x_save - mov new_x, new_x_save - mov cur_y, cur_y_save - mov attr, attr_save - jmp #cmdloop diff --git a/Source/Hardware/Experimental/vga2/Build.cmd b/Source/Hardware/Experimental/vga2/Build.cmd deleted file mode 100644 index e4ad8241..00000000 --- a/Source/Hardware/Experimental/vga2/Build.cmd +++ /dev/null @@ -1 +0,0 @@ -bstc -Ox -ls -e -p0 -dCOM5: vgademo.spin \ No newline at end of file diff --git a/Source/Hardware/Experimental/vga2/Makefile b/Source/Hardware/Experimental/vga2/Makefile deleted file mode 100644 index 197d1a47..00000000 --- a/Source/Hardware/Experimental/vga2/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -SPINC= bstc.linux -SPINC_FLAGS= -Ox -ls -e -p0 -d/dev/ttyS0 -INCLUDES= -L../lib - -VERSION= 0.0.4 - -all: vgademo - -vgademo: vgademo.spin vga8x8d.spin vt100.spin - $(SPINC) $(SPINC_FLAGS) $(INCLUDES) -o $@ $< - -clean: - rm -f *.eeprom *.lst *.list *.bck *.o - -dist: clean - cd .. && rm -f vgademo-$(VERSION).zip && \ - zip -r vgademo-$(VERSION).zip vga2 diff --git a/Source/Hardware/Experimental/vga2/bstc.exe b/Source/Hardware/Experimental/vga2/bstc.exe deleted file mode 100644 index febcbd0a7304f2acd70d3b87f80aaa3f351d4da9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120320 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%0Dw)c`$B<1ZS zIkiMcVdBBwgv#`G^|^6B#mi?0$zX@*3f6h|nzuJ->kdSS4G{UDneQ_hr~#?QWdH|& z29tjN##Im?11dXb za3wCTQ*>h60d2<6;LAP94VHe8l&l?&Y0;Y5+1T`Qlr5Wsw8991>FMdz%E^aP&;%3B z5@(Nm7uk6f>QUJvV@#)~tz3$?%QfOo;3ITV6Ka!kqK2cey10v?IckgVjR;q&G3;8 z9mZ;@ZPzEQQ}6B!G&xqbvFOU(UK20H3nKFFk)lf!5j;08HR6su}{vTq`_Tu ziX1?4TkE>@=GGc7keB1{NhF6vv-Qw5v{EG_Y;AqhS1(WbFTLv>g26S9l211b}_3^L!@OTgcL2a|TIBH;u55=%&Dv-lyNId9Hn z)F`oM@SVLJ>NU8@#8S7!A_9@oTgqwNU7j98Sv7DS<|nD zS*O}4r-O+y4{NB{{Sl?{gaMPkK0lRt&{q&#nS4bUubhG@zy1oU>u6^snz&Y5^q2It8_ z+C4k4`w|@4&^9+yUlAdcR#K2eBthxx7RP~ZvK7r-NCr6UO1stlZBW=VC%z>`wV@(g zcH}J!6?I`R-_~+QWXSMqJDJV=_8w)NL>i(qg-)%U(r5SDHMW8e6&($iyo6>H%gTt_ z-UOadgvkJuH&C|K!ww8X3(EEK-<`grc9a0mM!Sj*s)fKG4>bduP2Q;E-=n##&;yUj zEIEi%#?h!7P_ExdYGQB{itIp74!(VHn)8t5cp9bi80w*i;4*+^ilZ3<7*r_!$Z?0P zPbvZ3dtmHFp2QKN#Y3T7!<@|uw?Al0I1bZk-4^tZ`^Q`g`R>+Hnw0W@V{IfUKd_f5 zDEB{*%hEMBc}6lZYIAlp9r!Aw5^XuvR#s{SkZV2(8?@B$Ci58xlm+0arR9}2&|i?J zblTI>$FUmGrJ-21MJGs|OtJ(!vH3f`mSFFCVn59wj!UcJfNJHLorLq#jSiZ;zxm&a zPn$q<}za3K3)!D+-YOhFp9V?z~MwENBn*^Zrfuw-e zHI{oRQAF9jH(c@m{PebAY^v;<$=MV~YCx;*)Y<60saj);yjQxu6k@bEcru$$4lU)` zYRr39d|BX-oGpI#Y;~!YrXF@YL$0`neHCq=VRSUcSwP6}k$8ILT#e*OR>c|*t57`? z7IusDCZw4K)b-Ndxe}+hW|r2(dQLZ9Xs5N++|I*uN{qL63@@@Pd8>qK?`M*R_TxHU4h}PJ*06Z&T9dY7C|qZz;dvdD_B~Gk z1fH9581PP)G}&))U1CCy1nM@m|4|%DwEVkV3Y{SVi1s&ye&Ak3p$Q3f{Et1RO z>l{F@M_0jZ9BzBpebCTRWZVIAlewD?h)caU0}Vq#2LoNVq_?P7I4&K zl^rW|B5REp3qB5Mf7d|7Iqs(LLnVL9DUP5iqI05D@cbtdIQH3(8nQt@tW5fI8b+0~ zo?**|LLr@(WV&vB*QlNU@PNCoVtJxXy%MKUNeYH%ZV(1e>UkQs-L)YGk=U+2G3B8En-H$R3F+Q1!@6O7ij*Eobk+3i_u2)BzlarjE9jnZ){%|omN z{E@12PKAupdDwQ!Md3t`9;D?mpZ9jIkBPxze^3s@dQ)2!`CoWu;`4wbW$N+##=j=K zpWy81ZH*T7@aUM~wCLMU=UpApJ@;93s1|7G(B#O1SpGSAT@tQhT0zdG^;7Em)Ml8< z!MN~EMF|El1T62Q6OZyF=hyzsA`1j5kdsjB-)c@COH~78RhJ+mVvscxmrBabnY-aq zj?NVdyjOT|k=lH`J4N~Mysp8>S$4GCz*6ca;FuTwk~qd6^2u$XI4DS}!6-)ACQ~)l zxPMmhzRiiHZR!+-QkOB1h_K6wPy?~^CMcurW%b7#LI+rJLMR1`0M}_f+W_?A4|>mE zhh;Kb<;*Pabr8aX{GQi4LSaqOMr|%C=~|d6tw9ALok=UJf8Qe5d)F!2#URyRd*te< zgQttq`afI!DBP6l`mHTGAhebXXcR<0ek>F;ZVz^T?QL^;lOD99n}k%F4$L&iNATAJ zFW(J5$MzeBDF5&numRm-A3Wn6@*rlhaH5;;4#HAx$>ZucBrf(h5@dEmE$fUjn&;sV z;RkRkg&5N??#8BT%DyqgFWVa(<_N0eI?#HmGVd>6DY53*gRR2iEwi_N-4j8#n;Cxr zx2;wVP~on}Qb;Wr+f|v7o!qUi(UBykA{4~BI)g~FW&^P#?;IPh&L$!*8nG7DmjKCg zCwUJNoZ6;m31|`k>rpt#uAkWPru1-bYR_xQ1w(i$qs8U`K5#bCb0(Et?_OqM!N>d~DZ zmMEiKryH{fIiiOHq%p}-=1$Y+!$MlV)ktB}ViaQs)RqJxBPxd4VNMY@S=?EflUIel zT$%`l`J=pkm~z2!$fh*q zpWmq!1K@9Hi2YR7wBjrYfPtHZje2XaK@FYy*VcPEsnA(K@I_lHpJGo|ZiYK3?W!In z$>jfO;GBX{@&7l_*E+emFOYV8%B|OEmhq+m7}H#{cu^NeM@c+5+6G-=^R!Ooy6TG&#F+d`O)(& zfM8K+Zj}K{H%Jwv5F}3E6?J&k3|9%9;lo%!UH$?PPi1fB-_I}CX>rfHwpRv=q>s%I zndx!ElB(BWWpB1yS?nlZyFNrIIjAa(qf-cs+aiWTu2yxtB~>{ct@EEt2keMtAXS4I!|yJ>Pr z2cT2LSh(BvroRAc=6)CY|IT;SVT^Q@BHAP^yQnN^a+kunDVbV^K?ys@TfCdMd9r2# zRb)&;{CcYFyHFu%)fjayd*jKPUgT)UD)f;MF{2eTZ#AA{^~8IYhg+u%Y=3f0m4HC% zfmdvVP&}9luzbI$Sr?j)h0{YmV+#0D1h}c!ImwaYKE>gURwi(J_9>3WkBVv1Y4D+JUMPGR-3@S%b}(7tt>PCIl zBf^T7K#SqWg6AuRPVpdO7F32V-5aDKLtuik)zFhIToD+iad!t-uK|ZyAZ7lsWT(s` zmv5v8x z303*4)H004Yu6X_Ymd0?o=;iUNq*wE?s{hoC*jZ}=1QqxCd9k|&b@#rOJ!Jzult>$ zkK>+nsnPKh$o9cZGG$`~VrsOd$aR_iqjka_`RUjaxcxs7>|cB@^L{-su!-<_*gD<2 zAYSwUBW$Fwx%F)qdjAx7qN;o`=>_}s0&sZ)V^Gli4Yh;n-S)Rfp`>C@TQ|D4WCNon zMdD@dFaS4%Eu*Z_iu{7QLr6_+^bk>liDkmMbQWn5`KGadphY(Rhr;}j@iHNHB=hv- z<9`neLcL4f70-fHS#!`X5@twcSZHa*2yw#rHK20K{cGROkpt#Ow@x0fEQxy?e+Sx` zFt4P5KQnB_y`^Q}`0#Qza^)fdhIy}zIpVJWiF%=tL&I+MUPakvCU$}zN5-=8kzDWn zy9Zu_X#%$7cFv(i@H*w~mD^%8TN^y;c&eYH8B2BCeEQbG(9FbNvd2_;)|>R(QJE8f z+A=sB|G70`kO_>Oy1(7Ij_D4$`K$dXRnulZG5ap8BvHxXSV6CFUXLaiWt~XYn?NAR z95Vopza;h0md3c@^H{XZ9l6h9H*j0@V+1effU+Ptww2$xsL97AKr~lyDH=`YmqCo&nzY(;&>zl{Sh~=l4>n9CH){N(<$HqWa|m~`Co%I2)@9SwrHNU>(NiJ zVC{>t2O@n(TNdlIJe$X1e-%)~Tw>|cF+^AF)ANIcaVhqncB6b9=v+#ZEt>@YZ$fQ6 zz|sPRx_FnXZh&CPa!C6vo==~bN32tZ!CM_{4^Y`@oid5xv9dPZ2n)MH4@v)6gLsj@ zem`B)_e<}x4g;nBq>E!l;1MqJIUVcpkmM>4BeJ9XYD^ZTIrDfyRCKEe$q|8o$X9%7 z<~4nnyaRIABMrYFUkj_x>()v=IzR|}?{I7*MD=SJFpB9@i32bc8&psgGg4}`$U&VB zGc#3BsNhqSi#T46zFY7j8os!}Y%Ib#ba>icV&c;?N=*KoC-HU9R-JP-NjPl?p&yPs z+_vesB6C|Bbb1PzqCKNO4F!`P6A@edGM(q6ytT?| zY@T+l;153#B!`?1XQi<`rs%9&+2;eGB#)~7&1`DjAAvTWiq)!CGX`ty~8Lrg0b*l{W6Dx7O0pEEM3Q zr1>#~BOsH8-ci|&Vw;yBsg?vc^`z1?d#V|h87_&;edrj3LKZ>35GyhE1aQFoR_(9 z74ve|z{eeU(Po^zNbR3rskbYN_m(ln*beegEvXt!BeZ+megV3YNy zlT@MrQgDB>y#fwz35J@}7FQ=|)Ylhxt#P3}0XV*ocx3Zv>@M0=7kh(ZJ=S*G7rvJB zDPDLSgRuBx<2e8xyQNun))ph?%7JSIJ4sFIO~DqFH>EY+sYC;YEz~4}H}hIEJU`5N zf1_I7Tk?6Zgp(hGtEfO*Bip*sOshPaVjN_tHs75UsO1qCO4VOX8ZgEC$re~N8^y(L z^=wq=YQQ5*@D1a&x`1|4L6TmnT`9eA5dUd}F;HWlDGu;&x>5#%RQ91Q8+=aYn!06o>N7rYv~aJ$WyZ+@6B|YyhzsAUwtOAZ>DRi zZ`e;wfBwjqfTIDj6N{R3%_W_j&Iq>+_ra*?@m22ByF!*NCq1>i2TVHmG1|}J9AfT6+myz2VEvoGh>3Y( zWUR2CT6{;s!BYZZF4hn-P;c0i1^M;PDfFSuhXVe?8#*ix|9*q<3M$#5GERgWk!S8s z!8U$Z`%iT^haSh7WiDjDh4uJ0Ykyg@5Z*Mg9n|!;bnps>OMxC&uK;Ebo;j{KFTAgo%esoT2ppdZxOr5_xm`?(u-4c)rW%?W;Y-Q0# ztB;3A*hfWQ@k8tTENs5#x4LBYuP_q0pb~8$J;6aY)b3QU|Hj$jX;9eFWOUjwXe~Md zT9%k|c~DhXnHdl_$Ix=^@M{??s65Ek!!ytIv$@o(e1Nn zSt(=0cFyqrC*Y5I{2WT}8sD039Z*Rp@uywt5u~WJaX#H~T(;?+ow6GLwozfdaNso; zUO24|5Vd1kRwpJGqLYa>@l~PE+R(^b)de9@8(1Tn&;fj(DS@O??aMH)Xj94g$(y9z zjRBP3_Su6cN#b!~f2@6acr9_k)&&RCcZH=*Z5dqHgMA{{DMfu(pLQzX|6!g3l5smi zLUhdaJmM+P&cS=^*!as*h@Qr50)pNXMAywN)!YLj4s7+eM1<{3w1~4!3|LgUsWyW( zZJvsNWi6zmo5VK>`h(0vY#>2QyUc)fMSPLT8w>Z|FI&g1fJKJ062pxF-l8D;YqcfJ z^3MY{Q+N9hYNNn)dJDaI-hTL_oR|ls4@=2ISB^m0l6n&f*)jgUbn&dBnLX&P(td5k zKaY_^&f;G@$$x?(Io-%Rp&T+qACPrWOB)NcSg&M}!cwN33E1W?|seH7Q`~2`Uua@WCPjdX5MFOO;>l*7x zvu9UsGP>B)^~&6;a2gH;F=Ku?$@#U>Z37e;M(oa*N3zhl88>o;L-oiRW&XXhK=CdAX^H9DFg6w9nHr{n&&h59aLTAik0ImPmJ(j_O<`krWJ@)d;U1g$!2}PlK@>epM0bR78b;zBlFP&4@ z#gx{fz$3ewMnh$hw~ZKyFK~g|X_y^X_Z!cQf|&Ipq(~RDL3zA_8D*N4P`~jdcY8(N z+ldyx{~UtvGN~1u2YD@K!1@lg=sv-E{Yhm{Imu|A5ibR(j|j$;sl6=8h2NT3a0FZ_ zqlWb>mBbWt+MH!%haOqx)goP>#A5eQsm;X_vIypEkj(?yl9ci&n!B0SaBn!+VDt82 ziKx?i$%rRblFfskJ@^`?XfXP368U0>(@^^ue>Xy9Wnv8TGP@E9$t$S-;@MNrO0lW) zDVt<-$Tr+q*_&vTe)?giFtNZf9+W5f6h;|X%`5UxDKw50#Qq_1nGheH0I1nj( zW`o;l!!!t5-U9%enV7V2&_Zy_dGy8QKpsX*5Q{J?8K&>(hLt2wSMVE+rc;MfxC!7aI(BB2NH=1X(XM1tVv*piNF<`vfAi)wI53^ygD<%Bz;-{1j>#X?` zkcp}3sz!U^3}OqynL>t@@xTdd^gPRA-_Z9exZ!P+!&?uj4Y1)?lnL`J6l1u+`O~!N zmUW&TV9$CZt&1&pJ1Y`8fd4Iz3yoz7V(tg5gMT!XA)K`lO!|xP5JKSpLKU&b-j912 zbQ!U^piUfXFL#cz(;+ob?zt~UHdm#}*AFZBC>(|=#uy&eYghW*3LRUm(LvH54+BRI z15&SmYh|&)M<*_uxo@5G*vM&g1%+IRfp^!(D)=mOMcQOacmIO`ret%r6ab4k`}nJ(6y&Xuy}%Orb9<5HK=Rz zk-+yEoK}4K5OT8o39$(+nWw&xBA^dN7_C^UyihJo2N3@C*{V*E(|9KD%uL*#w?9 z$7}Zu*q@CZ2<;n7!2{HtI4>Nqay5{0A_!)Xn~15Kt9q`O+Bsjws#N7o16Z|H6L62E zg~04vH^mHhm)OWb(RGiU(R3Ld+Y~ux2ZBCiwU>wm^8@?^vYOve{ne!X$Jgtb9ey4q&I(D=inb8xGvWJw}|3Zw# zNY7I3xPcE9CDHV1%&`(-D1-3{|5k*fnWEhJQu6D)3yZ0KtqYr!7TVEVn+0fjd3ms=XJh~2wX+`c1k<1BKFiAR-e)Hv5k z%qx59wcQfhEtB2XS%B|THxsU0*ja*U_@VAoFup;Cplt{MUB*m?FIW}GLU1lcYGoQf z&=o&W`tb_ypxSXWu)8EGpN4Pm7FPkr957JI(p2()!pD%mK?Ak6n0njaCyi*>3ajXH zj!InV&opfr{6JGIJx=9$N3R`W3>3okWjsiDezPqk(fRJxcF`UcrTWe8cm~ zUG;O3$vvS)ka2@DlzUWbRA<8Daeeb-K$gzb0ToFkZwm3Ra4Z|5=G2s#IU|6EN7t=n zQ!M_7R2<-9+v}*;D8gc<8r%;Z(q;Hk>7D|3nq^^W;<55+S=5%x8JdgryKV|K zJyo)1N{)-f$l^P&{L?iQUb7wopbgN!$=Mg-k}uCtH=*j0(R{n67EjQ-Y)ov9?ws+t zzuX~33S33)80VWP8zKN24a*igkiqxWdeJ^eI{0z5Si}_sapnLZ6w}x>?nySDxHGN`)KPweUpX}1nynlmDf@}Q=hcwdxS9O$voya7;=C@J3l_&B`n zH$Q;JyHpTbddKVG)h%=4RjLT=1y{TfMriG~i$|M(h;{y!%&Iwg^owiTBu4uj`5hEu zj3U}l`hxyYz{I5E~<+;1#Qc z_+B0i{_Lw`|IjUO#3i}!!zEfHY@FD^cyx89>Lg{lb>4W_#E58I1>XJFKj80(GPThapfWOK2Mg9&KzKsw}?4?g6#%PNBazjAg)*d|TP^SvImgmerfM5FuOBUw?d zfFZ1MEEXFwGAGX73tq$gz{v6@PZ4z=u5{>Wa8GzV>*3T+{Pk?l@r|_+qse^`XSS@2 z7y)NNm=Ht{Elyk#Asx*K6I$zSpSN23xrqho?~FV-&__YlJ0W0M#$ zI})I+{cA&TMsElf!PSI=eZ{FlcOcVm-M!%oR|xLmfYG^IXZhKppcsagBYY_Y4s=c0{TJDVu`x3qnddsWX@WRTlSrmC zTFmN#PLSW<)o#6GIYd#(2uo(Aqpns-k4X@=mKgVA?kv)H0bE2Q2%GKc0H``4Nk~0v zC#-Gl?*^)zBNt8oHaG;s8V1-3g_t^@(gF-|R_TRkXVPv{2Xu3w;)i^_?Ra|3+px&( zqfC$Ryn4!Tv>pg*0`lDHw;Cf8YmIt;dn_j%3|2w1 zKz~=ZvVF;`Yv4+V85LjALvUI;tdlW16L1%L1{k2+N@Jgjzg@8R*$j@*D>MjY5uzOr z&J?cr1N{LC=VDGPKuEC$ZclJwtpiI9W0^7_0Q7*;oZgqWv)F%qM3@GlT&!sFxi*>fY=h;U<0Y(iL1c zHFWVz1$}}v)m_{@Z-tJQU0%|Op;U=_778Z+9ro`vT(-_FD3Gb?8@z?!8X9&fYBfFA z0cNgo^kOfk8oZ3+G`nX$;MmGVR!yOG2Zf|7!KavtM(VE52_Igdtb(o2X;peqLUk~k zbm!!c&)=6}n+b0%C34a|rR1av8>B8#nXBYe8MIH-)xR>W#9B@zDIp`ttbgs1{2uufa@)tjb1 zwB3;~E@uy2z~pp8^E}jgQd1v$F;0|-7~Msf zYP0X?gpC$Uxo2ljF*5ShLO&Jw5yqb!=A&*4HdB=cuV0*Xv2W}XyVQ<0)hpDCecgl2 zKdpNMFEC(~yB)-i{K<30{LS1+F*ALRK`h2BG1fDe3FFOnfyPNYi*d4xvU*gSX)sjn z>w!HP1#a_FiMRy)9!NEbHqiWR6{w}y*F*Mz$?{X*R0XfvpZ&=eG2^8UXcl6dg`Y@+ zSRGqSNx$YZ*zRNRklU@gbp}I~PnsDkzz^gFEN+6x8$$QbeYlnSW z$6E~!R)Z9^EFFNqK2{N-=lmXyy)?t0%Bzcn5$+tsv{d09pzcBPFpgBA_m(#B;d?X=(UM(`;2HHJ?du|CWxp7L8ottNHe5e$32&+}RIr z4|6z!YV3F49k#qT{Md<;+`9M;X#DA>dvoal>7S*ygi`K3a8oFmCjN736Jx1wD^yXj zqr@I_Eiw~jEk z2|t*=FyLb-t7mL&1RdnB!45I9%StrzZKy_Q?pzOiw7kF7h2(}LO(w&bKby|>J z``ylh7D0-$-b-lxph)B~X8Yl9W9cX$p-tS4b;!aFYa{iuJsMU#;)K+_;5PFY-tfx(8Pwog0Ut;>b&}2b-@c7Ikk5LW@U~8$DddUxb z;*_S#A03kj%RfLsx(wxUjCtV*FOZA_G_1#rte_l(^)x1Qqh;ko%B$GGcU0~r)8)w{ zxL@&7v$Xi!LKfvj?Z~K{x`vfj4z|D?HwX-FJxseS@;hbI!G8={FSoa;9nb<0roUfu zaByx|5mzwh>}%XwsWVf=kkYbI=X0;A$A7+#;dugW2czs4P{BWfbZAq!a+&ty9+*6k zn2A-#a10la9kQ&7w5m3Ebc1VnolS?J4TLHG>y^5_`?-Hj_l&9JW=&dtwjGq@t3m~3 zu27N7IHZ87LD}AR_Pq)iC}SDPU>FktKIaZ&&qL9N($G%%snP1)v|~7Riq1=;{O))n zMyT^2W?lYzy3)fxC%%Oqat2P{G+Z6>I$EO{!@g|h@6~!#KcX6c^6n;NSFcy|6l01m zFmb0vN-L$Da)`(d%ETXL*bH2xcZ1qzRKTZ;cGk?TnIwcH6aa;aFul1Ev!Nw&2p^QU zdghg5BO3U!WjLqXi;w1D%7QT@O(Qh;@!|Iqp&-%c9W=)uJ`(wHmE9P(1{Qz#DS@2U zX2vCVP1x#5U=mk*-9XxDPp<9Uw0#`~lO7@0C!h-3TnoY;Q3|@wi05ZgkiNQU?yOwa z&F&voHGVTT!;)9FwHH49=66Yxun;DZuU7XRDUg8iF2KPJe zs?j>+7OFr*b<;l)w*L%Nq`OO}a3+PuGy@Z*W=5W+2%pTEik^{ zSfsBW*NG~fF7POT%_H8r5f1(YTS%1jHRuVLP-ppXE`1m;z8|wrGhb;zS8u=SxT2;U z+gczJM0+?V#?n0<6EP;V!mHwh!!2;AOw;0Vxl&oYdHtw8AC%{X9#6p3os|N`r@9iK zBd4md8acFjg1RQ*KoI>e#}7UW6w4xj0{-cJwvKROG+efhN|=cfS*&^;Q>YxD20C2a z7C*!nDklEO=C6k)*EzyC2g{*oIX8yBs>`;Q-)#b`TV{2jA`JBCO#9MC~_0E0?lV$aA@CF=3?A37jHH3yMFh_vkK0 zIIILOYhY6Q_WIDX2cP=vP!3|Cc*Z`u)VpxLt{3!DH?xaHkFG5tE}+2aR#Hy^1RUqW z1a>aarSC)6c4|J!cU$<{1eNehMQsU}oh9IUafxv6Q$ZzUbfrT6E_??rhGHOX5KpID zVOe={;yeSMpZ+Pkf4vmU?WPEgO^1;)0mkxYLX@+E&^DO+nEwdG^`CSX1j5~vs^HGh z{ge2f!-YOx&Xp;V0)_VKwu<^}Y$J}olDIW@s=b2fC)Z3zKCJCe|CtE2gsa&s5;ON> zlzhMSq6^hjr0H?Be6iQ?*BuKmYoZasU}TXJt_~$H_0kBQi&cETa(Q=nmbapR8(im=xe!J3^S}OZ@pDn^b^u`r7QYN(~3)^*iR4+ z|CLV)Y6(jt>ywBkxCBt`JE4^LZiPvlw(fa{IG~~e2PcabVGFv*t^0;05xI9r6VI=j z++9ypS`c#~$b*;NKl5FYaDM$AW#nnS7i4KujP-UU(igVlaB!=zRfI!*$oJD%E&HPH z0&uKZNP#y^8o$*Hx|+KoCI`pm?+YWl3eikFH0HoUiN2TjmAYSlXpg>F=I=tFDqTs? z!DRq@m>DrHqT*l$SjGRAb3qbATyEO;y_T$SuUjAN)rbJQq%SVHPEnm_6&8uWVuL6A zK_k)qnZ8^S0trEOxA1RAi!z$=Z9`9p7(2JCr@FpXYV@z}^0vR5<07)=1Fu9XEPOJ1-@1SbOa|*=L>R6-nLvpbvm~H2t%chp6r?c9C$#w%fp|nE= zr67vqM*6o3wO`DAP8?$@()y!zmL4+7qG}t-c`SsN31rfikf5IPjnB1*X%3qUZ5|lt zsrt+Yv-kLF$hP06v}&XLByF@^AtHHs!%~>i_R<~?Ww=+>ApL(m3-P?T)OyKT#r{fz zaE8rrQwVWfGykk9w=g!jA|MYq?4p(7^mB^Y_FGV7ErT-01_p!!7O z@quh8jt5HM_5-D1s;a$yk`TOku?wUVCu=6u5@fCt?mF+>m-7bkhs=}7gNeZLs>Be1 zQ1U&xGNvZv4^y!Q%|$N0sqOnGEUzu3@_LA)A^j#2 z26=+4=Dsg~9{2%oWh`I~&YVRk|5Ou(gi?hTP zlQV6iF!A+19@BgQIjIQ^k!YE!Sz14|Bs; zp%}pM!E`_{cl>1;N2k%e2HKA)*tL~OllKXaO9VmwkGsFJb zLP(oNNC@A={vt5~!v|hH`nD@@m{w1&k-kMJd^%Qi!3SXVs!V77M*E7(e+-b8r}h)= z!8u?D2~Z$e1abu@Y3pnGTYi~qUYC!}U0Ph0t81b>^-W@1R!5^Dyxb~TLt$7?zLbvd znL@K#M!uF%11ep z0>9r{U+gR5=ZhrV(Szti3zh)H7#;$+D0iff(s26z(>Xl~%pY@X1bErzDCVU|3fnSa z&-_sct4xOai`H~k1HtHJ7w=ogUjGY~B=+bOe?a(O6;%W?rTs#x0|un{G+VOPzGW8H zoB8(^jLeSjRQm`XK(YP7fAefbxoMJHL<&#U*2S}wB*a&IHv))&T7+H2Wf{Kb57_S6 zZl{>R8LR4bRi})4nlh@W91busL06x{Ytkh>b2lJBsKacCNMGNP#*W*LZDWtQm;B}_ zAe^d6c^0yWu+UWvhIUk9a{`MV<1vNG&#)f%htefuOjjB^jX48gO<27w+6s}Z>PS`@ z5DlMadMr48d^c#}Pd`lDqTZOOR3i>FK~Zj5;Mwq|(=3mOWl^TJ5ZIFjFGs;E;N}EC z)A{M?tpI5yf!;#PB%lu*{!Tk7_2p)WrGg8K%?}0*5Kru+u5Z`ezl)tlgwRV65qqhW z_o_pO_wCEZoowhfgTlF;O>B_bgV1XHd~}0cz-24Px?kjPTS#d+_k483DJpE)t}Lln zBIVXN&^RGBLM3-@HFkbX!N6DM=AC9Q=hGjkuhmXZ_#(=g6*n5etJc&nJW09jNm|~n zC`b}Ib{gW+TWc$mynlm~tB#!3jbt*&6}_=o^QzUsxh`5#0|# z4~?*IG;)sShAi_S+Sd8|qWqcVRdO80jHC=7taX zI>lR7O55i4T*oqoz=Hq`_<3AoJu3`N7IZwP^Pf^getVEP@RYXI@Vy$SAn8pJ4M5{0 zs$|oc%}V7G<-gcMd(W`Wyk-Y6i>IKgoC+NLIE+98deD zM-+N|vLP$tNk6BOPEOOQPM4ika|y7${4eitZ(a{t<-&PygT4bLV_kfzp>Gdx^1nIf zlZ}#o_{_h1to0z@8barMjNmEcAqjTM$v1bkQ5}Rk(b|r;0q?k@xR7%Tp3-R5dM<-y zp8~csx5Xa0uBTHRnE(Ezx%cYPd4?tzTU#v>@EIfk-q}PfckoE>v;n&ChhaN!vXqqd z+S?DnX-m(Rs=&QoApXqHirn1{`42KXF65@7Qk8Eq9FOH5c6S5;*yID}P~dVk{R51A zh6NffT^!)ylcrdK>+vU*f_0S8CP|aASD<_x_ z8`D&nPC@}B<7jc@P9v25b9Nj7v9nDCB2IJTGET(G2iw&Kl$4fQC!!N|k7PO<_ z_Y;jnwtfnkuE|H}pw?8Odi*7v|5^xcRC@c;{I!1lllu?C!=sM{hss#MAT#+i4U>BodrN zT1>?wq)G7JboWO0V8bi71CCNxI|0W4*V?t zIF|C+fbha0n@6NYuR01(2S)>R-`0(LnKz9fDYBk=L%HYXM( zijOS5cNjJXTgiGq*RLTV%j@wVi;J)IN@duEH~k*+Rg{tYf3i3Zn^|d=@U(253zW z%QA2Jna*vD*lk@9RdHSfG=5r3DXSCUT#=J^c&pc}*q7no^SI(}LsZ79_gmOh!pDBo zLZo!Uhg;-1lr_*)5Iu@TUcDolrLy(CE-zh+eZ6!+CNmV(F0@L+^(E!~?l4iNIKWAi z24elat|ke_c}TDKgjv1w_XYjXzPLCg5E~_T{z|%Z^p?GSGm9s5XC0g++pm#SArTzx z;5NJH1I`-Jyt_P@2l0{w_-lsu84vp)?I}~U)9|0Xm=|T%8lE1YuWn;(rqF{&NGFEh z_T5-UjM1(qZ)Hq)b{PXtOw9o( zbhIDrFcMJ(p8-048Mnb)N|#97TnQLJeLn8~4LwOh({yDEf_@K2LTp1Fh5qvBp;YhwDm+-9qme!>z>ra| zT}tw?_p;h?O|^0e_I1gDON(~-o($%6gVaV1n2f(Txhu7yNNF6KSY^>u(hjhJLr2)q z341O;B|VV)!;zFf`3Q;z9W9e?wP5^NGEwq_o`~k}tkm`2*1?iO5)fWc`!?f?Vuld*$-Ggfq%5L%W8cFw){vMYbJefd4BJ*h z+}AY>%%MM3To}mhvGD5F+zYmB-J6NjdaL6ae4wv%RogJl!X<-ehhd#xFwE#ww zh1=<;kgx>UZkc)Q%^(jRC0?&F#Z>idmlMP58KXjSNpwEOgiS`x6J8Q?neR!wK=J17 zL~b8lu%c>HE78KLIqY^}vWt3DR+E_VVTo%pizJ=EJThf%v3npVc!q&e4AKfBHD+z~ z$$p^2^MJzCmGo&i(|9zG84NUna(FDNXc6z%ECZ=GX619IKBHtxhsW9ybM5?J-jT10 zeu%K@2{#)O-FS;y#J-^+$pu+bZzwtTL0b*Pp(V3 z(o@|YIz0|wS*7Ss705bpejBo5%fK4kAcIlFdKk3U%>T_?arJ;A`&KVz!nx*#sAZBb zdPs|)C)@QIx8@C|v96oMv9jDRY~tDrvCO{)O^>P~3Kte1&NoRoZ;0tVG>uUC^Y4QG zUd$T{komlirraT|5*Y9+ka2|oV3Pie61$;VEd4_)Q+tJjV!WR?iBUw20n_8n+WLf# zqvoKp%6tGcW*G?t7?N;{B<5FIiNK6Z64E$ons-UI>R5IR$uv4$o?KJ=8guPYy9l6` z+7JHB0a9(IaHs*LVQuj$6Nm=*aFh(>Ub#T=5V$o^(A`7A+zBOSs+!xmov1J+z_&$` z2>ot))SNwk_K+YEPH$#~H;0vGIb0S9r4Ho*uNJD#9pn7X0dy{aK|r+;6Cz4v8^|9W z&-^*l5Y06eF}|4{HcH&DCVw!_!4E>_PnLgX-tL4mz^y8+nPREC1m8vS%@4H*Jr&IO zv(*Ys9NSO56I01fIyZ=51pXs)Sy&+hmeK<|qpYdl#MHqNu z+gGmI2+q0TN*AGh3%@Ov0HO?I;=L_g?IzvI-CctUu}lZL?(G5YH`*UNcDhS4n%>)J zhv?p;6ug&lTldBTBAHVl^ zpgd(p>3l4%+bc1^(=Qb(VKDdyObR;_hFYb?5`&cHGH0Cb!$yjZ;Ns3}D7JZn3%FE= z%_Pj`Py%IJ-i(`?^#ALM-xW6@7!~$-vSKd_L@?eI7Rl9G2nR6zrF{&Shkv_3O>)T9 z!>3xX1kgod=fCQnPaOuV97=?!u-KVpVz%178*9A8a^0v+M2BD5X_BC`6Q%D>f**uD ztzm-z8V&~0Jrq8LZ)8WZiNbJ(Lb#YA4n))GO@VC6x|wTU9iPxIoqbniT||!iJxZy1F8){E7s(yM0C)r^@f~wxf!@V zZ)ZsQ&zb-HfvTx#;j!SHh#Oi`%;%Ssk#q}@y^D<0#9vk$Lj4JZH#p@;Pe`g@%QvJR z)C&6hslE+1js?(!rk-7E7IhC2p<<2$t%dPCDB7#V&W85>z*2snzGY6LNr`>D4pVbP z^ouIrl)XhEU9~K($bj(T1GFZPYz0^o=fwOnBYC?Z$UAt;rN-9(dK#2o86N3@AzY{= zu)!UK^B`A{ArlUIfsuk#%xMO8+9I)71PeXHJ+Ru`$#nhiZ4CNrVWaV{OoM{mb!ZC|pKnf%jei@M zi8=$fN2CBLF`bV6`7$ScP2wnz8)D!rR4#l%GemU(j;ZxYGWkf#JGYkG#_X0ld)vXv z+v!(e2*J+`#Wr`kGk5x`0s2*SG&KYL3UD?K7GGD(5wu43tf`PGPr~}iUg~DIeh5$v zRx=GTN`7Lfa5M~xVLZ}4hkW?Tn;IX}6we5p#JORQ!k=9KS&o6a_PhTKB0?Gt!$n5d zDv&7v;n0gc@j|+T{=2=qnUW30A%Np9rU&`RC_Q>z%`tJ8^=_2;pGNDqpH;k~YRNYG z9wDi#cza=lw5a0a#Y{zTBNb)#e~zMncwf6<^}w9@g9JOcIOR5LzS7JWK>$VB+*%Q+p&$q1=kOa zsVrqGVlN>ut257YXZgeof#dpsa9b2d<`mec`Q$jl0tBGcw}vi~&vR0~?$(sqfgAf@ zojY@i$;+)DRPfeUfl>Pv(Sb7IC|s!=G%;@=iY}ejY)^uwS})(e!TvbaROGHI-h6k( zAzf%84>wWdcx5`W$Vihd_0IO@jMU>#GwPLYOKXhMK|RHY4{>GZm5C49qN+K-ggz@c zbCdLjB>?2?+kPoeSZ=i+L-U0buiaiB_S^~xp$w&d+s971f+7(jo9_{uO=RZ1Hl=IAxay8P&>={3yxG*XF{pKN)`}dJwh`^;%N4p+sW(#3OWr#Vm zA|i@I_p+uo$8TDa!6Z2yy1;32Ok|ipPQe4>!`^*AET5Kl^+-Y*!b&;i7hv0Iq&6#b zM0FWDX`d6HJW1T;lo=*&`VUk)?yJJE5wN@!Ltf#J`l z-OEt^As$=RXb_<%=TE0=wQLk)@7Pj87cS*?WNj)}c0aloq`V4*A?;0U;j~1(#nw}n zy|t#i0*4CikTO`UD)al+wpyTw;nj{Ea!qUaF0aZDg^@W(SUxjMLHk~+X$*`z?LHfs zQZ|_Hkk`w5@%X-sREAY#0gCj}1-@0xxsvO}9_@jUmfaIqW2?n%Jo?YD0c6E_H%;qr z`H1{pP*kmo7G*6OE~`XuSXW|b0!(LiJE&DKvFKK`)ytyJtk%F-ew%1MF^byq^fC+o}|OVbbd8wMw;dC(On;GH~|IYV`sw!+J8Sl3!BrV2VIQ;`z^iBp;RrU zZmaup<%tWu`fF7)zt3$&N%L%3(Om&J)YT8evb*6C?O27nms|k9Fr&1lD2qzZ$=GxA zbv@lSx7X+v`>I>np6_=!dzNj@((3R%lX=y6?~EbATykg{IDg`_`*YED>Q&6qTe~$~ z%Y-}H`_YBpUBl4kdYv))TZj8Z32F6S;x7cKWYThfNX}J^?^|}Qzi`|37%9R=3xEo$ zv&Ae;oz?e8_dA5BZRV{@&H}+fmyAm>zSn8W?HkNPa-K$Cr-WoiUnXcdOf_O`)NlsU z-xR(2s@||V!kuS*5^ssrq?AD#+-xh}DLqjd#}=Hs)Qb|^LkbQ&B8Z&de}GYqVM%2U z=^-PXLYLSpVeUP{vT?XyF{IhF8gR?!I|s&gsEkl4!vaVS6i-d2LT;I&Xhg|0S@gjV z#i9c>Bb^V-{(FDq>F~I(i)OSJ(EgDoxc4&2ayhn)Nvj2bC3^70mP;}#4~q40F(D@{ zBypnZc-_Ffx1wbX^bes!^xv1c(&I4{AmkTbCO06W5rU`zyOJ4OIFpEIqr5OrZ90v(|#RWZ^bix5X^rm#=smbH?Y| zvnTF_LHt?2F-dZO^@er>><-OGosYuONh`%H#zY1xifcfwG@@4v(JZJ$>XnxDK}W?w zE~5kDiD?ZQh;&0WPSB;qq(we624Rh)UKc*FaFJlfT69AzSL}y8#yxd(bVT`A5w`Qp zODkrTz{0dnp85Y`^cewsj2*L949;iNTfHNQOMvPG$x@UF+Z(z0*5Sh}U6_CZD?73} z>LikSn{JppOs)pbSH8JE2?PqLu-DB2*Ja;0L}!Vx04K)1Ze`tqzT#|bA4+{wv}-B2 z&01g1tOxOVwS!>rh50b3=D%ppz~9nj&^qZbCsxzri{J1YpvJ6oDydue;$_ZwyVsV_ z5}@AC1+1WqW~1nx*%SAh5lc7Io0KYdMu6wGOk-The`Dd*kgWsW7H$%BPc$AW1=bP( znFAd#i8FR9LxIQFB5gGfBTKdXln*cKOXIgC0;NvX?||F&D2jInfcgBCaEu#+{w1_o z0-Uc!sP)+gsZ!RSShk!y+~9U2M20vQ?X2{yf8< z63H;8v`?>DfKy5f$l1}Fk2(N&W9C8#-x>IMUPeTvBBqmK->z!Tr}%)EuzN`e`QQJ~PY8Yx+6vTTl^g6as59eP=B=@k4toIsEvtTv z*d_v4J{BW%m*Tiz`H*1~7x8WUsP*Fe)ZSy6Sht}J9n``%JBcCaFw(ejbJduLmDHMQ zJ<%=hhdJm#3{Ox^JH=5zIbwh88kgKm#tDQdF`#o5zj7^=_@D(x0-P4sX;*k1(l8A$ zm_Wb@*8c+Az9#7o~+7Mch0pDueHfsLPSo-2sCDirZ}8Z#uw_BB!pK%5W5ha zbvUO=yl#U^t1H8lv^^zX!MDnbTL9p`sbB{>Ep3KosBXGO^%T<2e2T5=8e+EbKV5!J z8d8lOd zOyJl!tLG*^rk#s zS(eN%&JRWFK1-o=Lwx(g2tt?T*$6!_c4X1;yD*Ve8(LdrODiUMfvWH};x>QQee!V5 zkk_jwJdm7;Xv{|sg=A$GYdkF&39RFi^p2lEIpDeiw zMb$#}T#>fSw6p$`Hbfp+oz)#Wt8O5m-uR6Gs#*`K=ymDOyPLD6V(*JK4@-tLz)7St za%s7is$eAKH@kriIKOu_w$(*?Vk~`l+0{A9ir28nr5qTvVtjTj^bZf~EmPwSCGDHk zO+Y$rV-bJ*m$2u5o`@&gjYFxTQa1a#jO|6X(R$p$<|~CMF~mA$D=@|eQk3;V-=k%B zdiV!xtxZoOMWH@jnFDJ{BA7vGv#G>&nO#(W(E+)+e7uuY(#oC;P^N$dm#Gx+9+DMY zFT@AI%-^2CJe3HUzZA6um`S5%r$OF8w)a)|ZGY-6(F(1)y?BO`j>ha7P zKm|QmrW%RL_KwWA5bqfv6@i8XO^j?UL#L?D2)j{5tv|GJ>L}UK0mCC(k7%JEW1r5h z_5|PM`@G@|tfmW2GNxKv_Hgy5gjM(;9}nl-)=#InRq+2aovx?vAg= zqzw_K=p=tk?NqF}KiVXm;}a60JC;iyjifQB=ovr1DJ(GgrBTv`pFu1!#@wCv?yfl% zFh*J=9UuB8A%WK3@Eh&$7+P6s23o|DH~A9a-e`5Q%Jsz&;lPd$J#N-3xa0rc+Ln$m ztt7cS)Q_9cw|0u~>3?zH3`|@u0(?c*i-$sET4t(vk^fK260a?owSLXIBGTYlb&i$L z=l-j1iu`M9p0vd#sNl(H_Tq|*-tPdHkx3=vlpoo6Gb)`^NPxfW*@?!AhLt_ z6KSW`E@6det%?nzJLq%>HP`(cFcF1WMGPM?{jNe(F@hsm|BBS*NJ9e?$I92heZ6l~X?hCU; z7g1n>bu7O0h1sS#sQHG;C;Byx>y5PSi&);Fzu$?d$mxJ`iCwVrmqUV49Wx5iT$r{#gJb zuc=`R-6{daV;#YxvQF$TX^UD9jUv@KVjU`|V{>&D8=JKI!h<4Mom@Sj78>YHm@7U! zZo#a<7i2N?vfy0~+YmyeB(leIp3G{SQ`@nrD=S*0(3EhCHf&{kxFHt6m~KdShzK)a zMP+U5cMwQ1VC0aCRg70ZYISwcLaSAoX*F%z*^9qmG`Tp)zgT6b;ynlVjDo|9qb~$+Zg;(8jYpsg+Hka`bYwgH@t(&7&OeaLDB@Auk@cl6euMN%W7f6y1fLwzQPb zVIy_+t_XF4HO&FmKuyyu{U)5YN$@~reu2}^_qkq0ojW{A)@>_bi-dPi(qoe@%DzjWqooWI>%Ua3Wv62+6;(**^W@RZ`1$v zi{?q4j&~X?qw&F~e*!sy>4CbL-h>o(J zn+s>MDm7Se=Cs1P#EaM3Kt1!{f1GrVkiP&_g@i#+jyAW0*AT^pi-fL4?#Ixkdl)7E zMarB^Q-pZoZO0qP^(P4=i@FHX^c+#U9-`qefi@oCTm0ZNI-JhOR;6N8!PG}zV2Y^a zy&vkBbbUxsEXHIyo^)SC%a)7W(ogd4NI%n|I*&{SPLP@h2&#GyI!*vdPdPqv+E->8OtLpKDYnQBgzyZI^JfaI0uno($CQl zJTP)UUIjWSWt{IK8cFA*4`AXa5}Jf+p6G}jBD-h9*R)CCfTSl2%PpcoEjX}DE3hnt zme58Ch`_pjvtuW;vB1s8g6e;l#WTHuae4bOW+rt8;aujnlxhC`kVajwMHN(D1$F*e z7{`3XCBZ&fBA0hPs{&0}dT932z+7>>i-L>>V+Vsr zfdX&s#sVek_1^xh?4h=t940^YwI){0Zu=Y?Rz>Zk-zH04CQBGYd0z%U>cnjoZK!9z zV0lnO+HPVZ5N$mhM&?BF^GID4v{9jRk8aPG{r1Dm!LB$fUsqs)frr^ixWRk``M zQ8pykltYN_TBF@*UogtCQ5*R{>zwn`k4T&d6)k_P*Ywa)^EelDt2cl>lU-m% zz-M+J_uu6NI+(-ByOLJ+GYgfK>=J8idtHY2Y>zXh0eR#FmI3rnT1%MXK{!lv90_e#IaO}PY^@@zitHKYU;43qmkQr> zg3L=kbhM}tW7m+y_m+bTCVQ8(;I4+TpzI}56!|e+Ae)A8tetF3Ec_C$_|@+>B$J@P zicJQ&coi{Pp$Aj7eo*g(Vh6?&-Mg9{4s<-Udm-7T2}J%1FZKW=prFR7l+ybO^ zQS$LZws#0~`^rVXQsHeN;0_#ZYE1-RpACae0gi)GQ9_m*UcXNl6ToKq6L_YmZ_Foy zjg<3FMG>vWbFjlhaR@4=9Z8huUku~sfFH<|d&(p%gOy!$7N?Eun;H#h9lC(T)c2w6 zdbkPBE*FL6BAE1}hDU!=0?`*LcRViF?4m3wl7p(UQ?odv7*@bb=4Djxg(OG&anKXj znSOQys-z-AUr}MgM3cKtpy?D-$yC(LN<>lNQBr$cBJHV4Byx|oScA=wfis;sjBXPl zB`Vj$&*3wwFFruKfV0+)X9mt6LV%(ho&<$ggeWqlev$6-o31|u0f(?_Vv1%=KR9T6 zHH8L`>N^2MW6gy9J6@sf{o5ht4WpPAMJkZk(P`b9vlPY35asP8N90nba)CfBse$w5 z1jm{&Q&{r_MF_<4{{RgxVIN%{c*v7DGob+Kh`Y>{ywF+q-1&quW4Iju(1*G+0GT_U zv0IKO&AIf`J);)?>b{UdcbwzWq=T{O)2Sr3UsuEZm@3W{?q_D|&Ne z{=642w}u$iB0murJCxlYqtJINz$N4_2~To$f*gyI*^sl*vB#9-%lko@FjP->>huor zVtOw`pO|dTC9k?k5xA@TbH!P_H7VG%0p{(#*8&kTT{XO6Gs0x78lxtP5&fUUgbkb# z&lzz9JL&8*^q&S`zM_l+&sl@YeCx8)6*DAa?@5pXG}Awym1yN|-VfU4uBbhIH(mr2 zh32Lv;1FPeQL`YvcExbkWU^f^6bT#BWc+A)e+>=La?sOwyJ~d_Fh=M(H|H(GxqQ+9Fq6gSoj)g;ac9rAyRd=@p#(b|Qa4%*C0sgrM#IWm7IAbyr zC5&Q9l(o#zpzJz8^oQ zFS9%BU#CstFVUYTp>RV5Q`sQlV-A@e0XtYgrR(<(-J{1Em<%g**PrJI-MqqZ|Kjr| zis|uDFp3|5@AWyJo?uCXBq#LNLzBeTVy1JAvH@F~&LFu-dUhZ{IBQ}!K$isdS&k>B zpgDD5{L>}R?rrvjJm{;(0*Z$`&RcN#X-Z{Tv_AAZZ|1-}3>?_Im)_(Zp>D`&H^nv6 zbrx7>)7L0+xTgPLWX46pa2q-y4`6a0FLNKf4Q4BpaRf*C*g64jS)bUeuEhR(3iQ(r zI4++~g?E_6yDk z*mOVfGcmvfW^&Ih*UzVA`isO>5yV~TZ&oOY3d2kw(+daH^b@k{R!?n`QV0*%rQhqz z?g)RD>{zxw=(SK5@=)q#{p+x+Ok<}RLmR&r@b&nd)kX9&o#MYXK@^>7@FW5OEant( zR1{y^4&eR5D(TgPd=n)f2}V>Hmm(PtO>>XtmzArO+h?7X%){i{m*|i9bDTZ<;;t*x zEp_?Fc1K;7{<*7j9RN!}w7>f|3v+f3zM@?b2vI#(dr(K_h)*z6ykv_BlyY+4&)}GD zc!Ix$WBz~?ucR67z>_=Su~{F3DpsgamvZXq zss&pm@Bh6Lh0HyDU6^c%CWi0auFb##fYwge1mgEv3R()(Y_Q!ZLptMDZAF*yX*QWDl#cOGSZ@Y`MIZ@c# zh$tV`ofu^|zff9~$T`}4ia=(QrT;Y2fT2ez3!XgCoe_yrMaE-v^DYW}g?0LEv2QkX zcjowe>0Z%0OwdAZv}4Ids*~>~vYFxv+s{D|IM#)%%?-MjSMI?&%rRz$BlXqt-UKv{liGk)@wBn@nnr%f@1PF0$7m zU%#UtEmFn!*X5ohFb@>;xz2t14Sz)7Q7zp%AF>7Qo;!PLU(=NT5d7F;?V_r{L^H5} znD(38hOM-Fs6hL-Cf@pL!lx~mIs_K3jAs6rMtk;lEFz5PtLUYnlpCD7@Rd7wugH@ge8`Ts`_9ggP zPEfeIGx37^yRPuDVxeXLNu-`%3l@IZQZDGcVg#f=fRuTX;B-ckqlLzG(iaQ9dW?3SUxm7RLmRDA#$zdV^!)3~7^i)}Yj>@?1LJE~L9iBbZe5=)Y2A>L1W028L8lRAf-i$6CMmy2el9UFwHWFO@A_ymAe0*cG# zmWOdTVZW=H^)Z;Tt!}+uV&A{0(gb|XgSIO+t;=v?DDm+@ar8Xo!cWz7IVvdph#+#P zNm{z1yC2L2*bc1ZC=L?rS|uaCUEUz4NS{N?y<8JN{~W-1;z-dlMaj?w^Lk;qOUeBE zxB{>cK}|4DPR@ID_z<~Ba@nEN^`p>!7!8tbCBjg@13*cFlnlEqwPX5O!m05iY0(r! zSGI_<-Hi)b6`ztWmPGJKa{^sR0+&Ra-FQk;lF7EEF`%2t3d{72&>m?0bsq2bASz(< z*}_Vr5s1=PG?6JFy7;}KP^VRC17ksBD0v@C9$27u(sov-h!Tk)`?YuvV2tKPYnI|4 zUiF@*OSerxh2&>lrRaXdg+d0v@C;s2m(EKtrFBY3$!nQaay(gLPx|8r;?1yg6#|~T zJ)iHAL&#SHMxAAub*D%mj7#AK8U=Y}5MMN*OsDXmtB1Gaq+)UvuugFSzfL}+K@Z}&@+I3s3^zB)*}5fT_?qrz>@(j5uBHEv{bymC6d|KDzTh9jIv!GdG4^Q zbf!W3BaJqZ*b)(Cz|`WiG9vD7z!3@@ZNYiB8zvLij(6KAn~eZ$W39`nKtTF!LCt_;*xqqz+PX?$+Y!W=84pG3o+Lfh(c2F4%g__Y4$b6k!j|E- z<|{V-2~e{$G_?+{OB>(KU6eJJh^anR_D+)2&_lsm3%z1y@)~8S7@LM4-e5V7^L0F| z)0}7J0oM(Ow#EF`EC?Io6&y~BgCaMEpR*In+c!CO#z|a1_mB6+Fhr29jFZ+z9Ezi*%F)7D;WPvAq zB*C_EoBx%`rJr-BF?s!Lp1}xJ7L* zEk{ne59Os+<#vWeiT@Ag!ERfK;eSgw10t%|wZG9=?P>O>;SOySq*HetjUd4kv!)9> zW;l*j%*^U}oGmV-qb-t!NY?L&g+x1};+TI0Hvn&5LJr0%8$@L?VS%Qzq?emvo)&dc_*4YiUR zv*>l7cA%9+K2-dNy3)S5%C9aHg6E--cR4o<{i=Mcr9q~2VsvCow4{NoTf51?apAyo z1`FKcX_kGA(OG|F=T>q&u=iU?`59PV^ssB*&+|=k8K2ua*miQFahGa?2z|8(xs3ylECyY;-Vbl8Ru?$y zridZN8$0BZ%Y@F84(T*xh&M~qD%3Y+>}*}hDF(W2r@M=M-~IVNAHVgDFgfE++|bdZ zKrWN4)(4WEXH8Ks-82Q`Q2am#(KI8emfe4Vx8M?93Lh#}_WKlbnZk_F;8e3+zqhx> zJeO>uZCL`1b)6pMrz=q0gl|qd7%4;`kgs^fyxRc;^yPvbfwL=||Ep-|%|SmSD%Jp} z5u6plR5uch?@P>Uxp=Pht$am%Lp&J?SCv;h9Fa~NO}9(99WoppuL>tYDK zFG#q<^L}EBiN3LrV33yoeI;#jC%9+r5|zPrHPPl$oeaOuCOjrdrX=#xlqd>voBl)+ z3C-)@V2IdQc*E%LkMzA)#!U~bEkIH){DR@Te;Ahgd1Zp(o8CJWk@Cd?bj$*)7Xls+Pp{yU`8SY6P%bu; z7&?Y9qdr6yPp1y@t`yz4oTZ?R+sTwpRS2H?n#=8I^EsP$C!~g@NRle4{&nI#-h67L@+{7 zVa?KXqEkcQIS7%cOp>_ReGnk$b1=4jP6pW5{*M*x0{w1{yNR(*H7dOahag%OPYbyi zEcA`M#-Z3Z4}PMpb3vv3TS0hyF@|#%tZc~hGqW!(gI*k+cblC7%8W{yI-v!hP{tG) zKPB-#rNEUFI{=J-hiYSU2TbkK(H-`mw)JW?;Gf!o;y!gKTsdk3;OkIIRgbc4|L_>4 zP#QCbb@&ZCB!LG?aN8mh*wQo&e5-oIxt0wD`OQJP)MgkK2DWE977EEp5dUI}L4a)u z9$)L0t%mJVrm6B@4fu$?SSqRdMHb8dipj5{#&@}JKCXV}8dmP!?!2BYTI@f7bXG7r zr#hkkV3%Z1N(bMI$6(OI;m8j5!RL) zz~48K5axlC4#g`EFReYU!#m*du>rtsd%XsL>3^`3+W<&-rm*ONPR_gb?3Bae2j$mc>(il1K+FsmIvXHCa|eXGE~>8)tr}W7PMao9?&X6P;XNc%5A$EFAtVK!Zz@~TxUvEqAmRILyoGaD!2>lfq zbVJ@jw#w=i^c{yL0nqs2A*yu$5ekFgUwO7{YLIH?ihO&n&x0>`&2>N6aky8FraA$Z zEg@KV6&d(fJjzCzuIM{bF(C(X?;^=*Hq6o;S^GS={c>c*w2Co$q|y zmv0FjD5dHfTzh;2Ao5N2Cqik1fX_W`x!3<>S@}7vfgif7@3;p+gGb5hKrlQCJ|sqQ+00>DU?FAwQVy&sFK5=Cv{rMzNmn2^_DaPPGm6GUL~!NC&ny zbu`qoGpil+3Uh23IeY|sCaKxxdWa#t?KBE75-%gPH0&DtGn<5uP9Ciiz!Q@dpe6Hw zP|c&6OXCwCp2x_9=hZSEsS{+F{%yyx0&7SqReJdWc>JvUPzT|5KQ(4BwlRAQ-@N8$WiW z*6(?U11j3WrKzgUUfdh|P5irGj(^tFJm6nUR&eHCFKS*{omi?f6lyfX5_BYbnp9sL z4Lxa8(Ovv)8IKde2>h9!N5?t+;9c3&nJA6kAl}rbAZhW;h&h&GN~_Cr4wQ8>p+`*Z z_hEyXVu<`Z@V~^H;S@M%!W7Ws>|T)n1e2unQTd2jwL7YPnit0pRF0o64NA<{GK}d+ zi>S`eP#Dm1B~nGPM5+8Els++^X1)I;$v|WAq@P$SD>qx`i`UaVNE?b}jj^LnPMMk3~|kjd!FJ zeTT<$(EDzgR&UUyUUkaxIdTsl)>^H>%QW+2SuVE?EG)~Q-C-Lex zstted9#=b4w$ibkk9iH!V&4@*d?ftxje4WI5%3($NQ}1Ex0dMb9n0K>^Iu37wdz6w z%r4IMkIkyKVu~pmYp~Ut$f+Hv^z|T=-@I1kM0;w+60*;0F66*0vmvNY@Lc)K zN~>30_)yqNp)O_mrl|49FL(9S(cc>XUe4Pg3~$8kVt>)QJ}0DUIZpoOIdvm&+qrs% z5k+SZfM{p2;!6D2N}0vKIk;cJ%j2}WY~qy*!4Q`yc{2E46R*ZmVH2vD0PCE)ebqZ8 zAEZC@h-QDht^D8g4<(QHr_T$K%uwbOy25)C4U9mzUx&*2*HNBc9``qR)feB1ICh}` zU8u^@LwiV&@Dci^yoMG7Lo>FQdygn3L`v7JG+Jvur2?^&imZbyuHd7uv&nz7dPt4- z?fx?vWn;nL;~e{aX(*WDOY~jx^7!D>1WU=jX1zQB!$N;0iZjM-`fnsEp==Deq8mqN zM{UqnlVJ{CxK|+zci9xMcdP;Ep&dvmHDZiYt>S`#&7C7q`mJ-K90ujT)|utLbI-HW z`Z))?SMy`unMzwO7=~+Yb@_0DN1d`m(3QepzpC0t0!W;rrgb)FgN4&j2iFvoa=pJO z5}o2S=>ubAH~Swd^9@zheBuz=_FR}s^sMU!cS@wf1?;`k-JCqf-7hdc&F5l>>f+Gn z1d}RCI6GbeD0yz|b4Jg1UDIM&7{}5#vgB&>4Xbsc99ZYAEPnUhRd3g; zN})OOxoNuZdC5WlS&a1T%cRHz+to0|g-ex%i65QhL$3+)M;zr3@fie+k@Hd4>r%4(+Y*z4pxj zWr&mo@C;m?0B-wxb*)7xDCzg}nW6EM(=)>p7tT9WxJ7Q_D3q@>tYfcoW;E=x3f7k5)42LA6I(`W8(?2`=(ZhYD%5d&QaPVLF)CWyYYN%Om749OK(nnF zACk6M?XiEU;@%jEpFwnbIP6^H9bt`lipo`cJ^5UO^tQCXz zTF6L|vl>t|0f-mgr+(}qRmXL<1&FEzqK1iTR+1>(&?X;?lK5_lw_z}RSDqr4@+EE| z1L@C{b*MGd;u{@hVb_tjP^Bx1G+*WU?=Uh!pUpWTjxYUX-oWWqfXuJu7|0s$*+>K1GOqKMO5g!&8*02+^l-m#y5ZAg5Q6MjODq&RN6BHbL|HIkkUZ*NgtLR*HeE?lu*{l zqK6fee%cs+UA88Jg}bwn;9b~u7>l({EL;1(TsH*lT)%RfC(P$Lax+gLj93F zpILfdU$L%F1Z+XC-K$b+73rp-Iw91m0vpWyRa76Bu!h>^rtp1I9}Y!Z2WQu(rx;En zm6oUtGDV(d8V^ywUZTZ4ZuI+9-`s_z;ZaKWL=aq5uRERKmc#Kp`xt7+$g3GR#D~9C zT?IUT{R3vW>;g;l)aqpRe&hO+q=jl}m-A>|i_FAD^rookZ;ik;=hAY87adrxe;hr% ziBD%7?)=dezphn-+&PmDuz@gztGU}oj$tCwFD-wV-~#AQ|gZP`y-tkEBxT3ejUJkpvl1>Sb+x)HN!ZZ z18d)vjUhEjwRot(?5M3)Ly-O~ZYjpm?(HgV55G61c-o_mHc?Q^wk{0u9 zUp(!vM)>s4r&sUEg>qZQtk?`tlJOmc>(a%!b|e@|sQ-)WJcSPEsSWXrydDX0Q~m zhywqzn4wot66NPSW6QK8UtZ}?AX#ig@%v0G&*5Qq7yy9>pTE+Tb@>bCf!2+35xw?} zH|zhh3{Pxr+6rqOVDZ**^%WDB9c7Z#s>ziQ=BhoVYy8x(bB27(VkVo;eh^4$Ee4EU z_Ue=!x-6;S#xaZ~DMb=C@+CbfCHl7H4|B<*d)l8zmM7(ee2gHiaqK|-h@bcHC_NVn zs6p8UBV#WYNgu`qa)U^iBsZ+N3yk~h=piD&Mp-$`G(inrw5rIHD4uip!&bixMTx)n zvQ(4E$?@t;-wPw4v#(5=;-TN*MS2Ru?GXPG$4UrcVelBHu*Yk`PRQG2nuiI8xixg3 z|9}xuxe_aGafKh1@vF}ul-x&QkwQ`+Z&1Ou^gX1qZn~&_Es1zqoydahP%r_iSxb1L zhF3JblaCiL41EM94inqQI%mSCxbR)^=f<84L%tiCSB=u^f){gTC_+L@V0qtM?5+uOg)P zC>L4ApU@67OcQdAba+E)s4Y?IU>w|JNzX`jac(m0K)N(blG1pgJ^!V~!oMI8Y^kaS z^gZ0#1XT?#g*N6dQh&$+eCp!c%6T}km5sot8C5W?2Gkv(_&`Vz;9n4i(5c}~ChV}9 zpp|SmHcI7K_<~NH`8(o93rPrS#e2ES%^E{0EeNa-ORWUyYzu~A8{8BTn~~M|?;WD` zg#0hE-Sv?2;4hWxk|FnwB9S@aVxraj|Gc2A7#|@_@aH^YLKGa;Sq|oiG^OJ(xz-Vm>u_9fsv^}{b`)p! z_HjQ|X+l=B1w@wJt}JmiPY+##+EA%^L z_ePt)vnSDamNltf1+SG-YDpGG&c0cgI6<|L8#HuYW8}DPDtlt@Jp$uX0G0{Zz}E;* zn#63FGa7#2)z{q4Gq~x-jg&z*O)<;ALRjzx2+heVxZLQwrE2@uU;Nxk00ROCnGI%E zm-G^cmEB)ichRVT7ut!#gEvyZR$z3x8m9AQgu&GNW|^H~-axTX6r` z(;SR@Cr${ayDMAe?cyl4CMxZGpal#7-@Zo2)c83;ruQSLoot_Wjl&^-u%@pdGexE) zLQ>(>1X9X68M`E_j=dlAy7<`S6tv@JmxEi)t1!Nt&<6Y2Ci^synl)==avY;iwfUJ& z@(%khL8u>gO-kd<7Z)0Dw|M(dYf{-no3I((FFePKr8j^3}WsPiCCA^5jv0=j`X!K)T2cznTMW6zrsn zSzQHe`kqoqWYq)iE$0lAa|2%M-MK9bEoCj|V&|i*(FgM{?o|@~^w6*@yv*w{7Aajl(S#||Ib{_(WyF;r zqOR)Pobas)-il8guU*aL1kiW88_No$v|9#+`xHa5nRR8x5=``Qr9O$(g44s${v8#+ zsO6oSy|iu8f{(L*GTz7A`AH3~Nvb#fYO!+3dtgsa+Hcuy+aNvnz%>u`(D!wDEH4zoGeIk z+$;PIIi%54?x@24>v*k=s2A@}SEIp?Nng;sO_~-d7p+*sTwQ`nf`PklB~o&t&}B+i zGqIZ74ge|<$4OxTu+qP42}km8?tQljjlsTW_tuJmy74MQttgTAPX}1r;4le!KtP8^ zj>ZTpmXAlI`Bl->ewolAd#YsH`yVN}VXg2Tf%6bnkCH77cj9B+Y(5WtBe-AJ0qx!3 z6bQ@5u3mjL0j`)shm@YhqR@Ab*_7zNs}`%F#j!~bc%PP?8Zx$Y`~EWZuAO=r%IM!2 zvQO7fr7c?Ziuu)p`Q|#qQikv5BB|!ZXA&e5C6}s9g@XL>K8+IFb5Mmh((wIRrb~ z@LLGf&+Mmy`!9Q;I0jSiSSpPGdB&B3v`juZJoKXpg=ufhT>Rtw#A6MkKCVGK#2s^` zshDakAO-vGX(vLvwGL@t3N3S_P{Zl({>ryoKl5Ih zI(*}DWEv>m`rC60F<^AWD@WeVIdxT#Us4v~?6`ZKNO}0Ek8=Wwc?P79=e95%!4t^| zck?-OA_u;mxK5jk^#3)hyQyZB)J-YWY#c}NBaf71q?utEK=xaxpuu-LOBJP?6lyaZ z_t*XApYmyQ!%n7wwJoO(U?M%OKdJGH<$)|!cp3W^ST-T?w%|u^_7r(Y3{?~d-2#J4zq>(dMBf)9d7D3TrFV;J$Rhn}(!ow$mG(;-qG`Puztdt+61EVsh zJ2MOKFosJS5_%kzgF^boqi2n%q5xez=uw&Kmr5qjnb_Af1Yo^UvKt3LO+S-!qtSf#o>P< zFpf#g@=Wpch9GPbm$ht+CJ(oHSeObzztKHe84@N>E{g6xMaiiH4|+Q;%q;A#9Z`34 z!I*1~9DMUqb+WHyso{CxYLZZC;$@d5Ua<~n9Vp4zx22WLzbUS?5%bF#5n}H`xgCCpeIuX`#GP6!cV^-r1@4Qh^DVgN5lB!^z4g7p(E-UB`f(@Bdp=B0HJk0E5X!GPOjTb2*(TT5*vco%g=+1pF0$OYP|tv zNvUGS9>fcnan>A5sZfB4W5!(}*~_nV2IK-@V~|}6n1ko7RX@<$Bo1rfyA8|=b1h;z zC(O6cCxsWM89oK0+A-4HU)Jy{e~X+1(POSoGc#a4`}-#Ositau_Wd4ClO=n0P8wwD zH;>c7Y($DJHquCW7a2l9&P+|R&16Ec7p3_P(R(*&~1YJq)WL9=@yvu zPhK1Yuwx+$)T^V_FL~4ci4p9RjNxL=DQUcrGBpw(d;D1>|JiWB{0|VPm}MiiWM#}B zdU6s6ENDTwM`1?Q!s0J?ij`Bf2mejPqWLh1ivDn@AalwBmKet@uE?tib?gH?Yz&Zv z=OnG~iEl5CQ`j(bI27KC(Uff1+7@z|o~l*-GHb1;*{teMx_KMJ?gv6}MIa0tzpS3V zE;6LAUY|Lr{cgDyj23eXeMppp8QvRTx*M{)aOON=s!W}rH0+^*Eqbu?75~iXT4Vpz zRu>b6^sby8_O*W4%0?-NQyXfOVY9-_1v_7&ex~a#rIUS^`R{8W0u-Wo8ae~_nGXi2 z?mco%beN$Y(K_#z5sMKZDgJ(qWV2aUwVy|7D{y$d*uHTo9wu*lbHkkC>gNO$w9rQT zW@d1PRyh&Gj*e*_l}3yDF5pZM=pbKyHc3>YrPFiZl%mh+(<|(1Zq6!-`({IZJ}*4| zd_oJA>*zfxmj*d&X^k}7v(2wTN$gdL1np#{(bu?9PeZP?y(aV)o|A@(2G8JHNmJn_LgRRM+jM% zGppP#8S())D*jZ_I@uNX(18yO+!n}zzTUpPv5}a|VV_N+#nLQ_A%m~!L84@Hvfqyf z!>0$BKCtb>B`a#}1F*KJz1c9&@tc_+MF;0rFvMeX-022r>q$pp-^+xULxN_*$e@IP3HqCrKM~YX9sMFVTF%z0b3lh12HS&I z0E3#R92@=)V7fA|4C0x!FuW|mIIjm0<*b0rSbHx8J^h!BS%AxsMB^JlTykP=%Kkml zY2L|{c_%S7(&9~OpMQLAh*%q@+%tlbS2TtAWklcj^yd0BJqoE`6gB^b9jowM$&S>6 z*4y{VArR@$02HI6h3wWGoQkKKkBL`A(;mR_Du~wI^l<=Y+fqXryil|FHe}<7@s(2R z$QVpPPKgzPGZLdJ(}hGZ4PS%GJ*E-&681@!fFzEp+UV?}cMS=P)dC2mQ2=E59in{A z=8Ep}txQC-+r~%e9&--x*mWat_dy7sYl)rmhv|2md&(~E3K0b&q+j0w(Y5E@V{e6K z#Yd%dpE%{61jB-I^KI(u^X#PXtZwP`>2}(Zk#5t<6=#77UH;BiUU0e_>V*mpa>|;V z?!(V=6uw)1gf0ut0H#K2U8@TGLq@v(d<0dMP=6@Z1HzVd|A=J;p0|9*{JvJ>qc8VkDpSNXPHW z9l7BJJH&qa6gnZ z8y{qHRCk78z1m98_qTcD*eiT@D`I|*iE)9noFV0}TkK2xLs2A6wP7Lmf878ie& zr%8A9eoc%%H~cy7wt2U2g^ivDKcvMtikdvOEc@d7C9PL#mwn~Qwq&ABLFT8e*}CF; zW+J@oIhsQgfiP<>?L9adTGwv%L3__uR(n|zu{^43^Anh)<&U^m9r3axzwS6;GA)Z%)v z60r`L_pmz!btqp4H(6_D5K@guHdtMU9Sr}lQwQ3F+dvDzODHbk$fmD--cX|w!hAi= zFVXg)i^ZO?H1P)(C{-@MT!_M+j-1BSEm7|(YdHAOwompGtAf?cj^dFRfEjqnrD1GJ zZ~CdrFEqx8c&hd>9(q^FCuqhuVK@-%D$S%KE6lj^xS$wS$o#iYj6Eqz{YSGK(!;o_ z)2oSYB=H8cC52#@X*$E8iCbQMSPLJlf?2E^r8Ip_9)E*T%;i4TqEVA7&p^1j{gRW9 zV)ZlnXBfuFfTYrqVyFQa6*fINt!ZzEC44?;-U;g}Rl`(4yqr=BO-8vN*VbPt79u~) zJvW`GQZ>u-#3LD+h2r*G=Dz8CPIc6Za6i>OB936Ag$LPafk9e_xmxP`dRYhu*wP-t zIyF_ql!nI#cbjDO8=6KLyZw8=7y}4P19e~cvzL!VRNRq21@a`O2R%(eV&W*DLA{_; zx0weX_*ZrbOK!2)GpC~ZMrAX@!ZetCelJLPfm!7d&_U%NmJf83*d#znl5Iw62^GO$ zeMX~s$ws@wVkx42DPu~>i)zajASQTkpNp1(JB&^Y9M~PI_7J4)4r=n&!Eb1c4({;2 z*Db(RQ0lDxoZ;g0;E?(?BG2Kr;PRLFOFd)0t$!P^0hyqUOU~^IlA-WpL{K$+VRN3C z?mV3yF3=kU9pPspSkR98HPe1@B<8>iHi@%b4(`{BRK_GqsF$uRlrKjUdd<|xO13tr zLDTp2?-4{CNAar*OfztZ5C2;~3sP8UD5YbhqB`ksV%GRrX5lK?{Z0NjOR>DG>b+{+?`=4e%6mVSXi&ySIdfvW9k=h6DsaC`aI?G>7;m;|!ZfhJu4MyQ}Bcq3D~o+g+rVX9czYf$*}_R;uS!Y0yvF`KNH?K+q^Ux4QduW zE5VD^3Yre6;W7UYYzn>7$<=1T7b@h4qKVd|1o>o_}f$Q23U1DILH zpOa4xib(B&0EZTkz$7hjA{>+WssT3r_TBdi#@Ub6`SO z86}@Ag+BS`v3jKj!^Dm!UfqCh`Y@VUuhwei=|*f%`bs_3G!41oR;lRlWmFuvZEAg-HfM|lgR{wgIq-4Dr$co0ETn^5{vtRLgco|I zdjf88Z;eB+#^qRL9Q^}~@Z}#bXgP4De?>Z{11wK?0Z&Nd{ecXH#jl)}htEUNHQF(o zBX&6)W_!e<5cr`wXaDb0fmFh*rWA6$GyrZ}uAB=QJ?4bambSUKVg zqzxmjIkABI)yjl*%`rpkaK}=)5cPex)RdP3JV0W1vczZDW0KAA!~;|5Pgb5{{vQ}v z8Pxc_?DQ!Fn6f+B5Wdj0$O$iZrUmhX_Q1I%y$(U?0cTA&57&})pr~>zX9{KJq=c`! zA=TMY{P~u8T|!OeWKS1`x5saxf5V_ysEnshc0EXLw2{q%IMcyYv+_b`G6Vx5-UlPd z+Rh^m>S4Nv7Kn1E(u7Q4>@Zf#A{1yz z)lf)>o61`qzLSl(eS!6u^@v9gz4aJpCpt}5S)&dcBhS!ajUM4*wRS4po|)nRtr77- z*A{zKOeuZ_jPGxC0+*O?0JR>UzvsL&QDU^XqZf zOk+tZj1`K8PZ7ZB;SJ{^0|lOXEj#tXN^I%lXD8OEE0GzzzaM}!1Az9lcp(rVKec|s_`wRILe4a<^QXZ@Gy=zW!Y3K!uJ1l-HG8IcO(o+%wbL=O z0nEiO7lLwt8mTJ*aCdY-eJ5UG?L2}+PqA_Cevc09L1K%BNy$Q2r0hNt|MTa_TO#~sxp>A^844KHF zc=o}Loqvin^Vs!NK;u(gJ0=~VyD-g-9!&A(ioPuBdhl_nKj;Fr-25o2#f?24pDrm@ zjupwPTv(WhBftaaz6;K;=F`c1J-w29Dy4<_LshE-4|6=F5|%=}LH=4liU4{IV($`h z?m%?GBUs|Ry6hKd(dr;JTz&g>*Jn?eI{#4Y@37qJ zVFT0l^52ll@F$KH?RuTBMzHl3#_DF4SKin?|XF5QZ2qfdw zv)HysoAGH8+)&X@j$uZyGNw2YF^4F9Bvgt+QCb?b(4=JAzG$q`Dq#4e$Ebe%mp|Sf zoR&G^qcKXIoYGEMu^S$=s9apZ2@3Sn5VZ`w0&L(S@UY5WFlixUBy`#eWk{^cyR8LO zi1Th8V~5&B99I$ntZ&#-%=9G(%p(D&nsUC)p1|!8nvm2MEn8ArC%yO7>yHT0ikyu9 z?~7-mBvcT)nJh|;#B4#G#?ToVv?uX;1Qb0o#NYHYHi4_RlFMu7!;a+^9^vyRL|DqA ziw`e5jjMfmy2^kKok2yS#5!Js77BqCpxX>M!W3ANQ!VCf0)@<*ueAZi+?;r#=UcO> zg{0QfdZlujEZq<)Rcl9R<-UI7q7p&0+$CbLp5PZ}8eeB}(He&~BNnrV5@zfXp_8n9 zj7W7%8{EodrmQa?{tjUD%{dn~<|83H7P=x;l&iq3-REpQN{`5!MoyozmK0+vO z$R-`w=lL3_>jQky>aY)gQuOoiqfrZ_`Ey}hsG8>y@^LY8NPiU4WBWm@bFlkdM!9~g zXS&H)MH69PJ4oy0C2ihZy@^GF%+w{^c>v`gS=@|)H41DQ9&QDHI2ONf40+LLqFN&s zrW!c~g}?tWRPMMpr!k%rF({EX_L=cGHx&0ocxQ<)63cC;1fXb60XK1i$n~LJ;9d=3L@MkKCfT z#jDRw`&48=LGM!JT7LZhO;lGVNpVRyEBheG`Uo`d#YfL%o^3wsZS-E60ZL%$2qr5( zeKP$h8#&END0NcUc8|*+j?SH6@ZT&oJC?mFT}?Z!6m>R2{uu(ulD_J4Xo5-t_UexbWy- z6oKm#mBDL-QJXSO%v~met>M+cA950TzEHVWWMLYzee00Ez4a3g$@FV zQb>%Z%)VWD{TxT7Vj~%n6B-}RDr*9*Qkh!%kk~V0-t0atCKvL6H963g+eeSKu(3;g%;^s#pRrs$|hjx=(Kwoin%qiWr4h%6&F^bs4fQG%Z_#FxX?2RaiaY zj9|RdsQ;Q zb}TYYzUtb#;rZBUt62}IR$6Jgfx393vV`G!Qy$!cZ~Y^8S6kpQI_iS+jSkd z_Y;=j(!xHG+9a8gW`b|RH&cLV1Y7qbTFf_yUoups0a)IL+HH*jWp_{_Q0#oO<5k3EiUqQJ&gcEohF+iGU8 zFg45hYC@o&H?GPuNR=9@;S-wzC+Kk)&I_+I&WdlAZv`U;sz=>!^c&?w?S%?^7!6Lr zxQVP2G?F^^%f2<$>AYJX0!^FPvHB=Ya;Fgc%C;ogRG%w@+7-nfyaPPnz~~j4*H1e? zypkz{cYOHQ{X~db2Irx?&5>jzaXKh3?r|(m8hcf1MI~RJSnS9FR43hwez8_k+m#|r z9-^dy_3fvaWyS@0S7J}LI5@vf%BSBc_Q=N9{_#c{I750Xr*CxK|F8Bl;vUmQNFK3G zW=sAq=NUb-82g>i0AFU=%**oQ8@lOCaYYvw7Y^}aHz!%s1l~Ly38?*)W$+6;tbu@4GlNHq>)e$;E1&3mq64?YWxLSE^MgTQH%D=^< zZb@zm0bp=dZ$M9~c93lTP{rhol5UO9gd{*~W`uyZfvijWmEp?rh{#ys6$TrGjR9uw zi7Wth`~0lYMM$(nebM_e_zF~l`!FW~_=R$M6V17GOH1A5VdO!y%g*Pb`D1)eI*R$_ zok|EYwrN}3Ngs_CgK=QVhysaU)7uXJAF^Rzs?)+ z2zERGd8-c{`zG1igqp5ZiQo7MoLEW^H9oK>RmtJL=@YroI=P%JtledU zlXiBNGaTz--**#ulo3m@~m+GTR zt?!7E$Q>}X{#?Mw_=o}*imd}D3j9zop(+_BgtnxHw{MjO(2h&Z(nqa+`E(4o*7VG2 zr9lmNN~%^T#1xcK)?AE;!p@J=d%d`yp9@o`QeX87s`5&(YvW8?$Q6iWkM?|D2&$8f zX!9wz_Av#!YjG{>1MKxVSPs-Bm_m#D59D@5re%Hn@OXY6#2*s#R-&jsmhF($X6|_o z`clSzX&sFOt=Q7q?4pe9$_(d@V_>gfhBqCm-fgf!z-y($A}gTGB=rmTKb)=9M>;9dK-$Jf%F=?GXuL$fU_rlt zw`;7v;{$ane+v7oP5KNd3LcJwB1F1vT*zyrnaR6@GSdX@HqK{qA|+XxinI<{p zl^5R0`#z5TSJsFODv3yT-*3X_&Sc9F(VowIpBUm~UPffZ3(@>)rfWO;Zd$I=K%Q_( zNfqrBVk7;CccC;;hJw^wJIJr-nGD!MV_oD$Alh%jLss#WaQxBIGxD4-lATlS-^M>n zeiD}PvDN`Zq#>w5L)rGwd9OF!iOU;WO&ZQJ0bqcLu~TqwgxEBW6zV*c4F~R?|E~UXN~fNXraA8v@rqQ zQh=)3N~t<6E@CC(0M$@HIkyc_|gXcN_FLb@=Zc{@~ywQ&KD zrRUKG?av%FMD4m9`0M!(_McEW!oi{K)ikO4ssjriC&3`T=j`kUE1IA-b+ zxjDrzDYyl#$wsT{@1}}NKDxIG9M2}cNl~oRt{p?ZbaA8Jr5Z^ig=6%LMq6U9&O~%R z4ify14vb6^yP&div9HC|IB>KAJQNGEqodT|Ld>D-cbOxz-g;)h2`V3x0NrLReeRCMB!)-vnLoLg(^B`hDbq z0d8ZbnCP3FKjb1i7$*Th|AwJa#vG;fIWuJYLWYeg+j_;C7JxaSatf=JuF&Jhc?`ftk}NzMWg4C^5=+WLyg^3Yi; zI8^zUf%E{uadfRjamm@@6QyowA4TUE>J=(HctXD))m%daw9zVJ*X4Dd7oX`m~ zL(vm-gb$@LnbIpT$Q=1V`d*;D7JGLa`*nnLK?A}|NL2QwP0iXz=_oafRh(R|4ZUl1 zz$7TT`oWr9jS!;EZiNz5iwoKZbld+DF~s_Ibl}FSiN7w zUdPa(Z#@9euP22_Y296@{N~jwI5)N}(<`a3sGFOq#@LSa z#0u0I9=y-JB>i$Yoq{>e9gML=5zLb}_`D9_GNeDwK3tR-+stv>p)jbpDqS)AAs^v9>e4#Ne@h;9mvce zq>uk*Vb4b#3N=eJS8-_BCJP%e=RI3zvqF(3Jx-~+{2DalHP`f_G{w zQCqplMLP^HxDlbSmJI@Pgtd-}2^BR9E z^PB(8LJB6x-(3xwT6HhDDVqFZYiN3YtmLfh^N(FE|>=Ztu19%j{prdt+*Dv>=IwjR6qgjyY@bAN#( zZ;+lS>nAbT(llDK=iXzc4HwKH1-53r9P-E^iHuRqFrI5+wWH+lb-|Ar|fS zfpwaU4LbEs<{Qejvc@XzBpP^oQ*TBx zsQ5CaOM>mkr61=u`kpMu5w<^}gqRoEHJ{TDgAsKqE!kMhn(czFWtQZmGFQi+{1waR zat4`LCYbjK{zOe?W0pS9d?Ag!IeYpIoU8!)GvKTpXDV_C$mTQ8+$P_I_co-WIxW#X zlVN%y{@e&~(0gH(fCt=?R%CJ+*ne$!{jli@lr(UiYO2Omx7;uPkxb=?_hTCLTo-rW ztSsF9Nse-5Q>$BrR@5y@!%O>kCrVh0+T6*i*@b{xBGhHU#=euC`RNQ=WKLu+G_!n( zi;``^j;g!{-2@c78N=tJ6$2eISc}KIn>Xw3LI+lX#95QI7fWZs1Hej~up(OVGns^T-*ItW0OmSFAeS9-J>$b-{?LNVIl~}7O3-r5u3;~9=bq-Wd9{*h zZ)1$=MGtH76>*Uh_xH4REyw^0>v{iw83*>j1Pny)mD3={H;@rJVt{RY2MXCRB9~~o zHhH)1P8}*3THoU?qlDWascDOr9-;e%YH) zpx2sPAbR-)`o8j95%3_1V$FV0nceKNtxY^R7BuIVEWD-%3I7wO{J2O6~Tvt5~ zGkpwX>DeFHKbpde0T;iJ62pXJ#nj{il?<5N>RkF&vDn|g&6v!ssvz$w)*Z<$g*%pz zFC?0#EUfF%5d@q{1MymGa=Y(JUVE%=PoU@Or@w%058k5d9?SoTwZ~QZ5tJG4c38@PvU7I$VbB@_i3;8)__Pz^ ztkArfkM!KOJU5}+=u`_kBdv_NhmnuOC$Y4v;bu(BoXI~X+f|jU4R^xGJ+mqv7m!GV z98s;R{ZxTEGb!8_)Nb|W@Hzd)WW6-!iA!?SoVQL4uC7xl*FbfSpjp3`azs zS{gn2+|g9@Db@7r(1htnd{wX4+FilnViTQY3mR=InL9CJa+GMjHAj|k9}fV#^L zk8P|(ZvEDVBYP6PBhaFJ4Bfj06UO7qjvZDw7{Ry&)IP`W_mFk6d}5WDi66s&M^JDQi1=Nf zm_)SQYGJ2WdyA57cs@je+w8`9K1?Gnm6mV`Aj(rHWMoM>0+0gWLukvv@`oqg2LRDN z(82rp_bWMxMwUsBk44&PZE|jO&b_F!MO3EDgKRxNh{lYTkHcIEa6NH|S%w^ozyiWN zifeH`v+66v1jco@1a&J3(jG1< zHE}S%OSRYz2$lM;Q`Or1;;HCb;KhW%OqG*Z4`2CCe01ZAx-_T9f31D-k6faR49W>3v1svk-g2q<|jn*k!ds6YD+cd7?1mJAS zrfP-Pnwh5O_Y$b0+zr>2?x&Pt=W{n;_ehwiq&`a86S_Mg!YpP~3m?&jg{ZPRJ)bBb zQ;U957ZFrl8+hx~yC(W@EH=8a@bpqh>kCIoqLhG=xd}}gNOwh7Nu$DRRUc3^=3#IA zXaNzdm-+)vR-gogc~!#JU}UlFxHVGNIaKO|JnjBU&&D=eW4xKUS{x*?LLi8nBl|uM zDWnpA5dr=oXIgv4H&DBUpsVQD01Kay57=DJI*86AoT|-nFW=cOIO%rN9j+*b(ASXv za&J6kXTB~ea>oGwNQBgfe~&Q^;o^tpyZT3Zeu@ExfNhN<8?JEe?j+Sq_}^CW$gws-0K-fG`Nk8aOnomq^D@KyKJ zkA$HxjP>YR-SHQHw1lg8PbT6wI?oG=-C=~8V?Ze!GqTPqPo41imDdN0r#EAnrg3_4 zI_xpORih>yG5EV~sVN)Cki(B4zp7x7Q6N-7RuJr0OCS;zCY27l?Ui&#yOQqlo?08i zG*u>?QRY*zTzSxW4c{jryQ=V2BF?Pk=AEs!4YrNq!AJjTmL<0J7A?2Vauv9i%P{Y+ z?*p|;YJpOUNH2v=D;Rc8O5loLOv}mUr*8`Gp-}98)f$`uxC%>V)r889A4syB{pFlVODndlWn8D2!Q=wctnFj=<=l?a@qDFyX zd>mXjOYUo zp-05?hc(zbqDbS!3(_4?@kJMIs>1dQs4q-m`tJvn-}*UyR#FKf-r(yAVAKxp598oD zEa%xOMnxWWn}hKobGyfcITxs$bK;+9)F?;i*H3`+l(Fx|1ZIkUo44cKCw;T!zdKg2H34E~e@;M9&BLpC=D`(V|Q| zpy#~6*XNia#*d6z&DG~IF9Z(Nhpg^Mn7j2k(H8r}`cVw>n`o_U>*nb;1176(?JqRA zW3P{A(S`3|iofvP1vz#RkcaE0ayG+poCyIitOI>QtEAx0c);@OGVEoM?7Ov3Vyp2q z(Ck`nn3{m%yEvh^5sS9>-AJz@U0pRmaEF-Sa}VJ7p`Camdbpn7>@(i+R~#)DvXLm% zw$#y}6Eq=9o@I!XVA^#NaYEfCb-`W}V^} zkJM1kt0U&JqV5xiDcCeI4$>Zf1(XmW=Ha42M|5(We8z<|E7~4x%1FD?hKRT zUmCt#BL-B54x7v3OyOSznZ&6p8u|OgJA3%`RFJRc!b(_}4R1HH76kPs+`<8J54JI& zNCcqWLl)$;Sr!|;Q2ugrV=`*SvN#@7M&WWnF4KDs#okDo&dtFpf%s{h0#29TF(|h` zSS1uUXP^QoYYknJ`|ChBxRE8NdpjKdOkfn8%zy$n!qYi9PVD-v<;x?!ivN71ckng5 z)4m@fDd7f*kNEdBw_G&Ys%G@u;fg<-(-5|kLOER2Bdl~T4M3rmR(q>aw|VlxXkKnI z4JHSO70$jOWxVD^V;cx?jnAUwd7M(JG16aoPm^>!SR~HHGh>YJX>`=!`VcFWjFv( zrd#4jCR&j`doxfMtASD2F55SIAlC3ZiX@K`UT_?#rij73qNkTbFSDEb$4B)hI`Iic zaA(je<*ZDJzg9C10KSCrr+8wU$gQ};WJVSv%_PH_;S1?qYFSlO+Pavd!}IkejXyQI z=7CmA4n4=&`neH71^J=^=-GW@E`_qTr!U&z!^-&eSOC9BZ;>0KyM8 zA=!v&m3Al?`TMDN1qa0aE&Vedbs~I$37%wE6`o&s7@Cm|E z3jwRJFFw8DuHM>^n50|^5pCC6Rmz?}Gta+E^is)?F_ZoKP=)U>(Wvcax0R(us(-+> zJPX<4U?f9jhf?-_fg;AoKXhmx$YVfbFgkrdQNf7S=#M23j2@K|jFhQLyEOr6W4&c= z`c`gr?r>_DEXQBaYv03Jy~Ee!4QaIYz@xqe}Uitn$H3>!dKo9i{q=8&z!)fnSgGPe? zoh6?b7HS~uJzF&xpJpXLy=wa$%H;$+GycZHetJr{*a-X%;}r&;H;RhCmDNN{_2GwT zxjgXatp$!2;ZRRNxa2Rrl~55+|Cn*Z(m0HB=FM?YKTHzv*%#E#?)GH}-ypa4>hKN3 zW55hn%fqU3mn7~u=13zfSG#~Hqlr;|x=klsfai)+#9=v%N*Md>W`VMjE2J6gW|@-O zB9DojS}!jwmb;o9&mpJo;bucTHc!z>s2OOyC#p#0$hA}z)O5=;s6B4pG5{M88XpJKUG@fq>3qtHTkOs&- z{SE2STHr9--vR8*Z6YyQZlPM6vf5q@(7EqP`4(t4eL%Ji-4e*`%W}5> zd5+zFbS1u3&8!)WSroHy+BDn2Uh?|Qr)x1Ru1`$6H~l;HoCme_@ZVUYG1MynF*Ju!3T12KZjJcB4tT z)(C@)y}hfVg-ncptw`2|ECg1vR^Ccjq8XJ}dsONlIT}jTBE! zC+K!^6jY{0HL~-v4fceay^v>dv(#@w8pp--)HQE|&t1;7hD&}9N1EcD;Z;tnO;qd} z!Qwg0ZaPd&0#3KW6SZBw`s0w3ca}f0IOqvCO0|092hvBZP@vUmSDS@5@%9>ni@oZ= zI`YwBRx7_D!#wQq6cCoAbv7SBvplkjpA;FJHbd?@G~R*LAZ}qw!}PrqX?>^=*bRQn znllsKu9~e2%yr=vO*1aBF;C#ujYvVhTJ<#`7JCmz*H-X`*1Bdq_wQip+;8ZWiz`$) z<`&rL)_hqcMm#L)%&Mje6|f#4Nx( zdpKr%RY{NUaf_t6x-LltLl2H~nuE;u4DY!&_`q99aP`d4?YJwbd>}Y5WQ3qgk_HoP zmA=@g>gJAm6~tO*Is0 zb8jI~fIl?5OTWcYJ5z(9N39R`LP(K4#YHo$vZvT~p_}_YWPU^uy1c-b4s!uQO#tY9 z9WqKAm_Qg*{W9_z`M-K_c{Y*x850Etx{nJZS+SGLeBNS;lg&g;wsWZklxMqMQ_3G7^w0Qsa$y}2Z*IZwvEJN2C{J!+p7~;N=y0{ZVC8OO5_Zziy15sObFtSs+;-Xf%pb(K*okP!UzM z&sni2Pts%f9FMEAJT%leD@VA@x1h6!b#-{die6D^3-sU}a^`m?gn#d9bNio>=FW%@ z9Y>s6v@?SztKc9iF41PVMZ)3-_g)hVjUAit>0Czy%CT(|mE85Rl&v>xERvm! zq>*tT1R-u`rq|AGA31FdVwSgQ-IP#dQH>$yRWbe2zzfq%JtRhxo3&V)%p8Rxr%$gX zey0;f7kfLH!ql*EOkTS&3IQHorhxV~GEfVot`po!)JMrY zpbmvpwx@{I91V(#^R)Ow_SqtQ>bK;~1ag+5BH3L#lisDeewr4__4}*xhd>0j;DX>7 zw`_N?iXPU*`6B&MKk+3m@PF~dC$IAc;h!{IOU7A<$UH0JJH{GkL4yGHg0T$@uP=9} zMp6&#{{5Nd+x?ACXv<%MIG`r$G`~KTmBjMZlKu^Ydn|_kz3JkrI#gIw)BTM0huCej z9mqX3vY(o4y7!$Mon=LWB7Er0-7(6BJQr~h3+~4pHcvE*gBB&mk2CMAYLYa5mzFe< z)Eh}tQC&(V+L`b&ZyoP(0$_%8uubmih+zG0N3|1Ne0z|!Ge*0Hi|97B?330TJLhNU z!A*IwzO0UFa}@+;d*g!4d@jRR?zpg8l1XLfx7KPpLm6GZts1>wnEaK+59o7ppt@kEe7m@-OI*2O1B4U2!pbOA^FdB%#km#QgD zlc;i2I!uO5;g2_#y>>3+wKYu}tHo*waqZ&Whi=^JUKD?LC!mGI!eQxCXWTKPVBr3} z6d!np6AWz!vuYGLgz@sDYYa3~CUM$*#s#y>sauZsam}4@)!Q|zv%TL@v%G`45$)n| zUcZ;L;qbyvEuGh5Oz<@un@Xtd<)0l%1t58wN(4QanZdG%!)tnwPyf-I){xmLjk8Nq zD{yW8I3l*PIg?+V?~a8OocygMiKr6Ek0Nj1@C^-ThgeH$xBCLE`q}%eDDYfs%Zq=} zkwDNGo}tf7rfI6&52b>O-y}KchR%P(y!w?Wt z$I*B!*!Dr4^mKHjEq$vQeSN%-(t!rR-9;dKVjq|s-z#jvx^8KyuJjN}y=g)pclc-= z12}QSoT}tmEh(J#N3doz5D^B1GVZu1ZNQqskBPt!l7{1JQS6 zV+b-hwf;W-<@$VMqis83pG53>=!;fJlcEbQ&K>%RyWHtHtGF7mJJ)%b>kV@KEKrnJ zrvVAbkCVjlw`AsMOF?E*k#BBL%1ek4Mhy(rdg=s0oDblM(o{*4}; zA9hC*WMA6%Fz@`giX~hw)J9xa9waY-<~L%TQNlPb!r|}OCA7XMtFq=4fw$}e`Zl`6 zaeng0>^BxUCG$k4uL74ltX6C0$Iqd$v4-9-Ir+an^IGFJBZSL*;H-F%yY2Pw`c zzIdAgu3LUs7(b;@BMBe^QttYU)l>3K1G#JC_63jr%alo6`cK%ZKLy5ggxYVc^1tD* z#Bq)cAUxn)ObmZv$UHEniUDhlEp68Z>$I=q3kHI|%=03N*BYmzz=g-#gw|8boMN@2JSX zjRV!+icmUl-Ixmns|-EH?yf|u(vM<{XK@b|MVc^7H#YrLkODj9O8v{^TJ6^jYaM?a zO;c&ECTw$OT4^ZW5RrEv+Tp<;cvSXu?C%jj42138#oE`tp_pHi6!dS_$+%b^gg_b)2GV|mG0Cpteu zeP6Q6yZpy?oAZ$r--L^@U=_w*GRj9#y4MgHyb(sk4i@i z{erDTU_D=xWuvzkC&mC(-$$Z{wr`}Uf6hp*D1Pa+Oo{T@$}r-LM4g5S*-%sC>v+5s z&(UY;b}VigDd;QXSoO&$Zf!CbQtHjcL@mW7$U+UjVF9@RuPZR&H;BbHk-*lLGJZLb zE!Ok4b&|q_y)p9N!(?H{pganisR150Y`wE~nCe%>3N-C?$rvnQ$Rmup6+fFRpBt1m zkUx-}V=z%*V647kTPU1n;x!$-o(2WHWY=j=Qc?Fq6^P>ZY7N`fIWnOMa_0J5G*(sB zD}(~x9+f2<2n*yhTmT)4>^nkRg0r2!1mN4s21*lyW>!P+gQ21 zdSue%!iIUs2vxRSuAl^0C}43@)j$cm2wO`_AoLo;GOCkQt>Q1e?DdWQ0RuBhXUGhR zU&TGZW_ZO96qx&5NtMKQ1P{&Gzt~R3VkILZYxh!yR9m0z-QpF!IOt>rZ92{Z7qI2< zq*p2|#=X}zxWp8&Cl4P&kQ3Z&EA2GEwa=jjSRXMk6gEa@6vUVs&g5YbVc>Otc;d*F zoP*i6*0b6Ta!~nSQ9k@g9jOW3HI`T!lHnB^>(Q0HGc9(}UBlA$^jpfrt#VBZ6xydp z7+Dp_cZMK((H;uV`Gs{a;Y-EpkN|4AWCC;}sEEHki7O;(Nm!`{+N6b7sbFR8B_TGE zgVU-yO3;wkZJlNO$~8`fpl5nY1R~2>CF1V<7y4%cKw(*=Eqr#Cbk8~br_m3wjm5Fd z1Ih+D$>+=3R0Gmaw0=uZ(4`+En-5(Xj53{niZC5j(%n-e*3 z&D5XR%Y|hqXJt_vXpCdO2dkXfm~r}suy?5=mSqR87%v`V$&Zu$SdQZhDDMlWF zZc!m)!(S`0i8FPHij#?B|B%<$$dtx7pT1fWt_5Sq3zmF=%^+ooZIw$Xgzn^v->Ch* zSaM};GEI4;(fN?&3|R!FmiKaFEV|Q-fYOW>tzC!f8O;<5(NRhf7CS*y$j&x~jSRi$ zobf6DCOeWaB53i&RVy|JJlfnA!`)3*ub;&b>67)G{9wey<4~Q616}kVEh{T&f$@*7 z8#TC@xJ6bAxuK}3Q8`SnW{#EgX(Sb+-wkUE%MKPoq;Q9t4Vx%I@^r?mt%iO3!msyuF+VT03&9gT?QA~o=v2>B}1+tYQ znjQd!?l~qmy1_6n<2bLD$i6D2r-8=hc{OMR3l>A@-$QgAZmNln{sBYtw8ZNTY^ctY8l6 z)%{rQ(aH10yfER8395SkG~my@pQvl`hMY13nQ>slPa^Z4sdK{LNJaw?f#@v~(&(@q zizmUywZ@fCOjusp9gK;1i@+s>(IvqHu*UZ-OsV8W)6wlM<6nFf*>F7v(xoCYTswEa z9lHlfOp;n;(}$bQ3_OElmNRSO1B$eS7odNhTr`GWi7 zklOn*%G~w}^(*>z>5y4F54y_>mv%<@-;48p2($YQ5|*x+!6xA{6hTAJPi1=5`9w(s z43*}+tDXav#=7XB0b5|blLoDSFV_|d@Xvr~#wAt0L#NA>c_=*KTKB1IQWVTsk*q-< zcpD4o^u(v1<=s8c93m5x?|%F9sD9XJ){|C9P?-UfztM z>D?Buo}Z=1t>SM(bOE#JDIJK|*H__DLN-p{Vkvet0b+FUHh~0gpzit-XRCJ2?Rc8Y z$V-wo?grjQRHbuf6E@m=&*2QuQEaIq>Uu}&@EX2xiwVOqcZ5ZVD<{6SE&o5`P`&rGwN1%(ses>X1`GRCZ0f1ZDZ*}8R!Gb6Rjzo;b z&K7<8Mp3=zaQ>^wr@$=eq#YtG$hW@dS+b6>Q-7A8=Ohq&v6gc!Gj1SCx|f4jHA|i^ z3iP%(NR(iIQeWp@U;-|xx}x4phR;~Fb4**)4=Fyby8QVD0scmx5L_Q+Rrkxk3D%Tq zl|r+sedrJaNQIk{%ZM^RTte-7nwu8IsCgSU$b55Bg+Vxc2P~Cx3fdKyiQ;B>4x;H142*L zyDq9v8!?+iPUJ$jERUphRmX8tEJuGjEBE~%jk!a>d{VnXUWoYSRW0*`z6T3Bse)Kq zio+9!+`-_yi<*&}#-Af9oIop}3i4#e(ryu9T4v)0c*Ch(hL z-D49NC{h%7WErlvSmMgfc%ioCxp2~*4yBIvpGt7`J6X))Qt(TD1u^k`#*f6Er>}TJ zl^nAVHK;R3Dro5;Pvdm*{;K7FcAur?X!(XYw$R?sN0WR~xa_X!c$GHN6eGAG$A)2i zNeNaH^^?Hm3T`j=IU3*7uQgy^uQ8S94doqnFlVxHQoSWs6*PZXdu-br%tAVZFrL0i ziH9#~SqBW*q=enpCsMbu^=AMZ^4{EWuSA&%D~zKP-lP3dQ52#awQD?Yhs#k;kxK!p zUgzx3;$agHPRLg1r@+yJlVfMwLBLa-gG82af_=Lrey@5a0pj62|zW%P4g@m z+ISL+6B>~y5^>#0(0sq8w*i>?!HYn=?TL;1);G6WM22T1dMgkYQ2OGbz&WUNty27`4hQZ*(>8!w+7H`FmCQf*Q zE^qm2B30Qo${whod@~4*Y;FiW@9oaB7_s1`>~8cgCLvNf1)#M5(U)Umet_~?;`cEw zEnLILcDOI@Rr5Wv4B<8RDOOfjgd>xl;tcBb&zfTWubH>3krrcgV(Iua=Dd))WbJDtC|GDhmH z@X01~J9r5Ef3Gl%FWq`LV#^0KmjsS)jG;`h=aLA*$S8$}m4mSNWjv1r)uCZ+C|A^z z+Y{+*u7`|Zndzqb+v0ieaC9)!r7@9A6S$rZ;%#N$Z2;7-082gNKTu-#;A;$x$;T{_ z)!|;wdjSVhs)s4YGQ!~32zhNi^c%r4q48)0tgn^=zLg{rt8me8{|@6Ir7`%1NU z?7i&mY%^|Y^z96@BWtmBMn_D{TpU}j7;?~`H>mgI3Wy#iCtV|#c=HCX&A$4a5sUv2 ziYExldE@Vo--yHEyb{x7ACq7!ro&3Ll`#M*UA~V9VBChF001(WE4hPJcPUOcR^)9X@+_|f$gb++>@UtVtlk*AZ5 z1RFB|RhB()mmXsJ$p=O|?4r{@At>iqKIsCA-u6Y)YH%3^ZzDScy?8MN42x_)eT$`M zfHV@8Vqaz+o~98!e=O$0K*SuvbXIg2&h9R$mHB@4rIyi;>$FH{UO>wNFYL$)aM48m zA{6y=?WC3@K>b0NmeKg*VP^S$Lim8s2z`o7C4~9yS}$70{5((6jE?F6y!mVRO4W zF(N3!O&N;>)2{FwZvsVXVCK|)h|LtS-+6lm5TxvcW_8XAtR4Tp1;E9hrfRa@?%VgL zwb07rku4BbXbG8Vy|-7W%9V1F9xlEy`fzuv1+%;sUz_2sNTe713}$I_Yy4(~uM&C~5@eV=25 zpyNuP{1uR%!iB+$!Crh!$#(>n5QJ(T+;#k?Bz;H6DPdg(qjZ(HneW>5(S$IZUF${O zO;-k?Q@Z6NpT&}Ab(0LSZgK^!#LA|-sP9yHC7Qhfuae5SKAck0qcjAV;7hAuN&Cvk z~S7qdr&vRhElY4CR<79Yj-L zdQ#Z6{o!3is=#w-Jd#x7V7$Qai))ayjafnLAaZ))!-(%X`q5@Pt0VWK3r1Vgz7zn8 zfjy(95ogui6wh0NQmBBO{4v}?)x~aaBzSB!&{m$>tDN_OQG*KpwR3HfF-!@KaZ@nV zII8mPY_2Gz>3Y%hFBdh^agaoNaYB02{452VMwF!T9_F23&hZlJ>Jq;+r;_ zsiFj#%~RGKrB$NT(R1$G4*^|#;O$akFyd#|XP`79HvLo}`>12f?LEzs8zftVcYG4N z(8#xrXe9y&Boi4kxZJZOL8WAh`)h>uhK`a=lEM!#@IVnZjw?zH(DV(sAibM>QzZV< ztJo<*NP`!qlzE-cjy;zTSdL7tWA{Z?E96YcRlr0S{dp0@G)9r)b> zDZU!dPBadaBT44xRbTudqUrx`=enw7d*<2A09k$dzJgPsRf1wz%Z*G1z%(DZ>~2U* zrVHod8$p2I_-{l=d=zg6?)pvT+Ori-%cZ1eqvU!8u@)>p(COAMyatZmF_BtNjN=ARJHtCr?aAG#i2&gLlbqJrrqyY3GvPkiw zFs5L%a5!Cwga~#@uqs6MUL3Mi3s#3E1fA0AZdnTZMt%ke0pfS<9W< zxv_D;$9kg)lPQ0Bu%SG{_aQOHC9F;^>fX_UXZL=&^3n};W+UtB9ny@po_n^Jn*DW5 z3T)xTeT{3A%5T$*Q6nA=CMAy8G&~8LGccq-LhYz4rX&53N4xWD$*2HK@WS{HkO44` zPSGm851u~&uEOcI)t-|77K*PFw?8a!YxFg0$Ms(U>bs;DQ&ROW5LR^2i@Xj$5{7+J zF1oavE##eB5d+%YB?DB@Fp}x=Mc~iLWBg0-T`abeZcA{!w*0>H?>{))KpkPzwwh!y zu#2P+JD1C8sYHJHhcMDlVSM|^Q4;exNQ{CltzecCUj?)}1!PIPjTvDZqj@7C1MD!> z{jIvivEa-{5Bk(c7VX=CbF5V7P4voU`KtQMyZ}3-x)A!HZlYNf)lQsxTM$36lo~P3vC`Ch2_Z8(EES7{blgDe0FNxj&Dc){w_%*F;|7;Z19^APgpe_ z3Ldg@yJWT+Ks2|q)ed>ypMeOQ{5EayzxGY<4c{iZ1^LsOs;%}4mo`ypd6uC6lIm4_ zkz&C6y(=m}Y<94vojxwH0I!@kT|0>;(EP53&2S@Bg2HMZlkbmzeCe&Wf?nj*E?95N z=*j#n*me7xYS6TG!e`<4K-oNTm(L7{LO?pI_Vt6h0NiN@j)QCND9B33HM;*NQxdO6 zP8_EZuKQM)&1UnXLQ$ylP7AdyU4vX)RFYK!fg_<>uI@>ghO%<)YI16}F9^C=gGPiU z3h<$^9r?J7n%THZPZsJBQ&Bs!XdUS{g_EHgAbr5a$@!DRLoLguhmFzT5_nr_b3#Oz zh99Y%#BDa(=&UG}jS+qO*+O5eG4jJ9;@6pAbe$j5j(u}dN_v!Q8{9 z<^oH42+C$M1KODt8)~9_i4zhY(y;IlkF}%G&mrmjn#;g_|La5oqFO>-wLHcXLM&6f z(5~Wx0@%JD+(#vXc!e@Zfi@u7KzRs_0s@Z-53KvCfQVH^{aG+-A}wrk!3If=vo2C3 zztTSL*A9!8ca=W~R8ut--j|czwTJgb#Kt=sc`i;?b`ZHlUA9-WU3+XAc>{nJQ>~r7 z!8x(k{S^I)+%$5*z;n`jeZf1Z=b;Qpey*$5Ulzit;#o*f2#I@cM)xXYJ+<{zvy}d+ z`b_h@3j_vO-L5r|0qz@UqK{1ZaV-dEYJbrW)_~Ni3m^gupW28rD1ZT=KE9BBTC6&{ zi=7L5P9t9VUBSPxTWDp7gk+(sx?0ya%;-ugjYWUK;SDc*qkspr^H-|nD3DTOJX3Cg zehKiS8Uf~0=wjzdDl}S%$$7J{XgFM>hn9x7)q3xhR)Mfa*QQY8GK63?q1qm1>#yH4 zEz-c>(2=}gaHS(VN<9_qGU*~h++2>Ul_}2k{vNNQ`6Csu`fKI};AI1}E3ATP&}q zPf+kkaW2J%M~&zl@RJ1B!a}^~Dj3C|KW^33$X~o`mrJRZWQG|c^wGpJ1$1zGLt{-J zjC_E4Uj5u20tH0I_P~QkJ>XV+C=*D?2nnjyJXM^FcbnG?0sSs(9pH^3&jOA5ydMDf z-gpo-4gwyZm6}bxVEDj!M6X2OWxZ)YV1emlC1hwW+y}CX9IMOCf{uS5y_LW^RBgHOH{4`85mrun zfex-iJKYTRZq$Dgi314(V26VJ5ah~(8UaR(;xc$zr1mF(T?(Re=t_v9(a8vG@Mxxv zFAzbUqj9*_Vj{*;w|yX`U#SzDY@eyAS;{EqPtoJD1d%OP$SnE`H)O#2jVj;o+s?ZA zBh`@-u2c$&$2!anQ(AM@zl}8?IBoyu{9J8{0dT`uS~M7-)#sQ)!rw-1`{_Qe?DT&x zTk^!^U1?MkSr)E92#ZL-21G@{p2PyIZkUIzidgRuF-v8)p!dEvTsN0;rk$Dv4{)pE+lKO`TJz_g=kw?{~lZ zy;skp=Xj{;*KI#JOqp@Q?tr~K{}ySe;`aptcnQMF(H zu1+TU43lm*V=kMVG!1Oqwq4XfG`afpzOwIiY82cQUt{8((Z{ z9UIr-;<9Y`6pT^ra3iE_S!u50V6S-RwpYL9N z{*J?je(vz|0R;|4#%Jb^e5lA2u9U<|*2kLSS;t(ff5*nA_029>bhOawW>`VbqP?{R;<^8DsjBYqJfq?; z3uV06edFTqExU?Oj_xHaPj5$^84~a|Y{Wo4ysZk<(RMUF_4z>C+2W*?S9&J|jOctcsI>RD zxT8L1EgGoXXiJ{kdu4O5qv_*qO`WyfUyOnOi@tN|S~=T* zNK>Zmh;^T55-=$&e_`CPw@*cH?29)#sMfaF`zqmLweWnpC%!R(3ETWWxE1(Zvf|Mjax5aP3m^kAJz}i67Oq zX7FV5?jLvWRmJpq1=clfcxHFJdfm4RUE5Coo^BJVDVK3v!E@P5IBBe&dk zd5^P5GAn%5v@vm9S#nr8audFMR+?#;o421E1aFzt_wRhjkU zY0Xx>$M%z3ie{6XZEK%?+kE_-u|<$b*-+^FHKWWePLk%^b2gzXZ2k4PqMWMKh{s3# z^82Q`P5ou)ip(-SS*-e!V88E8v-N2c6X*>y65CT7rzFzjY2MpdVMEfbRtm<1E_FEd zfIC+3cjqw|n=j3Hxhj8cdo24!zDq!(`a(?LEno56(f$pB^c;-30!yuG*ce%=@)%J2 z6A#FPc#=}Bc2@A*np7T8__g};Nl|a(&}0`@Oqs* z1uvu~xK#SUlX4YEJ<$(Vg6U%zA;E(o!V2UGo&xQYuYK~g5ook0buHwMsfHNl&c!7W zW^xEGti&+7RH4`ULVgg>1_#b+aKTZ-Mf|RxjqigYf{$~ZZ-27_=Q2~`jS*UXWrvZM zw{fMkpPtYmPs0zxEaa0Z4Tkq}2`+Jv;3DuJDCgtR$`(36WYc<+<0;P=>Esnqu#cOeI$gHwVTVHm4Q#>In`uMA32W+YvY zd5(`q2ninyY$XneH4z?N*Kz^oVvaDiuAf#Ds=yc+CXL4f8Dxrq$c*x5$xOcnbC8)M z5D3-EgD&$NT@QkJ)&}FAaxU&kT22LrmdW=pi1#iB_B;$~HJx-a*X0rj@%}0o5=5a% z=Lz$4g?nX$!~0Zvi3UgnU`>ZaXhI?t&6WI3HIW6`vMPxxQcM#nI}L;^B{fM%P~IeF z$#2yNYPvsEN)@B&C4Q@gN~_nw)M2{{RsSn&^F9JL>{DPACLc_d`#BsTF%MI1hx$s0 zUXTDHZU@MF2i?RAv8)fOkt7ZVF$KaKtZM`SK;y=VCQ=c+?lM6G&|-99&;p(zT~JOS zOG(sdGA>K*gXAzFu>?Z}B_)wa>TXfi8tFWNdTLaoyk~@jBf{N?Dv*s(zB>sj#XR55 zJY5cSFCr>5y6J=|0-zg$@j*6#-3>~}gKo5t*otgG2`dN@&IcX@&I*K=!OT@8D}x~x zN%w@|z%B_?h`7nBWL0Q@g1MWJRR$%X!0tkRbQtHo$JqW3<5OifU?lfZ7?sS^HSUc} zX&aDq8L69SV3h-Fu2j1d&_WHU5JWPv0EB_iWh+|@^kMxb_oJw!6Gs>E4}*8CP!WNQ z7BC}vKUhx@fh;cWs*J~74S;c1$ch80N+3fQP#~JlOvwU2S_WXl$^&$$)IbKw#*7gU zxC2_o9MvH=VF{qKUeo`Sf?pY4ikI z)9PtY6%|ygCwpB`q^I{m(HwBjSB?Ep9iR*pQAq5h-t%!jba_A&lAQqL#|I}XfKa46 zo#xetrULR(`k%1NlKTHV9SXVZZl(3KM~g7!=y zK?5Lcl1rll2y>PAqmt>WVxbF{@>#frdLPI8=0C(ko3LiFv4zA;Ju=OL4n(1tfMznd z#Z;3tv0-s@kTwuXa~KEe&=llANG#M#R?^YR14E!^^3UJ|b;grULqNplv`3$Ad9`TQ z4gUPoV*TMtuz8QVN+TblTSzceRxHi_`(DG=FADlBYl*EpcZ0I8>GzqM`Pcw4FwB)Y6-J(*D6fv3;T~ zSVY&g({2;4ILVI0STzPKVTl5Gy2_8_4SY(yAGrFM`dSgrp}qJ94gg|9NBEWAr1?fx zfdZqI?R4;Jzy?x)8+%xUlwWAuq7qZ&KzKS$0pV0#q)I(^SjSPT;J}uLQs{PsB@G8C)FEBR%NVn$ucMxq8V(zCBuv;;sZ$f!id$6{ zU`BP}C3EY=7i#spG_BCrj$%Q=QW;VWmA$v4_OzyeGYdLR0uBi=9L{isDEJ`h)%fKr zR|V)tyw;C<<*Xpna13A*Jv{dtkpo1JbM;E%X{1z`Z@bERMe8MCGF{q5r;J(~rCqedU&vBy69bbQ8Y?8z z<*Vpq%495$fzh7vq?JbMJv?admKn}AQb?MKK7Y>B;w9=md>Dl3hJ-$xn^pJJdxBv= zUMzrL@YbtVU&LSo;PKbf7yGO0$?dtIge3dKq`>is0v?}-1_ePR8&6t~xnGU!m-Zxe zU2J-T4n+TpEB<>1#)JFAi-5l9ld(O}mwYm&v&n<;Vz^7;z6p0T+}&`a>y`FtbVk#k z>$7OS4|j^oL^hX;g^NOhA|=oX7KyOPh!C;1iE+b&g1Moq#X;hjnHV-ZM8Xq?ubCMf zEDni?z%aj1u_Q7`1Y?qrHSlK-ZGWan6u#zNZCrA+|Us0*x=0h(p8H U!dvfkL1J!rREQX&{Qq442KmAZP5=M^ diff --git a/Source/Hardware/Experimental/vga2/vga8x8d.spin b/Source/Hardware/Experimental/vga2/vga8x8d.spin deleted file mode 100644 index a9b7d006..00000000 --- a/Source/Hardware/Experimental/vga2/vga8x8d.spin +++ /dev/null @@ -1,619 +0,0 @@ -'' This object generates a 640x480 VGA signal which contains 80 columns x 30 -'' rows of 8x8 double scan characters. Each character can have a unique forground -'' and background color combination and each character can be inversed and highlit. -'' There are also two cursors which can be independently controlled (ie. mouse -'' and keyboard). A sync indicator signals each time the screen is refreshed -'' (you may ignore). -'' -'' You must provide buffers for the screen, cursors, and sync. Once started, -'' all interfacing is done via memory. To this object, all buffers are -'' read-only, with the exception of the sync indicator which gets written with -'' -1. You may freely write all buffers to affect screen appearance. Have fun! -'' - -CON - -' 640 x 480 @ 69Hz settings: 80 x 30 characters - - hp = 640 ' horizontal pixels - vp = 480 ' vertical pixels - hf = 24 ' horizontal front porch pixels - hs = 40 ' horizontal sync pixels - hb = 128 ' horizontal back porch pixels - vf = 20 ' vertical front porch lines - vs = 3 ' vertical sync lines - vb = 17 ' vertical back porch lines - hn = 1 ' horizontal normal sync state (0|1) - vn = 1 ' vertical normal sync state (0|1) - pr = 30 ' pixel rate in MHz at 80MHz system clock (5MHz granularity) - -' columns and rows - - cols = hp / 8 - rows = vp / 16 - - -VAR long cog[2] - -PUB start(BasePin, ScreenPtr, CursorPtr, SyncPtr) : okay | i, j - -'' Start VGA driver - starts two COGs -'' returns false if two COGs not available -'' -'' BasePin = VGA starting pin (0, 8, 16, 24, etc.) -'' -'' ScreenPtr = Pointer to 80x30 words containing Latin-1 codes and colors for -'' each of the 80x30 screen characters. The lower byte of the word -'' contains the Latin-1 code to display. The upper byte contains -'' the foreground colour in bits 11..8 and the background colour in -'' bits 15..12. -'' -'' screen word example: %00011111_01000001 = "A", white on blue -'' -'' CursorPtr = Pointer to 6 bytes which control the cursors: -'' -'' bytes 0,1,2: X, Y, and MODE of cursor 0 -'' bytes 3,4,5: X, Y, and MODE of cursor 1 -'' -'' X and Y are in terms of screen characters -'' (left-to-right, top-to-bottom) -'' -'' MODE uses three bottom bits: -'' -'' %x00 = cursor off -'' %x01 = cursor on -'' %x10 = cursor on, blink slow -'' %x11 = cursor on, blink fast -'' %0xx = cursor is solid block -'' %1xx = cursor is underscore -'' -'' cursor example: 127, 63, %010 = blinking block in lower-right -'' -'' SyncPtr = Pointer to long which gets written with -1 upon each screen -'' refresh. May be used to time writes/scrolls, so that chopiness -'' can be avoided. You must clear it each time if you want to see -'' it re-trigger. - - ' if driver is already running, stop it - stop - - ' implant pin settings - reg_vcfg := $200000FF + (BasePin & %111000) << 6 - i := $FF << (BasePin & %011000) - j := BasePin & %100000 == 0 - reg_dira := i & j - reg_dirb := i & !j - - ' implant CNT value to sync COGs to - sync_cnt := cnt + $10000 - - ' implant pointers - longmove(@screen_base, @ScreenPtr, 2) - font_base := @font - - ' implant unique settings and launch first COG - vf_lines.byte := vf - vb_lines.byte := vb - font_part := 1 - cog[1] := cognew(@entry, SyncPtr) + 1 - - ' allow time for first COG to launch - waitcnt($2000 + cnt) - - ' differentiate settings and launch second COG - vf_lines.byte := vf+8 - vb_lines.byte := vb-8 - font_part := 0 - cog[0] := cognew(@entry, SyncPtr) + 1 - - ' if both COGs launched, return true - if cog[0] and cog[1] - return true - - ' else, stop any launched COG and return false - stop - - -PUB stop | i - -'' Stop VGA driver - frees two COGs - - repeat i from 0 to 1 - if cog[i] - cogstop(cog[i]~ - 1) - - -CON - hv_inactive = (hn << 1 + vn) * $0101 'H,V inactive states - - -DAT - -'***************************************************** -'* Assembly language VGA high-resolution text driver * -'***************************************************** - -' This program runs concurrently in two different COGs. -' -' Each COG's program has different values implanted for front-porch lines and -' back-porch lines which surround the vertical sync pulse lines. This allows -' timed interleaving of their active display signals during the visible portion -' of the field scan. Also, they are differentiated so that one COG displays -' even four-line groups while the other COG displays odd four-line groups. -' -' These COGs are launched in the PUB 'start' and are programmed to synchronize -' their PLL-driven video circuits so that they can alternately prepare sets of -' four scan lines and then display them. The COG-to-COG switchover is seemless -' due to two things: exact synchronization of the two video circuits and the -' fact that all COGs' driven output states get OR'd together, allowing one COG -' to output lows during its preparatory state while the other COG effectively -' drives the pins to create the visible and sync portions of its scan lines. -' During non-visible scan lines, both COGs output together in unison. -' - org 0 ' set origin to $000 for start of program -entry -' Initialization code and data - after execution, space gets reused as scanbuff - - ' Init I/O registers and sync COGs' video circuits - - mov dira, reg_dira ' set pin directions - mov dirb, reg_dirb - movi frqa, #(pr / 5) << 2 ' set pixel rate - mov vcfg, reg_vcfg ' set video configuration - mov vscl, #1 ' set video to reload on every pixel - waitcnt sync_cnt, colormask ' wait for start value in cnt, add ~1ms - movi ctra, #%00001_110 ' COGs in sync! enable PLLs now - NCOs locked! - waitcnt sync_cnt, #0 ' wait ~1ms for PLLs to stabilize - PLLs locked! - mov vscl, #100 ' insure initial WAITVIDs lock cleanly - -' Main loop, display field - each COG alternately builds and displays four scan lines - -vsync mov x, #vs ' do vertical sync lines - call #blank_vsync - -vb_lines mov x, #vb ' do vertical back porch lines (# set at runtime) - call #blank_vsync - - mov screen_ptr, screen_base ' reset screen pointer to upper-left character - mov row, #0 ' reset row counter for cursor insertion - mov fours, #rows ' set number of 4-line builds for whole screen - - ' Build four scan lines into scanbuff - -fourline mov font_ptr, font_part ' get address of appropriate font section - shl font_ptr, #7+2 - add font_ptr, font_base - - movd :pixa, #scanbuff-1 ' reset scanbuff address (pre-decremented) - movd :pixb, #scanbuff-1 ' reset scanbuff address (pre-decremented) - movd :cola, #colorbuff-1 ' reset colorbuff address (pre-decremented) - movd :colb, #colorbuff-1 - - mov y, #4 ' must build scanbuff in four sections because - mov vscl, vscl_line2x ' ..pixel counter is limited to twelve bits - -:halfrow waitvid underscore, #0 ' output lows to let other COG drive VGA pins - mov x, #cols/4 ' ..for 2 scan lines, ready for a quarter row - -:column rdword z, screen_ptr ' get character and colors from screen memory - mov bg, z - ror z, #7 - shr z, #32 - 9 wc - add z, font_ptr ' add font section address to point to 8*4 pixels - add :pixa, d0 ' increment scanbuff destination addresses - add :pixb, d0 ' increment scanbuff destination addresses - add screen_ptr, #2 ' increment screen memory address - cmp font_part, #1 wz -:pixa rdlong scanbuff, z ' read pixel long (8*4) into scanbuff -:pixb if_c_and_z or scanbuff, underline - - ror bg, #12 ' background color in bits 3..0 - mov fg, bg ' foreground color in bits 31..28 - shr fg, #28 ' bits 3..0 - add fg, #fg_clut ' + offset to foreground CLUT - movs :cola, fg - add :cola, d0 - add bg, #bg_clut ' + offset to background CLUT - movs :colb, bg - add :colb, d0 -:cola mov colorbuff, 0-0 -:colb or colorbuff, 0-0 - - djnz x, #:column ' another character in this half-row? - djnz y, #:halfrow ' loop to do 2nd half-row, time for 2nd WAITVID - - ' Insert cursors into scanbuff - - mov z, #2 ' ready for two cursors - -:cursor rdbyte x, cursor_base ' x in range? - add cursor_base, #1 - cmp x, #cols wc - - rdbyte y, cursor_base ' y match? - add cursor_base, #1 - cmp y, row wz - - rdbyte y, cursor_base ' get cursor mode - add cursor_base, #1 - - if_nc_or_nz jmp #:nocursor ' if cursor not in scanbuff, no cursor - - add x, #scanbuff ' cursor in scanbuff, set scanbuff address - movd :xor, x - - test y, #%010 wc ' get mode bits into flags - test y, #%001 wz - if_nc_and_z jmp #:nocursor ' if cursor disabled, no cursor - - if_c_and_z test slowbit, cnt wc ' if blink mode, get blink state - if_c_and_nz test fastbit, cnt wc - - test y, #%100 wz ' get box or underscore cursor piece - if_z mov x, longmask - if_nz mov x, underscore - if_nz cmp font_part, #1 wz ' if underscore, must be last font section - -:xor if_nc_and_z xor scanbuff, x ' conditionally xor cursor into scanbuff - -:nocursor djnz z, #:cursor ' second cursor? - - sub cursor_base, #3*2 ' restore cursor base - - ' Display four scan lines from scanbuff - - mov y, #4 ' ready for four scan lines -scanline - mov x, #2 wc ' clear carry and set sweep count -sweep - mov vscl, vscl_chr - waitvid colorbuff+ 0, scanbuff+ 0 - if_c ror scanbuff+ 0, #8 - waitvid colorbuff+ 1, scanbuff+ 1 - if_c ror scanbuff+ 1, #8 - waitvid colorbuff+ 2, scanbuff+ 2 - if_c ror scanbuff+ 2, #8 - waitvid colorbuff+ 3, scanbuff+ 3 - if_c ror scanbuff+ 3, #8 - waitvid colorbuff+ 4, scanbuff+ 4 - if_c ror scanbuff+ 4, #8 - waitvid colorbuff+ 5, scanbuff+ 5 - if_c ror scanbuff+ 5, #8 - waitvid colorbuff+ 6, scanbuff+ 6 - if_c ror scanbuff+ 6, #8 - waitvid colorbuff+ 7, scanbuff+ 7 - if_c ror scanbuff+ 7, #8 - - waitvid colorbuff+ 8, scanbuff+ 8 - if_c ror scanbuff+ 8, #8 - waitvid colorbuff+ 9, scanbuff+ 9 - if_c ror scanbuff+ 9, #8 - waitvid colorbuff+10, scanbuff+10 - if_c ror scanbuff+10, #8 - waitvid colorbuff+11, scanbuff+11 - if_c ror scanbuff+11, #8 - waitvid colorbuff+12, scanbuff+12 - if_c ror scanbuff+12, #8 - waitvid colorbuff+13, scanbuff+13 - if_c ror scanbuff+13, #8 - waitvid colorbuff+14, scanbuff+14 - if_c ror scanbuff+14, #8 - waitvid colorbuff+15, scanbuff+15 - if_c ror scanbuff+15, #8 - - waitvid colorbuff+16, scanbuff+16 - if_c ror scanbuff+16, #8 - waitvid colorbuff+17, scanbuff+17 - if_c ror scanbuff+17, #8 - waitvid colorbuff+18, scanbuff+18 - if_c ror scanbuff+18, #8 - waitvid colorbuff+19, scanbuff+19 - if_c ror scanbuff+19, #8 - waitvid colorbuff+20, scanbuff+20 - if_c ror scanbuff+20, #8 - waitvid colorbuff+21, scanbuff+21 - if_c ror scanbuff+21, #8 - waitvid colorbuff+22, scanbuff+22 - if_c ror scanbuff+22, #8 - waitvid colorbuff+23, scanbuff+23 - if_c ror scanbuff+23, #8 - - waitvid colorbuff+24, scanbuff+24 - if_c ror scanbuff+24, #8 - waitvid colorbuff+25, scanbuff+25 - if_c ror scanbuff+25, #8 - waitvid colorbuff+26, scanbuff+26 - if_c ror scanbuff+26, #8 - waitvid colorbuff+27, scanbuff+27 - if_c ror scanbuff+27, #8 - waitvid colorbuff+28, scanbuff+28 - if_c ror scanbuff+28, #8 - waitvid colorbuff+29, scanbuff+29 - if_c ror scanbuff+29, #8 - waitvid colorbuff+30, scanbuff+30 - if_c ror scanbuff+30, #8 - waitvid colorbuff+31, scanbuff+31 - if_c ror scanbuff+31, #8 - - waitvid colorbuff+32, scanbuff+32 - if_c ror scanbuff+32, #8 - waitvid colorbuff+33, scanbuff+33 - if_c ror scanbuff+33, #8 - waitvid colorbuff+34, scanbuff+34 - if_c ror scanbuff+34, #8 - waitvid colorbuff+35, scanbuff+35 - if_c ror scanbuff+35, #8 - waitvid colorbuff+36, scanbuff+36 - if_c ror scanbuff+36, #8 - waitvid colorbuff+37, scanbuff+37 - if_c ror scanbuff+37, #8 - waitvid colorbuff+38, scanbuff+38 - if_c ror scanbuff+38, #8 - waitvid colorbuff+39, scanbuff+39 - if_c ror scanbuff+39, #8 - - waitvid colorbuff+40, scanbuff+40 - if_c ror scanbuff+40, #8 - waitvid colorbuff+41, scanbuff+41 - if_c ror scanbuff+41, #8 - waitvid colorbuff+42, scanbuff+42 - if_c ror scanbuff+42, #8 - waitvid colorbuff+43, scanbuff+43 - if_c ror scanbuff+43, #8 - waitvid colorbuff+44, scanbuff+44 - if_c ror scanbuff+44, #8 - waitvid colorbuff+45, scanbuff+45 - if_c ror scanbuff+45, #8 - waitvid colorbuff+46, scanbuff+46 - if_c ror scanbuff+46, #8 - waitvid colorbuff+47, scanbuff+47 - if_c ror scanbuff+47, #8 - - waitvid colorbuff+48, scanbuff+48 - if_c ror scanbuff+48, #8 - waitvid colorbuff+49, scanbuff+49 - if_c ror scanbuff+49, #8 - waitvid colorbuff+50, scanbuff+50 - if_c ror scanbuff+50, #8 - waitvid colorbuff+51, scanbuff+51 - if_c ror scanbuff+51, #8 - waitvid colorbuff+52, scanbuff+52 - if_c ror scanbuff+52, #8 - waitvid colorbuff+53, scanbuff+53 - if_c ror scanbuff+53, #8 - waitvid colorbuff+54, scanbuff+54 - if_c ror scanbuff+54, #8 - waitvid colorbuff+55, scanbuff+55 - if_c ror scanbuff+55, #8 - - waitvid colorbuff+56, scanbuff+56 - if_c ror scanbuff+56, #8 - waitvid colorbuff+57, scanbuff+57 - if_c ror scanbuff+57, #8 - waitvid colorbuff+58, scanbuff+58 - if_c ror scanbuff+58, #8 - waitvid colorbuff+59, scanbuff+59 - if_c ror scanbuff+59, #8 - waitvid colorbuff+60, scanbuff+60 - if_c ror scanbuff+60, #8 - waitvid colorbuff+61, scanbuff+61 - if_c ror scanbuff+61, #8 - waitvid colorbuff+62, scanbuff+62 - if_c ror scanbuff+62, #8 - waitvid colorbuff+63, scanbuff+63 - if_c ror scanbuff+63, #8 - - waitvid colorbuff+64, scanbuff+64 - if_c ror scanbuff+64, #8 - waitvid colorbuff+65, scanbuff+65 - if_c ror scanbuff+65, #8 - waitvid colorbuff+66, scanbuff+66 - if_c ror scanbuff+66, #8 - waitvid colorbuff+67, scanbuff+67 - if_c ror scanbuff+67, #8 - waitvid colorbuff+68, scanbuff+68 - if_c ror scanbuff+68, #8 - waitvid colorbuff+69, scanbuff+69 - if_c ror scanbuff+69, #8 - waitvid colorbuff+70, scanbuff+70 - if_c ror scanbuff+70, #8 - waitvid colorbuff+71, scanbuff+71 - if_c ror scanbuff+71, #8 - - waitvid colorbuff+72, scanbuff+72 - if_c ror scanbuff+72, #8 - waitvid colorbuff+73, scanbuff+73 - if_c ror scanbuff+73, #8 - waitvid colorbuff+74, scanbuff+74 - if_c ror scanbuff+74, #8 - waitvid colorbuff+75, scanbuff+75 - if_c ror scanbuff+75, #8 - waitvid colorbuff+76, scanbuff+76 - if_c ror scanbuff+76, #8 - waitvid colorbuff+77, scanbuff+77 - if_c ror scanbuff+77, #8 - waitvid colorbuff+78, scanbuff+78 - if_c ror scanbuff+78, #8 - waitvid colorbuff+79, scanbuff+79 - - mov vscl, #hf ' do horizontal front porch pixels - waitvid hvsync, #0 ' #0 makes hsync inactive - mov vscl, #hs ' do horizontal sync pixels - waitvid hvsync, #1 ' #1 makes hsync active - mov vscl, #hb ' do horizontal back porch pixels - waitvid hvsync, #0 ' #0 makes hsync inactive - if_c ror scanbuff+79, #8 - test x, #2 wc ' set carry - djnz x, #sweep - djnz y, #scanline ' another scan line? - - ' Next group of four scan lines - - add row, #1 ' if new row, increment row counter - djnz fours, #fourline ' another 4-line build/display? - - ' Visible section done, do vertical sync front porch lines - - wrlong longmask,par ' write -1 to refresh indicator - -vf_lines mov x,#vf ' do vertical front porch lines (# set at runtime) - call #blank - - jmp #vsync ' new field, loop to vsync - - ' Subroutine - do blank lines - -blank_vsync xor hvsync,#$101 ' flip vertical sync bits - -blank mov vscl, hx ' do blank pixels - waitvid hvsync, #0 - mov vscl, #hf ' do horizontal front porch pixels - waitvid hvsync, #0 - mov vscl, #hs ' do horizontal sync pixels - waitvid hvsync, #1 - mov vscl, #hb ' do horizontal back porch pixels - waitvid hvsync, #0 - djnz x, #blank ' another line? -blank_ret -blank_vsync_ret - ret - - ' Data - -screen_base long 0 ' set at runtime (3 contiguous longs) -cursor_base long 0 ' set at runtime - -font_base long 0 ' set at runtime -font_part long 0 ' set at runtime - -hx long hp ' visible pixels per scan line -vscl_line2x long (hp + hf + hs + hb) * 2 ' total number of pixels per 2 scan lines -vscl_chr long 1 << 12 + 8 ' 1 clock per pixel and 8 pixels per set -colormask long $fcfc ' mask to isolate R,G,B bits from H,V -longmask long $ffffffff ' all bits set -slowbit long 1 << 25 ' cnt mask for slow cursor blink -fastbit long 1 << 24 ' cnt mask for fast cursor blink -underscore long $ffff0000 ' underscore cursor pattern -underline long $ff000000 -hv long hv_inactive ' -H,-V states -hvsync long hv_inactive ^ $200 ' +/-H,-V states -d0 long 1 << 9 -d0s0 long 1 << 9 + 1 -d1 long 1 << 10 -reg_dira long 0 ' set at runtime -reg_dirb long 0 ' set at runtime -reg_vcfg long 0 ' set at runtime -sync_cnt long 0 ' set at runtime - -bg_clut long %00000011_00000011 ' black - long %00000011_00001011 ' dark blue - long %00000011_00100011 ' dark green - long %00000011_00101011 ' dark cyan - long %00000011_10000011 ' dark red - long %00000011_10001011 ' dark magenta - long %00000011_10100011 ' brown - long %00000011_10101011 ' light gray - long %00000011_01010111 ' dark gray - long %00000011_00001111 ' light blue - long %00000011_00110011 ' light green - long %00000011_00111111 ' light cyan - long %00000011_11000011 ' light red - long %00000011_11001111 ' light magenta - long %00000011_11110011 ' light yellow - long %00000011_11111111 ' white - -fg_clut long %00000011_00000011 ' black - long %00000111_00000011 ' dark blue - long %00010011_00000011 ' dark green - long %00010111_00000011 ' dark cyan - long %01000011_00000011 ' dark red - long %01000111_00000011 ' dark magenta - long %01010011_00000011 ' brown - long %10101011_00000011 ' light gray - long %01010111_00000011 ' dark gray - long %00001011_00000011 ' blue - long %00100011_00000011 ' green - long %00101011_00000011 ' cyan - long %10000011_00000011 ' red - long %10001011_00000011 ' magenta - long %10100011_00000011 ' yellow - long %11111111_00000011 ' white - - ' Uninitialized data - -screen_ptr res 1 -font_ptr res 1 - -x res 1 -y res 1 -z res 1 -fg res 1 -bg res 1 - -row res 1 -fours res 1 - -scanbuff res 80 -colorbuff res 80 - - fit $1f0 - -' 8 x 12 font - characters 0..127 -' -' Each long holds four scan lines of a single character. The longs are arranged into -' groups of 128 which represent all characters (0..127). There are four groups which -' each contain a vertical part of all characters. They are ordered top, middle, and -' bottom. - -font long - long $00000000,$0f0f0f0f,$f0f0f0f0,$ffffffff,$00000000,$0f0f0f0f,$f0f0f0f0,$ffffffff - long $00000000,$0f0f0f0f,$f0f0f0f0,$ffffffff,$00000000,$0f0f0f0f,$f0f0f0f0,$ffffffff - long $7e5a3c00,$7e3c1800,$7e7e2400,$7e3c1800,$f8000000,$1f000000,$f8181818,$1f181818 - long $18181818,$ff000000,$1f181818,$f8181818,$ff181818,$ff000000,$ff181818,$aa55aa55 - long $00000000,$18181800,$66666600,$66ff6600,$3c067c18,$18366600,$1c386c38,$18181800 - long $0c0c1830,$3030180c,$ff3c6600,$7e181800,$00000000,$7e000000,$00000000,$18306000 - long $76663c00,$181c1800,$30663c00,$18307e00,$3c383000,$3e067e00,$3e063c00,$30607e00 - long $3c663c00,$7c663c00,$18180000,$18180000,$0c183060,$007e0000,$30180c06,$30663c00 - long $76663c00,$663c1800,$3e663e00,$06663c00,$66361e00,$3e067e00,$3e067e00,$06067c00 - long $7e666600,$18187e00,$60606000,$1e366600,$06060600,$feeec600,$7e6e6600,$66663c00 - long $66663e00,$66663c00,$66663e00,$3c063c00,$18187e00,$66666600,$66666600,$d6c6c600 - long $3c666600,$3c666600,$18307e00,$0c0c0c3c,$0c060200,$3030303c,$c66c3810,$00000000 - long $30180c00,$603c0000,$3e060600,$063c0000,$7c606000,$663c0000,$7c187000,$667c0000 - long $3e060600,$1c001800,$60006000,$36060600,$18181c00,$fe660000,$663e0000,$663c0000 - long $663e0000,$667c0000,$663e0000,$067c0000,$187e1800,$66660000,$66660000,$d6c60000 - long $3c660000,$66660000,$307e0000,$0c181830,$18181800,$3018180c,$0000366c,$142a142a - - long $00000000,$00000000,$00000000,$00000000,$0f0f0f0f,$0f0f0f0f,$0f0f0f0f,$0f0f0f0f - long $f0f0f0f0,$f0f0f0f0,$f0f0f0f0,$f0f0f0f0,$ffffffff,$ffffffff,$ffffffff,$ffffffff - long $007e187e,$007e187e,$00183c7e,$00183c7e,$181818f8,$1818181f,$000000f8,$0000001f - long $18181818,$000000ff,$1818181f,$181818f8,$000000ff,$181818ff,$181818ff,$aa55aa55 - long $00000000,$00180018,$00000000,$0066ff66,$00183e60,$0062660c,$00dc66f6,$00000000 - long $30180c0c,$0c183030,$0000663c,$00001818,$0c181800,$00000000,$00181800,$0002060c - long $003c666e,$007e1818,$007e0c18,$003c6630,$00307e36,$003c6660,$003c6666,$000c0c18 - long $003c6666,$001c3060,$00181800,$0c181800,$00603018,$00007e00,$00060c18,$00180018 - long $007c0676,$00667e66,$003e6666,$003c6606,$001e3666,$007e0606,$00060606,$007c6676 - long $00666666,$007e1818,$003c6660,$0066361e,$007e0606,$00c6c6d6,$0066767e,$003c6666 - long $0006063e,$006c3666,$0066363e,$003c6060,$00181818,$007e6666,$00183c66,$00c6eefe - long $0066663c,$00181818,$007e060c,$3c0c0c0c,$00603018,$3c303030,$00000000,$ff000000 - long $00000000,$007c667c,$003e6666,$003c0606,$007c6666,$003c067e,$00181818,$3e607c66 - long $00666666,$003c1818,$3c606060,$0066361e,$003c1818,$00c6d6fe,$00666666,$003c6666 - long $06063e66,$60607c66,$00060606,$003e603c,$00701818,$007c6666,$00183c66,$006c7cfe - long $00663c18,$1e307c66,$007e0c18,$00301818,$00181818,$000c1818,$00000000,$002a142a - - -{{ -+------------------------------------------------------------------------------------------------------------------------------+ -| TERMS OF USE: Parallax Object Exchange 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/Hardware/Experimental/vga2/vgacolour.spin b/Source/Hardware/Experimental/vga2/vgacolour.spin deleted file mode 100644 index cb729bb9..00000000 --- a/Source/Hardware/Experimental/vga2/vgacolour.spin +++ /dev/null @@ -1,602 +0,0 @@ -''*************************************** -''* VGA High-Res Text Driver v1.0 * -''* Author: Chip Gracey * -''* Copyright (c) 2006 Parallax, Inc. * -''* See end of file for terms of use. * -''*************************************** -'' -'' This object generates a 640x480 VGA signal which contains 80 columns x 30 -'' rows of 8x16 characters. Each character can have a unique forground/background -'' color combination and each character can be inversed and high-lighted. -'' There are also two cursors which can be independently controlled (ie. mouse -'' and keyboard). A sync indicator signals each time the screen is refreshed -'' (you may ignore). -'' -'' You must provide buffers for the screen, cursors, and sync. Once started, -'' all interfacing is done via memory. To this object, all buffers are -'' read-only, with the exception of the sync indicator which gets written with -'' -1. You may freely write all buffers to affect screen appearance. Have fun! -'' - -CON - -' 640 x 480 @ 69Hz settings: 80 x 30 characters - - hp = 640 ' horizontal pixels - vp = 480 ' vertical pixels - hf = 24 ' horizontal front porch pixels - hs = 40 ' horizontal sync pixels - hb = 128 ' horizontal back porch pixels - vf = 20 ' vertical front porch lines - vs = 3 ' vertical sync lines - vb = 17 ' vertical back porch lines - hn = 1 ' horizontal normal sync state (0|1) - vn = 1 ' vertical normal sync state (0|1) - pr = 30 ' pixel rate in MHz at 80MHz system clock (5MHz granularity) - -' columns and rows - - cols = hp / 8 - rows = vp / 16 - - -VAR long cog[2] - -PUB start(BasePin, ScreenPtr, CursorPtr, SyncPtr) : okay | i, j - -'' Start VGA driver - starts two COGs -'' returns false if two COGs not available -'' -'' BasePin = VGA starting pin (0, 8, 16, 24, etc.) -'' -'' ScreenPtr = Pointer to 80x30 words containing Latin-1 codes and colors for -'' each of the 80x30 screen characters. The lower byte of the word -'' contains the Latin-1 code to display. The upper byte contains -'' the foreground colour in bits 11..8 and the background colour in -'' bits 15..12. -'' -'' screen word example: %00011111_01000001 = "A", white on blue -'' -'' CursorPtr = Pointer to 6 bytes which control the cursors: -'' -'' bytes 0,1,2: X, Y, and MODE of cursor 0 -'' bytes 3,4,5: X, Y, and MODE of cursor 1 -'' -'' X and Y are in terms of screen characters -'' (left-to-right, top-to-bottom) -'' -'' MODE uses three bottom bits: -'' -'' %x00 = cursor off -'' %x01 = cursor on -'' %x10 = cursor on, blink slow -'' %x11 = cursor on, blink fast -'' %0xx = cursor is solid block -'' %1xx = cursor is underscore -'' -'' cursor example: 127, 63, %010 = blinking block in lower-right -'' -'' SyncPtr = Pointer to long which gets written with -1 upon each screen -'' refresh. May be used to time writes/scrolls, so that chopiness -'' can be avoided. You must clear it each time if you want to see -'' it re-trigger. - - ' if driver is already running, stop it - stop - - ' implant pin settings - reg_vcfg := $200000FF + (BasePin & %111000) << 6 - i := $FF << (BasePin & %011000) - j := BasePin & %100000 == 0 - reg_dira := i & j - reg_dirb := i & !j - - ' implant CNT value to sync COGs to - sync_cnt := cnt + $10000 - - ' implant pointers - longmove(@screen_base, @ScreenPtr, 2) - font_base := @font - - ' implant unique settings and launch first COG - vf_lines.byte := vf - vb_lines.byte := vb - font_part := 1 - cog[1] := cognew(@d0, SyncPtr) + 1 - - ' allow time for first COG to launch - waitcnt($2000 + cnt) - - ' differentiate settings and launch second COG - vf_lines.byte := vf+4 - vb_lines.byte := vb-4 - font_part := 0 - cog[0] := cognew(@d0, SyncPtr) + 1 - - ' if both COGs launched, return true - if cog[0] and cog[1] - return true - - ' else, stop any launched COG and return false - stop - - -PUB stop | i - -'' Stop VGA driver - frees two COGs - - repeat i from 0 to 1 - if cog[i] - cogstop(cog[i]~ - 1) - - -CON - - #1, scanbuff[80], colorbuff[80], scancode[2*80-1+3], maincode 'enumerate COG RAM usage - - main_size = $1F0 - maincode 'size of main program - - hv_inactive = (hn << 1 + vn) * $0101 'H,V inactive states - - -DAT - -'***************************************************** -'* Assembly language VGA high-resolution text driver * -'***************************************************** - -' This program runs concurrently in two different COGs. -' -' Each COG's program has different values implanted for front-porch lines and -' back-porch lines which surround the vertical sync pulse lines. This allows -' timed interleaving of their active display signals during the visible portion -' of the field scan. Also, they are differentiated so that one COG displays -' even four-line groups while the other COG displays odd four-line groups. -' -' These COGs are launched in the PUB 'start' and are programmed to synchronize -' their PLL-driven video circuits so that they can alternately prepare sets of -' four scan lines and then display them. The COG-to-COG switchover is seemless -' due to two things: exact synchronization of the two video circuits and the -' fact that all COGs' driven output states get OR'd together, allowing one COG -' to output lows during its preparatory state while the other COG effectively -' drives the pins to create the visible and sync portions of its scan lines. -' During non-visible scan lines, both COGs output together in unison. -' -' COG RAM usage: $000 = d0 - used to inc destination fields for indirection -' $001-$050 = scanbuff - longs which hold 4 scan lines -' $051-$010 = colorbuff - longs which hold colors for 80 characters -' $0a1-$142 = scancode - stacked WAITVID/SHR for fast display -' $143-$1EF = maincode - main program loop which drives display - - org 0 ' set origin to $000 for start of program - -d0 long 1 << 9 ' d0 always resides here at $000, executes as NOP - - -' Initialization code and data - after execution, space gets reused as scanbuff - - ' Move main program into maincode area - -:move mov $1EF, main_begin + main_size - 1 - sub :move,d0s0 ' (do reverse move to avoid overwrite) - djnz main_ctr,#:move - - ' Build scanbuff display routine into scancode - -:waitvid mov scancode+0, i0 ' org scancode -:shr mov scancode+1, i1 ' waitvid colorbuff+0, scanbuff+0 - add :waitvid, d1 ' shr scanbuff+0,#8 - add :shr, d1 ' waitvid colorbuff+1, scanbuff+1 - add i0, d0s0 ' shr scanbuff+1,#8 - add i1, d0 ' ... - djnz scan_ctr, #:waitvid ' waitvid colorbuff+cols-1, scanbuff+cols-1 - - mov scancode+cols*2-1, i2 ' mov vscl,#hf - mov scancode+cols*2+0, i3 ' waitvid hvsync,#0 - mov scancode+cols*2+1, i4 ' jmp #scanret - - ' Init I/O registers and sync COGs' video circuits - - mov dira, reg_dira ' set pin directions - mov dirb, reg_dirb - movi frqa, #(pr / 5) << 2 ' set pixel rate - mov vcfg, reg_vcfg ' set video configuration - mov vscl, #1 ' set video to reload on every pixel - waitcnt sync_cnt, colormask ' wait for start value in cnt, add ~1ms - movi ctra, #%00001_110 ' COGs in sync! enable PLLs now - NCOs locked! - waitcnt sync_cnt, #0 ' wait ~1ms for PLLs to stabilize - PLLs locked! - mov vscl, #100 ' insure initial WAITVIDs lock cleanly - - ' Jump to main loop - - jmp #vsync ' jump to vsync - WAITVIDs will now be locked! - - ' Data - -d0s0 long 1 << 9 + 1 -d1 long 1 << 10 -main_ctr long main_size -scan_ctr long cols - -i0 waitvid colorbuff+0, scanbuff+0 -i1 shr scanbuff+0, #8 -i2 mov vscl, #hf -i3 waitvid hvsync, #0 -i4 jmp #scanret - -reg_dira long 0 ' set at runtime -reg_dirb long 0 ' set at runtime -reg_vcfg long 0 ' set at runtime -sync_cnt long 0 ' set at runtime - - ' Directives - - fit scancode ' make sure initialization code and data fit -main_begin org maincode ' main code follows (gets moved into maincode) - - -' Main loop, display field - each COG alternately builds and displays four scan lines - -vsync mov x, #vs ' do vertical sync lines - call #blank_vsync - -vb_lines mov x, #vb ' do vertical back porch lines (# set at runtime) - call #blank_vsync - - mov screen_ptr, screen_base ' reset screen pointer to upper-left character - mov row, #0 ' reset row counter for cursor insertion - mov fours, #rows * 4 / 2 ' set number of 4-line builds for whole screen - - ' Build four scan lines into scanbuff - -fourline mov font_ptr, font_part ' get address of appropriate font section - shl font_ptr, #8+2 - add font_ptr, font_base - - movd :pixa, #scanbuff-1 ' reset scanbuff address (pre-decremented) - movd :cola, #colorbuff-1 ' reset colorbuff address (pre-decremented) - movd :colb, #colorbuff-1 - - mov y, #2 ' must build scanbuff in two sections because - mov vscl, vscl_line2x ' ..pixel counter is limited to twelve bits - -:halfrow waitvid underscore, #0 ' output lows to let other COG drive VGA pins - mov x, #cols/2 ' ..for 2 scan lines, ready for half a row - -:column rdword z, screen_ptr ' get character and colors from screen memory - mov bg, z - and z, #$ff ' mask character code - shl z, #2 ' * 4 - add z, font_ptr ' add font section address to point to 8*4 pixels - add :pixa, d0 ' increment scanbuff destination addresses - add screen_ptr, #2 ' increment screen memory address -:pixa rdlong scanbuff, z ' read pixel long (8*4) into scanbuff - - ror bg, #12 ' background color in bits 3..0 - mov fg, bg ' foreground color in bits 31..28 - shr fg, #28 ' bits 3..0 - add fg, #fg_clut ' + offset to foreground CLUT - movs :cola, fg - add :cola, d0 - add bg, #bg_clut ' + offset to background CLUT - movs :colb, bg - add :colb, d0 -:cola mov colorbuff, 0-0 -:colb or colorbuff, 0-0 - - djnz x, #:column ' another character in this half-row? - - djnz y, #:halfrow ' loop to do 2nd half-row, time for 2nd WAITVID - - sub screen_ptr, #2*cols ' back up to start of same row in screen memory - - ' Insert cursors into scanbuff - - mov z, #2 ' ready for two cursors - -:cursor rdbyte x, cursor_base ' x in range? - add cursor_base, #1 - cmp x, #cols wc - - rdbyte y, cursor_base ' y match? - add cursor_base, #1 - cmp y, row wz - - rdbyte y, cursor_base ' get cursor mode - add cursor_base, #1 - - if_nc_or_nz jmp #:nocursor ' if cursor not in scanbuff, no cursor - - add x, #scanbuff ' cursor in scanbuff, set scanbuff address - movd :xor, x - - test y, #%010 wc ' get mode bits into flags - test y, #%001 wz - if_nc_and_z jmp #:nocursor ' if cursor disabled, no cursor - - if_c_and_z test slowbit, cnt wc ' if blink mode, get blink state - if_c_and_nz test fastbit, cnt wc - - test y, #%100 wz ' get box or underscore cursor piece - if_z mov x, longmask - if_nz mov x, underscore - if_nz cmp font_part, #3 wz ' if underscore, must be last font section - -:xor if_nc_and_z xor scanbuff, x ' conditionally xor cursor into scanbuff - -:nocursor djnz z, #:cursor ' second cursor? - - sub cursor_base, #3*2 ' restore cursor base - - ' Display four scan lines from scanbuff - - mov y, #4 ' ready for four scan lines - -scanline mov vscl, vscl_chr ' set pixel rate for characters - jmp #scancode ' jump to scanbuff display routine in scancode -scanret mov vscl, #hs ' do horizontal sync pixels - waitvid hvsync, #1 ' #1 makes hsync active - mov vscl, #hb ' do horizontal back porch pixels - waitvid hvsync, #0 ' #0 makes hsync inactive - shr scanbuff+cols-1, #8 ' shift last column's pixels right by 8 - djnz y, #scanline ' another scan line? - - ' Next group of four scan lines - - add font_part, #2 ' if font_part + 2 => 4, subtract 4 (new row) - cmpsub font_part, #4 wc ' c=0 for same row, c=1 for new row - if_c add screen_ptr, #2*cols ' if new row, advance screen pointer - if_c add row, #1 ' if new row, increment row counter - djnz fours, #fourline ' another 4-line build/display? - - ' Visible section done, do vertical sync front porch lines - - wrlong longmask,par ' write -1 to refresh indicator - -vf_lines mov x,#vf ' do vertical front porch lines (# set at runtime) - call #blank - - jmp #vsync ' new field, loop to vsync - - ' Subroutine - do blank lines - -blank_vsync xor hvsync,#$101 ' flip vertical sync bits - -blank mov vscl, hx ' do blank pixels - waitvid hvsync, #0 - mov vscl, #hf ' do horizontal front porch pixels - waitvid hvsync, #0 - mov vscl, #hs ' do horizontal sync pixels - waitvid hvsync, #1 - mov vscl, #hb ' do horizontal back porch pixels - waitvid hvsync, #0 - djnz x,#blank ' another line? -blank_ret -blank_vsync_ret - ret - - ' Data - -screen_base long 0 ' set at runtime (3 contiguous longs) -cursor_base long 0 ' set at runtime - -font_base long 0 ' set at runtime -font_part long 0 ' set at runtime - -hx long hp ' visible pixels per scan line -vscl_line long hp + hf + hs + hb ' total number of pixels per scan line -vscl_line2x long (hp + hf + hs + hb) * 2 ' total number of pixels per 2 scan lines -vscl_chr long 1 << 12 + 8 ' 1 clock per pixel and 8 pixels per set -colormask long $FCFC ' mask to isolate R,G,B bits from H,V -longmask long $FFFFFFFF ' all bits set -slowbit long 1 << 25 ' cnt mask for slow cursor blink -fastbit long 1 << 24 ' cnt mask for fast cursor blink -underscore long $FFFF0000 ' underscore cursor pattern -hv long hv_inactive ' -H,-V states -hvsync long hv_inactive ^ $200 ' +/-H,-V states - -bg_clut long %00000011_00000011 ' black - long %00000011_00001011 ' dark blue - long %00000011_00100011 ' dark green - long %00000011_00101011 ' dark cyan - long %00000011_10000011 ' dark red - long %00000011_10001011 ' dark magenta - long %00000011_10100011 ' brown - long %00000011_10101011 ' light gray - long %00000011_01010111 ' dark gray - long %00000011_00001111 ' light blue - long %00000011_00110011 ' light green - long %00000011_00111111 ' light cyan - long %00000011_11000011 ' light red - long %00000011_11001111 ' light magenta - long %00000011_11110011 ' light yellow - long %00000011_11111111 ' white - -fg_clut long %00000011_00000011 ' black - long %00000111_00000011 ' dark blue - long %00010011_00000011 ' dark green - long %00010111_00000011 ' dark cyan - long %01000011_00000011 ' dark red - long %01000111_00000011 ' dark magenta - long %01010011_00000011 ' brown - long %10101011_00000011 ' light gray - long %01010111_00000011 ' dark gray - long %00001011_00000011 ' blue - long %00100011_00000011 ' green - long %00101011_00000011 ' cyan - long %10000011_00000011 ' red - long %10001011_00000011 ' magenta - long %10100011_00000011 ' yellow - long %11111111_00000011 ' white - - ' Uninitialized data - -screen_ptr res 1 -font_ptr res 1 - -x res 1 -y res 1 -z res 1 -fg res 1 -bg res 1 - -row res 1 -fours res 1 - - - fit $1f0 - -' 8 x 12 font - characters 0..127 -' -' Each long holds four scan lines of a single character. The longs are arranged into -' groups of 128 which represent all characters (0..127). There are four groups which -' each contain a vertical part of all characters. They are ordered top, middle, and -' bottom. - -font long - long $0082ba00,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 - long $00000000,$6e660000,$66660000,$18181818,$00000000,$00000000,$18181818,$18181818 - long $0000ffff,$00000000,$00000000,$00000000,$00000000,$18181818,$18181818,$18181818 - long $00000000,$18181818,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 - long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 - long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 - long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 - long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 - long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 - long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 - long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 - long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 - long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 - long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 - long $00000000,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 - long $00000000,$6e660000,$66660000,$24242424,$00000000,$00000000,$24242424,$24242424 - long $00ff00ff,$ff000000,$00000000,$00000000,$00000000,$24242424,$24242424,$24242424 - long $00000000,$24242424,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 - long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 - long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 - long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 - long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 - long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 - long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 - long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 - long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 - long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 - long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 - long $82008282,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 - long $187e1818,$0066767e,$00183c24,$1f181818,$1f000000,$f8000000,$f8181818,$ff181818 - long $00000000,$0000ffff,$00000000,$00000000,$00000000,$f8181818,$1f181818,$ff181818 - long $ff000000,$18181818,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 - long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 - long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 - long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 - long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 - long $6a7a6262,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 - long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 - long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 - long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 - long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 - long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 - long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 - long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 - long $00000000,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 - long $187e1818,$0066767e,$00183c24,$20272424,$203f0000,$04fc0000,$04e42424,$00e72424 - long $00000000,$0000ff00,$ff000000,$00000000,$00000000,$04e42424,$20272424,$00e72424 - long $00ff0000,$24242424,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 - long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 - long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 - long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 - long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 - long $76766666,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 - long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 - long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 - long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 - long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 - long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 - long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 - long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 - long $82820082,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 - long $007e0018,$18181818,$30303078,$0000001f,$1818181f,$181818f8,$000000f8,$181818ff - long $00000000,$00000000,$0000ffff,$ff000000,$00000000,$181818f8,$1818181f,$000000ff - long $181818ff,$18181818,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 - long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 - long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c - long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 - long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 - long $3c62027a,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 - long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 - long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e - long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 - long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 - long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 - long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 - long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 - long $00000000,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 - long $007e0018,$18181818,$30303078,$00003f20,$24242720,$2424e404,$0000fc04,$2424e700 - long $00000000,$00000000,$0000ff00,$00ff0000,$00000000,$2424e404,$24242720,$0000ff00 - long $2424e700,$24242424,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 - long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 - long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c - long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 - long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 - long $3c660676,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 - long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 - long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e - long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 - long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 - long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 - long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 - long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 - long $00ba8200,$00000000,$00002a55,$00000030,$00000018,$00000058,$00000018,$00000000 - long $00000000,$00000078,$00000030,$00000000,$18181818,$18181818,$00000000,$18181818 - long $00000000,$00000000,$00000000,$000000ff,$ffff0000,$18181818,$18181818,$00000000 - long $18181818,$18181818,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$0000000c,$00000000,$00000018,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000018,$0000000c,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$000000fe - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00003c66 - long $00000000,$00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000606,$00006060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000,$aa55aa55 - long $ff000000,$ff000000,$ff002a55,$ff000030,$ff000018,$ff000058,$ff000018,$ff000000 - long $ff000000,$ff000078,$ff000030,$00000000,$24242424,$24242424,$00000000,$24242424 - long $00000000,$00000000,$00000000,$000000ff,$ff00ff00,$24242424,$24242424,$00000000 - long $24242424,$24242424,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff00000c,$ff000000,$ff000018,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000018,$ff00000c,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff0000fe - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff003c66 - long $ff000000,$ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000606,$ff006060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff55aa55 - - -{{ -+------------------------------------------------------------------------------------------------------------------------------+ -| TERMS OF USE: Parallax Object Exchange 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/Hardware/Experimental/vga2/vgademo.eeprom b/Source/Hardware/Experimental/vga2/vgademo.eeprom deleted file mode 100644 index 37325441b03c1a48fb64e774436d37b94039af94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 diff --git a/Source/Hardware/Experimental/vga2/vgademo.list b/Source/Hardware/Experimental/vga2/vgademo.list deleted file mode 100644 index 22a95164..00000000 --- a/Source/Hardware/Experimental/vga2/vgademo.list +++ /dev/null @@ -1,3019 +0,0 @@ -|===========================================================================| -Objects : - -vgademo - | - +---vgacolour - | - +---vt100 - -Object Address : 0010 : Object Name : vgademo -Object Address : 17F4 : Object Name : vgacolour -Object Address : 2B64 : Object Name : vt100 - -Binary Image Information : -PBASE : 0010 -VBASE : 38B8 -DBASE : 38E8 -PCURR : 12FC -DCURR : 38EC -|===========================================================================| -|===========================================================================| -Object vgademo -Object Base is 0010 -|===========================================================================| -Object Constants -|===========================================================================| -Constant _xinfreq = 004C4B40 (5000000) -Constant _clkmode = 00000408 (1032) -Constant CHAR_W = 00000050 (80) -Constant CHAR_H = 0000001E (30) -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0018 Variable params -VBASE : 0018 LONG Size 0004 Variable seed -|===========================================================================| -Object DAT Blocks -|===========================================================================| -002C(0000) 00 00 00 00 | command long 0 -0030(0001) 20 07 | screen word $0720[CHAR_W*CHAR_H] -12F0(04B1) 00 | cursor byte 0,0,%110,0,0,0,0,0 -12F1(04B1) 00 | -12F2(04B1) 06 | -12F3(04B1) 00 | -12F4(04B2) 00 | -12F5(04B2) 00 | -12F6(04B2) 00 | -12F7(04B2) 00 | -12F8(04B3) 00 00 00 00 | sync long 0 -|===========================================================================| -|===========================================================================| -Spin Block main with 0 Parameters and 0 Extra Stack Longs. Method 1 -PUB main - -Local Parameter DBASE:0000 - Result -|===========================================================================| -20 vga.start(16, @screen, @cursor, @sync) -Addr : 12FC: 01 : Drop Anchor -Addr : 12FD: 37 03 : Constant Mask Y=3 00000010 -Addr : 12FF: A7 20 : Memory Op Word PBASE + ADDRESS Address = 0020 -Addr : 1301: 87 92 E0 : Memory Op Byte PBASE + ADDRESS Address = 12E0 -Addr : 1304: C7 92 E8 : Memory Op Long PBASE + ADDRESS Address = 12E8 -Addr : 1307: 06 05 01 : Call Obj.Sub 5 1 -21 params[0] := @command -Addr : 130A: C7 1C : Memory Op Long PBASE + ADDRESS Address = 001C -Addr : 130C: 35 : Constant 1 $00000000 -Addr : 130D: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -22 params[1] := @screen -Addr : 130F: A7 20 : Memory Op Word PBASE + ADDRESS Address = 0020 -Addr : 1311: 36 : Constant 2 $00000001 -Addr : 1312: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -23 params[2] := @cursor -Addr : 1314: 87 92 E0 : Memory Op Byte PBASE + ADDRESS Address = 12E0 -Addr : 1317: 37 00 : Constant Mask Y=0 00000002 -Addr : 1319: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -24 params[3] := @sync -Addr : 131B: C7 92 E8 : Memory Op Long PBASE + ADDRESS Address = 12E8 -Addr : 131E: 37 21 : Constant Mask Y=33 Decrement 00000003 -Addr : 1320: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -25 params[4] := CHAR_W -Addr : 1322: 38 50 : Constant 1 Bytes - 50 -Addr : 1324: 37 01 : Constant Mask Y=1 00000004 -Addr : 1326: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -26 params[5] := CHAR_H -Addr : 1328: 38 1E : Constant 1 Bytes - 1E -Addr : 132A: 38 05 : Constant 1 Bytes - 05 -Addr : 132C: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -28 vt100.start(@params) -Addr : 132E: 01 : Drop Anchor -Addr : 132F: 43 : Variable Operation Global Offset - 0 Address -Addr : 1330: 06 06 01 : Call Obj.Sub 6 1 -30 seed := cnt -Addr : 1333: 3F 91 : Register op CNT Read -Addr : 1335: 59 : Variable Operation Global Offset - 6 Write -32 str(string(27,"[2;34m",27,"[2J",27,"[H","Hello World!",13,10)) -Addr : 1336: 01 : Drop Anchor -Addr : 1337: PBASE Constant Address of Label0008 -Addr : 1337: 87 94 51 : Memory Op Byte PBASE + ADDRESS Address = 1451 -Addr : 133A: 05 03 : Call Sub 3 -33 str(string(27,"[7m","Inverse on",13,10)) -Addr : 133C: 01 : Drop Anchor -Addr : 133D: PBASE Constant Address of Label0009 -Addr : 133D: 87 94 6E : Memory Op Byte PBASE + ADDRESS Address = 146E -Addr : 1340: 05 03 : Call Sub 3 -34 str(string(27,"[27m","Inverse off",13,10)) -Addr : 1342: 01 : Drop Anchor -Addr : 1343: PBASE Constant Address of Label000A -Addr : 1343: 87 94 7F : Memory Op Byte PBASE + ADDRESS Address = 147F -Addr : 1346: 05 03 : Call Sub 3 -35 str(string(27,"[1m","Highlite on",13,10)) -Addr : 1348: 01 : Drop Anchor -Addr : 1349: PBASE Constant Address of Label000B -Addr : 1349: 87 94 92 : Memory Op Byte PBASE + ADDRESS Address = 1492 -Addr : 134C: 05 03 : Call Sub 3 -36 str(string(27,"[2m","Highlite off",13,10)) -Addr : 134E: 01 : Drop Anchor -Addr : 134F: PBASE Constant Address of Label000C -Addr : 134F: 87 94 A4 : Memory Op Byte PBASE + ADDRESS Address = 14A4 -Addr : 1352: 05 03 : Call Sub 3 -37 str(string(27,"[4m","Underline on ",27,"[1m + highlite ",27,"[2m",27,"[7m + inverse ",27,"[0m all off + default color.",13,10)) -Addr : 1354: 01 : Drop Anchor -Addr : 1355: PBASE Constant Address of Label000D -Addr : 1355: 87 94 B7 : Memory Op Byte PBASE + ADDRESS Address = 14B7 -Addr : 1358: 05 03 : Call Sub 3 -38 str(string(27,"[40m","BGD 0")) -Addr : 135A: 01 : Drop Anchor -Addr : 135B: PBASE Constant Address of Label000E -Addr : 135B: 87 95 0B : Memory Op Byte PBASE + ADDRESS Address = 150B -Addr : 135E: 05 03 : Call Sub 3 -39 str(string(27,"[41m","BGD 1")) -Addr : 1360: 01 : Drop Anchor -Addr : 1361: PBASE Constant Address of Label000F -Addr : 1361: 87 95 16 : Memory Op Byte PBASE + ADDRESS Address = 1516 -Addr : 1364: 05 03 : Call Sub 3 -40 str(string(27,"[42m","BGD 2")) -Addr : 1366: 01 : Drop Anchor -Addr : 1367: PBASE Constant Address of Label0010 -Addr : 1367: 87 95 21 : Memory Op Byte PBASE + ADDRESS Address = 1521 -Addr : 136A: 05 03 : Call Sub 3 -41 str(string(27,"[43m","BGD 3")) -Addr : 136C: 01 : Drop Anchor -Addr : 136D: PBASE Constant Address of Label0011 -Addr : 136D: 87 95 2C : Memory Op Byte PBASE + ADDRESS Address = 152C -Addr : 1370: 05 03 : Call Sub 3 -42 str(string(27,"[44m","BGD 4")) -Addr : 1372: 01 : Drop Anchor -Addr : 1373: PBASE Constant Address of Label0012 -Addr : 1373: 87 95 37 : Memory Op Byte PBASE + ADDRESS Address = 1537 -Addr : 1376: 05 03 : Call Sub 3 -43 str(string(27,"[45m","BGD 5")) -Addr : 1378: 01 : Drop Anchor -Addr : 1379: PBASE Constant Address of Label0013 -Addr : 1379: 87 95 42 : Memory Op Byte PBASE + ADDRESS Address = 1542 -Addr : 137C: 05 03 : Call Sub 3 -44 str(string(27,"[46m","BGD 6")) -Addr : 137E: 01 : Drop Anchor -Addr : 137F: PBASE Constant Address of Label0014 -Addr : 137F: 87 95 4D : Memory Op Byte PBASE + ADDRESS Address = 154D -Addr : 1382: 05 03 : Call Sub 3 -45 str(string(27,"[47m","BGD 7",13,10)) -Addr : 1384: 01 : Drop Anchor -Addr : 1385: PBASE Constant Address of Label0015 -Addr : 1385: 87 95 58 : Memory Op Byte PBASE + ADDRESS Address = 1558 -Addr : 1388: 05 03 : Call Sub 3 -47 str(string(27,"[41m")) -Addr : 138A: 01 : Drop Anchor -Addr : 138B: PBASE Constant Address of Label0016 -Addr : 138B: 87 95 65 : Memory Op Byte PBASE + ADDRESS Address = 1565 -Addr : 138E: 05 03 : Call Sub 3 -49 str(string(27,"[30m","FGD 0")) -Addr : 1390: 01 : Drop Anchor -Addr : 1391: PBASE Constant Address of Label0017 -Addr : 1391: 87 95 6B : Memory Op Byte PBASE + ADDRESS Address = 156B -Addr : 1394: 05 03 : Call Sub 3 -50 str(string(27,"[31m","FGD 1")) -Addr : 1396: 01 : Drop Anchor -Addr : 1397: PBASE Constant Address of Label0018 -Addr : 1397: 87 95 76 : Memory Op Byte PBASE + ADDRESS Address = 1576 -Addr : 139A: 05 03 : Call Sub 3 -51 str(string(27,"[32m","FGD 2")) -Addr : 139C: 01 : Drop Anchor -Addr : 139D: PBASE Constant Address of Label0019 -Addr : 139D: 87 95 81 : Memory Op Byte PBASE + ADDRESS Address = 1581 -Addr : 13A0: 05 03 : Call Sub 3 -52 str(string(27,"[33m","FGD 3")) -Addr : 13A2: 01 : Drop Anchor -Addr : 13A3: PBASE Constant Address of Label001A -Addr : 13A3: 87 95 8C : Memory Op Byte PBASE + ADDRESS Address = 158C -Addr : 13A6: 05 03 : Call Sub 3 -53 str(string(27,"[34m","FGD 4")) -Addr : 13A8: 01 : Drop Anchor -Addr : 13A9: PBASE Constant Address of Label001B -Addr : 13A9: 87 95 97 : Memory Op Byte PBASE + ADDRESS Address = 1597 -Addr : 13AC: 05 03 : Call Sub 3 -54 str(string(27,"[35m","FGD 5")) -Addr : 13AE: 01 : Drop Anchor -Addr : 13AF: PBASE Constant Address of Label001C -Addr : 13AF: 87 95 A2 : Memory Op Byte PBASE + ADDRESS Address = 15A2 -Addr : 13B2: 05 03 : Call Sub 3 -55 str(string(27,"[36m","FGD 6")) -Addr : 13B4: 01 : Drop Anchor -Addr : 13B5: PBASE Constant Address of Label001D -Addr : 13B5: 87 95 AD : Memory Op Byte PBASE + ADDRESS Address = 15AD -Addr : 13B8: 05 03 : Call Sub 3 -56 str(string(27,"[37m","FGD 7",13,10)) -Addr : 13BA: 01 : Drop Anchor -Addr : 13BB: PBASE Constant Address of Label001E -Addr : 13BB: 87 95 B8 : Memory Op Byte PBASE + ADDRESS Address = 15B8 -Addr : 13BE: 05 03 : Call Sub 3 -57 str(string(27,"[1;40m")) -Addr : 13C0: 01 : Drop Anchor -Addr : 13C1: PBASE Constant Address of Label001F -Addr : 13C1: 87 95 C5 : Memory Op Byte PBASE + ADDRESS Address = 15C5 -Addr : 13C4: 05 03 : Call Sub 3 -58 str(string(27,"[30m","FGD 0")) -Addr : 13C6: 01 : Drop Anchor -Addr : 13C7: PBASE Constant Address of Label0020 -Addr : 13C7: 87 95 CD : Memory Op Byte PBASE + ADDRESS Address = 15CD -Addr : 13CA: 05 03 : Call Sub 3 -59 str(string(27,"[31m","FGD 1")) -Addr : 13CC: 01 : Drop Anchor -Addr : 13CD: PBASE Constant Address of Label0021 -Addr : 13CD: 87 95 D8 : Memory Op Byte PBASE + ADDRESS Address = 15D8 -Addr : 13D0: 05 03 : Call Sub 3 -60 str(string(27,"[32m","FGD 2")) -Addr : 13D2: 01 : Drop Anchor -Addr : 13D3: PBASE Constant Address of Label0022 -Addr : 13D3: 87 95 E3 : Memory Op Byte PBASE + ADDRESS Address = 15E3 -Addr : 13D6: 05 03 : Call Sub 3 -61 str(string(27,"[33m","FGD 3")) -Addr : 13D8: 01 : Drop Anchor -Addr : 13D9: PBASE Constant Address of Label0023 -Addr : 13D9: 87 95 EE : Memory Op Byte PBASE + ADDRESS Address = 15EE -Addr : 13DC: 05 03 : Call Sub 3 -62 str(string(27,"[34m","FGD 4")) -Addr : 13DE: 01 : Drop Anchor -Addr : 13DF: PBASE Constant Address of Label0024 -Addr : 13DF: 87 95 F9 : Memory Op Byte PBASE + ADDRESS Address = 15F9 -Addr : 13E2: 05 03 : Call Sub 3 -63 str(string(27,"[35m","FGD 5")) -Addr : 13E4: 01 : Drop Anchor -Addr : 13E5: PBASE Constant Address of Label0025 -Addr : 13E5: 87 96 04 : Memory Op Byte PBASE + ADDRESS Address = 1604 -Addr : 13E8: 05 03 : Call Sub 3 -64 str(string(27,"[36m","FGD 6")) -Addr : 13EA: 01 : Drop Anchor -Addr : 13EB: PBASE Constant Address of Label0026 -Addr : 13EB: 87 96 0F : Memory Op Byte PBASE + ADDRESS Address = 160F -Addr : 13EE: 05 03 : Call Sub 3 -65 str(string(27,"[37m","FGD 7",13,10)) -Addr : 13F0: 01 : Drop Anchor -Addr : 13F1: PBASE Constant Address of Label0027 -Addr : 13F1: 87 96 1A : Memory Op Byte PBASE + ADDRESS Address = 161A -Addr : 13F4: 05 03 : Call Sub 3 -66 str(string(27,"[2m","The quick brown fox jumps over the lazy dog.", 13, 10)) -Addr : 13F6: 01 : Drop Anchor -Addr : 13F7: PBASE Constant Address of Label0028 -Addr : 13F7: 87 96 27 : Memory Op Byte PBASE + ADDRESS Address = 1627 -Addr : 13FA: 05 03 : Call Sub 3 -68 str(string("Setting a scroll range below here.",13,10)) -Addr : 13FC: 01 : Drop Anchor -Addr : 13FD: PBASE Constant Address of Label0029 -Addr : 13FD: 87 96 5A : Memory Op Byte PBASE + ADDRESS Address = 165A -Addr : 1400: 05 03 : Call Sub 3 -69 str(string(27,"[24H","This part of the screen remains ",27,"[4mstatic",27,"[24m, since it is below the scrolling region.")) -Addr : 1402: 01 : Drop Anchor -Addr : 1403: PBASE Constant Address of Label002A -Addr : 1403: 87 96 7F : Memory Op Byte PBASE + ADDRESS Address = 167F -Addr : 1406: 05 03 : Call Sub 3 -70 str(string(27,"[12;23r",27,"[41m")) -Addr : 1408: 01 : Drop Anchor -Addr : 1409: PBASE Constant Address of Label002B -Addr : 1409: 87 96 DD : Memory Op Byte PBASE + ADDRESS Address = 16DD -Addr : 140C: 05 03 : Call Sub 3 -Addr : 140E: Label002C -72 chr(27) -Addr : 140E: 01 : Drop Anchor -Addr : 140F: 38 1B : Constant 1 Bytes - 1B -Addr : 1411: 05 02 : Call Sub 2 -73 chr("[") -Addr : 1413: 01 : Drop Anchor -Addr : 1414: 38 5B : Constant 1 Bytes - 5B -Addr : 1416: 05 02 : Call Sub 2 -74 chr("3") -Addr : 1418: 01 : Drop Anchor -Addr : 1419: 38 33 : Constant 1 Bytes - 33 -Addr : 141B: 05 02 : Call Sub 2 -75 chr("0" + rand & 7) -Addr : 141D: 01 : Drop Anchor -Addr : 141E: 38 30 : Constant 1 Bytes - 30 -Addr : 1420: 00 : Drop Anchor Push -Addr : 1421: 05 04 : Call Sub 4 -Addr : 1423: 37 22 : Constant Mask Y=34 Decrement 00000007 -Addr : 1425: E8 : Math Op & -Addr : 1426: EC : Math Op + -Addr : 1427: 05 02 : Call Sub 2 -76 chr("m") -Addr : 1429: 01 : Drop Anchor -Addr : 142A: 38 6D : Constant 1 Bytes - 6D -Addr : 142C: 05 02 : Call Sub 2 -77 chr(27) -Addr : 142E: 01 : Drop Anchor -Addr : 142F: 38 1B : Constant 1 Bytes - 1B -Addr : 1431: 05 02 : Call Sub 2 -78 chr("[") -Addr : 1433: 01 : Drop Anchor -Addr : 1434: 38 5B : Constant 1 Bytes - 5B -Addr : 1436: 05 02 : Call Sub 2 -79 chr("4") -Addr : 1438: 01 : Drop Anchor -Addr : 1439: 38 34 : Constant 1 Bytes - 34 -Addr : 143B: 05 02 : Call Sub 2 -80 chr("0" + rand & 7) -Addr : 143D: 01 : Drop Anchor -Addr : 143E: 38 30 : Constant 1 Bytes - 30 -Addr : 1440: 00 : Drop Anchor Push -Addr : 1441: 05 04 : Call Sub 4 -Addr : 1443: 37 22 : Constant Mask Y=34 Decrement 00000007 -Addr : 1445: E8 : Math Op & -Addr : 1446: EC : Math Op + -Addr : 1447: 05 02 : Call Sub 2 -81 chr("m") -Addr : 1449: 01 : Drop Anchor -Addr : 144A: 38 6D : Constant 1 Bytes - 6D -Addr : 144C: 05 02 : Call Sub 2 -82 str(string("Four score and seven years ago our ",27,"[1mfathers",27,"[2m brought forth, upon this continent, a new ",27,"[1mnation",27,"[2m, conceived in Liberty, and dedicated to the proposition that all men are created equal. ")) -Addr : 144E: 01 : Drop Anchor -Addr : 144F: PBASE Constant Address of Label002F -Addr : 144F: 87 96 EB : Memory Op Byte PBASE + ADDRESS Address = 16EB -Addr : 1452: 05 03 : Call Sub 3 -83 waitcnt(clkfreq/4 + cnt) -Addr : 1454: 35 : Constant 1 $00000000 -Addr : 1455: C0 : Memory Op Long POP Address READ -Addr : 1456: 37 01 : Constant Mask Y=1 00000004 -Addr : 1458: F6 : Math Op / -Addr : 1459: 3F 91 : Register op CNT Read -Addr : 145B: EC : Math Op + -Addr : 145C: 23 : WaitCnt(count) -Addr : 145D: Label002D -Addr : 145D: JMP Label002C -Addr : 145D: 04 FF AE : Jmp 140E -82 -Addr : 1460: Label002E -Addr : 1460: 32 : Return -Addr : 1461: Label0008 -Addr : 1461: Data : 1B 5B 32 3B 33 34 6D 1B .[2;34m. -Addr : 1469: Data : 5B 32 4A 1B 5B 48 48 65 [2J.[HHe -Addr : 1471: Data : 6C 6C 6F 20 57 6F 72 6C llo Worl -Addr : 1479: Data : 64 21 0D 0A 00 d!... -Addr : 147E: Label0009 -Addr : 147E: Data : 1B 5B 37 6D 49 6E 76 65 .[7mInve -Addr : 1486: Data : 72 73 65 20 6F 6E 0D 0A rse on.. -Addr : 148E: Data : 00 . -Addr : 148F: Label000A -Addr : 148F: Data : 1B 5B 32 37 6D 49 6E 76 .[27mInv -Addr : 1497: Data : 65 72 73 65 20 6F 66 66 erse off -Addr : 149F: Data : 0D 0A 00 ... -Addr : 14A2: Label000B -Addr : 14A2: Data : 1B 5B 31 6D 48 69 67 68 .[1mHigh -Addr : 14AA: Data : 6C 69 74 65 20 6F 6E 0D lite on. -Addr : 14B2: Data : 0A 00 .. -Addr : 14B4: Label000C -Addr : 14B4: Data : 1B 5B 32 6D 48 69 67 68 .[2mHigh -Addr : 14BC: Data : 6C 69 74 65 20 6F 66 66 lite off -Addr : 14C4: Data : 0D 0A 00 ... -Addr : 14C7: Label000D -Addr : 14C7: Data : 1B 5B 34 6D 55 6E 64 65 .[4mUnde -Addr : 14CF: Data : 72 6C 69 6E 65 20 6F 6E rline on -Addr : 14D7: Data : 20 1B 5B 31 6D 20 2B 20 .[1m + -Addr : 14DF: Data : 68 69 67 68 6C 69 74 65 highlite -Addr : 14E7: Data : 20 1B 5B 32 6D 1B 5B 37 .[2m.[7 -Addr : 14EF: Data : 6D 20 2B 20 69 6E 76 65 m + inve -Addr : 14F7: Data : 72 73 65 20 1B 5B 30 6D rse .[0m -Addr : 14FF: Data : 20 61 6C 6C 20 6F 66 66 all off -Addr : 1507: Data : 20 2B 20 64 65 66 61 75 + defau -Addr : 150F: Data : 6C 74 20 63 6F 6C 6F 72 lt color -Addr : 1517: Data : 2E 0D 0A 00 .... -Addr : 151B: Label000E -Addr : 151B: Data : 1B 5B 34 30 6D 42 47 44 .[40mBGD -Addr : 1523: Data : 20 30 00 0. -Addr : 1526: Label000F -Addr : 1526: Data : 1B 5B 34 31 6D 42 47 44 .[41mBGD -Addr : 152E: Data : 20 31 00 1. -Addr : 1531: Label0010 -Addr : 1531: Data : 1B 5B 34 32 6D 42 47 44 .[42mBGD -Addr : 1539: Data : 20 32 00 2. -Addr : 153C: Label0011 -Addr : 153C: Data : 1B 5B 34 33 6D 42 47 44 .[43mBGD -Addr : 1544: Data : 20 33 00 3. -Addr : 1547: Label0012 -Addr : 1547: Data : 1B 5B 34 34 6D 42 47 44 .[44mBGD -Addr : 154F: Data : 20 34 00 4. -Addr : 1552: Label0013 -Addr : 1552: Data : 1B 5B 34 35 6D 42 47 44 .[45mBGD -Addr : 155A: Data : 20 35 00 5. -Addr : 155D: Label0014 -Addr : 155D: Data : 1B 5B 34 36 6D 42 47 44 .[46mBGD -Addr : 1565: Data : 20 36 00 6. -Addr : 1568: Label0015 -Addr : 1568: Data : 1B 5B 34 37 6D 42 47 44 .[47mBGD -Addr : 1570: Data : 20 37 0D 0A 00 7... -Addr : 1575: Label0016 -Addr : 1575: Data : 1B 5B 34 31 6D 00 .[41m. -Addr : 157B: Label0017 -Addr : 157B: Data : 1B 5B 33 30 6D 46 47 44 .[30mFGD -Addr : 1583: Data : 20 30 00 0. -Addr : 1586: Label0018 -Addr : 1586: Data : 1B 5B 33 31 6D 46 47 44 .[31mFGD -Addr : 158E: Data : 20 31 00 1. -Addr : 1591: Label0019 -Addr : 1591: Data : 1B 5B 33 32 6D 46 47 44 .[32mFGD -Addr : 1599: Data : 20 32 00 2. -Addr : 159C: Label001A -Addr : 159C: Data : 1B 5B 33 33 6D 46 47 44 .[33mFGD -Addr : 15A4: Data : 20 33 00 3. -Addr : 15A7: Label001B -Addr : 15A7: Data : 1B 5B 33 34 6D 46 47 44 .[34mFGD -Addr : 15AF: Data : 20 34 00 4. -Addr : 15B2: Label001C -Addr : 15B2: Data : 1B 5B 33 35 6D 46 47 44 .[35mFGD -Addr : 15BA: Data : 20 35 00 5. -Addr : 15BD: Label001D -Addr : 15BD: Data : 1B 5B 33 36 6D 46 47 44 .[36mFGD -Addr : 15C5: Data : 20 36 00 6. -Addr : 15C8: Label001E -Addr : 15C8: Data : 1B 5B 33 37 6D 46 47 44 .[37mFGD -Addr : 15D0: Data : 20 37 0D 0A 00 7... -Addr : 15D5: Label001F -Addr : 15D5: Data : 1B 5B 31 3B 34 30 6D 00 .[1;40m. -Addr : 15DD: Data : -Addr : 15DD: Label0020 -Addr : 15DD: Data : 1B 5B 33 30 6D 46 47 44 .[30mFGD -Addr : 15E5: Data : 20 30 00 0. -Addr : 15E8: Label0021 -Addr : 15E8: Data : 1B 5B 33 31 6D 46 47 44 .[31mFGD -Addr : 15F0: Data : 20 31 00 1. -Addr : 15F3: Label0022 -Addr : 15F3: Data : 1B 5B 33 32 6D 46 47 44 .[32mFGD -Addr : 15FB: Data : 20 32 00 2. -Addr : 15FE: Label0023 -Addr : 15FE: Data : 1B 5B 33 33 6D 46 47 44 .[33mFGD -Addr : 1606: Data : 20 33 00 3. -Addr : 1609: Label0024 -Addr : 1609: Data : 1B 5B 33 34 6D 46 47 44 .[34mFGD -Addr : 1611: Data : 20 34 00 4. -Addr : 1614: Label0025 -Addr : 1614: Data : 1B 5B 33 35 6D 46 47 44 .[35mFGD -Addr : 161C: Data : 20 35 00 5. -Addr : 161F: Label0026 -Addr : 161F: Data : 1B 5B 33 36 6D 46 47 44 .[36mFGD -Addr : 1627: Data : 20 36 00 6. -Addr : 162A: Label0027 -Addr : 162A: Data : 1B 5B 33 37 6D 46 47 44 .[37mFGD -Addr : 1632: Data : 20 37 0D 0A 00 7... -Addr : 1637: Label0028 -Addr : 1637: Data : 1B 5B 32 6D 54 68 65 20 .[2mThe -Addr : 163F: Data : 71 75 69 63 6B 20 62 72 quick br -Addr : 1647: Data : 6F 77 6E 20 66 6F 78 20 own fox -Addr : 164F: Data : 6A 75 6D 70 73 20 6F 76 jumps ov -Addr : 1657: Data : 65 72 20 74 68 65 20 6C er the l -Addr : 165F: Data : 61 7A 79 20 64 6F 67 2E azy dog. -Addr : 1667: Data : 0D 0A 00 ... -Addr : 166A: Label0029 -Addr : 166A: Data : 53 65 74 74 69 6E 67 20 Setting -Addr : 1672: Data : 61 20 73 63 72 6F 6C 6C a scroll -Addr : 167A: Data : 20 72 61 6E 67 65 20 62 range b -Addr : 1682: Data : 65 6C 6F 77 20 68 65 72 elow her -Addr : 168A: Data : 65 2E 0D 0A 00 e.... -Addr : 168F: Label002A -Addr : 168F: Data : 1B 5B 32 34 48 54 68 69 .[24HThi -Addr : 1697: Data : 73 20 70 61 72 74 20 6F s part o -Addr : 169F: Data : 66 20 74 68 65 20 73 63 f the sc -Addr : 16A7: Data : 72 65 65 6E 20 72 65 6D reen rem -Addr : 16AF: Data : 61 69 6E 73 20 1B 5B 34 ains .[4 -Addr : 16B7: Data : 6D 73 74 61 74 69 63 1B mstatic. -Addr : 16BF: Data : 5B 32 34 6D 2C 20 73 69 [24m, si -Addr : 16C7: Data : 6E 63 65 20 69 74 20 69 nce it i -Addr : 16CF: Data : 73 20 62 65 6C 6F 77 20 s below -Addr : 16D7: Data : 74 68 65 20 73 63 72 6F the scro -Addr : 16DF: Data : 6C 6C 69 6E 67 20 72 65 lling re -Addr : 16E7: Data : 67 69 6F 6E 2E 00 gion.. -Addr : 16ED: Label002B -Addr : 16ED: Data : 1B 5B 31 32 3B 32 33 72 .[12;23r -Addr : 16F5: Data : 1B 5B 34 31 6D 00 .[41m. -Addr : 16FB: Label002F -Addr : 16FB: Data : 46 6F 75 72 20 73 63 6F Four sco -Addr : 1703: Data : 72 65 20 61 6E 64 20 73 re and s -Addr : 170B: Data : 65 76 65 6E 20 79 65 61 even yea -Addr : 1713: Data : 72 73 20 61 67 6F 20 6F rs ago o -Addr : 171B: Data : 75 72 20 1B 5B 31 6D 66 ur .[1mf -Addr : 1723: Data : 61 74 68 65 72 73 1B 5B athers.[ -Addr : 172B: Data : 32 6D 20 62 72 6F 75 67 2m broug -Addr : 1733: Data : 68 74 20 66 6F 72 74 68 ht forth -Addr : 173B: Data : 2C 20 75 70 6F 6E 20 74 , upon t -Addr : 1743: Data : 68 69 73 20 63 6F 6E 74 his cont -Addr : 174B: Data : 69 6E 65 6E 74 2C 20 61 inent, a -Addr : 1753: Data : 20 6E 65 77 20 1B 5B 31 new .[1 -Addr : 175B: Data : 6D 6E 61 74 69 6F 6E 1B mnation. -Addr : 1763: Data : 5B 32 6D 2C 20 63 6F 6E [2m, con -Addr : 176B: Data : 63 65 69 76 65 64 20 69 ceived i -Addr : 1773: Data : 6E 20 4C 69 62 65 72 74 n Libert -Addr : 177B: Data : 79 2C 20 61 6E 64 20 64 y, and d -Addr : 1783: Data : 65 64 69 63 61 74 65 64 edicated -Addr : 178B: Data : 20 74 6F 20 74 68 65 20 to the -Addr : 1793: Data : 70 72 6F 70 6F 73 69 74 proposit -Addr : 179B: Data : 69 6F 6E 20 74 68 61 74 ion that -Addr : 17A3: Data : 20 61 6C 6C 20 6D 65 6E all men -Addr : 17AB: Data : 20 61 72 65 20 63 72 65 are cre -Addr : 17B3: Data : 61 74 65 64 20 65 71 75 ated equ -Addr : 17BB: Data : 61 6C 2E 20 20 20 00 al. . -|===========================================================================| -Spin Block chr with 1 Parameters and 0 Extra Stack Longs. Method 2 -PUB chr(ch) - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - ch -|===========================================================================| -87 command := $100 | ch -Addr : 17C2: 37 07 : Constant Mask Y=7 00000100 -Addr : 17C4: 64 : Variable Operation Local Offset - 1 Read -Addr : 17C5: EA : Math Op | -Addr : 17C6: C5 1C : Memory Op Long PBASE + WRITE Address = 001C -Addr : 17C8: Label0008 -88 repeat while command -Addr : 17C8: C4 1C : Memory Op Long PBASE + READ Address = 001C -Addr : 17CA: JZ Label000A -Addr : 17CA: 0A 02 : jz Address = 17CE 2 -Addr : 17CC: Label0009 -Addr : 17CC: JMP Label0008 -Addr : 17CC: 04 7A : Jmp 17C8 -6 -Addr : 17CE: Label000A -Addr : 17CE: 32 : Return -|===========================================================================| -Spin Block str with 1 Parameters and 1 Extra Stack Longs. Method 3 -PUB str(strptr) | i - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - strptr -Local Variable DBASE:0008 - i -|===========================================================================| -91 repeat i from 0 to strsize(strptr) -Addr : 17CF: 35 : Constant 1 $00000000 -Addr : 17D0: 69 : Variable Operation Local Offset - 2 Write -Addr : 17D1: Label0008 -92 chr(byte[strptr][i]) -Addr : 17D1: 01 : Drop Anchor -Addr : 17D2: 64 : Variable Operation Local Offset - 1 Read -Addr : 17D3: 68 : Variable Operation Local Offset - 2 Read -Addr : 17D4: 90 : Memory Op Byte POP Address POP Index READ -Addr : 17D5: 05 02 : Call Sub 2 -Addr : 17D7: Label0009 -91 repeat i from 0 to strsize(strptr) -Addr : 17D7: 35 : Constant 1 $00000000 -Addr : 17D8: 64 : Variable Operation Local Offset - 1 Read -Addr : 17D9: 16 : StrSize(String) -Addr : 17DA: Repeat i Step Label0008 -Addr : 17DA: 6A 02 74 : Variable Operation Local Offset - 2 Assign Repeat-Var loop Address= 17D1 -12 -Addr : 17DD: Label000A -Addr : 17DD: 32 : Return -|===========================================================================| -Spin Block rand with 0 Parameters and 0 Extra Stack Longs. Method 4 -PUB rand - -Local Parameter DBASE:0000 - Result -|===========================================================================| -95 seed := seed * 1103515245 + 12345 + CNT / 7777 -Addr : 17DE: 58 : Variable Operation Global Offset - 6 Read -Addr : 17DF: 3B 41 C6 4E 6D : Constant 4 Bytes - 41 C6 4E 6D -Addr : 17E4: F4 : Math Op * -Addr : 17E5: 39 30 39 : Constant 2 Bytes - 30 39 -Addr : 17E8: EC : Math Op + -Addr : 17E9: 3F 91 : Register op CNT Read -Addr : 17EB: 39 1E 61 : Constant 2 Bytes - 1E 61 -Addr : 17EE: F6 : Math Op / -Addr : 17EF: EC : Math Op + -Addr : 17F0: 59 : Variable Operation Global Offset - 6 Write -96 return seed -Addr : 17F1: 58 : Variable Operation Global Offset - 6 Read -Addr : 17F2: 33 : Return value -Addr : 17F3: Data : 32 2 -|===========================================================================| -Object vgacolour -Object Base is 17F4 -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0008 Variable cog -|===========================================================================| -Object DAT Blocks -|===========================================================================| -1800(0000) | org 0 ' set origin to $000 for start of program -1800(0000) 00 02 00 00 | d0 long 1 << 9 ' d0 always resides here at $000, executes as NOP -1804(0001) D1 DE BF A0 | :move mov $1EF, main_begin + main_size - 1 -1808(0002) 18 02 BC 84 | sub :move,d0s0 ' (do reverse move to avoid overwrite) -180C(0003) 01 34 FC E4 | djnz main_ctr,#:move -1810(0004) 1C 42 BD A0 | :waitvid mov scancode+0, i0 ' org scancode -1814(0005) 1D 44 BD A0 | :shr mov scancode+1, i1 ' waitvid colorbuff+0, scanbuff+0 -1818(0006) 19 08 BC 80 | add :waitvid, d1 ' shr scanbuff+0,#8 -181C(0007) 19 0A BC 80 | add :shr, d1 ' waitvid colorbuff+1, scanbuff+1 -1820(0008) 18 38 BC 80 | add i0, d0s0 ' shr scanbuff+1,#8 -1824(0009) 00 3A BC 80 | add i1, d0 ' ... -1828(000A) 04 36 FC E4 | djnz scan_ctr, #:waitvid ' waitvid colorbuff+cols-1, scanbuff+cols-1 -182C(000B) 1E 80 BE A0 | mov scancode+cols*2-1, i2 ' mov vscl,#hf -1830(000C) 1F 82 BE A0 | mov scancode+cols*2+0, i3 ' waitvid hvsync,#0 -1834(000D) 20 84 BE A0 | mov scancode+cols*2+1, i4 ' jmp #scanret -1838(000E) 21 EC BF A0 | mov dira, reg_dira ' set pin directions -183C(000F) 22 EE BF A0 | mov dirb, reg_dirb -1840(0010) 18 F4 FF 58 | movi frqa, #(pr / 5) << 2 ' set pixel rate -1844(0011) 23 FC BF A0 | mov vcfg, reg_vcfg ' set video configuration -1848(0012) 01 FE FF A0 | mov vscl, #1 ' set video to reload on every pixel -184C(0013) A7 49 BC F8 | waitcnt sync_cnt, colormask ' wait for start value in cnt, add ~1ms -1850(0014) 0E F0 FF 58 | movi ctra, #%00001_110 ' COGs in sync! enable PLLs now - NCOs locked! -1854(0015) 00 48 FC F8 | waitcnt sync_cnt, #0 ' wait ~1ms for PLLs to stabilize - PLLs locked! -1858(0016) 64 FE FF A0 | mov vscl, #100 ' insure initial WAITVIDs lock cleanly -185C(0017) 43 01 7C 5C | jmp #vsync ' jump to vsync - WAITVIDs will now be locked! -1860(0018) 01 02 00 00 | d0s0 long 1 << 9 + 1 -1864(0019) 00 04 00 00 | d1 long 1 << 10 -1868(001A) AD 00 00 00 | main_ctr long main_size -186C(001B) 50 00 00 00 | scan_ctr long cols -1870(001C) 01 A2 3C FC | i0 waitvid colorbuff+0, scanbuff+0 -1874(001D) 08 02 FC 28 | i1 shr scanbuff+0, #8 -1878(001E) 18 FE FF A0 | i2 mov vscl, #hf -187C(001F) 00 5A 7F FC | i3 waitvid hvsync, #0 -1880(0020) 85 01 7C 5C | i4 jmp #scanret -1884(0021) 00 00 00 00 | reg_dira long 0 ' set at runtime -1888(0022) 00 00 00 00 | reg_dirb long 0 ' set at runtime -188C(0023) 00 00 00 00 | reg_vcfg long 0 ' set at runtime -1890(0024) 00 00 00 00 | sync_cnt long 0 ' set at runtime -1894(0025) | fit scancode ' make sure initialization code and data fit -1894(0025) | There are 124 ($07C) Longs left in the cog -1894(0025) | main_begin org maincode ' main code follows (gets moved into maincode) -1894(0143) 03 A0 FF A0 | vsync mov x, #vs ' do vertical sync lines -1898(0144) 94 3D FF 5C | call #blank_vsync -189C(0145) 11 A0 FF A0 | vb_lines mov x, #vb ' do vertical back porch lines (# set at runtime) -18A0(0146) 94 3D FF 5C | call #blank_vsync -18A4(0147) 9F 9D BF A0 | mov screen_ptr, screen_base ' reset screen pointer to upper-left character -18A8(0148) 00 AA FF A0 | mov row, #0 ' reset row counter for cursor insertion -18AC(0149) 3C AC FF A0 | mov fours, #rows * 4 / 2 ' set number of 4-line builds for whole screen -18B0(014A) A2 9F BF A0 | fourline mov font_ptr, font_part ' get address of appropriate font section -18B4(014B) 0A 9E FF 2C | shl font_ptr, #8+2 -18B8(014C) A1 9F BF 80 | add font_ptr, font_base -18BC(014D) 00 B6 FE 54 | movd :pixa, #scanbuff-1 ' reset scanbuff address (pre-decremented) -18C0(014E) 50 CA FE 54 | movd :cola, #colorbuff-1 ' reset colorbuff address (pre-decremented) -18C4(014F) 50 CC FE 54 | movd :colb, #colorbuff-1 -18C8(0150) 02 A2 FF A0 | mov y, #2 ' must build scanbuff in two sections because -18CC(0151) A5 FF BF A0 | mov vscl, vscl_line2x ' ..pixel counter is limited to twelve bits -18D0(0152) 00 56 7F FC | :halfrow waitvid underscore, #0 ' output lows to let other COG drive VGA pins -18D4(0153) 28 A0 FF A0 | mov x, #cols/2 ' ..for 2 scan lines, ready for half a row -18D8(0154) CE A5 BF 04 | :column rdword z, screen_ptr ' get character and colors from screen memory -18DC(0155) D2 A9 BF A0 | mov bg, z -18E0(0156) FF A4 FF 60 | and z, #$ff ' mask character code -18E4(0157) 02 A4 FF 2C | shl z, #2 ' * 4 -18E8(0158) CF A5 BF 80 | add z, font_ptr ' add font section address to point to 8*4 pixels -18EC(0159) 00 B6 BE 80 | add :pixa, d0 ' increment scanbuff destination addresses -18F0(015A) 02 9C FF 80 | add screen_ptr, #2 ' increment screen memory address -18F4(015B) D2 03 BC 08 | :pixa rdlong scanbuff, z ' read pixel long (8*4) into scanbuff -18F8(015C) 0C A8 FF 20 | ror bg, #12 ' background color in bits 3..0 -18FC(015D) D4 A7 BF A0 | mov fg, bg ' foreground color in bits 31..28 -1900(015E) 1C A6 FF 28 | shr fg, #28 ' bits 3..0 -1904(015F) BE A7 FF 80 | add fg, #fg_clut ' + offset to foreground CLUT -1908(0160) D3 CB BE 50 | movs :cola, fg -190C(0161) 00 CA BE 80 | add :cola, d0 -1910(0162) AE A9 FF 80 | add bg, #bg_clut ' + offset to background CLUT -1914(0163) D4 CD BE 50 | movs :colb, bg -1918(0164) 00 CC BE 80 | add :colb, d0 -191C(0165) 00 A2 BC A0 | :cola mov colorbuff, 0-0 -1920(0166) 00 A2 BC 68 | :colb or colorbuff, 0-0 -1924(0167) 54 A1 FF E4 | djnz x, #:column ' another character in this half-row? -1928(0168) 52 A3 FF E4 | djnz y, #:halfrow ' loop to do 2nd half-row, time for 2nd WAITVID -192C(0169) A0 9C FF 84 | sub screen_ptr, #2*cols ' back up to start of same row in screen memory -1930(016A) 02 A4 FF A0 | mov z, #2 ' ready for two cursors -1934(016B) A0 A1 BF 00 | :cursor rdbyte x, cursor_base ' x in range? -1938(016C) 01 40 FF 80 | add cursor_base, #1 -193C(016D) 50 A0 7F 85 | cmp x, #cols wc -1940(016E) A0 A3 BF 00 | rdbyte y, cursor_base ' y match? -1944(016F) 01 40 FF 80 | add cursor_base, #1 -1948(0170) D5 A3 3F 86 | cmp y, row wz -194C(0171) A0 A3 BF 00 | rdbyte y, cursor_base ' get cursor mode -1950(0172) 01 40 FF 80 | add cursor_base, #1 -1954(0173) 80 01 5C 5C | if_nc_or_nz jmp #:nocursor ' if cursor not in scanbuff, no cursor -1958(0174) 01 A0 FF 80 | add x, #scanbuff ' cursor in scanbuff, set scanbuff address -195C(0175) D0 FF BE 54 | movd :xor, x -1960(0176) 02 A2 7F 61 | test y, #%010 wc ' get mode bits into flags -1964(0177) 01 A2 7F 62 | test y, #%001 wz -1968(0178) 80 01 48 5C | if_nc_and_z jmp #:nocursor ' if cursor disabled, no cursor -196C(0179) F1 53 23 61 | if_c_and_z test slowbit, cnt wc ' if blink mode, get blink state -1970(017A) F1 55 13 61 | if_c_and_nz test fastbit, cnt wc -1974(017B) 04 A2 7F 62 | test y, #%100 wz ' get box or underscore cursor piece -1978(017C) A8 A1 AB A0 | if_z mov x, longmask -197C(017D) AB A1 97 A0 | if_nz mov x, underscore -1980(017E) 03 44 57 86 | if_nz cmp font_part, #3 wz ' if underscore, must be last font section -1984(017F) D0 03 88 6C | :xor if_nc_and_z xor scanbuff, x ' conditionally xor cursor into scanbuff -1988(0180) 6B A5 FF E4 | :nocursor djnz z, #:cursor ' second cursor? -198C(0181) 06 40 FF 84 | sub cursor_base, #3*2 ' restore cursor base -1990(0182) 04 A2 FF A0 | mov y, #4 ' ready for four scan lines -1994(0183) A6 FF BF A0 | scanline mov vscl, vscl_chr ' set pixel rate for characters -1998(0184) A1 00 7C 5C | jmp #scancode ' jump to scanbuff display routine in scancode -199C(0185) 28 FE FF A0 | scanret mov vscl, #hs ' do horizontal sync pixels -19A0(0186) 01 5A 7F FC | waitvid hvsync, #1 ' #1 makes hsync active -19A4(0187) 80 FE FF A0 | mov vscl, #hb ' do horizontal back porch pixels -19A8(0188) 00 5A 7F FC | waitvid hvsync, #0 ' #0 makes hsync inactive -19AC(0189) 08 A0 FC 28 | shr scanbuff+cols-1, #8 ' shift last column's pixels right by 8 -19B0(018A) 83 A3 FF E4 | djnz y, #scanline ' another scan line? -19B4(018B) 02 44 FF 80 | add font_part, #2 ' if font_part + 2 => 4, subtract 4 (new row) -19B8(018C) 04 44 FF E1 | cmpsub font_part, #4 wc ' c=0 for same row, c=1 for new row -19BC(018D) A0 9C F3 80 | if_c add screen_ptr, #2*cols ' if new row, advance screen pointer -19C0(018E) 01 AA F3 80 | if_c add row, #1 ' if new row, increment row counter -19C4(018F) 4A AD FF E4 | djnz fours, #fourline ' another 4-line build/display? -19C8(0190) F0 51 3F 08 | wrlong longmask,par ' write -1 to refresh indicator -19CC(0191) 14 A0 FF A0 | vf_lines mov x,#vf ' do vertical front porch lines (# set at runtime) -19D0(0192) 95 3D FF 5C | call #blank -19D4(0193) 43 01 7C 5C | jmp #vsync ' new field, loop to vsync -19D8(0194) 01 5B FF 6C | blank_vsync xor hvsync,#$101 ' flip vertical sync bits -19DC(0195) A3 FF BF A0 | blank mov vscl, hx ' do blank pixels -19E0(0196) 00 5A 7F FC | waitvid hvsync, #0 -19E4(0197) 18 FE FF A0 | mov vscl, #hf ' do horizontal front porch pixels -19E8(0198) 00 5A 7F FC | waitvid hvsync, #0 -19EC(0199) 28 FE FF A0 | mov vscl, #hs ' do horizontal sync pixels -19F0(019A) 01 5A 7F FC | waitvid hvsync, #1 -19F4(019B) 80 FE FF A0 | mov vscl, #hb ' do horizontal back porch pixels -19F8(019C) 00 5A 7F FC | waitvid hvsync, #0 -19FC(019D) 95 A1 FF E4 | djnz x,#blank ' another line? -1A00(019E) | blank_ret -1A00(019E) | blank_vsync_ret -1A00(019E) 00 00 7C 5C | ret -1A04(019F) 00 00 00 00 | screen_base long 0 ' set at runtime (3 contiguous longs) -1A08(01A0) 00 00 00 00 | cursor_base long 0 ' set at runtime -1A0C(01A1) 00 00 00 00 | font_base long 0 ' set at runtime -1A10(01A2) 00 00 00 00 | font_part long 0 ' set at runtime -1A14(01A3) 80 02 00 00 | hx long hp ' visible pixels per scan line -1A18(01A4) 40 03 00 00 | vscl_line long hp + hf + hs + hb ' total number of pixels per scan line -1A1C(01A5) 80 06 00 00 | vscl_line2x long (hp + hf + hs + hb) * 2 ' total number of pixels per 2 scan lines -1A20(01A6) 08 10 00 00 | vscl_chr long 1 << 12 + 8 ' 1 clock per pixel and 8 pixels per set -1A24(01A7) FC FC 00 00 | colormask long $FCFC ' mask to isolate R,G,B bits from H,V -1A28(01A8) FF FF FF FF | longmask long $FFFFFFFF ' all bits set -1A2C(01A9) 00 00 00 02 | slowbit long 1 << 25 ' cnt mask for slow cursor blink -1A30(01AA) 00 00 00 01 | fastbit long 1 << 24 ' cnt mask for fast cursor blink -1A34(01AB) 00 00 FF FF | underscore long $FFFF0000 ' underscore cursor pattern -1A38(01AC) 03 03 00 00 | hv long hv_inactive ' -H,-V states -1A3C(01AD) 03 01 00 00 | hvsync long hv_inactive ^ $200 ' +/-H,-V states -1A40(01AE) 03 03 00 00 | bg_clut long %00000011_00000011 ' black -1A44(01AF) 0B 03 00 00 | long %00000011_00001011 ' dark blue -1A48(01B0) 23 03 00 00 | long %00000011_00100011 ' dark green -1A4C(01B1) 2B 03 00 00 | long %00000011_00101011 ' dark cyan -1A50(01B2) 83 03 00 00 | long %00000011_10000011 ' dark red -1A54(01B3) 8B 03 00 00 | long %00000011_10001011 ' dark magenta -1A58(01B4) A3 03 00 00 | long %00000011_10100011 ' brown -1A5C(01B5) AB 03 00 00 | long %00000011_10101011 ' light gray -1A60(01B6) 57 03 00 00 | long %00000011_01010111 ' dark gray -1A64(01B7) 0F 03 00 00 | long %00000011_00001111 ' light blue -1A68(01B8) 33 03 00 00 | long %00000011_00110011 ' light green -1A6C(01B9) 3F 03 00 00 | long %00000011_00111111 ' light cyan -1A70(01BA) C3 03 00 00 | long %00000011_11000011 ' light red -1A74(01BB) CF 03 00 00 | long %00000011_11001111 ' light magenta -1A78(01BC) F3 03 00 00 | long %00000011_11110011 ' light yellow -1A7C(01BD) FF 03 00 00 | long %00000011_11111111 ' white -1A80(01BE) 03 03 00 00 | fg_clut long %00000011_00000011 ' black -1A84(01BF) 03 07 00 00 | long %00000111_00000011 ' dark blue -1A88(01C0) 03 13 00 00 | long %00010011_00000011 ' dark green -1A8C(01C1) 03 17 00 00 | long %00010111_00000011 ' dark cyan -1A90(01C2) 03 43 00 00 | long %01000011_00000011 ' dark red -1A94(01C3) 03 47 00 00 | long %01000111_00000011 ' dark magenta -1A98(01C4) 03 53 00 00 | long %01010011_00000011 ' brown -1A9C(01C5) 03 AB 00 00 | long %10101011_00000011 ' light gray -1AA0(01C6) 03 57 00 00 | long %01010111_00000011 ' dark gray -1AA4(01C7) 03 0B 00 00 | long %00001011_00000011 ' blue -1AA8(01C8) 03 23 00 00 | long %00100011_00000011 ' green -1AAC(01C9) 03 2B 00 00 | long %00101011_00000011 ' cyan -1AB0(01CA) 03 83 00 00 | long %10000011_00000011 ' red -1AB4(01CB) 03 8B 00 00 | long %10001011_00000011 ' magenta -1AB8(01CC) 03 A3 00 00 | long %10100011_00000011 ' yellow -1ABC(01CD) 03 FF 00 00 | long %11111111_00000011 ' white -1AC0(01CE) | screen_ptr res 1 -1AC0(01CF) | font_ptr res 1 -1AC0(01D0) | x res 1 -1AC0(01D1) | y res 1 -1AC0(01D2) | z res 1 -1AC0(01D3) | fg res 1 -1AC0(01D4) | bg res 1 -1AC0(01D5) | row res 1 -1AC0(01D6) | fours res 1 -1AC0(01D7) | fit $1f0 -1AC0(01D7) | There are 25 ($019) Longs left in the cog -1AC0(01D7) 00 00 00 00 | font long -1AC0(01D7) 00 BA 82 00 | long $0082ba00,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 -1AC4(01D8) 00 00 00 00 | -1AC8(01D9) 00 2A 55 2A | -1ACC(01DA) 00 00 36 36 | -1AD0(01DB) 00 00 1E 06 | -1AD4(01DC) 00 00 1C 06 | -1AD8(01DD) 00 00 06 06 | -1ADC(01DE) 00 00 00 3C | -1AE0(01DF) 00 00 00 00 | long $00000000,$6e660000,$66660000,$18181818,$00000000,$00000000,$18181818,$18181818 -1AE4(01E0) 00 00 66 6E | -1AE8(01E1) 00 00 66 66 | -1AEC(01E2) 18 18 18 18 | -1AF0(01E3) 00 00 00 00 | -1AF4(01E4) 00 00 00 00 | -1AF8(01E5) 18 18 18 18 | -1AFC(01E6) 18 18 18 18 | -1B00(01E7) FF FF 00 00 | long $0000ffff,$00000000,$00000000,$00000000,$00000000,$18181818,$18181818,$18181818 -1B04(01E8) 00 00 00 00 | -1B08(01E9) 00 00 00 00 | -1B0C(01EA) 00 00 00 00 | -1B10(01EB) 00 00 00 00 | -1B14(01EC) 18 18 18 18 | -1B18(01ED) 18 18 18 18 | -1B1C(01EE) 18 18 18 18 | -1B20(01EF) 00 00 00 00 | long $00000000,$18181818,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 -1B24(01F0) 18 18 18 18 | -1B28(01F1) 00 00 00 60 | -1B2C(01F2) 00 00 00 06 | -1B30(01F3) 00 00 00 00 | -1B34(01F4) 00 00 00 00 | -1B38(01F5) 00 00 00 38 | -1B3C(01F6) 00 00 00 00 | -1B40(01F7) 00 00 00 00 | long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 -1B44(01F8) 00 00 00 18 | -1B48(01F9) 00 00 00 36 | -1B4C(01FA) 00 00 00 24 | -1B50(01FB) 00 00 00 18 | -1B54(01FC) 00 00 00 4E | -1B58(01FD) 00 00 00 1C | -1B5C(01FE) 00 00 00 18 | -1B60(01FF) 00 00 00 30 | long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 -1B64(0200) 00 00 00 0C | -1B68(0201) 00 00 00 00 | -1B6C(0202) 00 00 00 00 | -1B70(0203) 00 00 00 00 | -1B74(0204) 00 00 00 00 | -1B78(0205) 00 00 00 00 | -1B7C(0206) 00 00 00 60 | -1B80(0207) 00 00 00 18 | long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 -1B84(0208) 00 00 00 18 | -1B88(0209) 00 00 00 3C | -1B8C(020A) 00 00 00 7E | -1B90(020B) 00 00 00 60 | -1B94(020C) 00 00 00 7E | -1B98(020D) 00 00 00 3C | -1B9C(020E) 00 00 00 7E | -1BA0(020F) 00 00 00 3C | long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 -1BA4(0210) 00 00 00 3C | -1BA8(0211) 00 00 00 00 | -1BAC(0212) 00 00 00 00 | -1BB0(0213) 00 00 00 60 | -1BB4(0214) 00 00 00 00 | -1BB8(0215) 00 00 00 06 | -1BBC(0216) 00 00 00 3C | -1BC0(0217) 00 00 00 3C | long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 -1BC4(0218) 00 00 00 3C | -1BC8(0219) 00 00 00 3E | -1BCC(021A) 00 00 00 3C | -1BD0(021B) 00 00 00 3E | -1BD4(021C) 00 00 00 7E | -1BD8(021D) 00 00 00 7E | -1BDC(021E) 00 00 00 3C | -1BE0(021F) 00 00 00 66 | long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 -1BE4(0220) 00 00 00 7E | -1BE8(0221) 00 00 00 60 | -1BEC(0222) 00 00 00 46 | -1BF0(0223) 00 00 00 06 | -1BF4(0224) 00 00 00 42 | -1BF8(0225) 00 00 00 66 | -1BFC(0226) 00 00 00 3C | -1C00(0227) 00 00 00 3E | long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 -1C04(0228) 00 00 00 3C | -1C08(0229) 00 00 00 3E | -1C0C(022A) 00 00 00 3C | -1C10(022B) 00 00 00 7E | -1C14(022C) 00 00 00 66 | -1C18(022D) 00 00 00 66 | -1C1C(022E) 00 00 00 66 | -1C20(022F) 00 00 00 42 | long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 -1C24(0230) 00 00 00 66 | -1C28(0231) 00 00 00 7E | -1C2C(0232) 00 00 00 3C | -1C30(0233) 00 00 00 06 | -1C34(0234) 00 00 00 3C | -1C38(0235) 00 00 00 18 | -1C3C(0236) 00 00 00 00 | -1C40(0237) 00 00 0C 18 | long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 -1C44(0238) 00 00 00 00 | -1C48(0239) 00 00 00 06 | -1C4C(023A) 00 00 00 00 | -1C50(023B) 00 00 00 60 | -1C54(023C) 00 00 00 00 | -1C58(023D) 00 00 00 38 | -1C5C(023E) 00 00 00 00 | -1C60(023F) 00 00 00 06 | long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 -1C64(0240) 00 00 00 18 | -1C68(0241) 00 00 00 60 | -1C6C(0242) 00 00 00 06 | -1C70(0243) 00 00 00 1C | -1C74(0244) 00 00 00 00 | -1C78(0245) 00 00 00 00 | -1C7C(0246) 00 00 00 00 | -1C80(0247) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -1C84(0248) 00 00 00 00 | -1C88(0249) 00 00 00 00 | -1C8C(024A) 00 00 00 00 | -1C90(024B) 00 00 00 00 | -1C94(024C) 00 00 00 00 | -1C98(024D) 00 00 00 00 | -1C9C(024E) 00 00 00 00 | -1CA0(024F) 00 00 00 00 | long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 -1CA4(0250) 00 00 00 00 | -1CA8(0251) 00 00 00 00 | -1CAC(0252) 00 00 00 38 | -1CB0(0253) 00 00 00 18 | -1CB4(0254) 00 00 00 1C | -1CB8(0255) 00 00 00 4C | -1CBC(0256) 55 AA 55 AA | -1CC0(0257) 00 00 00 00 | long $00000000,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 -1CC4(0258) 00 00 00 00 | -1CC8(0259) 00 2A 55 2A | -1CCC(025A) 00 00 36 36 | -1CD0(025B) 00 00 1E 06 | -1CD4(025C) 00 00 1C 06 | -1CD8(025D) 00 00 06 06 | -1CDC(025E) 00 00 00 3C | -1CE0(025F) 00 00 00 00 | long $00000000,$6e660000,$66660000,$24242424,$00000000,$00000000,$24242424,$24242424 -1CE4(0260) 00 00 66 6E | -1CE8(0261) 00 00 66 66 | -1CEC(0262) 24 24 24 24 | -1CF0(0263) 00 00 00 00 | -1CF4(0264) 00 00 00 00 | -1CF8(0265) 24 24 24 24 | -1CFC(0266) 24 24 24 24 | -1D00(0267) FF 00 FF 00 | long $00ff00ff,$ff000000,$00000000,$00000000,$00000000,$24242424,$24242424,$24242424 -1D04(0268) 00 00 00 FF | -1D08(0269) 00 00 00 00 | -1D0C(026A) 00 00 00 00 | -1D10(026B) 00 00 00 00 | -1D14(026C) 24 24 24 24 | -1D18(026D) 24 24 24 24 | -1D1C(026E) 24 24 24 24 | -1D20(026F) 00 00 00 00 | long $00000000,$24242424,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 -1D24(0270) 24 24 24 24 | -1D28(0271) 00 00 00 60 | -1D2C(0272) 00 00 00 06 | -1D30(0273) 00 00 00 00 | -1D34(0274) 00 00 00 00 | -1D38(0275) 00 00 00 38 | -1D3C(0276) 00 00 00 00 | -1D40(0277) 00 00 00 00 | long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 -1D44(0278) 00 00 00 18 | -1D48(0279) 00 00 00 36 | -1D4C(027A) 00 00 00 24 | -1D50(027B) 00 00 00 18 | -1D54(027C) 00 00 00 4E | -1D58(027D) 00 00 00 1C | -1D5C(027E) 00 00 00 18 | -1D60(027F) 00 00 00 30 | long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 -1D64(0280) 00 00 00 0C | -1D68(0281) 00 00 00 00 | -1D6C(0282) 00 00 00 00 | -1D70(0283) 00 00 00 00 | -1D74(0284) 00 00 00 00 | -1D78(0285) 00 00 00 00 | -1D7C(0286) 00 00 00 60 | -1D80(0287) 00 00 00 18 | long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 -1D84(0288) 00 00 00 18 | -1D88(0289) 00 00 00 3C | -1D8C(028A) 00 00 00 7E | -1D90(028B) 00 00 00 60 | -1D94(028C) 00 00 00 7E | -1D98(028D) 00 00 00 3C | -1D9C(028E) 00 00 00 7E | -1DA0(028F) 00 00 00 3C | long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 -1DA4(0290) 00 00 00 3C | -1DA8(0291) 00 00 00 00 | -1DAC(0292) 00 00 00 00 | -1DB0(0293) 00 00 00 60 | -1DB4(0294) 00 00 00 00 | -1DB8(0295) 00 00 00 06 | -1DBC(0296) 00 00 00 3C | -1DC0(0297) 00 00 00 3C | long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 -1DC4(0298) 00 00 00 3C | -1DC8(0299) 00 00 00 3E | -1DCC(029A) 00 00 00 3C | -1DD0(029B) 00 00 00 3E | -1DD4(029C) 00 00 00 7E | -1DD8(029D) 00 00 00 7E | -1DDC(029E) 00 00 00 3C | -1DE0(029F) 00 00 00 66 | long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 -1DE4(02A0) 00 00 00 7E | -1DE8(02A1) 00 00 00 60 | -1DEC(02A2) 00 00 00 46 | -1DF0(02A3) 00 00 00 06 | -1DF4(02A4) 00 00 00 42 | -1DF8(02A5) 00 00 00 66 | -1DFC(02A6) 00 00 00 3C | -1E00(02A7) 00 00 00 3E | long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 -1E04(02A8) 00 00 00 3C | -1E08(02A9) 00 00 00 3E | -1E0C(02AA) 00 00 00 3C | -1E10(02AB) 00 00 00 7E | -1E14(02AC) 00 00 00 66 | -1E18(02AD) 00 00 00 66 | -1E1C(02AE) 00 00 00 66 | -1E20(02AF) 00 00 00 42 | long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 -1E24(02B0) 00 00 00 66 | -1E28(02B1) 00 00 00 7E | -1E2C(02B2) 00 00 00 3C | -1E30(02B3) 00 00 00 06 | -1E34(02B4) 00 00 00 3C | -1E38(02B5) 00 00 00 18 | -1E3C(02B6) 00 00 00 00 | -1E40(02B7) 00 00 0C 18 | long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 -1E44(02B8) 00 00 00 00 | -1E48(02B9) 00 00 00 06 | -1E4C(02BA) 00 00 00 00 | -1E50(02BB) 00 00 00 60 | -1E54(02BC) 00 00 00 00 | -1E58(02BD) 00 00 00 38 | -1E5C(02BE) 00 00 00 00 | -1E60(02BF) 00 00 00 06 | long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 -1E64(02C0) 00 00 00 18 | -1E68(02C1) 00 00 00 60 | -1E6C(02C2) 00 00 00 06 | -1E70(02C3) 00 00 00 1C | -1E74(02C4) 00 00 00 00 | -1E78(02C5) 00 00 00 00 | -1E7C(02C6) 00 00 00 00 | -1E80(02C7) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -1E84(02C8) 00 00 00 00 | -1E88(02C9) 00 00 00 00 | -1E8C(02CA) 00 00 00 00 | -1E90(02CB) 00 00 00 00 | -1E94(02CC) 00 00 00 00 | -1E98(02CD) 00 00 00 00 | -1E9C(02CE) 00 00 00 00 | -1EA0(02CF) 00 00 00 00 | long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 -1EA4(02D0) 00 00 00 00 | -1EA8(02D1) 00 00 00 00 | -1EAC(02D2) 00 00 00 38 | -1EB0(02D3) 00 00 00 18 | -1EB4(02D4) 00 00 00 1C | -1EB8(02D5) 00 00 00 4C | -1EBC(02D6) 55 AA 55 AA | -1EC0(02D7) 82 82 00 82 | long $82008282,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 -1EC4(02D8) 00 00 18 3C | -1EC8(02D9) 55 2A 55 2A | -1ECC(02DA) 3E 36 36 00 | -1ED0(02DB) 0E 06 06 00 | -1ED4(02DC) 06 06 1C 00 | -1ED8(02DD) 06 06 1E 00 | -1EDC(02DE) 66 66 3C 00 | -1EE0(02DF) 18 18 7E 18 | long $187e1818,$0066767e,$00183c24,$1f181818,$1f000000,$f8000000,$f8181818,$ff181818 -1EE4(02E0) 7E 76 66 00 | -1EE8(02E1) 24 3C 18 00 | -1EEC(02E2) 18 18 18 1F | -1EF0(02E3) 00 00 00 1F | -1EF4(02E4) 00 00 00 F8 | -1EF8(02E5) 18 18 18 F8 | -1EFC(02E6) 18 18 18 FF | -1F00(02E7) 00 00 00 00 | long $00000000,$0000ffff,$00000000,$00000000,$00000000,$f8181818,$1f181818,$ff181818 -1F04(02E8) FF FF 00 00 | -1F08(02E9) 00 00 00 00 | -1F0C(02EA) 00 00 00 00 | -1F10(02EB) 00 00 00 00 | -1F14(02EC) 18 18 18 F8 | -1F18(02ED) 18 18 18 1F | -1F1C(02EE) 18 18 18 FF | -1F20(02EF) 00 00 00 FF | long $ff000000,$18181818,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 -1F24(02F0) 18 18 18 18 | -1F28(02F1) 30 0C 06 0C | -1F2C(02F2) 0C 30 60 30 | -1F30(02F3) 00 00 7E 66 | -1F34(02F4) 30 30 7E 18 | -1F38(02F5) 6C 0C 0C 3E | -1F3C(02F6) 00 00 18 18 | -1F40(02F7) 00 00 00 00 | long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 -1F44(02F8) 18 18 18 18 | -1F48(02F9) 36 36 00 00 | -1F4C(02FA) 24 7E 7E 24 | -1F50(02FB) 3C 5A 1A 3C | -1F54(02FC) 6A 2E 30 18 | -1F58(02FD) 36 36 36 1C | -1F5C(02FE) 18 18 18 00 | -1F60(02FF) 18 18 0C 0C | long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 -1F64(0300) 18 18 30 30 | -1F68(0301) 00 24 18 7E | -1F6C(0302) 00 18 18 7E | -1F70(0303) 00 00 00 00 | -1F74(0304) 00 00 00 00 | -1F78(0305) 00 00 00 00 | -1F7C(0306) 60 30 30 18 | -1F80(0307) 24 66 66 66 | long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 -1F84(0308) 1C 1A 18 18 | -1F88(0309) 66 66 60 38 | -1F8C(030A) 60 30 18 3C | -1F90(030B) 70 78 6C 66 | -1F94(030C) 06 06 3E 66 | -1F98(030D) 66 06 06 3E | -1F9C(030E) 60 60 30 30 | -1FA0(030F) 66 66 66 3C | long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 -1FA4(0310) 66 66 66 7C | -1FA8(0311) 00 18 3C 18 | -1FAC(0312) 00 18 3C 18 | -1FB0(0313) 30 18 0C 06 | -1FB4(0314) 00 00 7E 00 | -1FB8(0315) 0C 18 30 60 | -1FBC(0316) 66 66 60 38 | -1FC0(0317) 62 62 7A 6A | long $6a7a6262,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 -1FC4(0318) 66 66 66 7E | -1FC8(0319) 66 66 66 3E | -1FCC(031A) 66 06 06 06 | -1FD0(031B) 66 66 66 66 | -1FD4(031C) 06 06 06 3E | -1FD8(031D) 06 06 06 3E | -1FDC(031E) 66 06 06 76 | -1FE0(031F) 66 66 66 7E | long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 -1FE4(0320) 18 18 18 18 | -1FE8(0321) 60 60 60 60 | -1FEC(0322) 66 36 1E 0E | -1FF0(0323) 06 06 06 06 | -1FF4(0324) 66 7E 7E 66 | -1FF8(0325) 66 6E 6E 7E | -1FFC(0326) 66 66 66 66 | -2000(0327) 66 66 66 3E | long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 -2004(0328) 66 66 66 66 | -2008(0329) 66 66 66 3E | -200C(032A) 66 06 06 3C | -2010(032B) 18 18 18 18 | -2014(032C) 66 66 66 66 | -2018(032D) 66 66 24 24 | -201C(032E) 66 66 66 66 | -2020(032F) 66 24 3C 18 | long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 -2024(0330) 66 3C 3C 18 | -2028(0331) 60 60 30 18 | -202C(0332) 0C 0C 0C 0C | -2030(0333) 06 0C 0C 18 | -2034(0334) 30 30 30 30 | -2038(0335) 3C 66 42 00 | -203C(0336) 00 00 00 00 | -2040(0337) 30 00 00 00 | long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 -2044(0338) 00 00 3C 60 | -2048(0339) 06 06 3E 66 | -204C(033A) 00 00 3C 66 | -2050(033B) 60 60 7C 66 | -2054(033C) 00 00 3C 66 | -2058(033D) 6C 0C 0C 1E | -205C(033E) 00 00 5C 66 | -2060(033F) 06 06 3E 66 | long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 -2064(0340) 18 00 1C 18 | -2068(0341) 60 00 60 60 | -206C(0342) 06 06 66 36 | -2070(0343) 18 18 18 18 | -2074(0344) 00 00 6A FE | -2078(0345) 00 00 3E 66 | -207C(0346) 00 00 3C 66 | -2080(0347) 00 00 3E 66 | long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 -2084(0348) 00 00 7C 66 | -2088(0349) 00 00 3E 66 | -208C(034A) 00 00 3C 66 | -2090(034B) 0C 0C 3E 0C | -2094(034C) 00 00 66 66 | -2098(034D) 00 00 66 66 | -209C(034E) 00 00 66 66 | -20A0(034F) 00 00 66 66 | long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 -20A4(0350) 00 00 66 66 | -20A8(0351) 00 00 7E 60 | -20AC(0352) 0C 0C 18 0C | -20B0(0353) 18 18 18 18 | -20B4(0354) 30 30 18 30 | -20B8(0355) 7E 32 00 00 | -20BC(0356) 55 AA 55 AA | -20C0(0357) 00 00 00 00 | long $00000000,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 -20C4(0358) 00 00 18 3C | -20C8(0359) 55 2A 55 2A | -20CC(035A) 3E 36 36 00 | -20D0(035B) 0E 06 06 00 | -20D4(035C) 06 06 1C 00 | -20D8(035D) 06 06 1E 00 | -20DC(035E) 66 66 3C 00 | -20E0(035F) 18 18 7E 18 | long $187e1818,$0066767e,$00183c24,$20272424,$203f0000,$04fc0000,$04e42424,$00e72424 -20E4(0360) 7E 76 66 00 | -20E8(0361) 24 3C 18 00 | -20EC(0362) 24 24 27 20 | -20F0(0363) 00 00 3F 20 | -20F4(0364) 00 00 FC 04 | -20F8(0365) 24 24 E4 04 | -20FC(0366) 24 24 E7 00 | -2100(0367) 00 00 00 00 | long $00000000,$0000ff00,$ff000000,$00000000,$00000000,$04e42424,$20272424,$00e72424 -2104(0368) 00 FF 00 00 | -2108(0369) 00 00 00 FF | -210C(036A) 00 00 00 00 | -2110(036B) 00 00 00 00 | -2114(036C) 24 24 E4 04 | -2118(036D) 24 24 27 20 | -211C(036E) 24 24 E7 00 | -2120(036F) 00 00 FF 00 | long $00ff0000,$24242424,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 -2124(0370) 24 24 24 24 | -2128(0371) 30 0C 06 0C | -212C(0372) 0C 30 60 30 | -2130(0373) 00 00 7E 66 | -2134(0374) 30 30 7E 18 | -2138(0375) 6C 0C 0C 3E | -213C(0376) 00 00 18 18 | -2140(0377) 00 00 00 00 | long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 -2144(0378) 18 18 18 18 | -2148(0379) 36 36 00 00 | -214C(037A) 24 7E 7E 24 | -2150(037B) 3C 5A 1A 3C | -2154(037C) 6A 2E 30 18 | -2158(037D) 36 36 36 1C | -215C(037E) 18 18 18 00 | -2160(037F) 18 18 0C 0C | long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 -2164(0380) 18 18 30 30 | -2168(0381) 00 24 18 7E | -216C(0382) 00 18 18 7E | -2170(0383) 00 00 00 00 | -2174(0384) 00 00 00 00 | -2178(0385) 00 00 00 00 | -217C(0386) 60 30 30 18 | -2180(0387) 24 66 66 66 | long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 -2184(0388) 1C 1A 18 18 | -2188(0389) 66 66 60 38 | -218C(038A) 60 30 18 3C | -2190(038B) 70 78 6C 66 | -2194(038C) 06 06 3E 66 | -2198(038D) 66 06 06 3E | -219C(038E) 60 60 30 30 | -21A0(038F) 66 66 66 3C | long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 -21A4(0390) 66 66 66 7C | -21A8(0391) 00 18 3C 18 | -21AC(0392) 00 18 3C 18 | -21B0(0393) 30 18 0C 06 | -21B4(0394) 00 00 7E 00 | -21B8(0395) 0C 18 30 60 | -21BC(0396) 66 66 60 38 | -21C0(0397) 66 66 76 76 | long $76766666,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 -21C4(0398) 66 66 66 7E | -21C8(0399) 66 66 66 3E | -21CC(039A) 66 06 06 06 | -21D0(039B) 66 66 66 66 | -21D4(039C) 06 06 06 3E | -21D8(039D) 06 06 06 3E | -21DC(039E) 66 06 06 76 | -21E0(039F) 66 66 66 7E | long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 -21E4(03A0) 18 18 18 18 | -21E8(03A1) 60 60 60 60 | -21EC(03A2) 66 36 1E 0E | -21F0(03A3) 06 06 06 06 | -21F4(03A4) 66 7E 7E 66 | -21F8(03A5) 66 6E 6E 7E | -21FC(03A6) 66 66 66 66 | -2200(03A7) 66 66 66 3E | long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 -2204(03A8) 66 66 66 66 | -2208(03A9) 66 66 66 3E | -220C(03AA) 66 06 06 3C | -2210(03AB) 18 18 18 18 | -2214(03AC) 66 66 66 66 | -2218(03AD) 66 66 24 24 | -221C(03AE) 66 66 66 66 | -2220(03AF) 66 24 3C 18 | long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 -2224(03B0) 66 3C 3C 18 | -2228(03B1) 60 60 30 18 | -222C(03B2) 0C 0C 0C 0C | -2230(03B3) 06 0C 0C 18 | -2234(03B4) 30 30 30 30 | -2238(03B5) 3C 66 42 00 | -223C(03B6) 00 00 00 00 | -2240(03B7) 30 00 00 00 | long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 -2244(03B8) 00 00 3C 60 | -2248(03B9) 06 06 3E 66 | -224C(03BA) 00 00 3C 66 | -2250(03BB) 60 60 7C 66 | -2254(03BC) 00 00 3C 66 | -2258(03BD) 6C 0C 0C 1E | -225C(03BE) 00 00 5C 66 | -2260(03BF) 06 06 3E 66 | long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 -2264(03C0) 18 00 1C 18 | -2268(03C1) 60 00 60 60 | -226C(03C2) 06 06 66 36 | -2270(03C3) 18 18 18 18 | -2274(03C4) 00 00 6A FE | -2278(03C5) 00 00 3E 66 | -227C(03C6) 00 00 3C 66 | -2280(03C7) 00 00 3E 66 | long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 -2284(03C8) 00 00 7C 66 | -2288(03C9) 00 00 3E 66 | -228C(03CA) 00 00 3C 66 | -2290(03CB) 0C 0C 3E 0C | -2294(03CC) 00 00 66 66 | -2298(03CD) 00 00 66 66 | -229C(03CE) 00 00 66 66 | -22A0(03CF) 00 00 66 66 | long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 -22A4(03D0) 00 00 66 66 | -22A8(03D1) 00 00 7E 60 | -22AC(03D2) 0C 0C 18 0C | -22B0(03D3) 18 18 18 18 | -22B4(03D4) 30 30 18 30 | -22B8(03D5) 7E 32 00 00 | -22BC(03D6) 55 AA 55 AA | -22C0(03D7) 82 00 82 82 | long $82820082,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 -22C4(03D8) 7E 3C 18 00 | -22C8(03D9) 55 2A 55 2A | -22CC(03DA) 78 30 30 30 | -22D0(03DB) 78 18 38 18 | -22D4(03DC) 38 58 38 58 | -22D8(03DD) 78 18 38 18 | -22DC(03DE) 00 00 00 00 | -22E0(03DF) 18 00 7E 00 | long $007e0018,$18181818,$30303078,$0000001f,$1818181f,$181818f8,$000000f8,$181818ff -22E4(03E0) 18 18 18 18 | -22E8(03E1) 78 30 30 30 | -22EC(03E2) 1F 00 00 00 | -22F0(03E3) 1F 18 18 18 | -22F4(03E4) F8 18 18 18 | -22F8(03E5) F8 00 00 00 | -22FC(03E6) FF 18 18 18 | -2300(03E7) 00 00 00 00 | long $00000000,$00000000,$0000ffff,$ff000000,$00000000,$181818f8,$1818181f,$000000ff -2304(03E8) 00 00 00 00 | -2308(03E9) FF FF 00 00 | -230C(03EA) 00 00 00 FF | -2310(03EB) 00 00 00 00 | -2314(03EC) F8 18 18 18 | -2318(03ED) 1F 18 18 18 | -231C(03EE) FF 00 00 00 | -2320(03EF) FF 18 18 18 | long $181818ff,$18181818,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 -2324(03F0) 18 18 18 18 | -2328(03F1) 30 60 00 7E | -232C(03F2) 0C 06 00 7E | -2330(03F3) 66 66 66 66 | -2334(03F4) 18 7E 0C 0C | -2338(03F5) 0C 0C 6C 3A | -233C(03F6) 00 00 00 00 | -2340(03F7) 00 00 00 00 | long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 -2344(03F8) 18 00 18 18 | -2348(03F9) 00 00 00 00 | -234C(03FA) 7E 7E 24 24 | -2350(03FB) 58 5A 3C 18 | -2354(03FC) 0C 74 56 72 | -2358(03FD) 56 76 36 5C | -235C(03FE) 00 00 00 00 | -2360(03FF) 0C 18 18 30 | long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c -2364(0400) 30 18 18 0C | -2368(0401) 7E 18 24 00 | -236C(0402) 7E 18 18 00 | -2370(0403) 00 38 38 18 | -2374(0404) 7E 00 00 00 | -2378(0405) 00 00 18 3C | -237C(0406) 0C 0C 06 06 | -2380(0407) 66 66 24 18 | long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 -2384(0408) 18 18 18 7E | -2388(0409) 0C 06 06 7E | -238C(040A) 60 60 66 3C | -2390(040B) 66 7E 60 60 | -2394(040C) 60 60 66 3C | -2398(040D) 66 66 66 3C | -239C(040E) 18 18 0C 0C | -23A0(040F) 66 66 66 3C | long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 -23A4(0410) 60 60 66 3C | -23A8(0411) 00 00 18 3C | -23AC(0412) 00 38 38 18 | -23B0(0413) 0C 18 30 60 | -23B4(0414) 00 7E 00 00 | -23B8(0415) 30 18 0C 06 | -23BC(0416) 18 00 18 18 | -23C0(0417) 7A 02 62 3C | long $3c62027a,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 -23C4(0418) 66 66 66 66 | -23C8(0419) 66 66 66 3E | -23CC(041A) 06 06 66 3C | -23D0(041B) 66 66 66 3E | -23D4(041C) 06 06 06 7E | -23D8(041D) 06 06 06 06 | -23DC(041E) 66 66 66 7C | -23E0(041F) 66 66 66 66 | long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 -23E4(0420) 18 18 18 7E | -23E8(0421) 60 60 66 3C | -23EC(0422) 1E 36 66 46 | -23F0(0423) 06 06 06 7E | -23F4(0424) 66 66 66 66 | -23F8(0425) 76 76 66 66 | -23FC(0426) 66 66 66 3C | -2400(0427) 06 06 06 06 | long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e -2404(0428) 66 6E 76 3C | -2408(0429) 1E 36 66 46 | -240C(042A) 60 60 66 3C | -2410(042B) 18 18 18 18 | -2414(042C) 66 66 66 3C | -2418(042D) 3C 18 18 18 | -241C(042E) 7E 7E 66 42 | -2420(042F) 3C 24 66 42 | long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 -2424(0430) 18 18 18 18 | -2428(0431) 0C 06 06 7E | -242C(0432) 0C 0C 0C 3C | -2430(0433) 30 30 60 60 | -2434(0434) 30 30 30 3C | -2438(0435) 00 00 00 00 | -243C(0436) 00 00 00 FE | -2440(0437) 00 00 00 00 | long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 -2444(0438) 7C 66 66 7C | -2448(0439) 66 66 66 3E | -244C(043A) 06 06 66 3C | -2450(043B) 66 66 66 7C | -2454(043C) 7E 06 66 3C | -2458(043D) 0C 0C 0C 0C | -245C(043E) 66 3C 06 3C | -2460(043F) 66 66 66 66 | long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 -2464(0440) 18 18 18 7E | -2468(0441) 60 60 60 60 | -246C(0442) 1E 1E 36 66 | -2470(0443) 18 18 18 7E | -2474(0444) D6 D6 C6 C6 | -2478(0445) 66 66 66 66 | -247C(0446) 66 66 66 3C | -2480(0447) 66 66 3E 06 | long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 -2484(0448) 66 66 7C 60 | -2488(0449) 06 06 06 06 | -248C(044A) 0C 30 66 3C | -2490(044B) 0C 0C 6C 38 | -2494(044C) 66 66 66 7C | -2498(044D) 66 3C 3C 18 | -249C(044E) 66 7E 7E 24 | -24A0(044F) 3C 3C 66 66 | long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 -24A4(0450) 66 66 7C 60 | -24A8(0451) 30 0C 06 7E | -24AC(0452) 18 0C 0C 38 | -24B0(0453) 18 18 18 18 | -24B4(0454) 18 30 30 1C | -24B8(0455) 00 00 00 00 | -24BC(0456) 55 AA 55 AA | -24C0(0457) 00 00 00 00 | long $00000000,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 -24C4(0458) 7E 3C 18 00 | -24C8(0459) 55 2A 55 2A | -24CC(045A) 78 30 30 30 | -24D0(045B) 78 18 38 18 | -24D4(045C) 38 58 38 58 | -24D8(045D) 78 18 38 18 | -24DC(045E) 00 00 00 00 | -24E0(045F) 18 00 7E 00 | long $007e0018,$18181818,$30303078,$00003f20,$24242720,$2424e404,$0000fc04,$2424e700 -24E4(0460) 18 18 18 18 | -24E8(0461) 78 30 30 30 | -24EC(0462) 20 3F 00 00 | -24F0(0463) 20 27 24 24 | -24F4(0464) 04 E4 24 24 | -24F8(0465) 04 FC 00 00 | -24FC(0466) 00 E7 24 24 | -2500(0467) 00 00 00 00 | long $00000000,$00000000,$0000ff00,$00ff0000,$00000000,$2424e404,$24242720,$0000ff00 -2504(0468) 00 00 00 00 | -2508(0469) 00 FF 00 00 | -250C(046A) 00 00 FF 00 | -2510(046B) 00 00 00 00 | -2514(046C) 04 E4 24 24 | -2518(046D) 20 27 24 24 | -251C(046E) 00 FF 00 00 | -2520(046F) 00 E7 24 24 | long $2424e700,$24242424,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 -2524(0470) 24 24 24 24 | -2528(0471) 30 60 00 7E | -252C(0472) 0C 06 00 7E | -2530(0473) 66 66 66 66 | -2534(0474) 18 7E 0C 0C | -2538(0475) 0C 0C 6C 3A | -253C(0476) 00 00 00 00 | -2540(0477) 00 00 00 00 | long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 -2544(0478) 18 00 18 18 | -2548(0479) 00 00 00 00 | -254C(047A) 7E 7E 24 24 | -2550(047B) 58 5A 3C 18 | -2554(047C) 0C 74 56 72 | -2558(047D) 56 76 36 5C | -255C(047E) 00 00 00 00 | -2560(047F) 0C 18 18 30 | long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c -2564(0480) 30 18 18 0C | -2568(0481) 7E 18 24 00 | -256C(0482) 7E 18 18 00 | -2570(0483) 00 38 38 18 | -2574(0484) 7E 00 00 00 | -2578(0485) 00 00 18 3C | -257C(0486) 0C 0C 06 06 | -2580(0487) 66 66 24 18 | long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 -2584(0488) 18 18 18 7E | -2588(0489) 0C 06 06 7E | -258C(048A) 60 60 66 3C | -2590(048B) 66 7E 60 60 | -2594(048C) 60 60 66 3C | -2598(048D) 66 66 66 3C | -259C(048E) 18 18 0C 0C | -25A0(048F) 66 66 66 3C | long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 -25A4(0490) 60 60 66 3C | -25A8(0491) 00 00 18 3C | -25AC(0492) 00 38 38 18 | -25B0(0493) 0C 18 30 60 | -25B4(0494) 00 7E 00 00 | -25B8(0495) 30 18 0C 06 | -25BC(0496) 18 00 18 18 | -25C0(0497) 76 06 66 3C | long $3c660676,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 -25C4(0498) 66 66 66 66 | -25C8(0499) 66 66 66 3E | -25CC(049A) 06 06 66 3C | -25D0(049B) 66 66 66 3E | -25D4(049C) 06 06 06 7E | -25D8(049D) 06 06 06 06 | -25DC(049E) 66 66 66 7C | -25E0(049F) 66 66 66 66 | long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 -25E4(04A0) 18 18 18 7E | -25E8(04A1) 60 60 66 3C | -25EC(04A2) 1E 36 66 46 | -25F0(04A3) 06 06 06 7E | -25F4(04A4) 66 66 66 66 | -25F8(04A5) 76 76 66 66 | -25FC(04A6) 66 66 66 3C | -2600(04A7) 06 06 06 06 | long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e -2604(04A8) 66 6E 76 3C | -2608(04A9) 1E 36 66 46 | -260C(04AA) 60 60 66 3C | -2610(04AB) 18 18 18 18 | -2614(04AC) 66 66 66 3C | -2618(04AD) 3C 18 18 18 | -261C(04AE) 7E 7E 66 42 | -2620(04AF) 3C 24 66 42 | long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 -2624(04B0) 18 18 18 18 | -2628(04B1) 0C 06 06 7E | -262C(04B2) 0C 0C 0C 3C | -2630(04B3) 30 30 60 60 | -2634(04B4) 30 30 30 3C | -2638(04B5) 00 00 00 00 | -263C(04B6) 00 00 00 FE | -2640(04B7) 00 00 00 00 | long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 -2644(04B8) 7C 66 66 7C | -2648(04B9) 66 66 66 3E | -264C(04BA) 06 06 66 3C | -2650(04BB) 66 66 66 7C | -2654(04BC) 7E 06 66 3C | -2658(04BD) 0C 0C 0C 0C | -265C(04BE) 66 3C 06 3C | -2660(04BF) 66 66 66 66 | long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 -2664(04C0) 18 18 18 7E | -2668(04C1) 60 60 60 60 | -266C(04C2) 1E 1E 36 66 | -2670(04C3) 18 18 18 7E | -2674(04C4) D6 D6 C6 C6 | -2678(04C5) 66 66 66 66 | -267C(04C6) 66 66 66 3C | -2680(04C7) 66 66 3E 06 | long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 -2684(04C8) 66 66 7C 60 | -2688(04C9) 06 06 06 06 | -268C(04CA) 0C 30 66 3C | -2690(04CB) 0C 0C 6C 38 | -2694(04CC) 66 66 66 7C | -2698(04CD) 66 3C 3C 18 | -269C(04CE) 66 7E 7E 24 | -26A0(04CF) 3C 3C 66 66 | long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 -26A4(04D0) 66 66 7C 60 | -26A8(04D1) 30 0C 06 7E | -26AC(04D2) 18 0C 0C 38 | -26B0(04D3) 18 18 18 18 | -26B4(04D4) 18 30 30 1C | -26B8(04D5) 00 00 00 00 | -26BC(04D6) 55 AA 55 AA | -26C0(04D7) 00 82 BA 00 | long $00ba8200,$00000000,$00002a55,$00000030,$00000018,$00000058,$00000018,$00000000 -26C4(04D8) 00 00 00 00 | -26C8(04D9) 55 2A 00 00 | -26CC(04DA) 30 00 00 00 | -26D0(04DB) 18 00 00 00 | -26D4(04DC) 58 00 00 00 | -26D8(04DD) 18 00 00 00 | -26DC(04DE) 00 00 00 00 | -26E0(04DF) 00 00 00 00 | long $00000000,$00000078,$00000030,$00000000,$18181818,$18181818,$00000000,$18181818 -26E4(04E0) 78 00 00 00 | -26E8(04E1) 30 00 00 00 | -26EC(04E2) 00 00 00 00 | -26F0(04E3) 18 18 18 18 | -26F4(04E4) 18 18 18 18 | -26F8(04E5) 00 00 00 00 | -26FC(04E6) 18 18 18 18 | -2700(04E7) 00 00 00 00 | long $00000000,$00000000,$00000000,$000000ff,$ffff0000,$18181818,$18181818,$00000000 -2704(04E8) 00 00 00 00 | -2708(04E9) 00 00 00 00 | -270C(04EA) FF 00 00 00 | -2710(04EB) 00 00 FF FF | -2714(04EC) 18 18 18 18 | -2718(04ED) 18 18 18 18 | -271C(04EE) 00 00 00 00 | -2720(04EF) 18 18 18 18 | long $18181818,$18181818,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2724(04F0) 18 18 18 18 | -2728(04F1) 00 00 00 00 | -272C(04F2) 00 00 00 00 | -2730(04F3) 00 00 00 00 | -2734(04F4) 00 00 00 00 | -2738(04F5) 00 00 00 00 | -273C(04F6) 00 00 00 00 | -2740(04F7) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2744(04F8) 00 00 00 00 | -2748(04F9) 00 00 00 00 | -274C(04FA) 00 00 00 00 | -2750(04FB) 00 00 00 00 | -2754(04FC) 00 00 00 00 | -2758(04FD) 00 00 00 00 | -275C(04FE) 00 00 00 00 | -2760(04FF) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$0000000c,$00000000,$00000018,$00000000 -2764(0500) 00 00 00 00 | -2768(0501) 00 00 00 00 | -276C(0502) 00 00 00 00 | -2770(0503) 0C 00 00 00 | -2774(0504) 00 00 00 00 | -2778(0505) 18 00 00 00 | -277C(0506) 00 00 00 00 | -2780(0507) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2784(0508) 00 00 00 00 | -2788(0509) 00 00 00 00 | -278C(050A) 00 00 00 00 | -2790(050B) 00 00 00 00 | -2794(050C) 00 00 00 00 | -2798(050D) 00 00 00 00 | -279C(050E) 00 00 00 00 | -27A0(050F) 00 00 00 00 | long $00000000,$00000000,$00000018,$0000000c,$00000000,$00000000,$00000000,$00000000 -27A4(0510) 00 00 00 00 | -27A8(0511) 18 00 00 00 | -27AC(0512) 0C 00 00 00 | -27B0(0513) 00 00 00 00 | -27B4(0514) 00 00 00 00 | -27B8(0515) 00 00 00 00 | -27BC(0516) 00 00 00 00 | -27C0(0517) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -27C4(0518) 00 00 00 00 | -27C8(0519) 00 00 00 00 | -27CC(051A) 00 00 00 00 | -27D0(051B) 00 00 00 00 | -27D4(051C) 00 00 00 00 | -27D8(051D) 00 00 00 00 | -27DC(051E) 00 00 00 00 | -27E0(051F) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -27E4(0520) 00 00 00 00 | -27E8(0521) 00 00 00 00 | -27EC(0522) 00 00 00 00 | -27F0(0523) 00 00 00 00 | -27F4(0524) 00 00 00 00 | -27F8(0525) 00 00 00 00 | -27FC(0526) 00 00 00 00 | -2800(0527) 00 00 00 00 | long $00000000,$00000060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2804(0528) 60 00 00 00 | -2808(0529) 00 00 00 00 | -280C(052A) 00 00 00 00 | -2810(052B) 00 00 00 00 | -2814(052C) 00 00 00 00 | -2818(052D) 00 00 00 00 | -281C(052E) 00 00 00 00 | -2820(052F) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$000000fe -2824(0530) 00 00 00 00 | -2828(0531) 00 00 00 00 | -282C(0532) 00 00 00 00 | -2830(0533) 00 00 00 00 | -2834(0534) 00 00 00 00 | -2838(0535) 00 00 00 00 | -283C(0536) FE 00 00 00 | -2840(0537) 00 00 00 00 | long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00003c66 -2844(0538) 00 00 00 00 | -2848(0539) 00 00 00 00 | -284C(053A) 00 00 00 00 | -2850(053B) 00 00 00 00 | -2854(053C) 00 00 00 00 | -2858(053D) 00 00 00 00 | -285C(053E) 66 3C 00 00 | -2860(053F) 00 00 00 00 | long $00000000,$00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000 -2864(0540) 00 00 00 00 | -2868(0541) 66 3C 00 00 | -286C(0542) 00 00 00 00 | -2870(0543) 00 00 00 00 | -2874(0544) 00 00 00 00 | -2878(0545) 00 00 00 00 | -287C(0546) 00 00 00 00 | -2880(0547) 06 06 00 00 | long $00000606,$00006060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 -2884(0548) 60 60 00 00 | -2888(0549) 00 00 00 00 | -288C(054A) 00 00 00 00 | -2890(054B) 00 00 00 00 | -2894(054C) 00 00 00 00 | -2898(054D) 00 00 00 00 | -289C(054E) 00 00 00 00 | -28A0(054F) 00 00 00 00 | long $00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000,$aa55aa55 -28A4(0550) 66 3C 00 00 | -28A8(0551) 00 00 00 00 | -28AC(0552) 00 00 00 00 | -28B0(0553) 00 00 00 00 | -28B4(0554) 00 00 00 00 | -28B8(0555) 00 00 00 00 | -28BC(0556) 55 AA 55 AA | -28C0(0557) 00 00 00 FF | long $ff000000,$ff000000,$ff002a55,$ff000030,$ff000018,$ff000058,$ff000018,$ff000000 -28C4(0558) 00 00 00 FF | -28C8(0559) 55 2A 00 FF | -28CC(055A) 30 00 00 FF | -28D0(055B) 18 00 00 FF | -28D4(055C) 58 00 00 FF | -28D8(055D) 18 00 00 FF | -28DC(055E) 00 00 00 FF | -28E0(055F) 00 00 00 FF | long $ff000000,$ff000078,$ff000030,$00000000,$24242424,$24242424,$00000000,$24242424 -28E4(0560) 78 00 00 FF | -28E8(0561) 30 00 00 FF | -28EC(0562) 00 00 00 00 | -28F0(0563) 24 24 24 24 | -28F4(0564) 24 24 24 24 | -28F8(0565) 00 00 00 00 | -28FC(0566) 24 24 24 24 | -2900(0567) 00 00 00 00 | long $00000000,$00000000,$00000000,$000000ff,$ff00ff00,$24242424,$24242424,$00000000 -2904(0568) 00 00 00 00 | -2908(0569) 00 00 00 00 | -290C(056A) FF 00 00 00 | -2910(056B) 00 FF 00 FF | -2914(056C) 24 24 24 24 | -2918(056D) 24 24 24 24 | -291C(056E) 00 00 00 00 | -2920(056F) 24 24 24 24 | long $24242424,$24242424,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2924(0570) 24 24 24 24 | -2928(0571) 00 00 00 FF | -292C(0572) 00 00 00 FF | -2930(0573) 00 00 00 FF | -2934(0574) 00 00 00 FF | -2938(0575) 00 00 00 FF | -293C(0576) 00 00 00 FF | -2940(0577) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2944(0578) 00 00 00 FF | -2948(0579) 00 00 00 FF | -294C(057A) 00 00 00 FF | -2950(057B) 00 00 00 FF | -2954(057C) 00 00 00 FF | -2958(057D) 00 00 00 FF | -295C(057E) 00 00 00 FF | -2960(057F) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff00000c,$ff000000,$ff000018,$ff000000 -2964(0580) 00 00 00 FF | -2968(0581) 00 00 00 FF | -296C(0582) 00 00 00 FF | -2970(0583) 0C 00 00 FF | -2974(0584) 00 00 00 FF | -2978(0585) 18 00 00 FF | -297C(0586) 00 00 00 FF | -2980(0587) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2984(0588) 00 00 00 FF | -2988(0589) 00 00 00 FF | -298C(058A) 00 00 00 FF | -2990(058B) 00 00 00 FF | -2994(058C) 00 00 00 FF | -2998(058D) 00 00 00 FF | -299C(058E) 00 00 00 FF | -29A0(058F) 00 00 00 FF | long $ff000000,$ff000000,$ff000018,$ff00000c,$ff000000,$ff000000,$ff000000,$ff000000 -29A4(0590) 00 00 00 FF | -29A8(0591) 18 00 00 FF | -29AC(0592) 0C 00 00 FF | -29B0(0593) 00 00 00 FF | -29B4(0594) 00 00 00 FF | -29B8(0595) 00 00 00 FF | -29BC(0596) 00 00 00 FF | -29C0(0597) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -29C4(0598) 00 00 00 FF | -29C8(0599) 00 00 00 FF | -29CC(059A) 00 00 00 FF | -29D0(059B) 00 00 00 FF | -29D4(059C) 00 00 00 FF | -29D8(059D) 00 00 00 FF | -29DC(059E) 00 00 00 FF | -29E0(059F) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -29E4(05A0) 00 00 00 FF | -29E8(05A1) 00 00 00 FF | -29EC(05A2) 00 00 00 FF | -29F0(05A3) 00 00 00 FF | -29F4(05A4) 00 00 00 FF | -29F8(05A5) 00 00 00 FF | -29FC(05A6) 00 00 00 FF | -2A00(05A7) 00 00 00 FF | long $ff000000,$ff000060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2A04(05A8) 60 00 00 FF | -2A08(05A9) 00 00 00 FF | -2A0C(05AA) 00 00 00 FF | -2A10(05AB) 00 00 00 FF | -2A14(05AC) 00 00 00 FF | -2A18(05AD) 00 00 00 FF | -2A1C(05AE) 00 00 00 FF | -2A20(05AF) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff0000fe -2A24(05B0) 00 00 00 FF | -2A28(05B1) 00 00 00 FF | -2A2C(05B2) 00 00 00 FF | -2A30(05B3) 00 00 00 FF | -2A34(05B4) 00 00 00 FF | -2A38(05B5) 00 00 00 FF | -2A3C(05B6) FE 00 00 FF | -2A40(05B7) 00 00 00 FF | long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff003c66 -2A44(05B8) 00 00 00 FF | -2A48(05B9) 00 00 00 FF | -2A4C(05BA) 00 00 00 FF | -2A50(05BB) 00 00 00 FF | -2A54(05BC) 00 00 00 FF | -2A58(05BD) 00 00 00 FF | -2A5C(05BE) 66 3C 00 FF | -2A60(05BF) 00 00 00 FF | long $ff000000,$ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2A64(05C0) 00 00 00 FF | -2A68(05C1) 66 3C 00 FF | -2A6C(05C2) 00 00 00 FF | -2A70(05C3) 00 00 00 FF | -2A74(05C4) 00 00 00 FF | -2A78(05C5) 00 00 00 FF | -2A7C(05C6) 00 00 00 FF | -2A80(05C7) 06 06 00 FF | long $ff000606,$ff006060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 -2A84(05C8) 60 60 00 FF | -2A88(05C9) 00 00 00 FF | -2A8C(05CA) 00 00 00 FF | -2A90(05CB) 00 00 00 FF | -2A94(05CC) 00 00 00 FF | -2A98(05CD) 00 00 00 FF | -2A9C(05CE) 00 00 00 FF | -2AA0(05CF) 00 00 00 FF | long $ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff55aa55 -2AA4(05D0) 66 3C 00 FF | -2AA8(05D1) 00 00 00 FF | -2AAC(05D2) 00 00 00 FF | -2AB0(05D3) 00 00 00 FF | -2AB4(05D4) 00 00 00 FF | -2AB8(05D5) 00 00 00 FF | -2ABC(05D6) 55 AA 55 FF | -|===========================================================================| -|===========================================================================| -Spin Block start with 4 Parameters and 2 Extra Stack Longs. Method 1 -PUB start(BasePin, ScreenPtr, CursorPtr, SyncPtr) : okay | i, j - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - BasePin -Local Parameter DBASE:0008 - ScreenPtr -Local Parameter DBASE:000C - CursorPtr -Local Parameter DBASE:0010 - SyncPtr -Local Variable DBASE:0014 - i -Local Variable DBASE:0018 - j -|===========================================================================| -85 stop -Addr : 2AC0: 01 : Drop Anchor -Addr : 2AC1: 05 02 : Call Sub 2 -88 reg_vcfg := $200000FF + (BasePin & %111000) << 6 -Addr : 2AC3: 3B 20 00 00 FF : Constant 4 Bytes - 20 00 00 FF -Addr : 2AC8: 64 : Variable Operation Local Offset - 1 Read -Addr : 2AC9: 38 38 : Constant 1 Bytes - 38 -Addr : 2ACB: E8 : Math Op & -Addr : 2ACC: 38 06 : Constant 1 Bytes - 06 -Addr : 2ACE: E3 : Math Op << -Addr : 2ACF: EC : Math Op + -Addr : 2AD0: C5 80 98 : Memory Op Long PBASE + WRITE Address = 0098 -89 i := $FF << (BasePin & %011000) -Addr : 2AD3: 37 27 : Constant Mask Y=39 Decrement 000000FF -Addr : 2AD5: 64 : Variable Operation Local Offset - 1 Read -Addr : 2AD6: 38 18 : Constant 1 Bytes - 18 -Addr : 2AD8: E8 : Math Op & -Addr : 2AD9: E3 : Math Op << -Addr : 2ADA: 75 : Variable Operation Local Offset - 5 Write -90 j := BasePin & %100000 == 0 -Addr : 2ADB: 64 : Variable Operation Local Offset - 1 Read -Addr : 2ADC: 37 04 : Constant Mask Y=4 00000020 -Addr : 2ADE: E8 : Math Op & -Addr : 2ADF: 35 : Constant 1 $00000000 -Addr : 2AE0: FC : Math Op == -Addr : 2AE1: 79 : Variable Operation Local Offset - 6 Write -91 reg_dira := i & j -Addr : 2AE2: 74 : Variable Operation Local Offset - 5 Read -Addr : 2AE3: 78 : Variable Operation Local Offset - 6 Read -Addr : 2AE4: E8 : Math Op & -Addr : 2AE5: C5 80 90 : Memory Op Long PBASE + WRITE Address = 0090 -92 reg_dirb := i & !j -Addr : 2AE8: 74 : Variable Operation Local Offset - 5 Read -Addr : 2AE9: 78 : Variable Operation Local Offset - 6 Read -Addr : 2AEA: E7 : Math Op ! -Addr : 2AEB: E8 : Math Op & -Addr : 2AEC: C5 80 94 : Memory Op Long PBASE + WRITE Address = 0094 -95 sync_cnt := cnt + $10000 -Addr : 2AEF: 3F 91 : Register op CNT Read -Addr : 2AF1: 37 0F : Constant Mask Y=15 00010000 -Addr : 2AF3: EC : Math Op + -Addr : 2AF4: C5 80 9C : Memory Op Long PBASE + WRITE Address = 009C -98 longmove(@screen_base, @ScreenPtr, 2) -Addr : 2AF7: C7 82 10 : Memory Op Long PBASE + ADDRESS Address = 0210 -Addr : 2AFA: 6B : Variable Operation Local Offset - 2 Address -Addr : 2AFB: 37 00 : Constant Mask Y=0 00000002 -Addr : 2AFD: 1E : LongMove(To, From, Count) -99 font_base := @font -Addr : 2AFE: C7 82 CC : Memory Op Long PBASE + ADDRESS Address = 02CC -Addr : 2B01: C5 82 18 : Memory Op Long PBASE + WRITE Address = 0218 -102 vf_lines.byte := vf -Addr : 2B04: 38 14 : Constant 1 Bytes - 14 -Addr : 2B06: 85 81 D8 : Memory Op Byte PBASE + WRITE Address = 01D8 -103 vb_lines.byte := vb -Addr : 2B09: 38 11 : Constant 1 Bytes - 11 -Addr : 2B0B: 85 80 A8 : Memory Op Byte PBASE + WRITE Address = 00A8 -104 font_part := 1 -Addr : 2B0E: 36 : Constant 2 $00000001 -Addr : 2B0F: C5 82 1C : Memory Op Long PBASE + WRITE Address = 021C -105 cog[1] := cognew(@d0, SyncPtr) + 1 -Addr : 2B12: 34 : Constant 0 $FFFFFFFF -Addr : 2B13: C7 0C : Memory Op Long PBASE + ADDRESS Address = 000C -Addr : 2B15: 70 : Variable Operation Local Offset - 4 Read -Addr : 2B16: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 2B17: 36 : Constant 2 $00000001 -Addr : 2B18: EC : Math Op + -Addr : 2B19: 36 : Constant 2 $00000001 -Addr : 2B1A: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -108 waitcnt($2000 + cnt) -Addr : 2B1C: 37 0C : Constant Mask Y=12 00002000 -Addr : 2B1E: 3F 91 : Register op CNT Read -Addr : 2B20: EC : Math Op + -Addr : 2B21: 23 : WaitCnt(count) -111 vf_lines.byte := vf+4 -Addr : 2B22: 38 14 : Constant 1 Bytes - 14 -Addr : 2B24: 37 01 : Constant Mask Y=1 00000004 -Addr : 2B26: EC : Math Op + -Addr : 2B27: 85 81 D8 : Memory Op Byte PBASE + WRITE Address = 01D8 -112 vb_lines.byte := vb-4 -Addr : 2B2A: 38 11 : Constant 1 Bytes - 11 -Addr : 2B2C: 37 01 : Constant Mask Y=1 00000004 -Addr : 2B2E: ED : Math Op - -Addr : 2B2F: 85 80 A8 : Memory Op Byte PBASE + WRITE Address = 00A8 -113 font_part := 0 -Addr : 2B32: 35 : Constant 1 $00000000 -Addr : 2B33: C5 82 1C : Memory Op Long PBASE + WRITE Address = 021C -114 cog[0] := cognew(@d0, SyncPtr) + 1 -Addr : 2B36: 34 : Constant 0 $FFFFFFFF -Addr : 2B37: C7 0C : Memory Op Long PBASE + ADDRESS Address = 000C -Addr : 2B39: 70 : Variable Operation Local Offset - 4 Read -Addr : 2B3A: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 2B3B: 36 : Constant 2 $00000001 -Addr : 2B3C: EC : Math Op + -Addr : 2B3D: 35 : Constant 1 $00000000 -Addr : 2B3E: D9 00 : Memory Op Long VBASE + POP Index WRITE Address = 0000 -117 if cog[0] and cog[1] -Addr : 2B40: 35 : Constant 1 $00000000 -Addr : 2B41: D8 00 : Memory Op Long VBASE + POP Index READ Address = 0000 -Addr : 2B43: 36 : Constant 2 $00000001 -Addr : 2B44: D8 00 : Memory Op Long VBASE + POP Index READ Address = 0000 -Addr : 2B46: F0 : Math Op AND -Addr : 2B47: JZ Label0008 -Addr : 2B47: 0A 02 : jz Address = 2B4B 2 -118 return true -Addr : 2B49: 34 : Constant 0 $FFFFFFFF -Addr : 2B4A: 33 : Return value -Addr : 2B4B: Label0008 -Addr : 2B4B: Label0009 -121 stop -Addr : 2B4B: 01 : Drop Anchor -Addr : 2B4C: 05 02 : Call Sub 2 -Addr : 2B4E: 32 : Return -|===========================================================================| -Spin Block stop with 0 Parameters and 1 Extra Stack Longs. Method 2 -PUB stop | i - -Local Parameter DBASE:0000 - Result -Local Variable DBASE:0004 - i -|===========================================================================| -128 repeat i from 0 to 1 -Addr : 2B4F: 35 : Constant 1 $00000000 -Addr : 2B50: 65 : Variable Operation Local Offset - 1 Write -Addr : 2B51: Label0008 -Addr : 2B51: Label0009 -Addr : 2B51: 35 : Constant 1 $00000000 -Addr : 2B52: 36 : Constant 2 $00000001 -Addr : 2B53: Repeat i Step Label0008 -Addr : 2B53: 66 02 7B : Variable Operation Local Offset - 1 Assign Repeat-Var loop Address= 2B51 -5 -Addr : 2B56: Label000A -129 if cog[i] -Addr : 2B56: 64 : Variable Operation Local Offset - 1 Read -Addr : 2B57: D8 00 : Memory Op Long VBASE + POP Index READ Address = 0000 -Addr : 2B59: JZ Label000B -Addr : 2B59: 0A 00 : jz Address = 2B5B 0 -Addr : 2B5B: Label000B -Addr : 2B5B: Label000C -130 cogstop(cog[i]~ - 1) -Addr : 2B5B: 64 : Variable Operation Local Offset - 1 Read -Addr : 2B5C: DA 00 98 : Memory Op Long VBASE + POP Index ASSIGN Address = 0000 VAR~ Post-clear Push -Addr : 2B5F: 36 : Constant 2 $00000001 -Addr : 2B60: ED : Math Op - -Addr : 2B61: 21 : CogStop(id) -Addr : 2B62: 32 : Return -|===========================================================================| -Object vt100 -Object Base is 2B64 -|===========================================================================| -Object Constants -|===========================================================================| -|===========================================================================| -VBASE Global Variables -|===========================================================================| -VBASE : 0000 LONG Size 0004 Variable cog -|===========================================================================| -Object DAT Blocks -|===========================================================================| -2B70(0000) | org 0 -2B70(0000) | entry -2B70(0000) F0 69 BC A0 | command_ptr mov t1, PAR -2B74(0001) 34 00 BC 08 | cmd rdlong command_ptr, t1 ' parameter 0 -2B78(0002) 04 68 FC 80 | screen_ptr add t1, #4 -2B7C(0003) 34 04 BC 08 | screen_end rdlong screen_ptr, t1 ' parameter 1 -2B80(0004) 04 68 FC 80 | cursor_ptr add t1, #4 -2B84(0005) 34 08 BC 08 | vsync_ptr rdlong cursor_ptr, t1 ' parameter 2 -2B88(0006) 04 68 FC 80 | screen_w add t1, #4 -2B8C(0007) 34 0A BC 08 | screen_w2 rdlong vsync_ptr, t1 ' parameter 3 -2B90(0008) 04 68 FC 80 | screen_h add t1, #4 -2B94(0009) 34 0C BC 08 | cur_ptr rdlong screen_w, t1 ' parameter 4 -2B98(000A) 04 68 FC 80 | scroll_top add t1, #4 -2B9C(000B) 34 10 BC 08 | scroll_bot rdlong screen_h, t1 ' parameter 5 -2BA0(000C) 06 0E BC A0 | dst mov screen_w2, screen_w -2BA4(000D) 01 0E FC 28 | src shr screen_w2, #1 ' screen width / 2 -2BA8(000E) 06 68 BC A0 | end mov t1, screen_w -2BAC(000F) 08 6A BC A0 | data mov t2, screen_h -2BB0(0010) 79 FF FE 5C | cols call #mul16x16 -2BB4(0011) 35 06 BC A0 | rows mov screen_end, t2 ' result in t2 -2BB8(0012) 35 06 BC 80 | lmm_pc add screen_end, t2 ' * 2 -2BBC(0013) 02 06 BC 80 | cur_x_save add screen_end, screen_ptr -2BC0(0014) 00 14 FC A0 | cur_y_save mov scroll_top, #0 -2BC4(0015) 08 16 BC A0 | new_x_save mov scroll_bot, screen_h -2BC8(0016) F1 47 BC A0 | attr_save mov cur_delay, CNT -2BCC(0017) 45 00 7C 5C | jmp #startup -2BD0(0018) A4 31 00 00 | control_ptr long @@@control_table -2BD4(0019) E4 31 00 00 | csi_cmds_ptr long @@@csi_cmds -2BD8(001A) 20 00 20 00 | x00200020 long $00200020 -2BDC(001B) 5F 00 00 00 | cur_block long $5f -2BE0(001C) 00 00 00 00 | inverse long 0 -2BE4(001D) 00 00 00 00 | cur_x long 0 -2BE8(001E) 00 00 00 00 | new_x long 0 -2BEC(001F) 00 00 00 00 | cur_y long 0 -2BF0(0020) 00 00 00 00 | attr long 0 ' attribute mode -2BF4(0021) 24 00 00 00 | flags long flag_decom | flag_decawm -2BF8(0022) 00 00 00 00 | cur_char long 0 -2BFC(0023) 00 00 00 00 | cur_delay long 0 -2C00(0024) 07 00 00 00 | fgcol long %0111 ' foreground color -2C04(0025) 00 00 00 00 | bgcol long %0000 ' background color -2C08(0026) 00 07 00 00 | color long %00000111_00000000 ' composed fore- and background -2C0C(0027) 00 00 00 00 | esc_mode long 0 -2C10(0028) 00 00 00 00 | csi_mode long 0 -2C14(0029) 00 00 00 00 | csi_argc long 0 -2C18(002A) 00 00 00 00 | csi_argf long 0 -2C1C(002B) 00 00 00 00 | csi_args long 0,0,0,0,0,0,0,0 -2C20(002C) 00 00 00 00 | -2C24(002D) 00 00 00 00 | -2C28(002E) 00 00 00 00 | -2C2C(002F) 00 00 00 00 | -2C30(0030) 00 00 00 00 | -2C34(0031) 00 00 00 00 | -2C38(0032) 00 00 00 00 | -2C3C(0033) 00 00 00 00 | question_mark long 0 -2C40(0034) 00 00 00 00 | t1 long 0 -2C44(0035) 00 00 00 00 | t2 long 0 -2C48(0036) 00 00 00 00 | t3 long 0 -2C4C(0037) | goto_xay -2C4C(0037) 0A 3E BC 80 | add cur_y, scroll_top -2C50(0038) | validate_cursor -2C50(0038) 1D 3A BC A1 | mov cur_x, cur_x WC ' negative x? -2C54(0039) 00 3A F0 A0 | if_c mov cur_x, #0 ' yes, clip to 0 -2C58(003A) 06 3A 3C 87 | cmp cur_x, screen_w WZ, WC -2C5C(003B) 06 3A 8C A0 | if_ae mov cur_x, screen_w ' stay inside the boundaries -2C60(003C) 01 3A CC 84 | if_ae sub cur_x, #1 -2C64(003D) 1D 3C BC A0 | mov new_x, cur_x -2C68(003E) 1F 3E BC A1 | mov cur_y, cur_y WC ' negative y? -2C6C(003F) 00 3E F0 A0 | if_c mov cur_y, #0 ' yes, clip to 0 -2C70(0040) 08 3E 3C 87 | cmp cur_y, screen_h WZ, WC -2C74(0041) 08 3E 8C A0 | if_ae mov cur_y, screen_h ' stay inside the boundaries -2C78(0042) 01 3E CC 84 | if_ae sub cur_y, #1 -2C7C(0043) | cmdloop -2C7C(0043) 00 02 FC A0 | mov cmd, #0 -2C80(0044) 00 02 3C 08 | wrlong cmd, command_ptr -2C84(0045) | startup -2C84(0045) 4C 08 7C EC | :loop tjz cursor_ptr, #:cursor ' skip if cursor_ptr is null -2C88(0046) 04 3C 3C 00 | wrbyte new_x, cursor_ptr ' write the (new) cursor position -2C8C(0047) 01 08 FC 80 | add cursor_ptr, #1 -2C90(0048) 04 3E 3C 00 | wrbyte cur_y, cursor_ptr ' and the cursor row, too -2C94(0049) 01 08 FC 84 | sub cursor_ptr, #1 -2C98(004A) 5A C3 FE 5C | call #calc_cursor -2C9C(004B) 5B 00 7C 5C | jmp #:check_cmd -2CA0(004C) 23 68 BC A0 | :cursor mov t1, cur_delay ' software cursor -2CA4(004D) F1 69 BC 84 | sub t1, CNT -2CA8(004E) 00 68 7C C3 | cmps t1, #0 WZ, WC -2CAC(004F) 5B 00 4C 5C | if_ae jmp #:check_cmd -2CB0(0050) 00 68 FC 08 | rdlong t1, #0 ' get clkfreq -2CB4(0051) 02 68 FC 28 | shr t1, #2 ' / 4 -2CB8(0052) 34 46 BC 80 | add cur_delay, t1 ' next cursor flash event -2CBC(0053) 5A C3 FE 5C | call #calc_cursor -2CC0(0054) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC ' new_x beyond last column? -2CC4(0055) 5B 00 4C 5C | if_ae jmp #:check_cmd -2CC8(0056) 22 68 BC A2 | mov t1, cur_char WZ ' get saved character -2CCC(0057) 09 44 A8 00 | if_z rdbyte cur_char, cur_ptr ' none: save character under cursor -2CD0(0058) 09 36 28 00 | if_z wrbyte cur_block, cur_ptr ' display a cursor block -2CD4(0059) 00 44 D4 A0 | if_nz mov cur_char, #0 ' reset saved character -2CD8(005A) 09 68 14 00 | if_nz wrbyte t1, cur_ptr ' restore saved character in screen buffer -2CDC(005B) 00 02 BC 0A | :check_cmd rdlong cmd, command_ptr WZ -2CE0(005C) 45 00 68 5C | if_z jmp #:loop -2CE4(005D) 22 68 BC A2 | mov t1, cur_char WZ ' get saved character -2CE8(005E) 03 12 14 85 | if_nz cmp cur_ptr, screen_end WC -2CEC(005F) 00 44 D0 A0 | if_nz_and_c mov cur_char, #0 ' reset saved character -2CF0(0060) 09 68 10 00 | if_nz_and_c wrbyte t1, cur_ptr ' restore saved character in screen buffer -2CF4(0061) FF 02 FC 60 | and cmd, #$ff -2CF8(0062) 88 50 7C E8 | tjnz csi_mode, #csi ' go to CSI decoding if enabled -2CFC(0063) 7F 4E 7C E8 | tjnz esc_mode, #esc ' go to ESC decoding if enabled -2D00(0064) 20 02 7C 87 | cmp cmd, #$20 WZ, WC ' other control characters? -2D04(0065) 6A 00 4C 5C | if_ae jmp #do_emit ' no, just emit to the screen buffer -2D08(0066) 01 02 FC 2C | shl cmd, #1 -2D0C(0067) 18 02 BC 80 | add cmd, control_ptr -2D10(0068) 01 02 BC 04 | rdword cmd, cmd -2D14(0069) 01 00 3C 5C | jmp cmd ' dispatch on control_table -2D18(006A) 4A B3 FE 5C | do_emit call #emit -2D1C(006B) 43 00 7C 5C | jmp #cmdloop -2D20(006C) | do_nul ' NUL - null character -2D20(006C) | do_soh ' SOH - start of header -2D20(006C) | do_stx ' STX - start of text -2D20(006C) | do_etx ' ETX - end of text -2D20(006C) | do_eot ' EOT - end of transmission -2D20(006C) | do_enq ' ENQ - enquiry -2D20(006C) | do_ack ' ACK - acknowledgement -2D20(006C) | do_bel ' BEL - bell -2D20(006C) | do_dle ' DLE - data link escape -2D20(006C) | do_dc1 ' DC1 - device control 1 (XON) -2D20(006C) | do_dc2 ' DC2 - device control 2 -2D20(006C) | do_dc3 ' DC3 - device control 3 (XOFF) -2D20(006C) | do_dc4 ' DC4 - device control 4 -2D20(006C) | do_nak ' NAK - negative acknowledgement -2D20(006C) | do_syn ' SYN - synchronous idle -2D20(006C) | do_etb ' ETB - end of transmission block -2D20(006C) | do_em ' EM - end of medium -2D20(006C) | do_sub ' SUB - substitute -2D20(006C) | do_fs ' FS - file separator -2D20(006C) | do_gs ' GS - group separator -2D20(006C) | do_rs ' RS - request to send -2D20(006C) | do_us ' US - unit separator -2D20(006C) 43 00 7C 5C | jmp #cmdloop -2D24(006D) C4 8C FD 5C | do_cr call #cr -2D28(006E) 43 00 7C 5C | jmp #cmdloop -2D2C(006F) C7 9A FD 5C | do_bs call #bs -2D30(0070) 43 00 7C 5C | jmp #cmdloop -2D34(0071) D2 AC FD 5C | do_ht call #ht -2D38(0072) 43 00 7C 5C | jmp #cmdloop -2D3C(0073) D7 04 FE 5C | do_lf call #lf -2D40(0074) 43 00 7C 5C | jmp #cmdloop -2D44(0075) 03 59 FE 5C | do_vt call #vt -2D48(0076) 43 00 7C 5C | jmp #cmdloop -2D4C(0077) 2D 73 FE 5C | do_ff call #ff -2D50(0078) 43 00 7C 5C | jmp #cmdloop -2D54(0079) | do_so ' ??? -2D54(0079) 43 00 7C 5C | jmp #cmdloop -2D58(007A) | do_si ' ??? -2D58(007A) 43 00 7C 5C | jmp #cmdloop -2D5C(007B) | do_can ' CAN - cancel -2D5C(007B) 3E 93 FE 5C | call #can -2D60(007C) 43 00 7C 5C | jmp #cmdloop -2D64(007D) | do_esc -2D64(007D) 01 4E FC A0 | mov esc_mode, #1 -2D68(007E) 43 00 7C 5C | jmp #cmdloop -2D6C(007F) | esc -2D6C(007F) 00 4E FC A0 | mov esc_mode, #0 -2D70(0080) 5B 02 7C 86 | cmp cmd, #"[" WZ -2D74(0081) 83 00 68 5C | if_z jmp #:csi -2D78(0082) 43 00 7C 5C | jmp #cmdloop -2D7C(0083) | :csi -2D7C(0083) 01 50 FC A0 | mov csi_mode, #1 ' start CSI mode -2D80(0084) 00 52 FC A0 | mov csi_argc, #0 ' argument count = 0 -2D84(0085) 00 54 FC A0 | mov csi_argf, #0 ' argument flag = 0 -2D88(0086) 00 56 FC A0 | mov csi_args, #0 ' first argument = 0 -2D8C(0087) 43 00 7C 5C | jmp #cmdloop -2D90(0088) | csi -2D90(0088) 01 50 7C 86 | cmp csi_mode, #1 WZ ' first character after "["? -2D94(0089) 8E 00 54 5C | if_nz jmp #:not_question ' no, check arguments -2D98(008A) 02 50 FC A0 | mov csi_mode, #2 ' skip this test in the future -2D9C(008B) 3F 02 7C 86 | cmp cmd, #"?" WZ ' "[?" mode? -2DA0(008C) 01 66 FC 78 | muxz question_mark, #1 -2DA4(008D) 43 00 68 5C | if_z jmp #cmdloop -2DA8(008E) | :not_question -2DA8(008E) 30 02 7C 87 | cmp cmd, #"0" WZ, WC -2DAC(008F) A0 00 70 5C | if_b jmp #:not_numeric -2DB0(0090) 39 02 7C 87 | cmp cmd, #"9" WZ, WC -2DB4(0091) A0 00 44 5C | if_a jmp #:not_numeric -2DB8(0092) 29 68 BC A0 | mov t1, csi_argc -2DBC(0093) 2B 68 FC 80 | add t1, #csi_args -2DC0(0094) 34 2E BD 50 | movs :get_arg, t1 -2DC4(0095) 34 3C BD 54 | movd :put_arg, t1 -2DC8(0096) 01 54 FC A0 | mov csi_argf, #1 ' set the "seen arguments" flag -2DCC(0097) 00 68 BC A0 | :get_arg mov t1, 0-0 ' get csi_args[csi_argc] -2DD0(0098) 34 6A BC A0 | mov t2, t1 ' to t2 also -2DD4(0099) 02 68 FC 2C | shl t1, #2 ' * 4 -2DD8(009A) 35 68 BC 80 | add t1, t2 ' * 5 -2DDC(009B) 01 68 FC 2C | shl t1, #1 ' * 10 -2DE0(009C) 01 68 BC 80 | add t1, cmd ' + digit -2DE4(009D) 30 68 FC 84 | sub t1, #"0" ' - ASCII for "0" -2DE8(009E) 34 00 BC A0 | :put_arg mov 0-0, t1 ' put csi_args[csi_argc] -2DEC(009F) 43 00 7C 5C | jmp #cmdloop -2DF0(00A0) | :not_numeric -2DF0(00A0) 3B 02 7C 86 | cmp cmd, #";" WZ ' next argument delimiter? -2DF4(00A1) AA 00 54 5C | if_nz jmp #:not_delimiter -2DF8(00A2) 07 52 7C 86 | cmp csi_argc, #7 WZ ' reached maximum number of arguments? -2DFC(00A3) 01 52 D4 80 | if_nz add csi_argc, #1 ' no, use next slot -2E00(00A4) 29 68 BC A0 | mov t1, csi_argc -2E04(00A5) 2B 68 FC 80 | add t1, #csi_args -2E08(00A6) 34 50 BD 54 | movd :clr_arg, t1 -2E0C(00A7) 00 00 00 00 | nop -2E10(00A8) 00 00 FC A0 | :clr_arg mov 0-0, #0 ' preset csi_args[csi_argc] to 0 -2E14(00A9) 43 00 7C 5C | jmp #cmdloop -2E18(00AA) | :not_delimiter -2E18(00AA) 00 50 FC A0 | mov csi_mode, #0 ' end CSI mode -2E1C(00AB) 2A 52 BC 80 | add csi_argc, csi_argf ' incr. argument count, if any arguments were specified -2E20(00AC) 40 02 7C 87 | cmp cmd, #"@" WZ, WC ' below @? -2E24(00AD) 43 00 70 5C | if_b jmp #cmdloop -2E28(00AE) 7A 02 7C 87 | cmp cmd, #"z" WZ, WC ' above z? -2E2C(00AF) 43 00 4C 5C | if_ae jmp #cmdloop -2E30(00B0) 40 02 FC 84 | sub cmd, #"@" -2E34(00B1) 01 02 FC 2C | shl cmd, #1 ' function word index -2E38(00B2) 19 02 BC 80 | add cmd, csi_cmds_ptr -2E3C(00B3) 01 02 BC 04 | rdword cmd, cmd ' get function pointer -2E40(00B4) FF 03 7C 66 | testn cmd, #$1ff WZ ' any bits outside the cog? -2E44(00B5) 01 00 28 5C | if_z jmp cmd ' cog function -2E48(00B6) 01 24 BC A0 | mov lmm_pc, cmd ' otherwise it's an LMM address -2E4C(00B7) 80 01 7C 5C | jmp #lmm_loop ' execute LMM code -2E50(00B8) | non_zero_args -2E50(00B8) BA 56 7C E8 | tjnz csi_args, #non_zero_args_ret -2E54(00B9) 01 56 FC 80 | add csi_args, #1 -2E58(00BA) | non_zero_args_ret -2E58(00BA) 00 00 7C 5C | ret -2E5C(00BB) | shift_csi_args -2E5C(00BB) 2C 56 BC A0 | mov csi_args, csi_args + 1 -2E60(00BC) 2D 58 BC A0 | mov csi_args + 1, csi_args + 2 -2E64(00BD) 2E 5A BC A0 | mov csi_args + 2, csi_args + 3 -2E68(00BE) 2F 5C BC A0 | mov csi_args + 3, csi_args + 4 -2E6C(00BF) 30 5E BC A0 | mov csi_args + 4, csi_args + 5 -2E70(00C0) 31 60 BC A0 | mov csi_args + 5, csi_args + 6 -2E74(00C1) 32 62 BC A0 | mov csi_args + 6, csi_args + 7 -2E78(00C2) 00 64 FC A0 | mov csi_args + 7, #0 -2E7C(00C3) | shift_csi_args_ret -2E7C(00C3) 00 00 7C 5C | ret -2E80(00C4) | cr -2E80(00C4) 00 3A FC A0 | mov cur_x, #0 -2E84(00C5) 00 3C FC A0 | mov new_x, #0 -2E88(00C6) | cr_ret -2E88(00C6) 00 00 7C 5C | ret -2E8C(00C7) | bs -2E8C(00C7) 00 3C 7C 86 | cmp new_x, #0 WZ -2E90(00C8) 01 3C D4 84 | if_nz sub new_x, #1 -2E94(00C9) CD 00 54 5C | if_nz jmp #bs_ret -2E98(00CA) 06 3C BC A0 | mov new_x, screen_w -2E9C(00CB) 01 3C FC 84 | sub new_x, #1 -2EA0(00CC) 03 59 FE 5C | call #vt -2EA4(00CD) | bs_ret -2EA4(00CD) 00 00 7C 5C | ret -2EA8(00CE) | fs -2EA8(00CE) 01 3A FC 80 | add cur_x, #1 -2EAC(00CF) 06 3A 3C 86 | cmp cur_x, screen_w WZ -2EB0(00D0) 01 3A E8 84 | if_z sub cur_x, #1 ' stay in last column -2EB4(00D1) | fs_ret -2EB4(00D1) 00 00 7C 5C | ret -2EB8(00D2) | ht -2EB8(00D2) 20 02 FC A0 | mov cmd, #$20 -2EBC(00D3) 4A B3 FE 5C | call #emit -2EC0(00D4) 07 3C 7C 62 | test new_x, #7 WZ -2EC4(00D5) D2 00 54 5C | if_nz jmp #ht -2EC8(00D6) | ht_ret -2EC8(00D6) 00 00 7C 5C | ret -2ECC(00D7) | lf -2ECC(00D7) 01 3E FC 80 | add cur_y, #1 -2ED0(00D8) 04 42 7C 62 | test flags, #flag_decom WZ ' origin mode enabled? -2ED4(00D9) E2 00 54 5C | if_nz jmp #:origin ' yes, check cursor in scroll range -2ED8(00DA) 08 3E 3C 87 | :screen cmp cur_y, screen_h WZ, WC ' no, check cursor in screen range -2EDC(00DB) 02 01 70 5C | if_b jmp #lf_ret -2EE0(00DC) 08 3E BC A0 | mov cur_y, screen_h -2EE4(00DD) 01 3E FC 84 | sub cur_y, #1 -2EE8(00DE) 02 18 BC A0 | mov dst, screen_ptr ' destination = screen buffer -2EEC(00DF) 02 1A BC A0 | mov src, screen_ptr ' source = dito -2EF0(00E0) 08 22 BC A0 | mov rows, screen_h ' screen height -2EF4(00E1) EF 00 7C 5C | jmp #scroll_up_1 ' scroll the entire screen -2EF8(00E2) 0B 3E 3C 87 | :origin cmp cur_y, scroll_bot WZ, WC -2EFC(00E3) 02 01 70 5C | if_b jmp #lf_ret -2F00(00E4) 0B 3E BC A0 | mov cur_y, scroll_bot -2F04(00E5) 01 3E FC 84 | sub cur_y, #1 -2F08(00E6) | scroll_up -2F08(00E6) 0A 68 BC A0 | mov t1, scroll_top -2F0C(00E7) 06 6A BC A0 | mov t2, screen_w -2F10(00E8) 79 FF FE 5C | call #mul16x16 -2F14(00E9) 01 6A FC 2C | shl t2, #1 -2F18(00EA) 02 6A BC 80 | add t2, screen_ptr -2F1C(00EB) 35 18 BC A0 | mov dst, t2 ' destination = scroll_top of screen buffer -2F20(00EC) 35 1A BC A0 | mov src, t2 ' source = dito -2F24(00ED) 0B 22 BC A0 | mov rows, scroll_bot ' scroll range height -2F28(00EE) 0A 22 BC 84 | sub rows, scroll_top -2F2C(00EF) | scroll_up_1 -2F2C(00EF) 06 1A BC 80 | add src, screen_w ' copy from one line below -2F30(00F0) 06 1A BC 80 | add src, screen_w -2F34(00F1) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 rows to move -2F38(00F2) FA 00 78 5C | if_be jmp #:fill ' nothing left to scroll? -2F3C(00F3) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -2F40(00F4) 0D 1E BC 08 | :cols rdlong data, src -2F44(00F5) 04 1A FC 80 | add src, #4 -2F48(00F6) 0C 1E 3C 08 | wrlong data, dst -2F4C(00F7) 04 18 FC 80 | add dst, #4 -2F50(00F8) F4 20 FC E4 | djnz cols, #:cols -2F54(00F9) F3 22 FC E4 | djnz rows, #:rows -2F58(00FA) 07 20 BC A0 | :fill mov cols, screen_w2 ' columns = screen width / 2 -2F5C(00FB) 1A 68 BC A0 | mov t1, x00200020 -2F60(00FC) 26 68 BC 68 | or t1, color -2F64(00FD) 10 68 FC 24 | rol t1, #16 -2F68(00FE) 26 68 BC 68 | or t1, color -2F6C(00FF) 0C 68 3C 08 | :blank wrlong t1, dst ' fill 4 spaces -2F70(0100) 04 18 FC 80 | add dst, #4 -2F74(0101) FF 20 FC E4 | djnz cols, #:blank -2F78(0102) | scroll_up_ret -2F78(0102) | lf_ret -2F78(0102) 00 00 7C 5C | ret -2F7C(0103) | vt -2F7C(0103) 01 3E FC 84 | sub cur_y, #1 -2F80(0104) 04 42 7C 62 | test flags, #flag_decom WZ ' origin mode enabled? -2F84(0105) 0D 01 54 5C | if_nz jmp #:origin ' yes, check cursor in scroll range -2F88(0106) | :screen ' no, check cursor in screen range -2F88(0106) 00 3E 7C C3 | cmps cur_y, #0 WZ, WC ' < 0? -2F8C(0107) 2C 01 4C 5C | if_ae jmp #vt_ret ' in range -2F90(0108) 00 3E FC A0 | mov cur_y, #0 ' stay in line 0 -2F94(0109) 03 1A BC A0 | mov src, screen_end -2F98(010A) 03 18 BC A0 | mov dst, screen_end -2F9C(010B) 08 22 BC A0 | mov rows, screen_h -2FA0(010C) 19 01 7C 5C | jmp #scroll_down_1 -2FA4(010D) | :origin -2FA4(010D) 0A 3E 3C C3 | cmps cur_y, scroll_top WZ, WC -2FA8(010E) 2C 01 4C 5C | if_ae jmp #vt_ret -2FAC(010F) 0A 3E BC A0 | mov cur_y, scroll_top -2FB0(0110) | scroll_down -2FB0(0110) 0B 68 BC A0 | mov t1, scroll_bot -2FB4(0111) 06 6A BC A0 | mov t2, screen_w -2FB8(0112) 79 FF FE 5C | call #mul16x16 -2FBC(0113) 01 6A FC 2C | shl t2, #1 -2FC0(0114) 02 6A BC 80 | add t2, screen_ptr -2FC4(0115) 35 18 BC A0 | mov dst, t2 ' destination = end of scroll range buffer -2FC8(0116) 35 1A BC A0 | mov src, t2 ' source = last row of scroll range buffer -2FCC(0117) 0B 22 BC A0 | mov rows, scroll_bot ' scroll range height -2FD0(0118) 0A 22 BC 84 | sub rows, scroll_top -2FD4(0119) | scroll_down_1 -2FD4(0119) 06 1A BC 84 | sub src, screen_w -2FD8(011A) 06 1A BC 84 | sub src, screen_w -2FDC(011B) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 rows to move -2FE0(011C) 24 01 78 5C | if_be jmp #:fill ' nothing left to scroll? -2FE4(011D) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -2FE8(011E) 04 1A FC 84 | :cols sub src, #4 ' pre decrement source -2FEC(011F) 0D 1E BC 08 | rdlong data, src -2FF0(0120) 04 18 FC 84 | sub dst, #4 ' pre decrement destination -2FF4(0121) 0C 1E 3C 08 | wrlong data, dst -2FF8(0122) 1E 21 FC E4 | djnz cols, #:cols ' for all columns -2FFC(0123) 1D 23 FC E4 | djnz rows, #:rows ' for all rows -3000(0124) 1A 68 BC A0 | :fill mov t1, x00200020 -3004(0125) 26 68 BC 68 | or t1, color -3008(0126) 10 68 FC 24 | rol t1, #16 -300C(0127) 26 68 BC 68 | or t1, color -3010(0128) 07 20 BC A0 | mov cols, screen_w2 ' columns = screen width / 2 -3014(0129) 04 18 FC 84 | :blank sub dst, #4 -3018(012A) 0C 68 3C 08 | wrlong t1, dst -301C(012B) 29 21 FC E4 | djnz cols, #:blank -3020(012C) | scroll_down_ret -3020(012C) | vt_ret -3020(012C) 00 00 7C 5C | ret -3024(012D) | ff -3024(012D) 02 18 BC A0 | mov dst, screen_ptr -3028(012E) 08 22 BC A0 | mov rows, screen_h ' screen height rows -302C(012F) 1A 68 BC A0 | mov t1, x00200020 -3030(0130) 26 68 BC 68 | or t1, color -3034(0131) 10 68 FC 24 | rol t1, #16 -3038(0132) 26 68 BC 68 | or t1, color -303C(0133) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3040(0134) 0C 68 3C 08 | :cols wrlong t1, dst ' fill with 4 blanks -3044(0135) 04 18 FC 80 | add dst, #4 -3048(0136) 34 21 FC E4 | djnz cols, #:cols ' for all columns -304C(0137) 33 23 FC E4 | djnz rows, #:rows ' for all rows -3050(0138) 3A 7B FE 5C | call #home -3054(0139) | ff_ret -3054(0139) 00 00 7C 5C | ret -3058(013A) | home -3058(013A) 00 3A FC A0 | mov cur_x, #0 -305C(013B) 00 3C FC A0 | mov new_x, #0 -3060(013C) 00 3E FC A0 | mov cur_y, #0 -3064(013D) | home_ret -3064(013D) 00 00 7C 5C | ret -3068(013E) | can -3068(013E) 09 18 BC A0 | mov dst, cur_ptr -306C(013F) 06 20 BC A0 | mov cols, screen_w -3070(0140) 1E 20 BC 87 | sub cols, new_x WZ, WC -3074(0141) 49 01 78 5C | if_be jmp #can_ret -3078(0142) 1A 68 BC A0 | mov t1, x00200020 -307C(0143) 26 68 BC 68 | or t1, color -3080(0144) 10 68 FC 24 | rol t1, #16 -3084(0145) 26 68 BC 68 | or t1, color -3088(0146) 0C 68 3C 04 | :fill wrword t1, dst -308C(0147) 02 18 FC 80 | add dst, #2 -3090(0148) 46 21 FC E4 | djnz cols, #:fill -3094(0149) | can_ret -3094(0149) 00 00 7C 5C | ret -3098(014A) | emit -3098(014A) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC ' reached end of line? -309C(014B) 50 01 70 5C | if_b jmp #:in_bounds -30A0(014C) 20 42 7C 62 | test flags, #flag_decawm WZ ' auto wrap mode active? -30A4(014D) 59 01 68 5C | if_z jmp #emit_ret ' no, don't emit character -30A8(014E) C4 8C FD 5C | call #cr -30AC(014F) D7 04 FE 5C | call #lf -30B0(0150) 1E 3A BC A0 | :in_bounds mov cur_x, new_x -30B4(0151) 5A C3 FE 5C | call #calc_cursor -30B8(0152) 26 02 BC 68 | or cmd, color -30BC(0153) 02 40 7C 62 | test attr, #attr_underline WZ -30C0(0154) 80 02 FC 7C | muxnz cmd, #$80 -30C4(0155) 09 02 3C 04 | wrword cmd, cur_ptr ' write character to screen RAM -30C8(0156) 1D 3C BC A0 | mov new_x, cur_x -30CC(0157) 01 3C FC 80 | add new_x, #1 -30D0(0158) 02 12 FC 80 | add cur_ptr, #2 -30D4(0159) | emit_ret -30D4(0159) 00 00 7C 5C | ret -30D8(015A) | calc_cursor -30D8(015A) 1F 68 BC A0 | mov t1, cur_y ' cursor row -30DC(015B) 06 6A BC A0 | mov t2, screen_w ' * screen width -30E0(015C) 79 FF FE 5C | call #mul16x16 -30E4(015D) 35 12 BC A0 | mov cur_ptr, t2 ' product in cur_ptr -30E8(015E) 1E 12 BC 80 | add cur_ptr, new_x ' + new cursor column -30EC(015F) 01 12 FC 2C | shl cur_ptr, #1 ' * 2 -30F0(0160) 02 12 BC 80 | add cur_ptr, screen_ptr ' + screen buffer address -30F4(0161) | calc_cursor_ret -30F4(0161) 00 00 7C 5C | ret -30F8(0162) | enable_cursor -30F8(0162) 43 08 7C EC | tjz cursor_ptr, #cmdloop -30FC(0163) 01 42 7C 62 | test flags, #flag_deccm WZ ' cursor enabled? -3100(0164) 00 68 E8 A0 | if_z mov t1, #%000 ' cursor off -3104(0165) 06 68 D4 A0 | if_nz mov t1, #%110 ' cursor on, blink slow -3108(0166) 02 08 FC 80 | add cursor_ptr, #2 ' cursor control -310C(0167) 04 68 3C 00 | wrbyte t1, cursor_ptr -3110(0168) 02 08 FC 84 | sub cursor_ptr, #2 -3114(0169) 43 00 7C 5C | jmp #cmdloop -3118(016A) | set_color -3118(016A) 04 40 7C 62 | test attr, #attr_inverse WZ -311C(016B) 70 01 68 5C | if_z jmp #:default -3120(016C) | :inverse -3120(016C) 24 4C BC A0 | mov color, fgcol ' compose inverse color -3124(016D) 04 4C FC 2C | shl color, #4 -3128(016E) 25 4C BC 68 | or color, bgcol -312C(016F) 73 01 7C 5C | jmp #:cont -3130(0170) | :default -3130(0170) 25 4C BC A0 | mov color, bgcol ' compose default color -3134(0171) 04 4C FC 2C | shl color, #4 -3138(0172) 24 4C BC 68 | or color, fgcol -313C(0173) | :cont -313C(0173) 01 40 7C 62 | test attr, #attr_highlite WZ -3140(0174) 08 4C FC 7C | muxnz color, #$08 -3144(0175) 08 40 7C 62 | test attr, #attr_blinking WZ -3148(0176) 80 4C FC 7C | muxnz color, #$80 -314C(0177) 08 4C FC 2C | shl color, #8 ' in bits 15..8 -3150(0178) 43 00 7C 5C | jmp #cmdloop -3154(0179) | mul16x16 -3154(0179) 10 68 FC 2C | shl t1, #16 ' multiplicand in bits 31..16 -3158(017A) 10 6C FC A0 | mov t3, #16 ' loop 16 times -315C(017B) 01 6A FC 29 | shr t2, #1 WC ' get initial multiplier bit in carry -3160(017C) 34 6A B0 81 | :loop if_c add t2, t1 WC ' if carry set, add multiplicand to product -3164(017D) 01 6A FC 31 | rcr t2, #1 WC ' next multiplier bit to carry, shift product -3168(017E) 7C 6D FC E4 | djnz t3, #:loop ' until done -316C(017F) | mul16x16_ret -316C(017F) 00 00 7C 5C | ret -3170(0180) | lmm_loop -3170(0180) 12 04 BF 08 | rdlong :op1, lmm_pc -3174(0181) 04 24 FC 80 | add lmm_pc, #4 -3178(0182) 00 00 00 00 | :op1 nop -317C(0183) 12 0A BF 08 | rdlong :op2, lmm_pc -3180(0184) 04 24 FC 80 | add lmm_pc, #4 -3184(0185) 00 00 00 00 | :op2 nop -3188(0186) 12 10 BF 08 | rdlong :op3, lmm_pc -318C(0187) 04 24 FC 80 | add lmm_pc, #4 -3190(0188) 00 00 00 00 | :op3 nop -3194(0189) 12 16 BF 08 | rdlong :op4, lmm_pc -3198(018A) 04 24 FC 80 | add lmm_pc, #4 -319C(018B) 00 00 00 00 | :op4 nop -31A0(018C) 80 01 7C 5C | jmp #lmm_loop -31A4(018D) | fit $1f0 -31A4(018D) | There are 99 ($063) Longs left in the cog -31A4(018D) 6C 00 | control_table word do_nul, do_soh, do_stx, do_etx, do_eot, do_enq, do_ack, do_bel -31A6(018D) 6C 00 | -31A8(018E) 6C 00 | -31AA(018E) 6C 00 | -31AC(018F) 6C 00 | -31AE(018F) 6C 00 | -31B0(0190) 6C 00 | -31B2(0190) 6C 00 | -31B4(0191) 6F 00 | word do_bs, do_ht, do_lf, do_vt, do_ff, do_cr, do_so, do_si -31B6(0191) 71 00 | -31B8(0192) 73 00 | -31BA(0192) 75 00 | -31BC(0193) 77 00 | -31BE(0193) 6D 00 | -31C0(0194) 79 00 | -31C2(0194) 7A 00 | -31C4(0195) 6C 00 | word do_dle, do_dc1, do_dc2, do_dc3, do_dc4, do_nak, do_syn, do_etb -31C6(0195) 6C 00 | -31C8(0196) 6C 00 | -31CA(0196) 6C 00 | -31CC(0197) 6C 00 | -31CE(0197) 6C 00 | -31D0(0198) 6C 00 | -31D2(0198) 6C 00 | -31D4(0199) 7B 00 | word do_can, do_em, do_sub, do_esc, do_fs, do_gs, do_rs, do_us -31D6(0199) 6C 00 | -31D8(019A) 6C 00 | -31DA(019A) 7D 00 | -31DC(019B) 6C 00 | -31DE(019B) 6C 00 | -31E0(019C) 6C 00 | -31E2(019C) 6C 00 | -31E4(019D) 5A 32 | csi_cmds word @@@do_insert_char ' [...@ -31E6(019D) D4 32 | word @@@do_cursor_up ' [...A -31E8(019E) E8 32 | word @@@do_cursor_down ' [...B -31EA(019E) F8 32 | word @@@do_cursor_left ' [...C -31EC(019F) 0C 33 | word @@@do_cursor_right ' [...D -31EE(019F) 1C 33 | word @@@do_rows_up ' [...E -31F0(01A0) 34 33 | word @@@do_rows_down ' [...F -31F2(01A0) 6C 33 | word @@@do_cursor_column ' [...G -31F4(01A1) 48 33 | word @@@do_cursor_address ' [...H -31F6(01A1) 43 00 | word cmdloop ' I unused? -31F8(01A2) 7C 33 | word @@@do_clear_screen ' [...J -31FA(01A2) DC 33 | word @@@do_clear_row ' [...K -31FC(01A3) 50 34 | word @@@do_insert_line ' [...L -31FE(01A3) C4 34 | word @@@do_delete_line ' [...M -3200(01A4) 43 00 | word cmdloop ' N unused? -3202(01A4) 43 00 | word cmdloop ' O unused? -3204(01A5) 50 35 | word @@@do_delete_char ' P unused? -3206(01A5) 43 00 | word cmdloop ' Q unused? -3208(01A6) 43 00 | word cmdloop ' R unused? -320A(01A6) 43 00 | word cmdloop ' S unused? -320C(01A7) 43 00 | word cmdloop ' T unused? -320E(01A7) 43 00 | word cmdloop ' U unused? -3210(01A8) 43 00 | word cmdloop ' V unused? -3212(01A8) 43 00 | word cmdloop ' W unused? -3214(01A9) C8 35 | word @@@do_blank_chars ' [...X -3216(01A9) 43 00 | word cmdloop ' Y unused? -3218(01AA) 43 00 | word cmdloop ' Z unused? -321A(01AA) 43 00 | word cmdloop ' [ unused -321C(01AB) 43 00 | word cmdloop ' \ unused -321E(01AB) 43 00 | word cmdloop ' ] unused -3220(01AC) 43 00 | word cmdloop ' ^ unused -3222(01AC) 43 00 | word cmdloop ' _ unused -3224(01AD) 6C 33 | word @@@do_cursor_column ' [...` alternate form for [...G -3226(01AD) 43 00 | word cmdloop ' a unused? -3228(01AE) 43 00 | word cmdloop ' b unused? -322A(01AE) 43 00 | word cmdloop ' c unused? -322C(01AF) 43 00 | word cmdloop ' d unused? -322E(01AF) 43 00 | word cmdloop ' e unused? -3230(01B0) 48 33 | word @@@do_cursor_address ' [...f alternate form for [...H -3232(01B0) 43 00 | word cmdloop ' g unused? -3234(01B1) 08 36 | word @@@do_flag_set ' h unused? -3236(01B1) 43 00 | word cmdloop ' i unused? -3238(01B2) 43 00 | word cmdloop ' j unused? -323A(01B2) 43 00 | word cmdloop ' k unused? -323C(01B3) 78 36 | word @@@do_flag_res ' h unused? -323E(01B3) E8 36 | word @@@do_mode_attributes ' [...m -3240(01B4) 43 00 | word cmdloop ' n unused? -3242(01B4) 43 00 | word cmdloop ' o unused? -3244(01B5) 43 00 | word cmdloop ' p unused? -3246(01B5) 43 00 | word cmdloop ' q unused? -3248(01B6) 28 38 | word @@@do_scroll_range ' [...r -324A(01B6) 78 38 | word @@@do_save_cursor ' [?...s -324C(01B7) 43 00 | word cmdloop ' t unused? -324E(01B7) 8C 38 | word @@@do_restore_cursor ' [?...u -3250(01B8) 43 00 | word cmdloop ' v unused? -3252(01B8) 43 00 | word cmdloop ' w unused? -3254(01B9) 43 00 | word cmdloop ' x unused? -3256(01B9) 43 00 | word cmdloop ' y unused? -3258(01BA) 43 00 | word cmdloop ' z unused? -325A(01BA) | do_insert_char -325A(01BA) B8 74 FD 5C | call #non_zero_args -3260(01BC) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC -3264(01BD) 43 00 4C 5C | if_ae jmp #cmdloop -3268(01BE) 1F 68 BC A0 | :loop mov t1, cur_y -326C(01BF) 06 6A BC A0 | mov t2, screen_w -3270(01C0) 79 FF FE 5C | call #mul16x16 -3274(01C1) 1E 6A BC 80 | add t2, new_x -3278(01C2) 01 6A FC 2C | shl t2, #1 -327C(01C3) 02 6A BC 80 | add t2, screen_ptr -3280(01C4) 35 18 BC A0 | mov dst, t2 -3284(01C5) 02 18 FC 80 | add dst, #2 -3288(01C6) 35 1A BC A0 | mov src, t2 -328C(01C7) 06 20 BC A0 | mov cols, screen_w -3290(01C8) 1E 20 BC 84 | sub cols, new_x -3294(01C9) 01 20 FC 87 | sub cols, #1 WZ, WC -3298(01CA) 28 24 F8 80 | if_be add lmm_pc, #4*(:blank - $ - 1) -329C(01CB) 0D 1E BC 04 | :insert rdword data, src -32A0(01CC) 02 1A FC 80 | add src, #2 -32A4(01CD) 0C 1E 3C 04 | wrword data, dst -32A8(01CE) 02 18 FC 80 | add dst, #2 -32AC(01CF) 01 20 FC 86 | sub cols, #1 WZ -32B0(01D0) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :insert) -32B4(01D1) 1A 68 BC A0 | mov t1, x00200020 -32B8(01D2) 26 68 BC 68 | or t1, color -32BC(01D3) 10 68 FC 24 | rol t1, #16 -32C0(01D4) 26 68 BC 68 | or t1, color -32C4(01D5) 35 68 3C 04 | :blank wrword t1, t2 -32C8(01D6) 01 56 FC 86 | sub csi_args, #1 WZ -32CC(01D7) 68 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -32D0(01D8) 43 00 7C 5C | jmp #cmdloop -32D4(01D9) | do_cursor_up -32D4(01D9) B8 74 FD 5C | call #non_zero_args -32D8(01DA) 03 59 FE 5C | :loop call #vt -32DC(01DB) 01 56 FC 86 | sub csi_args, #1 WZ -32E0(01DC) 0C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -32E4(01DD) 43 00 7C 5C | jmp #cmdloop -32E8(01DE) | do_cursor_down -32E8(01DE) B8 74 FD 5C | call #non_zero_args -32EC(01DF) D7 04 FE 5C | :loop call #lf -32F0(01E0) DF 57 FC E4 | djnz csi_args, #:loop -32F4(01E1) 43 00 7C 5C | jmp #cmdloop -32F8(01E2) | do_cursor_left -32F8(01E2) B8 74 FD 5C | call #non_zero_args -32FC(01E3) 1E 3A BC A0 | mov cur_x, new_x -3300(01E4) 2B 3A BC 85 | sub cur_x, csi_args WC -3304(01E5) 00 3A F0 A0 | if_c mov cur_x, #0 -3308(01E6) 38 00 7C 5C | jmp #validate_cursor -330C(01E7) | do_cursor_right -330C(01E7) B8 74 FD 5C | call #non_zero_args -3310(01E8) 1E 3A BC A0 | mov cur_x, new_x -3314(01E9) 2B 3A BC 80 | add cur_x, csi_args -3318(01EA) 38 00 7C 5C | jmp #validate_cursor -331C(01EB) | do_rows_up -331C(01EB) B8 74 FD 5C | call #non_zero_args -3320(01EC) 00 3A FC A0 | mov cur_x, #0 -3324(01ED) 00 3C FC A0 | mov new_x, #0 -3328(01EE) 2B 3E BC 85 | sub cur_y, csi_args WC -332C(01EF) 00 3E F0 A0 | if_c mov cur_y, #0 -3330(01F0) 38 00 7C 5C | jmp #validate_cursor -3334(01F1) | do_rows_down -3334(01F1) B8 74 FD 5C | call #non_zero_args -3338(01F2) 00 3A FC A0 | mov cur_x, #0 -333C(01F3) 00 3C FC A0 | mov new_x, #0 -3340(01F4) 2B 3E BC 80 | add cur_y, csi_args -3344(01F5) 38 00 7C 5C | jmp #validate_cursor -3348(01F6) | do_cursor_address -3348(01F6) 00 54 7C 86 | cmp csi_argf, #0 WZ ' nor arguments at all? -334C(01F7) 3A 7B EA 5C | if_z call #home -3350(01F8) 43 00 68 5C | if_z jmp #cmdloop -3354(01F9) B8 74 FD 5C | call #non_zero_args -3358(01FA) 2B 3E BC A0 | mov cur_y, csi_args -335C(01FB) 01 3E FC 84 | sub cur_y, #1 -3360(01FC) 01 52 7C 87 | cmp csi_argc, #1 WZ, WC ' the caller specified just a row? -3364(01FD) 38 00 78 5C | if_be jmp #validate_cursor -3368(01FE) BB 86 FD 5C | call #shift_csi_args -336C(01FF) | do_cursor_column -336C(01FF) B8 74 FD 5C | call #non_zero_args -3370(0200) 2B 3A BC A0 | mov cur_x, csi_args -3374(0201) 01 3A FC 84 | sub cur_x, #1 -3378(0202) 38 00 7C 5C | jmp #validate_cursor -337C(0203) | do_clear_screen -337C(0203) 5A C3 FE 5C | call #calc_cursor -3380(0204) 00 56 7C 86 | cmp csi_args, #0 WZ ' cursor to end of screen? -3384(0205) 0C 24 D4 80 | if_nz add lmm_pc, #4*(:not_0 - $ - 1) -3388(0206) 09 18 BC A0 | mov dst, cur_ptr -338C(0207) 03 1C BC A0 | mov end, screen_end -3390(0208) 24 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -3394(0209) 01 56 7C 86 | :not_0 cmp csi_args, #1 WZ ' start of screen to cursor? -3398(020A) 0C 24 D4 80 | if_nz add lmm_pc, #4*(:not_1 - $ - 1) -339C(020B) 02 18 BC A0 | mov dst, screen_ptr -33A0(020C) 09 1C BC A0 | mov end, cur_ptr -33A4(020D) 10 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -33A8(020E) 02 56 7C 86 | :not_1 cmp csi_args, #2 WZ ' entire screen? -33AC(020F) 43 00 54 5C | if_nz jmp #cmdloop ' invalid argument -33B0(0210) 02 18 BC A0 | mov dst, screen_ptr ' default = entire screen -33B4(0211) 03 1C BC A0 | mov end, screen_end -33B8(0212) 1A 68 BC A0 | :fill mov t1, x00200020 -33BC(0213) 26 68 BC 68 | or t1, color -33C0(0214) 10 68 FC 24 | rol t1, #16 -33C4(0215) 26 68 BC 68 | or t1, color -33C8(0216) 0C 68 3C 04 | :loop wrword t1, dst ' fill a word -33CC(0217) 02 18 FC 80 | add dst, #2 -33D0(0218) 0E 18 3C 87 | cmp dst, end WZ, WC -33D4(0219) 10 24 F0 84 | if_b sub lmm_pc, #4*($ + 1 - :loop) -33D8(021A) 43 00 7C 5C | jmp #cmdloop -33DC(021B) | do_clear_row -33DC(021B) 5A C3 FE 5C | call #calc_cursor -33E0(021C) 00 56 7C 86 | cmp csi_args, #0 WZ ' cursor to end of row? -33E4(021D) 14 24 D4 80 | if_nz add lmm_pc, #4*(:not_0 - $ - 1) -33E8(021E) 09 18 BC A0 | mov dst, cur_ptr ' default = cursor to end of row -33EC(021F) 09 1C BC A0 | mov end, cur_ptr -33F0(0220) 1E 1C BC 84 | sub end, new_x -33F4(0221) 06 1C BC 80 | add end, screen_w ' end of row -33F8(0222) 30 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -33FC(0223) 01 56 7C 86 | :not_0 cmp csi_args, #1 WZ ' start of row to cursor? -3400(0224) 10 24 D4 80 | if_nz add lmm_pc, #4*(:not_1 - $ - 1) -3404(0225) 09 18 BC A0 | mov dst, cur_ptr -3408(0226) 1E 18 BC 84 | sub dst, new_x ' start of row -340C(0227) 09 1C BC A0 | mov end, cur_ptr ' to cursor -3410(0228) 18 24 FC 80 | add lmm_pc, #4*(:fill - $ - 1) -3414(0229) 02 56 7C 86 | :not_1 cmp csi_args, #2 WZ ' entire row? -3418(022A) 43 00 54 5C | if_nz jmp #cmdloop ' invalid argument -341C(022B) 09 18 BC A0 | mov dst, cur_ptr -3420(022C) 1E 18 BC 84 | sub dst, new_x ' start of row -3424(022D) 0C 1C BC A0 | mov end, dst -3428(022E) 06 1C BC 80 | add end, screen_w ' end of row -342C(022F) 1A 68 BC A0 | :fill mov t1, x00200020 -3430(0230) 26 68 BC 68 | or t1, color -3434(0231) 10 68 FC 24 | rol t1, #16 -3438(0232) 26 68 BC 68 | or t1, color -343C(0233) 0C 68 3C 04 | :loop wrword t1, dst ' fill a word -3440(0234) 02 18 FC 80 | add dst, #2 -3444(0235) 0E 18 3C 87 | cmp dst, end WZ, WC -3448(0236) 10 24 F0 84 | if_b sub lmm_pc, #4*($ + 1 - :loop) -344C(0237) 43 00 7C 5C | jmp #cmdloop -3450(0238) | do_insert_line -3450(0238) B8 74 FD 5C | call #non_zero_args -3454(0239) 03 18 BC A0 | :loop mov dst, screen_end -3458(023A) 03 1A BC A0 | mov src, screen_end -345C(023B) 06 1A BC 84 | sub src, screen_w -3460(023C) 08 22 BC A0 | mov rows, screen_h ' screen rows -3464(023D) 1F 22 BC 84 | sub rows, cur_y ' - cursor row -3468(023E) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 -346C(023F) 24 24 F8 80 | if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -3470(0240) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3474(0241) 04 1A FC 84 | :cols sub src, #4 -3478(0242) 0D 1E BC 08 | rdlong data, src -347C(0243) 04 18 FC 84 | sub dst, #4 -3480(0244) 0C 1E 3C 08 | wrlong data, dst -3484(0245) 01 20 FC 86 | sub cols, #1 WZ -3488(0246) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :cols) -348C(0247) 01 22 FC 86 | sub rows, #1 WZ -3490(0248) 24 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :rows) -3494(0249) 1A 68 BC A0 | :fill mov t1, x00200020 -3498(024A) 26 68 BC 68 | or t1, color -349C(024B) 10 68 FC 24 | rol t1, #16 -34A0(024C) 26 68 BC 68 | or t1, color -34A4(024D) 07 20 BC A0 | mov cols, screen_w2 ' columns = screen width / 2 -34A8(024E) 04 18 FC 84 | :blank sub dst, #4 -34AC(024F) 0C 68 3C 08 | wrlong t1, dst -34B0(0250) 01 20 FC 86 | sub cols, #1 WZ -34B4(0251) 10 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns -34B8(0252) 01 56 FC 86 | sub csi_args, #1 WZ ' more lines to insert? -34BC(0253) 6C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -34C0(0254) 43 00 7C 5C | jmp #cmdloop -34C4(0255) | do_delete_line -34C4(0255) B8 74 FD 5C | call #non_zero_args -34C8(0256) 1F 68 BC A0 | :loop mov t1, cur_y -34CC(0257) 06 6A BC A0 | mov t2, screen_w -34D0(0258) 79 FF FE 5C | call #mul16x16 -34D4(0259) 01 6A FC 2C | shl t2, #1 -34D8(025A) 02 6A BC 80 | add t2, screen_ptr ' cursor row address -34DC(025B) 35 18 BC A0 | mov dst, t2 -34E0(025C) 35 1A BC A0 | mov src, t2 -34E4(025D) 06 1A BC 80 | add src, screen_w ' one row down -34E8(025E) 06 1A BC 80 | add src, screen_w -34EC(025F) 08 22 BC A0 | mov rows, screen_h ' screen rows -34F0(0260) 1F 22 BC 84 | sub rows, cur_y ' - cursor row -34F4(0261) 01 22 FC 87 | sub rows, #1 WZ, WC ' - 1 -34F8(0262) 24 24 F8 80 | if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -34FC(0263) 07 20 BC A0 | :rows mov cols, screen_w2 ' columns = screen width / 2 -3500(0264) 0D 1E BC 08 | :cols rdlong data, src -3504(0265) 04 1A FC 80 | add src, #4 -3508(0266) 0C 1E 3C 08 | wrlong data, dst -350C(0267) 04 18 FC 80 | add dst, #4 -3510(0268) 01 20 FC 86 | sub cols, #1 WZ -3514(0269) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :cols) -3518(026A) 01 22 FC 86 | sub rows, #1 WZ -351C(026B) 24 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :rows) -3520(026C) 1A 68 BC A0 | :fill mov t1, x00200020 -3524(026D) 26 68 BC 68 | or t1, color -3528(026E) 10 68 FC 24 | rol t1, #16 -352C(026F) 26 68 BC 68 | or t1, color -3530(0270) 07 20 BC A0 | mov cols, screen_w2 ' columns = screen width / 2 -3534(0271) 0C 68 3C 08 | :blank wrlong t1, dst -3538(0272) 04 18 FC 80 | add dst, #4 -353C(0273) 01 20 FC 86 | sub cols, #1 WZ -3540(0274) 10 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns -3544(0275) 01 56 FC 86 | sub csi_args, #1 WZ ' more lines to insert? -3548(0276) 84 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -354C(0277) 43 00 7C 5C | jmp #cmdloop -3550(0278) | do_delete_char -3550(0278) B8 74 FD 5C | call #non_zero_args -3554(0279) 06 3C 3C 87 | cmp new_x, screen_w WZ, WC -3558(027A) 43 00 4C 5C | if_ae jmp #cmdloop ' can't delete beyond last column -355C(027B) 1F 68 BC A0 | :loop mov t1, cur_y -3560(027C) 06 6A BC A0 | mov t2, screen_w -3564(027D) 79 FF FE 5C | call #mul16x16 -3568(027E) 1E 6A BC 80 | add t2, new_x -356C(027F) 01 6A FC 2C | shl t2, #1 -3570(0280) 02 6A BC 80 | add t2, screen_ptr -3574(0281) 35 18 BC A0 | mov dst, t2 -3578(0282) 35 1A BC A0 | mov src, t2 -357C(0283) 02 1A FC 80 | add src, #2 -3580(0284) 06 20 BC A0 | mov cols, screen_w -3584(0285) 1E 20 BC 84 | sub cols, new_x -3588(0286) 01 20 FC 87 | sub cols, #1 WZ, WC -358C(0287) 18 24 F8 80 | if_be add lmm_pc, #4*(:blank - $ - 1) ' new_x is beyond the last column -3590(0288) 0D 1E BC 04 | :insert rdword data, src -3594(0289) 02 1A FC 80 | add src, #2 -3598(028A) 0C 1E 3C 04 | wrword data, dst -359C(028B) 02 18 FC 80 | add dst, #2 -35A0(028C) 01 20 FC 86 | sub cols, #1 WZ -35A4(028D) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :insert) -35A8(028E) 1A 68 BC A0 | :blank mov t1, x00200020 -35AC(028F) 26 68 BC 68 | or t1, color -35B0(0290) 10 68 FC 24 | rol t1, #16 -35B4(0291) 26 68 BC 68 | or t1, color -35B8(0292) 0C 68 3C 04 | wrword t1, dst ' clear the last character in the row -35BC(0293) 01 56 FC 86 | sub csi_args, #1 WZ -35C0(0294) 68 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -35C4(0295) 43 00 7C 5C | jmp #cmdloop -35C8(0296) | do_blank_chars -35C8(0296) B8 74 FD 5C | call #non_zero_args -35CC(0297) 09 18 BC A0 | mov dst, cur_ptr -35D0(0298) 06 20 BC A0 | mov cols, screen_w -35D4(0299) 1E 20 BC 87 | sub cols, new_x WZ, WC -35D8(029A) 43 00 78 5C | if_be jmp #cmdloop -35DC(029B) 1A 68 BC A0 | mov t1, x00200020 -35E0(029C) 26 68 BC 68 | or t1, color -35E4(029D) 10 68 FC 24 | rol t1, #16 -35E8(029E) 26 68 BC 68 | or t1, color -35EC(029F) 0C 68 3C 04 | :fill wrword t1, dst -35F0(02A0) 02 18 FC 80 | add dst, #2 -35F4(02A1) 01 56 FC 86 | sub csi_args, #1 WZ -35F8(02A2) 43 00 68 5C | if_z jmp #cmdloop -35FC(02A3) 01 20 FC 86 | sub cols, #1 WZ -3600(02A4) 18 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :fill) -3604(02A5) 43 00 7C 5C | jmp #cmdloop -3608(02A6) | do_flag_set -3608(02A6) | :loop -3608(02A6) 2B 02 BC A0 | mov cmd, csi_args -360C(02A7) 01 66 7C 86 | cmp question_mark, #1 WZ ' [? sequence? -3610(02A8) 1C 24 E8 80 | if_z add lmm_pc, #4*(:ques - $ - 1) -3614(02A9) 03 02 7C 86 | cmp cmd, #3 WZ ' [3h - display control characters -3618(02AA) 00 43 E8 68 | if_z or flags, #flag_ctrl -361C(02AB) 04 02 7C 86 | cmp cmd, #4 WZ ' [4h - set insert mode -3620(02AC) 02 42 E8 68 | if_z or flags, #flag_decim -3624(02AD) 14 02 7C 86 | cmp cmd, #20 WZ ' [20h - set auto CR mode -3628(02AE) 08 42 E8 68 | if_z or flags, #flag_deccr -362C(02AF) 30 24 FC 80 | add lmm_pc, #4*(:next - $ - 1) -3630(02B0) | :ques -3630(02B0) 01 02 7C 86 | cmp cmd, #1 WZ ' [?1h - enable cursor keys -3634(02B1) 10 42 E8 68 | if_z or flags, #flag_decck -3638(02B2) 05 02 7C 86 | cmp cmd, #5 WZ ' [?5h - inverse terminal on -363C(02B3) 01 38 E8 68 | if_z or inverse, #1 -3640(02B4) 06 02 7C 86 | cmp cmd, #6 WZ ' [?6h - enable origin mode -3644(02B5) 04 42 E8 68 | if_z or flags, #flag_decom -3648(02B6) 07 02 7C 86 | cmp cmd, #7 WZ ' [?7h - enable auto wrap mode -364C(02B7) 20 42 E8 68 | if_z or flags, #flag_decawm -3650(02B8) 08 02 7C 86 | cmp cmd, #8 WZ ' [?8h - enable auto repeat mode -3654(02B9) 40 42 E8 68 | if_z or flags, #flag_decarm -3658(02BA) 19 02 7C 86 | cmp cmd, #25 WZ ' [?25h - enable cursor -365C(02BB) 01 42 E8 68 | if_z or flags, #flag_deccm -3660(02BC) | :next -3660(02BC) 00 54 7C 86 | cmp csi_argf, #0 WZ ' no arguments specified? -3664(02BD) 43 00 68 5C | if_z jmp #cmdloop -3668(02BE) BB 86 FD 5C | call #shift_csi_args -366C(02BF) 01 52 FC 86 | sub csi_argc, #1 WZ -3670(02C0) 6C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -3674(02C1) 62 01 7C 5C | jmp #enable_cursor -3678(02C2) | do_flag_res -3678(02C2) | :loop -3678(02C2) 2B 02 BC A0 | mov cmd, csi_args -367C(02C3) 01 66 7C 86 | cmp question_mark, #1 WZ ' [? sequence? -3680(02C4) 1C 24 E8 80 | if_z add lmm_pc, #4*(:ques - $ - 1) -3684(02C5) 03 02 7C 86 | cmp cmd, #3 WZ ' [3l - don't display control characters -3688(02C6) 00 43 E8 64 | if_z andn flags, #flag_ctrl -368C(02C7) 04 02 7C 86 | cmp cmd, #4 WZ ' [4l - reset insert mode -3690(02C8) 02 42 E8 64 | if_z andn flags, #flag_decim -3694(02C9) 14 02 7C 86 | cmp cmd, #20 WZ ' [20l - reset auto CR mode -3698(02CA) 08 42 E8 64 | if_z andn flags, #flag_deccr -369C(02CB) 30 24 FC 80 | add lmm_pc, #4*(:next - $ - 1) -36A0(02CC) | :ques -36A0(02CC) 01 02 7C 86 | cmp cmd, #1 WZ ' [?1l - disable cursor keys -36A4(02CD) 10 42 E8 64 | if_z andn flags, #flag_decck -36A8(02CE) 05 02 7C 86 | cmp cmd, #5 WZ ' [?5l - inverse terminal off -36AC(02CF) 01 38 E8 64 | if_z andn inverse, #1 -36B0(02D0) 06 02 7C 86 | cmp cmd, #6 WZ ' [?6l - disable origin mode -36B4(02D1) 04 42 E8 64 | if_z andn flags, #flag_decom -36B8(02D2) 07 02 7C 86 | cmp cmd, #7 WZ ' [?7l - disable auto wrap mode -36BC(02D3) 20 42 E8 64 | if_z andn flags, #flag_decawm -36C0(02D4) 08 02 7C 86 | cmp cmd, #8 WZ ' [?8l - disable auto repeat mode -36C4(02D5) 40 42 E8 64 | if_z andn flags, #flag_decarm -36C8(02D6) 19 02 7C 86 | cmp cmd, #25 WZ ' [?25l - disable cursor -36CC(02D7) 01 42 E8 64 | if_z andn flags, #flag_deccm -36D0(02D8) | :next -36D0(02D8) 00 54 7C 86 | cmp csi_argf, #0 WZ ' no arguments specified? -36D4(02D9) 43 00 68 5C | if_z jmp #cmdloop -36D8(02DA) BB 86 FD 5C | call #shift_csi_args -36DC(02DB) 01 52 FC 86 | sub csi_argc, #1 WZ -36E0(02DC) 6C 24 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :loop) -36E4(02DD) 62 01 7C 5C | jmp #enable_cursor -36E8(02DE) | do_mode_attributes -36E8(02DE) 2B 02 BC A0 | :get_arg mov cmd, csi_args ' get next argument -36EC(02DF) 00 02 7C 86 | cmp cmd, #0 WZ ' 0 = reset all attributes -36F0(02E0) 00 40 E8 A0 | if_z mov attr, #0 -36F4(02E1) 00 4A E8 A0 | if_z mov bgcol, #%0000 -36F8(02E2) 07 48 E8 A0 | if_z mov fgcol, #%0111 -36FC(02E3) 01 02 7C 86 | cmp cmd, #1 WZ ' 1 = highlight on -3700(02E4) 01 40 E8 68 | if_z or attr, #attr_highlite -3704(02E5) 02 02 7C 86 | cmp cmd, #2 WZ ' 2 = highlight off -3708(02E6) 01 40 E8 64 | if_z andn attr, #attr_highlite -370C(02E7) 04 02 7C 86 | cmp cmd, #4 WZ ' 4 = underline on -3710(02E8) 02 40 E8 68 | if_z or attr, #attr_underline -3714(02E9) 05 02 7C 86 | cmp cmd, #5 WZ ' 5 = blinking on -3718(02EA) 08 40 E8 68 | if_z or attr, #attr_blinking -371C(02EB) 07 02 7C 86 | cmp cmd, #7 WZ ' 7 = inverse on -3720(02EC) 04 40 E8 68 | if_z or attr, #attr_inverse -3724(02ED) 0A 02 7C 86 | cmp cmd, #10 WZ ' 10 = primary font, no ctrl, no meta -3728(02EE) 00 43 E8 64 | if_z andn flags, #flag_ctrl -372C(02EF) 80 42 E8 64 | if_z andn flags, #flag_meta -3730(02F0) 0B 02 7C 86 | cmp cmd, #11 WZ ' 11 = alternate font, ctrl chars, low half, meta off -3734(02F1) 00 43 E8 68 | if_z or flags, #flag_ctrl -3738(02F2) 80 42 E8 64 | if_z andn flags, #flag_meta -373C(02F3) 0C 02 7C 86 | cmp cmd, #12 WZ ' 12 = alternate font, ctrl chars, low half, meta on -3740(02F4) 00 43 E8 68 | if_z or flags, #flag_ctrl -3744(02F5) 80 42 E8 68 | if_z or flags, #flag_meta -3748(02F6) 15 02 7C 86 | cmp cmd, #21 WZ ' 21 = highlight on -374C(02F7) 01 40 E8 68 | if_z or attr, #attr_highlite -3750(02F8) 16 02 7C 86 | cmp cmd, #22 WZ ' 22 = highlight on -3754(02F9) 01 40 E8 68 | if_z or attr, #attr_highlite -3758(02FA) 18 02 7C 86 | cmp cmd, #24 WZ ' 24 = underline off -375C(02FB) 02 40 E8 64 | if_z andn attr, #attr_underline -3760(02FC) 19 02 7C 86 | cmp cmd, #25 WZ ' 25 = blinking off -3764(02FD) 08 40 E8 64 | if_z andn attr, #attr_blinking -3768(02FE) 1B 02 7C 86 | cmp cmd, #27 WZ ' 27 = inverse off -376C(02FF) 04 40 E8 64 | if_z andn attr, #attr_inverse -3770(0300) 1E 02 7C 86 | cmp cmd, #30 WZ ' 30 = foreground color 0 -3774(0301) 00 48 E8 A0 | if_z mov fgcol, #%0000 -3778(0302) 1F 02 7C 86 | cmp cmd, #31 WZ ' 31 = foreground color 1 -377C(0303) 01 48 E8 A0 | if_z mov fgcol, #%0001 -3780(0304) 20 02 7C 86 | cmp cmd, #32 WZ ' 32 = foreground color 2 -3784(0305) 02 48 E8 A0 | if_z mov fgcol, #%0010 -3788(0306) 21 02 7C 86 | cmp cmd, #33 WZ ' 33 = foreground color 3 -378C(0307) 03 48 E8 A0 | if_z mov fgcol, #%0011 -3790(0308) 22 02 7C 86 | cmp cmd, #34 WZ ' 34 = foreground color 4 -3794(0309) 04 48 E8 A0 | if_z mov fgcol, #%0100 -3798(030A) 23 02 7C 86 | cmp cmd, #35 WZ ' 35 = foreground color 5 -379C(030B) 05 48 E8 A0 | if_z mov fgcol, #%0101 -37A0(030C) 24 02 7C 86 | cmp cmd, #36 WZ ' 36 = foreground color 6 -37A4(030D) 06 48 E8 A0 | if_z mov fgcol, #%0110 -37A8(030E) 25 02 7C 86 | cmp cmd, #37 WZ ' 37 = foreground color 7 -37AC(030F) 07 48 E8 A0 | if_z mov fgcol, #%0111 -37B0(0310) 26 02 7C 86 | cmp cmd, #38 WZ ' 38 = default color and underline on -37B4(0311) 07 48 E8 A0 | if_z mov fgcol, #%0111 -37B8(0312) 02 40 E8 68 | if_z or attr, #attr_underline -37BC(0313) 27 02 7C 86 | cmp cmd, #39 WZ ' 39 = default color and underline off -37C0(0314) 07 48 E8 A0 | if_z mov fgcol, #%0111 -37C4(0315) 02 40 E8 64 | if_z andn attr, #attr_underline -37C8(0316) 28 02 7C 86 | cmp cmd, #40 WZ ' 40 = default background -37CC(0317) 00 4A E8 A0 | if_z mov bgcol, #%0000 ' black -37D0(0318) 29 02 7C 86 | cmp cmd, #41 WZ ' 41 = background color 1 -37D4(0319) 01 4A E8 A0 | if_z mov bgcol, #%0001 -37D8(031A) 2A 02 7C 86 | cmp cmd, #42 WZ ' 42 = background color 2 -37DC(031B) 02 4A E8 A0 | if_z mov bgcol, #%0010 -37E0(031C) 2B 02 7C 86 | cmp cmd, #43 WZ ' 43 = background color 3 -37E4(031D) 03 4A E8 A0 | if_z mov bgcol, #%0011 -37E8(031E) 2C 02 7C 86 | cmp cmd, #44 WZ ' 44 = background color 4 -37EC(031F) 04 4A E8 A0 | if_z mov bgcol, #%0100 -37F0(0320) 2D 02 7C 86 | cmp cmd, #45 WZ ' 45 = background color 5 -37F4(0321) 05 4A E8 A0 | if_z mov bgcol, #%0101 -37F8(0322) 2E 02 7C 86 | cmp cmd, #46 WZ ' 46 = background color 6 -37FC(0323) 06 4A E8 A0 | if_z mov bgcol, #%0110 -3800(0324) 2F 02 7C 86 | cmp cmd, #47 WZ ' 47 = background color 7 -3804(0325) 07 4A E8 A0 | if_z mov bgcol, #%0111 -3808(0326) 31 02 7C 86 | cmp cmd, #49 WZ ' 49 = default background -380C(0327) 00 4A E8 A0 | if_z mov bgcol, #%0000 ' black -3810(0328) 00 54 7C 86 | cmp csi_argf, #0 WZ ' no arguments specified? -3814(0329) 43 00 68 5C | if_z jmp #cmdloop -3818(032A) BB 86 FD 5C | call #shift_csi_args -381C(032B) 01 52 FC 86 | sub csi_argc, #1 WZ -3820(032C) 3C 25 D4 84 | if_nz sub lmm_pc, #4*($ + 1 - :get_arg) -3824(032D) 6A 01 7C 5C | jmp #set_color -3828(032E) | do_scroll_range -3828(032E) 02 52 7C 87 | cmp csi_argc, #2 WZ, WC ' 2 arguments specified? -382C(032F) 0C 24 CC 80 | if_ae add lmm_pc, #4*(:set_range - $ - 1) -3830(0330) 01 14 FC A0 | mov scroll_top, #1 -3834(0331) 08 16 BC A0 | mov scroll_bot, screen_h -3838(0332) 2C 24 FC 80 | add lmm_pc, #4*(:bottom_ok - $ - 1) -383C(0333) | :set_range -383C(0333) 2B 14 BC A0 | mov scroll_top, csi_args -3840(0334) 2C 16 BC A0 | mov scroll_bot, csi_args + 1 -3844(0335) 0B 14 3C 87 | cmp scroll_top, scroll_bot WZ, WC ' bottom => top? -3848(0336) 0C 24 F8 80 | if_be add lmm_pc, #4*(:order_ok - $ - 1) -384C(0337) 01 14 FC A0 | mov scroll_top, #1 -3850(0338) 08 16 BC A0 | mov scroll_bot, screen_h -3854(0339) 10 24 FC 80 | add lmm_pc, #4*(:bottom_ok - $ - 1) -3858(033A) | :order_ok -3858(033A) 08 16 3C 87 | cmp scroll_bot, screen_h WZ, WC ' bottom > screen height? -385C(033B) 08 24 F8 80 | if_be add lmm_pc, #4*(:bottom_ok - $ - 1) -3860(033C) 01 14 FC A0 | mov scroll_top, #1 -3864(033D) 08 16 BC A0 | mov scroll_bot, screen_h -3868(033E) | :bottom_ok -3868(033E) 01 14 FC 84 | sub scroll_top, #1 -386C(033F) 00 3A FC A0 | mov cur_x, #0 -3870(0340) 00 3E FC A0 | mov cur_y, #0 -3874(0341) 37 00 7C 5C | jmp #goto_xay -3878(0342) | do_save_cursor -3878(0342) 1D 26 BC A0 | mov cur_x_save, cur_x -387C(0343) 1E 2A BC A0 | mov new_x_save, new_x -3880(0344) 1F 28 BC A0 | mov cur_y_save, cur_y -3884(0345) 20 2C BC A0 | mov attr_save, attr -3888(0346) 43 00 7C 5C | jmp #cmdloop -388C(0347) | do_restore_cursor -388C(0347) 13 3A BC A0 | mov cur_x, cur_x_save -3890(0348) 15 3C BC A0 | mov new_x, new_x_save -3894(0349) 14 3E BC A0 | mov cur_y, cur_y_save -3898(034A) 16 40 BC A0 | mov attr, attr_save -389C(034B) 43 00 7C 5C | jmp #cmdloop -|===========================================================================| -|===========================================================================| -Spin Block start with 1 Parameters and 0 Extra Stack Longs. Method 1 -PUB start(params) : okay - -Local Parameter DBASE:0000 - Result -Local Parameter DBASE:0004 - params -|===========================================================================| -29 stop -Addr : 38A0: 01 : Drop Anchor -Addr : 38A1: 05 02 : Call Sub 2 -30 okay := cog := COGNEW(@entry, params) + 1 -Addr : 38A3: 34 : Constant 0 $FFFFFFFF -Addr : 38A4: C7 0C : Memory Op Long PBASE + ADDRESS Address = 000C -Addr : 38A6: 64 : Variable Operation Local Offset - 1 Read -Addr : 38A7: 28 : CogInit(Id, Addr, Ptr) Push -Addr : 38A8: 36 : Constant 2 $00000001 -Addr : 38A9: EC : Math Op + -Addr : 38AA: 42 80 : Variable Operation Global Offset - 0 Assign Write Push -Addr : 38AC: 61 : Variable Operation Local Offset - 0 Write -Addr : 38AD: 32 : Return -|===========================================================================| -Spin Block stop with 0 Parameters and 0 Extra Stack Longs. Method 2 -PUB stop : okay - -Local Parameter DBASE:0000 - Result -|===========================================================================| -33 if cog -Addr : 38AE: 40 : Variable Operation Global Offset - 0 Read -Addr : 38AF: JZ Label0008 -Addr : 38AF: 0A 05 : jz Address = 38B6 5 -34 COGSTOP(cog~~ - 1) -Addr : 38B1: 42 9C : Variable Operation Global Offset - 0 Assign VAR~~ Post-set Push -Addr : 38B3: 36 : Constant 2 $00000001 -Addr : 38B4: ED : Math Op - -Addr : 38B5: 21 : CogStop(id) -Addr : 38B6: Label0008 -Addr : 38B6: Label0009 -Addr : 38B6: 32 : Return diff --git a/Source/Hardware/Experimental/vga2/vgademo.spin b/Source/Hardware/Experimental/vga2/vgademo.spin deleted file mode 100644 index bdde289c..00000000 --- a/Source/Hardware/Experimental/vga2/vgademo.spin +++ /dev/null @@ -1,102 +0,0 @@ -CON - _xinfreq = 5_000_000 ' Quartz is 5MHz - _clkmode = xtal1 + pll16x ' System clock is 80MHz - -#define DracBladeProp - - CHAR_W = 80 - CHAR_H = 30 - -OBJ -' vga : "vga8x8d" - vga : "vgacolour" - vt100 : "vt100" - -VAR - long params[6] - long seed - -PUB main - vga.start(16, @screen, @cursor, @sync) - params[0] := @command - params[1] := @screen - params[2] := @cursor - params[3] := @sync - params[4] := CHAR_W - params[5] := CHAR_H - - vt100.start(@params) - - seed := cnt - - str(string(27,"[2;34m",27,"[2J",27,"[H","Hello World!",13,10)) - str(string(27,"[7m","Inverse on",13,10)) - str(string(27,"[27m","Inverse off",13,10)) - str(string(27,"[1m","Highlite on",13,10)) - str(string(27,"[2m","Highlite off",13,10)) - str(string(27,"[4m","Underline on ",27,"[1m + highlite ",27,"[2m",27,"[7m + inverse ",27,"[0m all off + default color.",13,10)) - str(string(27,"[40m","BGD 0")) - str(string(27,"[41m","BGD 1")) - str(string(27,"[42m","BGD 2")) - str(string(27,"[43m","BGD 3")) - str(string(27,"[44m","BGD 4")) - str(string(27,"[45m","BGD 5")) - str(string(27,"[46m","BGD 6")) - str(string(27,"[47m","BGD 7",13,10)) - - str(string(27,"[41m")) - - str(string(27,"[30m","FGD 0")) - str(string(27,"[31m","FGD 1")) - str(string(27,"[32m","FGD 2")) - str(string(27,"[33m","FGD 3")) - str(string(27,"[34m","FGD 4")) - str(string(27,"[35m","FGD 5")) - str(string(27,"[36m","FGD 6")) - str(string(27,"[37m","FGD 7",13,10)) - str(string(27,"[1;40m")) - str(string(27,"[30m","FGD 0")) - str(string(27,"[31m","FGD 1")) - str(string(27,"[32m","FGD 2")) - str(string(27,"[33m","FGD 3")) - str(string(27,"[34m","FGD 4")) - str(string(27,"[35m","FGD 5")) - str(string(27,"[36m","FGD 6")) - str(string(27,"[37m","FGD 7",13,10)) - str(string(27,"[2m","The quick brown fox jumps over the lazy dog.", 13, 10)) - - str(string("Setting a scroll range below here.",13,10)) - str(string(27,"[24H","This part of the screen remains ",27,"[4mstatic",27,"[24m, since it is below the scrolling region.")) - str(string(27,"[12;23r",27,"[41m")) - repeat - chr(27) - chr("[") - chr("3") - chr("0" + rand & 7) - chr("m") - chr(27) - chr("[") - chr("4") - chr("0" + rand & 7) - chr("m") - str(string("Four score and seven years ago our ",27,"[1mfathers",27,"[2m brought forth, upon this continent, a new ",27,"[1mnation",27,"[2m, conceived in Liberty, and dedicated to the proposition that all men are created equal. ")) - waitcnt(clkfreq/4 + cnt) - - -PUB chr(ch) - command := $100 | ch - repeat while command - -PUB str(strptr) | i - repeat i from 0 to strsize(strptr) - chr(byte[strptr][i]) - -PUB rand - seed := seed * 1103515245 + 12345 + CNT / 7777 - return seed - -DAT -command long 0 -screen word $0720[CHAR_W*CHAR_H] -cursor byte 0,0,%110,0,0,0,0,0 -sync long 0 diff --git a/Source/Hardware/Experimental/vga2/vt100.spin b/Source/Hardware/Experimental/vga2/vt100.spin deleted file mode 100644 index 710b0fc4..00000000 --- a/Source/Hardware/Experimental/vga2/vt100.spin +++ /dev/null @@ -1,1198 +0,0 @@ -'****************************************************************************** -'* vt100.spin - DEC VT100 terminal emulation -'* -'* (c) Juergen Buchmueller -'* -'* $Id: vt100.spin,v 1.6 2010-04-17 13:48:13 pm Exp $ -'****************************************************************************** -CON - attr_highlite = %00000001 - attr_underline = %00000010 - attr_inverse = %00000100 - attr_blinking = %00001000 - - flag_deccm = %0_00000001 ' DEC cursor mode (0: off, 1: on) - flag_decim = %0_00000010 ' DEC insert mode - flag_decom = %0_00000100 ' DEC origin mode - flag_deccr = %0_00001000 ' DEC send CRLF or LF (0: LF, 1: CRLF) - flag_decck = %0_00010000 ' DEC send cursor keys - flag_decawm = %0_00100000 ' DEC auto wrap mode - flag_decarm = %0_01000000 ' DEC auto repeat mode - flag_meta = %0_10000000 ' meta character toggle - flag_ctrl = %1_00000000 ' display control characters - flag_decrm = 1<<10 ' DEC report mouse - -VAR - long cog - -PUB start(params) : okay - stop - okay := cog := COGNEW(@entry, params) + 1 - -PUB stop : okay - if cog - COGSTOP(cog~~ - 1) - -DAT - org 0 -entry -command_ptr mov t1, PAR -cmd rdlong command_ptr, t1 ' parameter 0 -screen_ptr add t1, #4 -screen_end rdlong screen_ptr, t1 ' parameter 1 -cursor_ptr add t1, #4 -vsync_ptr rdlong cursor_ptr, t1 ' parameter 2 -screen_w add t1, #4 -screen_w2 rdlong vsync_ptr, t1 ' parameter 3 -screen_h add t1, #4 -cur_ptr rdlong screen_w, t1 ' parameter 4 -scroll_top add t1, #4 -scroll_bot rdlong screen_h, t1 ' parameter 5 -dst mov screen_w2, screen_w -src shr screen_w2, #1 ' screen width / 2 -end mov t1, screen_w -data mov t2, screen_h -cols call #mul16x16 -rows mov screen_end, t2 ' result in t2 -lmm_pc add screen_end, t2 ' * 2 -cur_x_save add screen_end, screen_ptr -cur_y_save mov scroll_top, #0 -new_x_save mov scroll_bot, screen_h -attr_save mov cur_delay, CNT - jmp #startup -control_ptr long @@@control_table -csi_cmds_ptr long @@@csi_cmds -x00200020 long $00200020 -cur_block long $5f - -inverse long 0 -cur_x long 0 -new_x long 0 -cur_y long 0 -attr long 0 ' attribute mode -flags long flag_decom | flag_decawm -cur_char long 0 -cur_delay long 0 -fgcol long %0111 ' foreground color -bgcol long %0000 ' background color -color long %00000111_00000000 ' composed fore- and background -esc_mode long 0 -csi_mode long 0 -csi_argc long 0 -csi_argf long 0 -csi_args long 0,0,0,0,0,0,0,0 -question_mark long 0 - -t1 long 0 -t2 long 0 -t3 long 0 - -goto_xay - ' TODO: check origin mode flag - add cur_y, scroll_top -validate_cursor - mov cur_x, cur_x WC ' negative x? - if_c mov cur_x, #0 ' yes, clip to 0 - cmp cur_x, screen_w WZ, WC - if_ae mov cur_x, screen_w ' stay inside the boundaries - if_ae sub cur_x, #1 - mov new_x, cur_x - mov cur_y, cur_y WC ' negative y? - if_c mov cur_y, #0 ' yes, clip to 0 - cmp cur_y, screen_h WZ, WC - if_ae mov cur_y, screen_h ' stay inside the boundaries - if_ae sub cur_y, #1 -cmdloop - mov cmd, #0 - wrlong cmd, command_ptr -startup -:loop tjz cursor_ptr, #:cursor ' skip if cursor_ptr is null - wrbyte new_x, cursor_ptr ' write the (new) cursor position - add cursor_ptr, #1 - wrbyte cur_y, cursor_ptr ' and the cursor row, too - sub cursor_ptr, #1 - call #calc_cursor - jmp #:check_cmd -:cursor mov t1, cur_delay ' software cursor - sub t1, CNT - cmps t1, #0 WZ, WC - if_ae jmp #:check_cmd - rdlong t1, #0 ' get clkfreq - shr t1, #2 ' / 4 - add cur_delay, t1 ' next cursor flash event - call #calc_cursor - cmp new_x, screen_w WZ, WC ' new_x beyond last column? - if_ae jmp #:check_cmd - mov t1, cur_char WZ ' get saved character - if_z rdbyte cur_char, cur_ptr ' none: save character under cursor - if_z wrbyte cur_block, cur_ptr ' display a cursor block - if_nz mov cur_char, #0 ' reset saved character - if_nz wrbyte t1, cur_ptr ' restore saved character in screen buffer -:check_cmd rdlong cmd, command_ptr WZ - if_z jmp #:loop - - mov t1, cur_char WZ ' get saved character - if_nz cmp cur_ptr, screen_end WC - if_nz_and_c mov cur_char, #0 ' reset saved character - if_nz_and_c wrbyte t1, cur_ptr ' restore saved character in screen buffer - - and cmd, #$ff - tjnz csi_mode, #csi ' go to CSI decoding if enabled - tjnz esc_mode, #esc ' go to ESC decoding if enabled - cmp cmd, #$20 WZ, WC ' other control characters? - if_ae jmp #do_emit ' no, just emit to the screen buffer - shl cmd, #1 - add cmd, control_ptr - rdword cmd, cmd - jmp cmd ' dispatch on control_table - -do_emit call #emit - jmp #cmdloop - -do_nul ' NUL - null character -do_soh ' SOH - start of header -do_stx ' STX - start of text -do_etx ' ETX - end of text -do_eot ' EOT - end of transmission -do_enq ' ENQ - enquiry -do_ack ' ACK - acknowledgement -do_bel ' BEL - bell -do_dle ' DLE - data link escape -do_dc1 ' DC1 - device control 1 (XON) -do_dc2 ' DC2 - device control 2 -do_dc3 ' DC3 - device control 3 (XOFF) -do_dc4 ' DC4 - device control 4 -do_nak ' NAK - negative acknowledgement -do_syn ' SYN - synchronous idle -do_etb ' ETB - end of transmission block -do_em ' EM - end of medium -do_sub ' SUB - substitute -do_fs ' FS - file separator -do_gs ' GS - group separator -do_rs ' RS - request to send -do_us ' US - unit separator - jmp #cmdloop - -do_cr call #cr - jmp #cmdloop - -do_bs call #bs - jmp #cmdloop - -do_ht call #ht - jmp #cmdloop - -do_lf call #lf - jmp #cmdloop - -do_vt call #vt - jmp #cmdloop - -do_ff call #ff - jmp #cmdloop - -do_so ' ??? - jmp #cmdloop - -do_si ' ??? - jmp #cmdloop - -do_can ' CAN - cancel - call #can - jmp #cmdloop -do_esc - mov esc_mode, #1 - jmp #cmdloop -esc - mov esc_mode, #0 - cmp cmd, #"[" WZ - if_z jmp #:csi - ' TODO: non-CSI escape sequences - jmp #cmdloop -:csi - mov csi_mode, #1 ' start CSI mode - mov csi_argc, #0 ' argument count = 0 - mov csi_argf, #0 ' argument flag = 0 - mov csi_args, #0 ' first argument = 0 - jmp #cmdloop - -csi - cmp csi_mode, #1 WZ ' first character after "["? - if_nz jmp #:not_question ' no, check arguments - mov csi_mode, #2 ' skip this test in the future - cmp cmd, #"?" WZ ' "[?" mode? - muxz question_mark, #1 - if_z jmp #cmdloop - -:not_question - cmp cmd, #"0" WZ, WC - if_b jmp #:not_numeric - cmp cmd, #"9" WZ, WC - if_a jmp #:not_numeric - mov t1, csi_argc - add t1, #csi_args - movs :get_arg, t1 - movd :put_arg, t1 - mov csi_argf, #1 ' set the "seen arguments" flag -:get_arg mov t1, 0-0 ' get csi_args[csi_argc] - mov t2, t1 ' to t2 also - shl t1, #2 ' * 4 - add t1, t2 ' * 5 - shl t1, #1 ' * 10 - add t1, cmd ' + digit - sub t1, #"0" ' - ASCII for "0" -:put_arg mov 0-0, t1 ' put csi_args[csi_argc] - jmp #cmdloop - -:not_numeric - cmp cmd, #";" WZ ' next argument delimiter? - if_nz jmp #:not_delimiter - cmp csi_argc, #7 WZ ' reached maximum number of arguments? - if_nz add csi_argc, #1 ' no, use next slot - mov t1, csi_argc - add t1, #csi_args - movd :clr_arg, t1 - nop -:clr_arg mov 0-0, #0 ' preset csi_args[csi_argc] to 0 - jmp #cmdloop - -:not_delimiter - mov csi_mode, #0 ' end CSI mode - add csi_argc, csi_argf ' incr. argument count, if any arguments were specified - - cmp cmd, #"@" WZ, WC ' below @? - if_b jmp #cmdloop - cmp cmd, #"z" WZ, WC ' above z? - if_ae jmp #cmdloop - sub cmd, #"@" - shl cmd, #1 ' function word index - add cmd, csi_cmds_ptr - rdword cmd, cmd ' get function pointer - testn cmd, #$1ff WZ ' any bits outside the cog? - if_z jmp cmd ' cog function - mov lmm_pc, cmd ' otherwise it's an LMM address - jmp #lmm_loop ' execute LMM code - -'******************************************************************************************** -' non_zero_args - make sure the first argument is at least 1 -' -non_zero_args - tjnz csi_args, #non_zero_args_ret - add csi_args, #1 -non_zero_args_ret - ret - -'******************************************************************************************** -' shift_csi_args - remove the first value from the list of arguments, pad with 0 -' -shift_csi_args - mov csi_args, csi_args + 1 - mov csi_args + 1, csi_args + 2 - mov csi_args + 2, csi_args + 3 - mov csi_args + 3, csi_args + 4 - mov csi_args + 4, csi_args + 5 - mov csi_args + 5, csi_args + 6 - mov csi_args + 6, csi_args + 7 - mov csi_args + 7, #0 -shift_csi_args_ret - ret - -'******************************************************************************************** -' cr - carriage return -' -cr - mov cur_x, #0 - mov new_x, #0 -cr_ret - ret - -'******************************************************************************************** -' bs - back space -' -bs - cmp new_x, #0 WZ - if_nz sub new_x, #1 - if_nz jmp #bs_ret - mov new_x, screen_w - sub new_x, #1 - call #vt -bs_ret - ret - -'******************************************************************************************** -' fs - forward space -' -fs - add cur_x, #1 - cmp cur_x, screen_w WZ - if_z sub cur_x, #1 ' stay in last column -fs_ret - ret - -'******************************************************************************************** -' ht - horizontal tabulator -' -ht - mov cmd, #$20 - call #emit - test new_x, #7 WZ - if_nz jmp #ht -ht_ret - ret -'******************************************************************************************** -' lf - line feed -' -lf - add cur_y, #1 - test flags, #flag_decom WZ ' origin mode enabled? - if_nz jmp #:origin ' yes, check cursor in scroll range - -:screen cmp cur_y, screen_h WZ, WC ' no, check cursor in screen range - if_b jmp #lf_ret - mov cur_y, screen_h - sub cur_y, #1 - mov dst, screen_ptr ' destination = screen buffer - mov src, screen_ptr ' source = dito - mov rows, screen_h ' screen height - jmp #scroll_up_1 ' scroll the entire screen - -:origin cmp cur_y, scroll_bot WZ, WC - if_b jmp #lf_ret - mov cur_y, scroll_bot - sub cur_y, #1 -scroll_up - mov t1, scroll_top - mov t2, screen_w - call #mul16x16 - shl t2, #1 - add t2, screen_ptr - mov dst, t2 ' destination = scroll_top of screen buffer - mov src, t2 ' source = dito - mov rows, scroll_bot ' scroll range height - sub rows, scroll_top -scroll_up_1 - add src, screen_w ' copy from one line below - add src, screen_w - sub rows, #1 WZ, WC ' - 1 rows to move - if_be jmp #:fill ' nothing left to scroll? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols rdlong data, src - add src, #4 - wrlong data, dst - add dst, #4 - djnz cols, #:cols - djnz rows, #:rows -:fill mov cols, screen_w2 ' columns = screen width / 2 - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:blank wrlong t1, dst ' fill 4 spaces - add dst, #4 - djnz cols, #:blank -scroll_up_ret -lf_ret - ret - -'******************************************************************************************** -' vt - vertical tab (inverse line feed) -' -vt - sub cur_y, #1 - test flags, #flag_decom WZ ' origin mode enabled? - if_nz jmp #:origin ' yes, check cursor in scroll range - -:screen ' no, check cursor in screen range - cmps cur_y, #0 WZ, WC ' < 0? - if_ae jmp #vt_ret ' in range - mov cur_y, #0 ' stay in line 0 - mov src, screen_end - mov dst, screen_end - mov rows, screen_h - jmp #scroll_down_1 -:origin - cmps cur_y, scroll_top WZ, WC - if_ae jmp #vt_ret - mov cur_y, scroll_top -scroll_down - mov t1, scroll_bot - mov t2, screen_w - call #mul16x16 - shl t2, #1 - add t2, screen_ptr - mov dst, t2 ' destination = end of scroll range buffer - mov src, t2 ' source = last row of scroll range buffer - mov rows, scroll_bot ' scroll range height - sub rows, scroll_top -scroll_down_1 - sub src, screen_w - sub src, screen_w - sub rows, #1 WZ, WC ' - 1 rows to move - if_be jmp #:fill ' nothing left to scroll? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols sub src, #4 ' pre decrement source - rdlong data, src - sub dst, #4 ' pre decrement destination - wrlong data, dst - djnz cols, #:cols ' for all columns - djnz rows, #:rows ' for all rows -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - mov cols, screen_w2 ' columns = screen width / 2 -:blank sub dst, #4 - wrlong t1, dst - djnz cols, #:blank -scroll_down_ret -vt_ret - ret - -'******************************************************************************************** -' ff - form feed (clear screen) -' -ff - mov dst, screen_ptr - mov rows, screen_h ' screen height rows - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols wrlong t1, dst ' fill with 4 blanks - add dst, #4 - djnz cols, #:cols ' for all columns - djnz rows, #:rows ' for all rows - call #home -ff_ret - ret - -'******************************************************************************************** -' home - cursor home -' -home - mov cur_x, #0 - mov new_x, #0 - mov cur_y, #0 -home_ret - ret - -'******************************************************************************************** -' can - clear from cursor to end of line -' -can - mov dst, cur_ptr - mov cols, screen_w - sub cols, new_x WZ, WC - if_be jmp #can_ret - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:fill wrword t1, dst - add dst, #2 - djnz cols, #:fill -can_ret - ret - -'******************************************************************************************** -' emit - emit character to cursor and advance cursor position -' -emit - cmp new_x, screen_w WZ, WC ' reached end of line? - if_b jmp #:in_bounds - test flags, #flag_decawm WZ ' auto wrap mode active? - if_z jmp #emit_ret ' no, don't emit character - call #cr - call #lf -:in_bounds mov cur_x, new_x - call #calc_cursor - or cmd, color - test attr, #attr_underline WZ - muxnz cmd, #$80 - wrword cmd, cur_ptr ' write character to screen RAM - mov new_x, cur_x - add new_x, #1 - add cur_ptr, #2 -emit_ret - ret - -'******************************************************************************************** -' calc_cursor - compute cursor address in cur_ptr -' -calc_cursor - mov t1, cur_y ' cursor row - mov t2, screen_w ' * screen width - call #mul16x16 - mov cur_ptr, t2 ' product in cur_ptr - add cur_ptr, new_x ' + new cursor column - shl cur_ptr, #1 ' * 2 - add cur_ptr, screen_ptr ' + screen buffer address -calc_cursor_ret - ret - -'******************************************************************************************** -' enable_cursor - enable or disable the cursor depending on the deccm flag -' -enable_cursor - tjz cursor_ptr, #cmdloop - test flags, #flag_deccm WZ ' cursor enabled? - if_z mov t1, #%000 ' cursor off - if_nz mov t1, #%110 ' cursor on, blink slow - add cursor_ptr, #2 ' cursor control - wrbyte t1, cursor_ptr - sub cursor_ptr, #2 - jmp #cmdloop - -'******************************************************************************************** -' set_color - combine background and foreground color and write the table -' -set_color - test attr, #attr_inverse WZ - if_z jmp #:default -:inverse - mov color, fgcol ' compose inverse color - shl color, #4 - or color, bgcol - jmp #:cont -:default - mov color, bgcol ' compose default color - shl color, #4 - or color, fgcol -:cont - test attr, #attr_highlite WZ - muxnz color, #$08 - test attr, #attr_blinking WZ - muxnz color, #$80 - shl color, #8 ' in bits 15..8 - jmp #cmdloop - -'******************************************************************************************** -' mul16x16 - multiply 16 bits in t1 by 16 bits in t2, result in t2 -' -mul16x16 - shl t1, #16 ' multiplicand in bits 31..16 - mov t3, #16 ' loop 16 times - shr t2, #1 WC ' get initial multiplier bit in carry -:loop if_c add t2, t1 WC ' if carry set, add multiplicand to product - rcr t2, #1 WC ' next multiplier bit to carry, shift product - djnz t3, #:loop ' until done -mul16x16_ret - ret - -lmm_loop - rdlong :op1, lmm_pc - add lmm_pc, #4 -:op1 nop - rdlong :op2, lmm_pc - add lmm_pc, #4 -:op2 nop - rdlong :op3, lmm_pc - add lmm_pc, #4 -:op3 nop - rdlong :op4, lmm_pc - add lmm_pc, #4 -:op4 nop - jmp #lmm_loop - - fit $1f0 - -control_table word do_nul, do_soh, do_stx, do_etx, do_eot, do_enq, do_ack, do_bel - word do_bs, do_ht, do_lf, do_vt, do_ff, do_cr, do_so, do_si - word do_dle, do_dc1, do_dc2, do_dc3, do_dc4, do_nak, do_syn, do_etb - word do_can, do_em, do_sub, do_esc, do_fs, do_gs, do_rs, do_us - -csi_cmds word @@@do_insert_char ' [...@ - word @@@do_cursor_up ' [...A - word @@@do_cursor_down ' [...B - word @@@do_cursor_left ' [...C - word @@@do_cursor_right ' [...D - word @@@do_rows_up ' [...E - word @@@do_rows_down ' [...F - word @@@do_cursor_column ' [...G - word @@@do_cursor_address ' [...H - word cmdloop ' I unused? - word @@@do_clear_screen ' [...J - word @@@do_clear_row ' [...K - word @@@do_insert_line ' [...L - word @@@do_delete_line ' [...M - word cmdloop ' N unused? - word cmdloop ' O unused? - word @@@do_delete_char ' P unused? - word cmdloop ' Q unused? - word cmdloop ' R unused? - word cmdloop ' S unused? - word cmdloop ' T unused? - word cmdloop ' U unused? - word cmdloop ' V unused? - word cmdloop ' W unused? - word @@@do_blank_chars ' [...X - word cmdloop ' Y unused? - word cmdloop ' Z unused? - word cmdloop ' [ unused - word cmdloop ' \ unused - word cmdloop ' ] unused - word cmdloop ' ^ unused - word cmdloop ' _ unused - word @@@do_cursor_column ' [...` alternate form for [...G - word cmdloop ' a unused? - word cmdloop ' b unused? - word cmdloop ' c unused? - word cmdloop ' d unused? - word cmdloop ' e unused? - word @@@do_cursor_address ' [...f alternate form for [...H - word cmdloop ' g unused? - word @@@do_flag_set ' h unused? - word cmdloop ' i unused? - word cmdloop ' j unused? - word cmdloop ' k unused? - word @@@do_flag_res ' h unused? - word @@@do_mode_attributes ' [...m - word cmdloop ' n unused? - word cmdloop ' o unused? - word cmdloop ' p unused? - word cmdloop ' q unused? - word @@@do_scroll_range ' [...r - word @@@do_save_cursor ' [?...s - word cmdloop ' t unused? - word @@@do_restore_cursor ' [?...u - word cmdloop ' v unused? - word cmdloop ' w unused? - word cmdloop ' x unused? - word cmdloop ' y unused? - word cmdloop ' z unused? - -'******************************************************************************************** -' -' LMM code fragments following -' -'******************************************************************************************** - -'******************************************************************************************** -' [...@ - insert n spaces at the cursor position -' -do_insert_char - call #non_zero_args - cmp new_x, screen_w WZ, WC - if_ae jmp #cmdloop -:loop mov t1, cur_y - mov t2, screen_w - call #mul16x16 - add t2, new_x - shl t2, #1 - add t2, screen_ptr - mov dst, t2 - add dst, #2 - mov src, t2 - mov cols, screen_w - sub cols, new_x - sub cols, #1 WZ, WC - if_be add lmm_pc, #4*(:blank - $ - 1) -:insert rdword data, src - add src, #2 - wrword data, dst - add dst, #2 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :insert) - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:blank wrword t1, t2 - sub csi_args, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...A - cursor up -' -do_cursor_up - call #non_zero_args -:loop call #vt - sub csi_args, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...B - cursor down -' -do_cursor_down - call #non_zero_args -:loop call #lf - djnz csi_args, #:loop - jmp #cmdloop - -'******************************************************************************************** -' [...C - cursor left -' -do_cursor_left - call #non_zero_args - mov cur_x, new_x - sub cur_x, csi_args WC - if_c mov cur_x, #0 - jmp #validate_cursor - -'******************************************************************************************** -' [...D - cursor right -' -do_cursor_right - call #non_zero_args - mov cur_x, new_x - add cur_x, csi_args - jmp #validate_cursor - -'******************************************************************************************** -' [...E - rows up, cursor column = 0 -' -do_rows_up - call #non_zero_args - mov cur_x, #0 - mov new_x, #0 - sub cur_y, csi_args WC - if_c mov cur_y, #0 - jmp #validate_cursor - -'******************************************************************************************** -' [...F - rows down, cursor column = 0 -' -do_rows_down - call #non_zero_args - mov cur_x, #0 - mov new_x, #0 - add cur_y, csi_args - jmp #validate_cursor - -'******************************************************************************************** -' [...H - cursor address - row, column -' -do_cursor_address - cmp csi_argf, #0 WZ ' nor arguments at all? - if_z call #home - if_z jmp #cmdloop - call #non_zero_args - mov cur_y, csi_args - sub cur_y, #1 - cmp csi_argc, #1 WZ, WC ' the caller specified just a row? - if_be jmp #validate_cursor - call #shift_csi_args - ' fall through -'******************************************************************************************** -' [...G - cursor column -' -do_cursor_column - call #non_zero_args - mov cur_x, csi_args - sub cur_x, #1 - jmp #validate_cursor - -'******************************************************************************************** -' [...J - clear screen -' -do_clear_screen - call #calc_cursor - cmp csi_args, #0 WZ ' cursor to end of screen? - if_nz add lmm_pc, #4*(:not_0 - $ - 1) - mov dst, cur_ptr - mov end, screen_end - add lmm_pc, #4*(:fill - $ - 1) -:not_0 cmp csi_args, #1 WZ ' start of screen to cursor? - if_nz add lmm_pc, #4*(:not_1 - $ - 1) - mov dst, screen_ptr - mov end, cur_ptr - add lmm_pc, #4*(:fill - $ - 1) -:not_1 cmp csi_args, #2 WZ ' entire screen? - if_nz jmp #cmdloop ' invalid argument - mov dst, screen_ptr ' default = entire screen - mov end, screen_end -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:loop wrword t1, dst ' fill a word - add dst, #2 - cmp dst, end WZ, WC - if_b sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...K - clear cursor row -' -do_clear_row - call #calc_cursor - cmp csi_args, #0 WZ ' cursor to end of row? - if_nz add lmm_pc, #4*(:not_0 - $ - 1) - mov dst, cur_ptr ' default = cursor to end of row - mov end, cur_ptr - sub end, new_x - add end, screen_w ' end of row - add lmm_pc, #4*(:fill - $ - 1) -:not_0 cmp csi_args, #1 WZ ' start of row to cursor? - if_nz add lmm_pc, #4*(:not_1 - $ - 1) - mov dst, cur_ptr - sub dst, new_x ' start of row - mov end, cur_ptr ' to cursor - add lmm_pc, #4*(:fill - $ - 1) -:not_1 cmp csi_args, #2 WZ ' entire row? - if_nz jmp #cmdloop ' invalid argument - mov dst, cur_ptr - sub dst, new_x ' start of row - mov end, dst - add end, screen_w ' end of row -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:loop wrword t1, dst ' fill a word - add dst, #2 - cmp dst, end WZ, WC - if_b sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...L - insert line(s) -' -do_insert_line - call #non_zero_args -:loop mov dst, screen_end - mov src, screen_end - sub src, screen_w - mov rows, screen_h ' screen rows - sub rows, cur_y ' - cursor row - sub rows, #1 WZ, WC ' - 1 - if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols sub src, #4 - rdlong data, src - sub dst, #4 - wrlong data, dst - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :cols) - sub rows, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :rows) -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - mov cols, screen_w2 ' columns = screen width / 2 -:blank sub dst, #4 - wrlong t1, dst - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns - sub csi_args, #1 WZ ' more lines to insert? - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...M - delete line(s) -' -do_delete_line - call #non_zero_args -:loop mov t1, cur_y - mov t2, screen_w - call #mul16x16 - shl t2, #1 - add t2, screen_ptr ' cursor row address - mov dst, t2 - mov src, t2 - add src, screen_w ' one row down - add src, screen_w - mov rows, screen_h ' screen rows - sub rows, cur_y ' - cursor row - sub rows, #1 WZ, WC ' - 1 - if_be add lmm_pc, #4*(:fill - $ - 1) ' nothing left to move? -:rows mov cols, screen_w2 ' columns = screen width / 2 -:cols rdlong data, src - add src, #4 - wrlong data, dst - add dst, #4 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :cols) - sub rows, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :rows) -:fill mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - mov cols, screen_w2 ' columns = screen width / 2 -:blank wrlong t1, dst - add dst, #4 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :blank) ' for all columns - sub csi_args, #1 WZ ' more lines to insert? - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...P - delete n characters at the cursor position -' -do_delete_char - call #non_zero_args - cmp new_x, screen_w WZ, WC - if_ae jmp #cmdloop ' can't delete beyond last column -:loop mov t1, cur_y - mov t2, screen_w - call #mul16x16 - add t2, new_x - shl t2, #1 - add t2, screen_ptr - mov dst, t2 - mov src, t2 - add src, #2 - mov cols, screen_w - sub cols, new_x - sub cols, #1 WZ, WC - if_be add lmm_pc, #4*(:blank - $ - 1) ' new_x is beyond the last column -:insert rdword data, src - add src, #2 - wrword data, dst - add dst, #2 - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :insert) -:blank mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color - wrword t1, dst ' clear the last character in the row - sub csi_args, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #cmdloop - -'******************************************************************************************** -' [...X - blank characters -' -do_blank_chars - call #non_zero_args - mov dst, cur_ptr - mov cols, screen_w - sub cols, new_x WZ, WC - if_be jmp #cmdloop - mov t1, x00200020 - or t1, color - rol t1, #16 - or t1, color -:fill wrword t1, dst - add dst, #2 - sub csi_args, #1 WZ - if_z jmp #cmdloop - sub cols, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :fill) - jmp #cmdloop - -'******************************************************************************************** -' [...h - set flag(s) -' -do_flag_set -:loop - mov cmd, csi_args - cmp question_mark, #1 WZ ' [? sequence? - if_z add lmm_pc, #4*(:ques - $ - 1) - cmp cmd, #3 WZ ' [3h - display control characters - if_z or flags, #flag_ctrl - cmp cmd, #4 WZ ' [4h - set insert mode - if_z or flags, #flag_decim - cmp cmd, #20 WZ ' [20h - set auto CR mode - if_z or flags, #flag_deccr - add lmm_pc, #4*(:next - $ - 1) -:ques - cmp cmd, #1 WZ ' [?1h - enable cursor keys - if_z or flags, #flag_decck -' cmp cmd, #2 WZ ' [?2h - enable 132 column mode -' if_z or flags, #flag_decck - cmp cmd, #5 WZ ' [?5h - inverse terminal on - if_z or inverse, #1 - cmp cmd, #6 WZ ' [?6h - enable origin mode - if_z or flags, #flag_decom - cmp cmd, #7 WZ ' [?7h - enable auto wrap mode - if_z or flags, #flag_decawm - cmp cmd, #8 WZ ' [?8h - enable auto repeat mode - if_z or flags, #flag_decarm -' cmp cmd, #9 WZ ' [?9h - enable report mouse mode -' if_z or flags, #flag_decrm - cmp cmd, #25 WZ ' [?25h - enable cursor - if_z or flags, #flag_deccm -:next - cmp csi_argf, #0 WZ ' no arguments specified? - if_z jmp #cmdloop - - call #shift_csi_args - sub csi_argc, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #enable_cursor - -'******************************************************************************************** -' [...l - reset flag(s) -' -do_flag_res -:loop - mov cmd, csi_args - cmp question_mark, #1 WZ ' [? sequence? - if_z add lmm_pc, #4*(:ques - $ - 1) - cmp cmd, #3 WZ ' [3l - don't display control characters - if_z andn flags, #flag_ctrl - cmp cmd, #4 WZ ' [4l - reset insert mode - if_z andn flags, #flag_decim - cmp cmd, #20 WZ ' [20l - reset auto CR mode - if_z andn flags, #flag_deccr - add lmm_pc, #4*(:next - $ - 1) -:ques - cmp cmd, #1 WZ ' [?1l - disable cursor keys - if_z andn flags, #flag_decck -' cmp cmd, #2 WZ ' [?2l - disable 132 column mode -' if_z andn flags, #flag_decck - cmp cmd, #5 WZ ' [?5l - inverse terminal off - if_z andn inverse, #1 - cmp cmd, #6 WZ ' [?6l - disable origin mode - if_z andn flags, #flag_decom - cmp cmd, #7 WZ ' [?7l - disable auto wrap mode - if_z andn flags, #flag_decawm - cmp cmd, #8 WZ ' [?8l - disable auto repeat mode - if_z andn flags, #flag_decarm -' cmp cmd, #9 WZ ' [?9l - disable report mouse mode -' if_z andn flags, #flag_decrm - cmp cmd, #25 WZ ' [?25l - disable cursor - if_z andn flags, #flag_deccm -:next - cmp csi_argf, #0 WZ ' no arguments specified? - if_z jmp #cmdloop - - call #shift_csi_args - sub csi_argc, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :loop) - jmp #enable_cursor - - -'******************************************************************************************** -' [...m - set mode attributes -' -do_mode_attributes -:get_arg mov cmd, csi_args ' get next argument - cmp cmd, #0 WZ ' 0 = reset all attributes - if_z mov attr, #0 - if_z mov bgcol, #%0000 - if_z mov fgcol, #%0111 - cmp cmd, #1 WZ ' 1 = highlight on - if_z or attr, #attr_highlite - cmp cmd, #2 WZ ' 2 = highlight off - if_z andn attr, #attr_highlite - cmp cmd, #4 WZ ' 4 = underline on - if_z or attr, #attr_underline - cmp cmd, #5 WZ ' 5 = blinking on - if_z or attr, #attr_blinking - cmp cmd, #7 WZ ' 7 = inverse on - if_z or attr, #attr_inverse - cmp cmd, #10 WZ ' 10 = primary font, no ctrl, no meta - if_z andn flags, #flag_ctrl - if_z andn flags, #flag_meta - cmp cmd, #11 WZ ' 11 = alternate font, ctrl chars, low half, meta off - if_z or flags, #flag_ctrl - if_z andn flags, #flag_meta - cmp cmd, #12 WZ ' 12 = alternate font, ctrl chars, low half, meta on - if_z or flags, #flag_ctrl - if_z or flags, #flag_meta - cmp cmd, #21 WZ ' 21 = highlight on - if_z or attr, #attr_highlite - cmp cmd, #22 WZ ' 22 = highlight on - if_z or attr, #attr_highlite - cmp cmd, #24 WZ ' 24 = underline off - if_z andn attr, #attr_underline - cmp cmd, #25 WZ ' 25 = blinking off - if_z andn attr, #attr_blinking - cmp cmd, #27 WZ ' 27 = inverse off - if_z andn attr, #attr_inverse - cmp cmd, #30 WZ ' 30 = foreground color 0 - if_z mov fgcol, #%0000 - cmp cmd, #31 WZ ' 31 = foreground color 1 - if_z mov fgcol, #%0001 - cmp cmd, #32 WZ ' 32 = foreground color 2 - if_z mov fgcol, #%0010 - cmp cmd, #33 WZ ' 33 = foreground color 3 - if_z mov fgcol, #%0011 - cmp cmd, #34 WZ ' 34 = foreground color 4 - if_z mov fgcol, #%0100 - cmp cmd, #35 WZ ' 35 = foreground color 5 - if_z mov fgcol, #%0101 - cmp cmd, #36 WZ ' 36 = foreground color 6 - if_z mov fgcol, #%0110 - cmp cmd, #37 WZ ' 37 = foreground color 7 - if_z mov fgcol, #%0111 - cmp cmd, #38 WZ ' 38 = default color and underline on - if_z mov fgcol, #%0111 - if_z or attr, #attr_underline - cmp cmd, #39 WZ ' 39 = default color and underline off - if_z mov fgcol, #%0111 - if_z andn attr, #attr_underline - cmp cmd, #40 WZ ' 40 = default background - if_z mov bgcol, #%0000 ' black - cmp cmd, #41 WZ ' 41 = background color 1 - if_z mov bgcol, #%0001 - cmp cmd, #42 WZ ' 42 = background color 2 - if_z mov bgcol, #%0010 - cmp cmd, #43 WZ ' 43 = background color 3 - if_z mov bgcol, #%0011 - cmp cmd, #44 WZ ' 44 = background color 4 - if_z mov bgcol, #%0100 - cmp cmd, #45 WZ ' 45 = background color 5 - if_z mov bgcol, #%0101 - cmp cmd, #46 WZ ' 46 = background color 6 - if_z mov bgcol, #%0110 - cmp cmd, #47 WZ ' 47 = background color 7 - if_z mov bgcol, #%0111 - cmp cmd, #49 WZ ' 49 = default background - if_z mov bgcol, #%0000 ' black - - cmp csi_argf, #0 WZ ' no arguments specified? - if_z jmp #cmdloop - - call #shift_csi_args - sub csi_argc, #1 WZ - if_nz sub lmm_pc, #4*($ + 1 - :get_arg) - jmp #set_color - -'******************************************************************************************** -' [...r - set scroll range -' -do_scroll_range - cmp csi_argc, #2 WZ, WC ' 2 arguments specified? - if_ae add lmm_pc, #4*(:set_range - $ - 1) - mov scroll_top, #1 - mov scroll_bot, screen_h - add lmm_pc, #4*(:bottom_ok - $ - 1) -:set_range - mov scroll_top, csi_args - mov scroll_bot, csi_args + 1 - cmp scroll_top, scroll_bot WZ, WC ' bottom => top? - if_be add lmm_pc, #4*(:order_ok - $ - 1) - mov scroll_top, #1 - mov scroll_bot, screen_h - add lmm_pc, #4*(:bottom_ok - $ - 1) -:order_ok - cmp scroll_bot, screen_h WZ, WC ' bottom > screen height? - if_be add lmm_pc, #4*(:bottom_ok - $ - 1) - mov scroll_top, #1 - mov scroll_bot, screen_h -:bottom_ok - sub scroll_top, #1 - mov cur_x, #0 - mov cur_y, #0 - jmp #goto_xay - -'******************************************************************************************** -' [?...s - save cursor position and attributes -' -do_save_cursor - mov cur_x_save, cur_x - mov new_x_save, new_x - mov cur_y_save, cur_y - mov attr_save, attr - jmp #cmdloop - - -'******************************************************************************************** -' [?...u - restore cursor position and attributes -' -do_restore_cursor - mov cur_x, cur_x_save - mov new_x, new_x_save - mov cur_y, cur_y_save - mov attr, attr_save - jmp #cmdloop diff --git a/Source/Hardware/Prop/Spin/AnsiTerm.spin b/Source/Hardware/Prop/Spin/AnsiTerm.spin new file mode 100644 index 00000000..3d5fb32d --- /dev/null +++ b/Source/Hardware/Prop/Spin/AnsiTerm.spin @@ -0,0 +1,535 @@ +'' AnsiTerm.spin +'' +'' MODIFIED BY WAYNE WARTHEN FOR ANSI COLOR CHARACTER SUPPORT +'' +'' based on... +'' +'' VGA_1024.spin +'' +'' MODIFIED BY VINCE BRIEL FOR POCKETERM FEATURES +'' MODIIFED BY JEFF LEDGER / AKA OLDBITCOLLECTOR +'' + +CON + cols = 80 ' screen columns + rows = 40 ' screen rows + chars = rows * cols ' screen characters + termRows = 25 ' rows in terminal area + termChars = termRows * cols ' characters in terminal area + termLastRow = termChars - cols ' buffer pos of first char in last term row + statArea = termChars ' starting position of status area + statRows = rows - TermRows ' status area rows + blank = $20 + +OBJ + vga : "vgacolour" + 'vga : "vga8x8d" + +VAR + word screen[chars] ' screen character buffer + word tmpl[cols] ' temporary line buffer + byte cursor[6] ' cursor info array (see CursorPtr description above) + long sync, loc, xloc, yloc ' sync used by VGA routine, others are local screen pointers + byte state ' Current state of state machine + word pos ' Current Position on the screen + word regionTop, regionBot ' Scroll region top/bottom + long arg0 ' First argument of escape sequence + long arg1 ' Second argument of escape sequence + byte lastc ' Last displayed char + long vgaBasePin + word curAttr ' active attribute value + word bold, underscore, blink, reverse, fg, bg + + +DAT + { + color ansi rgb + ----- ---- --- + black 0 0 + red 1 4 + green 2 2 + yellow 3 6 + blue 4 1 + magenta 5 5 + cyan 6 3 + white 7 7 + } + cmap WORD 0,4,2,6,1,5,3,7 ' Map ANSI color codes to VGA driver RGB + +PUB start(BasePin) | i, char + vgaBasePin := BasePin + + cursor[2] := %110 ' init cursor to underscore with slow blink + xloc := cursor[0] := 0 + yloc := cursor[1] := 0 + loc := xloc + yloc * cols + + pos := 0 + regionTop := 0 + regionBot := termChars + state := 0 + bold := 0 + underscore := 0 + blink := 0 + reverse := 0 + fg := 0 + bg := 0 + setMode(0) ' reset attributes + +PUB vidOn + if (!vga.start(vgaBasePin, @screen, @cursor, @sync)) + return false + +PUB vidOff + vga.stop + +PUB cls + wordfill(@screen, (curAttr | blank), chars) + +PUB dec(value) | i + +'' Print a decimal number + + if value < 0 + -value + outc("-") + + i := 1_000_000_000 + + repeat 10 + if value => i + outc(value/i + "0") + value //= i + result~~ + elseif result or i == 1 + outc("0") + i /= 10 + +PUB bin(value, digits) + +'' Print a binary number, specify number of digits + + repeat while digits > 32 + outc("0") + digits-- + + value <<= 32 - digits + + repeat digits + outc((value <-= 1) & 1 + "0") + + +PUB hex(value, digits) + +'' Print a hexadecimal number, specify number of digits + + repeat while digits > 8 + outc("0") + digits-- + + value <<= (8 - digits) << 2 + + repeat digits + outc(lookupz((value <-= 4) & $f : "0".."9", "A".."F")) + + +PUB str(string_ptr) + +'' Print a zero terminated string + + repeat strsize(string_ptr) + outc(byte[string_ptr++]) + +PUB statInfo + result := (statRows << 8) | cols + +PUB statStr(row, col, attr, strVal) | nxtPos + nxtPos := statArea + (row * cols) + col + repeat strsize(strVal) + screen[nxtPos++] := (attr | byte[strVal++]) + +PUB statFill(row, col, attr, charVal, count) + wordfill(@screen + ((statArea + (row * cols) + col) * 2), (attr | charVal), count) + +PRI clsTerm + wordfill (@screen, (curAttr | blank), termChars) + +PRI outc(c) + + screen[pos++] := (curAttr | c) + lastc := c + + if pos == regionBot + scrollUp + pos -= cols + elseif pos == termChars + pos := termLastRow + +PRI setMode(n) + if (n == 0) + bold := 0 + underscore := 0 + blink := 0 + reverse := 0 + fg := 7 + bg := 0 + elseif (n == 1) + bold := 1 + elseif (n == 4) + underscore := 1 + elseif (n == 5) + blink := 1 + elseif (n == 7) + reverse := 1 + elseif ((n => 30) & (n =< 37)) + fg := cmap[(n - 30)] + elseif ((n => 40) & (n =< 47)) + bg := cmap[(n - 40)] + + if (reverse == 0) + curAttr := ((fg << 8) | (bg << 12)) + else + curAttr := ((fg << 12) | (bg << 8)) + + curAttr |= (bold << 11) | (underscore << 7) | (blink << 15) + +PRI clEOL(position) | count + count := cols - (position // cols) + wordfill(@screen + (position * 2), (curAttr | blank), count) + +PRI clBOL(position) | count + count := position // cols + wordfill(@screen + ((position - count) * 2), (curAttr | blank), count) + +PRI delLine(position) | src, count + position -= position // cols + + src := position + cols + + count := termChars - src + + if count > 0 + wordmove(@screen + (position * 2), @screen + (src * 2), count) + + wordfill(@screen + (termLastRow * 2), (curAttr | blank), cols) + +PRI clEOS(position) + cleol(position) + position += cols - (position // cols) + repeat while position < termChars + wordfill(@screen + (position * 2), (curAttr | blank), cols) + pos += cols + +PRI setCursorPos(position) + cursor[0] := position // cols + cursor[1] := position / cols + +PRI insLine(position) | base, nxt + base := position - (position // cols) + position := termLastRow + repeat while position > base + nxt := position - cols + wordmove(@screen + (position * 2), @screen + (nxt * 2), cols) + position := nxt + clEOL(base) + +PRI insChar(position) | count + count := (cols - (position // cols)) - 1 + wordmove(@tmpl, @screen + (position * 2), count) + screen[position] := (curAttr | blank) + wordmove(@screen + ((position + 1) * 2), @tmpl, count) + +PRI delChar(position) | count + count := (cols - (position // cols)) - 1 + wordmove(@screen + (position * 2), @screen + ((position + 1) * 2), count) + screen[position + count] := (curAttr | blank) + +PRI inRegion : answer + answer := (pos => regionTop) AND (pos < regionBot) + +PRI scrollUp + delLine(regionTop) + if regionBot < termChars + insLine(regionBot) + +PRI scrollDown + if regionBot < termChars + delLine(regionBot) + insLine(regionTop) + +PRI ansi(c) | x, defVal + + state := 0 + + if (c <> "r") AND (c <> "J") AND (c <> "m") AND (c <> "K") + if arg0 == -1 + arg0 := 1 + if arg1 == -1 + arg1 := 1 + + case c + "@": + repeat while arg0-- > 0 + insChar(pos) + + "b": + repeat while arg0-- > 0 + outc(lastc) + + "d": + if (arg0 < 1) OR (arg0 > rows) + arg0 := rows + pos := ((arg0 - 1) * cols) + (pos // cols) + + "m": + if (arg0 == -1) + setMode(0) + else + setMode(arg0) + if arg1 <> -1 + setMode(arg1) + + "r": + if arg0 < 1 + arg0 := 1 + elseif arg0 > cols + arg0 := cols + if arg1 < 1 + arg1 := 1 + elseif arg1 > cols + arg1 := cols + if arg1 < arg0 + arg1 := arg0 + + regionTop := (arg0 - 1) * cols + regionBot := arg1 * cols + pos := 0 + + "A": + repeat while arg0-- > 0 + pos -= cols + if pos < 0 + pos += cols + return + + "B": + repeat while arg0-- > 0 + pos += cols + if pos => termChars + pos -= cols + return + + "C": + repeat while arg0-- > 0 + pos += 1 + if pos => termChars + pos -= 1 + return + + "D": + repeat while arg0-- > 0 + pos -= 1 + if pos < 0 + pos := 0 + return + + "G": + if (arg0 < 1) OR (arg0 > cols) + arg0 := cols + pos := (pos - (pos // cols)) + (arg0 - 1) + + "H", "f": + if arg0 =< 0 + arg0 := 1 + if arg1 =< 0 + arg1 := 1 + pos := (cols * (arg0 - 1)) + (arg1 - 1) + if pos < 0 + pos := 0 + if pos => termChars + pos := termChars - 1 + + "J": + if arg0 == 1 + clBOL(pos) + x := pos - cols + x -= x // cols + repeat while x => 0 + clEOL(x) + x -= cols + return + + if arg0 == 2 + pos := 0 + + clEOL(pos) + x := pos + cols + x -= (x // cols) + repeat while x < termChars + clEOL(x) + x += cols + + "K": + if arg0 == -1 + clEOL(pos) + elseif arg0 == 1 + clBOL(pos) + else + clEOL(pos - (pos // cols)) + + "L": + if inRegion + repeat while arg0-- > 0 + if regionBot < termChars + delLine(regionBot) + insLine(pos) + + "M": + if inRegion + repeat while arg0-- > 0 + delLine(pos) + if regionBot < termChars + insLine(regionBot) + + "P": + repeat while arg0-- + delChar(pos) + +PUB processChar(c) + + case state + + 0: ' Default state (no escape sequence in process) + if c > 127 + c := $20 + + if c => $20 + outc(c) + setCursorPos(pos) + return + + if c == $1B + state := 1 + return + + if c == $0D + pos := pos - (pos // cols) + setCursorPos(pos) + return + + if c == $0A + if inRegion + pos += cols + if pos => regionBot + scrollUp + pos -= cols + else + pos += cols + if pos => termChars + pos -= cols + setCursorPos(pos) + return + + if c == 9 + pos += (8 - (pos // 8)) + + if pos => termChars + pos := termLastRow + delLine(0) + + setCursorPos(pos) + return + + if c == 8 + if pos > 0 + pos -= 1 + setCursorPos(pos) + return + + 1: ' Process char following escape + case c + "[": + arg0 := arg1 := -1 + state := 2 + return + + "P": + pos += cols + if pos => termChars + pos -= cols + + "K": + if pos > 0 + pos -= 1 + + "H": + pos -= cols + if pos < 0 + pos += cols + + "D": + if inRegion + scrollUp + + "M": + if inRegion + scrollDown + + "G": + pos := 0 + + "(": + state := 5 + return + + state := 0 + return + + 2: ' Parse first argument (arg0) of escape sequence + if (c => "0") AND (c =< "9") + if arg0 == -1 + arg0 := c - "0" + else + arg0 := (arg0 * 10) + (c - "0") + return + + if c == ";" + state := 3 + return + + ansi(c) + setCursorPos(pos) + return + + 3: ' Parse second argument (arg1) of escape sequence + if (c => "0") AND (c =< "9") + if arg1 == -1 + arg1 := c - "0" + else + arg1 := (arg1 * 10) + (c - "0") + return + + if c == ";" + state := 4 + return + + ansi(c) + setCursorPos(pos) + return + + 4: ' Parse remaining arguments (ignored) + if (c => "0") AND (c =< "9") + return + + if c == ";" + return + + ansi(c) + setCursorPos(pos) + return + + 5: ' Set character set (not implemented) + state := 0 + return + + return \ No newline at end of file diff --git a/Source/Hardware/Prop/Spin/E555_SPKEngine.spin b/Source/Hardware/Prop/Spin/E555_SPKEngine.spin index 02e55e87..e1011bd3 100644 --- a/Source/Hardware/Prop/Spin/E555_SPKEngine.spin +++ b/Source/Hardware/Prop/Spin/E555_SPKEngine.spin @@ -1 +1,100 @@ -{{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // E555 Speaker Engine // // Author: Kwabena W. Agyeman // Updated: 7/27/2010 // Designed For: P8X32A // Version: 1.1 // // Copyright (c) 2010 Kwabena W. Agyeman // See end of file for terms of use. // // Update History: // // v1.0 - Original release - 8/26/2009. // v1.1 - Added support for variable pin assignments - 7/27/2010. // // For each included copy of this object only one spin interpreter should access it at a time. // // Nyamekye, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Speaker Circuit: // // SpeakerPinNumber --- Speaker Driver (Active High). // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }} PUB speakerFrequency(newFrequency, speakerPinNumber) '' 10 Stack Longs '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// '' // Changes the speaker frequency using the SPIN interpreter's counter modules. '' // '' // NewFrequency - The new frequency. Between 0 Hz and 80MHz @ 80MHz. -1 to reset the pin and counter modules. '' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// speakerSetup((newFrequency <> -1), speakerPinNumber) newFrequency := ((newFrequency <# clkfreq) #> 0) result := 1 repeat 32 newFrequency <<= 1 result <-= 1 if(newFrequency => clkfreq) newFrequency -= clkfreq result += 1 frqa := result~ phsb := 0 PUB speakerVolume(newVolume, speakerPinNumber) '' 10 Stack Longs '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// '' // Changes the speaker volume using the SPIN interpreter's counter modules. '' // '' // NewVolume - The new volume. Between 0% and 100%. -1 to reset the pin and counter modules. '' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// speakerSetup((newVolume <> -1), speakerPinNumber) frqb := (((100 - ((newVolume <# 100) #> 0)) * constant(posx / 50)) | $7) PRI speakerSetup(activeOrInactive, speakerPinNumber) ' 5 Stack Longs speakerPinNumber := ((speakerPinNumber <# 31) #> 0) dira[speakerPinNumber] := activeOrInactive outa[speakerPinNumber] := false ctra := ((constant(%0_0100 << 26) + speakerPinNumber) & activeOrInactive) ctrb := ((constant(%0_0110 << 26) + speakerPinNumber) & activeOrInactive) {{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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 +{{ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// E555 Speaker Engine +// +// Author: Kwabena W. Agyeman +// Updated: 7/27/2010 +// Designed For: P8X32A +// Version: 1.1 +// +// Copyright (c) 2010 Kwabena W. Agyeman +// See end of file for terms of use. +// +// Update History: +// +// v1.0 - Original release - 8/26/2009. +// v1.1 - Added support for variable pin assignments - 7/27/2010. +// +// For each included copy of this object only one spin interpreter should access it at a time. +// +// Nyamekye, +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Speaker Circuit: +// +// SpeakerPinNumber --- Speaker Driver (Active High). +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +}} + +PUB speakerFrequency(newFrequency, speakerPinNumber) '' 10 Stack Longs + +'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +'' // Changes the speaker frequency using the SPIN interpreter's counter modules. +'' // +'' // NewFrequency - The new frequency. Between 0 Hz and 80MHz @ 80MHz. -1 to reset the pin and counter modules. +'' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. +'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + speakerSetup((newFrequency <> -1), speakerPinNumber) + + newFrequency := ((newFrequency <# clkfreq) #> 0) + + result := 1 + + repeat 32 + newFrequency <<= 1 + result <-= 1 + if(newFrequency => clkfreq) + newFrequency -= clkfreq + result += 1 + + frqa := result~ + + phsb := 0 + +PUB speakerVolume(newVolume, speakerPinNumber) '' 10 Stack Longs + +'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +'' // Changes the speaker volume using the SPIN interpreter's counter modules. +'' // +'' // NewVolume - The new volume. Between 0% and 100%. -1 to reset the pin and counter modules. +'' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. +'' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + speakerSetup((newVolume <> -1), speakerPinNumber) + + frqb := (((100 - ((newVolume <# 100) #> 0)) * constant(posx / 50)) | $7) + +PRI speakerSetup(activeOrInactive, speakerPinNumber) ' 5 Stack Longs + + speakerPinNumber := ((speakerPinNumber <# 31) #> 0) + + dira[speakerPinNumber] := activeOrInactive + + outa[speakerPinNumber] := false + + ctra := ((constant(%0_0100 << 26) + speakerPinNumber) & activeOrInactive) + + ctrb := ((constant(%0_0110 << 26) + speakerPinNumber) & activeOrInactive) + +{{ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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/Hardware/Prop/Spin/FullDuplexSerial.spin b/Source/Hardware/Prop/Spin/FullDuplexSerial.spin index b248f963da513059a2c960b996f9743e6a7fc67f..eed14313fb861dc0c7830e2ad38ecb39d714ce9f 100644 GIT binary patch literal 12819 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 CO75os diff --git a/Source/Hardware/Prop/Spin/FullDuplexSerialNull.spin b/Source/Hardware/Prop/Spin/FullDuplexSerialNull.spin index 7a03e7ab97f93c0682cf0abd5407bcfca95139bc..f8f5f0bf6e0759d2a530097228cfbb64a69b1a0a 100644 GIT binary patch literal 286 zcmZvWI}XDj3_$lvy@N+0ae|ILL6#nXfE!Q}h>WR-l*5;X(4p#pjGv!B{o@Xi6|tba zIxm51Sb{+bgGz=JV+S_~liIGA{_w+Ef0Undinb*>B+o@XVuhUlK+4*po{C9%*ce+s zy9LD(Kig^ncHmb0!Zuj&(cINMGKun>A6KT68PwvX=2Y(A!AZzfwU{fGVBF|9p8DYY G4}SyErdyW) literal 574 zcmah`%MOA-44kux|G*Ivzrdqk;KdJ+he!}HPz)x1yEqw!dOD|maj$4$OCJvVEJ3J+L-n^;X;lc z=S3zX&p-__vwGihs5+l<{k?CI+AU+Bg0`MHHI`DTs{h3bH_$L1)ArxlY(<18d1O)P zR9K|tR>d)^eCH%!&`WegxL>bOa&H<7ae9S}xI1^PJ9PV3Mb&hjF<{lXwXa9(ZF6Ev OKA9%8DpN+UfAAj{@LiMu diff --git a/Source/Hardware/Prop/Spin/Keyboard.spin b/Source/Hardware/Prop/Spin/Keyboard.spin index 29025a99689e5fc04d794a2e281e42ace8c1d4b4..3a1b1e37823c86fb32978763d27b25c13f31815e 100644 GIT binary patch literal 31240 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 literal 49604 zcmeI5`*R$}amVjxSLJ_zBUKSnESi+42UV6O5CA2b;==?)T2WjqkRTz5F9?80DUSd3 zB>maO_j+b__Hm1&O(m!+;O_QjdV2ab-95dt|MTB}oBeI}FSFk?e=D<<*}F@60n_2} z|MqNWc4+@!*#BdDKeSH=cKva4Wo359-k;6x&92xV?aSA@34Z)`ZT8&YJTf?s4e~?# zv|`_1*#A2QW8L1nMs&y}yt@soquIW}cy7Hf%+Aj)&px#O7wy~dtAw{^vpY0sPp$9! z_WE7(e!-x9Gy)o22>LCDBPoyX8O?sNc|tWl!;|mr+w=LTuV$~Z>tD?Fj6XZgjLsXq z;Z_Q9YxdLZ!R*N3>@=L&xA&*^`o%`rZD_kcdui{x_Wg0g{b%;+mBBfjJ+V&@tmUWk z(KYuCgYweGq}L7W{k?sEY%id$+W!~!%g*eb43l+($T<6k%h3r;!CN!jcAMW{8HBG5 z!gHI;_YE{~^=~_~9}H&6b4lvMrvHvX-?#RA*3N0SGP^nZWOjG9X_#ufyG9k^>f%j;R^`GoBRE9!OalXrrB9XaU#K**h(eWiWMGIV8s&$$MnIj^?x}rDBoq!j&17va@cO-Y^{8hHcF@GMU~s z+&1j5ts&o-ok0hnaw_eApZ$FfVSRSXWK+~eLhsDB%z|=tW%il z*8gUI*g!t}b*z_uxj2Up4ep!G{d#uY=5Wg}-Lxyf{fo)!nq9|+0`0ba=G#a1i}1N` zpRXAvR}HJp*`H5(erOOcG%vl=UVXL<%BH<;pS1qST4FO-4BH`&oU;~NCRs>477uyA z${?lCf4`B27bbVe3VfmkQqIb-YoCRM-nR^o>xS=LoBP++nwfuWnB*9Hn;S-tzch2z zOfOo`_nVoP@NUfMqPEdaZST&$G>G?Y&0DisiSFZ887SfXd3RZ71wCkHjcx$vJ;Uw; z`@A~)++J>Lq49MabE7iyCHrmY#mKh}-`^W-AU!hue_-@wCBoLH7+f+8E;f8!wei*( ziDET%c?*2dnUW6g&&FW0GIN>OXrQ)n018z2*nS6xTg__jmzBMd0 zR#4;K>?`Bbw)LpB_iNtks#z0Z_?69O+cXP%TEmWh-fKPKvZ&ELl6q|^Nmh;69-)Xed=PWvi=k9?ZxA#paoi=qC_ZmHg zZew5o_if{_>!BcCHOqO^M!9b=zGJp0bt{MEj_H~XXg zcWhXN@I{bv;wF5*SO;U=FU@)&?d@^#$7(NMm!XhG%&{0ZuIBsATY0 zS)tkb8q9Y=-i?9Fb-fKEZnZ$H}2muj=3zR^M1QW z58(iw{)+LJ2oBvQ$}C}Tnq*<^+uX&DrlZAYVBayC5s%7B5-UoE&^ktQU)a6h<3U@y;U)knql;IqcKjM~SctvRiUVHv+RGI^F`8y_!ywefOA ztE0pgND`d_u9ty{+n_$aNDJNicogKZe$J6pYj3xt!bf+FEJyG1hGmJ+pG8K$)-gIh zTROJS{gPd)y(E+55a6>i9BJ;Vlm;}%qj#tV-l>&BW{EiA*`c*0wo2vO<;*!+m!w#e zgfWuT74I^Gdo~jK$~uwrF0u@%JV##c^~_+~R-)UDN9!w~^Pnpq$_zpmoZ9Pi-8;5* zkNBugt98@4-10&z;AL(JkA$SEp$zGB(dt#r^`~&-Y*iiMC&aoX=&CzH1Np)mJ zp0cjxEZ0wL4%qB9c)-oW1{XX4zVY9!fJgnM9VjVu*H(98SbUOHBZ&Mi^kA7vQ@Uy> zXQd3BWBAOlRle_$WmJA@GIDM^z^KH^vk5h8`9UvM*yzxy9IwcZKDY6onLax0loKT% zh);ob^9xi2>s)i|nAYsc2fcQ^jVYPu90RNbd3RrB_nRCnejY3Kk-cc`a#v#I*@kW7 z>&-&Lh&F0c@3OaPbn(%S8hwg<1H5t{Q(05=4cUKef04<5H2cx0iyS^Q+*S-n_Y`&; zJ)*DgsnodcSxBN)V%?C&x6Q8gVGS*@Xy_;J*g4NFYc&o$w1z)02}G00mLn(3ja>kI znV%Xvk1QYw<%(Ks6aKc=Sf9%s%kITIpgVKvTkn}mmq#Xf49i@fZCe`1?rv9c>09r~ zp2NSRxm4sDrL1V0DevY$9V;k=o(GknP@f;bDp2F_VL`cc4TXpNF57@^zh!@69hL7t zoc-KfC))CeV#VYEI`5h%Ro9$FuhuC6f7+C|)G?-3sTw7YTYQ^Fi{lC{unX8o^nyIO z?*Z-@CE5FdLiO3f=d1I4xHO^9Um45i)UU!L^F1Q;dKs_!Y~WRUHbcJ4I9_$nXVrAk z_wm@3IA|!&UX`!>E}!6A;_R^w(SK-}bKq*PUEQ+L9yeAM-9ZPiu-dI>?-HILw#KXN zDQUbu+Xu&ewO~zQPt$juku{G(wIi=t67l|NK0doK2iEpe`}^0Ey^Q;2ZHYE7*_CC; zgJ7V4+AY~`sF3V_r>iIQ*syoEeLov^;R~D&uQuADcelU(rKQ+HJOspZ{sFXi;mm zVH|&ABYIAs?B*v;Ucb#PzXH$7EGW?-T1{09k)X$5Zr$)XZr1K+hBa-}E}(52mGOTL z%?^MYBY$UoJ~CSNwPr^gIjGG=Ii+orhBTw(+$Lvw#i-}CZ|KE;HS|p-(e3{E6P(Bu zuNqF|=6rY2V@2V2!)CYFv^}(T`01=O@NU&Ctehu#nUTa;FFLvH46VF@wcartT zA>TCmyfVMrZFfq?{*kX44rBs6l17?^LDYuSM!jR>A!SdkFP59Um-}ToMaoK*h@d^s zvD)lS1SIN^E+n%97tyq7~=Wj z4U31-4}R77xMC~G^@2b25@n)BW7R5ns2fVF5n|-L4_I8RNX>BlEO7c?bvf(r)A#F3 zh;+vOL7afqgmo}r4)B1hAv0qdGqVvQftEN{$pCOqKixDBc!F7>wz zzh&r9ow}tyNxpnN6P_35awl8b{v}__YQLu|nQQ46CUdbWX>7mdb|^GDa8Msv{`Od< zMQyjxSU%4+(+bvCVU@4unseDo*99x5K-oI~HTncq+CAd8yuH@?dJp|dAN3ouTWwo0 zB-i~AyKQ+Hg_aVCMyEDVT=7^ox9DXBApS{t&FeldCK~(y#oE6v4(3txSpNNoX*$t< z&Ou;B&19O(JL8hyy)sqL(l`|#&T9n5a?7K`oLB5Fp<(QY@$UaGo9{~n+ZpfhR`d9) zpLcCfJA8$)e0pen^*HL4`6baG{(O;q_pyjp&iHhCK1rL{EA=nOpZmH}ZrM%+Qrjmn|2@=5fxD2XL;L zsZ%pD6J&mf6Ul;~x14Yp>#C<|}LSv(XRD+G*y={X3eKw;iVT?+xzzRay%Yd?~R7 z8_&zhQ_Q`0$5yjZwCwNT>sb%)^I1W^ysu{IZQ*7*%e-x!YP69y3+F#HGFC>Pv@CHx zY9jpugy>)XP8-!GcqMAwJti1w zo3f&m8S&b*k-oQeP7ze!I01wDPeDjw5L5L*NNY8tKYJZsh2=J#Jiss%RTBjqLGkrC zuePhvB(0kaD1psw%T64hWOaw}@e0TqoG*=!oB6uYZ!_u z`T~+D+|H&3eI=DnU9Z&(2r(P-2nY68*4qW7kZ{2wqN&5;m%bULb#W<#$bQ~xxZMXM zuVM=*Wz;=Z{v2ML-zB^;e9tSy0=KPfJ>ND>mmi(dna|=|UbU4%ioLmO28C>LAGM-l zDqt{98av&wm2DUX)fwF|wnxEGT~fd)@etR>;e++5!vdf2uvAA=hXsAET6UWKySM`= ztyVg`fG`xrdPNr;dTCJBCu2!s*a3 zQWYQ9_-oHaeuaAFJGaU#D|fBdaKc+EYb%NJy;qG#y9Xz`#Z)R$rLlU_(|3pQ=lmWp zKIJgenE#xuLhQsJoV4+Z!&S=`q_{a%HJ33I6j$)Of+w$QH1R7&6Rv&Sl5c>Gz;ksA zp`OFL2GTxkXKl}|o#Fhn(Bt~v#<<+5@O13+{mvY&S_)t7E#|F)OKR7)DuN{6+cirv z%Dw39-)Jr2l!koIbd2PPm#OZhR!k97ITo>b88>zDFz?H(G_x`CqWSsVPVB$yN(xC- z?2-;iU-SlEDItQg44%dQkvJwTPx0@zL6_!KT7-|Tlj7habS|SA_5J7AQgTS$wp6%{ zp-kI0s`nK8I7VX2cuwOjpORzdFAbk=trb&_n}>FW^Va1G>(Z?@W9HG#M`>-B?rUYh zb~6{w2lBclYHrf3jUXvo$a{TW(vRVom^xeG zaQgYx@~VqKmp4#b6SS^%t;*%t=bK_Dx6szXF!!tq)`e>nf409bwYTY&KE}m(Q zi|9~I$`|1rK4Iy_(_j0!-1Evlyq{P*MCY8oZSIiUX>;ea^X=nYA1&%T9KL3#egTap zGw1h!d)AX{Vf7c`T4|e*7GCVd>%Mxy69%GUX(#+#OKK`|i!p|peR$OF&j-hn3W3+E z*)q=fjFUROLc>oB<@C*5E^>TJZE>xM{q&qmE4F*$)-JaXU?@n6T13InbG49WmScTo zcQ?S@+~()rLVLDUNT{}@J(jR((~o`*JIw?S;rPsKY>uCLblZ7WpeMEl@g8SKiav2l z1NnS3=Et6@7${v>vb)xPG)p|gM*B^-;ncaP1 zd_zvT+lP9ndc9|fqa;e!WGt<;ud05z=1S*<7iT1>F% zZ62k4&8^f}?4X}>E8oQ!rXv-I`MqeTp{SyTbg#PHUltYmaf3F28*;zQmvC72T-*EK z8c94ycH@i)epQRHyoR3nuDBqup7)>7;QNN<87b)XtCP zo+10k?~CxXy*nWZ?t;R-_vLPT1%X~EfDWJo!&37-*8c|@ZM4&PA*JHKCC)b-pC z6~HOR;(=z>-aAdH*CikH3Ou`bP{#!Ly028c5KYF8-IWn=c!DNbYRiCH)MP+<*;mEV z4cTXaA9~*Yxc@dXB0BesO7RbpY6WFb`r4;aP>!K^#C5-sp@u~gZ#zZ#AG4Y6&`~1oIq^E*v)bZ^di=p<+7OYath#1<{ zF23r-`MvDv?>Di?4|51WLoUOv?Aw*cjV$r(6V8Y8vn$eb_e42*m-D1QQ7U;%sKcEF zwf5rvk-<+_gSPc=MUN0O?pY{8r~RM&F&p98RIX+8GDjACcmZoDqBRq?*6l zAM;U064-i)23>P1W8f68y1kI}-!b0kjHXA1UC6(4li6yDZx%cdkR>D9SZ`)NrJwoHe73%-oE7y7#cZaKWItyI`(=tlte2(-!7MD5a zS9uQ${k0a=u_^aU=`q~vv*sLz^uAm5<6V~4^We8kV%t^uHEiB9+LlzUW#z`=Cu=U; zO1$EER5fhsoB}_8PKYo~d8Ltt-tj#4j8a}%3It9>@;k+b`ugwBOrl;I1mudS9u583 ztQk))xNm>ECM9?}T`#;I_h~qHk9!B>OiQ;+FB-2%RuI33cE<)Ay`;Bi>+^Ffy2dN7 z3;$h%M-C;&->>@9TFRdO9sKpA25(JeDcF(M6V|(iDNk@yJ)NK0NTxcE%j;v*uQKvY z8-=m_Sz+A20yWT8DC4K+`1-AtD9{hVR;>#^?V4A+qV(ldNh?0e{YpQOHi3(qO7$^eehU)H{j z#!_Ru9Y59$?7g2jyk{-Q{gMI2o~M-??%!%1e`r0hOzeelPKnOBoMM-x_dnaXWOVRo zJ?0oQD__(13}gHvj|<{Sn&TjNE1xw`QcS|X(41e{9)Ark^!0VnDXKg8(`X=`8&`wS zb&VDGzEPQRe`sjLne)N_u9L6@56pgPcnWQ)8pCFJlt>QG_nPAQa_TqceTZuKs6-^g zR3j^oKaS+ZnnJt-wn)UDJ$rA8gbmSeXr9o|?dYRMI@vFnVpXT$KD53lg72CGxaZ!k zdYmq5P%NozdE9zC6h-nYt#I)Q2X6S%jd2=!bw4Z|va zUu1#XaOziT8eVT%zY2Cddj$I|YmTLc+T35tUKcw`a7dDjWKNOJw%;Cd;Px_?1KH5P zyeTR&k@N_wW_X%xgScT&XZt;U*9{pMD^ zI zx_SVKKk1lTw_%+^D*cQkDuL2xqYL6NjJ!qNryjqWgHd=C%ia?}ej-Lp*B{wbuY~DZ z*TGJHXux^dM4H?c;+Z_xTS1?~ z{#Nssbyv`EZ_ja#+jp5l-SCyMym>VV*}FW3_ZkCMAN)67NP%F4C0A_$Pw71{FOOOX zr-PpyM@#(Ecn19#N~p~;;wtK{cA8lzhWcmck42esb(_M~de(Ez^c^l75AGen)o+bL zM-BgT8${)iI5GBpss$CN`*vI2w0*(4)sNiR&|Vg_&$G7lP~`-^#%c0AzotFGn&nij z+Yl9zOeopT)t1yeUB-5dgnG1F*A;NY*IlG0iMaN36(8tKM6~klu=ROFTgTZcTeAvq z%&WuooOV`R_8B8a$MX8qz2U?Z>sI&sx^Qh@cMW4_$@k}U5@fq&{}ov^#YBsFnzx&i zGv#NpEBkDo4e1}Z{i{~s1EY1mig)kG46owKE1#|6USBJU_3dZ=npSbiZ(E-FuMDkl z+70W1(q7@z<8*6VXo1(s#+uu$1u2f;B^cq$N(<5q#Q&|mf+;q*Z*3MgQ`(lFp>=z0 zR?l+hWeSF@aS@j)0%eUGAKz}7C+2nU%KNbU63^|V?iCM!XT40paY~=FwObhhJc-k; z-O3V?&n#uM_8qzPJI$7pBg(UQ+l@ROScN=$DK4vE=64>}GBMy2Ss2>-{aw^Uy)a*l z`%B1D=5v`McXdqt3A?{5&a)W8R5AAh^9}=JcKXSwhV7-&2JEBWcnaoz2Vu(Tp{gmU zRbS=a{OnyWLpk5mZ>i**W$jYR@VU0Won`ILvUaJQph3STe?P^2%x7%v6nhI@;`9a2 zkYLq4i%llLchddN63^|Saby-*1Mmy^&WcQyf>mG&9#i^^$>*G99LGqH+AJgEh(xeo zz&?U@i_h*d>&uG2c{xY!yXQ_v`6u!msb`NTV@hhqyt98p4o?unYn}>`3=h>ff*3d| zM|#@*Z_m#~1~d0cr&`>zm~fdfq4K$l#Dua&p3n6NaVj_Kkyc2zLqCfNwWly;ou^OA z=P?nXa)W1C_Ore6SfB8A--NyLdcGoZ;L5EA=J_Y)k?%XJ$5~cB%^rL1Kc`*SH)wiR z!T%eh!eX!P+`T+AUk#_OuxGxg-&IPS9lmJ39!{n0nJ-%NMMcf=HCV1OWAYKNH`ZHB zbBT}A+LD_Vx$oH>YQ#O`>PvhbQl*;b;fecMjqvzB7=-rCO_8&}yA@as^EG3g{{E>87ocpN z>>BxsQ1(o}*P%e+i0;$&-Jk1_Qd#fr8^4rL((`1)Z&TGt^s9X;VR<~tlVWbzX#uq! z`88zOy?V|TMpJWrQ>0Z|;lAm-G*Tj4jr}flPMC&P?%YFpZYJH@OC`=U;XhwEdT%j diff --git a/Source/Hardware/Prop/Spin/Parallax Serial Terminal Null.spin b/Source/Hardware/Prop/Spin/Parallax Serial Terminal Null.spin index 982e894c86d319b7fd00303abb4c67bef8d280d0..a426486bd17e14b812cd3cf95b60cade2bb9204b 100644 GIT binary patch literal 606 zcmZvZ!ES>v42JKM_6|9wQl4N(=&B;M6QZrO9Rqj}4HA@?l1h8{ktQ(4dW!S;_ixKi zFA+H**GO~TmzpDNo}bbQX7+5Uww;iSpnqCb0we##s`F)W%{9$$2t}=flS5`=j1;Pu zxJV^(YN)9}Eo9Z_ZV>^$qTusJc@+$ zN=8ai2{d7}k*}qDun(mpUrXZ#xDFd};j1hczX%#N`2SwD;G){QzE_*XIMEYQ!I9dE3#VSVXXcbzWMsL;dDIT(pABr#={RsqV=sTA2nL^d3fSzPnm9g?VHId zIwD3l90hgSu4{ZB>zLZaWt;OlYmM(?4d^=7`(Qd~qtEmjSv6?)e4gC#CY09xn30q_ zCf|&)T)iipNp~x)?%An?i+fk3T`d>$L5$1u%KRlJ+6P-n6B`i`JIIZ3U^muQ^?XJ`e6fNDo!O403$gRYCMmi75E25jJ#z4 diff --git a/Source/Hardware/Prop/Spin/Parallax Serial Terminal.spin b/Source/Hardware/Prop/Spin/Parallax Serial Terminal.spin index a525a4be6de09fc6484285ea6379be29e945dfd2..cc9e4be0ab0178b8b2cc5d107c98174a5fa1fc85 100644 GIT binary patch literal 20650 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 PuT_ueUsCUa{ayYK!)rep diff --git a/Source/Hardware/Prop/Spin/PropIO.spin b/Source/Hardware/Prop/Spin/PropIO.spin index 7371302a2d6a911a19b64ce0e09e0069070cca88..8e742296ac6591c15648e8759f7eceab2f3f5e33 100644 GIT binary patch literal 16842 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 literal 32980 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 Rrdg)~9+#N)OjLH#{11kd8kGP5 diff --git a/Source/Hardware/Prop/Spin/PropIO2.spin b/Source/Hardware/Prop/Spin/PropIO2.spin index 984b2c38a85d4054e88a42a05598fb544102dc70..1e21b200f406bb2ab1887d64306982b274c09dbf 100644 GIT binary patch literal 16423 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 z AUjP6A diff --git a/Source/Hardware/Prop/Spin/VGA_1024.spin b/Source/Hardware/Prop/Spin/VGA_1024.spin index 796cc930..516a0940 100644 --- a/Source/Hardware/Prop/Spin/VGA_1024.spin +++ b/Source/Hardware/Prop/Spin/VGA_1024.spin @@ -73,7 +73,7 @@ PUB vidon if (!vga.start(vgabasepin, @screen, @colors, @cursor, @sync)) return false - waitcnt(clkfreq * 1 + cnt) 'wait 1 second for cogs to start + 'waitcnt(clkfreq * 1 + cnt) 'wait 1 second for cogs to start PUB vidoff diff --git a/Source/Hardware/Prop/Spin/VGA_HiRes_Text.spin b/Source/Hardware/Prop/Spin/VGA_HiRes_Text.spin index 5b892316533d01d855cf1bf08be8a9513fc1775b..b5958ea34ab77e11113cfa8adc9ff289c32a7b23 100644 GIT binary patch literal 28019 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 Tiog8bhyLv(@Sph8I)D5h#G}Wy literal 54408 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 4, subtract 4 (new row) - cmpsub font_part, #4 wc ' c=0 for same row, c=1 for new row - if_c add screen_ptr, #2*cols ' if new row, advance screen pointer - if_c add row, #1 ' if new row, increment row counter - djnz fours, #fourline ' another 4-line build/display? - - ' Visible section done, do vertical sync front porch lines - - wrlong longmask,par ' write -1 to refresh indicator - -vf_lines mov x,#vf ' do vertical front porch lines (# set at runtime) - call #blank - - jmp #vsync ' new field, loop to vsync - - ' Subroutine - do blank lines - -blank_vsync xor hvsync,#$101 ' flip vertical sync bits - -blank mov vscl, hx ' do blank pixels - waitvid hvsync, #0 - mov vscl, #hf ' do horizontal front porch pixels - waitvid hvsync, #0 - mov vscl, #hs ' do horizontal sync pixels - waitvid hvsync, #1 - mov vscl, #hb ' do horizontal back porch pixels - waitvid hvsync, #0 - djnz x,#blank ' another line? -blank_ret -blank_vsync_ret - ret - - ' Data - -screen_base long 0 ' set at runtime (3 contiguous longs) -cursor_base long 0 ' set at runtime - -font_base long 0 ' set at runtime -font_part long 0 ' set at runtime - -hx long hp ' visible pixels per scan line -vscl_line long hp + hf + hs + hb ' total number of pixels per scan line -vscl_line2x long (hp + hf + hs + hb) * 2 ' total number of pixels per 2 scan lines -vscl_chr long 1 << 12 + 8 ' 1 clock per pixel and 8 pixels per set -colormask long $FCFC ' mask to isolate R,G,B bits from H,V -longmask long $FFFFFFFF ' all bits set -slowbit long 1 << 25 ' cnt mask for slow cursor blink -fastbit long 1 << 24 ' cnt mask for fast cursor blink -underscore long $FFFF0000 ' underscore cursor pattern -hv long hv_inactive ' -H,-V states -hvsync long hv_inactive ^ $200 ' +/-H,-V states - -bg_clut long %00000011_00000011 ' black - long %00000011_00001011 ' dark blue - long %00000011_00100011 ' dark green - long %00000011_00101011 ' dark cyan - long %00000011_10000011 ' dark red - long %00000011_10001011 ' dark magenta - long %00000011_10100011 ' brown - long %00000011_10101011 ' light gray - long %00000011_01010111 ' dark gray - long %00000011_00001111 ' light blue - long %00000011_00110011 ' light green - long %00000011_00111111 ' light cyan - long %00000011_11000011 ' light red - long %00000011_11001111 ' light magenta - long %00000011_11110011 ' light yellow - long %00000011_11111111 ' white - -fg_clut long %00000011_00000011 ' black - long %00000111_00000011 ' dark blue - long %00010011_00000011 ' dark green - long %00010111_00000011 ' dark cyan - long %01000011_00000011 ' dark red - long %01000111_00000011 ' dark magenta - long %01010011_00000011 ' brown - long %10101011_00000011 ' light gray - long %01010111_00000011 ' dark gray - long %00001011_00000011 ' blue - long %00100011_00000011 ' green - long %00101011_00000011 ' cyan - long %10000011_00000011 ' red - long %10001011_00000011 ' magenta - long %10100011_00000011 ' yellow - long %11111111_00000011 ' white - - ' Uninitialized data - -screen_ptr res 1 -font_ptr res 1 - -x res 1 -y res 1 -z res 1 -fg res 1 -bg res 1 - -row res 1 -fours res 1 - - - fit $1f0 - -' 8 x 12 font - characters 0..127 -' -' Each long holds four scan lines of a single character. The longs are arranged into -' groups of 128 which represent all characters (0..127). There are four groups which -' each contain a vertical part of all characters. They are ordered top, middle, and -' bottom. - -font long - long $0082ba00,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 - long $00000000,$6e660000,$66660000,$18181818,$00000000,$00000000,$18181818,$18181818 - long $0000ffff,$00000000,$00000000,$00000000,$00000000,$18181818,$18181818,$18181818 - long $00000000,$18181818,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 - long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 - long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 - long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 - long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 - long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 - long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 - long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 - long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 - long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 - long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 - long $00000000,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 - long $00000000,$6e660000,$66660000,$24242424,$00000000,$00000000,$24242424,$24242424 - long $00ff00ff,$ff000000,$00000000,$00000000,$00000000,$24242424,$24242424,$24242424 - long $00000000,$24242424,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 - long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 - long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 - long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 - long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 - long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 - long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 - long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 - long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 - long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 - long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 - long $82008282,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 - long $187e1818,$0066767e,$00183c24,$1f181818,$1f000000,$f8000000,$f8181818,$ff181818 - long $00000000,$0000ffff,$00000000,$00000000,$00000000,$f8181818,$1f181818,$ff181818 - long $ff000000,$18181818,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 - long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 - long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 - long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 - long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 - long $6a7a6262,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 - long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 - long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 - long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 - long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 - long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 - long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 - long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 - long $00000000,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 - long $187e1818,$0066767e,$00183c24,$20272424,$203f0000,$04fc0000,$04e42424,$00e72424 - long $00000000,$0000ff00,$ff000000,$00000000,$00000000,$04e42424,$20272424,$00e72424 - long $00ff0000,$24242424,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 - long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 - long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 - long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 - long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 - long $76766666,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 - long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 - long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 - long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 - long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 - long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 - long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 - long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 - long $82820082,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 - long $007e0018,$18181818,$30303078,$0000001f,$1818181f,$181818f8,$000000f8,$181818ff - long $00000000,$00000000,$0000ffff,$ff000000,$00000000,$181818f8,$1818181f,$000000ff - long $181818ff,$18181818,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 - long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 - long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c - long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 - long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 - long $3c62027a,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 - long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 - long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e - long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 - long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 - long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 - long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 - long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 - long $00000000,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 - long $007e0018,$18181818,$30303078,$00003f20,$24242720,$2424e404,$0000fc04,$2424e700 - long $00000000,$00000000,$0000ff00,$00ff0000,$00000000,$2424e404,$24242720,$0000ff00 - long $2424e700,$24242424,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 - long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 - long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c - long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 - long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 - long $3c660676,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 - long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 - long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e - long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 - long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 - long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 - long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 - long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 - long $00ba8200,$00000000,$00002a55,$00000030,$00000018,$00000058,$00000018,$00000000 - long $00000000,$00000078,$00000030,$00000000,$18181818,$18181818,$00000000,$18181818 - long $00000000,$00000000,$00000000,$000000ff,$ffff0000,$18181818,$18181818,$00000000 - long $18181818,$18181818,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$0000000c,$00000000,$00000018,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000018,$0000000c,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$000000fe - long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00003c66 - long $00000000,$00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000606,$00006060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 - long $00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000,$aa55aa55 - long $ff000000,$ff000000,$ff002a55,$ff000030,$ff000018,$ff000058,$ff000018,$ff000000 - long $ff000000,$ff000078,$ff000030,$00000000,$24242424,$24242424,$00000000,$24242424 - long $00000000,$00000000,$00000000,$000000ff,$ff00ff00,$24242424,$24242424,$00000000 - long $24242424,$24242424,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff00000c,$ff000000,$ff000018,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000018,$ff00000c,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff0000fe - long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff003c66 - long $ff000000,$ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000606,$ff006060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 - long $ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff55aa55 - - -{{ -+------------------------------------------------------------------------------------------------------------------------------+ -| TERMS OF USE: Parallax Object Exchange 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. | -+------------------------------------------------------------------------------------------------------------------------------+ -}} +''*************************************** +''* VGA High-Res Text Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** +'' +'' This object generates a 640x480 VGA signal which contains 80 columns x 30 +'' rows of 8x16 characters. Each character can have a unique forground/background +'' color combination and each character can be inversed and high-lighted. +'' There are also two cursors which can be independently controlled (ie. mouse +'' and keyboard). A sync indicator signals each time the screen is refreshed +'' (you may ignore). +'' +'' You must provide buffers for the screen, cursors, and sync. Once started, +'' all interfacing is done via memory. To this object, all buffers are +'' read-only, with the exception of the sync indicator which gets written with +'' -1. You may freely write all buffers to affect screen appearance. Have fun! +'' + +CON + +' 640 x 480 @ 69Hz settings: 80 x 30 characters + + hp = 640 ' horizontal pixels + vp = 480 ' vertical pixels + hf = 24 ' horizontal front porch pixels + hs = 40 ' horizontal sync pixels + hb = 128 ' horizontal back porch pixels + vf = 20 ' vertical front porch lines + vs = 3 ' vertical sync lines + vb = 17 ' vertical back porch lines + hn = 1 ' horizontal normal sync state (0|1) + vn = 1 ' vertical normal sync state (0|1) + pr = 30 ' pixel rate in MHz at 80MHz system clock (5MHz granularity) + +' columns and rows + + cols = hp / 8 + rows = vp / 16 + + +VAR long cog[2] + +PUB start(BasePin, ScreenPtr, CursorPtr, SyncPtr) : okay | i, j + +'' Start VGA driver - starts two COGs +'' returns false if two COGs not available +'' +'' BasePin = VGA starting pin (0, 8, 16, 24, etc.) +'' +'' ScreenPtr = Pointer to 80x30 words containing Latin-1 codes and colors for +'' each of the 80x30 screen characters. The lower byte of the word +'' contains the Latin-1 code to display. The upper byte contains +'' the foreground colour in bits 11..8 and the background colour in +'' bits 15..12. +'' +'' screen word example: %00011111_01000001 = "A", white on blue +'' +'' CursorPtr = Pointer to 6 bytes which control the cursors: +'' +'' bytes 0,1,2: X, Y, and MODE of cursor 0 +'' bytes 3,4,5: X, Y, and MODE of cursor 1 +'' +'' X and Y are in terms of screen characters +'' (left-to-right, top-to-bottom) +'' +'' MODE uses three bottom bits: +'' +'' %x00 = cursor off +'' %x01 = cursor on +'' %x10 = cursor on, blink slow +'' %x11 = cursor on, blink fast +'' %0xx = cursor is solid block +'' %1xx = cursor is underscore +'' +'' cursor example: 127, 63, %010 = blinking block in lower-right +'' +'' SyncPtr = Pointer to long which gets written with -1 upon each screen +'' refresh. May be used to time writes/scrolls, so that chopiness +'' can be avoided. You must clear it each time if you want to see +'' it re-trigger. + + ' if driver is already running, stop it + stop + + ' implant pin settings + reg_vcfg := $200000FF + (BasePin & %111000) << 6 + i := $FF << (BasePin & %011000) + j := BasePin & %100000 == 0 + reg_dira := i & j + reg_dirb := i & !j + + ' implant CNT value to sync COGs to + sync_cnt := cnt + $10000 + + ' implant pointers + longmove(@screen_base, @ScreenPtr, 2) + font_base := @font + + ' implant unique settings and launch first COG + vf_lines.byte := vf + vb_lines.byte := vb + font_part := 1 + cog[1] := cognew(@d0, SyncPtr) + 1 + + ' allow time for first COG to launch + waitcnt($2000 + cnt) + + ' differentiate settings and launch second COG + vf_lines.byte := vf+4 + vb_lines.byte := vb-4 + font_part := 0 + cog[0] := cognew(@d0, SyncPtr) + 1 + + ' if both COGs launched, return true + if cog[0] and cog[1] + 'return true + return 0 + + ' else, stop any launched COG and return false + stop + + +PUB stop | i + +'' Stop VGA driver - frees two COGs + + repeat i from 0 to 1 + if cog[i] + cogstop(cog[i]~ - 1) + + +CON + + #1, scanbuff[80], colorbuff[80], scancode[2*80-1+3], maincode 'enumerate COG RAM usage + + main_size = $1F0 - maincode 'size of main program + + hv_inactive = (hn << 1 + vn) * $0101 'H,V inactive states + + +DAT + +'***************************************************** +'* Assembly language VGA high-resolution text driver * +'***************************************************** + +' This program runs concurrently in two different COGs. +' +' Each COG's program has different values implanted for front-porch lines and +' back-porch lines which surround the vertical sync pulse lines. This allows +' timed interleaving of their active display signals during the visible portion +' of the field scan. Also, they are differentiated so that one COG displays +' even four-line groups while the other COG displays odd four-line groups. +' +' These COGs are launched in the PUB 'start' and are programmed to synchronize +' their PLL-driven video circuits so that they can alternately prepare sets of +' four scan lines and then display them. The COG-to-COG switchover is seemless +' due to two things: exact synchronization of the two video circuits and the +' fact that all COGs' driven output states get OR'd together, allowing one COG +' to output lows during its preparatory state while the other COG effectively +' drives the pins to create the visible and sync portions of its scan lines. +' During non-visible scan lines, both COGs output together in unison. +' +' COG RAM usage: $000 = d0 - used to inc destination fields for indirection +' $001-$050 = scanbuff - longs which hold 4 scan lines +' $051-$010 = colorbuff - longs which hold colors for 80 characters +' $0a1-$142 = scancode - stacked WAITVID/SHR for fast display +' $143-$1EF = maincode - main program loop which drives display + + org 0 ' set origin to $000 for start of program + +d0 long 1 << 9 ' d0 always resides here at $000, executes as NOP + + +' Initialization code and data - after execution, space gets reused as scanbuff + + ' Move main program into maincode area + +:move mov $1EF, main_begin + main_size - 1 + sub :move,d0s0 ' (do reverse move to avoid overwrite) + djnz main_ctr,#:move + + ' Build scanbuff display routine into scancode + +:waitvid mov scancode+0, i0 ' org scancode +:shr mov scancode+1, i1 ' waitvid colorbuff+0, scanbuff+0 + add :waitvid, d1 ' shr scanbuff+0,#8 + add :shr, d1 ' waitvid colorbuff+1, scanbuff+1 + add i0, d0s0 ' shr scanbuff+1,#8 + add i1, d0 ' ... + djnz scan_ctr, #:waitvid ' waitvid colorbuff+cols-1, scanbuff+cols-1 + + mov scancode+cols*2-1, i2 ' mov vscl,#hf + mov scancode+cols*2+0, i3 ' waitvid hvsync,#0 + mov scancode+cols*2+1, i4 ' jmp #scanret + + ' Init I/O registers and sync COGs' video circuits + + mov dira, reg_dira ' set pin directions + mov dirb, reg_dirb + movi frqa, #(pr / 5) << 2 ' set pixel rate + mov vcfg, reg_vcfg ' set video configuration + mov vscl, #1 ' set video to reload on every pixel + waitcnt sync_cnt, colormask ' wait for start value in cnt, add ~1ms + movi ctra, #%00001_110 ' COGs in sync! enable PLLs now - NCOs locked! + waitcnt sync_cnt, #0 ' wait ~1ms for PLLs to stabilize - PLLs locked! + mov vscl, #100 ' insure initial WAITVIDs lock cleanly + + ' Jump to main loop + + jmp #vsync ' jump to vsync - WAITVIDs will now be locked! + + ' Data + +d0s0 long 1 << 9 + 1 +d1 long 1 << 10 +main_ctr long main_size +scan_ctr long cols + +i0 waitvid colorbuff+0, scanbuff+0 +i1 shr scanbuff+0, #8 +i2 mov vscl, #hf +i3 waitvid hvsync, #0 +i4 jmp #scanret + +reg_dira long 0 ' set at runtime +reg_dirb long 0 ' set at runtime +reg_vcfg long 0 ' set at runtime +sync_cnt long 0 ' set at runtime + + ' Directives + + fit scancode ' make sure initialization code and data fit +main_begin org maincode ' main code follows (gets moved into maincode) + + +' Main loop, display field - each COG alternately builds and displays four scan lines + +vsync mov x, #vs ' do vertical sync lines + call #blank_vsync + +vb_lines mov x, #vb ' do vertical back porch lines (# set at runtime) + call #blank_vsync + + mov screen_ptr, screen_base ' reset screen pointer to upper-left character + mov row, #0 ' reset row counter for cursor insertion + mov fours, #rows * 4 / 2 ' set number of 4-line builds for whole screen + + ' Build four scan lines into scanbuff + +fourline mov font_ptr, font_part ' get address of appropriate font section + shl font_ptr, #8+2 + add font_ptr, font_base + + movd :pixa, #scanbuff-1 ' reset scanbuff address (pre-decremented) + movd :cola, #colorbuff-1 ' reset colorbuff address (pre-decremented) + movd :colb, #colorbuff-1 + + mov y, #2 ' must build scanbuff in two sections because + mov vscl, vscl_line2x ' ..pixel counter is limited to twelve bits + +:halfrow waitvid underscore, #0 ' output lows to let other COG drive VGA pins + mov x, #cols/2 ' ..for 2 scan lines, ready for half a row + +:column rdword z, screen_ptr ' get character and colors from screen memory + mov bg, z + and z, #$ff ' mask character code + shl z, #2 ' * 4 + add z, font_ptr ' add font section address to point to 8*4 pixels + add :pixa, d0 ' increment scanbuff destination addresses + add screen_ptr, #2 ' increment screen memory address +:pixa rdlong scanbuff, z ' read pixel long (8*4) into scanbuff + + ror bg, #12 ' background color in bits 3..0 + mov fg, bg ' foreground color in bits 31..28 + shr fg, #28 ' bits 3..0 + add fg, #fg_clut ' + offset to foreground CLUT + movs :cola, fg + add :cola, d0 + add bg, #bg_clut ' + offset to background CLUT + movs :colb, bg + add :colb, d0 +:cola mov colorbuff, 0-0 +:colb or colorbuff, 0-0 + + djnz x, #:column ' another character in this half-row? + + djnz y, #:halfrow ' loop to do 2nd half-row, time for 2nd WAITVID + + sub screen_ptr, #2*cols ' back up to start of same row in screen memory + + ' Insert cursors into scanbuff + + mov z, #2 ' ready for two cursors + +:cursor rdbyte x, cursor_base ' x in range? + add cursor_base, #1 + cmp x, #cols wc + + rdbyte y, cursor_base ' y match? + add cursor_base, #1 + cmp y, row wz + + rdbyte y, cursor_base ' get cursor mode + add cursor_base, #1 + + if_nc_or_nz jmp #:nocursor ' if cursor not in scanbuff, no cursor + + add x, #scanbuff ' cursor in scanbuff, set scanbuff address + movd :xor, x + + test y, #%010 wc ' get mode bits into flags + test y, #%001 wz + if_nc_and_z jmp #:nocursor ' if cursor disabled, no cursor + + if_c_and_z test slowbit, cnt wc ' if blink mode, get blink state + if_c_and_nz test fastbit, cnt wc + + test y, #%100 wz ' get box or underscore cursor piece + if_z mov x, longmask + if_nz mov x, underscore + if_nz cmp font_part, #3 wz ' if underscore, must be last font section + +:xor if_nc_and_z xor scanbuff, x ' conditionally xor cursor into scanbuff + +:nocursor djnz z, #:cursor ' second cursor? + + sub cursor_base, #3*2 ' restore cursor base + + ' Display four scan lines from scanbuff + + mov y, #4 ' ready for four scan lines + +scanline mov vscl, vscl_chr ' set pixel rate for characters + jmp #scancode ' jump to scanbuff display routine in scancode +scanret mov vscl, #hs ' do horizontal sync pixels + waitvid hvsync, #1 ' #1 makes hsync active + mov vscl, #hb ' do horizontal back porch pixels + waitvid hvsync, #0 ' #0 makes hsync inactive + shr scanbuff+cols-1, #8 ' shift last column's pixels right by 8 + djnz y, #scanline ' another scan line? + + ' Next group of four scan lines + + add font_part, #2 ' if font_part + 2 => 4, subtract 4 (new row) + cmpsub font_part, #4 wc ' c=0 for same row, c=1 for new row + if_c add screen_ptr, #2*cols ' if new row, advance screen pointer + if_c add row, #1 ' if new row, increment row counter + djnz fours, #fourline ' another 4-line build/display? + + ' Visible section done, do vertical sync front porch lines + + wrlong longmask,par ' write -1 to refresh indicator + +vf_lines mov x,#vf ' do vertical front porch lines (# set at runtime) + call #blank + + jmp #vsync ' new field, loop to vsync + + ' Subroutine - do blank lines + +blank_vsync xor hvsync,#$101 ' flip vertical sync bits + +blank mov vscl, hx ' do blank pixels + waitvid hvsync, #0 + mov vscl, #hf ' do horizontal front porch pixels + waitvid hvsync, #0 + mov vscl, #hs ' do horizontal sync pixels + waitvid hvsync, #1 + mov vscl, #hb ' do horizontal back porch pixels + waitvid hvsync, #0 + djnz x,#blank ' another line? +blank_ret +blank_vsync_ret + ret + + ' Data + +screen_base long 0 ' set at runtime (3 contiguous longs) +cursor_base long 0 ' set at runtime + +font_base long 0 ' set at runtime +font_part long 0 ' set at runtime + +hx long hp ' visible pixels per scan line +vscl_line long hp + hf + hs + hb ' total number of pixels per scan line +vscl_line2x long (hp + hf + hs + hb) * 2 ' total number of pixels per 2 scan lines +vscl_chr long 1 << 12 + 8 ' 1 clock per pixel and 8 pixels per set +colormask long $FCFC ' mask to isolate R,G,B bits from H,V +longmask long $FFFFFFFF ' all bits set +slowbit long 1 << 25 ' cnt mask for slow cursor blink +fastbit long 1 << 24 ' cnt mask for fast cursor blink +underscore long $FFFF0000 ' underscore cursor pattern +hv long hv_inactive ' -H,-V states +hvsync long hv_inactive ^ $200 ' +/-H,-V states + +bg_clut long %00000011_00000011 ' black + long %00000011_00001011 ' dark blue + long %00000011_00100011 ' dark green + long %00000011_00101011 ' dark cyan + long %00000011_10000011 ' dark red + long %00000011_10001011 ' dark magenta + long %00000011_10100011 ' brown + long %00000011_10101011 ' light gray + long %00000011_01010111 ' dark gray + long %00000011_00001111 ' light blue + long %00000011_00110011 ' light green + long %00000011_00111111 ' light cyan + long %00000011_11000011 ' light red + long %00000011_11001111 ' light magenta + long %00000011_11110011 ' light yellow + long %00000011_11111111 ' white + +fg_clut long %00000011_00000011 ' black + long %00000111_00000011 ' dark blue + long %00010011_00000011 ' dark green + long %00010111_00000011 ' dark cyan + long %01000011_00000011 ' dark red + long %01000111_00000011 ' dark magenta + long %01010011_00000011 ' brown + long %10101011_00000011 ' light gray + long %01010111_00000011 ' dark gray + long %00001011_00000011 ' blue + long %00100011_00000011 ' green + long %00101011_00000011 ' cyan + long %10000011_00000011 ' red + long %10001011_00000011 ' magenta + long %10100011_00000011 ' yellow + long %11111111_00000011 ' white + + ' Uninitialized data + +screen_ptr res 1 +font_ptr res 1 + +x res 1 +y res 1 +z res 1 +fg res 1 +bg res 1 + +row res 1 +fours res 1 + + + fit $1f0 + +' 8 x 12 font - characters 0..127 +' +' Each long holds four scan lines of a single character. The longs are arranged into +' groups of 128 which represent all characters (0..127). There are four groups which +' each contain a vertical part of all characters. They are ordered top, middle, and +' bottom. + +font long + long $0082ba00,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 + long $00000000,$6e660000,$66660000,$18181818,$00000000,$00000000,$18181818,$18181818 + long $0000ffff,$00000000,$00000000,$00000000,$00000000,$18181818,$18181818,$18181818 + long $00000000,$18181818,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 + long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 + long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 + long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 + long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 + long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 + long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 + long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 + long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 + long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 + long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 + long $00000000,$00000000,$2a552a00,$36360000,$061e0000,$061c0000,$06060000,$3c000000 + long $00000000,$6e660000,$66660000,$24242424,$00000000,$00000000,$24242424,$24242424 + long $00ff00ff,$ff000000,$00000000,$00000000,$00000000,$24242424,$24242424,$24242424 + long $00000000,$24242424,$60000000,$06000000,$00000000,$00000000,$38000000,$00000000 + long $00000000,$18000000,$36000000,$24000000,$18000000,$4e000000,$1c000000,$18000000 + long $30000000,$0c000000,$00000000,$00000000,$00000000,$00000000,$00000000,$60000000 + long $18000000,$18000000,$3c000000,$7e000000,$60000000,$7e000000,$3c000000,$7e000000 + long $3c000000,$3c000000,$00000000,$00000000,$60000000,$00000000,$06000000,$3c000000 + long $3c000000,$3c000000,$3e000000,$3c000000,$3e000000,$7e000000,$7e000000,$3c000000 + long $66000000,$7e000000,$60000000,$46000000,$06000000,$42000000,$66000000,$3c000000 + long $3e000000,$3c000000,$3e000000,$3c000000,$7e000000,$66000000,$66000000,$66000000 + long $42000000,$66000000,$7e000000,$3c000000,$06000000,$3c000000,$18000000,$00000000 + long $180c0000,$00000000,$06000000,$00000000,$60000000,$00000000,$38000000,$00000000 + long $06000000,$18000000,$60000000,$06000000,$1c000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$38000000,$18000000,$1c000000,$4c000000,$aa55aa55 + long $82008282,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 + long $187e1818,$0066767e,$00183c24,$1f181818,$1f000000,$f8000000,$f8181818,$ff181818 + long $00000000,$0000ffff,$00000000,$00000000,$00000000,$f8181818,$1f181818,$ff181818 + long $ff000000,$18181818,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 + long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 + long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 + long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 + long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 + long $6a7a6262,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 + long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 + long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 + long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 + long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 + long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 + long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 + long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 + long $00000000,$3c180000,$2a552a55,$0036363e,$0006060e,$001c0606,$001e0606,$003c6666 + long $187e1818,$0066767e,$00183c24,$20272424,$203f0000,$04fc0000,$04e42424,$00e72424 + long $00000000,$0000ff00,$ff000000,$00000000,$00000000,$04e42424,$20272424,$00e72424 + long $00ff0000,$24242424,$0c060c30,$3060300c,$667e0000,$187e3030,$3e0c0c6c,$18180000 + long $00000000,$18181818,$00003636,$247e7e24,$3c1a5a3c,$18302e6a,$1c363636,$00181818 + long $0c0c1818,$30301818,$7e182400,$7e181800,$00000000,$00000000,$00000000,$18303060 + long $66666624,$18181a1c,$38606666,$3c183060,$666c7870,$663e0606,$3e060666,$30306060 + long $3c666666,$7c666666,$183c1800,$183c1800,$060c1830,$007e0000,$6030180c,$38606666 + long $76766666,$7e666666,$3e666666,$06060666,$66666666,$3e060606,$3e060606,$76060666 + long $7e666666,$18181818,$60606060,$0e1e3666,$06060606,$667e7e66,$7e6e6e66,$66666666 + long $3e666666,$66666666,$3e666666,$3c060666,$18181818,$66666666,$24246666,$66666666 + long $183c2466,$183c3c66,$18306060,$0c0c0c0c,$180c0c06,$30303030,$0042663c,$00000000 + long $00000030,$603c0000,$663e0606,$663c0000,$667c6060,$663c0000,$1e0c0c6c,$665c0000 + long $663e0606,$181c0018,$60600060,$36660606,$18181818,$fe6a0000,$663e0000,$663c0000 + long $663e0000,$667c0000,$663e0000,$663c0000,$0c3e0c0c,$66660000,$66660000,$66660000 + long $66660000,$66660000,$607e0000,$0c180c0c,$18181818,$30183030,$0000327e,$aa55aa55 + long $82820082,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 + long $007e0018,$18181818,$30303078,$0000001f,$1818181f,$181818f8,$000000f8,$181818ff + long $00000000,$00000000,$0000ffff,$ff000000,$00000000,$181818f8,$1818181f,$000000ff + long $181818ff,$18181818,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 + long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 + long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c + long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 + long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 + long $3c62027a,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 + long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 + long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e + long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 + long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 + long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 + long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 + long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 + long $00000000,$00183c7e,$2a552a55,$30303078,$18381878,$58385838,$18381878,$00000000 + long $007e0018,$18181818,$30303078,$00003f20,$24242720,$2424e404,$0000fc04,$2424e700 + long $00000000,$00000000,$0000ff00,$00ff0000,$00000000,$2424e404,$24242720,$0000ff00 + long $2424e700,$24242424,$7e006030,$7e00060c,$66666666,$0c0c7e18,$3a6c0c0c,$00000000 + long $00000000,$18180018,$00000000,$24247e7e,$183c5a58,$7256740c,$5c367656,$00000000 + long $3018180c,$0c181830,$0024187e,$0018187e,$18383800,$0000007e,$3c180000,$06060c0c + long $18246666,$7e181818,$7e06060c,$3c666060,$60607e66,$3c666060,$3c666666,$0c0c1818 + long $3c666666,$3c666060,$3c180000,$18383800,$6030180c,$00007e00,$060c1830,$18180018 + long $3c660676,$66666666,$3e666666,$3c660606,$3e666666,$7e060606,$06060606,$7c666666 + long $66666666,$7e181818,$3c666060,$4666361e,$7e060606,$66666666,$66667676,$3c666666 + long $06060606,$3c766e66,$4666361e,$3c666060,$18181818,$3c666666,$1818183c,$42667e7e + long $4266243c,$18181818,$7e06060c,$3c0c0c0c,$60603030,$3c303030,$00000000,$fe000000 + long $00000000,$7c66667c,$3e666666,$3c660606,$7c666666,$3c66067e,$0c0c0c0c,$3c063c66 + long $66666666,$7e181818,$60606060,$66361e1e,$7e181818,$c6c6d6d6,$66666666,$3c666666 + long $063e6666,$607c6666,$06060606,$3c66300c,$386c0c0c,$7c666666,$183c3c66,$247e7e66 + long $66663c3c,$607c6666,$7e060c30,$380c0c18,$18181818,$1c303018,$00000000,$aa55aa55 + long $00ba8200,$00000000,$00002a55,$00000030,$00000018,$00000058,$00000018,$00000000 + long $00000000,$00000078,$00000030,$00000000,$18181818,$18181818,$00000000,$18181818 + long $00000000,$00000000,$00000000,$000000ff,$ffff0000,$18181818,$18181818,$00000000 + long $18181818,$18181818,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$0000000c,$00000000,$00000018,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000018,$0000000c,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$000000fe + long $00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$00003c66 + long $00000000,$00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000606,$00006060,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000 + long $00000000,$00003c66,$00000000,$00000000,$00000000,$00000000,$00000000,$aa55aa55 + long $ff000000,$ff000000,$ff002a55,$ff000030,$ff000018,$ff000058,$ff000018,$ff000000 + long $ff000000,$ff000078,$ff000030,$00000000,$24242424,$24242424,$00000000,$24242424 + long $00000000,$00000000,$00000000,$000000ff,$ff00ff00,$24242424,$24242424,$00000000 + long $24242424,$24242424,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000000,$ff000000,$ff000000,$ff00000c,$ff000000,$ff000018,$ff000000 + long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000000,$ff000018,$ff00000c,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff0000fe + long $ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff003c66 + long $ff000000,$ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000606,$ff006060,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000 + long $ff000000,$ff003c66,$ff000000,$ff000000,$ff000000,$ff000000,$ff000000,$ff55aa55 + + +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: Parallax Object Exchange 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. | ++------------------------------------------------------------------------------------------------------------------------------+ +}}