Welcome to the Parallax Discussion Forums, sign-up to participate.
--------------------------------------------------------------------------------------------- LMM DEBUGGER - SUPPORTED COMMANDS (Rev 1 & 2 silicon) --------------------------------------------------------------------------------------------- xxxxxx : xx xx xx xx ... <cr> DOWNLOAD: to cog/lut/hub {addr1} following {byte(s)} xxxxxx - [xxxxxx] [L] <cr> MEM LIST: from cog/lut/hub {addr1} to < {addr2} L=longs xxxxxx G <cr> GOTO: to cog/lut/hub {addr1} Q <cr> QUIT: Quit Rom Monitor and return to the User Program {addr} is on the stack Lfilename.xxx<cr> LOAD: Load file from SD (8.3 filename) returns "=" on success, "!" on failure Rfilename.xxx<cr> RUN: Run file from SD (8.3 filename) returns "!" on failure <esc><cr> TAQOZ: goto TAQOZ <cr> will repeat last MEM LIST command --------------------------------------------------------------------------------------------- Note: COG/LUT addresses are 3 digits or less and <$3FF, otherwise hub address is presumed. To list a low Hub address below $400, use a leading zero. (When calling from a user program use $1x_xxxx as only the lower 20 address bits are used)
-------------------------------------------------------------------------------------------- LMM DEBUGGER - Routines callable from users' programs -------------------------------------------------------------------------------------------- _SerialInit = $fcab8 'Serial Initialise (lmm_x & lmm_bufad must be set first) _HubTxCR = $fcae4 'Sends <cr><lf> (overwrites lmm_x) _HubTxRev = $fcaec 'Sends lmm_x with bytes reversed _HubTx = $fcaf0 'Sends lmm_x (can be up to 4 bytes) _HubHexRev = $fcb24 'Sends lmm_x with bytes reversed as Hex char(s) as defined in lmm_f _HubHex8 = $fcb28 'Sends lmm_x as Hex char(s) after setting lmm_f as 8 hex chars _HubHex = $fcb2c 'Sends lmm_x as Hex char(s) as defined in lmm_f _HubTxStrVer = $fcb9c 'Sends hub $0 terminated string at lmm_p address after setting lmm_p=##_str_vers _HubTxString = $fcba4 'Sends hub $0 terminated string at lmm_p address _HubListA2H = $fcbc4 'List/Dump line(s) from lmm_p address to lmm_p2 address after setting lmm_f=#_LIST+_ADDR2 _HubList = $fcbc8 'List/Dump line(s) from lmm_p address to lmm_p2 address according to lmm_f _HubRx = $fcb10 'Recv char into lmm_x _HubRxStrMon = $fccc4 'Recv string into hub address pointed to by lmm_bufad after setting prompt=lmm_x=#"*" & params=lmm_f=#_RXSTRING+_ECHO_+_PROMPT _HubRxString = $fcccc 'Recv string into hub address pointed to by lmm_p/lmm_bufad according to params in lmm_f _HubMonitor = $fcd78 'Calls the Monitor; uses lmm_bufad as the input buffer address _RdLongCogHub = $fcf34 'read cog/lut/hub long from lmm_p address into lmm_x, then lmm_p++ _str_vers = $fd014 'locn of the monitors hub string, $0 terminated -------------------------------------------------------------------------------------------- _HUBROM = $FC000 'ROM $FC000 _HUBBUF = $FC000 'use as RxString buffer (overwrites Booter) _HUBBUFSIZE = 80 'default size for _HUBBUF (can be 128) --------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------- LMM DEBUGGER - COG VARIABLES $1E0-$1EF -------[ LMM parameters, etc ]-------------------------------------------------------------- lmm_x = $1e0 'parameter passed to/from LMM routine (typically a value) lmm_f = $1e1 'parameter passed to LMM routine (function options; returns unchanged) lmm_p = $1e2 'parameter passed to/from LMM routine (typically a hub/cog ptr/addr) lmm_p2 = $1e3 'parameter passed to/from LMM routine (typically a 2nd hub/cog address) lmm_c = $1e4 'parameter passed to/from LMM routine (typically a count) -------[ LMM additional workareas ]------------------------------------------- lmm_w = $1e5 'workarea (never saved - short term use between calls, except _HubTx) lmm_tx = $1e6 '_HubTx lmm_hx = $1e7 '_HubHex/_HubString lmm_hx2 = $1e8 '_HubHex lmm_hc = $1e9 ' " lmm_lx = $1ea '_HubList lmm_lf = $1eb ' " lmm_lp = $1ec ' " lmm_lp2 = $1ed ' " lmm_lc = $1ee ' " lmm_bufad = $1ef '_HubRxString --------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------- LMM DEBUGGER - lmm_f CALL Modes...(b4..b0 are modifier options) -------------------------------------------------------------------------------------------- _HEX_ = 2 << 5 ' hex... _REV_ = 1 << 4 ' - reverse byte order _SP = 1 << 3 ' - space between hex output pairs '_DIGITS = 7..0 ' no. of digits to display where 0 is 8 digits _LIST = 3 << 5 ' LIST memory line (1/4 longs) from cog/hub _ADDR2 = 1 << 4 ' 1= use lmm_p2 as to-address _LONG_ = 1 << 1 ' 1=display longs xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx _RXSTRING = 5 << 5 ' RXSTRING... _ECHO_ = 1 << 4 ' - echo char _PROMPT = 1 << 3 ' - prompt (lmm_x) _ADDR = 1 << 2 ' - addr of string buffer supplied _NOLF = 1 << 1 ' - strip <lf> --------------------------------------------------------------------------------------------
Comments
- [>][ ][Esc] to enter TAQOZ
- [>][ ][Ctrl + D] to enter P2 Monitor
Thanks, Cluso! It worked.
Kind regards, Samuel Lourenço
Please point me to an example of a call to _SerialInit and a description of the contents of lmm_x for that call. I plan to use _SerialInit, _HubTx, and _HubRx from Spin. Any suggestion or "gotcha"s.
Mike
forums.parallax.com/discussion/comment/1494072/#Comment_1494072
BUT then started getting weird results. Turns out spin2 uses the registers (lmm_x etc) that the ROM code uses
Warning: The ROM Monitor uses registers $1E0-$1EF which is also used by Spin2. Therefore, it is suggested you call the ROM Monitor/Debugger as a one-way event ie do not return to your spin2 code from the monitor
Once in the monitor, the usual monitor features are available eg examine/modify cog/lut/hub memory.
Putting this together with what Chip suggested, couldn't you copy $1E0-$1EF to a buffer somewhere before calling the ROM Monitor/Debugger, and then return to a stub that copies the saved content back to $1E0-$1EF before returning to Spin2?
Perhaps a 16 word buffer declared in HUBRAM with a SETQ WRLONG combo to save and a SETQ RDLONG combo to restore.
Have to get something working first!
I had embarked on using the Tx and TxString etc, but something was slightly messing up the results whereupon Chip said they were used by spin2. Been trying ever since to get something working reliably.
Ok. I was thinking that if you were to save the contentious range before monitor and debugger calls and restore them after that there'd be nothing else to do, but there's possibly something I'm missing.
I'm reminded of the zero page use under ProDOS on the Apple II, where we have to do the same thing to avoid ProDOS stomping on our zero page variables.
The monitor not only provides an interactive monitor, it also includes serial routines for outputting characters, string, hex, crlf, dumping cog/lut/hub, reading an input character or string, together with an optional prompt character. The dump has options for reversing and bytes or longs, and includes ascii output on the line.
The input also accepts a saved dump (download) to input to cog/lut/hub too.
All while still running Spin2 code? Impressive.
I'm offering an alternative to the solution of having to load a modified version of the ROM routines.
If you need to save the state of these variables between monitor calls then you need two buffers: One to hold Spin2's variables during each call, and one to hold the monitor's variables between calls. Then the code to call and return involves 8 extra instructions (probably inline pasm2):
Of course, if there are 8 spare longs available in the Spin2 memory footprint then building this into Spin2 would be more elegant. But then I seem to recall @cgracey saying something about the top 16k being wiped for debug. If so, I hope there's an opt-out for that or all of your work here will be for nothing.
Also I have to get the SD code working again, and include write too. It’s actually done but I’ve been waiting for spin2 to get the full FAT32 file interface done.
I am heavily reliant of having my monitor (debugger) working as I can check code operation along the way. It’s so easy to just display a register or hub value, or dump a piece of memory.
The calls to the monitor are extremely simple. Just load 1-5 registers and a call into hub.
lmm_x is the data register
lmm_f is an optional function register that selects options for the specific call
lmm_p and lmm_p2 are address registers (when required)
lmm_c is an optional count register (not sure if it is still used as some features were removed due to the rom size limits)
The ROM monitor can locate and load and optionally run a binary file from the SD card but the re-loaded monitor probably will not support these routines. They will be part of my full OS.
I am having trouble with the hex routines so no examples yet.
And I have to hard-code this due to a deficiency IMHO in Chip's compiler but Chip disagrees
The monitor code is contained within a pasm object and the register/calls/parameters are contained in another object.
The demo file gives simple examples of some of the calls available.
If you call the monitor from spin2, then typing "Q<cr>" at the "*" monitor prompt will return you to the spin code.
This code may also be called from pasm code. I'll need to provide a new example for that.
Serial Monitor calling examples PST output from above examples
The calls mon.TxListA2 and mon.TxListF...
* use the mon.TxListA2 call if you want the default address range and hex display (register mon.f is set by the routine)
* set mon.f to the bit options to control the format and then use the mon.TXListF call
From the call...
* any address < $200 will be cog
* any address < $400 but >= $200 will be lut
* otherwise it will be hub
But..
* an address > $1_0000 will be $00000 in hub
Note: both mon.p and mon.p2 must have this address $1_xxxxx set, otherwise only a single line will be displayed.
From the monitor...
* any address with 3 or less digits and < $200 will be cog
* any address with 3 or less digits and < $400 but >= $200 will be lut
* any address with more than 3 digits or >= $400 will be hub
* a <cr> will display the next list block
So, all of cog/lut/hub can be displayed (and it can be input ie changed too).
The use of the lmm prefix is because I wrote this back in 2013 before the P2 had hubexec so it was running in lmm mode back then. This was even before P2-HOT.
V1.4 is the ROM code compiled for soft-loading and uses different cog registers so it can be used with spin code.