Mercurial > hg > Members > kono > nitros9-code
changeset 3114:61a8ce1200ed
New mc6850 driver, based on existing sc6551 driver
author | Neal Crook <foofoobedoo@gmail.com> |
---|---|
date | Sat, 17 Oct 2015 21:21:11 +0100 |
parents | 9abc463adb1e |
children | 460fdd304adf |
files | level1/modules/mc6850.asm level1/modules/term_mc6850.asm |
diffstat | 2 files changed, 1131 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level1/modules/mc6850.asm Sat Oct 17 21:21:11 2015 +0100 @@ -0,0 +1,1045 @@ +******************************************************************** +* mc6850 Driver +* +* $Id$ +* +* Edt/Rev YYYY/MM/DD Modified by +* Comment +* ------------------------------------------------------------------ +* ????/??/?? +* NitrOS-9 2.00 distribution. +* +* 9r4 2003/01/01 Boisy G. Pitre +* Back-ported to OS-9 Level Two. +* +* 10r1 2003/??/?? Robert Gault +* Added 6809 code where it was lacking. +* +* 10r2 2004/05/03 Boisy G. Pitre +* Fixed numerous issues with 6809 and Level 1 versions. +* Tested 6809 Level 1 and Level 2. +* [NAC HACK 2015Sep08] I should have cloned this to make 6851 version +* and that's what I'll end up doing, reverting this to its former glory. +* I might even need to do 2 versions - one with handshake and one without. + + nam mc6850 + ttl mc6850 Driver + + ifp1 + use defsfile +; use scfdefs + endc + +* conditional assembly switches +TC9 set false "true" for TC-9 version, "false" for Coco 3 + +* miscellaneous definitions +DCDStBit equ %00100000 DCD status bit for SS.CDSta call +DSRStBit equ %01000000 DSR status bit for SS.CDSta call +SlpBreak set TkPerSec/2+1 line Break duration +SlpHngUp set TkPerSec/2+1 hang up (drop DTR) duration + + ifeq TC9-true +IRQBit equ %00000100 GIME IRQ bit to use for IRQ ($FF92) + else +IRQBit equ %00000001 GIME IRQ bit to use for IRQ ($FF92) + endc + + IFNE mc09 +* 6850 registers + org 0 +StatReg rmb 1 +CtlReg equ StatReg +DataReg rmb 1 + ELSE +* 6551 register definitions + org 0 +DataReg rmb 1 receive/transmit Data (read Rx / write Tx) +StatReg rmb 1 status (read only) +PRstReg equ StatReg programmed reset (write only) +CmdReg rmb 1 command (read/write) +CtlReg rmb 1 control (read/write) + ENDC + + IFNE mc09 +* Status bit definitions +Stat.IRQ equ %10000000 IRQ occurred +Stat.TxE equ %00000010 Tx data register Empty +Stat.RxF equ %00000001 Rx data register Full +Stat.Ovr equ %00100000 Rx data Overrun error +Stat.Frm equ %00010000 Rx data Framing error +Stat.Par equ %01000000 Rx data Parity error + +Stat.Err equ Stat.Ovr!Stat.Frm!Stat.Par Status error bits +Stat.Flp equ $00 all Status bits active when set +Stat.Msk equ Stat.IRQ!Stat.RxF active IRQs + ELSE +* Status bit definitions +Stat.IRQ equ %10000000 IRQ occurred +Stat.DSR equ %01000000 DSR level (clear = active) +Stat.DCD equ %00100000 DCD level (clear = active) +Stat.TxE equ %00010000 Tx data register Empty +Stat.RxF equ %00001000 Rx data register Full +Stat.Ovr equ %00000100 Rx data Overrun error +Stat.Frm equ %00000010 Rx data Framing error +Stat.Par equ %00000001 Rx data Parity error + +Stat.Err equ Stat.Ovr!Stat.Frm!Stat.Par Status error bits +Stat.Flp equ $00 all Status bits active when set +Stat.Msk equ Stat.IRQ!Stat.RxF active IRQs + ENDC + +* Control bit definitions +Ctl.Stop equ %10000000 stop bits (set=two, clear=one) +Ctl.DBit equ %01100000 see data bit table below +Ctl.RxCS equ %00010000 Rx clock source (set=baud rate, clear=external) +Ctl.Baud equ %00001111 see baud rate table below + +* data bit table +DB.8 equ %00000000 eight data bits per character +DB.7 equ %00100000 seven data bits per character +DB.6 equ %01000000 six data bits per character +DB.5 equ %01100000 five data bits per character + +* baud rate table + org $00 +BR.ExClk rmb 1 16x external clock (not supported) + org $11 +BR.00050 rmb 1 50 baud (not supported) +BR.00075 rmb 1 75 baud (not supported) +BR.00110 rmb 1 109.92 baud +BR.00135 rmb 1 134.58 baud (not supported) +BR.00150 rmb 1 150 baud (not supported) +BR.00300 rmb 1 300 baud +BR.00600 rmb 1 600 baud +BR.01200 rmb 1 1200 baud +BR.01800 rmb 1 1800 baud (not supported) +BR.02400 rmb 1 2400 baud +BR.03600 rmb 1 3600 baud (not supported) +BR.04800 rmb 1 4800 baud +BR.07200 rmb 1 7200 baud (not supported) +BR.09600 rmb 1 9600 baud +BR.19200 rmb 1 19200 baud + +* Command bit definitions +Cmd.Par equ %11100000 see parity table below +Cmd.Echo equ %00010000 local echo (set=activated) +Cmd.TIRB equ %00001100 see Tx IRQ/RTS/Break table below +Cmd.RxI equ %00000010 Rx IRQ (set=disabled) +Cmd.DTR equ %00000001 DTR output (set=enabled) + +* parity table +Par.None equ %00000000 +Par.Odd equ %00100000 +Par.Even equ %01100000 +Par.Mark equ %10100000 +Par.Spac equ %11100000 + +* Tx IRQ/RTS/Break table +TIRB.Off equ %00000000 RTS & Tx IRQs disabled +TIRB.On equ %00000100 RTS & Tx IRQs enabled +TIRB.RTS equ %00001000 RTS enabled, Tx IRQs disabled +TIRB.Brk equ %00001100 RTS enabled, Tx IRQs disabled, Tx line Break + +* V.ERR bit definitions +DCDLstEr equ %00100000 DCD lost error +OvrFloEr equ %00000100 Rx data overrun or Rx buffer overflow error +FrmingEr equ %00000010 Rx data framing error +ParityEr equ %00000001 Rx data parity error + +* FloCtlRx bit definitions +FCRxSend equ %10000000 send flow control character +FCRxSent equ %00010000 Rx disabled due to XOFF sent +FCRxDTR equ %00000010 Rx disabled due to DTR +FCRxRTS equ %00000001 Rx disabled due to RTS + +* FloCtlTx bit definitions +FCTxXOff equ %10000000 due to XOFF received +FCTxBrk equ %00000010 due to currently transmitting Break + +* Wrk.Type bit definitions +Parity equ %11100000 parity bits +MdmKill equ %00010000 modem kill option +RxSwFlow equ %00001000 Rx data software (XON/XOFF) flow control +TxSwFlow equ %00000100 Tx data software (XON/XOFF) flow control +RTSFlow equ %00000010 CTS/RTS hardware flow control +DSRFlow equ %00000001 DSR/DTR hardware flow control + +* Wrk.Baud bit definitions +StopBits equ %10000000 number of stop bits code +WordLen equ %01100000 word length code +BaudRate equ %00001111 baud rate code + +* Wrk.XTyp bit definitions +SwpDCDSR equ %10000000 swap DCD+DSR bits (valid for 6551 only) +ForceDTR equ %01000000 don't drop DTR in term routine +RxBufPag equ %00001111 input buffer page count + +* static data area definitions + org V.SCF allow for SCF manager data area +Cpy.Stat rmb 1 Status register copy +CpyDCDSR rmb 1 DSR+DCD status copy +Mask.DCD rmb 1 DCD status bit mask (MUST immediately precede Mask.DSR) +Mask.DSR rmb 1 DSR status bit mask (MUST immediately follow Mask.DCD) +CDSigPID rmb 1 process ID for CD signal +CDSigSig rmb 1 CD signal code +FloCtlRx rmb 1 Rx flow control flags +FloCtlTx rmb 1 Tx flow control flags +RxBufEnd rmb 2 end of Rx buffer +RxBufGet rmb 2 Rx buffer output pointer +RxBufMax rmb 2 Send XOFF (if enabled) at this point +RxBufMin rmb 2 Send XON (if XOFF sent) at this point +RxBufPtr rmb 2 pointer to Rx buffer +RxBufPut rmb 2 Rx buffer input pointer +RxBufSiz rmb 2 Rx buffer size +RxDatLen rmb 2 current length of data in Rx buffer +SigSent rmb 1 keyboard abort/interrupt signal already sent +SSigPID rmb 1 SS.SSig process ID +SSigSig rmb 1 SS.SSig signal code +WritFlag rmb 1 initial write attempt flag +Wrk.Type rmb 1 type work byte (MUST immediately precede Wrk.Baud) +Wrk.Baud rmb 1 baud work byte (MUST immediately follow Wrk.Type) +Wrk.XTyp rmb 1 extended type work byte + +regWbuf rmb 2 substitute for regW +RxBufDSz equ 256-. default Rx buffer gets remainder of page... +RxBuff rmb RxBufDSz default Rx buffer +MemSize equ . + +rev set 2 +edition set 10 + + mod ModSize,ModName,Drivr+Objct,ReEnt+rev,ModEntry,MemSize + + fcb UPDAT. access mode(s) + +ModName fcs "mc6850" + fcb edition + + +* These 3 bytes control how the IRQ ISR processes interrupts from this +* device +IRQPckt equ * +Pkt.Flip fcb Stat.Flp flip byte +Pkt.Mask fcb Stat.Msk mask byte + fcb $0A priority + +BaudTabl equ * + fcb BR.00110,BR.00300,BR.00600 + fcb BR.01200,BR.02400,BR.04800 + fcb BR.09600,BR.19200 + + +* NOTE: SCFMan has already cleared all device memory except for V.PAGE and +* V.PORT. Zero-default variables are: CDSigPID, CDSigSig, Wrk.XTyp. +* Entry: +* Y = address of the device descriptor +* U = address of the device memory area +* +* Exit: +* CC = carry set on error +* B = error code +Init clrb default to no error... + pshs cc,dp save IRQ/Carry status, system DP + IFNE H6309 + tfr u,w + tfr e,dp + tfr y,w save descriptor pointer + ELSE + tfr u,d get device memory area + tfr a,dp and make it the direct page + pshs y save descriptor pointer + ENDC + +* Register the ISR +* D address of the device status register +* X address of the "packet" containing the flip/mask/priority +* Y address of the device IRQ service routine +* U address of the device IRQ service routine memory + ldd <V.PORT base hardware address (=status register) + + leax IRQPckt,pc + leay IRQSvc,pc + os9 F$IRQ + + IFNE H6309 + tfr w,y recover descriptor pointer + ELSE + puls y + ENDC + + lbcs ErrExit failed to register interrupt + +DfltInfo ldd #RxBufDSz default Rx buffer size + leax RxBuff,u default Rx buffer address + std <RxBufSiz save Rx buffer size + stx <RxBufPtr save Rx buffer address + stx <RxBufGet set initial Rx buffer input address + stx <RxBufPut set initial Rx buffer output address + IFNE H6309 + addr d,x point to end of Rx buffer + ELSE + leax d,x + ENDC + stx <RxBufEnd save Rx buffer end address + subd #80 characters available in Rx buffer + std <RxBufMax set auto-XOFF threshold + ldd #10 characters remaining in Rx buffer + std <RxBufMin set auto-XON threshold after auto-XOFF + ldb #TIRB.RTS default command register + +NoDTR ldx <V.PORT get port address + + orcc #IntMasks disable IRQs while setting up hardware + +* [NAC HACK 2015Sep13] might be a problem that mc09 has no way to flush +* (virtual or real) UART fifos. + +* lda StatReg,x ensure old IRQ flags are clear +* lda DataReg,x ensure old error and Rx data IRQ flags are clear +* lda StatReg,x ... again +* lda DataReg,x ... and again + +* [NAC HACK 2015Sep13] NOPs are to keep addresses unchanged during debug + nop + nop + nop + nop + nop + nop + nop + nop + lda StatReg,x get new Status register contents + +* [NAC HACK 2015Sep16] Enable Rx interrupt + ora #$80 + sta StatReg,x + + sta <Cpy.Stat save Status copy + tfr a,b copy it... + eora Pkt.Flip,pc flip bits per D.Poll + anda Pkt.Mask,pc any IRQ(s) still pending? + +* [NAC HACK 2015Sep13] the UART model in exec09 cannot flag rx char available +* so this test will always fail. Even if I could get the i/o there to be non- +* blocking I still can't work out how I could get the UART status register to +* behave correctly.. it would need to support type-ahead. +* lbne NRdyErr yes, go report error... (device not plugged in?) + nop + nop + + puls cc,dp,pc recover IRQ/Carry status, system DP, return + +* +* +Term clrb default to no error... + pshs cc,dp save IRQ/Carry status, dummy B, system DP + IFNE H6309 + tfr u,w setup our DP + tfr e,dp + ELSE + tfr u,d + tfr a,dp + ENDC + IFEQ Level-1 + ldx >D.Proc + lda P$ID,x + sta <V.BUSY + sta <V.LPRC + ENDC + ldx <V.PORT + lda 0,x get current status +* [NAC HACK 2015Sep09] ?? + anda #^(Cmd.TIRB!Cmd.DTR) disable Tx IRQs, RTS, and DTR + ora #Cmd.RxI disable Rx IRQs + + + ldd <RxBufSiz get Rx buffer size + tsta less than 256 bytes? + beq TermExit yes, no system memory to return... + pshs u save data pointer + ldu <RxBufPtr get address of system memory + os9 F$SRtMem + puls u recover data pointer +TermExit + ldd <V.PORT base hardware address is status register + + ldx #$0000 remove IRQ table entry + leay IRQSvc,pc + puls cc recover IRQ/Carry status + os9 F$IRQ + puls dp,pc restore dummy A, system DP, return + +ReadSlp + IFEQ Level-1 + lda <V.BUSY + sta <V.WAKE + lbsr Sleep0 go suspend process... + ELSE + ldd >D.Proc process descriptor address + sta <V.WAKE save MSB for IRQ service routine + tfr d,x copy process descriptor address + IFNE H6309 + oim #Suspend,P$State,x + ELSE + ldb P$State,x + orb #Suspend + stb P$State,x + ENDC + lbsr Sleep1 go suspend process... + ENDC + ldx >D.Proc process descriptor address + ldb P$Signal,x pending signal for this process? + beq ChkState no, go check process state... + cmpb #S$Intrpt do we honor signal? + lbls ErrExit yes, go do it... +ChkState equ * + IFNE H6309 + tim #Condem,P$State,x + ELSE + ldb P$State,x + bitb #Condem + ENDC + bne PrAbtErr yes, go do it... + ldb <V.WAKE true interrupt? + beq ReadChk yes, go read the char. + bra ReadSlp no, go suspend the process + +* +* Input U = Address of device static data storage +* Y = Address of path descriptor module +* +* Output +* A = Character read +* CC = carry set on error, clear on none +* B = error code if CC.C set. +* +Read clrb default to no errors... + pshs cc,dp save IRQ/Carry status, system DP + IFNE H6309 + tfr u,w setup our DP + tfr e,dp + ELSE + tfr u,d + tfr a,dp + ENDC +ReadLoop orcc #IntMasks disable IRQs while checking Rx flow control +ReadChk lda <FloCtlRx get Rx flow control flags + beq ReadChar none, go get Rx character... + ldx <RxDatLen get Rx data count again + cmpx <RxBufMin at or below XON level? + bhi ReadChar no, go get Rx character... + ldx <V.PORT + bita #FCRxSent Rx disabled due to XOFF sent? + beq ChkHWHS no, go check hardware handshake(s)... + ldb <FloCtlTx get Tx flow control flags + bitb #FCTxBrk currently transmitting line Break? + beq NotTxBrk yes, go skip XON this time... +ReadLp2 andcc #^IntMasks turn interupts back on + bra ReadLoop +NotTxBrk equ * + IFNE H6309 + tim #Stat.TxE,StatReg,x + ELSE + pshs a + lda StatReg,x + bita #Stat.TxE + puls a + ENDC + beq ReadLp2 no, go skip XON this time... + ldb <V.XON + stb DataReg,x write XON character +ChkHWHS bita #FCRxDTR!FCRxRTS Rx disabled due to DTR or RTS? + beq RxFloClr no, go clear Rx flow control flag(s)... +* ldb CmdReg,x get current Command register contents + ldb #0 + andb #^Cmd.TIRB clear Tx IRQ/RTS/Break control bits + orb #TIRB.RTS!Cmd.DTR enable RTS and DTR, disable Tx IRQs +* stb CmdReg,x set Command register +RxFloClr clr <FloCtlRx clear Rx flow control flags +ReadChar ldb <V.ERR get accumulated errors, if any + stb PD.ERR,y set/clear error(s) in path descriptor + bne ReprtErr error(s), go report it/them... + ldd <RxDatLen get Rx buffer count + beq ReadSlp none, go sleep while waiting for new Rx data... + IFNE H6309 + decd less character we're about to grab + ELSE + subd #$0001 + ENDC + std <RxDatLen save new Rx data count + orcc #IntMasks see if this fixes the problem + ldx <RxBufGet current Rx buffer pickup position + lda ,x+ get Rx character, set up next pickup position + cmpx <RxBufEnd end of Rx buffer? + blo SetPckUp no, go keep pickup pointer + ldx <RxBufPtr get Rx buffer start address +SetPckUp stx <RxBufGet set new Rx data pickup pointer + puls cc,dp,pc recover IRQ/Carry status, dummy B, system DP, return + +* +* Module jump table +* +ModEntry lbra Init + bra Read + nop + bra Write + nop + IFNE H6309 + bra GStt + nop + ELSE + lbra GStt + ENDC + lbra SStt + lbra Term + +PrAbtErr ldb #E$PrcAbt + bra ErrExit + +ReprtErr clr <V.ERR clear error status + bitb #DCDLstEr DCD lost error? + bne HngUpErr yes, go report it... + ldb #E$Read + +* come here with cc, dp, pc stacked. +* set carry in the stacked copy of cc and return. +ErrExit equ * + IFNE H6309 + oim #Carry,,s set carry + ELSE + lda ,s + ora #Carry + sta ,s + ENDC + puls cc,dp,pc restore CC, system DP, return + +HngUpErr ldb #E$HangUp + lda #PST.DCD DCD lost flag + sta PD.PST,y set path status flag + bra ErrExit + +NRdyErr ldb #E$NotRdy + bra ErrExit + +UnSvcErr ldb #E$UnkSvc + bra ErrExit + +* +* +Write clrb default to no error... + pshs cc,dp save IRQ/Carry status, Tx character, system DP + IFNE H6309 + tfr u,w setup our DP + tfr e,dp + tfr a,e + ELSE + pshs a + tfr u,d + tfr a,dp + puls a + sta <regWbuf + ENDC + orcc #IntMasks disable IRQs during error and Tx disable checks + bra WritChr +WritLoop lda <WritFlag + beq WritFast + lbsr Sleep1 +WritFast inc <WritFlag +WritChr ldx <V.PORT + ldb <V.ERR get accumulated errors, if any + andb #DCDLstEr DCD lost error? (ignore other errors, if any) + stb PD.ERR,y set/clear error(s) in path descriptor + bne ReprtErr DCD lost error, go report it... +ChkTxFlo ldb <FloCtlTx get Tx flow control flags + bitb #FCTxBrk currently transmitting line Break? + bne WritLoop yes, go sleep a while... + lda <Wrk.Type get software/hardware handshake enables + bita #DSRFlow DSR/DTR handshake enabled? +* Changed below - BGP +* beq ChkTxFlo no, go check Tx flow control + beq ChkRxFlo no, go check Rx flow control + ldb <Cpy.Stat get copy of status register + bitb <Mask.DSR Tx disabled due to DSR? + bne WritLoop yes, go sleep a while... + bita #TxSwFlow Tx software flow control enabled? + beq ChkRxFlo no, go check pending Rx flow control + bitb #FCTxXOff Tx disabled due to received XOFF? + bne WritLoop yes, go sleep a while... +ChkRxFlo bita #RxSwFlow Rx software flow control enabled? + beq ChkTxE no, go check Tx register empty + ldb <FloCtlRx get Rx flow control flags + bitb #FCRxSend XON/XOFF Rx flow control pending? + bne WritLoop yes, go sleep a while... +ChkTxE equ * + IFNE H6309 + tim #Stat.TxE,StatReg,x + ELSE + pshs a + lda StatReg,x + bita #Stat.TxE + puls a + ENDC + beq WritLoop no, go sleep a while... + IFNE H6309 + ste DataReg,x write Tx character + ELSE + ldb <regWbuf + stb DataReg,x + ENDC + clr <WritFlag clear "initial write attempt" flag + puls cc,dp,pc recover IRQ/Carry status, Tx character, system DP, return + +GStt clrb default to no error... + pshs cc,dp save IRQ/Carry status, dummy B, system DP + IFNE H6309 + tfr u,w setup our DP + tfr e,dp + ELSE + pshs a + tfr u,d + tfr a,dp + puls a + ENDC + ldx PD.RGS,y caller's register stack pointer + cmpa #SS.EOF + beq GSExitOK yes, SCF devices never return EOF + cmpa #SS.Ready + bne GetScSiz + ldd <RxDatLen get Rx data length + beq NRdyErr none, go report error + tsta more than 255 bytes? + beq SaveLen no, keep Rx data available + ldb #255 yes, just use 255 +SaveLen stb R$B,x set Rx data available in caller's [B] +GSExitOK puls cc,dp,pc restore Carry status, dummy B, system DP, return + +GetScSiz cmpa #SS.ScSiz + bne GetComSt + ldu PD.DEV,y + ldu V$DESC,u + clra + ldb IT.COL,u + std R$X,x + ldb IT.ROW,u + std R$Y,x + puls cc,dp,pc restore Carry status, dummy B, system DP, return + +GetComSt cmpa #SS.ComSt + lbne UnSvcErr no, go report error + ldd <Wrk.Type + std R$Y,x + clra default to DCD and DSR enabled + ldb <CpyDCDSR + bitb #Mask.DCD + beq CheckDSR no, go check DSR status + ora #DCDStBit +CheckDSR bitb <Mask.DSR DSR bit set (disabled)? + beq SaveCDSt no, go set DCD/DSR status + ora #DSRStBit +SaveCDSt sta R$B,x set 6551 ACIA style DCD/DSR status in caller's [B] + puls cc,dp,pc restore Carry status, dummy B, system DP, return + +BreakSlp ldx #SlpBreak SS.Break duration + bra TimedSlp + +HngUpSlp ldx #SlpHngUp SS.HngUp duration + bra TimedSlp + + IFEQ Level-1 +Sleep0 ldx #$0000 + bra TimedSlp + ENDC +Sleep1 ldx #1 give up balance of tick +TimedSlp pshs cc save IRQ enable status + andcc #^Intmasks enable IRQs + os9 F$Sleep + puls cc,pc restore IRQ enable status, return + +SStt clrb default to no error... + pshs cc,dp save IRQ/Carry status, dummy B, system DP + IFNE H6309 + tfr u,w setup our DP + tfr e,dp + ELSE + pshs a + tfr u,d + tfr a,dp + puls a + ENDC + ldx PD.RGS,y + cmpa #SS.HngUp + bne SetBreak + lda #^Cmd.DTR cleared (disabled) DTR bit + ldx <V.PORT + orcc #IntMasks disable IRQs while setting Command register +* anda CmdReg,x mask in current Command register contents +* sta CmdReg,x set new Command register + bsr HngUpSlp go sleep for a while... +BreakClr lda #^(Cmd.TIRB!Cmd.DTR) clear (disable) DTR and RTS control bits +FRegClr ldx <V.PORT +* anda CmdReg,x mask in current Command register + ldb <FloCtlRx get Rx flow control flags + bitb #FCRxDTR Rx disabled due to DTR? + bne LeaveDTR yes, go leave DTR disabled + ora #Cmd.DTR set (enable) DTR bit +LeaveDTR bitb #FCRxRTS Rx disabled due to RTS? + bne LeaveRTS yes, go leave RTS disabled + ora #TIRB.RTS enable RTS output +LeaveRTS ldb <FloCtlTx get Tx flow control flags + bitb #FCTxBrk currently transmitting line Break? + beq NoTxBrk no, go leave RTS alone... + ora #TIRB.Brk set Tx Break bits +NoTxBrk +* sta CmdReg,x set new Command register + puls cc,dp,pc restore IRQ/Carry status, dummy B, system DP, return + +SetBreak cmpa #SS.Break Tx line break? + bne SetSSig + ldy <V.PORT + ldd #FCTxBrk*256+TIRB.Brk [A]=flow control flag, [B]=Tx break enable + orcc #Intmasks disable IRQs while messing with flow control flags + ora <FloCtlTx set Tx break flag bit + sta <FloCtlTx save Tx flow control flags +* orb CmdReg,y set Tx line break bits +* stb CmdReg,y start Tx line break + bsr BreakSlp go sleep for a while... + anda #^FCTxBrk clear Tx break flag bit + sta <FloCtlTx save Tx flow control flags +* clr CmdReg,y clear Tx line break + bra BreakClr go restore RTS output to previous... + +SetSSig cmpa #SS.SSig + bne SetRelea + lda PD.CPR,y current process ID + ldb R$X+1,x LSB of [X] is signal code + orcc #IntMasks disable IRQs while checking Rx data length + ldx <RxDatLen + bne RSendSig + std <SSigPID + puls cc,dp,pc restore IRQ/Carry status, dummy B, system DP, return +RSendSig puls cc restore IRQ/Carry status + os9 F$Send + puls dp,pc restore system DP, return + +SetRelea cmpa #SS.Relea + bne SetCDSig + leax SSigPID,u point to Rx data signal process ID + bsr ReleaSig go release signal... + puls cc,dp,pc restore Carry status, dummy B, system DP, return + +SetCDSig cmpa #SS.CDSig set DCD signal? + bne SetCDRel + lda PD.CPR,y current process ID + ldb R$X+1,x LSB of [X] is signal code + std <CDSigPID + puls cc,dp,pc restore Carry status, dummy B, system DP, return + +SetCDRel cmpa #SS.CDRel release DCD signal? + bne SetComSt +CDRelSig leax CDSigPID,u point to DCD signal process ID + bsr ReleaSig go release signal... + puls cc,dp,pc restore Carry status, dummy B, system DP, return + +SetComSt cmpa #SS.ComSt + bne SetOpen + ldd R$Y,x caller's [Y] contains ACIAPAK format type/baud info +* bsr SetPort go save it and set up control/format registers +ReturnOK puls cc,dp,pc restore Carry status, dummy B, system DP, return + +SetOpen cmpa #SS.Open + bne SetClose + lda R$Y+1,x get LSB of caller's [Y] + deca real SS.Open from SCF? (SCF sets LSB of [Y] = 1) + bne ReturnOK no, go do nothing but return OK... + lda #TIRB.RTS enabled DTR and RTS outputs + orcc #IntMasks disable IRQs while setting Format register + lbra FRegClr go enable DTR and RTS (if not disabled due to Rx flow control) + +SetClose cmpa #SS.Close + lbne UnSvcErr no, go report error... + lda R$Y+1,x real SS.Close from SCF? (SCF sets LSB of [Y] = 0) + bne ReturnOK no, go do nothing but return OK... + leax SSigPID,u point to Rx data signal process ID + bsr ReleaSig go release signal... + bra CDRelSig go release DCD signal, return from there... + +ReleaSig pshs cc save IRQ enable status + orcc #IntMasks disable IRQs while releasing signal + lda PD.CPR,y get current process ID + suba ,x same as signal process ID? + bne NoReleas no, go return... + sta ,x clear this signal's process ID +NoReleas puls cc,pc restore IRQ enable status, return + + +* Interrupt service routine +IRQSvc + pshs dp save system DP + IFNE H6309 + tfr u,w setup our DP + tfr e,dp + ELSE + tfr u,d setup our DP + tfr a,dp + ENDC + + ldx <V.PORT + ldb StatReg,x get current Status register contents + stb <Cpy.Stat save Status register copy + bitb #Stat.Err error(s)? + beq ChkRDRF no, go check Rx data +* Error-handling + tst DataReg,x read Rx data register to clear ACIA error flags + bitb #Stat.Frm framing error (assume Rx line Break)? + beq ChkParty no, go check if parity error... + lda <V.QUIT default to keyboard quit ("Break") code + bra RxBreak go pretend we've received V.QUIT character... + +ChkParty bitb #Stat.Par parity error? + beq ChkOvRun no, go check overrun error... + lda #ParityEr mark parity error +ChkOvRun bita #Stat.Ovr overrun error? + beq SaveErrs no, go save errors... + ora #OvrFloEr mark overrun error +SaveErrs ora <V.ERR + sta <V.ERR + lbra ChkTrDCD go check if DCD transition... + +* Read data? +ChkRDRF bitb #Stat.RxF Rx data? + lbeq ChkTrDCD no, go check DCD transition + lda DataReg,x get Rx data +RxBreak beq SavRxDat its a null, go save it... + clr <SigSent + cmpa <V.INTR interrupt? + bne Chk.Quit no, go on... + ldb #S$Intrpt + bra SendSig + +Chk.Quit cmpa <V.QUIT abort? + bne Chk.PChr no, go on... + ldb #S$Abort +SendSig pshs a save Rx data + lda <V.LPRC get last process' ID + os9 F$Send + puls a recover Rx data + stb <SigSent set signal sent flag + bra SavRxDat go save Rx data... + +Chk.PChr cmpa <V.PCHR pause? + bne Chk.Flow no, go on... + ldx <V.DEV2 attached device defined? + beq SavRxDat no, go save Rx data... + sta V.PAUS,x yes, pause attached device + bra SavRxDat go save Rx data... + +Chk.Flow equ * + IFNE H6309 + tim #TxSwFlow,<Wrk.Type Tx data software flow control enabled? + ELSE + pshs a + lda #TxSwFlow + bita <Wrk.Type + puls a + ENDC + beq SavRxDat no, go save Rx data... + cmpa <V.XON XON? + bne Chk.XOff no, go on... + IFNE H6309 + aim #^FCTxXOff,<FloCtlTx clear XOFF received bit + ELSE + pshs a + lda #^FCTxXOff + anda <FloCtlTx + sta <FloCtlTx + puls a + ENDC + bra SetTxFlo go save new Tx flow control flags... + +Chk.XOff cmpa <V.XOFF XOFF? + bne SavRxDat no, go save Rx data... + ldb #FCTxXOff set XOFF received bit + orb <FloCtlTx set software Tx flow control flag +SetTxFlo stb <FloCtlTx save new Tx flow control flags + lbra ChkTrDCD go check DCD transition... +SavRxDat equ * + IFNE H6309 + aim #^FCRxSend,<FloCtlRx clear possible pending XOFF flag + ELSE + pshs a + lda #^FCRxSend + anda <FloCtlRx + sta <FloCtlRx + puls a + ENDC + ldx <RxBufPut get Rx buffer input pointer + IFNE H6309 + ldw <RxDatLen Rx get Rx buffer data length + cmpw <RxBufSiz Rx buffer already full? + ELSE + pshs d + ldd <RxDatLen + std <regWbuf + cmpd <RxBufSiz + puls d + ENDC + blo NotOvFlo no, go skip overflow error... + IFNE H6309 + oim #OvrFloEr,<V.ERR mark RX buffer overflow error + ELSE + ldb #OvrFloEr + orb <V.ERR + stb <V.ERR + ENDC + bra DisRxFlo go ensure Rx is disabled (if possible) + +NotOvFlo sta ,x+ save Rx data + cmpx <RxBufEnd end of Rx buffer? + blo SetLayDn no, go keep laydown pointer + ldx <RxBufPtr get Rx buffer start address +SetLayDn stx <RxBufPut set new Rx data laydown pointer + IFNE H6309 + incw one more byte in Rx buffer + stw <RxDatLen save new Rx data length + cmpw <RxBufMax at or past maximum fill point? + ELSE + pshs d + ldd <regWbuf + addd #1 + std <regWbuf + std <RxDatLen + cmpd <RxBufMax + puls d + ENDC + blo SgnlRxD no, go check Rx data signal... +DisRxFlo ldx <V.PORT +* ldb CmdReg,x get current Command register contents + IFNE H6309 + tim #ForceDTR,<Wrk.XTyp forced DTR? + ELSE + lda #ForceDTR + bita <Wrk.XTyp + ENDC + bne DisRxRTS yes, go check RTS disable... + IFNE H6309 + tim #DSRFlow,<Wrk.Type DSR/DTR Flow control? + ELSE + lda #DSRFlow + bita <Wrk.Type + ENDC + beq DisRxRTS no, go check RTS disable + IFNE H6309 + oim #FCRxDTR,<Wrk.Type mark RX disabled due to DTR + ELSE + lda #FCRxDTR + ora <Wrk.Type + sta <Wrk.Type + ENDC + andb #^Cmd.DTR clear (disable) DTR bit +DisRxRTS equ * + IFNE H6309 + tim #RTSFlow,<Wrk.Type + ELSE + lda #RTSFlow + bita <Wrk.Type + ENDC + beq NewRxFlo no, go set new Rx flow control... + IFNE H6309 + tim #DSRFlow,<Wrk.Type line break? + ELSE + lda #DSRFlow + bita <Wrk.Type + ENDC + bne NewRxFlo yes, go set new Rx flow control... + IFNE H6309 + oim #FCRxRTS,<FloCtlRx + ELSE + lda #FCRxRTS + ora <FloCtlRx + sta <FloCtlRx + ENDC + andb #^Cmd.TIRB clear Tx IRQ/RTS/Break control bits (disable RTS) +NewRxFlo +* stb CmdReg,x set/clear DTR and RTS in Command register + IFNE H6309 + tim #RxSwFlow,<Wrk.Type Rx software flow control? + ELSE + ldb <Wrk.Type + bitb #RxSwFlow + ENDC + beq SgnlRxD no, go check Rx data signal... + lda <V.XOFF XOFF character defined? + beq SgnlRxD no, go check Rx data signal... + ldb <FloCtlRx get Rx flow control flags + bitb #FCRxSent XOFF already sent? + bne SgnlRxD yes, go check Rx data signal... + orb #FCRxSend set send XOFF flag + stb <FloCtlRx set new Rx flow control flags + IFNE H6309 + tim #Stat.TxE,StatReg,x + ELSE + ldb StatReg,x + bitb #Stat.TxE + ENDC + beq SgnlRxD no, go skip XOFF this time... + sta DataReg,x write XOFF character + ldb #FCRxSent set XOFF sent flag + orb <FloCtlRx mask in current Rx flow control flags + andb #^FCRxSend clear send XOFF flag + stb <FloCtlRx save new flow control flags +SgnlRxD ldb <SigSent already sent abort/interrupt signal? + bne ChkTrDCD yes, go check DCD transition... + lda <SSigPID Rx data signal process ID? + beq ChkTrDCD none, go check DCD transition... + stb <SSigPID clear Rx data signal + ldb <SSigSig Rx data signal code + os9 F$Send +ChkTrDCD ldx <V.PORT + lda <Cpy.Stat get Status register copy + tfr a,b copy it... + eora <CpyDCDSR mark changes from old DSR+DCD status copy +* andb #Stat.DSR!Stat.DCD clear all but DSR+DCD status + stb <CpyDCDSR save new DSR+DCD status copy + bita <Mask.DCD DCD transition? + beq CkSuspnd no, go check for suspended process... + bitb <Mask.DCD DCD disabled now? + beq SgnlDCD no, go check DCD signal... + lda <Wrk.Type + bita #MdmKill modem kill enabled? + beq SgnlDCD no, go on... + ldx <V.PDLHd path descriptor list header + beq StCDLost no list, go set DCD lost error... + lda #PST.DCD DCD lost flag +PDListLp sta PD.PST,x set path status flag + ldx PD.PLP,x get next path descriptor in list + bne PDListLp not end of list, go do another... +StCDLost lda #DCDLstEr DCD lost error flag + ora <V.ERR + sta <V.ERR +SgnlDCD lda <CDSigPID get process ID, send a DCD signal? + beq CkSuspnd no, go check for suspended process... + ldb <CDSigSig get DCD signal code + clr <CDSigPID clear DCD signal + os9 F$Send + +CkSuspnd clrb clear Carry (for exit) and LSB of process descriptor address + lda <V.WAKE anybody waiting? ([D]=process descriptor address) + beq IRQExit no, go return... + IFEQ Level-1 + clr <V.WAKE + ldb #S$Wake + os9 F$Send + ELSE + stb <V.WAKE mark I/O done + tfr d,x copy process descriptor pointer + lda P$State,x get state flags + anda #^Suspend clear suspend state + sta P$State,x save state flags + ENDC +IRQExit puls dp,pc recover system DP, return... + + emod +ModSize equ * + end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level1/modules/term_mc6850.asm Sat Oct 17 21:21:11 2015 +0100 @@ -0,0 +1,86 @@ +******************************************************************** +* Term - mc6850 Device Descriptor +* +* $Id$ +* +* Edt/Rev YYYY/MM/DD Modified by +* Comment +* ------------------------------------------------------------------ + + nam Term + ttl mc6850 Device Descriptor + +* Disassembled 98/08/23 21:16:50 by Disasm v1.6 (C) 1988 by RML + + ifp1 + use defsfile + endc + +tylg set Devic+Objct +atrv set ReEnt+rev +rev set $00 + + mod eom,name,tylg,atrv,mgrnam,drvnam + + fcb UPDAT. mode byte + fcb HW.Page extended controller address + + IFNE mc09 + IFDEF HwBASE from makefile + fdb HwBASE + ELSE + fdb VDUSTA virtual UART physical controller address + ENDIF + ELSE + fdb $FF68 physical controller address + ENDC + + fcb initsize-*-1 initilization table size + fcb DT.SCF device type:0=scf,1=rbf,2=pipe,3=scf + fcb $00 case:0=up&lower,1=upper only + fcb $01 backspace:0=bsp,1=bsp then sp & bsp + fcb $00 delete:0=bsp over line,1=return + fcb $01 echo:0=no echo + fcb $01 auto line feed:0=off + fcb $00 end of line null count + fcb $01 pause:0=no end of page pause + fcb 24 lines per page + fcb C$BSP backspace character + fcb C$DEL delete line character + fcb C$CR end of record character + fcb C$EOF end of file character + fcb C$RPRT reprint line character + fcb C$RPET duplicate last line character + fcb C$PAUS pause character + fcb C$INTR interrupt character + fcb C$QUIT quit character + fcb C$BSP backspace echo character + fcb C$BELL line overflow character (bell) + fcb PARNONE parity + fcb STOP1+WORD8+B9600 stop bits/word size/baud rate + fdb name copy of descriptor name address + fcb C$XON acia xon char + fcb C$XOFF acia xoff char + fcb 80 (szx) number of columns for display + fcb 24 (szy) number of rows for display + fcb $00 Extended type +initsize equ * + + IFDEF TNum from makefile + IFEQ TNum +name fcs /T0/ + ENDIF + IFEQ TNum-1 +name fcs /T1/ + ENDIF + ELSE +name fcs /Term/ + ENDIF match IFDEF TNum + +mgrnam fcs /SCF/ +drvnam fcs /mc6850/ + + emod +eom equ * + end +