1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-21 00:48:06 +00:00
Files
PDP-10.its/src/mits_s/dl11.4
2018-11-25 20:59:17 +01:00

303 lines
7.3 KiB
Groff
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.lif z %defin
.title DL11 support
.sbttl DL11 support: Definitions, Macros and Code
;;; ;;; General info:
;;; ;;; DL11 async line driver. Also works for other single line async
;;; ;;; interfaces that look like a DL11 (DLV11-J, Technical magic DLV11-J,
;;; ;;; etc.
;;; ;;; Usage:
;;; ;;; defdev dl,dl11,<
;;; ;;; ;;; dl vec,csr ,typ,baud.,where
;;; ;;; dl 060,177560,v52,9600.,<This is where it is.>
;;; ;;; >
;;; ;;; where TYP is as defined in the TTY module, and BAUD is with the
;;; ;;; decimal point.
.iif z %defin, .nlist ;don't list definitions and macros if not
;defining them
.if nz %defin ;only define symbols when we are supposed to
.if p1
.sbttl -- Definitions
;; dl11 definitions
;; offsets to device registers
dl.rcs==0 ;receiver csr
dl.rbf==2 ;receiver buffer
dl.xcs==4 ;transmitter csr
dl.xbf==6 ;transmitter buffer
;; receiver csr bits
dl.ren==bit.00 ;reader enable [w]
dl.rie==bit.06 ;receiver interrupt enable [rw]
dl.rdn==bit.07 ;receiver done [r]
dl.rac==bit.11 ;receiver active [r]
;; receiver data buffer [read only]
dl.rdt==mask8 ;eight bits of data
dl.par==bit.12 ;parity error
dl.frm==bit.13 ;framing error
dl.ovr==bit.14 ;overrun
dl.err==bit.15 ;error
;; transmitter status register
dl.xbk==bit.01 ;transmit a BREAK [rw]
dl.mnt==bit.03 ;maintenance [rw]
dl.xie==bit.06 ;transmitter interrupt enable [rw]
dl.xrd==bit.07 ;transmitter ready [r]
;; transmitter data buffer [write only]
dl.xdt==mask8 ;transmitter data
.sbttl -- Macros
.macro dl vec,csr,ttytyp,baud,where
.if p1
%%==.
.=0
.string <where>
.=%%
.iff
%%==.
.=dl$vec+<2*ndl>
.word vec
.=dl$csr+<2*ndl>
.word csr
.=dl$rpt+<2*ndl>
.word dl$brk+dl$rbk+<ndl*ldl$bk>
.=dl$xpt+<2*ndl>
.word dl$brk+dl$xbk+<ndl*ldl$bk>
.=dl$tty+<2*ndl>
.word 2*ntty
.=ttyityp+<2*ntty>
.word t.'ttytyp
.=ttyispd+<2*ntty>
.word baud
.=ttyilo+<2*ntty>
.string <where>
.=%%
.endc
ndl==ndl+1
ntty==ntty+1
.endm
.endc p1
dv%dl==ndv%
ndv%==ndv%+1
ndl==0 ;no dls to start with
.endc %defin
.iif z %defin, .list ;start listing again
.iif nz %defin, .nlist ;don't list code if only doing definitions
.if z %defin ;only do code if not defining symbols
.sbttl -- Code
dsect < ;;; a DL11 receiver structure
.blkb l$tti ;basically an input tty with...
$dlrnum:: .blkw 1 ;a DL device index
>,l$dlr
dsect < ;;; a DL11 transmitter structure
.blkb l$tto ;basically an output tty with...
$dlxnum:: .blkw 1 ;a DL device index
$dlxcsr:: .blkw 1 ;cached xmit csr for dlpput
$dlbrk:: .blkw 1 ;number of characters before turning off
;break
>,l$dlx
;;; DL11s are PDP11 interfaces to one serial line. The receiver is supported
;;; by one source object, and the transmitter by one destination object.
dl$vec: .blkw ndl ;interrupt vector location
dl$csr: .blkw ndl ;csr device register base
dl$tty: .blkw ndl ;tty number of this dl
dl$rpt: .blkw ndl ;pointer to receiver interrupt routines
dl$xpt: .blkw ndl ;pointer to transmitter interrupt routines
.wvector dl$rdv,ndl ;receiver devices
.wvector dl$xdv,ndl ;transmitter devices
dsect <
dl$rbk:: jsr r0,dlrint ;receiver interrupt
.blkw 1 ;dl index
dl$xbk:: jsr r0,dlxint ;transmitter interrupt
.blkw 1 ;pointer into transmitter object table
>,ldl$bk
dl$brk:
.rept ndl
jsr r0,dlrint
.rpcnt*2
jsr r0,dlxint
.rpcnt*2
.endr
.s1clk dlrftm ;DL Receiver %^& Techinical Magic
.wscalar $dlrftm ;counter
dlrftm: push r0,r1,r2,r3 ;gets called once per minute
mov #ndl,r0
if ne,< ;safety
mov #dl$rdv,r1
mov #dl$csr,r2
loop <
mov (r2)+,r3 ;get the CSR
tst (r1)+ ;make sure there is an object
if ne,<
bic #dl.rie,dl.rcs(r3) ;clear interrupt enable
bis #dl.rie+dl.ren,dl.rcs(r3) ;turn it back on, and make sure enabled too
>
sorl r0
>
>
pop r3,r2,r1,r0
return
;;; DL11 receiver interrupt handler. Interrupt vector points to DLJSR field
;;; of source object, which contains JSR R0,@#DLRINT. Thus on entry here R0
;;; is saved on the stack and initialized to line specific data. Because the
;;; JSR is in the object rather than before it, R0 does not contain a pointer
;;; to the beginning of the object. This is purely an efficiency hack (see
;;; code below).
dlrint: push r1 ;save reg
mov (r0)+,r0 ;get dl index
mov dl$csr(r0),r1 ;get the csr
bit #dl.rdn,dl.rcs(r1) ;check receiver done (safety)
if ne,<
push r4
mov dl$rdv(r0),r4 ;get the receive device
mov dl.rbf(r1),r1 ;get the character
bit #dl.frm,r1
if ne,< ;break character on framing error
movb #%acom,r1 ;send COM-B
call @$dvlpt(r4)
movb #'B,r1
>
else <bic #mask8,r1>
call @$dvlpt(r4) ;logically put the character in the device
pop r4
>
pop r1,r0
rti
;;; DL11 transmitter interrupt handler. Interrupt vector points at object
;;; representing the specific DL11 starting with JSR R0,@#DLXINT. Thus on
;;; entry here R0 is saved on the stack and initialized to a pointer to the
;;; object itself for the appropriate DL11.
dlxint: ;; Remove next character from queue in DL11 object and send it. If
;; queue becomes empty, then disable interrupts. This code can fail
;; if interrupted by a queue insertion; thus our source cannot be an
;; interrupt routine that runs at higher priority than we do.
mov (r0)+,r0 ;get the index
push r1,r4
mov dl$csr(r0),r1
mov dl$xdv(r0),r4
movb @$dvfpt(r4),dl.xbf(r1) ;stuff character in device register
push r1
call chnfgt ;do a fast get (no channel in r0) from the device
pop r1
dec $dlbrk(r4) ;decrement break count
if eq,<bicb #dl.xbk,dl.xcs(r1)>
else <if mi,<clr $dlbrk(r4)>>
tst $dvhmn(r4)
if eq,<bicb #dl.xie,dl.xcs(r1)>
pop r4,r1,r0
rti
dlpwu::
dlini: clr $dlrftm ;clear counter
clr r0
loop <
call dlinit
add #2,r0
cmp r0,#2*ndl
rptl lt
>
return
;;; Initialize one DL11 line. Called with R0 as DL11 index.
dlinit: push r2
mov dl$csr(r0),r2 ;get CSR
call nxmcat ;install catch for NXM errors
dlnxm
clr dl.rcs(r2) ;clear receiver
clr dl.xcs(r2) ;clear transmitter
call nxmclr ;we have a DL11
push dl$tty(r0),#l$dlr,#l$dlx ;size of transmit and receive devices
call ttygood ;declare tty good and create it
if cs,<bpt>
pop r2 ;get transmit device
mov r2,dl$xdv(r0)
mov dl$csr(r0),$dlxcsr(r2) ;setup fast xmit csr for dlpput
add #dl.xcs,$dlxcsr(r2) ;...
mov #dlpput,$dvppt(r2) ;reset physical put
pop dl$rdv(r0) ;get receive device
pop * ;flush tty number
mov dl$vec(r0),r2 ;get the vector address
mov dl$rpt(r0),(r2)+ ;setup receive and xmit interrupt vectors
mov #pr5,(r2)+
mov dl$xpt(r0),(r2)+
mov #pr5,(r2)+
mov dl$csr(r0),r2
bis #dl.rie+dl.ren,dl.rcs(r2) ; turn on receiver interrupts
pop r2
return
dlnxm: clr dl$rdv(r0) ;no receiver device
clr dl$xdv(r0) ;nor a transmitter device
push r0
mov dl$tty(r0),r0
call ttybad ;declare tty bad
pop r0
pop r2
return
dlpput: lock 6
call chnput
if cc,<bis #dl.xie,@$dlxcs(r4)> ;enable interrupts
unlock
return
dlpget: lock 6
call chnget
unlock
return
.endc %defin
.iif nz %defin, .list ;start listing as usual
;; local modes:
;; mode:midas
;; auto fill mode:
;; fill column:75
;; comment column:32
;; end: