Didn't he publish the source in an earlier message in this thread? I think we already know what he came up with. :-)
Exactly! I read every word Chip wrote, four times over. I also copied the monitor code and examined every line carefully. I'm totally excited about the monitor in ROM, for all the reasons Chip has given. I've had enough of fancy chips that require a 2GB IDE and a $500 programming pod...just to squeeze out "Hello World." This one feature gives the Prop2 a giant leap forward in being able to host its own development system.
Exactly! I read every word Chip wrote, four times over. I also copied the monitor code and examined every line carefully. I'm totally excited about the monitor in ROM, for all the reasons Chip has given. I've had enough of fancy chips that require a 2GB IDE and a $500 programming pod...just to squeeze out "Hello World." This one feature gives the Prop2 a giant leap forward in being able to host its own development system.
I don't understand. A monitor is not a development system. You'll still need a tool on the host to compile or assemble code and download it into the P2 chip. This is really no different from the way P1 works. I guess you could use the monitor as a "development environment" if you like entering your code in hex. Is that what you mean?
One could do what Sun Microsystems did with their workstation. Allow users to boot up into a Forth system to run diagnostics and such. But I don't think that would be appropriate for the P2 since it has no flash and is just a micro controller. There are plenty of engineers who know how work with such chips using C and since it has not JTAG port, one doesn't have to worry about a expensive program dongle.
It is more universally accessible than the binary/HMAC-signed downloader because it sends and receives only standard ASCII characters $20..$7E (space.."~").
Some programming languages, serial interfaces, and OS's have issues with sending and receiving full binary ($00..$FF). For this reason, you might have to jump through some hoops to get the more-efficient binary downloader working on a given host system. The monitor, on the other hand, can talk to anything that speaks serial, without concern over non-ASCII characters. It is so simple that it can't NOT work on any host machine that has a serial port. Plus, it doesn't force an ordered protocol, but is conversational in operation. I've been using the Parallax Serial Terminal program to talk to it as well as PUTTY, which is free on the 'net and very tidy.
My thinking might be a little anachronistic, but I've seen many host-level systems which are big on brains and storage, but for which the serial interfaces were fleeting afterthoughts, and full binary can trigger unwanted events. The monitor will play politely and offer no offense to any host.
The reason I put a help menu in the monitor was so that you could quickly get command syntax without having to refer to any documents. You might launch the monitor from within an app you want to debug and you'll need to search memory for a string of data to get your bearings. The help menu will be handy then.
Here is the ROM now:
=== Propeller II Monitor ===
>0.e7f
00000- 50 72 6F 70 32 2E 30 20 00 20 7C 0C 03 D0 7C 0C 'Prop2.0 . |...|.'
00010- 45 FE C1 0D E3 B6 FC 0C 01 C2 7C 0C 01 C2 7C 0D 'E.........|...|.'
00020- 01 C2 FC 80 1F C2 7C 62 01 E0 FC 30 66 0C A8 80 '......|b...0f...'
00030- 01 CA 7C 0C 2A DE FC FA 5B C0 FC 1C 7C FA BC A0 '..|.*...[...|...'
00040- 5B C0 FC 1C 7C FA BC 80 01 FA FC 28 FA F0 FC A0 '[...|......(....'
00050- 5B C0 FC 1C 01 C8 7C 62 2A 00 64 1C B2 C8 7C 61 '[.....|b*.d...|a'
00060- 01 C8 FC 34 10 F0 FC F6 02 F1 FC A0 08 F0 7C 86 '...4..........|.'
00070- 52 C8 E8 A0 01 C8 7C 62 25 52 FC 1C DA B4 FC 0C 'R.....|b%R......'
00080- 25 52 FC 1C DF B4 FC 0C 25 52 FC 1C DB B4 FC 0C '%R......%R......'
00090- 25 52 FC 1C B2 C8 7C 61 01 C8 FC 34 17 F0 FC F6 '%R....|a...4....'
000A0- 35 00 7C 1C 0D F6 FC 0C 62 F6 BC 80 63 C6 BC FF '5.|.....b...c...'
000B0- 37 4F FC 0C 00 00 4C 1C 04 F0 FC A0 DB B2 FC 0C '7O....L.........'
000C0- DA B0 FC 0C 44 3E C0 0D DA B2 FC 0C 01 F0 7C E1 '....D>........|.'
000D0- 01 CA CC 27 DC AE FC 0C DB B0 FC 0C DA B0 FC 0C '...'............'
000E0- 2B F0 FC F6 B2 D8 7C 0C 66 F0 BC A0 20 F2 FC A0 '+.....|.f... ...'
000F0- 5B C0 E8 1C D6 AC D4 0D DB B0 D4 0C DA B0 D4 0C '[...............'
00100- 01 F4 FC 34 38 F2 FC F6 C1 F4 7C 08 37 F0 FC F6 '...48.....|.7...'
00110- 40 0E C0 0D 70 00 04 E0 C1 EC 53 08 6B F0 3C 08 '@...p.....S.k.<.'
00120- E0 02 FC 0C 6B D4 3C 0C 67 00 04 E0 03 F0 FC A0 '....k.<.g.......'
00130- 6B EC 13 08 6B F4 BC 0A 49 F4 7C FA 48 F0 FC F6 'k...k...I.|.H...'
00140- 03 1C 7C 0C 42 0E C0 0D E0 00 FC 0C 30 F2 FC 08 '..|.B.......0...'
00150- C1 F4 FC 08 7A F2 28 86 6D D8 28 0C 41 FE FF 0F '....z.(.m.(.A...'
00160- 01 DC 7C 0C C1 F0 7C 08 C1 F0 7C 08 71 E0 BC 6A '..|...|...|.q..j'
00170- 73 E4 A8 6A 08 DC D4 A0 6F DC 3C 0C 25 52 FC 1C 's..j....o.<.%R..'
00180- 0D F8 FC 0C 25 52 FC 1C 0C F8 FC 0C 7D F8 3C 85 '....%R......}.<.'
00190- 00 00 7C 1C 00 02 00 00 C0 C6 2D 00 00 00 00 08 '..|.......-.....'
001A0- 50 00 00 00 00 00 00 03 00 02 00 00 80 16 1E 40 'P..............@'
001B0- 80 0E BE 8F A0 16 00 C0 D0 01 00 00 C0 16 00 00 '................'
001C0- 80 0E 00 00 80 16 00 00 10 07 00 00 5B B4 00 00 '............[...'
001D0- CA E0 FD 0C 46 96 FC 1C 00 9E FE 08 02 9E 7E F8 '....F.........~.'
001E0- B3 9E 7E 0C 4F CB BD A0 02 CA FD 2C 13 CA FD 28 '..~.O......,...('
001F0- 01 CA FD 80 1E 9E FE 28 08 00 7C 0C 10 9E FE F4 '.......(..|.....'
00200- 1D 9E FE F4 21 9E FE F4 00 30 7D 08 02 00 7C 1C '....!....0}...|.'
00210- 35 96 FC 1C 00 9E FE A0 E4 CA 3D E1 C1 9F F2 01 '5.........=.....'
00220- 36 9E FE 6C 4C A6 FC 1C 11 00 54 1C 41 1E C0 0D '6..lL.....T.A...'
00230- 07 CF 15 E0 F6 EF 87 A0 9A EE 93 6C 01 C6 FD A0 '...........l....'
00240- 0E 00 7C 1C C1 9F FE 01 4C A6 FC 1C 1D CA FD F6 '..|.....L.......'
00250- 0E 00 7C 1C 2C C6 7D F8 35 96 FC 1C 40 1E C0 0D '..|.,.}.5...@...'
00260- E7 0E 16 E0 F6 EF 97 A0 54 2E FD 1C 40 0E C0 0D '........T...@...'
00270- FF 0E 16 E0 F6 EF 97 A0 0F 99 FC 54 60 C8 FD A0 '...........T`...'
00280- 35 96 FC 1C FF 00 04 E0 08 CA FD A0 41 06 C0 0D '5...........A...'
00290- F6 9F 86 A0 08 9E FE 24 C1 9F 7E 00 2F CA FD F6 '.......$..~./...'
002A0- 0E 00 7C 1C E4 CC BD A0 03 CC FD 2C 80 9E FE A0 '..|........,....'
002B0- 4C A6 FC 1C E4 9E BE A0 3F 9E FE 60 38 9E 7E 86 'L.......?..`8.~.'
002C0- 00 9E FE A0 38 00 54 1C 04 C8 7D 61 08 CC F1 24 '....8.T...}a...$'
002D0- E6 9E B2 A0 4C A6 FC 1C 3E 00 54 1C 40 0E C0 0D '....L...>.T.@...'
002E0- F7 FE 15 E0 F6 EF 97 A0 40 0E C0 0D 9B EE 15 E0 '........@.......'
002F0- F6 EF 97 A0 00 C6 FD A0 00 C8 FD A0 00 00 7C 1C '..............|.'
00300- 4F 0F 3E 14 01 C8 FD 80 03 C8 7D 62 99 98 A8 80 'O.>.......}b....'
00310- 3F C8 7D 62 07 99 E8 54 54 2E E9 1C 00 00 7C 1C '?.}b...TT.....|.'
00320- 53 5E C0 0D 0F 2F 16 E0 F9 01 0C E0 F6 EF 8B A0 'S^.../..........'
00330- F7 9F 82 A0 0B 9E FE 24 F7 9F 82 6C 12 9E FE 20 '.......$...l... '
00340- 03 EE C3 28 4F EF 83 6C F6 EF 83 80 0E 00 0C E0 '...(O..l........'
00350- F6 9F 82 A0 4F A1 BE A0 02 A0 FE 24 4F A1 BE 6C '....O......$O..l'
00360- 13 A0 FE 20 0A 9E FE 28 50 9F BE 6C 4F EF 83 80 '... ...(P..lO...'
00370- FB 01 0C E0 F6 EF 93 80 40 0E C0 0D F7 8E 16 E0 '........@.......'
00380- F6 EF 97 A0 64 7E C0 0D 07 47 15 E0 4D 9F BE A0 '....d~...G..M...'
00390- 4C 9F BE 6C 4B 9F BE 60 4D 9F BE 6C 4B A1 BE A0 'L..lK..`M..lK...'
003A0- 05 A0 FE 24 4B A1 BE 6C 0E A0 FE 24 4B A1 BE 6C '...$K..l...$K..l'
003B0- 19 A0 FE 20 50 9F BE 80 F7 9F 86 80 F6 9F 86 80 '... P...........'
003C0- 4E 9F BE 80 49 A1 BE A0 48 A1 BE 60 47 A1 BE 68 'N...I...H..`G..h'
003D0- 49 9D BE A0 48 9D BE 68 4E A1 BE 60 47 9D BE A0 'I...H..hN..`G...'
003E0- 0B 9C FE 24 47 9D BE 6C 09 9C FE 24 47 9D BE 6C '...$G..l...$G..l'
003F0- 16 9C FE 20 4E A1 BE 80 4D 9D BE A0 4C 9B BE A0 '... N...M...L...'
00400- 4B 99 BE A0 4A 97 BE A0 49 95 BE A0 48 93 BE A0 'K...J...I...H...'
00410- 47 91 BE A0 4F 97 BE 80 4F 8F BE A0 50 8F BE 80 'G...O...O...P...'
00420- 40 0E C0 0D 47 EF 15 E0 F6 EF 97 80 00 00 7C 1C '@...G.........|.'
00430- 00 00 00 00 00 02 00 00 6A 6A 6A 6A 67 E6 09 6A '........jjjjg..j'
00440- 85 AE 67 BB 72 F3 6E 3C 3A F5 4F A5 7F 52 0E 51 '..g.r.n<:.O..R.Q'
00450- 8C 68 05 9B AB D9 83 1F 19 CD E0 5B 98 2F 8A 42 '.h.........[./.B'
00460- 91 44 37 71 CF FB C0 B5 A5 DB B5 E9 5B C2 56 39 '.D7q........[.V9'
00470- F1 11 F1 59 A4 82 3F 92 D5 5E 1C AB 98 AA 07 D8 '...Y..?..^......'
00480- 01 5B 83 12 BE 85 31 24 C3 7D 0C 55 74 5D BE 72 '.[....1$.}.Ut].r'
00490- FE B1 DE 80 A7 06 DC 9B 74 F1 9B C1 C1 69 9B E4 '........t....i..'
004A0- 86 47 BE EF C6 9D C1 0F CC A1 0C 24 6F 2C E9 2D '.G.........$o,.-'
004B0- AA 84 74 4A DC A9 B0 5C DA 88 F9 76 52 51 3E 98 '..tJ...\...vRQ>.'
004C0- 6D C6 31 A8 C8 27 03 B0 C7 7F 59 BF F3 0B E0 C6 'm.1..'....Y.....'
004D0- 47 91 A7 D5 51 63 CA 06 67 29 29 14 85 0A B7 27 'G...Qc..g))....''
004E0- 38 21 1B 2E FC 6D 2C 4D 13 0D 38 53 54 73 0A 65 '8!...m,M..8STs.e'
004F0- BB 0A 6A 76 2E C9 C2 81 85 2C 72 92 A1 E8 BF A2 '..jv.....,r.....'
00500- 4B 66 1A A8 70 8B 4B C2 A3 51 6C C7 19 E8 92 D1 'Kf..p.K..Ql.....'
00510- 24 06 99 D6 85 35 0E F4 70 A0 6A 10 16 C1 A4 19 '$....5..p.j.....'
00520- 08 6C 37 1E 4C 77 48 27 B5 BC B0 34 B3 0C 1C 39 '.l7.LwH'...4...9'
00530- 4A AA D8 4E 4F CA 9C 5B F3 6F 2E 68 EE 82 8F 74 'J..NO..[.o.h...t'
00540- 6F 63 A5 78 14 78 C8 84 08 02 C7 8C FA FF BE 90 'oc.x.x..........'
00550- EB 6C 50 A4 F7 A3 F9 BE F2 78 71 C6 12 00 2A 59 '.lP......xq...*Y'
00560- 2B 57 2C 4E 32 2E 3B 2F 55 3A A1 4D AD 4C AE 48 '+W,N2.;/U:.M.L.H'
00570- AF 54 B0 5A B1 52 9E 51 BD 3F 00 38 00 38 20 24 '.T.Z.R.Q.?.8.8 $'
00580- 2E 3C 2F 53 3A 82 40 8F 2A 96 2B 9F 2D AD 4C AE '.</S:.@.*.+.-.L.'
00590- 48 AF 54 B0 5A B1 52 80 23 B6 7C BB 5C 00 39 00 'H.T.Z.R.#.|.\.9.'
005A0- 39 20 3D 2F 51 3A 5F 3E 5F 3C 77 5E 00 0D 0D 3D '9 =/Q:_>_<w^...='
005B0- 3D 3D 20 50 72 6F 70 65 6C 6C 65 72 20 49 49 20 '== Propeller II '
005C0- 4D 6F 6E 69 74 6F 72 20 3D 3D 3D 0D 0D 00 3F 20 'Monitor ===...? '
005D0- 2D 20 48 65 6C 70 0D 07 00 48 69 74 20 53 50 41 '- Help...Hit SPA'
005E0- 43 45 00 20 20 27 00 27 0D 00 20 2D 0D 80 7B 61 'CE. '.'.. -..{a'
005F0- 64 72 7B 2E 61 64 72 7D 7D 80 7B 64 61 74 7B 20 'dr{.adr}}.{dat{ '
00600- 64 61 74 7D 7D 80 61 64 72 80 0D 7E 48 55 42 8E 'dat}}.adr..~HUB.'
00610- 92 60 56 69 65 77 0D 92 2F 9E 60 53 65 61 72 63 '.`View../.`Searc'
00620- 68 0D 92 3A 9E 60 45 6E 74 65 72 0D AA 2E AA 5B 'h..:.`Enter....['
00630- 3C 2F 3E 5D AA 60 4D 6F 76 65 0D AA 2E AA 5E 60 '</>].`Move....^`'
00640- 43 68 65 63 6B 73 75 6D 0D AA 40 60 57 61 74 63 'Checksum..@`Watc'
00650- 68 0D 5B 59 2F 57 2F 4E 5D 60 42 79 74 65 2F 77 'h.[Y/W/N]`Byte/w'
00660- 6F 72 64 2F 6C 6F 6E 67 0D 7E 43 4F 47 53 8E 63 'ord/long.~COGS.c'
00670- 6F 67 2B AA 7B 2B AA 7D 60 53 74 61 72 74 0D 63 'og+.{+.}`Start.c'
00680- 6F 67 2D 60 53 74 6F 70 0D 4D 60 4D 61 70 0D 7E 'og-`Stop.M`Map.~'
00690- 50 49 4E 53 8E 7B 70 69 6E 7D 5B 48 2F 4C 2F 54 'PINS.{pin}[H/L/T'
006A0- 2F 5A 2F 52 5D 60 48 69 67 68 2F 6C 6F 77 2F 74 '/Z/R]`High/low/t'
006B0- 6F 67 67 6C 65 2F 6F 66 66 2F 72 65 61 64 0D 70 'oggle/off/read.p'
006C0- 69 6E 23 60 57 61 74 63 68 0D 70 69 6E 7C 63 66 'in#`Watch.pin|cf'
006D0- 67 60 43 6F 6E 66 69 67 75 72 65 0D 64 61 74 5C 'g`Configure.dat\'
006E0- 60 53 65 74 20 44 41 43 73 0D 7E 4D 49 53 43 8E '`Set DACs.~MISC.'
006F0- 64 61 74 2A 60 53 65 74 20 63 6C 6F 63 6B 0D 27 'dat*`Set clock.''
00700- 60 52 65 70 65 61 74 0D 51 60 51 75 69 74 0D 00 '`Repeat.Q`Quit..'
00710- 00 00 00 00 40 3C C0 0D D7 01 04 E0 00 EC D3 A0 '....@<..........'
00720- 12 CC FF 0C 12 CE FF 0C 09 CE FF 28 DB CE 7F 0C '...........(....'
00730- 92 74 FF 0C CB 22 FC 0C 0A E6 7F F8 94 56 FF 0C '.t...".......V..'
00740- CB 32 FC 0C 01 C6 FF A0 D2 BE FD 1C AA 00 FC 0C '.2..............'
00750- B2 A2 FC 0C 6F E3 FE 1C E9 1A FE 1C 2B 73 FE 1C '....o.......+s..'
00760- 2F B0 6B F8 19 00 7C 1C 0B 1B FE 1C A4 02 FC 0C '/.k...|.........'
00770- 2B 73 FE 1C 1F 00 54 1C DA 65 FD 54 B2 00 FC 0C '+s....T..e.T....'
00780- C0 84 FD 1C B2 E4 FC 0C 11 00 7C 1C DD B7 BF A0 '..........|.....'
00790- E0 65 FD 54 B2 3E FC 0C C0 84 FD 1C 38 00 7C 1C '.e.T.>......8.|.'
007A0- 2A 73 FE 1C 35 00 68 1C DD B9 BF A0 B2 84 FC 0C '*s..5.h.........'
007B0- C0 84 FD 1C 39 00 7C 1C 01 C6 FF A2 02 C6 EB A2 '....9.|.........'
007C0- 04 C6 EB A0 D2 BE FD 1C 17 00 7C 1C 0F B8 FF A0 '..........|.....'
007D0- 49 DD FE 1C 12 00 7C 1C FF B8 FF A0 49 DD FE 1C 'I.....|.....I...'
007E0- 17 00 7C 1C FF B8 FF A0 4A DD FE 1C 18 00 7C 1C '..|.....J.....|.'
007F0- DB B9 BF A0 4C DD FE 1C 18 00 7C 1C DE B7 BF A0 '....L.....|.....'
00800- E5 B9 BF A0 C7 A2 FD 1C 0E 45 FE 1C B2 B6 7F 0C '.........E......'
00810- 00 00 04 E0 00 B0 FF A0 E5 CC FD 1C F6 BB 07 86 '................'
00820- 4B 00 68 1C E3 B7 BF 80 DC B7 3F 87 3F 00 78 1C 'K.h.......?.?.x.'
00830- DB BD BF A0 E5 BD BF 60 18 00 7C 1C E1 B1 BF E9 '.......`..|.....'
00840- 42 00 4C 1C E1 B9 BF A0 E4 B9 BF 2C DB B9 BF 80 'B.L........,....'
00850- 39 00 7C 1C C7 A2 FD 1C 01 B2 FF A0 DB BF BF A0 '9.|.............'
00860- E5 BF BF 60 0E 45 FE 1C 59 B2 7F FA E1 B5 BF A0 '...`.E..Y.......'
00870- 01 B4 FF 80 B3 BE 7F 0C F6 BB 87 A0 E7 D0 FD 1C '................'
00880- 5A B4 FF F6 13 BE FF 0C 18 00 7C 1C D8 B3 BF A0 'Z.........|.....'
00890- C7 A2 FD 1C 27 53 FE 1C E5 BB BF 4C E5 BB BF 60 '....'S.....L...`'
008A0- 3C B2 7F 86 DB B1 AB A0 DD B7 AB A0 D8 BB AB A0 '<...............'
008B0- DD B7 3F 85 DA B1 B3 A0 E4 B1 B3 2C D8 B7 B3 80 '..?........,....'
008C0- D8 BB B3 80 7E CA F1 6C 7E CE F1 6C B2 B6 7F 0C '....~..l~..l....'
008D0- B3 BA 7F 0C E5 CC FD 1C E7 D0 FD 1C 71 B4 FF F6 '............q...'
008E0- 7E CA F1 6C 7E CE F1 6C 18 00 7C 1C C7 A2 FD 1C '~..l~..l..|.....'
008F0- B2 B6 7F 0C E5 CC FD 1C DD B3 BF 80 79 B4 FF F6 '............y...'
00900- D9 BB BF A0 08 C4 FF A0 85 1B FF 1C 16 00 7C 1C '..............|.'
00910- E6 C6 FD 52 01 C4 FF A0 E4 C6 E9 50 E3 C5 AB A0 '...R.......P....'
00920- 01 C4 EB 2C E0 CC FD 1C DD B5 BF A0 85 1B FF 1C '...,............'
00930- 90 3D FF 1C A2 55 FF 1C 16 00 54 1C E0 CC FD 1C '.=...U....T.....'
00940- DA BB 3F 86 89 00 68 1C 86 00 7C 1C B2 FA FC 0C '..?...h...|.....'
00950- 6F E3 FE 1C 00 B6 7F 0C 9F 43 FF 1C 20 B0 7F 86 'o........C.. ...'
00960- 92 00 54 1C 16 00 7C 1C E0 B6 7F 0C 27 53 FE 1C '..T...|.....'S..'
00970- DD B3 BF A0 00 BA FF A0 2B B0 7F 86 27 53 EA 1C '........+...'S..'
00980- DD B3 3F 0C 18 00 7C 1C 01 B6 FF 0C 03 B6 7F 0C '..?...|.........'
00990- 17 00 7C 1C 07 B2 FF A0 90 3D FF 1C D9 B1 BF A0 '..|......=......'
009A0- 01 B0 FF 0D D9 B1 3F 86 30 B0 CF A0 31 B0 F3 A0 '......?.0...1...'
009B0- 4D B0 EB A0 96 3D FF 1C 01 B2 FF 85 A2 00 4C 1C 'M....=........L.'
009C0- 16 00 7C 1C DA 66 FD 52 DB 66 E9 52 D9 66 E9 52 '..|..f.R.f.R.f.R'
009D0- D8 66 E9 52 D6 66 E9 50 DB C1 BF A0 D6 C0 7F 0D '.f.R.f.P........'
009E0- A5 00 68 1C 17 00 7C 1C 27 53 FE 1C E3 B6 7F 0C '..h...|.'S......'
009F0- 23 B6 FF 0C DD B7 3F E8 18 00 7C 1C D5 B6 7F 0C '#.....?...|.....'
00A00- 17 00 7C 1C B2 5C FD 0C 6F E3 FE 1C 16 00 7C 1C '..|..\..o.....|.'
00A10- B4 A4 7F 0C C1 B4 FF 00 00 B4 7F F8 C1 B2 FF 00 '................'
00A20- D8 B3 BF 6E C1 00 54 1C DA 01 3C 1C E5 B7 BF 4C '...n..T...<....L'
00A30- E5 B7 BF 60 E5 B9 BF 4C E5 B9 BF 60 DB B9 3F 85 '...`...L...`..?.'
00A40- 1D 00 70 1C DC B5 BF A0 DB B5 BF 84 E4 B5 BF 28 '..p............('
00A50- 01 B4 FF 80 00 00 7C 1C 02 C6 7F 61 9A CB FD 0C '......|....a....'
00A60- 9A CF FD 0C 04 C6 7F 61 9B CB FD 0C 9B CF FD 0C '.......a........'
00A70- E3 C9 BF A0 01 C8 FF 28 E3 CB BF A0 01 CA FF 84 '.......(........'
00A80- D3 CB BF 6C E5 BD BF 60 E5 BF BF 60 00 00 7C 1C '...l...`...`..|.'
00A90- D6 B6 7F 0D 00 BA CF A0 01 BA F3 A0 E6 00 7C 1C '..............|.'
00AA0- B2 B6 7F 0C C1 BA FF 00 00 00 7C 1C C1 BB 7F 00 '..........|.....'
00AB0- 00 00 7C 1C A2 00 FC 0C 3E B0 FF A0 96 3D FF 1C '..|.....>....=..'
00AC0- 9F 43 FF 1C 27 B0 7F 86 F4 00 54 1C 18 B0 FF 0E '.C..'.....T.....'
00AD0- 96 3D D7 1C EF 00 54 1C 0A 01 7C 1C 9F 43 FF 1C '.=....T...|..C..'
00AE0- 0D B0 7F 86 09 01 68 1C 08 B0 7F 86 7F B0 57 86 '......h.......W.'
00AF0- 01 01 68 1C 20 B0 7F 85 7E B0 4F E1 F3 00 70 1C '..h. ...~.O...p.'
00B00- AA B0 7F 0C 16 00 7C 0D A6 02 F0 0C 96 3D CF 1C '......|......=..'
00B10- F3 00 7C 1C 16 00 7C 0E A8 B0 57 0C 96 3D D7 1C '..|...|...W..=..'
00B20- 90 3D D7 1C 18 B0 D7 0C 96 3D D7 1C A6 02 D4 0C '.=.......=......'
00B30- F3 00 7C 1C AA 00 FC 0C A2 00 FC 0C D4 B1 BF A0 '..|.............'
00B40- 96 3D FF 1C 00 00 7C 1C 00 AE FF A0 00 00 04 E0 '.=....|.........'
00B50- 2A 73 FE 1C 23 4D D6 1C 20 B0 7F 86 10 01 68 1C '*s..#M.. .....h.'
00B60- 27 B0 7F 86 1E 01 54 1C A4 04 FC 0C 1A B0 FF 0C ''.....T.........'
00B70- 27 B0 7F 86 10 01 68 1C 1E B1 7F F8 D8 BB BF A0 ''.....h.........'
00B80- 23 4D FE 1C 16 01 7C 1C 01 AE FF 85 D7 C3 8F A0 '#M....|.........'
00B90- E1 43 BE 54 00 00 04 E4 00 00 7C 1C 11 AE FF E9 '.C.T......|.....'
00BA0- 1D 00 70 1C DD ED 93 A0 00 00 7C 1C 2A 73 FE 1C '..p.......|.*s..'
00BB0- 1D 00 68 1C 00 00 7C 1C A4 02 FC 0C 00 BA FF A2 '..h...|.........'
00BC0- 3A 7D FE 1E 18 B0 FF 0C 3F 91 FE 1C 04 BA F3 2C ':}......?......,'
00BD0- D8 BB B3 68 2D 01 70 1E A6 02 FC 0C 3A 7D FE 1E '...h-.p.....:}..'
00BE0- 3F 91 FE 1C 1A B0 F3 0C 60 B0 7F E1 7B B0 73 85 '?.......`...{.s.'
00BF0- 20 B0 F3 84 00 00 7C 1C 18 B0 FF 0C 20 B0 7F 86 ' .....|..... ...'
00C00- 3A 01 68 1C A6 02 FC 0C 00 00 7C 1E 2F B0 7F E1 ':.h.......|./...'
00C10- 3A B0 73 85 07 B0 F3 80 40 B0 4F E1 47 B0 73 85 ':.s.....@.O.G.s.'
00C20- 20 B0 F3 80 60 B0 4F E1 67 B0 73 85 57 B0 F3 84 ' ...`.O.g.s.W...'
00C30- 00 00 7C 1C DE B7 BF A0 E5 B9 BF 60 DB B9 BF 80 '..|........`....'
00C40- C7 A2 FD 1C DB BD BF A0 DE BB BF A0 05 C4 FF A0 '................'
00C50- 85 1B FF 1C 8E 3D FF 1C E3 B1 BF A0 1B B0 FF 3C '.....=.........<'
00C60- DA B7 BF A0 D8 B7 BF 4C DB B9 BF A0 E4 B9 BF 2C '.......L.......,'
00C70- DB B5 BF 84 B2 BC 7F 0C E5 CC FD 1C E3 C5 BF A0 '................'
00C80- 01 C4 FF 2C 85 1B FF 1C 90 3D FF 1C 5A B7 FF F6 '...,.....=..Z...'
00C90- B2 0E FD 0C 6F E3 FE 1C B2 BC 7F 0C C1 B0 FF 00 '....o...........'
00CA0- 20 B0 7F 85 7E B0 4F E1 2E B0 F3 A0 96 3D FF 1C ' ...~.O......=..'
00CB0- 63 B9 FF F6 12 BC FF 0C B2 16 FD 0C 6F E3 FE 1C 'c...........o...'
00CC0- A2 55 FF 1C 4E B5 6B FA 00 00 7C 1C B4 A4 7F 0C '.U..N.k...|.....'
00CD0- C1 B0 FF 00 00 B0 7F F8 80 B0 7F 62 28 E1 D6 0C '...........b(...'
00CE0- B3 B0 57 0C B5 A4 57 0C 70 01 54 1C 60 B0 7F 86 '..W...W.p.T.`...'
00CF0- 10 B2 EB E0 7E B0 57 86 10 B2 EB 80 90 3D EB 1C '....~.W......=..'
00D00- 7B B3 EB F6 8E 3D EB 1C 70 01 68 1C 0D B0 7F 86 '{....=..p.h.....'
00D10- 0B 1B EA 1C 00 B2 EB A0 96 3D D7 1C 01 B2 D7 80 '.........=......'
00D20- 70 01 7C 1C E2 B3 BF A0 02 B2 FF 2C D9 BB BF 20 'p.|........,... '
00D30- E2 B3 BF A0 04 BA FF 24 DD B1 BF A0 92 3D FF 1C '.......$.....=..'
00D40- 89 B3 FF F6 00 00 7C 1C D5 B1 BF A0 96 01 7C 1C '......|.......|.'
00D50- 20 B0 FF A0 96 01 7C 1C 0F B0 FF 60 0A B0 7F 85 ' .....|....`....'
00D60- 30 B0 F3 80 37 B0 CF 80 01 B0 FF 2C 69 B1 FF 0C '0...7......,i...'
00D70- 0D AE FF 0C F3 AF BF 80 0D AE 7F 0C 01 B0 FF 29 '...............)'
00D80- DC CE 7F 0C 99 B1 7F FA 00 00 7C 1C A2 55 FF 1C '..........|..U..'
00D90- 9F 01 68 1C 00 00 7C 1C 80 D0 FF 68 17 D2 FF 0E '..h...|....h....'
00DA0- E8 D3 17 86 16 D2 D7 0C A2 D0 57 0C 18 B0 D7 0C '..........W.....'
00DB0- 16 D0 D7 0C A2 D2 57 0C 00 00 7C 1C 17 00 7C 0E '......W...|...|.'
00DC0- A3 00 E9 0C 09 D8 FF A0 F3 D5 BF A4 01 D4 FF 38 '...............8'
00DD0- B0 CD FF F8 0C D4 FF 0C 01 D6 FF 30 F3 D5 BF 80 '...........0....'
00DE0- 0D D4 7F 0C D6 CC 7F 0D B2 D9 FF F6 18 D6 FF 28 '...............('
00DF0- AB D6 7F 0C AB 01 7C 1C E6 AD BF 54 25 AD FF 0D '......|....T%...'
00E00- F0 AC 7F 0C ED E1 8F A0 04 E0 CF 28 F0 E3 8F A4 '...........(....'
00E10- ED E1 8F 80 ED E3 8F 80 EE E5 8F A0 06 E4 CF 10 '................'
00E20- F0 E5 0F E1 F1 E5 0F 85 EF E5 8F A0 03 E4 CF 10 '................'
00E30- F0 E5 0F E1 F1 E5 0F 85 EF DB 8F 80 03 DA CF 28 '...............('
00E40- ED E7 8F A0 EE DB BF A0 EF DD BF A0 3A DE FF 0C '............:...'
00E50- BB DF 7F FA CF 01 7C 1C 5C 05 00 00 FF FF 01 00 '......|.\.......'
00E60- 0D 28 04 00 2D 80 04 00 89 00 00 00 78 CF 68 9D '.(..-.......x.h.'
00E70- 3D 3D 20 45 6E 64 20 6F 66 20 52 4F 4D 20 3D 3D '== End of ROM =='
It is now 128 bytes shorter than it used to be, since I've used this time during full-chip verification being done by Beau and Open Silicon to pack things more efficiently.
Here is the binary/HMAC-signed loader (it's only $70 longs and starts at $000):
'********************************************************
'* *
'* Propeller II ROM Booter *
'* *
'* Version 0.1 *
'* *
'* 11/01/2012 *
'* *
'********************************************************
CON
rx_pin = 91
tx_pin = 90
spi_cs = 89
spi_ck = 88
spi_di = 87
spi_do = 86
base = $E80
DAT
'
'
' Version (@$000)
'
byte "Prop2.0 "
'
'
' Shut down (@$008)
'
org
clkset h001+offset 'set clock to rc slow
cogstop h200+offset 'stop cog0
offset
'
'
' Entry, read fuses (@$010)
'
org
reps #256,@:fuse 'ready to read 256 fuses
setport #rx_pin 'set rx_pin port for booting
cogid fuse_read nr 'read fuses (172 fuses + 84 zeros)
cogid fuse_read nr,wc '(last iteration initializes cnt to $00000000_00000001)
add fuse_read,#1
test fuse_read,#$1F wz
:fusex rcr fuses,#1
:fuse if_z add :fusex,h200
cogid spi_read nr 'disable fuses and enable cnt (spi_read[10..0] = 0)
'
'
' Attempt to boot from serial
'
jnp monitor_ptr,#boot_flash 'if rx_pin is low, skip serial and boot from flash
call #rx_bit 'measure low rx calibration pulses (host $F9 -> %1..010011111..)
mov threshold,delta 'and calculate threshold
call #rx_bit '(any timeout results in flash boot)
add threshold,delta
h001 shr threshold,#1 '(9 lsb's are $001)
mov count,#250 'ready to receive/verify 250 lfsr bits
:lfsrin call #rx_bit 'receive bit ($FE/$FF) into c
test lfsr,#$01 wz 'get lfsr bit into nz
if_c_eq_z jmp #boot_flash 'if mismatch, boot from flash
test lfsr,#$B2 wc 'advance lfsr
rcl lfsr,#1
djnz count,#:lfsrin 'loop for next bit in
mov count,#250+8 'ready to transmit 250 lfsr bits + 8 version bits
:lfsrout cmp count,#8 wz 'if last 8 bits, set lfsr so that version will be output
if_z mov lfsr,#$52 '$52 results in version $20 being sent (%00000100)
test lfsr,#$01 wz 'get lfsr/version bit into nz, z=1 on last iteration
call #wait_rx 'wait for rx low (convey incoming $F9 on rx_pin to $FE/$FF on tx_pin)
clrp #tx_pin 'make tx low
call #wait_rx 'wait for rx high
setpnz #tx_pin 'make tx lfsr/version bit
call #wait_rx 'wait for rx low
setp #tx_pin 'make tx high
call #wait_rx 'wait for rx high
test lfsr,#$B2 wc 'advance lfsr
rcl lfsr,#1
djnz count,#:lfsrout 'loop for next bit out
jmp #load 'serial handshake done, attempt to load from serial (z=1)
'
'
' Wait for rx low/high - if timeout, attempt to boot from flash
'
wait_rx getcnt time 'ready timeout
add time,timeout
:waitpxx waitpne rx_mask,rx_mask wc 'wait for rx low/high with timeout
notb :waitpxx,#23 'toggle waitpeq/waitpne
wait_rx_ret if_nc ret 'return if not timeout (boot_flash follows)
'
'
' Attempt to boot from flash
'
boot_flash mov count,#4 'ready for 3 resets and 1 read command
:cmd setp #spi_cs 'spi_cs high
clrp #spi_ck 'spi_ck low
reps #32,@:bit 'ready for 32 command bits
clrp #spi_cs 'spi_cs low
cmpr count,#1 wc 'first 3 commands = $FF_FF_FF_FF (reset)
if_nc rol spi_read,#1 wc,wz 'last command = $03_00_00_00 (read from 0), z=0
setpc #spi_di
setp #spi_ck 'cycle spi_ck
:bit clrp #spi_ck
djnz count,#:cmd 'loop for next spi command
'
'
' Load from serial (z=1) or flash (z=0)
'
load setptra loader_pgm 'load loader into base+$000..$7DF, HMAC into base+$7E0..$7FF
mov count,h200 'ready to input $200 longs
:long mov bits,#32 'ready to input 32 data bits
:bit if_z call #rx_bit 'input serial bit (serial mode)
if_nz getp #spi_do wc 'input spi_do (flash mode)
if_nz setp #spi_ck 'high spi_ck (flash mode)
if_nz clrp #spi_ck 'low spi_ck (flash_mode)
rcl data,#1 'shift bit into long
djnz bits,#:bit 'loop, adequate time for next flash bit
wrlong data,ptra++ 'store long in hub ram (ptra=base+$800 after)
djnz count,#:long 'loop for next long (count=0 after)
'
'
' Compute loader HMAC signature for loader authentication
'
' base+$000..$7DF = loader ($1F8 longs)
' base+$7E0..$7FF = loader HMAC signature (8 longs)
' base+$800..$81F = fuses, 1st half are HMAC key (8 longs)
' base+$820..$83F = proper HMAC signature (8 longs)
' base+$840..$843 = sha256 command interface (1 long)
'
reps #8,#1 'store 128-bit key + 44 extra fuses + 84 zero bits
setinda fuses 'into base+$800..$81F
wrlong inda++,ptra++ '(ptra = base+$820, afterwards)
wrlong count,sha256_ptr 'clear sha256 command
setcog #1 'launch sha256 in cog1
coginit sha256_pgm,sha256_ptr
setinda begin_hmac 'do sha256 commands to compute proper loader hmac
mov count,#3 'ready for 3 commands: begin_hmac, hash_bytes, read_hash
:cmd wrlong inda++,sha256_ptr 'set command
:wait rdlong data,sha256_ptr wz 'wait for command done
tjnz data,#:wait
djnz count,#:cmd 'loop for next command (count=0, z=1 after)
cogstop h001 'done with sha256, stop cog1
'
'
' If loader authenticates, run it
'
reps #8,@:cmp 'verify loader hmac signature (z=1 on entry)
setcog #0 'ready to relaunch cog0 with loader/monitor
rdlong bits,ptra[-$10] 'get loader hmac signature long
rdlong data,ptra++ 'get proper hmac signature long
:cmp if_z cmp bits,data wz 'compare, z=1 if authenticated
if_z coginit loader_pgm,loader_ptr 'if loader authenticated, relaunch cog0 with loader
'
'
' Authentication failed, hide fuses and clear memory
'
reps #$20000/8,@:clr 'clear all memory
cogid monitor_pgm nr 'hide fuses (bit 10 set)
wrlong count,ptra++ '(count=0)
:clr wrlong count,ptra++
'
'
' If key <> 0, shut down - else, monitor
'
or fuses+0,fuses+1 wz 'check if 128-bit key = 0
if_z or fuses+2,fuses+3 wz
if_nz mov monitor_pgm,#$008 'if key <> 0, shut down
coginit monitor_pgm,monitor_ptr 'relaunch cog0 with shut down or monitor
'
'
' Receive bit (c) - compare incoming pulse to threshold
'
rx_bit call #wait_rx 'wait for rx low
getcnt delta 'get time
call #wait_rx 'wait for rx high
subcnt delta 'get time delta
cmp delta,threshold wc 'compare time delta to threshold
rx_bit_ret ret
'
'
' Constants
'
fuse_read long $200 '(gets modified to $300)
timeout long 20_000_000 / 1000 * 150 '150ms @20MHz (rcfast)
rx_mask long 1 << (rx_pin & $1F)
lfsr long "P"
spi_read long $03_000000
h200 long $200
begin_hmac long 1<<30 + (($004<<2)-1)<<17 + base+$800 'begin_hmac, loads key at base+$800 (4 longs)
hash_bytes long 2<<30 + (($1F8<<2)-1)<<17 + base+$000 'hash_bytes, hashes message at base+$000 ($1F8 longs)
read_hash long 3<<30 + base+$820 'read_hash, writes hash at base+$820 (8 longs)
sha256_pgm long $1D0 'sha256 program address
sha256_ptr long base+$840 'sha256 parameter (points to command)
loader_pgm long base+$000 'loader program address
loader_ptr long base+$800 'loader parameter (points to fuses)
monitor_pgm long $55C+$1B4 'monitor program address
monitor_ptr long tx_pin<<9 + rx_pin 'monitor parameter (conveys pins)
'
'
' Variables
'
fuses res 8
count res 1
bits res 1
data res 1
time res 1
delta res 1
threshold res 1
Here is the SHA-256/HMAC program used to authenticate code (thanks to Pedward for making this happen):
'********************************************************
'* *
'* Propeller II ROM SHA-256/HMAC *
'* *
'* Version 0.1 *
'* *
'* 11/01/2012 *
'* *
'********************************************************
'
' Usage: commandlong := 0 'pre-clear command long
' cognew($1D0, @commandlong) 'start SHA-256/HMAC in new cog
'
' Start here for HMAC: commandlong := 1<<30 + (keysize-1)<<17 + @key 'start HMAC with key of keysize bytes (1..64)
' repeat while commandlong '(wait for command done)
'
' Start here for SHA-256: commandlong := 2<<30 + (msgsize-1)<<17 + @msg 'hash msg of msgsize bytes (1..8192)
' repeat while commandlong '(wait for command done)
'
' {issue more 2<<30 commands if msg > 8192 bytes}
'
' commandlong := 3<<30 + @hashbuffer 'read resulting hash into hashbuffer (32 bytes)
' repeat while commandlong '(wait for command done)
'
' {hasbuffer now contains result, ready for new 1<<30 or 2<<30 command}
'
DAT
org
setf #%0_1111_0000 'configure movf for sbyte0 -> {dbyte3,dbyte2,dbyte1,dbyte0,dbyte3,...}
call #init_hash 'init hash, clear hmac mode, reset byte count
'
'
' Command Loop
'
command rdlong x,ptra 'wait for command (%cc_nnnnnnnnnnnnn_ppppppppppppppppp)
tjz x,#command
setptrb x 'get pointer (%ppppppppppppppppp)
mov count,x 'get count (%nnnnnnnnnnnnn)
shl count,#2
shr count,#2+17
add count,#1 '+1 for 1..8192 range
shr x,#32-2 'get command (%cc)
cachex 'invalidate cache for fresh rdbytec's
djz x,#begin_hmac '1 = begin hmac, pointer @key (count+1 bytes, 1..64)
djz x,#hash_bytes '2 = hash bytes, pointer @message (count+1 bytes, 1..8192)
djz x,#read_hash '3 = read hash, pointer @hashbuffer (32 bytes)
done wrlong zero,ptra 'clear command to signal done
jmp #command 'get next command
'
'
' Begin HMAC
'
begin_hmac call #end_hash 'end any hash in progress
:ipad mov x,#$00 'get and hash ipad key (full block)
cmpr count,bytes wc 'after key bytes, hash $00's to fill block
if_c rdbytec x,ptrb++
xor x,#$36 'xor bytes with ipad ($36)
call #hash_byte '(last iteration triggers hash_block, z=1)
if_nz jmp #:ipad
reps #16,#2 'save opad key
setinds opad_key,w
mov indb,inda++
xor indb++,opad 'xor bytes with opad ($5C)
mov hmac,#1 'set hmac mode
jmp #done
'
'
' Hash Bytes
'
hash_bytes rdbytec x,ptrb++ 'hash bytes
call #hash_byte
djnz count,#hash_bytes
jmp #done
'
'
' Read Hash
'
read_hash tjz hmac,#:not 'if not hmac, output hash
call #end_hash 'hmac, end current hash
reps #16,#1 'get opad key into w[0..15] (full block)
setinds w,opad_key
mov indb++,inda++
call #hash_block 'hash opad key
reps #8,#1 'get hashx[0..7] into w[0..7]
setinds w,hashx
mov indb++,inda++
movd hash_byte,#w+8 'account for opad key and hashx bytes
mov bytes,#64+32 '(1-1/2 blocks, 1/2 block needs end_hash)
:not call #end_hash 'end current hash
setinda hashx 'store hashx[0..7] at pointer, big-endian
mov count,#8
:out reps #4,#2
mov x,inda++
rol x,#8
wrbyte x,ptrb++
djnz count,#:out
jmp #done
'
'
' End Hash - hash $80, any $00's needed to get to offset $38, then 8-byte length
'
end_hash mov length,bytes 'get message length in bits
shl length,#3
mov x,#$80 'hash end-of-message byte ($80)
:fill call #hash_byte '(may trigger hash_block)
mov x,bytes 'hash any $00's needed to get to offset $38
and x,#$3F
cmp x,#$38 wz
mov x,#$00
if_nz jmp #:fill
:len test bytes,#$04 wc 'hash 8-byte length, big-endian
if_c rol length,#8 '(hash four $00's, then four length bytes)
if_c mov x,length
call #hash_byte '(last iteration triggers hash_block)
if_nz jmp #:len
reps #8,#1 'save hash[0..7] into hashx[0..7]
setinds hashx,hash
mov indb++,inda++
init_hash reps #8,#1 'copy hash_init[0..7] into hash[0..7]
setinds hash,hash_init
mov indb++,inda++
mov hmac,#0 'clear hmac mode
mov bytes,#0 'reset byte count
init_hash_ret
end_hash_ret ret
'
'
' Hash Byte - add byte to w[0..15] and hash block if full (z=1)
'
hash_byte movf w,x 'store byte into w[0..15], big-endian
add bytes,#1 'increment byte count
test bytes,#$03 wz 'every 4th byte, increment w pointer
if_z add hash_byte,d0
test bytes,#$3F wz 'every 64th byte, reset w pointer
if_z movd hash_byte,#w
if_z call #hash_block 'every 64th byte, hash block
hash_byte_ret ret
'
'
' Hash Block - first extend w[0..15] into w[16..63] to generate schedule
'
hash_block reps #48,@:sch 'i = 16..63
setinds w+16,w+16-15+7 'indb = @w[i], inda = @w[i-15+7]
setinda --7 's0 = (w[i-15] -> 7) ^ (w[i-15] -> 18) ^ (w[i-15] >> 3)
mov indb,inda--
mov x,indb
rol x,#18-7
xor x,indb
ror x,#18
shr indb,#3
xor indb,x
add indb,inda 'w[i] = s0 + w[i-16]
setinda ++14 's1 = (w[i-2] -> 17) ^ (w[i-2] -> 19) ^ (w[i-2] >> 10)
mov x,inda
mov y,x
rol y,#19-17
xor y,x
ror y,#19
shr x,#10
xor x,y
add indb,x 'w[i] = s0 + w[i-16] + s1
setinda --5 'w[i] = s0 + w[i-16] + s1 + w[i-7]
:sch add indb++,inda
' Load variables from hash
reps #8,#1 'copy hash[0..7] into a..h
setinds a,hash
mov indb++,inda++
' Do 64 hash iterations on variables
reps #64,@:itr 'i = 0..63
setinds k+0,w+0 'indb = @k[i], inda = @w[i]
mov x,g 'ch = (e & f) ^ (!e & g)
xor x,f
and x,e
xor x,g
mov y,e 's1 = (e -> 6) ^ (e -> 11) ^ (e -> 25)
rol y,#11-6
xor y,e
rol y,#25-11
xor y,e
ror y,#25
add x,y 't1 = ch + s1
add x,indb++ 't1 = ch + s1 + k[i]
add x,inda++ 't1 = ch + s1 + k[i] + w[i]
add x,h 't1 = ch + s1 + k[i] + w[i] + h
mov y,c 'maj = (a & b) ^ (b & c) ^ (c & a)
and y,b
or y,a
mov h,c
or h,b
and y,h
mov h,a 's0 = (a -> 2) ^ (a -> 13) ^ (a -> 22)
rol h,#13-2
xor h,a
rol h,#22-13
xor h,a
ror h,#22
add y,h 't2 = maj + s0
mov h,g 'h = g
mov g,f 'g = f
mov f,e 'f = e
mov e,d 'e = d
mov d,c 'd = c
mov c,b 'c = b
mov b,a 'b = a
add e,x 'e = e + t1
mov a,x 'a = t1 + t2
:itr add a,y
' Add variables back into hash
reps #8,#1 'add a..h into hash[0..7]
setinds hash,a
add indb++,inda++
hash_block_ret ret
'
'
' Defined data
'
zero long 0
d0 long 1 << 9
opad long $36363636 ^ $5C5C5C5C
hash_init long $6A09E667, $BB67AE85, $3C6EF372, $A54FF53A, $510E527F, $9B05688C, $1F83D9AB, $5BE0CD19 'fractionals of square roots of primes 2..19
k long $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5 'fractionals of cube roots of primes 2..311
long $D807AA98, $12835B01, $243185BE, $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174
long $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA
long $983E5152, $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967
long $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E, $92722C85
long $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819, $D6990624, $F40E3585, $106AA070
long $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3
long $748F82EE, $78A5636F, $84C87814, $8CC70208, $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2
'
'
' Undefined data
'
hmac res 1
bytes res 1
count res 1
length res 1
opad_key res 16
hash res 8
hashx res 8
w res 64
a res 1
b res 1
c res 1
d res 1
e res 1
f res 1
g res 1
h res 1
x res 1
y res 1
And here's the monitor, shrunk and improved:
'********************************************************
'* *
'* Propeller II ROM Monitor *
'* *
'* Version 0.1 *
'* *
'* 11/01/2012 *
'* *
'********************************************************
'
' Usage: cognew($738, tx_pin << 9 + rx_pin) 'start monitor in new cog
'
CON
branch1_ = 0
branch2_ = branch1_ + 31
branch3_ = branch2_ + 35
hello_ = branch3_ + 15
error_ = hello_ + 33
hitspace_ = error_ + 11
spquote_ = hitspace_ + 10
quotecr_ = spquote_ + 4
sub0_ = quotecr_ + 3 'must be => $80
sub1_ = sub0_ + 4
sub2_ = sub1_ + 12
sub3_ = sub2_ + 12
help_ = sub3_ + 4
DAT
'********
'* Data *
'********
branch1 byte cmd_new, 0
byte cmd_byte, "Y"
byte cmd_word, "W"
byte cmd_long, "N"
byte cmd_viewp, "."
byte cmd_search, "/"
byte cmd_enter, ":"
byte cmd_map, "M"
byte cmd_clrp, "L"
byte cmd_setp, "H"
byte cmd_notp, "T"
byte cmd_offp, "Z"
byte cmd_getp, "R"
byte cmd_quit, "Q"
byte cmd_help, "?"
byte 0 '31 bytes
branch2 byte cmd_view2, 0
byte cmd_view2, " "
byte cmd_range, "."
byte cmd_search2, "/"
byte cmd_enter2, ":"
byte cmd_watch, "@"
byte cmd_clkset, "*"
byte cmd_coginit, "+"
byte cmd_cogstop, "-"
byte cmd_clrp, "L"
byte cmd_setp, "H"
byte cmd_notp, "T"
byte cmd_offp, "Z"
byte cmd_getp, "R"
byte cmd_watchp, "#"
byte cmd_cfgp, "|"
byte cmd_setdacs, "\"
byte 0 '35 bytes
branch3 byte cmd_view3, 0
byte cmd_view3, " "
byte cmd_search3, "/"
byte cmd_enter3, ":"
byte cmd_move, ">"
byte cmd_move, "<"
byte cmd_checksum, "^"
byte 0 '15 bytes
hello byte 13,13,"=== Propeller II Monitor ===",13,13
byte 0 '33 bytes
error byte "? - Help"
byte 13,7,0 '11 bytes
hitspace byte "Hit SPACE",0 '10 bytes
spquote byte " '",0 '4 bytes
quotecr byte "'",13,0 '3 bytes
sub0 byte " -",13,$80 '4 bytes
sub1 byte "{adr{.adr}}",$80 '12 bytes
sub2 byte "{dat{ dat}}",$80 '12 bytes
sub3 byte "adr",$80 '4 bytes
help byte 13, "~HUB",sub0_
byte sub1_, "`View",13
byte sub1_,"/",sub2_, "`Search",13
byte sub1_,":",sub2_, "`Enter",13
byte sub3_,".",sub3_,"[</>]",sub3_, "`Move",13
byte sub3_,".",sub3_,"^", "`Checksum",13
byte sub3_,"@", "`Watch",13
byte "[Y/W/N]", "`Byte/word/long",13
byte "~COGS",sub0_
byte "cog+",sub3_,"{+",sub3_,"}", "`Start",13
byte "cog-", "`Stop",13
byte "M", "`Map",13
byte "~PINS",sub0_
byte "{pin}[H/L/T/Z/R]", "`High/low/toggle/off/read",13
byte "pin#", "`Watch",13
byte "pin|cfg", "`Configure",13
byte "dat\", "`Set DACs",13
byte "~MISC",sub0_
byte "dat*", "`Set clock",13
byte "'", "`Repeat",13
byte "Q", "`Quit",13 '(0 long follows)
longs long
'*********
'* Entry *
'*********
org
long 0 'start of data string = 0/nop
reps #$1F6-reserves,#1 'clear reserves
setinda reserves
mov inda++,#0
getptra rx_pin 'get rx/tx pins
getptra tx_pin
shr tx_pin,#9
setp tx_pin
jmptask #baud_task,#%0010 'enable baud detector task
settask #%%0101
tjz period,#$ 'wait for <space> to set period
jmptask #rx_task,#%0100 'enable serial receiver task
settask #%%0121
mov wsize,#1 'init word size to byte
call #set_size
pusha #0 'init input line to <enter>
setptra #hello_ 'print hello message
dmax 'end of data string
'*************
'* Main Task *
'*************
message call #tx_string 'print hello/error message
cmd_new call #rx_line 'get input line
call #parse 'parse first term
if_z tjz x,#cmd_viewl 'if no hex and eol, view data
jmp #cmd_go 'else, process command
cmd_next_crlf call #tx_crlf 'print cr/lf
cmd_next addspa #1 'skip chr
cmd_loop call #parse 'parse next term
cmd_go if_nz jmp #cmd_hex 'if hex, branch
movd pinx,#z 'pin update redirected to z
setptra #branch1_ 'not hex, vector by chr
call #vector 'if returns, no match
cmd_error setptra #error_ 'print error message
jmp #message
cmd_hex mov v1,value 'hex, save v1
movd pinx,#pin 'pin update okay
setptra #branch2_ 'vector by chr
call #vector 'if returns, no match
jmp #cmd_view2 'view data
cmd_range call #parse_next 'hex., get hex
if_z jmp #cmd_viewp2 'if no hex, view data
mov v2,value 'hex.hex, save v2
setptra #branch3_ 'vector by chr
call #vector 'if returns, no match
jmp #cmd_view3 'view data
'
'
' Byte/word/long data
'
cmd_byte mov wsize,#1 wz 'set byte mode, z=0
cmd_word if_z mov wsize,#2 wz 'set word mode, z=0
cmd_long if_z mov wsize,#4 'set long mode
call #set_size
jmp #cmd_next 'next command
'
'
' View data
'
cmd_viewl mov v2,#$F '<enter> (eol), show line of data
call #tx_range1
jmp #cmd_new
cmd_viewp mov v2,#$FF '. (more), show page of data
call #tx_range1
jmp #cmd_next
cmd_viewp2 mov v2,#$FF 'addr. (more), show page of data
call #tx_range2
jmp #cmd_loop
cmd_view2 mov v2,v1 'addr, show unit of data
cmd_view3 call #tx_range 'addr.addr, show range of data
jmp #cmd_loop
'
'
' Search
'
cmd_search mov v1,view '/, search from view to end
cmd_search2 mov v2,amask 'addr/, search from address to end
cmd_search3 call #check_range 'addr.addr/, search range
call #parse_data 'parse data string
:start setptra v1 'start search, point to search address
setinda 0 'point to search data
mov x,#0 'reset word match counter
:word call #rdxxxx 'get memory word
cmp value,inda++ wz 'compare against search data word
if_z jmp #:match 'if word match, check if string match
add v1,wsize 'word mismatch, advance search address
cmp v1,v2 wz,wc 'at end of range?
if_be jmp #:start 'if not, start next search
mov view,v1 'else, update view
and view,amask
jmp #cmd_loop 'next command
:match incmod x,dsize wc 'word match, increment match counter
if_nc jmp #:word 'if more words to match, compare next word
mov v2,dsize 'got string match
shl v2,shift 'v1 = start of found data
add v2,v1 'v2 = end of found data
jmp #cmd_view3 'show found data
'
'
' Enter data
'
cmd_enter3 call #check_range 'addr.addr:, check range, z=words to fill
mov y,#1 'set fill flag
cmd_enter2 mov enter,v1 'addr:, set enter address
and enter,amask 'trim enter address (in case cmd_enter2)
cmd_enter call #parse_data ':, parse data
tjnz y,#:go 'if not fill, set z to data size
mov z,dsize
add z,#1
:go setptrb enter 'get pointer
:loop mov value,inda++ 'get word from string data
call #wrxxxx 'store value in memory
djnz z,#:loop 'loop until enter done
getptrb enter 'update pointer
jmp #cmd_loop 'next command
'
'
' Move data
'
cmd_move mov y,x 'save ">"/"<"
call #check_range 'check 1st address range, get number of words
call #parse_hex 'get 2nd address
max value,amask 'v1=1st, value=2nd, z=words, y=">"/"<"
and value,amask
cmp y,#"<" wz 'if "<", swap v1 and value
if_z mov x,v1
if_z mov v1,value
if_z mov value,x 'v1=from, value=to, z=words
cmp v1,value wc 'if from < to, downward move
if_c mov x,z
if_c shl x,shift
if_c add v1,x
if_c add value,x
if_c xor rdxxxx,#%001_111110 'modify 'rdxxxx value,--ptra'
if_c xor wrxxxx,#%001_111110 'modify 'wrxxxx value,--ptrb'
setptra v1 'set pointers
setptrb value
:loop call #rdxxxx 'move data
call #wrxxxx
djnz z,#:loop
if_c xor rdxxxx,#%001_111110 'restore 'rdxxxx value,ptra++'
if_c xor wrxxxx,#%001_111110 'restore 'wrxxxx value,ptrb++'
jmp #cmd_loop 'next command
'
'
' Checksum
'
cmd_checksum call #check_range 'check range
setptra v1 'sum bytes
:loop call #rdxxxx
add y,value
djnz z,#:loop
mov value,y 'print sum
mov hsize,#8
call #tx_hex
jmp #cmd_next_crlf 'next command
'
'
' Watch
'
cmd_watchp movs rdxxxj,#rdxxxx_ret wz 'set pin mode, z=0
mov hsize,#1
cmd_watch if_z movs rdxxxj,#rdxxxm 'set mem mode
if_z mov hsize,wsize 'set hex size by word size
if_z shl hsize,#1
call #rdxxxp 'get initial value
:loop mov z,value 'preserve value
call #tx_hex 'print value
call #tx_space 'print space
:wait call #rx_check 'if key hit, exit
if_nz jmp #cmd_next_crlf
call #rdxxxp 'get current value
cmp value,z wz 'if same, check again
if_z jmp #:wait
jmp #:loop 'new value, loop
'
'
' Clkset
'
cmd_clkset setptra #hitspace_ 'print hit-space message
call #tx_string
clkset v1 'set clk
:wait call #rx 'wait for space
cmp x,#" " wz
if_nz jmp #:wait
jmp #cmd_next_crlf 'next command
'
'
' Coginit
'
cmd_coginit setcog v1 'set cog
call #parse_hex 'get program address
mov y,value 'save program address
mov value,#0 'clear pointer address
cmp x,#"+" wz 'if '+', get pointer address
if_z call #parse_hex
coginit y,value 'do 'coginit program,pointer'
jmp #cmd_loop 'next command
'
'
' Cogstop
' Quit
'
cmd_quit cogid v1 'quit
cmd_cogstop cogstop v1 'stop cog
jmp #cmd_next 'next command
'
'
' Map
'
cmd_map mov y,#7 'ready for 7..0
cmd_map_loop call #tx_space 'print space
mov x,y 'get cog status
cogid x wc
cmd_map_c cmp x,y wz
if_nc mov x,#"0" 'get 0/1/M chr
if_c mov x,#"1"
if_z mov x,#"M"
call #tx 'print chr
sub y,#1 wc
if_nc jmp #cmd_map_loop 'loop until done
jmp #cmd_next_crlf 'next command
'
'
' Pin writes clrp/setp/notp/offp
' Pin read
'
cmd_clrp movs pinop,#$DA wz 'clrp, z=0
cmd_setp if_z movs pinop,#$DB wz 'setp, z=0
cmd_notp if_z movs pinop,#$D9 wz 'notp, z=0
cmd_offp if_z movs pinop,#$D8 wz 'offp, z=0
cmd_getp if_z movs pinop,#$D6 'getp, z=1
pinx mov pin,v1 'if hex, get pin (d = pin/z)
pinop getp pin wc 'becomes clrp/setp/notp/offp/getp
if_z jmp #cmd_map_c 'if getp, show pin value
jmp #cmd_next 'next command
'
'
' Pin configuration
'
cmd_cfgp call #parse_hex 'get configuration
setport v1 'set pin port
decod5 v1 'get pin mask
cfgpins v1,value 'configure pin
jmp #cmd_loop 'next command
'
'
' Setdacs
'
cmd_setdacs setdacs v1 'set all four dacs with 8-bit values
jmp #cmd_next 'next command
'
'
' Help
'
cmd_help setptra #help_ 'print help message
call #tx_string
jmp #cmd_next_crlf 'next command
'*************************
'* Main Task Subroutines *
'*************************
'
'
' Vector branch
'
vector addptra base 'add data base pointer
vector_loop rdbyte z,ptra++ 'get jump address
vector_ret tjz z,#0 'if 0, no match found, return
rdbyte y,ptra++ 'get target
xor y,x wz 'compare to x
if_nz jmp #vector_loop 'if no match, loop
jmp z 'match found, jump, y=0, z=1
'
'
' Check address range (v1..v2)
'
check_range max v1,amask 'trim v1
and v1,amask
max v2,amask 'trim v2
and v2,amask
cmp v2,v1 wc 'make sure v2 => v1
if_c jmp #cmd_error
mov z,v2 'get number of words
sub z,v1
shr z,shift
add z,#1
check_range_ret ret
'
'
' Set rdxxxx/wrxxxx and others by word size
'
set_size test wsize,#%010 wc 'set rdxxxx/wrxxxx by word size
setbc rdxxxx,#26
setbc wrxxxx,#26
test wsize,#%100 wc
setbc rdxxxx,#27
setbc wrxxxx,#27
mov shift,wsize 'set shift by word size
shr shift,#1
mov amask,wsize 'set amask by word size
sub amask,#1
xor amask,h0001FFFF
and view,amask 'trim view
and enter,amask 'trim enter
set_size_ret ret
rdxxxp getp v1 wc 'read pin as "0" or "1"
if_nc mov value,#0
if_c mov value,#1
rdxxxj jmp #rdxxxx_ret 'd = rdxxxx_ret/rdxxxm
rdxxxm setptra v1 'read mem
rdxxxx rdbyte value,ptra++ 'rdbyte/rdword/rdlong
rdxxxp_ret
rdxxxx_ret ret
wrxxxx wrbyte value,ptrb++ 'wrbyte/wrword/wrlong
wrxxxx_ret ret
'
'
' Input line
'
rx_line setspa #0 'point to start of line
mov x,#">" 'show prompt
call #tx
call #rx 'get first chr
cmp x,#"'" wz 'check for repeat
if_nz jmp #:first 'if not repeat, first chr
:show popar x wz 'repeat, show line
if_nz call #tx
if_nz jmp #:show
jmp #:done
:loop call #rx 'get next chr
:first cmp x,#13 wz 'cr?
if_z jmp #:cr
cmp x,#8 wz 'backspace?
if_nz cmp x,#127 wz
if_z jmp #:bs
cmp x,#" " wc 'visible chr?
if_nc cmpr x,#"~" wc
if_c jmp #:loop
pusha x 'visible chr, append to line
chkspa wc 'overflow?
if_c subspa #1 'if overflow, back up
if_nc call #tx 'if not overflow, print chr
jmp #:loop
:bs chkspa wz 'backspace, line empty?
if_nz pushar x 'if not empty,
if_nz call #tx '..print backspace
if_nz call #tx_space '..print space
if_nz popar x '..print backspace
if_nz call #tx
if_nz subspa #1 '..back up
jmp #:loop
:cr pusha #0 'cr, end line with 0
:done setspa #0 'point to start of line
tx_crlf mov x,crlf 'print cr/lf
call #tx
tx_crlf_ret
rx_line_ret ret
'
'
' Parse hex/text data
'
parse_data mov w,#0 'reset data count
setinda 0 'point to string data
:hex call #parse_next 'hex loop, check hex
if_nz call #enter_data 'if hex, enter value
cmp x,#" " wz 'check for space (more hex)
if_z jmp #:hex 'if more hex, loop
cmp x,#"'" wz 'not hex, "'"?
if_nz jmp #:done 'if not "'", done
:text addspa #2 'text loop
popa x 'get and point to next chr
cmp x,#"'" wz 'check for "'"
if_z jmp #:hex 'if "'", back to hex
tjz x,#:done 'if eol, done
mov value,x 'text chr
call #enter_data 'enter chr
jmp #:text 'loop
:done sub w,#1 wc 'get data count
if_nc mov dsize,w 'if 0, reuse old data
movd :fix,dsize 'form circular buffer
:fix fixinda 0,0 '(no instruction-modification problem with 1:4 threading)
parse_data_ret ret
enter_data incmod w,#dmax wc 'check if data limit exceeded
if_c jmp #cmd_error 'if data limit exceeded, error
mov inda++,value 'store value in data
enter_data_ret ret
'
'
' Parse hex
'
parse_hex call #parse_next 'try to parse hex
if_z jmp #cmd_error 'if no hex, error
parse_hex_ret ret
'
'
' Parse line (@spa), z=0 if hex (value)
'
parse_next addspa #1 'advance to next chr
parse mov value,#0 wz 'z=1
call #skip_spaces wz 'skip any spaces (preserve z)
:loop popar x 'get chr
call #check_hex 'check hex
if_c shl value,#4 'if hex, append nibble and loop
if_c or value,x
if_c jmp #:loop wz 'z=0
subspa #1 'repoint to non-hex chr
call #skip_spaces wz 'skip any post-hex spaces (preserve z)
call #check_hex 'check hex
if_c popa x 'if hex, back up to space chr
cmpr x,#"a"-1 wc 'make non-hex chr uppercase
if_c cmp x,#"z"+1 wc
if_c sub x,#"a"-"A"
parse_next_ret
parse_ret ret
'
'
' Skip spaces (@spa)
'
skip_spaces popar x 'skip space chr(s)
cmp x,#" " wz
if_z jmp #skip_spaces
subspa #1 'back up to non-space chr
skip_spaces_ret ret wz 'restore z
'
'
' Check hex (x), c=1 if hex (x)
'
check_hex cmpr x,#"0"-1 wc '"0".."9" -> $0..$9
if_c cmp x,#"9"+1 wc
if_c add x,#"A"-"9"-1
if_nc cmpr x,#"A"-1 wc '"A".."F" -> $A..$F
if_c cmp x,#"F"+1 wc
if_c add x,#"a"-"A"
if_nc cmpr x,#"a"-1 wc '"a".."f" -> $A..$F
if_c cmp x,#"f"+1 wc
if_c sub x,#"a"-10
check_hex_ret ret
'
'
' Print range (v1..v2)
'
tx_range1 mov v1,view 'view..view + v2
tx_range2 and v2,amask 'v1..v1 + v2
add v2,v1
tx_range call #check_range 'check range
mov view,v1 'set address
:line mov value,view 'print 5-digit address
mov hsize,#5
call #tx_hex
call #tx_dspace 'print "- "
mov x,wsize 'get number of words on line
rev x,#32-5
mov v1,z
max v1,x
mov v2,v1 'get number of ascii bytes on line
shl v2,shift
sub z,v1 'update number of words left
setptra view 'print hex words
:hex call #rdxxxx
mov hsize,wsize
shl hsize,#1
call #tx_hex
call #tx_space
djnz v1,#:hex
setptra #spquote_ 'print " '"
call #tx_string
setptra view 'print ascii bytes
:ascii rdbyte x,ptra++
cmp x,#" " wc 'visible chr?
if_nc cmpr x,#"~" wc
if_c mov x,#"." 'substitute "." for non-visible chrs
call #tx
djnz v2,#:ascii
getptra view 'update address
setptra #quotecr_ 'print "'" + cr
call #tx_string
call #rx_check 'check key hit
if_z tjnz z,#:line 'if no key hit and more words left, print another line
tx_range1_ret
tx_range2_ret
tx_range_ret ret
'
'
' Print string (@ptra)
'
tx_string addptra base 'add data base pointer
tx_string_loop rdbyte x,ptra++ 'get chr
tx_string_ret tjz x,#0 'if 0, done
test x,#$80 wz 'substring?
if_nz notb tx_string_loop,#8 'toggle ptra/ptrb
if_nz setptrb x 'ptrb points to substring
if_nz addptrb base
if_nz jmp #tx_string_loop 'start substring or resume string
cmp x,#"`" wz 'long tab?
if_z subr y,#32-16
if_nz cmp x,#"~" wz 'short tab?
if_z add y,#16
:tab if_z call #tx_space
if_z djnz y,#:tab
if_z call #tx_dspace
if_z jmp #tx_string_loop
cmp x,#13 wz 'cr?
if_z call #tx_crlf
if_z mov y,#0
if_nz call #tx 'other?
if_nz add y,#1
jmp #tx_string_loop
'
'
' Print hex (value)
'
tx_hex mov y,hsize 'pre-rotate to get 1st nibble in top
shl y,#2
ror value,y
mov y,hsize 'print nibbles
:loop rol value,#4
mov x,value
call #tx_nib
djnz y,#:loop
tx_hex_ret ret
'
'
' Print "- "
'
tx_dspace mov x,dspace
jmp #tx
'
'
' Print space
'
tx_space mov x,#" "
jmp #tx
'
'
' Print nibble (x)
'
tx_nib and x,#$F 'isolate nibble
cmp x,#$A wc 'alpha or numeric?
if_c add x,#"0" 'numeric
if_nc add x,#"A"-$A 'alpha
'
'
' Transmit chr (x)
'
tx shl x,#1 'insert start bit
setb x,#9 'set stop bit
getcnt w 'get initial time
:loop add w,period 'add bit period to time
passcnt w 'loop until bit period elapsed
shr x,#1 wc 'get next bit into c
setpc tx_pin 'write c to tx pin
tjnz x,#:loop 'loop until bits done
tx_dspace_ret
tx_space_ret
tx_nib_ret
tx_ret ret
'
'
' Receive chr (x)
'
rx call #rx_check 'wait for rx chr
if_z jmp #rx
rx_ret ret
'
'
' Check receiver, z=0 if chr (x)
'
rx_check or rx_tail,#$80 'if start or rollover, reset tail
getspb rx_temp wz 'if head uninitialized, z=1
if_nz cmp rx_temp,rx_tail wz 'if head-tail mismatch, byte ready, z=0
if_nz getspa rx_temp 'preserve spa
if_nz setspa rx_tail 'get tail
if_nz popar x 'get byte at tail
if_nz getspa rx_tail 'update tail
if_nz setspa rx_temp 'restore spa
rx_check_ret ret
'************************
'* Serial Receiver Task *
'************************
rx_task chkspb wz 'if start or rollover, reset head
if_z setspb #$80
mov rx_bits,#9 'ready for 8 data bits + 1 stop bit
neg rx_time,period 'get -0.5 period
sar rx_time,#1
jp rx_pin,#$ 'wait for start bit
subcnt rx_time 'get time + 0.5 period for initial 1.5 period delay
:bit rcr rx_data,#1 'rotate c into byte
add rx_time,period 'add 1 period
passcnt rx_time 'wait for center of next bit
getp rx_pin wc 'read rx pin into c
djnz rx_bits,#:bit 'loop until 8 data bits + 1 stop bit received
shr rx_data,#32-8 'align byte
pushb rx_data 'store byte at head, inc head
jmp #rx_task 'wait for next byte
'**********************
'* Baud Detector Task *
'**********************
baud_task movd ctr,rx_pin 'set ctra to time rx pin states
:loop notb ctr,#5 wc 'if 1,0 sample set, c=0
setctra ctr '($20 -> 10000001001 -> 1, 6x 0, 1x 1, 2x 0, 1)
if_nc mov limh,buff0 'if 1,0 sample set,
if_nc shr limh,#4 '..make window from 1st 0 (6x if $20)
if_nc neg liml,limh
if_nc add limh,buff0
if_nc add liml,buff0
if_nc mov comp,buff1 'if 1,0 sample set,
if_nc mul comp,#6 '..normalize 2nd 1 (1x if $20) to 6x
if_nc cmpr comp,limh wc '..check if within window
if_nc cmp comp,liml wc
if_nc mov comp,buff2 'if 1,0 sample set,
if_nc mul comp,#3 '..normalize 2nd 0 (2x if $20) to 6x
if_nc cmpr comp,limh wc '..check if within window
if_nc cmp comp,liml wc
if_nc add buff0,buff2 'if $20,
if_nc shr buff0,#3 '..compute period from 6x 0 and 2x 0
if_nc mov period,buff0 '..update period
mov buff0,buff1 'scroll sample buffer
mov buff1,buff2
:wait getcosa buff2 'wait for next sample
tjnz buff2,#:loop
jmp #:wait
'*************
'* Constants *
'*************
base long $55C 'start of byte data
h0001FFFF long $0001FFFF 'memory limit
crlf long 1<<18 + $0A<<10 + $0D 'cr/lf
dspace long 1<<18 + " "<<10 + "-" 'dash/space
ctr long %100_01001 'ctr configuration for timing low on rx pin
'*************
'* Variables *
'*************
reserves
w res 1 'main task
x res 1
y res 1
z res 1
v1 res 1
v2 res 1
value res 1
view res 1
enter res 1
pin res 1
dsize res 1
hsize res 1
wsize res 1
shift res 1
amask res 1
rx_pin res 1
tx_pin res 1
rx_tail res 1 'serial receiver task
rx_temp res 1
rx_time res 1
rx_data res 1
rx_bits res 1
buff0 res 1 'baud detector task
buff1 res 1
buff2 res 1
limh res 1
liml res 1
comp res 1
period res 1
One thing I'm are curious Why You not implemented Intel HEX loader in monitor with checksum cheking.
That have ben nice to use as Loader from any Terminal program.
Ps. In 8080 assembly it is only some lines of code.
It is more universally accessible than the binary/HMAC-signed downloader because it sends and receives only standard ASCII characters $20..$7E (space.."~").
Some programming languages, serial interfaces, and OS's have issues with sending and receiving full binary ($00..$FF). For this reason, you might have to jump through some hoops to get the more-efficient binary downloader working on a given host system. The monitor, on the other hand, can talk to anything that speaks serial, without concern over non-ASCII characters. It is so simple that it can't NOT work on any host machine that has a serial port. Plus, it doesn't force an ordered protocol, but is conversational in operation. I've been using the Parallax Serial Terminal program to talk to it as well as PUTTY, which is free on the 'net and very tidy.
My thinking might be a little anachronistic, but I've seen many host-level systems which are big on brains and storage, but for which the serial interfaces were fleeting afterthoughts, and full binary can trigger unwanted events. The monitor will play politely and offer no offense to any host.
The reason I put a help menu in the monitor was so that you could quickly get command syntax without having to refer to any documents. You might launch the monitor from within an app you want to debug and you'll need to search memory for a string of data to get your bearings. The help menu will be handy then.
Here is the ROM now:
=== Propeller II Monitor ===
>0.e7f
00000- 50 72 6F 70 32 2E 30 20 00 20 7C 0C 03 D0 7C 0C 'Prop2.0 . |...|.'
00010- 45 FE C1 0D E3 B6 FC 0C 01 C2 7C 0C 01 C2 7C 0D 'E.........|...|.'
00020- 01 C2 FC 80 1F C2 7C 62 01 E0 FC 30 66 0C A8 80 '......|b...0f...'
00030- 01 CA 7C 0C 2A DE FC FA 5B C0 FC 1C 7C FA BC A0 '..|.*...[...|...'
00040- 5B C0 FC 1C 7C FA BC 80 01 FA FC 28 FA F0 FC A0 '[...|......(....'
00050- 5B C0 FC 1C 01 C8 7C 62 2A 00 64 1C B2 C8 7C 61 '[.....|b*.d...|a'
00060- 01 C8 FC 34 10 F0 FC F6 02 F1 FC A0 08 F0 7C 86 '...4..........|.'
00070- 52 C8 E8 A0 01 C8 7C 62 25 52 FC 1C DA B4 FC 0C 'R.....|b%R......'
00080- 25 52 FC 1C DF B4 FC 0C 25 52 FC 1C DB B4 FC 0C '%R......%R......'
00090- 25 52 FC 1C B2 C8 7C 61 01 C8 FC 34 17 F0 FC F6 '%R....|a...4....'
000A0- 35 00 7C 1C 0D F6 FC 0C 62 F6 BC 80 63 C6 BC FF '5.|.....b...c...'
000B0- 37 4F FC 0C 00 00 4C 1C 04 F0 FC A0 DB B2 FC 0C '7O....L.........'
000C0- DA B0 FC 0C 44 3E C0 0D DA B2 FC 0C 01 F0 7C E1 '....D>........|.'
000D0- 01 CA CC 27 DC AE FC 0C DB B0 FC 0C DA B0 FC 0C '...'............'
000E0- 2B F0 FC F6 B2 D8 7C 0C 66 F0 BC A0 20 F2 FC A0 '+.....|.f... ...'
000F0- 5B C0 E8 1C D6 AC D4 0D DB B0 D4 0C DA B0 D4 0C '[...............'
00100- 01 F4 FC 34 38 F2 FC F6 C1 F4 7C 08 37 F0 FC F6 '...48.....|.7...'
00110- 40 0E C0 0D 70 00 04 E0 C1 EC 53 08 6B F0 3C 08 '@...p.....S.k.<.'
00120- E0 02 FC 0C 6B D4 3C 0C 67 00 04 E0 03 F0 FC A0 '....k.<.g.......'
00130- 6B EC 13 08 6B F4 BC 0A 49 F4 7C FA 48 F0 FC F6 'k...k...I.|.H...'
00140- 03 1C 7C 0C 42 0E C0 0D E0 00 FC 0C 30 F2 FC 08 '..|.B.......0...'
00150- C1 F4 FC 08 7A F2 28 86 6D D8 28 0C 41 FE FF 0F '....z.(.m.(.A...'
00160- 01 DC 7C 0C C1 F0 7C 08 C1 F0 7C 08 71 E0 BC 6A '..|...|...|.q..j'
00170- 73 E4 A8 6A 08 DC D4 A0 6F DC 3C 0C 25 52 FC 1C 's..j....o.<.%R..'
00180- 0D F8 FC 0C 25 52 FC 1C 0C F8 FC 0C 7D F8 3C 85 '....%R......}.<.'
00190- 00 00 7C 1C 00 02 00 00 C0 C6 2D 00 00 00 00 08 '..|.......-.....'
001A0- 50 00 00 00 00 00 00 03 00 02 00 00 80 16 1E 40 'P..............@'
001B0- 80 0E BE 8F A0 16 00 C0 D0 01 00 00 C0 16 00 00 '................'
001C0- 80 0E 00 00 80 16 00 00 10 07 00 00 5B B4 00 00 '............[...'
001D0- CA E0 FD 0C 46 96 FC 1C 00 9E FE 08 02 9E 7E F8 '....F.........~.'
001E0- B3 9E 7E 0C 4F CB BD A0 02 CA FD 2C 13 CA FD 28 '..~.O......,...('
001F0- 01 CA FD 80 1E 9E FE 28 08 00 7C 0C 10 9E FE F4 '.......(..|.....'
00200- 1D 9E FE F4 21 9E FE F4 00 30 7D 08 02 00 7C 1C '....!....0}...|.'
00210- 35 96 FC 1C 00 9E FE A0 E4 CA 3D E1 C1 9F F2 01 '5.........=.....'
00220- 36 9E FE 6C 4C A6 FC 1C 11 00 54 1C 41 1E C0 0D '6..lL.....T.A...'
00230- 07 CF 15 E0 F6 EF 87 A0 9A EE 93 6C 01 C6 FD A0 '...........l....'
00240- 0E 00 7C 1C C1 9F FE 01 4C A6 FC 1C 1D CA FD F6 '..|.....L.......'
00250- 0E 00 7C 1C 2C C6 7D F8 35 96 FC 1C 40 1E C0 0D '..|.,.}.5...@...'
00260- E7 0E 16 E0 F6 EF 97 A0 54 2E FD 1C 40 0E C0 0D '........T...@...'
00270- FF 0E 16 E0 F6 EF 97 A0 0F 99 FC 54 60 C8 FD A0 '...........T`...'
00280- 35 96 FC 1C FF 00 04 E0 08 CA FD A0 41 06 C0 0D '5...........A...'
00290- F6 9F 86 A0 08 9E FE 24 C1 9F 7E 00 2F CA FD F6 '.......$..~./...'
002A0- 0E 00 7C 1C E4 CC BD A0 03 CC FD 2C 80 9E FE A0 '..|........,....'
002B0- 4C A6 FC 1C E4 9E BE A0 3F 9E FE 60 38 9E 7E 86 'L.......?..`8.~.'
002C0- 00 9E FE A0 38 00 54 1C 04 C8 7D 61 08 CC F1 24 '....8.T...}a...$'
002D0- E6 9E B2 A0 4C A6 FC 1C 3E 00 54 1C 40 0E C0 0D '....L...>.T.@...'
002E0- F7 FE 15 E0 F6 EF 97 A0 40 0E C0 0D 9B EE 15 E0 '........@.......'
002F0- F6 EF 97 A0 00 C6 FD A0 00 C8 FD A0 00 00 7C 1C '..............|.'
00300- 4F 0F 3E 14 01 C8 FD 80 03 C8 7D 62 99 98 A8 80 'O.>.......}b....'
00310- 3F C8 7D 62 07 99 E8 54 54 2E E9 1C 00 00 7C 1C '?.}b...TT.....|.'
00320- 53 5E C0 0D 0F 2F 16 E0 F9 01 0C E0 F6 EF 8B A0 'S^.../..........'
00330- F7 9F 82 A0 0B 9E FE 24 F7 9F 82 6C 12 9E FE 20 '.......$...l... '
00340- 03 EE C3 28 4F EF 83 6C F6 EF 83 80 0E 00 0C E0 '...(O..l........'
00350- F6 9F 82 A0 4F A1 BE A0 02 A0 FE 24 4F A1 BE 6C '....O......$O..l'
00360- 13 A0 FE 20 0A 9E FE 28 50 9F BE 6C 4F EF 83 80 '... ...(P..lO...'
00370- FB 01 0C E0 F6 EF 93 80 40 0E C0 0D F7 8E 16 E0 '........@.......'
00380- F6 EF 97 A0 64 7E C0 0D 07 47 15 E0 4D 9F BE A0 '....d~...G..M...'
00390- 4C 9F BE 6C 4B 9F BE 60 4D 9F BE 6C 4B A1 BE A0 'L..lK..`M..lK...'
003A0- 05 A0 FE 24 4B A1 BE 6C 0E A0 FE 24 4B A1 BE 6C '...$K..l...$K..l'
003B0- 19 A0 FE 20 50 9F BE 80 F7 9F 86 80 F6 9F 86 80 '... P...........'
003C0- 4E 9F BE 80 49 A1 BE A0 48 A1 BE 60 47 A1 BE 68 'N...I...H..`G..h'
003D0- 49 9D BE A0 48 9D BE 68 4E A1 BE 60 47 9D BE A0 'I...H..hN..`G...'
003E0- 0B 9C FE 24 47 9D BE 6C 09 9C FE 24 47 9D BE 6C '...$G..l...$G..l'
003F0- 16 9C FE 20 4E A1 BE 80 4D 9D BE A0 4C 9B BE A0 '... N...M...L...'
00400- 4B 99 BE A0 4A 97 BE A0 49 95 BE A0 48 93 BE A0 'K...J...I...H...'
00410- 47 91 BE A0 4F 97 BE 80 4F 8F BE A0 50 8F BE 80 'G...O...O...P...'
00420- 40 0E C0 0D 47 EF 15 E0 F6 EF 97 80 00 00 7C 1C '@...G.........|.'
00430- 00 00 00 00 00 02 00 00 6A 6A 6A 6A 67 E6 09 6A '........jjjjg..j'
00440- 85 AE 67 BB 72 F3 6E 3C 3A F5 4F A5 7F 52 0E 51 '..g.r.n<:.O..R.Q'
00450- 8C 68 05 9B AB D9 83 1F 19 CD E0 5B 98 2F 8A 42 '.h.........[./.B'
00460- 91 44 37 71 CF FB C0 B5 A5 DB B5 E9 5B C2 56 39 '.D7q........[.V9'
00470- F1 11 F1 59 A4 82 3F 92 D5 5E 1C AB 98 AA 07 D8 '...Y..?..^......'
00480- 01 5B 83 12 BE 85 31 24 C3 7D 0C 55 74 5D BE 72 '.[....1$.}.Ut].r'
00490- FE B1 DE 80 A7 06 DC 9B 74 F1 9B C1 C1 69 9B E4 '........t....i..'
004A0- 86 47 BE EF C6 9D C1 0F CC A1 0C 24 6F 2C E9 2D '.G.........$o,.-'
004B0- AA 84 74 4A DC A9 B0 5C DA 88 F9 76 52 51 3E 98 '..tJ...\...vRQ>.'
004C0- 6D C6 31 A8 C8 27 03 B0 C7 7F 59 BF F3 0B E0 C6 'm.1..'....Y.....'
004D0- 47 91 A7 D5 51 63 CA 06 67 29 29 14 85 0A B7 27 'G...Qc..g))....''
004E0- 38 21 1B 2E FC 6D 2C 4D 13 0D 38 53 54 73 0A 65 '8!...m,M..8STs.e'
004F0- BB 0A 6A 76 2E C9 C2 81 85 2C 72 92 A1 E8 BF A2 '..jv.....,r.....'
00500- 4B 66 1A A8 70 8B 4B C2 A3 51 6C C7 19 E8 92 D1 'Kf..p.K..Ql.....'
00510- 24 06 99 D6 85 35 0E F4 70 A0 6A 10 16 C1 A4 19 '$....5..p.j.....'
00520- 08 6C 37 1E 4C 77 48 27 B5 BC B0 34 B3 0C 1C 39 '.l7.LwH'...4...9'
00530- 4A AA D8 4E 4F CA 9C 5B F3 6F 2E 68 EE 82 8F 74 'J..NO..[.o.h...t'
00540- 6F 63 A5 78 14 78 C8 84 08 02 C7 8C FA FF BE 90 'oc.x.x..........'
00550- EB 6C 50 A4 F7 A3 F9 BE F2 78 71 C6 12 00 2A 59 '.lP......xq...*Y'
00560- 2B 57 2C 4E 32 2E 3B 2F 55 3A A1 4D AD 4C AE 48 '+W,N2.;/U:.M.L.H'
00570- AF 54 B0 5A B1 52 9E 51 BD 3F 00 38 00 38 20 24 '.T.Z.R.Q.?.8.8 $'
00580- 2E 3C 2F 53 3A 82 40 8F 2A 96 2B 9F 2D AD 4C AE '.</S:.@.*.+.-.L.'
00590- 48 AF 54 B0 5A B1 52 80 23 B6 7C BB 5C 00 39 00 'H.T.Z.R.#.|.\.9.'
005A0- 39 20 3D 2F 51 3A 5F 3E 5F 3C 77 5E 00 0D 0D 3D '9 =/Q:_>_<w^...='
005B0- 3D 3D 20 50 72 6F 70 65 6C 6C 65 72 20 49 49 20 '== Propeller II '
005C0- 4D 6F 6E 69 74 6F 72 20 3D 3D 3D 0D 0D 00 3F 20 'Monitor ===...? '
005D0- 2D 20 48 65 6C 70 0D 07 00 48 69 74 20 53 50 41 '- Help...Hit SPA'
005E0- 43 45 00 20 20 27 00 27 0D 00 20 2D 0D 80 7B 61 'CE. '.'.. -..{a'
005F0- 64 72 7B 2E 61 64 72 7D 7D 80 7B 64 61 74 7B 20 'dr{.adr}}.{dat{ '
00600- 64 61 74 7D 7D 80 61 64 72 80 0D 7E 48 55 42 8E 'dat}}.adr..~HUB.'
00610- 92 60 56 69 65 77 0D 92 2F 9E 60 53 65 61 72 63 '.`View../.`Searc'
00620- 68 0D 92 3A 9E 60 45 6E 74 65 72 0D AA 2E AA 5B 'h..:.`Enter....['
00630- 3C 2F 3E 5D AA 60 4D 6F 76 65 0D AA 2E AA 5E 60 '</>].`Move....^`'
00640- 43 68 65 63 6B 73 75 6D 0D AA 40 60 57 61 74 63 'Checksum..@`Watc'
00650- 68 0D 5B 59 2F 57 2F 4E 5D 60 42 79 74 65 2F 77 'h.[Y/W/N]`Byte/w'
00660- 6F 72 64 2F 6C 6F 6E 67 0D 7E 43 4F 47 53 8E 63 'ord/long.~COGS.c'
00670- 6F 67 2B AA 7B 2B AA 7D 60 53 74 61 72 74 0D 63 'og+.{+.}`Start.c'
00680- 6F 67 2D 60 53 74 6F 70 0D 4D 60 4D 61 70 0D 7E 'og-`Stop.M`Map.~'
00690- 50 49 4E 53 8E 7B 70 69 6E 7D 5B 48 2F 4C 2F 54 'PINS.{pin}[H/L/T'
006A0- 2F 5A 2F 52 5D 60 48 69 67 68 2F 6C 6F 77 2F 74 '/Z/R]`High/low/t'
006B0- 6F 67 67 6C 65 2F 6F 66 66 2F 72 65 61 64 0D 70 'oggle/off/read.p'
006C0- 69 6E 23 60 57 61 74 63 68 0D 70 69 6E 7C 63 66 'in#`Watch.pin|cf'
006D0- 67 60 43 6F 6E 66 69 67 75 72 65 0D 64 61 74 5C 'g`Configure.dat\'
006E0- 60 53 65 74 20 44 41 43 73 0D 7E 4D 49 53 43 8E '`Set DACs.~MISC.'
006F0- 64 61 74 2A 60 53 65 74 20 63 6C 6F 63 6B 0D 27 'dat*`Set clock.''
00700- 60 52 65 70 65 61 74 0D 51 60 51 75 69 74 0D 00 '`Repeat.Q`Quit..'
00710- 00 00 00 00 40 3C C0 0D D7 01 04 E0 00 EC D3 A0 '....@<..........'
00720- 12 CC FF 0C 12 CE FF 0C 09 CE FF 28 DB CE 7F 0C '...........(....'
00730- 92 74 FF 0C CB 22 FC 0C 0A E6 7F F8 94 56 FF 0C '.t...".......V..'
00740- CB 32 FC 0C 01 C6 FF A0 D2 BE FD 1C AA 00 FC 0C '.2..............'
00750- B2 A2 FC 0C 6F E3 FE 1C E9 1A FE 1C 2B 73 FE 1C '....o.......+s..'
00760- 2F B0 6B F8 19 00 7C 1C 0B 1B FE 1C A4 02 FC 0C '/.k...|.........'
00770- 2B 73 FE 1C 1F 00 54 1C DA 65 FD 54 B2 00 FC 0C '+s....T..e.T....'
00780- C0 84 FD 1C B2 E4 FC 0C 11 00 7C 1C DD B7 BF A0 '..........|.....'
00790- E0 65 FD 54 B2 3E FC 0C C0 84 FD 1C 38 00 7C 1C '.e.T.>......8.|.'
007A0- 2A 73 FE 1C 35 00 68 1C DD B9 BF A0 B2 84 FC 0C '*s..5.h.........'
007B0- C0 84 FD 1C 39 00 7C 1C 01 C6 FF A2 02 C6 EB A2 '....9.|.........'
007C0- 04 C6 EB A0 D2 BE FD 1C 17 00 7C 1C 0F B8 FF A0 '..........|.....'
007D0- 49 DD FE 1C 12 00 7C 1C FF B8 FF A0 49 DD FE 1C 'I.....|.....I...'
007E0- 17 00 7C 1C FF B8 FF A0 4A DD FE 1C 18 00 7C 1C '..|.....J.....|.'
007F0- DB B9 BF A0 4C DD FE 1C 18 00 7C 1C DE B7 BF A0 '....L.....|.....'
00800- E5 B9 BF A0 C7 A2 FD 1C 0E 45 FE 1C B2 B6 7F 0C '.........E......'
00810- 00 00 04 E0 00 B0 FF A0 E5 CC FD 1C F6 BB 07 86 '................'
00820- 4B 00 68 1C E3 B7 BF 80 DC B7 3F 87 3F 00 78 1C 'K.h.......?.?.x.'
00830- DB BD BF A0 E5 BD BF 60 18 00 7C 1C E1 B1 BF E9 '.......`..|.....'
00840- 42 00 4C 1C E1 B9 BF A0 E4 B9 BF 2C DB B9 BF 80 'B.L........,....'
00850- 39 00 7C 1C C7 A2 FD 1C 01 B2 FF A0 DB BF BF A0 '9.|.............'
00860- E5 BF BF 60 0E 45 FE 1C 59 B2 7F FA E1 B5 BF A0 '...`.E..Y.......'
00870- 01 B4 FF 80 B3 BE 7F 0C F6 BB 87 A0 E7 D0 FD 1C '................'
00880- 5A B4 FF F6 13 BE FF 0C 18 00 7C 1C D8 B3 BF A0 'Z.........|.....'
00890- C7 A2 FD 1C 27 53 FE 1C E5 BB BF 4C E5 BB BF 60 '....'S.....L...`'
008A0- 3C B2 7F 86 DB B1 AB A0 DD B7 AB A0 D8 BB AB A0 '<...............'
008B0- DD B7 3F 85 DA B1 B3 A0 E4 B1 B3 2C D8 B7 B3 80 '..?........,....'
008C0- D8 BB B3 80 7E CA F1 6C 7E CE F1 6C B2 B6 7F 0C '....~..l~..l....'
008D0- B3 BA 7F 0C E5 CC FD 1C E7 D0 FD 1C 71 B4 FF F6 '............q...'
008E0- 7E CA F1 6C 7E CE F1 6C 18 00 7C 1C C7 A2 FD 1C '~..l~..l..|.....'
008F0- B2 B6 7F 0C E5 CC FD 1C DD B3 BF 80 79 B4 FF F6 '............y...'
00900- D9 BB BF A0 08 C4 FF A0 85 1B FF 1C 16 00 7C 1C '..............|.'
00910- E6 C6 FD 52 01 C4 FF A0 E4 C6 E9 50 E3 C5 AB A0 '...R.......P....'
00920- 01 C4 EB 2C E0 CC FD 1C DD B5 BF A0 85 1B FF 1C '...,............'
00930- 90 3D FF 1C A2 55 FF 1C 16 00 54 1C E0 CC FD 1C '.=...U....T.....'
00940- DA BB 3F 86 89 00 68 1C 86 00 7C 1C B2 FA FC 0C '..?...h...|.....'
00950- 6F E3 FE 1C 00 B6 7F 0C 9F 43 FF 1C 20 B0 7F 86 'o........C.. ...'
00960- 92 00 54 1C 16 00 7C 1C E0 B6 7F 0C 27 53 FE 1C '..T...|.....'S..'
00970- DD B3 BF A0 00 BA FF A0 2B B0 7F 86 27 53 EA 1C '........+...'S..'
00980- DD B3 3F 0C 18 00 7C 1C 01 B6 FF 0C 03 B6 7F 0C '..?...|.........'
00990- 17 00 7C 1C 07 B2 FF A0 90 3D FF 1C D9 B1 BF A0 '..|......=......'
009A0- 01 B0 FF 0D D9 B1 3F 86 30 B0 CF A0 31 B0 F3 A0 '......?.0...1...'
009B0- 4D B0 EB A0 96 3D FF 1C 01 B2 FF 85 A2 00 4C 1C 'M....=........L.'
009C0- 16 00 7C 1C DA 66 FD 52 DB 66 E9 52 D9 66 E9 52 '..|..f.R.f.R.f.R'
009D0- D8 66 E9 52 D6 66 E9 50 DB C1 BF A0 D6 C0 7F 0D '.f.R.f.P........'
009E0- A5 00 68 1C 17 00 7C 1C 27 53 FE 1C E3 B6 7F 0C '..h...|.'S......'
009F0- 23 B6 FF 0C DD B7 3F E8 18 00 7C 1C D5 B6 7F 0C '#.....?...|.....'
00A00- 17 00 7C 1C B2 5C FD 0C 6F E3 FE 1C 16 00 7C 1C '..|..\..o.....|.'
00A10- B4 A4 7F 0C C1 B4 FF 00 00 B4 7F F8 C1 B2 FF 00 '................'
00A20- D8 B3 BF 6E C1 00 54 1C DA 01 3C 1C E5 B7 BF 4C '...n..T...<....L'
00A30- E5 B7 BF 60 E5 B9 BF 4C E5 B9 BF 60 DB B9 3F 85 '...`...L...`..?.'
00A40- 1D 00 70 1C DC B5 BF A0 DB B5 BF 84 E4 B5 BF 28 '..p............('
00A50- 01 B4 FF 80 00 00 7C 1C 02 C6 7F 61 9A CB FD 0C '......|....a....'
00A60- 9A CF FD 0C 04 C6 7F 61 9B CB FD 0C 9B CF FD 0C '.......a........'
00A70- E3 C9 BF A0 01 C8 FF 28 E3 CB BF A0 01 CA FF 84 '.......(........'
00A80- D3 CB BF 6C E5 BD BF 60 E5 BF BF 60 00 00 7C 1C '...l...`...`..|.'
00A90- D6 B6 7F 0D 00 BA CF A0 01 BA F3 A0 E6 00 7C 1C '..............|.'
00AA0- B2 B6 7F 0C C1 BA FF 00 00 00 7C 1C C1 BB 7F 00 '..........|.....'
00AB0- 00 00 7C 1C A2 00 FC 0C 3E B0 FF A0 96 3D FF 1C '..|.....>....=..'
00AC0- 9F 43 FF 1C 27 B0 7F 86 F4 00 54 1C 18 B0 FF 0E '.C..'.....T.....'
00AD0- 96 3D D7 1C EF 00 54 1C 0A 01 7C 1C 9F 43 FF 1C '.=....T...|..C..'
00AE0- 0D B0 7F 86 09 01 68 1C 08 B0 7F 86 7F B0 57 86 '......h.......W.'
00AF0- 01 01 68 1C 20 B0 7F 85 7E B0 4F E1 F3 00 70 1C '..h. ...~.O...p.'
00B00- AA B0 7F 0C 16 00 7C 0D A6 02 F0 0C 96 3D CF 1C '......|......=..'
00B10- F3 00 7C 1C 16 00 7C 0E A8 B0 57 0C 96 3D D7 1C '..|...|...W..=..'
00B20- 90 3D D7 1C 18 B0 D7 0C 96 3D D7 1C A6 02 D4 0C '.=.......=......'
00B30- F3 00 7C 1C AA 00 FC 0C A2 00 FC 0C D4 B1 BF A0 '..|.............'
00B40- 96 3D FF 1C 00 00 7C 1C 00 AE FF A0 00 00 04 E0 '.=....|.........'
00B50- 2A 73 FE 1C 23 4D D6 1C 20 B0 7F 86 10 01 68 1C '*s..#M.. .....h.'
00B60- 27 B0 7F 86 1E 01 54 1C A4 04 FC 0C 1A B0 FF 0C ''.....T.........'
00B70- 27 B0 7F 86 10 01 68 1C 1E B1 7F F8 D8 BB BF A0 ''.....h.........'
00B80- 23 4D FE 1C 16 01 7C 1C 01 AE FF 85 D7 C3 8F A0 '#M....|.........'
00B90- E1 43 BE 54 00 00 04 E4 00 00 7C 1C 11 AE FF E9 '.C.T......|.....'
00BA0- 1D 00 70 1C DD ED 93 A0 00 00 7C 1C 2A 73 FE 1C '..p.......|.*s..'
00BB0- 1D 00 68 1C 00 00 7C 1C A4 02 FC 0C 00 BA FF A2 '..h...|.........'
00BC0- 3A 7D FE 1E 18 B0 FF 0C 3F 91 FE 1C 04 BA F3 2C ':}......?......,'
00BD0- D8 BB B3 68 2D 01 70 1E A6 02 FC 0C 3A 7D FE 1E '...h-.p.....:}..'
00BE0- 3F 91 FE 1C 1A B0 F3 0C 60 B0 7F E1 7B B0 73 85 '?.......`...{.s.'
00BF0- 20 B0 F3 84 00 00 7C 1C 18 B0 FF 0C 20 B0 7F 86 ' .....|..... ...'
00C00- 3A 01 68 1C A6 02 FC 0C 00 00 7C 1E 2F B0 7F E1 ':.h.......|./...'
00C10- 3A B0 73 85 07 B0 F3 80 40 B0 4F E1 47 B0 73 85 ':.s.....@.O.G.s.'
00C20- 20 B0 F3 80 60 B0 4F E1 67 B0 73 85 57 B0 F3 84 ' ...`.O.g.s.W...'
00C30- 00 00 7C 1C DE B7 BF A0 E5 B9 BF 60 DB B9 BF 80 '..|........`....'
00C40- C7 A2 FD 1C DB BD BF A0 DE BB BF A0 05 C4 FF A0 '................'
00C50- 85 1B FF 1C 8E 3D FF 1C E3 B1 BF A0 1B B0 FF 3C '.....=.........<'
00C60- DA B7 BF A0 D8 B7 BF 4C DB B9 BF A0 E4 B9 BF 2C '.......L.......,'
00C70- DB B5 BF 84 B2 BC 7F 0C E5 CC FD 1C E3 C5 BF A0 '................'
00C80- 01 C4 FF 2C 85 1B FF 1C 90 3D FF 1C 5A B7 FF F6 '...,.....=..Z...'
00C90- B2 0E FD 0C 6F E3 FE 1C B2 BC 7F 0C C1 B0 FF 00 '....o...........'
00CA0- 20 B0 7F 85 7E B0 4F E1 2E B0 F3 A0 96 3D FF 1C ' ...~.O......=..'
00CB0- 63 B9 FF F6 12 BC FF 0C B2 16 FD 0C 6F E3 FE 1C 'c...........o...'
00CC0- A2 55 FF 1C 4E B5 6B FA 00 00 7C 1C B4 A4 7F 0C '.U..N.k...|.....'
00CD0- C1 B0 FF 00 00 B0 7F F8 80 B0 7F 62 28 E1 D6 0C '...........b(...'
00CE0- B3 B0 57 0C B5 A4 57 0C 70 01 54 1C 60 B0 7F 86 '..W...W.p.T.`...'
00CF0- 10 B2 EB E0 7E B0 57 86 10 B2 EB 80 90 3D EB 1C '....~.W......=..'
00D00- 7B B3 EB F6 8E 3D EB 1C 70 01 68 1C 0D B0 7F 86 '{....=..p.h.....'
00D10- 0B 1B EA 1C 00 B2 EB A0 96 3D D7 1C 01 B2 D7 80 '.........=......'
00D20- 70 01 7C 1C E2 B3 BF A0 02 B2 FF 2C D9 BB BF 20 'p.|........,... '
00D30- E2 B3 BF A0 04 BA FF 24 DD B1 BF A0 92 3D FF 1C '.......$.....=..'
00D40- 89 B3 FF F6 00 00 7C 1C D5 B1 BF A0 96 01 7C 1C '......|.......|.'
00D50- 20 B0 FF A0 96 01 7C 1C 0F B0 FF 60 0A B0 7F 85 ' .....|....`....'
00D60- 30 B0 F3 80 37 B0 CF 80 01 B0 FF 2C 69 B1 FF 0C '0...7......,i...'
00D70- 0D AE FF 0C F3 AF BF 80 0D AE 7F 0C 01 B0 FF 29 '...............)'
00D80- DC CE 7F 0C 99 B1 7F FA 00 00 7C 1C A2 55 FF 1C '..........|..U..'
00D90- 9F 01 68 1C 00 00 7C 1C 80 D0 FF 68 17 D2 FF 0E '..h...|....h....'
00DA0- E8 D3 17 86 16 D2 D7 0C A2 D0 57 0C 18 B0 D7 0C '..........W.....'
00DB0- 16 D0 D7 0C A2 D2 57 0C 00 00 7C 1C 17 00 7C 0E '......W...|...|.'
00DC0- A3 00 E9 0C 09 D8 FF A0 F3 D5 BF A4 01 D4 FF 38 '...............8'
00DD0- B0 CD FF F8 0C D4 FF 0C 01 D6 FF 30 F3 D5 BF 80 '...........0....'
00DE0- 0D D4 7F 0C D6 CC 7F 0D B2 D9 FF F6 18 D6 FF 28 '...............('
00DF0- AB D6 7F 0C AB 01 7C 1C E6 AD BF 54 25 AD FF 0D '......|....T%...'
00E00- F0 AC 7F 0C ED E1 8F A0 04 E0 CF 28 F0 E3 8F A4 '...........(....'
00E10- ED E1 8F 80 ED E3 8F 80 EE E5 8F A0 06 E4 CF 10 '................'
00E20- F0 E5 0F E1 F1 E5 0F 85 EF E5 8F A0 03 E4 CF 10 '................'
00E30- F0 E5 0F E1 F1 E5 0F 85 EF DB 8F 80 03 DA CF 28 '...............('
00E40- ED E7 8F A0 EE DB BF A0 EF DD BF A0 3A DE FF 0C '............:...'
00E50- BB DF 7F FA CF 01 7C 1C 5C 05 00 00 FF FF 01 00 '......|.\.......'
00E60- 0D 28 04 00 2D 80 04 00 89 00 00 00 78 CF 68 9D '.(..-.......x.h.'
00E70- 3D 3D 20 45 6E 64 20 6F 66 20 52 4F 4D 20 3D 3D '== End of ROM =='
It is now 128 bytes shorter than it used to be, since I've used this time during full-chip verification being done by Beau and Open Silicon to pack things more efficiently.
Here is the binary/HMAC-signed loader (it's only $70 longs and starts at $000):
'********************************************************
'* *
'* Propeller II ROM Booter *
'* *
'* Version 0.1 *
'* *
'* 11/01/2012 *
'* *
'********************************************************
CON
rx_pin = 91
tx_pin = 90
spi_cs = 89
spi_ck = 88
spi_di = 87
spi_do = 86
base = $E80
DAT
'
'
' Version (@$000)
'
byte "Prop2.0 "
'
'
' Shut down (@$008)
'
org
clkset h001+offset 'set clock to rc slow
cogstop h200+offset 'stop cog0
offset
'
'
' Entry, read fuses (@$010)
'
org
reps #256,@:fuse 'ready to read 256 fuses
setport #rx_pin 'set rx_pin port for booting
cogid fuse_read nr 'read fuses (172 fuses + 84 zeros)
cogid fuse_read nr,wc '(last iteration initializes cnt to $00000000_00000001)
add fuse_read,#1
test fuse_read,#$1F wz
:fusex rcr fuses,#1
:fuse if_z add :fusex,h200
cogid spi_read nr 'disable fuses and enable cnt (spi_read[10..0] = 0)
'
'
' Attempt to boot from serial
'
jnp monitor_ptr,#boot_flash 'if rx_pin is low, skip serial and boot from flash
call #rx_bit 'measure low rx calibration pulses (host $F9 -> %1..010011111..)
mov threshold,delta 'and calculate threshold
call #rx_bit '(any timeout results in flash boot)
add threshold,delta
h001 shr threshold,#1 '(9 lsb's are $001)
mov count,#250 'ready to receive/verify 250 lfsr bits
:lfsrin call #rx_bit 'receive bit ($FE/$FF) into c
test lfsr,#$01 wz 'get lfsr bit into nz
if_c_eq_z jmp #boot_flash 'if mismatch, boot from flash
test lfsr,#$B2 wc 'advance lfsr
rcl lfsr,#1
djnz count,#:lfsrin 'loop for next bit in
mov count,#250+8 'ready to transmit 250 lfsr bits + 8 version bits
:lfsrout cmp count,#8 wz 'if last 8 bits, set lfsr so that version will be output
if_z mov lfsr,#$52 '$52 results in version $20 being sent (%00000100)
test lfsr,#$01 wz 'get lfsr/version bit into nz, z=1 on last iteration
call #wait_rx 'wait for rx low (convey incoming $F9 on rx_pin to $FE/$FF on tx_pin)
clrp #tx_pin 'make tx low
call #wait_rx 'wait for rx high
setpnz #tx_pin 'make tx lfsr/version bit
call #wait_rx 'wait for rx low
setp #tx_pin 'make tx high
call #wait_rx 'wait for rx high
test lfsr,#$B2 wc 'advance lfsr
rcl lfsr,#1
djnz count,#:lfsrout 'loop for next bit out
jmp #load 'serial handshake done, attempt to load from serial (z=1)
'
'
' Wait for rx low/high - if timeout, attempt to boot from flash
'
wait_rx getcnt time 'ready timeout
add time,timeout
:waitpxx waitpne rx_mask,rx_mask wc 'wait for rx low/high with timeout
notb :waitpxx,#23 'toggle waitpeq/waitpne
wait_rx_ret if_nc ret 'return if not timeout (boot_flash follows)
'
'
' Attempt to boot from flash
'
boot_flash mov count,#4 'ready for 3 resets and 1 read command
:cmd setp #spi_cs 'spi_cs high
clrp #spi_ck 'spi_ck low
reps #32,@:bit 'ready for 32 command bits
clrp #spi_cs 'spi_cs low
cmpr count,#1 wc 'first 3 commands = $FF_FF_FF_FF (reset)
if_nc rol spi_read,#1 wc,wz 'last command = $03_00_00_00 (read from 0), z=0
setpc #spi_di
setp #spi_ck 'cycle spi_ck
:bit clrp #spi_ck
djnz count,#:cmd 'loop for next spi command
'
'
' Load from serial (z=1) or flash (z=0)
'
load setptra loader_pgm 'load loader into base+$000..$7DF, HMAC into base+$7E0..$7FF
mov count,h200 'ready to input $200 longs
:long mov bits,#32 'ready to input 32 data bits
:bit if_z call #rx_bit 'input serial bit (serial mode)
if_nz getp #spi_do wc 'input spi_do (flash mode)
if_nz setp #spi_ck 'high spi_ck (flash mode)
if_nz clrp #spi_ck 'low spi_ck (flash_mode)
rcl data,#1 'shift bit into long
djnz bits,#:bit 'loop, adequate time for next flash bit
wrlong data,ptra++ 'store long in hub ram (ptra=base+$800 after)
djnz count,#:long 'loop for next long (count=0 after)
'
'
' Compute loader HMAC signature for loader authentication
'
' base+$000..$7DF = loader ($1F8 longs)
' base+$7E0..$7FF = loader HMAC signature (8 longs)
' base+$800..$81F = fuses, 1st half are HMAC key (8 longs)
' base+$820..$83F = proper HMAC signature (8 longs)
' base+$840..$843 = sha256 command interface (1 long)
'
reps #8,#1 'store 128-bit key + 44 extra fuses + 84 zero bits
setinda fuses 'into base+$800..$81F
wrlong inda++,ptra++ '(ptra = base+$820, afterwards)
wrlong count,sha256_ptr 'clear sha256 command
setcog #1 'launch sha256 in cog1
coginit sha256_pgm,sha256_ptr
setinda begin_hmac 'do sha256 commands to compute proper loader hmac
mov count,#3 'ready for 3 commands: begin_hmac, hash_bytes, read_hash
:cmd wrlong inda++,sha256_ptr 'set command
:wait rdlong data,sha256_ptr wz 'wait for command done
tjnz data,#:wait
djnz count,#:cmd 'loop for next command (count=0, z=1 after)
cogstop h001 'done with sha256, stop cog1
'
'
' If loader authenticates, run it
'
reps #8,@:cmp 'verify loader hmac signature (z=1 on entry)
setcog #0 'ready to relaunch cog0 with loader/monitor
rdlong bits,ptra[-$10] 'get loader hmac signature long
rdlong data,ptra++ 'get proper hmac signature long
:cmp if_z cmp bits,data wz 'compare, z=1 if authenticated
if_z coginit loader_pgm,loader_ptr 'if loader authenticated, relaunch cog0 with loader
'
'
' Authentication failed, hide fuses and clear memory
'
reps #$20000/8,@:clr 'clear all memory
cogid monitor_pgm nr 'hide fuses (bit 10 set)
wrlong count,ptra++ '(count=0)
:clr wrlong count,ptra++
'
'
' If key <> 0, shut down - else, monitor
'
or fuses+0,fuses+1 wz 'check if 128-bit key = 0
if_z or fuses+2,fuses+3 wz
if_nz mov monitor_pgm,#$008 'if key <> 0, shut down
coginit monitor_pgm,monitor_ptr 'relaunch cog0 with shut down or monitor
'
'
' Receive bit (c) - compare incoming pulse to threshold
'
rx_bit call #wait_rx 'wait for rx low
getcnt delta 'get time
call #wait_rx 'wait for rx high
subcnt delta 'get time delta
cmp delta,threshold wc 'compare time delta to threshold
rx_bit_ret ret
'
'
' Constants
'
fuse_read long $200 '(gets modified to $300)
timeout long 20_000_000 / 1000 * 150 '150ms @20MHz (rcfast)
rx_mask long 1 << (rx_pin & $1F)
lfsr long "P"
spi_read long $03_000000
h200 long $200
begin_hmac long 1<<30 + (($004<<2)-1)<<17 + base+$800 'begin_hmac, loads key at base+$800 (4 longs)
hash_bytes long 2<<30 + (($1F8<<2)-1)<<17 + base+$000 'hash_bytes, hashes message at base+$000 ($1F8 longs)
read_hash long 3<<30 + base+$820 'read_hash, writes hash at base+$820 (8 longs)
sha256_pgm long $1D0 'sha256 program address
sha256_ptr long base+$840 'sha256 parameter (points to command)
loader_pgm long base+$000 'loader program address
loader_ptr long base+$800 'loader parameter (points to fuses)
monitor_pgm long $55C+$1B4 'monitor program address
monitor_ptr long tx_pin<<9 + rx_pin 'monitor parameter (conveys pins)
'
'
' Variables
'
fuses res 8
count res 1
bits res 1
data res 1
time res 1
delta res 1
threshold res 1
Here is the SHA-256/HMAC program used to authenticate code (thanks to Pedward for making this happen):
'********************************************************
'* *
'* Propeller II ROM SHA-256/HMAC *
'* *
'* Version 0.1 *
'* *
'* 11/01/2012 *
'* *
'********************************************************
'
' Usage: commandlong := 0 'pre-clear command long
' cognew($1D0, @commandlong) 'start SHA-256/HMAC in new cog
'
' Start here for HMAC: commandlong := 1<<30 + (keysize-1)<<17 + @key 'start HMAC with key of keysize bytes (1..64)
' repeat while commandlong '(wait for command done)
'
' Start here for SHA-256: commandlong := 2<<30 + (msgsize-1)<<17 + @msg 'hash msg of msgsize bytes (1..8192)
' repeat while commandlong '(wait for command done)
'
' {issue more 2<<30 commands if msg > 8192 bytes}
'
' commandlong := 3<<30 + @hashbuffer 'read resulting hash into hashbuffer (32 bytes)
' repeat while commandlong '(wait for command done)
'
' {hasbuffer now contains result, ready for new 1<<30 or 2<<30 command}
'
DAT
org
setf #%0_1111_0000 'configure movf for sbyte0 -> {dbyte3,dbyte2,dbyte1,dbyte0,dbyte3,...}
call #init_hash 'init hash, clear hmac mode, reset byte count
'
'
' Command Loop
'
command rdlong x,ptra 'wait for command (%cc_nnnnnnnnnnnnn_ppppppppppppppppp)
tjz x,#command
setptrb x 'get pointer (%ppppppppppppppppp)
mov count,x 'get count (%nnnnnnnnnnnnn)
shl count,#2
shr count,#2+17
add count,#1 '+1 for 1..8192 range
shr x,#32-2 'get command (%cc)
cachex 'invalidate cache for fresh rdbytec's
djz x,#begin_hmac '1 = begin hmac, pointer @key (count+1 bytes, 1..64)
djz x,#hash_bytes '2 = hash bytes, pointer @message (count+1 bytes, 1..8192)
djz x,#read_hash '3 = read hash, pointer @hashbuffer (32 bytes)
done wrlong zero,ptra 'clear command to signal done
jmp #command 'get next command
'
'
' Begin HMAC
'
begin_hmac call #end_hash 'end any hash in progress
:ipad mov x,#$00 'get and hash ipad key (full block)
cmpr count,bytes wc 'after key bytes, hash $00's to fill block
if_c rdbytec x,ptrb++
xor x,#$36 'xor bytes with ipad ($36)
call #hash_byte '(last iteration triggers hash_block, z=1)
if_nz jmp #:ipad
reps #16,#2 'save opad key
setinds opad_key,w
mov indb,inda++
xor indb++,opad 'xor bytes with opad ($5C)
mov hmac,#1 'set hmac mode
jmp #done
'
'
' Hash Bytes
'
hash_bytes rdbytec x,ptrb++ 'hash bytes
call #hash_byte
djnz count,#hash_bytes
jmp #done
'
'
' Read Hash
'
read_hash tjz hmac,#:not 'if not hmac, output hash
call #end_hash 'hmac, end current hash
reps #16,#1 'get opad key into w[0..15] (full block)
setinds w,opad_key
mov indb++,inda++
call #hash_block 'hash opad key
reps #8,#1 'get hashx[0..7] into w[0..7]
setinds w,hashx
mov indb++,inda++
movd hash_byte,#w+8 'account for opad key and hashx bytes
mov bytes,#64+32 '(1-1/2 blocks, 1/2 block needs end_hash)
:not call #end_hash 'end current hash
setinda hashx 'store hashx[0..7] at pointer, big-endian
mov count,#8
:out reps #4,#2
mov x,inda++
rol x,#8
wrbyte x,ptrb++
djnz count,#:out
jmp #done
'
'
' End Hash - hash $80, any $00's needed to get to offset $38, then 8-byte length
'
end_hash mov length,bytes 'get message length in bits
shl length,#3
mov x,#$80 'hash end-of-message byte ($80)
:fill call #hash_byte '(may trigger hash_block)
mov x,bytes 'hash any $00's needed to get to offset $38
and x,#$3F
cmp x,#$38 wz
mov x,#$00
if_nz jmp #:fill
:len test bytes,#$04 wc 'hash 8-byte length, big-endian
if_c rol length,#8 '(hash four $00's, then four length bytes)
if_c mov x,length
call #hash_byte '(last iteration triggers hash_block)
if_nz jmp #:len
reps #8,#1 'save hash[0..7] into hashx[0..7]
setinds hashx,hash
mov indb++,inda++
init_hash reps #8,#1 'copy hash_init[0..7] into hash[0..7]
setinds hash,hash_init
mov indb++,inda++
mov hmac,#0 'clear hmac mode
mov bytes,#0 'reset byte count
init_hash_ret
end_hash_ret ret
'
'
' Hash Byte - add byte to w[0..15] and hash block if full (z=1)
'
hash_byte movf w,x 'store byte into w[0..15], big-endian
add bytes,#1 'increment byte count
test bytes,#$03 wz 'every 4th byte, increment w pointer
if_z add hash_byte,d0
test bytes,#$3F wz 'every 64th byte, reset w pointer
if_z movd hash_byte,#w
if_z call #hash_block 'every 64th byte, hash block
hash_byte_ret ret
'
'
' Hash Block - first extend w[0..15] into w[16..63] to generate schedule
'
hash_block reps #48,@:sch 'i = 16..63
setinds w+16,w+16-15+7 'indb = @w[i], inda = @w[i-15+7]
setinda --7 's0 = (w[i-15] -> 7) ^ (w[i-15] -> 18) ^ (w[i-15] >> 3)
mov indb,inda--
mov x,indb
rol x,#18-7
xor x,indb
ror x,#18
shr indb,#3
xor indb,x
add indb,inda 'w[i] = s0 + w[i-16]
setinda ++14 's1 = (w[i-2] -> 17) ^ (w[i-2] -> 19) ^ (w[i-2] >> 10)
mov x,inda
mov y,x
rol y,#19-17
xor y,x
ror y,#19
shr x,#10
xor x,y
add indb,x 'w[i] = s0 + w[i-16] + s1
setinda --5 'w[i] = s0 + w[i-16] + s1 + w[i-7]
:sch add indb++,inda
' Load variables from hash
reps #8,#1 'copy hash[0..7] into a..h
setinds a,hash
mov indb++,inda++
' Do 64 hash iterations on variables
reps #64,@:itr 'i = 0..63
setinds k+0,w+0 'indb = @k[i], inda = @w[i]
mov x,g 'ch = (e & f) ^ (!e & g)
xor x,f
and x,e
xor x,g
mov y,e 's1 = (e -> 6) ^ (e -> 11) ^ (e -> 25)
rol y,#11-6
xor y,e
rol y,#25-11
xor y,e
ror y,#25
add x,y 't1 = ch + s1
add x,indb++ 't1 = ch + s1 + k[i]
add x,inda++ 't1 = ch + s1 + k[i] + w[i]
add x,h 't1 = ch + s1 + k[i] + w[i] + h
mov y,c 'maj = (a & b) ^ (b & c) ^ (c & a)
and y,b
or y,a
mov h,c
or h,b
and y,h
mov h,a 's0 = (a -> 2) ^ (a -> 13) ^ (a -> 22)
rol h,#13-2
xor h,a
rol h,#22-13
xor h,a
ror h,#22
add y,h 't2 = maj + s0
mov h,g 'h = g
mov g,f 'g = f
mov f,e 'f = e
mov e,d 'e = d
mov d,c 'd = c
mov c,b 'c = b
mov b,a 'b = a
add e,x 'e = e + t1
mov a,x 'a = t1 + t2
:itr add a,y
' Add variables back into hash
reps #8,#1 'add a..h into hash[0..7]
setinds hash,a
add indb++,inda++
hash_block_ret ret
'
'
' Defined data
'
zero long 0
d0 long 1 << 9
opad long $36363636 ^ $5C5C5C5C
hash_init long $6A09E667, $BB67AE85, $3C6EF372, $A54FF53A, $510E527F, $9B05688C, $1F83D9AB, $5BE0CD19 'fractionals of square roots of primes 2..19
k long $428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5 'fractionals of cube roots of primes 2..311
long $D807AA98, $12835B01, $243185BE, $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174
long $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA
long $983E5152, $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967
long $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E, $92722C85
long $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819, $D6990624, $F40E3585, $106AA070
long $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3
long $748F82EE, $78A5636F, $84C87814, $8CC70208, $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2
'
'
' Undefined data
'
hmac res 1
bytes res 1
count res 1
length res 1
opad_key res 16
hash res 8
hashx res 8
w res 64
a res 1
b res 1
c res 1
d res 1
e res 1
f res 1
g res 1
h res 1
x res 1
y res 1
And here's the monitor, shrunk and improved:
[code]
'********************************************************
'* *
'* Propeller II ROM Monitor *
'* *
'* Version 0.1 *
'* *
'* 11/01/2012 *
'* *
'********************************************************
'
' Usage: cognew($738, tx_pin << 9 + rx_pin) 'start monitor in new cog
'
cmd_loop call #parse 'parse next term
cmd_go if_nz jmp #cmd_hex 'if hex, branch
movd pinx,#z 'pin update redirected to z
setptra #branch1_ 'not hex, vector by chr
call #vector 'if returns, no match
cmd_hex mov v1,value 'hex, save v1
movd pinx,#pin 'pin update okay
setptra #branch2_ 'vector by chr
call #vector 'if returns, no match
jmp #cmd_view2 'view data
cmd_range call #parse_next 'hex., get hex
if_z jmp #cmd_viewp2 'if no hex, view data
mov v2,value 'hex.hex, save v2
setptra #branch3_ 'vector by chr
call #vector 'if returns, no match
jmp #cmd_view3 'view data
'
'
' Byte/word/long data
'
cmd_byte mov wsize,#1 wz 'set byte mode, z=0
cmd_word if_z mov wsize,#2 wz 'set word mode, z=0
cmd_long if_z mov wsize,#4 'set long mode
call #set_size
jmp #cmd_next 'next command
'
'
' View data
'
cmd_viewl mov v2,#$F '<enter> (eol), show line of data
call #tx_range1
jmp #cmd_new
cmd_viewp mov v2,#$FF '. (more), show page of data
call #tx_range1
jmp #cmd_next
cmd_viewp2 mov v2,#$FF 'addr. (more), show page of data
call #tx_range2
jmp #cmd_loop
cmd_view2 mov v2,v1 'addr, show unit of data
cmd_view3 call #tx_range 'addr.addr, show range of data
jmp #cmd_loop
'
'
' Search
'
cmd_search mov v1,view '/, search from view to end
cmd_search2 mov v2,amask 'addr/, search from address to end
cmd_search3 call #check_range 'addr.addr/, search range
call #parse_data 'parse data string
:start setptra v1 'start search, point to search address
setinda 0 'point to search data
mov x,#0 'reset word match counter
:word call #rdxxxx 'get memory word
cmp value,inda++ wz 'compare against search data word
if_z jmp #:match 'if word match, check if string match
add v1,wsize 'word mismatch, advance search address
cmp v1,v2 wz,wc 'at end of range?
if_be jmp #:start 'if not, start next search
:match incmod x,dsize wc 'word match, increment match counter
if_nc jmp #:word 'if more words to match, compare next word
mov v2,dsize 'got string match
shl v2,shift 'v1 = start of found data
add v2,v1 'v2 = end of found data
jmp #cmd_view3 'show found data
'
'
' Enter data
'
cmd_enter3 call #check_range 'addr.addr:, check range, z=words to fill
mov y,#1 'set fill flag
cmd_enter2 mov enter,v1 'addr:, set enter address
and enter,amask 'trim enter address (in case cmd_enter2)
cmd_enter call #parse_data ':, parse data
tjnz y,#:go 'if not fill, set z to data size
mov z,dsize
add z,#1
:go setptrb enter 'get pointer
:loop mov value,inda++ 'get word from string data
call #wrxxxx 'store value in memory
djnz z,#:loop 'loop until enter done
mov z,v2 'get number of words
sub z,v1
shr z,shift
add z,#1
check_range_ret ret
'
'
' Set rdxxxx/wrxxxx and others by word size
'
set_size test wsize,#%010 wc 'set rdxxxx/wrxxxx by word size
setbc rdxxxx,#26
setbc wrxxxx,#26
test wsize,#%100 wc
setbc rdxxxx,#27
setbc wrxxxx,#27
mov shift,wsize 'set shift by word size
shr shift,#1
mov amask,wsize 'set amask by word size
sub amask,#1
xor amask,h0001FFFF
and view,amask 'trim view
and enter,amask 'trim enter
set_size_ret ret
rdxxxp getp v1 wc 'read pin as "0" or "1"
if_nc mov value,#0
if_c mov value,#1
rdxxxj jmp #rdxxxx_ret 'd = rdxxxx_ret/rdxxxm
rdxxxm setptra v1 'read mem
rdxxxx rdbyte value,ptra++ 'rdbyte/rdword/rdlong
rdxxxp_ret
rdxxxx_ret ret
wrxxxx wrbyte value,ptrb++ 'wrbyte/wrword/wrlong
wrxxxx_ret ret
'
'
' Input line
'
rx_line setspa #0 'point to start of line
mov x,#">" 'show prompt
call #tx
call #rx 'get first chr
cmp x,#"'" wz 'check for repeat
if_nz jmp #:first 'if not repeat, first chr
:show popar x wz 'repeat, show line
if_nz call #tx
if_nz jmp #:show
jmp #:done
call #rx_check 'check key hit
if_z tjnz z,#:line 'if no key hit and more words left, print another line
tx_range1_ret
tx_range2_ret
tx_range_ret ret
'
'
' Print string (@ptra)
'
tx_string addptra base 'add data base pointer
tx_string_loop rdbyte x,ptra++ 'get chr
tx_string_ret tjz x,#0 'if 0, done
test x,#$80 wz 'substring?
if_nz notb tx_string_loop,#8 'toggle ptra/ptrb
if_nz setptrb x 'ptrb points to substring
if_nz addptrb base
if_nz jmp #tx_string_loop 'start substring or resume string
:loop add w,period 'add bit period to time
passcnt w 'loop until bit period elapsed
shr x,#1 wc 'get next bit into c
setpc tx_pin 'write c to tx pin
tjnz x,#:loop 'loop until bits done
tx_dspace_ret
tx_space_ret
tx_nib_ret
tx_ret ret
'
'
' Receive chr (x)
'
rx call #rx_check 'wait for rx chr
if_z jmp #rx
rx_ret ret
'
'
' Check receiver, z=0 if chr (x)
'
rx_check or rx_tail,#$80 'if start or rollover, reset tail
'************************
'* Serial Receiver Task *
'************************
rx_task chkspb wz 'if start or rollover, reset head
if_z setspb #$80
mov rx_bits,#9 'ready for 8 data bits + 1 stop bit
neg rx_time,period 'get -0.5 period
sar rx_time,#1
jp rx_pin,#$ 'wait for start bit
subcnt rx_time 'get time + 0.5 period for initial 1.5 period delay
:bit rcr rx_data,#1 'rotate c into byte
add rx_time,period 'add 1 period
passcnt rx_time 'wait for center of next bit
getp rx_pin wc 'read rx pin into c
djnz rx_bits,#:bit 'loop until 8 data bits + 1 stop bit received
shr rx_data,#32-8 'align byte
pushb rx_data 'store byte at head, inc head
One thing I'm are curious Why You not implemented Intel HEX loader in monitor with checksum cheking.
That have ben nice to use as Loader from any Terminal program.
Ps. In 8080 assembly it is only some lines of code.
Because it's burdensome to have to remember how to compose Intel Hex lines and compute those checksum bytes. That's work for a computer, not a person. The monitor has a checksum command that can sum data within an address range in whatever mode you are are in (bytes/word/long) and return a 32-bit sum. You could just do one of those after loading your code and make sure it comes back with what you expect.
With Intel HEX Loader it is possible to have automated Loader that can know what place in memory I will place my data. And automatically test after every line if transfer was correct.
Because it's burdensome to have to remember how to compose Intel Hex lines and compute those checksum bytes. That's work for a computer, not a person. The monitor has a checksum command that can sum data within an address range in whatever mode you are are in (bytes/word/long) and return a 32-bit sum. You could just do one of those after loading your code and make sure it comes back with what you expect.
With Intel HEX Loader it is possible to have automated Loader that can know what place in memory I will place my data. And automatically test after every line if transfer was correct.
In steps You describe it is impossible.
Here is how you'd enter code with the monitor and get a checksum:
=== Propeller II Monitor ===
>1000:50 72 6F 70 32 2E 30 20 00 20 7C 0C 03 D0 7C 0C
>1010:45 FE C1 0D E3 B6 FC 0C 01 C2 7C 0C 01 C2 7C 0D
>1020:01 C2 FC 80 1F C2 7C 62 01 E0 FC 30 66 0C A8 80
>1030:01 CA 7C 0C 2A DE FC FA 5B C0 FC 1C 7C FA BC A0
>1000.103F^
00001C98
>
Here is Intel Hex (as used by Altera's FPGA tool):
BUT still Alteras HEX not give complete hex code. It is missing last line in it - That are not necessary in it BUT important in CPU's (computers).
It is starting point of loaded code to automatically start that Loaded program.
In time I worked with control systems only possibility to update systems I have build was 300 baud modem -- And with Intel hex it give me possibility to Update them from Malmoe even if them was placed in Stockholm.
I see Yours monitors possibility to show me HEX but still show me how I can use it with automated LOADER that can use simple serial communication ---- That Load code from serial test it if it is correct -- And then start it without my intervention.
BUT still Alteras HEX not give complete hex code. It is missing last line in it - That are not necessary in it BUT important in CPU's (computers).
It is starting point of loaded code to automatically start that Loaded program.
In time I worked with control systems only possibility to update systems I have build was 300 baud modem -- And with Intel hex it give me possibility to Update them from Malmoe even if them was placed in Stockholm.
I see Yours monitors possibility to show me HEX but still show me how I can use it with automated LOADER that can use simple serial communication ---- That Load code from serial test it if it is correct -- And then start it without my intervention.
After you load the hub memory, you can start a cog from it. For example, if you wanted to restart cog0 (which is running the monitor) with a program at $1000, you'd just type "0+1000" that would start cog0 at $1000.
So my question are -- Can I in time I Load that program in memory some 1000 Km by simple serial modem be sure as it loaded correctly so it can be Started.
If I load in my systems that Intel HEX LOADER automatically check for errors and only start that code if error free.
If not give me prompt with info on load error.
Ps. It is not as I say You need implement that -- BUT only debate with You what are usable.
Lets say I send system with Propeller II up in one balloon and then see I need update it by some serial interface as simply as possible -- BUT need have security that will work correctly.
Steps You describe -- NOT give me automated update possibility's.
It is line that are missing in Altera HEX code that give automated Start of Loaded code.
Line to start loaded code - xx checksum of this line
:0000 1000 XX
Ps 2. --- I see I need add to my signature line You wreit on --- And see it is usable
After you load the hub memory, you can start a cog from it. For example, if you wanted to restart cog0 (which is running the monitor) with a program at $1000, you'd just type "0+1000" that would start cog0 at $1000.
3. your remote loader program checks if this is correct and if not repeats the steps 1 and 2
4. if all is fine you start your code where you want with
cog+adr{+adr} - Start
so the only difference I see to your approach is that the check if the checksum is correct is done on the loader program and not inside the loaded PROP2
If you like you can even do this line by line
load the line, calc checksum, if ok proceed, else resend the line.
But for automated HEX loader it need have possibility to send from Terminal simple text file in Intel HEX that MONITOR automatically load in correct place and if al OK then START it without any extra commands from You !!
3. your remote loader program checks if this is correct and if not repeats the steps 1 and 2
4. if all is fine you start your code where you want with
so the only difference I see to your approach is that the check if the checksum is correct is done on the loader program and not inside the loaded PROP2
If you like you can even do this line by line
load the line, calc checksum, if ok proceed, else resend the line.
After you load the hub memory, you can start a cog from it. For example, if you wanted to restart cog0 (which is running the monitor) with a program at $1000, you'd just type "0+1000" that would start cog0 at $1000.
Are there any (effortless) means of patching only part of the running monitor, perhaps a new command to control that behavior, to extend (or ablate) funcionality without having to serialy re-send and re-check the entire (new) monitor then stoping, loading and restarting Cog 0?
Can that be done by the use of self modifying code that acts based on Hub memory contents detected by the running monitor and/or a specific triggering event (command, piece of code or anything else)?
I *REALLY* like the monitor - it will be extremely handy.
BUT
What did you end up doing with the direct mode of {RD|WR}{BYTE|WORD|LONG|QUAD} ?
The reason I ask that with the rom in low memory, the direct mode for the instructions would now be useless; knowing you, I expect you would have found a new use for it... I am guessing one of:
A) added the extra bit to the offset moved the direct addressing to the end of memory (by substituting all 1's instead of all 0's when it is used)
C) using it to select from among four pointer registers (instead of two)
Inquiring minds want to know...
(I suspect it is either A or B, C would be a pretty big change)
I *REALLY* like the monitor - it will be extremely handy.
BUT
What did you end up doing with the direct mode of {RD|WR}{BYTE|WORD|LONG|QUAD} ?
The reason I ask that with the rom in low memory, the direct mode for the instructions would now be useless; knowing you, I expect you would have found a new use for it... I am guessing one of:
A) added the extra bit to the offset moved the direct addressing to the end of memory (by substituting all 1's instead of all 0's when it is used)
C) using it to select from among four pointer registers (instead of two)
Inquiring minds want to know...
(I suspect it is either A or B, C would be a pretty big change)
Regards,
Bill
There is no more direct addressing for RDxxxx/WRxxxx instructions. Any immediate #S value is treated as a pointer. So, I think "A" is the answer, if I understand.
Are there any (effortless) means of patching only part of the running monitor, perhaps a new command to control that behavior, to extend (or ablate) funcionality without having to serialy re-send and re-check the entire (new) monitor then stoping, loading and restarting Cog 0?
Can that be done by the use of self modifying code that acts based on Hub memory contents detected by the running monitor and/or a specific triggering event (command, piece of code or anything else)?
(crossing my fingers and praying here
Yanomani
I don't understand exactly what you are asking, but it sounds like you would like the monitor to have a restricted mode where it only allows a subset of commands to enable a verifiable download-and-execute procedure?
I don't understand. A monitor is not a development system. You'll still need a tool on the host to compile or assemble code and download it into the P2 chip. This is really no different from the way P1 works. I guess you could use the monitor as a "development environment" if you like entering your code in hex. Is that what you mean?
I wasn't comparing P2 to P1, but P2 to most of the 32-bit embedded world.
You are certainly right...a monitor is not a development system. That's why I referred to it as a giant leap toward that end. It's a needed hook, especially if you're taking an incremental approach like I intend to do.
Of course the P2 has other resources that would also contribute to it hosting a development system: More screen memory, and more hooks to fast external memory.
Great, I can get started on P2, with my Tandy Model 100 now! Just having a little fun.
That's really not so far-fetched an idea. I did a lot of in-field program loading, testing and debugging on my Z8671 systems with a Model 100. They were a great little machine for that and easy for field personnel to understand and use. In fact, they are still being used by loyal fans:
I know it's not. I use mine on occasion for notes on a meeting and such. It's always hilarious! Many people recognize it, and the discussion is always a good one. Great little computer. Got mine mint for a song out of a thrift store last year. It was $10, and I could not resist. Great curio. Everybody comes in with laptops, cords and the usual stuff. I just turn it on, in my lap and go, near instantly. When the right people are in the building, I find the entertainment worth it. The rest of the time, it is on my desk, with somebody tinkering with it every week.
The keyboard is awesome! Heck, maybe I can gut another one for other uses. The thing runs about 20 hours on a nice set of batteries. And that's 20 hours just ON. If one is careful about not leaving it on, it's not unusual to go a week, using it when needed.
I'm now wondering whether or not somebody did an 80 or 64 column display ROM for it.
Could use the Apple as well. And I will too, just for some fun.
Honestly, a P2 with some external RAM can probably do reasonable development. Bet we see a prop only system within a year. Can't wait, because I may well gut something, get that all installed and run portable, all prop! I've been collecting displays and such for that purpose as I find them cheap.
Not sure what such a system would look like yet, but I know it will have two SD card slots, display, keyboard, battery, I/O, RAM. Lots of time for that once P2 gets completed.
NO -- My thinking was have alternate Loader -- That can load Simple ASCI HEX file from any terminal program and execute it.
If You read entire Forum You will find that many people have problems with Load Propeller from all type of wireless serial communication.
With Intel HEX Loader I talk on - that problem can be resolved.
Ps. That give possibility to use send FILE mode in terminal program to load and start code automaticaly
Ps 2. --- That system give possibility to update Program code by any type of Radio / Serial -Link.
I'd agree with this, part of the terminal access cut/paste/copy/send file facility, should include blocks of intel hex.
Things like Help strings, really do not need to be consuming valuable RAM space - put them in the terminal.
Also things like Move and Fill and even Search, those can easily be done from a configured terminal, and are so rare
the speed difference is not going to matter.
In contrast, the RAM space is precious, and needed by everyone.
Instead, put stuff in the smallest possible Monitor that allows human and non-human systems to easily slave the Prop II.
Intel hex is universal, and comes from many tools, and a tiny micro can either compose Intel Hex, or Block-copy it.
Given all intel hex lines start with :, it should be a safe syntax to include.
This also give you a simple way to transport library files, that turn this into a really useful I/O Expander.
Intel hex also allows comments, and you can append any single 'Load and go' line you like.
Any common comment tag can be used ; or // or -- ; is my first guess, but may be close to :
An example of how this would work :
; Title Comment Library Version 0.124 ; PWM Generation blah etc
-- Pin lists, link info - comments simply stripped by both/either Terminal and Monitor
:100100000C7CD0030C7C200020302E32706F72509C
:100101000D7CC2010C7CC2010CFCB6E30DC1FE45A6
:1001020080A80C6630FCE001627CC21F80FCC20149
:10010300A0BCFA7C1CFCC05BFAFCDE2A0C7CCA0197
:00000001FF
// Load above bytes, into Cog2, and Run
cog2+0100+103F ; whatever Monitor uses
; Title Comment Library Version 0.124 ; Multi Channel Quadrature Counter : Pins :
; Pin lists, link info - comments simply stripped by both/either Terminal and Monitor
:100100000C7CD0030C7C200020302E32706F72509C
:100101000D7CC2010C7CC2010CFCB6E30DC1FE45A6
:00000001FF
; Load above bytes, into Cog3, and Run
cog3+0100+102F ; whatever Monitor uses
Someone can Select the I/O Function Library(s) from the configured terminal (or just paste it in), and then connect and test with their Host,
and when they have decided that works, they paste their HEX library into their Host-loader, and they are on-air.
They do not need to know any PASM, and it is a safe-step from terminal to field, as they can compose a single text script like file as they work.
This target user is a total Prop II novice, but they are system experts. Make integration easy for them.
Comments
It is more universally accessible than the binary/HMAC-signed downloader because it sends and receives only standard ASCII characters $20..$7E (space.."~").
Some programming languages, serial interfaces, and OS's have issues with sending and receiving full binary ($00..$FF). For this reason, you might have to jump through some hoops to get the more-efficient binary downloader working on a given host system. The monitor, on the other hand, can talk to anything that speaks serial, without concern over non-ASCII characters. It is so simple that it can't NOT work on any host machine that has a serial port. Plus, it doesn't force an ordered protocol, but is conversational in operation. I've been using the Parallax Serial Terminal program to talk to it as well as PUTTY, which is free on the 'net and very tidy.
My thinking might be a little anachronistic, but I've seen many host-level systems which are big on brains and storage, but for which the serial interfaces were fleeting afterthoughts, and full binary can trigger unwanted events. The monitor will play politely and offer no offense to any host.
The reason I put a help menu in the monitor was so that you could quickly get command syntax without having to refer to any documents. You might launch the monitor from within an app you want to debug and you'll need to search memory for a string of data to get your bearings. The help menu will be handy then.
Here is the ROM now:
It is now 128 bytes shorter than it used to be, since I've used this time during full-chip verification being done by Beau and Open Silicon to pack things more efficiently.
Here is the binary/HMAC-signed loader (it's only $70 longs and starts at $000):
Here is the SHA-256/HMAC program used to authenticate code (thanks to Pedward for making this happen):
And here's the monitor, shrunk and improved:
One thing I'm are curious Why You not implemented Intel HEX loader in monitor with checksum cheking.
That have ben nice to use as Loader from any Terminal program.
Ps. In 8080 assembly it is only some lines of code.
Because it's burdensome to have to remember how to compose Intel Hex lines and compute those checksum bytes. That's work for a computer, not a person. The monitor has a checksum command that can sum data within an address range in whatever mode you are are in (bytes/word/long) and return a 32-bit sum. You could just do one of those after loading your code and make sure it comes back with what you expect.
Yes and NO.
With Intel HEX Loader it is possible to have automated Loader that can know what place in memory I will place my data. And automatically test after every line if transfer was correct.
In steps You describe it is impossible.
Here is how you'd enter code with the monitor and get a checksum:
Here is Intel Hex (as used by Altera's FPGA tool):
Both give you checksum functions, but the first seems way more human to me.
I agree with your signature line: "If your gonna construct something, make it as simple as possible yet as versatile as possible."
Thanks for that word on my signature.
BUT still Alteras HEX not give complete hex code. It is missing last line in it - That are not necessary in it BUT important in CPU's (computers).
It is starting point of loaded code to automatically start that Loaded program.
In time I worked with control systems only possibility to update systems I have build was 300 baud modem -- And with Intel hex it give me possibility to Update them from Malmoe even if them was placed in Stockholm.
I see Yours monitors possibility to show me HEX but still show me how I can use it with automated LOADER that can use simple serial communication ---- That Load code from serial test it if it is correct -- And then start it without my intervention.
After you load the hub memory, you can start a cog from it. For example, if you wanted to restart cog0 (which is running the monitor) with a program at $1000, you'd just type "0+1000" that would start cog0 at $1000.
Here is the help menu from the monitor:
I see we don't understand each other.
So my question are -- Can I in time I Load that program in memory some 1000 Km by simple serial modem be sure as it loaded correctly so it can be Started.
If I load in my systems that Intel HEX LOADER automatically check for errors and only start that code if error free.
If not give me prompt with info on load error.
Ps. It is not as I say You need implement that -- BUT only debate with You what are usable.
Lets say I send system with Propeller II up in one balloon and then see I need update it by some serial interface as simply as possible -- BUT need have security that will work correctly.
Steps You describe -- NOT give me automated update possibility's.
Bytes Address ___ Code ___________________________ Checksum.
:10 0100000C7CD0030C7C200020302E32706F7250 9C :10 0101000D7CC2010C7CC2010CFCB6E30DC1FE45 A6 :10 01020080A80C6630FCE001627CC21F80FCC201 49 :10 010300A0BCFA7C1CFCC05BFAFCDE2A0C7CCA01 97
It is line that are missing in Altera HEX code that give automated Start of Loaded code.
Line to start loaded code - xx checksum of this line
:0000 1000 XX
Ps 2. --- I see I need add to my signature line You wreit on --- And see it is usable
what I understand from Chips messages is:
1. you load memory by this command 2. then you compute the checksum with 3. your remote loader program checks if this is correct and if not repeats the steps 1 and 2
4. if all is fine you start your code where you want with
so the only difference I see to your approach is that the check if the checksum is correct is done on the loader program and not inside the loaded PROP2
If you like you can even do this line by line
load the line, calc checksum, if ok proceed, else resend the line.
Yes I understand that.
But for automated HEX loader it need have possibility to send from Terminal simple text file in Intel HEX that MONITOR automatically load in correct place and if al OK then START it without any extra commands from You !!
so with you mean the part running in the PROP2, not a program on the sender side.
There you want to be able to only do with a simple terminal.
Then this would require a kind of conditional start command in the monitor
like FORTH
Original Intel HEX loader on 8080 check every loaded line for CHECKSUM - if not correct enter Monitor command mode else load next line.
Then if it enter last line with (Byte counter 0) Start address -- Simply transfer Start address to tthis address.
Ps. That give possibility to use send FILE mode in terminal program to load and start code automaticaly
Ps 2. --- That system give possibility to update Program code by any type of Radio / Serial -Link.
Are there any (effortless) means of patching only part of the running monitor, perhaps a new command to control that behavior, to extend (or ablate) funcionality without having to serialy re-send and re-check the entire (new) monitor then stoping, loading and restarting Cog 0?
Can that be done by the use of self modifying code that acts based on Hub memory contents detected by the running monitor and/or a specific triggering event (command, piece of code or anything else)?
(crossing my fingers and praying here
Yanomani
I *REALLY* like the monitor - it will be extremely handy.
BUT
What did you end up doing with the direct mode of {RD|WR}{BYTE|WORD|LONG|QUAD} ?
The reason I ask that with the rom in low memory, the direct mode for the instructions would now be useless; knowing you, I expect you would have found a new use for it... I am guessing one of:
A) added the extra bit to the offset
moved the direct addressing to the end of memory (by substituting all 1's instead of all 0's when it is used)
C) using it to select from among four pointer registers (instead of two)
Inquiring minds want to know...
(I suspect it is either A or B, C would be a pretty big change)
Regards,
Bill
Great, I can get started on P2, with my Tandy Model 100 now! Just having a little fun. I second, "Squirt a program..." Love it!
There is no more direct addressing for RDxxxx/WRxxxx instructions. Any immediate #S value is treated as a pointer. So, I think "A" is the answer, if I understand.
I don't understand exactly what you are asking, but it sounds like you would like the monitor to have a restricted mode where it only allows a subset of commands to enable a verifiable download-and-execute procedure?
I wasn't comparing P2 to P1, but P2 to most of the 32-bit embedded world.
You are certainly right...a monitor is not a development system. That's why I referred to it as a giant leap toward that end. It's a needed hook, especially if you're taking an incremental approach like I intend to do.
Of course the P2 has other resources that would also contribute to it hosting a development system: More screen memory, and more hooks to fast external memory.
great work - I love the monitor.
I think @Sapieha is confused about the Monitor replacing boot over serial. As far as I understand the monitor is the last in the line of duty.
So after failing to boot from serial, and failing to boot from flash the monitor gets activated if NO fuses for encryption are destroyed/set.
So there is still a normals serial boot-loader, right?
Can you please confirm this?
Enjoy!
Mike
-Phil
The keyboard is awesome! Heck, maybe I can gut another one for other uses. The thing runs about 20 hours on a nice set of batteries. And that's 20 hours just ON. If one is careful about not leaving it on, it's not unusual to go a week, using it when needed.
I'm now wondering whether or not somebody did an 80 or 64 column display ROM for it.
Could use the Apple as well. And I will too, just for some fun.
Honestly, a P2 with some external RAM can probably do reasonable development. Bet we see a prop only system within a year. Can't wait, because I may well gut something, get that all installed and run portable, all prop! I've been collecting displays and such for that purpose as I find them cheap.
Not sure what such a system would look like yet, but I know it will have two SD card slots, display, keyboard, battery, I/O, RAM. Lots of time for that once P2 gets completed.
I think he's asking for an easy extension scheme. Boot monitor, "squirt the extensions over" restart, and now it's a monitor, plus some stuff.
Bet it's not hard to do once we get to play with it some.
Re: Intel HEX
Saphia just wants it to run the code sent over without further intervention. [deleted]
NO -- My thinking was have alternate Loader -- That can load Simple ASCI HEX file from any terminal program and execute it.
If You read entire Forum You will find that many people have problems with Load Propeller from all type of wireless serial communication.
With Intel HEX Loader I talk on - that problem can be resolved.
I'd agree with this, part of the terminal access cut/paste/copy/send file facility, should include blocks of intel hex.
Things like Help strings, really do not need to be consuming valuable RAM space - put them in the terminal.
Also things like Move and Fill and even Search, those can easily be done from a configured terminal, and are so rare
the speed difference is not going to matter.
In contrast, the RAM space is precious, and needed by everyone.
Instead, put stuff in the smallest possible Monitor that allows human and non-human systems to easily slave the Prop II.
Intel hex is universal, and comes from many tools, and a tiny micro can either compose Intel Hex, or Block-copy it.
Given all intel hex lines start with :, it should be a safe syntax to include.
This also give you a simple way to transport library files, that turn this into a really useful I/O Expander.
Intel hex also allows comments, and you can append any single 'Load and go' line you like.
Any common comment tag can be used ; or // or -- ; is my first guess, but may be close to :
An example of how this would work :
Someone can Select the I/O Function Library(s) from the configured terminal (or just paste it in), and then connect and test with their Host,
and when they have decided that works, they paste their HEX library into their Host-loader, and they are on-air.
They do not need to know any PASM, and it is a safe-step from terminal to field, as they can compose a single text script like file as they work.
This target user is a total Prop II novice, but they are system experts. Make integration easy for them.
You are correct.
One thing I can add to Yours comments are that many of Terminal programs have ---- Send TEXT file command inbuilt that simplify that Loading.