|
|
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: 11648 (0x2d80)
Types: TextFile
Names: »SYNGATEW.MAC«
└─⟦9f46c4107⟧ Bits:30005988 Sources for TurboDOS ver. 1.30 device drivers
└─⟦this⟧ »SYNGATEW.MAC«
.Z80
TITLE TURBODOS 1.21 RC-850 SYNCRONUS GATEWAY DRIVER
SUBTTL COPYRIGHT (C) 1982, ASE GmbH Altenstadt, vers.: 25.1.84
;
NAME ('SGATEW') ;synronus gateway
;
INCLUDE RCEQUATE.MAC
;
COMMON /?INIT?/ ;LOCATE IN INIT-CODE AREA
;
REG3 EQU 3 ;SIO register 3
REG5 EQU 5 ;SIO register 5
;
CKTIN@::DI
LD HL,SIOINT ;init sio for receive
LD B,SIOINL ;
LD C,SIO0C ;
OTIR ;
;
LD HL,RXISR ;set receive interrupt vector
LD (SIO0V##+4),HL
LD HL,SRXISR ;set special receive interrupt vector
LD (SIO0V##+6),HL
LD HL,TXISR ;set transmit interrupt vector
LD (SIO0V##),HL
; LD HL,EXSISR
; LD (SIO0V##+2),HL
EI ;
RET
;
SIOINT: DB 18H ;channel reset
DB 4 ;WR4 NEXT
DB 20H ;WR4: SDLC MODE
DB 6 ;WR6 NEXT
DB 0 ;WR6: SDLC ADDRESS FIELD
DB 7 ;WR6 NEXT
DB 7EH ;WR7: SDLC FLAG
DB 5 ;reset reg 5
DB 0 ;
SIOINL EQU $-SIOINT
;
CSEG ;LOCATE IN PROGRAM AREA
;
CKTDR@::LD A,C ;GET FUNCTION NUMBER
CP 0 ;FUNCTION NUMBER=0?
JR Z,RCVMSG ;IF SO, RECEIVE MESSAGE
CP 01 ;
JP Z,SNDMSG ;IF SO, SEND MESSAGE
RET ;ELSE, DONE
;
RCVMSG:
INC DE ;ADVANCE PAST LINK POINTERS
INC DE
INC DE
INC DE
LD HL,RXMSPH ;lock driver
CALL WAIT## ;
LD (SRXBUF),DE ;SAVE MSG BUFFER ADDRESS
RCVMS1: CALL RECEIV ;do receive setup
LD HL,RXSPH ;wait for receive interupt
CALL WAIT## ;
;
LD A,(RXSTAT) ;get receive status
AND 0E0H ;seperate end of frame, CRC, Rx overrun error
SUB NORXER ;CRC or Rx overrun error ?
JR Z,RCVMS2 ;if rx status = 0, no error
LD HL,ERRCNT ;update error counter
INC (HL) ;
JR RCVMS1 ;wait for next block
;
RCVMS2: CALL TXACK ;answer the MSG received
LD A,(ERRFLG) ;error occured during transmit ?
OR A ;
JR NZ,RCVMS1 ;if, wait for new block
LD HL,RXMSPH ;unlock driver
CALL SIGNAL## ;
XOR A ;A = 0
RET ;done
;
;
;
SNDMSG: INC DE ;ADVANCE PAST LINK POINTERS
INC DE
INC DE
INC DE
LD HL,TXMSPH ;lock driver
CALL WAIT## ;
LD (STXBUF),DE ;
LD A,(DE) ;recovery complete MSG ?
CP 0 ;
JP Z,SNDMS3 ;on match, done
LD A,MAXTRY ;set retry counter
LD (TRTRYC),A ;
SNDMS0: CALL COMTX ;do transmit setup
LD A,(ERRFLG) ;error occured during tx setup ?
OR A ;
JR NZ,SNDMS1 ;if, signal the error
LD HL,(STXBUF) ;get transmit buffer address
LD (TXBUFP),HL ;and set it as DMA address
LD A,(HL) ;get length to transmit
LD (TXCNT),A ;and set it as DMA count
CALL COMTXE ;use common transmit routine
LD A,(ERRFLG) ;error occured during transmit ?
OR A ;
JR NZ,SNDMS0 ;if, try again without updating the rt. count.
CALL RXACK ;receive ACK (or not)
OR A ;test return code
JR Z,SNDMS3 ;on good return done
LD HL,TRTRYC ;get transmit retry counter address
DEC (HL) ;counter - 1
JR NZ,SNDMS0 ;on none zero, try again
;
SNDMS1: LD HL,TXMSPH ;unlock driver
CALL SIGNAL## ;
LD HL,(STXBUF) ;get tx buffer address
INC HL ;points to destination address
LD E,(HL) ;get node address
INC HL ;
LD D,(HL) ;
LD A,0FFH ;
RET ;done
;
SNDMS3: CALL RECEIV ;initialize for receive
LD HL,TXMSPH ;unlock driver
CALL SIGNAL## ;
XOR A ;set good return
RET ;done
;
PAGE
;
COMTX: LD HL,(SYNDEL) ;delay for transmitter to set up
CALL DELAY## ;for receive
DI ;disable interupt during init.
LD HL,SIOTX ;get initialize table top
LD B,SIOTXL ;get table length
LD C,SIO0C ;get port number
OTIR ;initialize SIO
EI ;
LD HL,0 ;delay for carrier
CALL DELAY## ;
XOR A ;clear possible positiv sph count
LD (TXSPH),A ;
LD (ERRFLG),A ;and error flag
DEC A ;set loop counter max. value (FF)
LD (LOOPC),A ;
LD A,(MODSIG) ;get modem signals to test
BIT 0,A ;CTS test requested ?
JR Z,COMTX3 ;if not, continue
;
COMTX2: LD HL,LOOPC ;set address of loop counter
DEC (HL) ;loop counter minus one
JR Z,COMTX5 ;error exit
LD A,10H ;reset ext. stat
OUT (SIO0C),A ;
IN A,(SIO0C) ;get SIO status
BIT CTS,A ;clear to send ?
JR NZ,COMTX3 ;if set, continue
LD HL,6 ;give modem a chance to set the signal
CALL DELAY## ;
JR COMTX2 ;get status again
;
COMTX3: LD A,(MODSIG) ;get modem signals to test
BIT 1,A ;DCD test requested ?
RET Z ;if not, done
;
COMTX4: LD HL,LOOPC ;set address of loop counter
DEC (HL) ;loop counter minus one
JR Z,COMTX5 ;error exit
LD A,10H ;reset ext. stat
OUT (SIO0C),A ;
IN A,(SIO0C) ;get SIO status
BIT 3,A ;test DCD
RET Z ;if it's clear, done
LD HL,6 ;same as for CTS signal
CALL DELAY## ;
JR COMTX4 ;
;
COMTX5: LD A,18H ;disable the SIO
OUT (SIO0C),A ;
LD (ERRFLG),A ;set the error flag
RET ;done
;
;
;
COMTXE: DI ;
OUT (SIO0D),A ;issue first data byte
LD A,0C0H ;reset underrun/eom latch
OUT (SIO0C),A ;
EI ;
LD HL,TXSPH ;now wait for transmit interupt
CALL WAIT## ;
;
LD HL,(SYNDEL) ;delay for CRC and flags
CALL DELAY## ;
LD A,REG5 ;select register 5
OUT (SIO0C),A ;
LD A,80H ;disable transmiter
OUT (SIO0C),A ;
; LD A,18H ;disable the SIO
; OUT (SIO0C),A ;
RET ;transmit done
;
;
;
RECEIV: XOR A ;
LD (RXSTAT),A ;clear Rx status
LD (ERRFLG),A ;clear error flag
LD HL,(SRXBUF) ;
LD (HL),A ;clear first byte of rx buffer
LD A,MMSGL ;
LD (RXCNT),A ;set rx counter
LD (RXBUFP),HL ;set DMA address
LD HL,SIORCV ;init sio for receive
LD B,SIORCL ;
LD C,SIO0C ;
OTIR ;
RET ;done
;
;
;
RXACK: CALL RECEIV ;do receive initialize
DI ;
LD A,(SYNDEL) ;load timeout value (1=20ms)
SLA A ;multiply ACK,CRC delay
SLA A ;by 2 exp. 4
SLA A ;
SLA A ;
LD (TOUTV2),A ;
EI ;
LD HL,ACKSPH ;and wait for receive int. or timeout
CALL WAIT## ;
;
DI ;disable the SIO
LD A,REG3 ;select register 3
OUT (SIO0C),A ;
XOR A ;disable receiver
OUT (SIO0C),A ;
; LD A,18H ;
; OUT (SIO0C),A ;
EI ;
LD A,(ERRFLG) ;error occured ?
OR A ;
RET NZ ;if, done
LD HL,(SRXBUF) ;get receive buffer bottom
LD A,ACK ;is MSG received interproc. MSG ?
CP (HL) ;
RET NZ ;error return
XOR A ;good return
RET ;done
;
;
;
TXACK: LD HL,(SYNDEL) ;delay to give transmitter time
CALL DELAY## ;for receiv setup
CALL COMTX ;do transmit set up
LD A,1 ;dissable the interupt mode for
OUT (SIO0C),A ;ACK transmit
XOR A ;
OUT (SIO0C),A ;
LD A,ACK ;now issue the ACK
DI ;
OUT (SIO0D),A ;issue first data byte
LD A,0C0H ;reset underrun/eom latch
OUT (SIO0C),A ;
EI ;
;
LD HL,(SYNDEL) ;delay for CRC and flags
CALL DELAY## ;
LD A,REG5 ;select register 5
OUT (SIO0C),A ;
LD A,80H ;disable transmiter
OUT (SIO0C),A ;
; LD A,18H ;disable the SIO
; OUT (SIO0C),A ;
RET ;transmit done
;
PAGE
;
RXISR:: DI ;receive character routine
PUSH AF ;
PUSH BC ;
PUSH DE ;
PUSH HL ;
IN A,(SIO0C) ;get SIO staus
BIT 7,A ;abort sequence received ?
JR NZ,RXERR ;if, dissable the receiver
LD A,13H ;enable sync. load
OUT (SIO0C),A ;
LD A,11001001B ;
OUT (SIO0C),A ;
LD HL,(RXBUFP) ;get current receive buffer pointer
LD BC,(RDPORT) ;get current receive count and address
INI ;get data from SIO
JR Z,RXISRE ;no pointer update on receiv count =0
LD (RDPORT),BC ;restore count and address
LD (RXBUFP),HL ;buffer pointer also
RXISRE: DI
POP HL ;
POP DE ;
POP BC ;
POP AF ;
EI ;
RETI ;done
;
RXERR: LD (ERRFLG),A ;set error flag for main routine
JR SRXIS0 ;and process receive end
;
;
SRXISR:: ;special receive routine
;we comes here if receiver overun or
;normal end of frame occurs
DI ;
PUSH AF ;save registers
PUSH BC ;
PUSH DE ;
PUSH HL ;
;stop receive timeout
SRXIS0: XOR A
LD (TOUTV2),A ;
LD A,11H ;get register 1 status
OUT (SIO0C),A ;
IN A,(SIO0C) ;
LD (RXSTAT),A ;save Rx status
LD A,33H ;disable receive and clear special
OUT (SIO0C),A ;receive condition
XOR A ;
OUT (SIO0C),A ;
LD A,(ACKSPH) ;is the transmitter waiting for an ACK ?
OR A ;
JR Z,SRXIS1 ;if not signal to OS
LD HL,ACKSPH ;else process ack
CALL SIGNAL## ;
JR SRXIS2 ;
SRXIS1: LD HL,RXSPH ;signal to os, end of receive call
CALL SIGNAL## ;
SRXIS2: DI ;
POP HL ;restore registers
POP DE ;
POP BC ;
POP AF ;
EI ;
RETI ;
;
;
;
TXISR:: DI ;transmit character routine
PUSH AF ;
PUSH BC ;
PUSH DE ;
PUSH HL ;
LD A,(TXCNT) ;get current transmit count
DEC A ;tx counter -1
JR Z,TXISR1 ;on count = 0, done
LD (TXCNT),A ;
IN A,(SIO0C) ;get SIO status
BIT 6,A ;underrun occured ?
JR NZ,TXERR ;if, process the underrun situation
LD HL,(TXBUFP) ;get current transmit buffer pointer
INC HL ;update buffer pointer
LD A,(HL) ;get the data byte
OUT (SIO0D),A ;and issue it
LD (TXBUFP),HL ;
LD A,10H ;reset ext. status
OUT (SIO0C),A ;
POP HL ;
POP DE ;
POP BC ;
POP AF ;
EI ;
RETI ;done
;
TXERR: LD A,08H ;load abort command
OUT (SIO0C),A ;and issue it
LD (ERRFLG),A ;set error flag for main routine
;
TXISR1: LD A,28H ;reset transmit int pending
OUT (SIO0C),A ;
LD A,11H ;and disable interupts
OUT (SIO0C),A ;
XOR A ;
OUT (SIO0C),A ;
LD HL,TXSPH ;if not, signal end of transmit
CALL SIGNAL## ;
POP HL ;
POP DE ;
POP BC ;
POP AF ;
JP ISRXIT## ;
;
;
;
EXSISR::RETI
;
SYGCLK::LD A,(TOUTV2) ;get timeout counter
OR A ;service reqested ?
RET Z ;
DEC A ;yes, update count
LD (TOUTV2),A ;restore updated count
RET NZ ;on none zero, done
LD HL,ACKSPH ;signal the timeout
CALL SIGNAL## ;
RET ;done
;
PAGE
;
DSEG ;LOCATE IN DATA AREA
;
TOUTV2: DB 0 ;timeout count
;
RXMSPH: DW 1 ;receive mutual-exclusion semaphore
DW $
DW $-2
;
RXSPH: DW 0 ;receive interupt event counter
DW $
DW $-2
;
ACKSPH: DW 0 ;ACK receive event counter
DW $
DW $-2
;
TXMSPH: DW 1 ;SEND MUTUAL-EXLCLUSION SEMAPHORE
DW $
DW $-2
;
TXSPH: DW 0 ;event counter for transmit int.
DW $
DW $-2
;
SIORCV:; DB 18H ;channel reset
DB 0 ;
DB 10H ;reset ext. status
DB 4 ;WR4 NEXT
DB 20H ;WR4: SDLC MODE
DB 6 ;WR6 NEXT
DB 0 ;WR6: SDLC ADDRESS FIELD
DB 7 ;WR6 NEXT
DB 7EH ;WR7: SDLC FLAG
DB 1 ;select reg 1
DB 00011000B ;set: int. on all rx,
DB 5 ;
DB 10000000B ;set: DTR, SDLC-CRC
DB 3 ;
DB 11011011B ;set: rx 8 bit, hunt ph., rx crc, sync. inhib.
DB 40H ;reset rx crc
SIORCL EQU $-SIORCV
;
SIOTX: ;DB 18H ;channel reset
DB 0 ;
DB 10H ;reset ext. status
DB 4 ;WR4 NEXT
DB 20H ;WR4: SDLC MODE
DB 6 ;WR6 NEXT
DB 0 ;WR6: SDLC ADDRESS FIELD
DB 7 ;WR6 NEXT
DB 7EH ;WR7: SDLC FLAG
DB 3 ;
DB 0 ;
DB 15H ;reset ext. stat.
DB 11101011B ;set: DTR, tx 8 bit, tx ena., SDLC-CRC, RTS, tx-crc
DB 11H ;
DB 02H ;
DB 0B0H ;reset tx crc, error reset
SIOTXL EQU $-SIOTX
;
;
ERRCNT: DB 0 ;Rx error counter
SRXBUF: DW 0 ;OS Rx buffer address
STXBUF: DW 0 ;OS Tx buffer address
TRTRYC: DB 0 ;transmit retry counter (data only)
RXSTAT: DB 0 ;Rx status (register 1)
RXBUFP: DW 0 ;DMA address for rx
RDPORT: DB SIO0D ;data port address
RXCNT: DB 0 ;rx DMA count
TXBUFP: DW 0 ;DMA address for tx
TXCNT: DB 0 ;tx DMA count
ERRFLG: DB 0 ;used to signal error during rx and tx
LOOPC: DB 0 ;loop counter for modem signals
MODSIG::DB 1 ;test flags for RTS and DCD
; 1 = test RTS bevor transmit
; 2 = test DCD " "
; 3 = test both
SYNDEL::DW 4 ;syncronus delay, used during CRC and ACK
;transmit, must set for several speeds as
;follows: 600 = 04
; 1200 = 03
; 2400 = 02
; 4800 > = 01
;
END
«eof»