P2 ROM SERIAL ROUTINES - ROM version
pic18f2550
Posts: 400
Hello,
does anyone know how I can query the Rx status if a character is ready to be fetched?
And how do I fetch a single character.
Both functions must not block the process.
The code is from the Z80 emulator.
'+-----------------------------------------------------------------------------+ _bitper = (_clkfreq / _baudx) << 16 + 7 ' xxx 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 '+-----------------------------------------------------------------------------+ '+============[ COG VARIABLES $1E0-$1EF - ROM 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 '+-------[ 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) - ROM version ]--------------------+ _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 _hubTxStr = $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 ]-----------------------------------------------------+ _HUB_ROM = $FC000 ' ROM $FC000 _HUB_SERBUF = $FC000 '[80] Serial receive buffer (overwrites ROM Booter) _HUB_SERSIZE = 80 ' Serial receive buffer size '+-----------------------------------------------------------------------------+ '+-------[ Start Serial for P2xxxx ]-------------------------------------------+ mov lmm_bufad, ##_HUB_SERBUF ' locn of hub buffer for serial routine mov lmm_x, ##_BITPER ' sets serial baud call #\_SerialInit ' initialise serial '+-----------------------------------------------------------------------------+ waitx ##_STARTUP_DELAY ' delay to get terminal running '+-----------------------------------------------------------------------------+ '+-----------------------------------------------------------------------------+ TX_DATA mov lmm_x, Tx_Data call #\_hubTx ret '+-----------------------------------------------------------------------------+ RX_STATUS call #\_hubRxStat????? mov Rx_Stat, lmm_x ret '+-----------------------------------------------------------------------------+ RX_DATA call #\_hubRx mov Rx_Data, lmm_x ret '+-----------------------------------------------------------------------------+
Smartpinn is easier with single characters.
Comments
Hello,
I would like to ask again if there is a way to determine whether a new character was received or their number.
CP/M often asks the status and I don't want to block the whole system.
Thank you.
I would think that the RX_STATUS code below that is near the end of the code you posted would do that. Not 100% sure of that since the code it calls is not listed here.
'+-----------------------------------------------------------------------------+
RX_STATUS
call #_hubRxStat?????
mov Rx_Stat, lmm_x
ret
No, the routine is only a guess, as _hubRxStat is not defined in the constants.
Sorry i am away and on my iphone.
I created a thread about using the P2 ROM Serial routines. IIRC there is a routine that does a rxline that places any received chars into a buffer.
Yesterday I wrote something for my RPi Zero based contraption. A P2 uses a serial port to receive messages from it via a serial port. This is done without any ROM procedures, instead I read the pin status to determine if the serial port received a byte. Then I put this byte into a circular buffer. Without this buffer there were missed bytes as they can arrive faster than the main program process them.
Maybe something from this code can help. It opens 2 serial ports, one for a RPi (keyboard/mouse interface), one for MIDI and then receicves and processes this data.
https://github.com/pik33/P2-retromachine/blob/main/Propeller/retrocog.spin2
Pic33, that looks good.
I just have to see how I do it with PASM.
I will leave the (lmm) part in for debugging.
I will use a new interface for the console in/out of the CP/M bios.
I added today the standard serial pin p63 as 4th input source to the code (and removed a bug) - I wanted to do this in PASM first, but the spin is fast enough. Maybe this code will be rewritten in Pasm as I want more input sources to receive data (I want to connect analog and digital joystick to the P2)
I pulled out the important part and this is what comes out:
Now I still have to test it and convert it into PASM.
I hope I have the TX status query right.
I don't have a P2 at hand, so it's all theory.
Remember to enable output for TX (the or P_OE bit in spin, there is a particular bit# to set)
The input pin (RX) is normally floating. If the signal source is on the same board, it is OK, but if there is a long cable between the source and P2, trash happens. This is why there is this P_HIGH_15K and pinhigh in my code. This enables 15k pullup which magically removed these interferences.
pic33,
i have adjusted the code in #10 a little.
Thanks
Sending and receiving works.
I want to check whether the smart pin has sent the old byte before sending.
But that doesn't work somehow.
I don't want to wait after each byte until the byte has been sent.