mirror of
https://github.com/PDP-10/its.git
synced 2026-03-25 01:47:08 +00:00
423 lines
9.3 KiB
Groff
Executable File
423 lines
9.3 KiB
Groff
Executable File
|
||
.lif z %defin
|
||
.title DZ11 support
|
||
.sbttl DZ11 support: Definitions, Macros and Code
|
||
|
||
;;; ;;; General info:
|
||
;;; ;;; DZ11 8 line async tty driver. Can probably also be used for qbus
|
||
;;; ;;; version.
|
||
;;; ;;; Usage:
|
||
;;; ;;; defdev dz,dz11,<
|
||
;;; ;;; ;;; dz vec,csr ,<lines>
|
||
;;; ;;; ;;; dzl typ,baud.,P,stp,nbts,where
|
||
;;; ;;; dz 300,160100,<
|
||
;;; ;;; dzl v52,9600.,n,002,8,<EE Admin (DZ01-CH0)>
|
||
;;; ;;; >
|
||
;;; ;;; >
|
||
;;; ;;; Known bugs:
|
||
;;; ;;; sometimes the buffer wraps, and characters keep coming (probably
|
||
;;; ;;; 65K of them). I don't know why this happens, but it is probably my
|
||
;;; ;;; misunderstanding of what a DZ wants to see for output.
|
||
;;; ;;; More bugs:
|
||
;;; ;;; Ignores all terminal info (except type, baud, and location). Assumes
|
||
;;; ;;; no parity, 2 stop bits, 8 bits per character.
|
||
|
||
.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
|
||
|
||
|
||
|
||
;; dz11 definitions
|
||
;; offsets to device registers
|
||
dz.csr==0 ;(R/W) csr
|
||
dz.rbf==2 ;(R/ ) receiver buffer
|
||
dz.lpr==2 ;( /W) line parameter register
|
||
dz.xcr==4 ;(R/W) transmitter control register
|
||
dz.msr==6 ;(R/ ) modem status
|
||
dz.xdr==6 ;( /W) transmitter data
|
||
dz.xbr==7 ;( /W) transmitter break data
|
||
;; Control and Status Register bits (dz.csr) [read/write]
|
||
dz.xrd==bit.15 ;transmitter ready
|
||
dz.xie==bit.14 ;transmitter interrupt enable
|
||
dz.sa==bit.13 ;silo alarm (notification)
|
||
dz.sae==bit.12 ;silo alarm enable
|
||
dz.xln==mask3 ;xmit line number mask (after SWAB)
|
||
dz.rdn==bit.07 ;receiver done
|
||
dz.rie==bit.06 ;receiver interrupt enable
|
||
dz.mse==bit.05 ;master scan enable
|
||
dz.mcl==bit.04 ;master clear
|
||
dz.mnt==bit.03 ;maintenance
|
||
;; Receiver Buffer bits (dz.rbf) [read only, word only]
|
||
dz.vdp==bit.15 ;Valid Data Present
|
||
dz.dov==bit.14 ;Data Overrun
|
||
dz.frm==bit.13 ;framing error (break was hit)
|
||
dz.par==bit.12 ;parity error
|
||
dz.rln==mask3 ;rcvr line number mask (after SWAB)
|
||
dz.rch==mask8 ;the received character
|
||
;; Line paramter register bits (dz.lpr) [write only, word only]
|
||
dz.rcv==bit.12 ;receiver on
|
||
dz.spd==08. ;ash for speed select
|
||
dz.paN==0_6 ;no parity
|
||
dz.paE==1_6 ;even parity
|
||
dz.paO==3_6 ;odd parity
|
||
dz.tsb==bit.05 ;two stop bits
|
||
dz.5bt==0_3 ;5 bit characters
|
||
dz.6bt==1_3 ;6 bit characters
|
||
dz.7bt==2_3 ;7 bit characters
|
||
dz.8bt==3_3 ;8 bit characters
|
||
dz.lln==mask3 ;line number
|
||
|
||
|
||
.sbttl -- Macros
|
||
|
||
.macro dz vec,csr,lines
|
||
ndzl==0
|
||
lines
|
||
.if p2
|
||
%%==.
|
||
.=dz$vec+<2*ndz>
|
||
.word vec
|
||
.=dz$csr+<2*ndz>
|
||
.word csr
|
||
.=dz$tty+<2*ndz>
|
||
.word 2*<ntty-ndzl>
|
||
.=dz$nlines+<2*ndz>
|
||
.word ndzl
|
||
.=%%
|
||
.endc
|
||
ndz==ndz+1
|
||
.endm
|
||
|
||
.macro dzl ttytyp,baud,par,nstop,nbits,where
|
||
.if p1
|
||
%%==.
|
||
.=0
|
||
.string <where>
|
||
.=%%
|
||
.iff
|
||
%%==.
|
||
.=ttyityp+<2*ntty>
|
||
.word t.'ttytyp
|
||
.=ttyispd+<2*ntty>
|
||
.word baud
|
||
.=ttyilo+<2*ntty>
|
||
.string <where>
|
||
.=%%
|
||
.endc
|
||
ntty==ntty+1
|
||
ndzl==ndzl+1
|
||
.endm
|
||
|
||
.endc p1
|
||
|
||
ndz==0
|
||
|
||
.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 DZ11 receiver structure
|
||
.blkb l$tti ;basically an input tty with....
|
||
>,l$dzr
|
||
|
||
dsect < ;;; a DZ11 transmitter structure
|
||
.blkb l$tto ;basically an output tty with...
|
||
$dzbit:: .blkw 1 ;enable bit (lsh 1 line_number)
|
||
$dzint:: .blkw 1 ;place to put the bit to interrupt do XMIT
|
||
$dzbct:: .blkw 1 ;how many we've done
|
||
>,l$dzx
|
||
|
||
;;; DZ11s are PDP11 interfaces to 8 serial lines. Each line is supported
|
||
;;; by one source object, and the transmitter by one destination object.
|
||
|
||
dz$vec: .blkw ndz ;interrupt vector location
|
||
dz$csr: .blkw ndz ;csr device register base address
|
||
dz$tty: .blkw ndz ;base tty number of this dz
|
||
dz$nli: .blkw ndz ;number of lines on the DZs
|
||
dz$bkc: .blkw ndz ;break bits
|
||
|
||
dz%bit: .rept 8.
|
||
.word 1_.rpcnt
|
||
.endr
|
||
|
||
dz$brk:
|
||
.rept ndz
|
||
.lif z .rpcnt
|
||
dz$rbk::
|
||
jsr r0,@#dzrint
|
||
.rpcnt*2
|
||
.lif z .rpcnt
|
||
dz$xbk::
|
||
jsr r0,@#dzxint
|
||
.rpcnt*2
|
||
.endr
|
||
ldz$brk==<.-dz$brk>/ndz
|
||
|
||
|
||
|
||
;;; DZ11 receiver interrupt handler. Interrupt vector points in DZ$BRK, which
|
||
;;; contains a JSR R0,@#DZRINT. This saves r0 on the stack, and the DZ index
|
||
;;; can be picked up with MOV (R0),R0
|
||
|
||
;;; r0: device index
|
||
;;; r1: character
|
||
;;; r4: tty device
|
||
;;; r5: csr
|
||
|
||
dzrint: mov (r0),r0 ;get the DZ index
|
||
push r1,r4,r5 ;save some more regs
|
||
mov dz$csr(r0),r5 ;get the CSR
|
||
loop <
|
||
mov dz.rbf(r5),r1 ;get the receiver buffer
|
||
exitl pl ;nothing there, so exit
|
||
mov r1,r4
|
||
swab r4
|
||
bic #dz.rln,r4 ;get line number
|
||
cmp r4,dz$nlines(r0) ;make sure it is known
|
||
if lt,<
|
||
asl r4
|
||
add dz$tty(r0),r4 ;tty index
|
||
mov ttyrdv(r4),r4 ;get the receive device
|
||
bit #dz.frm,r1 ;BREAK?
|
||
if ne,<
|
||
movb #%acom,r1 ;send COM-B
|
||
call @$dvlpt(r4) ;put the character in the device
|
||
movb #'B,r1
|
||
>
|
||
else <
|
||
bic #dz.rch,r1 ;get character bits only
|
||
>
|
||
call @$dvlpt(r4) ;put the character in the device
|
||
>
|
||
rptl ;try for more characters
|
||
>
|
||
pop r5,r4,r1,r0 ;restore all regs
|
||
rti
|
||
|
||
;;; DZ11 Transmitter interrupt handler. Interrupt vector points in DZ$BRK
|
||
;;; which contains a JSR R0,@#DZXINT. This saves r0 on the stack and the DZ
|
||
;;; index can be picked up with MOV (R0),R0.
|
||
|
||
;;; r0: dz index
|
||
;;; r1: temp for character
|
||
;;; r4: tty output device
|
||
;;; r5: dz csr
|
||
|
||
dzxint: mov (r0),r0
|
||
push r1,r3,r4,r5 ;save some more regs
|
||
mov dz$csr(r0),r5
|
||
loop <
|
||
mov dz.csr(r5),r3 ;read CSR
|
||
exitl pl ;no more lines ready
|
||
swab r3
|
||
bic #dz.xln,r3 ;get line number
|
||
asl r3 ;indexable
|
||
add dz$tty(r0),r3 ;tty index
|
||
mov ttyxdv(r3),r4 ;get tty output object
|
||
tst $dzbct(r4) ;in break?
|
||
if ne,<
|
||
if gt,<
|
||
bisb $dzbit(r4),dz$bkc(r0)
|
||
movb dz$bkc(r0),dz.xbr(r5)
|
||
>
|
||
cmp $dzbct(r4),ttyispd(r3)
|
||
if gt,<
|
||
bicb $dzbit(r4),dz$bkc(r0)
|
||
movb dz$bkc(r0),dz.xbr(r5)
|
||
clr $dzbct(r4)
|
||
br 10$
|
||
>
|
||
clrb dz.xdr(r5) ;send a NUL
|
||
add #50.,$dzbct(r4) ;done yet?
|
||
rptl
|
||
>
|
||
10$: tst $dvhmn(r4)
|
||
if gt,<
|
||
call chnfgt
|
||
movb r1,dz.xdr(r5) ;put character in xmit data register
|
||
>
|
||
else <bic $dzbit(r4),@$dzint(r4)> ;clear interrupt bit
|
||
rptl
|
||
>
|
||
pop r5,r4,r3,r1,r0
|
||
rti
|
||
|
||
|
||
dzpwu::
|
||
dzini: clr r0
|
||
loop <
|
||
call dzinit ;initial this DZ11
|
||
add #2,r0
|
||
cmp r0,#2*ndz ;done all of them yet?
|
||
rptl lt
|
||
>
|
||
return
|
||
|
||
dzinit: push r5,r4
|
||
mov dz$csr(r0),r5
|
||
call nxmcat
|
||
dznxm
|
||
mov #dz.mcl,dz.csr(r5) ;request a master clear
|
||
call nxmclr ;it's probably there
|
||
loop <
|
||
bit #dz.mcl,dz.csr(r5)
|
||
rptl ne ;wait for master clear to finish
|
||
>
|
||
|
||
mov dz$vec(r0),r4 ;get vector
|
||
mov r0,r5 ;get index
|
||
mul #ldz$brk/2,r5 ;convert to offset into dz$brk (table)
|
||
add #dz$rbk,r5 ;point to receiver interrupt routine
|
||
mov r5,(r4)+ ;setup receiver interrupt routine
|
||
mov #pr5,(r4)+ ;and priority
|
||
sub #dz$rbk-dz$xbk,r5 ;now has pointer to xmit routine
|
||
mov r5,(r4)+ ;setup xmit interrupt routine
|
||
mov #pr5,(r4)+ ;and priority
|
||
|
||
mov dz$csr(r0),r5 ;get csr back
|
||
|
||
push r2,r1
|
||
clr r4 ;start at line zero
|
||
loop <
|
||
;;get the speed part of the LPR
|
||
mov r4,r1
|
||
asl r1
|
||
add dz$tty(r0),r1 ;now is tty index
|
||
mov #dzstbl,r2
|
||
loop <
|
||
tst (r2)
|
||
if eq,<bpt>
|
||
cmp (r2)+,ttyisp(r1)
|
||
exitl eq
|
||
tst (r2)+
|
||
rptl
|
||
>
|
||
mov (r2),r1 ;get speed part
|
||
|
||
bis r4,r1 ;or in the line line
|
||
bis #dz.rcv+dz.paN+dz.8bt,r1
|
||
mov r1,dz.lpr(r5) ;setup the line parameter register
|
||
|
||
mov r4,r1
|
||
asl r1
|
||
push r1
|
||
add dz$tty(r0),(sp) ;tty index
|
||
push #l$dzr,#l$dzx ;size of xmit and recv devices
|
||
call ttygood
|
||
if cs,<bpt>
|
||
|
||
pop r2 ;get xmit device
|
||
mov #dzpput,$dvppt(r2) ;set physical put
|
||
mov #dzpio,$dvlio(r2) ;and I/O control
|
||
mov dz%bit(r1),$dzbit(r2)
|
||
mov r5,$dzint(r2)
|
||
add #dz.xcr,$dzint(r2)
|
||
|
||
pop r2 ;get receive devices
|
||
mov #dzpget,$dvpgt(r2) ;set physical get routine
|
||
|
||
pop * ;punt tty index
|
||
|
||
inc r4
|
||
cmp r4,dz$nlines(r0)
|
||
rptl lo
|
||
>
|
||
pop r1,r2
|
||
|
||
mov #dz.xie+dz.rie+dz.mse,dz.csr(r5) ;enable the world
|
||
|
||
pop r4,r5
|
||
return
|
||
|
||
.macro ..dzs speed,ubusval,qbusval
|
||
.if z qbus
|
||
.if ge ubusval
|
||
.word speed,ubusval'_dz.spd
|
||
.endc
|
||
.iff
|
||
.if ge qbusval
|
||
.word speed,qbusval'_dz.spd
|
||
.endc
|
||
.endc
|
||
.endm
|
||
|
||
dzstbl: ;dz speed table (unibus version may not be
|
||
;correct. Assumed same as qbus.)
|
||
..dzs 19200.,17,17
|
||
..dzs 9600.,16,16
|
||
..dzs 7200.,15,15 ;only on qbus version
|
||
..dzs 4800.,14,14
|
||
..dzs 3600.,13,13
|
||
..dzs 2400.,12,12
|
||
..dzs 2000.,11,11
|
||
..dzs 1800.,10,10
|
||
..dzs 1200.,07,07
|
||
..dzs 600.,06,06
|
||
..dzs 300.,05,05
|
||
.word 0
|
||
|
||
dzpio: .word $open,dzpopn ;I/O control
|
||
.word $close,dzpcls
|
||
.word ttybrk,dzpbrk
|
||
.word 0
|
||
|
||
dznxm: push r0
|
||
mov dz$nlines(r0),r5
|
||
mov dz$tty(r0),r0
|
||
loop <
|
||
call ttybad
|
||
tst (r0)+
|
||
sorl r5
|
||
>
|
||
pop r0,r4,r5
|
||
return
|
||
|
||
dzpput: lock 6
|
||
call chnput
|
||
if cc,<bisb $dzbit(r4),@$dzint(r4)>
|
||
unlock
|
||
return
|
||
|
||
dzpget:
|
||
lock 6
|
||
call chnget
|
||
unlock
|
||
return
|
||
|
||
dzpopn: push $dzbit(r4) ;set DTR
|
||
swab (sp)
|
||
bis (sp)+,@$dzint(r4)
|
||
return
|
||
|
||
dzpcls: push $dzbit(r4) ;reset DTR
|
||
swab (sp)
|
||
bic (sp)+,@$dzint(r4)
|
||
return
|
||
|
||
dzpbrk: mov #-1,$dzbct(r4) ;start breaking
|
||
bisb $dzbit(r4),@$dzint(r4)
|
||
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:
|