|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 13952 (0x3680)
Types: TextFile
Names: »LANDRVM.ASM«
└─⟦9f46c4107⟧ Bits:30005988 Sources for TurboDOS ver. 1.30 device drivers
└─⟦this⟧ »LANDRVM.ASM«
.PAGE 132,69
.TITLE "Driver for ASE LAN Controler with COM 9026 Chip"
.SBTTL "COPYRIGHT 1983, ASE GmbH. vers.: 5.2.84"
;
.IDENT LANDRM ;MODULE ID
;
.INSERT RCEQUATE ;EQUATES USED FOR RC855
;
LANBAD = 0A0H ;LAN Controller base address
;
CCOMND = LANBAD ;cont. command port
CSTAT = LANBAD+1 ;status port
CIMSK = LANBAD+1 ;interupt mask port
CMEMP0 = LANBAD+4 ;memory page 0
CMEMP1 = LANBAD+5 ;memory page 1
CMEMP2 = LANBAD+2 ;memory page 2
CMEMP3 = LANBAD+3 ;memory page 3
CCLRAC = LANBAD+7 ;clear address counter
HDWCON = LANBAD+6 ;hardware configuration port
;
DEFCON = 05H ;configuration byte set to 1k buffer size
CLRFLG = 1EH ;clear POR and RECON flags command
DISTRM = 01H ;disable transmitter
DISREC = 02H ;disable receiver
ENTX = 03H ;enable transmit from page n
ENRX = 04H ;enable receive to page n
ERXI = 7 ;enable rx interupt bit
PCKRX = 7 ;rx status bit
PCKTX = 0 ;tx status bit
TXACK = 1 ;tx ack status bit
ETXI = 0 ;enable tx interupt bit
RCONT = 2 ;reconfiguration timeout bit
CONTID = 0D1H ;controller ID
PAGE3 = 18H ;cont. memory page 3 address
MAXTRY = 3 ;max. retry count
TIMOC = 100 ;timeout count (value x 16.7ms)
NACTIV = 7 ;node activ bit (on verify)
ENDMRK = 0FFH ;end of data block mark
MAXML = 185 ;maximum MSG length + 1
;
.LOC .INIT.#
;
CKTIN%::XRA A ;on entry, disable controller interupts
OUT CIMSK ;
STA RXPAGP ;clear buffer pointer
SET RCONT,A ;set reconfiguration interupt bit
STA INTMSK ;
MVI A,CLRFLG ;and clear the flags
OUT CCOMND ;
MVI A,DEFCON ;set packet size to 256 bytes
OUT CCOMND ;
MVI A,6 ;set timeout values
OUT HDWCON ;
IN CCLRAC ;make sure address counter is = 0
IN CMEMP0 ;now read first memory position
CPI CONTID ;test for valid POR setup
JRZ CKTIN1 ;
;
LXI H,RSTMSG ;error, display error MSG
..LOP: MOV C,M ;get character to display
BIT 7,C ;sign bit set ?
JRNZ ..END ;if, end of MSG
PUSH H ;save pointer
CALL CRTOUT# ;call console driver
POP H ;restore pointer
INX H ;next MSG location
JMPR ..LOP ;display it
..END: DI ;restart only via hardware reset
JMPR . ;
;
CKTIN1: IN CMEMP0 ;no error, now read node address
DCR A ;physical address - 1
STA NODE ;and save it for further access
STA CKTAST# ;set node also into circuit asigmend table
LXI H,LANISR ;set ISR to interupt page
SHLD FDSVEC# ;
; SHLD DUMVEC# ;
MVI A,0D7H ;initialize CTC
OUT CTC3 ;
MVI A,1 ;
OUT CTC3 ;
LXI H,NODACT ;get address of node activ table
MVI B,0 ;
XRA A ;
..CLOP: MOV M,A ;clear table
INX H ;
DJNZ ..CLOP ;
MVI A,30 ;preset timeout counter
STA RTIOC1 ;
STA RTIOC2 ;
;
RET ;done
;
MVI A,ENRX ;get enable receive command
DI ;
OUT CCOMND ;issue it (receive is enabled to
;controller memory page 0)
LDA INTMSK ;get interupt mask byte
SET ERXI,A ;set enable receive interupt bit
STA INTMSK ;restore updated mask
OUT CIMSK ;and issue the interupt mask to controller
EI ;
RET ;initialization done
;
RSTMSG: .ASCIS "LAN Controller ID nicht korrekt ! RESET fuer wiederholen "
;
.LOC .PROG.#
;
CKTDR%::MOV A,C ;decode requested function
ORA A ;receive requested ?
JRZ RCVMSG ;
DCR A ;transmit requested ?
JZ SNDMSG ;
RET ;wrong call, done
;
RCVMSG: INX D ;advance patst link pointers
INX D ;
INX D ;
INX D ;
LXI H,RXMSPH ;lock driver
CALL WAIT# ;
SDED SRXBUF ;save receive buffer address
; LXI H,0 ;allow the OS to process
; CALL DELAY# ;
MVI A,3 ;set receive retry counter
STA RETRYR ;
LDA RECONF ;get reconfiguration flag
ORA A ;reconfiguration in progress ?
JNZ RTIME5 ;if not, resume
RCVMS1: MVI A,1 ;clear drive activ LED
OUT STAT6 ;
MVI A,ENRX ;get enable receive command
DI ;
OUT CCOMND ;issue it (receive is enabled to
;controller memory page 0)
LDA INTMSK ;get interupt mask byte
SET ERXI,A ;set enable receive interupt bit
STA INTMSK ;restore updated mask
OUT CIMSK ;and issue the interupt mask to controller
EI ;
LXI H,RXSPH ;and wait for interupt service request
CALL WAIT# ;
;
LDA RECONF ;get reconfiguration flag
ORA A ;set ?
JNZ RTIMEO ;if, process timeout
RCVMS2: DI ;move packet into system buffer
IN CCLRAC ;clear address counter
IN CMEMP0 ;get source ID
DCR A ;node address physical to logical translation
LXI H,NODACT ;get activ table start address
MOV C,A ;A to C
MVI B,0 ;
DAD B ;add node to table start address to get offset
SET NACTIV,A ;set node activ bit
MOV M,A ;write node to table
IN CMEMP0 ;controller packet length
IN CMEMP0 ;
IN CMEMP0 ;get MSG length
CPI 0FFH ;MSG length = 256 ?
JRZ RCVMS1 ;if, ignore the MSG (slave activ MSG)
MOV B,A ;set number of bytes to move
SUI MAXML ;subtract max. MSG length from move count
JRNC RCVMS3 ;if MSG length greater max. length, error
MVI C,CMEMP0 ;set port address
LHLD SRXBUF ;get system buffer address
MOV M,B ;store MSG length
DCR B ;MSG length minus one
INX H ;HL + 1
INIR ;and move
IN CMEMP0 ;get address behind data block
CPI ENDMRK ;end mark ?
JRZ RCVMS4 ;if not, error
RCVMS3: EI ;
LXI H,LERRCO ;update error counter
INR M ;
LXI H,RETRYR ;get receive retry counter
DCR M ;decrement counter
JRNZ RCVMS2 ;on positiv count, try again
; LXI H,0 ;allow the OS to process
; CALL DELAY# ;
; ;initialize and allow receive
; MVI A,ENRX ;get enable receive command
; DI ;
; OUT CCOMND ;issue it (receive is enabled to
; ;controller memory page 0)
; LDA INTMSK ;get interupt mask byte
; SET ERXI,A ;set enable receive interupt bit
; STA INTMSK ;restore updated mask
; OUT CIMSK ;and issue the interupt mask to controller
; EI ;
RCVMS4: EI ;
LXI H,RXMSPH ;unlock driver
CALL SIGNAL# ;
MVI A,1 ;reset LAN busy LED
OUT STAT6 ;
XRA A ;set return code
RET ;done
;
.PAGE
;
;
SNDMSG: XRA A ;set LAN busy LED
OUT STAT6 ;
INX D ;advance patst link pointers
INX D ;
INX D ;
INX D ;
LXI H,TXMSPH ;lock driver
CALL WAIT# ;
SDED STXBUF ;save system tx buffer address
MVI A,MAXTRY ;set retry count
STA RETRYT ;
;
SNDMS1: DI ;
IN CCLRAC ;clear address pointer
OUT CMEMP3 ;issue the SID (not valid,
;set by the controller)
LDAX D ;get the MSG length byte from buffer
CPI 0 ;MSG length = 0 ? (slave restart request)
JRZ SNDMS4 ;if so, no further action
MOV B,A ;save it
INX D ;next address
LDAX D ;get destination node address
INR A ;logical address + 1
OUT CMEMP3 ;write MSGDID to controller memory
MVI A,3 ;set A to max data length
OUT CMEMP3 ;and write length to controller memory
MVI C,CMEMP3 ;set memory page 3 address
LHLD STXBUF ;get the system buffer address
OUTIR ;and write data block to cont. memory
MVI A,ENDMRK ;set end of block mark
OUT CMEMP3 ;
EI
SNDMS2: MVI A,ENTX ;get enable transmit command
ORI PAGE3 ;set the transmitt buffer page
OUT CCOMND ;(transmit buffer is allways page 3)
;and issue the command
MVI A,TIMOC ;get max. timeout count
STA TOUTCO ;and set it as service flag and count value
TXLOOP: EI ;
LXI H,0 ;wait now till MSG is transmitted
CALL DELAY# ;or timeout occurs
DI ;prevent timer interupt
LDA TOUTCO ;get timeout count
ORA A ;timeout ?
JRZ SNDMS3 ;if, process timeout
IN CSTAT ;else get controller status
BIT PCKTX,A ;packet transmitted bit set ?
JRZ TXLOOP ;else try again
XRA A ;stop watchdog timer
STA TOUTCO ;
EI ;
;
IN CSTAT ;get controlelr status
BIT TXACK,A ;is the transmission acknowledged ?
JRZ SNDMS3 ;on error try again
SNDMSE: LXI H,TXMSPH ;unlock driver
CALL SIGNAL# ;
MVI A,1 ;clear the LAN busy LED
OUT STAT6 ;
XRA A ;
RET ;good return
;
SNDMS4: EI ;
LHLD RESTC ;get restart counter
INX H ;increment it
SHLD RESTC ;and restore updated counter
JMPR SNDMSE ;leave the driver
;
SNDMS3: EI ;
LHLD TXERRC ;get the transmit error counter
INX H ;increment it
SHLD TXERRC ;and restore the counter
LDA RETRYT ;get the retry count
DCR A ;minus one
STA RETRYT ;restore count
JRNZ SNDMS2 ;try again if count > 0
LXI H,TXMSPH ;unlock driver
CALL SIGNAL# ;
MVI A,1 ;clear the LAN busy LED
OUT STAT6 ;
LHLD STXBUF ;get system buffer address
INX H ;HL points to DID
MOV E,M ;
INX H ;
MVI D,M ;
MVI A,0FFH ;set error code
RET ;error return
;
.PAGE
; node activ table update
; purpose of this routine is, to update the node activ table
; and signal the OS any crashed node address to alow restart
; activity
;
RTIMEO: LXI H,NODACT ;get table start address
LDA NOACTN ;get number of active entrys to test
MOV B,A ;count to B
XRA A ;clear A
RTIME1: CMP M ;loop till first activ node is detected
JRNZ RTIME3 ;
RTIME2: INX H ;increment address pointer
DJNZ RTIME1 ;
STA RECONF ;clear reconfiguration flag
LDA RECONT ;get reconfiguration timeout value
STA RTIOC1 ;preset counters
STA RTIOC2 ;
MVI A,1 ;clear driver activ LED
OUT STAT6 ;
IN CSTAT ;get controller status
BIT PCKRX,A ;packet receive bit set ?
JNZ RCVMS2 ;if, process received packet
JP RCVMS1 ;all table entrys tested and updated
;go to normal receive
RTIME3: BIT NACTIV,M ;verify bit set ?
JRZ RTIME4 ;if not, node has crashed
JMPR RTIME2 ;verify next table entry
;
RTIME4: SHLD TABADD ;save table address
SBCD LOOPC ;save loop count
LXI H,RXMSPH ;unlock driver
CALL SIGNAL# ;
LHLD TABADD ;restore table address
MOV E,M ;get node number
MVI D,0 ;
MVI A,0FFH ;set receive error
RET ;pass over control
RTIME5: LHLD TABADD ;restore table address
LBCD LOOPC ;restore loop count
XRA A ;clear A
MOV M,A ;reset activ flag for crashed node
JMPR RTIME2 ;test next node
;
.PAGE
LANISR::DI ;transmit / receive interupt service routine
SSPD INTSP# ;save stack pointer
LXI SP,INTSTK# ;get aux stack pointer
PUSH PSW ;and save the registers
PUSH B ;
PUSH D ;
PUSH H ;
IN CSTAT ;get controller status
BIT PCKRX,A ;packet received bit set ?
JRZ TXINT ;if not, interupt may be set by transmitter
LDA INTMSK ;rx flag set ?
BIT ERXI,A ;if not, we are not waiting for any receiption
JRZ TXINT ;so the int. request is not valid for rx
RES ERXI,A ;valid interupt, clear the interupt
STA INTMSK ;request flag
OUT CIMSK ;and reset the rx mask bit
XRA A ;set the LAN busy LED
OUT STAT6 ;
LXI H,RXSPH ;signal the receiption
CALL SIGNAL# ;
;
TXINT:
REINT: IN CSTAT ;get controller status again
BIT RCONT,A ;reconfiguration timeout ?
JRZ IEXIT ;if not set, done
MVI A,CLRFLG ;rest the reconfiguration bit
OUT CCOMND ;
MVI A,1 ;reset the LAN connected LED
OUT STAT7 ;
IEXIT: POP H ;restore registers
POP D ;
POP B ;
POP PSW ;
LSPD INTSP# ;restore stack pointer
EI
RETI
;
; the following routine is called from the real time driver
; every real time tick
;
LANCLK::LDA TOUTCO ;get timeout counter
ORA A ;on zero, no service requested
RZ ;
DCR A ;decrement the timeout count
STA TOUTCO ;store updated count
RNZ ;one none zero, no further action
MVI A,DISTRM ;TIMEOUT, disable transmitter
ORI PAGE3 ;
OUT CCOMND ;
RET ;done
;
; the following routine is called from the real time clock
; driver every one second tick, to service the connected/
; discionnected status LED and the reconfiguration timeouts
;
LANSTD::MVI A,0 ;set the conected LED
OUT STAT7 ;issue the value
;
LDA RTIOC1 ;get reconfi. timeout counter
ORA A ;counter zero ?
JRZ LANST2 ;if test for verify loop count out
DCR A ;else decrement it
STA RTIOC1 ;and restore counter
RNZ ;done if counter is not = 0
LDA NOACTN ;else reset all activ bits into the table
MOV B,A ;number of activ nodes to B
LXI H,NODACT ;get table bottom
LANST1: RES NACTIV,M ;reset bit 7
INX H ;next table entry
DJNZ LANST1 ;loop till B = 0
RET ;done
;
LANST2: LDA RTIOC2 ;get reconfig. timeout counter
ORA A ;counter zero ?
RZ ;if, all done
DCR A ;else decrement counter
STA RTIOC2 ;and restore updated count
RNZ ;on none zero, also done
LDA RXSPH ;get receive SPH
ORA A ;receive in progress ?
JRNZ LANST3 ;if not, resume
MVI A,1 ;set reconfig. counter for next service
STA RTIOC2 ;
RET ;done
;
LANST3: LDA INTMSK ;get interupt mask byte
RES ERXI,A ;dissable receive interupt
STA INTMSK ;
OUT CIMSK ;
LXI H,RXSPH ;signal timeout
CALL SIGNAL# ;
MVI A,1 ;set reconfiguration in progress flag
STA RECONF ;
RET ;done
;
.LOC .DATA.#
;
RECONT::.BYTE 20 ;reconfiguration time in seconds x 2
RTIOC1: .BYTE 0 ;reconfiguration timeout counter 1
RTIOC2: .BYTE 0 ;reconfiguration timeout counter 2
NOACTN::.BYTE 10 ;number of activ nodes to test
TXERRF: .BYTE 0 ;tx error flag (none zero = error)
TOUTCO: .BYTE 0 ;timeout counter for transmit
NODE: .BYTE 0 ;node address, set by init.
RETRYT: .BYTE 0 ;transmit retry counter
RETRYR::.BYTE 0 ;receive retry counter
TXERRC::.WORD 0 ;transmit error counter
RESTC: .WORD 0 ;slave restart request counter
INTMSK: .BYTE 0 ;interupt mask
SRXBUF: .WORD 0 ;system rx buffer address
STXBUF: .WORD 0 ;system tx buffer address
RXPAGP: .BYTE 0 ;rx buffer pointer
RECONF: .BYTE 0 ;reconfiguration timeout flag
TABADD: .WORD 0 ;table address pointer save area
LOOPC: .WORD 0 ;loop counter save area
LERRCO::.BYTE 0 ;length check error counter
;
NODACT::.BLKB 256 ;bottom of node activ table
TXMSPH: .WORD 1 ;tx mutual exclusion sph.
.WORD . ;
.WORD .-2 ;
;
TXSPH: .WORD 0 ;transmit sph.
.WORD . ;
.WORD .-2 ;
;
RXMSPH: .WORD 1 ;rx mutual exclusion sph.
.WORD . ;
.WORD .-2 ;
;
RXSPH: .WORD 0 ;receive sph.
.WORD . ;
.WORD .-2 ;
;
.XSYM
.END
«eof»