So, do you think it would be better to trap overrun, too?
Took some time to get focused but no, the two types can't be combined. An overwrite could happen during the empty test. In particular, following the POLLQMT. That's not compatible.
PS: Here's what I'm using for my debug hexadecimal ascii emits. It has a tidy compare and add:
itohl
revpa'least significant first
itoh
mov bcdi, #7'most significant nibble first (zero extended)
.emit
altgn bcdi, #pa'(instruction prefix)getnib char 'retrieve next hex digit from pa register: char = pa[bcdi]cmp char, #10wcz'test if below 10, C = borrow of (D - S)if_cadd char, #"0"'ASCII encode 0-9if_ncadd char, #"a"-10'ASCII encode a-fcall #putch
djnf bcdi, #.emit
retwcz'restore C/Z flags of calling routine
I think the rev is wrong as you are reversing the bits, not bytes. Try a MOVBYTS instruction. I need the check my ROM code.
Your conversion to ASCII above uses 3 instructions here, same as mine. I suggest here you only need a CMP CHAR,#10 WC (rather than WCZ). Saves using the Z flag.
As for your prior post, I think you're right. Should be GETNIB X,Y,#0
Code to convert a nibble to an ASCII character "0".."9" "A".."F" using just the C flag...
' convert nibble to ASCII hex chargetnib x,value,#7'\ either instruction extracts only the lower nibbleand x,#$0F'/or x,#"0"cmp x,#";"wc' : -> A etcif_ncadd x,#7
";" typo as well as GETNIB to correct:
' convert nibble to ASCII hex chargetnib x,value,#0'\ either instruction extracts only the lower nibbleand x,#$0F'/or x,#"0"cmp x,#":"wc' : -> A etcif_ncadd x,#7
REV was correct for the purpose - which was to represent the sigma-delta bitstream in received bit order. Not the digit significance within an integer.
Although, I suspect this could be a valid way of displaying little endian too. We have a bad habit of calling something's LE when they're just a mishmash. LE hurts to think about sometimes.
Your conversion to ASCII above uses 3 instructions here, same as mine. I suggest here you only need a CMP CHAR,#10 WC (rather than WCZ). Saves using the Z flag.
I always restore the flags. Gives more options further up.
I just realised the implications of having 4 bits each for setting/clearing the C and Z flags.
While it's been documented for quite a long time, I missed it. It's in the document that starts with Instruction Timing, and near the end of the doc... (not sure when/where I found the doc)
The gem is the 4 bits each for setting/clearing the C and/or Z flag(s) is the same as the conditional execution bits EEEE found in each instruction.
Further down in that document are some instruction aliases...
Good idea. Having some aliases will help cement understanding of MODCZ too. An excellent example of this occurs in the google doc with the simplified list of basic inc/dec of PTRA/B.
I just realised the implications of having 4 bits each for setting/clearing the C and Z flags.
While it's been documented for quite a long time, I missed it. It's in the document that starts with Instruction Timing, and near the end of the doc... (not sure when/where I found the doc)
The gem is the 4 bits each for setting/clearing the C and/or Z flag(s) is the same as the conditional execution bits EEEE found in each instruction.
Further down in that document are some instruction aliases...
getct timeout '\ set timeout valueadd timeout, ##delay1s '/
and code to test if the timeout has been exceeded
getct timenow '\ timeout ?cmpm timeout, timenow wc'| c if timenow > timeoutif_cjmp #timed_out '/ y: timed out
Note the use of the CMPM D,#/S {wc/wz/wcz} instruction!!!
C = MSB of the result of D-S
or
pollct1wcif_cjmp #timed_out
However, that is not the whole story for using POLLCTn. Rather than polute that thread, perhaps you can edit your post. Thanks Brian Postedit: I meant me poluting the thread with discussion
Example shown for using CT1 (CT1, 2 &3 are available)
getct timeout '\ set timeout value
addct1 timeout, ##delay1s '/set CT1 event totriggerwhen CT=timeout+delay1s
Rather than polute that thread, perhaps you can edit your post.
Never had one of my posts refered to as "pollution" before.
Not sure why my post doesn't qualify as reference, but does as general discussion?
Why do I even bother!
I didn't mean it that way Really bad choice of words on my part
I didn't want to clutter that thread with general discussion (by me asking/correcting) and as I cannot edit your post, I thought I would ask if you would mind doing that. It was just missing the bit setting up the ct1 which may have caused confusion.
I have found that the SETQ value remains persistent for multiple MUXQ instructions.
Here is an example...
setq ##$0000FFFFmuxq x,y ' x -> 1122CCDDmuxq a,b ' a -> 556600FFor v,w
muxq y,b ' y -> AABB00FFmuxq b,x ' b -> 99EECCDD
x long$11223344
y long$AABBCCDD
a long$55667788
b long$99EE00FF
Hey, I didn't know MUXQ existed. I've wanted to do that operation too.
No, it won't work like that Cluso. Easy enough to test ...
Oh, I'm wrong. Yes, you can issue as many additional MUXQ's as you like. And can be interspersed with other instructions as well.
That's quite revealing. SETQ, the instruction, must be doing two things. One is moving the specified data to special Q register. The other is arming a special flag for telling certain other instructions they can use the value in Q.
MUXQ is different to the rest of those Q using instructions because it ignores that flag and always uses the value in Q irrespective of if a SETQ has been executed or not.
Here's a coupe of code snippets that might be useful.
The first one returns information of cog usage/count.
'get active cog informationmovpa,#7
.loop cogidpawc'get cog statusrcl active,#1'rotate into maskdjnfpa,#.loop
and active,#$ff'active cog maskones inuse,active 'number of cogs in use
and the second shows an example of inverting the output state of the pins used on the P2-ES board for true led indication.
'invert outputs on 56-63 for true led operationmovpa,#56
.loop wrpin ##%1000000_00_00000_0,paincmodpa,#63wzif_nzjmp #.loop
''BTW This will be done in one instruction in Rev B silicon with it's range option.'wrpin ##%1000000_00_00000_0,#56 + 7 << 6'Rev. B silicon only
What justification is there for excluding fastspin bugs from the reference Traps/Tips thread - the duplicate
label issue I just reported wasted hours of my time and is definity a nasty trap for the prop1->prop2 newcomers
till its fixed, at which point the posting can be edited to reflect that point?
The point of the thread is to alert people to issues that could bite them, whatever they are, surely?
What justification is there for excluding fastspin bugs from the reference Traps/Tips thread - the duplicate
label issue I just reported wasted hours of my time and is definity a nasty trap for the prop1->prop2 newcomers
till its fixed, at which point the posting can be edited to reflect that point?
The point of the thread is to alert people to issues that could bite them, whatever they are, surely?
Because it's a temporary problem, one that if reported gets rather rapidly fixed.
You have to ask, how relevant is this information let's say a month, or a year from now?
Whereas a trick or trap is for example forgetting that blasted # before a label, something that won't change and something we always have to look out for.
When you spend an hour trying to understand bizarre program behaviour which is very heisenbuggy, the
notion of temporary v. permanent trap is not so useful - the thread is surely a working document that
will be subject to update?
In case anyone's missed it, the spin2ui 1.3.6 version at least fails to give any warning about duplicate
labels leading to unpredictable behaviour if you accidentally create duplicates (copy and paste for example).
Comments
waitx #60
Took some time to get focused but no, the two types can't be combined. An overwrite could happen during the empty test. In particular, following the POLLQMT. That's not compatible.
It would need its own event.
You might want to make a change to recent posted code - https://forums.parallax.com/discussion/comment/1461959/#Comment_1461959
I'm pretty certain that GETNIB ,,#7 is the most significant nibble of a longword.
itohl rev pa 'least significant first itoh mov bcdi, #7 'most significant nibble first (zero extended) .emit altgn bcdi, #pa '(instruction prefix) getnib char 'retrieve next hex digit from pa register: char = pa[bcdi] cmp char, #10 wcz 'test if below 10, C = borrow of (D - S) if_c add char, #"0" 'ASCII encode 0-9 if_nc add char, #"a"-10 'ASCII encode a-f call #putch djnf bcdi, #.emit ret wcz 'restore C/Z flags of calling routine
I think the rev is wrong as you are reversing the bits, not bytes. Try a MOVBYTS instruction. I need the check my ROM code.
Your conversion to ASCII above uses 3 instructions here, same as mine. I suggest here you only need a CMP CHAR,#10 WC (rather than WCZ). Saves using the Z flag.
As for your prior post, I think you're right. Should be GETNIB X,Y,#0
Always good to have someone keep me on my toes
";" typo as well as GETNIB to correct:
' convert nibble to ASCII hex char getnib x,value,#0 '\ either instruction extracts only the lower nibble and x,#$0F '/ or x,#"0" cmp x,#":" wc ' : -> A etc if_nc add x,#7
rep #2,#8 rolnib pa,pb,#0 ror pb,#4 mov pb,pa
Although, I suspect this could be a valid way of displaying little endian too. We have a bad habit of calling something's LE when they're just a mishmash. LE hurts to think about sometimes.
I always restore the flags. Gives more options further up.
'x = $abcdefgh movbyts x,#%%0123 'x = $ghefcdab mov y,x 'y = $ghefcdab rol x,#4 'x = $hefcdabg ror y,#4 'y = $bghefcda setq ##$0f0f0f0f muxq x,y 'x = $hgfedcba 'or 'x = $abcdefgh movbyts x,#%%0123 'x = $ghefcdab mov y,x 'y = $ghefcdab rol x,#4 'x = $hefcdabg ror y,#4 'y = $bghefcda setq muxy muxq x,y 'x = $hgfedcba muxy long $0f0f0f0f
I just realised the implications of having 4 bits each for setting/clearing the C and Z flags.
While it's been documented for quite a long time, I missed it. It's in the document that starts with Instruction Timing, and near the end of the doc... (not sure when/where I found the doc)
The gem is the 4 bits each for setting/clearing the C and/or Z flag(s) is the same as the conditional execution bits EEEE found in each instruction.
Further down in that document are some instruction aliases...
MODCZ 0,_SET WZ MODCZ _CLR,0 WC MODCZ _SET,_CLR WCZ MODCZ _CLR,_SET WCZ etc
Might these be better aliases for simple setting/clearing the C and/or Z flag(s)? (Just a compiler addition)
CLR {WC/WZ/WCZ} SET {WC/WZ/WCZ} CLRSET WCZ SETCLR WCZ
There are separate aliases already for MODC c and MODZ z.
CLRSET and SETCLR are rather like DOWNUP and UPDOWN, i.e. most confusing!
Postedit: I meant me poluting the thread with discussion
Example shown for using CT1 (CT1, 2 &3 are available)
getct timeout '\ set timeout value addct1 timeout, ##delay1s '/ set CT1 event to trigger when CT=timeout+delay1s
and code to test if the timeout has been exceededpollct1 wc if_c jmp #timed_out
Not sure why my post doesn't qualify as reference, but does as general discussion?
Why do I even bother!
I didn't mean it that way
I didn't want to clutter that thread with general discussion (by me asking/correcting) and as I cannot edit your post, I thought I would ask if you would mind doing that. It was just missing the bit setting up the ct1 which may have caused confusion.
BTW It absolutely qualifies as a reference!
Indeed, I had forgotten about using the pollctx.
I'll edit it all later tonight.
No worries.
I have found that the SETQ value remains persistent for multiple MUXQ instructions.
Here is an example...
setq ##$0000FFFF muxq x,y ' x -> 1122CCDD muxq a,b ' a -> 556600FF or v,w muxq y,b ' y -> AABB00FF muxq b,x ' b -> 99EECCDD x long $11223344 y long $AABBCCDD a long $55667788 b long $99EE00FF
Chip,
Is this a legitimate use of SETQ and MUXQ ?
No, it won't work like that Cluso. Easy enough to test ...
Oh, I'm wrong. Yes, you can issue as many additional MUXQ's as you like. And can be interspersed with other instructions as well.
That's quite revealing. SETQ, the instruction, must be doing two things. One is moving the specified data to special Q register. The other is arming a special flag for telling certain other instructions they can use the value in Q.
MUXQ is different to the rest of those Q using instructions because it ignores that flag and always uses the value in Q irrespective of if a SETQ has been executed or not.
Q is maintained indefinitely.
I did test it. These are the results. It is persistent for the MUXQ instructions
'' +--------------------------------------------------------------------------+ '' | Cluso's P2 Test Program (c)2013-2019 "Cluso99" (Ray Rodrick)| '' +--------------------------------------------------------------------------+ '' RR20190201 generalised test program CON '+-------[ Select for P2-EVAL ]------------------------------------------------+ _XTALFREQ = 20_000_000 ' crystal frequency _XDIV = 2 '\ '\ crystal divider to give 10.0MHz _XMUL = 15 '| 150 MHz '| crystal / div * mul to give 150MHz _XDIVP = 1 '/ '/ crystal / div * mul /divp to give 150MHz _XOSC = %10 '15pF ' %00=OFF, %01=OSC, %10=15pF, %11=30pF '+-------[ Select for P2D2 ]---------------------------------------------------+ { _XTALFREQ = 12_000_000 ' crystal frequency _XDIV = 4 '\ '\ crystal divider to give 3.0MHz _XMUL = 99 '| 148.5MHz '| crystal / div * mul to give 297.0MHz _XDIVP = 2 '/ '/ crystal / div * mul /divp to give 148.5MHz _XOSC = %01 'OSC ' %00=OFF, %01=OSC, %10=15pF, %11=30pF } '+-----------------------------------------------------------------------------+ _XSEL = %11 'XI+PLL ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms) _XPPPP = ((_XDIVP>>1) + 15) & $F ' 1->15, 2->0, 4->1, 6->2...30->14 _CLOCKFREQ = _XTALFREQ / _XDIV * _XMUL / _XDIVP ' internal clock frequency _SETFREQ = 1<<24 + (_XDIV-1)<<18 + (_XMUL-1)<<8 + _XPPPP<<4 + _XOSC<<2 ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_00 ' setup oscillator _ENAFREQ = _SETFREQ + _XSEL ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_ss ' enable oscillator _1us = _clockfreq/1_000_000 ' 1us '------------------------------------------------------------------------------------------------ _baud = 115_200 _bitper = (_clockfreq / _baud) << 16 + 7 ' 115200 baud, 8 bits _txmode = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output _rxmode = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input enabled for smart input '------------------------------------------------------------------------------------------------ rx_pin = 63 ' pin serial receiver tx_pin = 62 ' pin serial transmitter spi_cs = 61 ' pin SPI memory select (also sd_ck) spi_ck = 60 ' pin SPI memory clock (also sd_cs) spi_di = 59 ' pin SPI memory data in (also sd_di) spi_do = 58 ' pin SPI memory data out (also sd_do) '------------------------------------------------------------------------------------------------ CON '' +--------------------------------------------------------------------------+ '' | Cluso's LMM_SerialDebugger for P2 (c)2013-2018 "Cluso99" (Ray Rodrick)| '' +--------------------------------------------------------------------------+ '' xxxxxx : xx xx xx xx ... <cr> DOWNLOAD: to cog/lut/hub {addr1} following {byte(s)} '' xxxxxx - [xxxxxx] [L] <cr> 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 '' Lffffffff[.]xxx<cr> LOAD: Load file from SD '' Rffffffff[.]xxx<cr> RUN: Load & Run file from SD '' <esc><cr> TAQOZ: goto TAQOZ '' +--------------------------------------------------------------------------+ '' LMM DEBUGGER - CALL Modes...(not all modes supported) '' +--------------------------------------------------------------------------+ _MODE = $F << 5 ' mode bits defining the call b8..b5 (b4..b0 are modifier options) _SHIFT = 5 ' shr # to extract mode bits _HEX_ = 2 << 5 ' hex... _REV_ = 1 << 4 ' - reverse byte order _SP = 1 << 3 ' - space between hex output pairs '_DIGITS = 7..0 where 8->0 ' - no. of digits to display _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 _TXSTRING = 4 << 5 ' tx string (nul terminated) from hub _RXSTRING = 5 << 5 ' rx string _ECHO_ = 1 << 4 ' - echo char _PROMPT = 1 << 3 ' - prompt (lmm_x) _ADDR = 1 << 2 ' - addr of string buffer supplied _NOLF = 1 << 1 ' - strip <lf> _MONITOR = 7 << 5 ' goto rom monitor '' +--------------------------------------------------------------------------+ '' P2 ROM SERIAL ROUTINES (HUBEXEC) '' +--------------------------------------------------------------------------+ _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 $0 terminated string at lmm_p address after setting lmm_p=##_str_vers _HubTxString = $fcba4 ' Sends $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 lmm_bufad address after setting prompt=lmm_x=#"*" & params=lmm_f=#_RXSTRING+_ECHO_+_PROMPT _HubRxString = $fcccc ' Recv string into lmm_p/lmm_bufad address 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 hub string, $0 terminated '' +--------------------------------------------------------------------------+ '' HUB ADDRESSES '' +--------------------------------------------------------------------------+ _HUBROM = $FC000 ' ROM $FC000 _HUBBUF = $FC000 ' overwrite Booter _HUBBUFSIZE = 80 ' RxString default size for _HUBBUF '' +--------------------------------------------------------------------------+ ''============[ COG VARIABLES $1E0-$1EF - MONITOR]============================= ''-------[ 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 '' +--------------------------------------------------------------------------+ '' ASCII equates '' +--------------------------------------------------------------------------+ _CLS_ = $0C _BS_ = $08 _LF_ = $0A _CR_ = $0D _TAQOZ_ = $1B ' <esc> goto TAQOZ '' +--------------------------------------------------------------------------+ DAT org 0 '+-------[ Set Xtal ]----------------------------------------------------------+ entry2 hubset #0 ' set 20MHz+ mode hubset ##_SETFREQ ' setup oscillator waitx ##20_000_000/100 ' ~10ms hubset ##_ENAFREQ ' enable oscillator '+-----------------------------------------------------------------------------+ waitx ##_clockfreq*5 ' just a delay to get pc terminal running '+-------[ Start Serial ]------------------------------------------------------+ mov lmm_bufad, ##_HUBBUF ' locn of hub buffer for serial routine mov lmm_x, ##_bitper ' sets serial baud call #_SerialInit ' initialise serial '+-----------------------------------------------------------------------------+ '' mov lmm_x, #0 ' clear screen '' call #_hubTx '+-----------------------------------------------------------------------------+ mov lmm_f, #_TXSTRING+0 ' send string, $00 terminated mov lmm_p, ##_hubstring ' must be in hub! call #_HubTxString '+=============================================================================+ '+ Test Section + '+=============================================================================+ ' SETQ tests setq ##$0000FFFF muxq x,y ' x -> 1122CCDD muxq a,b ' a -> 556600FF or v,w muxq y,b ' y -> AABB00FF muxq b,x ' b -> 99EECCDD mov lmm_x, x call #_hubHex8 mov lmm_x, #" " call #_hubTx mov lmm_x, y call #_hubHex8 call #_hubTxCR mov lmm_x, a call #_hubHex8 mov lmm_x, #" " call #_hubTx mov lmm_x, b call #_hubHex8 call #_hubTxCR '+-----------------------------------------------------------------------------+ jmp #$ ' loop here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< '+-----------------------------------------------------------------------------+ x long $11223344 y long $AABBCCDD a long $55667788 b long $99EE00FF v long $11111111 w long $22222222 fit $1E0 ' check fits in cog with lmm_x ''============[ HUB VARIABLES ]================================================= DAT orgh $4000 _hubstring byte "P2 Test Program v0006a",13,10,0
The first one returns information of cog usage/count.
'get active cog information mov pa,#7 .loop cogid pa wc 'get cog status rcl active,#1 'rotate into mask djnf pa,#.loop and active,#$ff 'active cog mask ones inuse,active 'number of cogs in use
and the second shows an example of inverting the output state of the pins used on the P2-ES board for true led indication.'invert outputs on 56-63 for true led operation mov pa,#56 .loop wrpin ##%1000000_00_00000_0,pa incmod pa,#63 wz if_nz jmp #.loop ' 'BTW This will be done in one instruction in Rev B silicon with it's range option. ' wrpin ##%1000000_00_00000_0,#56 + 7 << 6 'Rev. B silicon only
label issue I just reported wasted hours of my time and is definity a nasty trap for the prop1->prop2 newcomers
till its fixed, at which point the posting can be edited to reflect that point?
The point of the thread is to alert people to issues that could bite them, whatever they are, surely?
Because it's a temporary problem, one that if reported gets rather rapidly fixed.
You have to ask, how relevant is this information let's say a month, or a year from now?
Whereas a trick or trap is for example forgetting that blasted # before a label, something that won't change and something we always have to look out for.
notion of temporary v. permanent trap is not so useful - the thread is surely a working document that
will be subject to update?
In case anyone's missed it, the spin2ui 1.3.6 version at least fails to give any warning about duplicate
labels leading to unpredictable behaviour if you accidentally create duplicates (copy and paste for example).