|
DataMuseum.dkPresents historical artifacts from the history of: RegneCentralen RC850 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RegneCentralen RC850 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»