1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-25 01:47:08 +00:00
Files
PDP-10.its/src/mits_s/dz11.5
2018-11-25 20:59:17 +01:00

423 lines
9.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 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: