DataMuseum.dk

Presents historical artifacts from the history of:

RegneCentralen RC850

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RegneCentralen RC850

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦73f6827dc⟧ TextFile

    Length: 13952 (0x3680)
    Types: TextFile
    Names: »LANDRVM.ASM«

Derivation

└─⟦9f46c4107⟧ Bits:30005988 Sources for TurboDOS ver. 1.30 device drivers
    └─⟦this⟧ »LANDRVM.ASM« 

TextFile

.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»