mirror of
https://github.com/PDP-10/its.git
synced 2026-03-21 08:48:51 +00:00
835 lines
19 KiB
Groff
Executable File
835 lines
19 KiB
Groff
Executable File
|
||
.lif z %defin
|
||
.title Versatec (V80) support
|
||
.sbttl Versatec (V80) support: Definitions, Macros and Code
|
||
v80vrs==%fnam2
|
||
|
||
;;; Plotter will be refered to as MATRIX (because printer and
|
||
;;; plotter both begin with "p"
|
||
|
||
.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
|
||
|
||
;;; prefixes used in this module
|
||
|
||
;;; ;;; V8. Hardware interface offsets and bits
|
||
;;; ;;; $VS Versated scan line structure offsets
|
||
;;; ;;; $VH Hardware device object offsets
|
||
;;; ;;; VA V80 hardware routines
|
||
;;; ;;; V80 V80 support routines (random things)
|
||
;;; ;;; V8S V80 scan line routines
|
||
;;; ;;; V8% V80 scan line commands
|
||
;;; ;;; V8N V80 network routines
|
||
;;; ;;; V8C V80 constants
|
||
;;; ;;; V8V V80 variables
|
||
;;; ;;; V8T V80 tables
|
||
;;; ;;; V8$ V80 strings
|
||
|
||
|
||
;;; ;;; typical register usage:
|
||
;;; ;;; r0/ chaos connection
|
||
;;; ;;; r1/ chaos packet
|
||
;;; ;;; r2/ V80 hardware/interface object (v80 connection?)
|
||
;;; ;;; r3/ V80 scan line (V80 packet?)
|
||
;;; ;;; r5/ device base address = $vaadr(r2)
|
||
|
||
|
||
;; V80 definitions
|
||
;; offsets to the device registers (relative to printer status)
|
||
v8.mbc==00 ;matrix byte count
|
||
v8.ext==02 ;dma data buffer address extension bits
|
||
v8.pbc==04 ;printer byte count
|
||
v8.dma==06 ;dma data buffer address
|
||
v8.mcs==10 ;matrix control and status
|
||
v8.mdb==12 ;matrix data buffer
|
||
v8.pcs==14 ;printer control and status
|
||
v8.pdb==16 ;printer data buffer
|
||
|
||
;;; Control and Status Register bits
|
||
v8.err==bit.15 ;error
|
||
v8.dtc==bit.14 ;data transmission complete interrupt enable
|
||
v8.bsy==bit.13 ;DMA busy
|
||
v8.swp==bit.09 ;swap bytes on DMA transfer
|
||
v8.ers==bit.08 ;DMA erase after read
|
||
v8.rdy==bit.07 ;ready
|
||
v8.ien==bit.06 ;interrupt enable
|
||
v8.lnt==bit.05 ;remote line terminate
|
||
v8.frm==bit.04 ;remote form feed
|
||
v8.eot==bit.03 ;remote end of transmission
|
||
v8.clb==bit.02 ;clear buffer
|
||
v8.rst==bit.01 ;remote reset
|
||
v8.spp==bit.00 ;enable SPP
|
||
|
||
.endc p1
|
||
.sbttl -- Macros
|
||
|
||
v8cnv8==0 ;start with no V80s
|
||
.macro v8 pvec,mvec,csr,nos,chwin
|
||
.if p2
|
||
%%==.
|
||
.=v8tpvc+<2*v8cnv8>
|
||
.word pvec
|
||
.=v8tmvc+<2*v8cnv8>
|
||
.word mvec
|
||
.=v8tcsr+<2*v8cnv8>
|
||
.word csr
|
||
.=%%
|
||
.endc p2
|
||
v8cnos==nos
|
||
v8cchw==chwin
|
||
v8cnv8==v8cnv8+1
|
||
.endm
|
||
|
||
|
||
chnsrv ^"VERSATEC",cxversatec ;define the new server
|
||
|
||
.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
|
||
|
||
.sbttl VA.... Interface definitions and tables
|
||
|
||
;;
|
||
;;;;;; a V80 hardware object
|
||
;;
|
||
|
||
dsect < ;;interface/hardware object
|
||
$vasta:: .blkw 1 ;device available flag
|
||
%vsava==100000 ;available flag (must be high bit)
|
||
%vsprn==000001 ;state is printing
|
||
%vsplt==000002 ;state is plotting
|
||
$vaadd:: .blkw 1 ;address of this interface
|
||
$vaxqu:: .blkw 1 ;transmission queue
|
||
$vaxqe:: .blkw 1 ;pointer to end of transmission queue
|
||
$vanvs:: .blkw 1 ;number of items on transmission queue
|
||
$vanos:: .blkw 1 ;number of output slots on queue
|
||
$vapks:: .blkw 1 ;chaos packets (print) that should be freed
|
||
$vacur:: .blkw 1 ;current scan line being worked on
|
||
$vaprv:: .blkw 1 ;previous scan line (for XORing)
|
||
$vaeof:: .blkw 1 ;consecutive CHAOS EOF count
|
||
$vawid:: .blkw 1 ;width of usable line in bytes
|
||
$varem:: .blkw 1 ;number of bytes remaning in line
|
||
$valft:: .blkw 1 ;offset to left of scan line
|
||
$vaxor:: .blkw 1 ;xor flag
|
||
$vacon:: .blkw 1 ;current command continuation (0 for top level)
|
||
$vacom:: .blkw 1 ;last command (in case continuation needs it)
|
||
$vanar:: .blkw 1 ;number of args needed for current command
|
||
$vaarp:: .blkw 1 ;pointer to place to deposit next arg
|
||
$vaarg:: .blkb 64. ;max of 64 bytes of args (plot n)
|
||
;; if you add things, be sure to update VAINI and V80DWN
|
||
>,l$vaobj
|
||
|
||
;;
|
||
;;;;;; Tables
|
||
;;
|
||
|
||
.wvector v8tobj,v8cnv8 ;table of the objects
|
||
|
||
v8tpvc: .blkw v8cnv8 ;print vector
|
||
v8tmvc: .blkw v8cnv8 ;matrix vector
|
||
v8tcsr: .blkw v8cnv8 ;control and status register
|
||
|
||
;;
|
||
;;;;;; Interrupt vectors point here
|
||
;;
|
||
|
||
v8tbrk:
|
||
.rept v8cnv8
|
||
.lif z .rpcnt
|
||
v8tpbr::
|
||
jsr r2,@#vaintp
|
||
.word v8tobj+<2*.rpcnt>
|
||
.lif z .rpcnt
|
||
v8tmbr::
|
||
jsr r2,@#vaintm
|
||
.word v8tobj+<2*.rpcnt>
|
||
.endr
|
||
lv8tbrk==<.-v8tbrk>/v8cnv8
|
||
|
||
v8tvap: ;vector address, print
|
||
.rept v8cnv8
|
||
.word v8tpbr+<.rpcnt*lv8tbrk>
|
||
.endr
|
||
|
||
v8tvam: ;vector address, matrix
|
||
.rept v8cnv8
|
||
.word v8tmbr+<.rpcnt*lv8tbrk>
|
||
.endr
|
||
|
||
|
||
|
||
;;; Init the Versatec hardware(s)
|
||
|
||
v8ini:
|
||
vaini: clr r0 ;start at v80 index 0
|
||
loop <
|
||
call 100$ ;really init the beast
|
||
add #2,r0
|
||
cmp r0,#v8cnv8*2
|
||
rptl lo
|
||
>
|
||
call v8sini ;init the scan line routines
|
||
return
|
||
|
||
100$: ;do the work
|
||
mov v8tcsr(r0),r3
|
||
call nxmcat ;catch bad interface
|
||
vanxm
|
||
mov #v8.clb,v8.pcs(r3) ;clear buffer (to print CSR)
|
||
mov #v8.clb,v8.mcs(r3) ;clear buffer (to matrix CSR)
|
||
clr v8.dma(r3) ;clear DMA address
|
||
clr v8.ext(r3) ;and DMA address extension bits
|
||
call nxmclr ;safe, interface is alive
|
||
|
||
mov v8tpvc(r0),r2 ;get print vector
|
||
mov v8tvap(r0),(r2)+ ;set vector address
|
||
mov #pr5,(r2)+ ;and priority
|
||
mov v8tmvc(r0),r2 ;get matrix vector
|
||
mov v8tvam(r0),(r2)+ ;set vector address
|
||
mov #pr5,(r2)+ ;and priority
|
||
|
||
push #l$vaobj
|
||
call fsmall
|
||
call fsmclr
|
||
pop r2
|
||
if eq,<bpt> ;oops, out of memory at initialization
|
||
mov r2,v8tobj(r0)
|
||
|
||
mov #%vsava,$vasta(r2) ;device is available
|
||
mov r3,$vaadd(r2) ;set it's CSR address
|
||
|
||
jcall v80dwn ;shut down this versatec
|
||
|
||
vanxm: clr v8tobj(r0) ;declare no hardware object
|
||
return
|
||
|
||
v80dwn: tst sysup ;is the system up yet
|
||
if ne,< ;yup
|
||
push r1,r3
|
||
mov $vaxqu(r2),r3 ;get the Xmit queue
|
||
if ne,<call v8sfrl> ;free it if exists
|
||
mov $vacur(r2),r3 ;get current scan line
|
||
if ne,<call v8sfre> ;free it if exists
|
||
mov $vaprv(r2),r3 ;get previous scan line
|
||
if ne,<call v8sfre> ;free it if exists
|
||
mov $vapks(r2),r1 ;get list of chaos packets to free
|
||
if ne,<call cpkfrl> ;free them if exists
|
||
call v8sfls ;flush all scan lines
|
||
pop r3,r1
|
||
>
|
||
push r2
|
||
add #$vaxqu,r2 ;want to auto-inc
|
||
clr (r2)+ ;nothing on the Xmit queue
|
||
mov r2,(r2) ;set up end pointer
|
||
sub #2,(r2)+ ;...
|
||
clr (r2)+ ;no scan lines on the Xmit list
|
||
mov #v8cnos,(r2)+ ;all output slots available
|
||
clr (r2)+ ;no chaos packets to free
|
||
clr (r2)+ ;no current scan line
|
||
clr (r2)+ ;no previous scan line
|
||
clr (r2)+ ;no chaos eofs
|
||
clr (r2)+ ;no width
|
||
clr (r2)+ ;no bytes remaining
|
||
clr (r2)+ ;no left margin info yet
|
||
clr (r2)+ ;don't do XOR
|
||
clr (r2)+ ;no current command continuation
|
||
add #3*2,r2 ;last command, # needed args, arg ptr have
|
||
;no meaning without command continuation
|
||
pop r2
|
||
return
|
||
|
||
|
||
|
||
vaintp: ;printer support
|
||
mov @(r2),r2 ;get the hardware object
|
||
push r1,r5
|
||
mov $vaadd(r2),r5 ;get device address
|
||
loop <
|
||
mov $vaxqu(r2),r1 ;get a packet off the list
|
||
if eq,<
|
||
bic #v8.ien,v8.pcs(r5) ;turn off interrupts
|
||
mov r2,$vaxqe(r2) ;set up end pointer
|
||
add #$vaxqu,$vaxqe(r2) ;...
|
||
exitl
|
||
>
|
||
tst $cpknb(r1) ;did we already use it?
|
||
if mi,< ;yup
|
||
mov (r1),$vaxqu(r2) ;unlink it
|
||
dec $vanvs(r2) ;one less scan line
|
||
inc $vanos(r2) ;one more output slot
|
||
mov $vapks(r2),(r1) ;link the chaos packets into this one
|
||
mov r1,$vapks(r2) ;and make this one the list
|
||
rptl ;and try again
|
||
>
|
||
push r1
|
||
add #$cpkdt,(sp) ;point to the data region
|
||
pop v8.dma(r5) ;put it in the DMA register
|
||
push $cpknb(r1) ;number of bytes
|
||
neg (sp) ;V80 wants 2's complement
|
||
pop v8.pbc(r5) ;this is the printer byte count
|
||
bis #bit.15,$cpknb(r1) ;flag this packet as printed
|
||
>
|
||
pop r5,r1,r2 ;pop all regs
|
||
rti
|
||
|
||
|
||
|
||
vaintm: mov @(r2),r2 ;get the hardware object
|
||
push r3,r5 ;for scan line and device address
|
||
mov $vaadd(r2),r5 ;get the address of the interface
|
||
loop < ;loop over the transmission queue
|
||
mov $vaxqu(r2),r3 ;get the scan line on the front
|
||
if eq,<
|
||
bic #v8.ien,v8.mcs(r5) ;turn off interrupts
|
||
mov r2,$vaxqe(r2) ;set up the end of the queue
|
||
add #$vaxqu,$vaxqe(r2) ;...
|
||
exitl
|
||
>
|
||
tst $vsskb(r3) ;skip before?
|
||
if ne,< ;yup
|
||
dec $vsskb(r3)
|
||
bis #v8.lnt,v8.mcs(r5) ;terminate line
|
||
exitl
|
||
>
|
||
tst $vsnum(r3) ;print this line?
|
||
if ne,< ;yup
|
||
dec $vsnum(r3)
|
||
push r3
|
||
add #$vsdat,(sp) ;point to data
|
||
pop v8.dma(r5) ;set the DMA address
|
||
mov #-%vsnby,v8.mbc(r5) ;neg byte count
|
||
exitl
|
||
>
|
||
tst $vsska(r3) ;skip after?
|
||
if ne,< ;yup
|
||
dec $vsska(r3)
|
||
bis #v8.lnt,v8.mcs(r5) ;terminate line
|
||
exitl
|
||
>
|
||
tst $vsflg(r3)
|
||
if ne,<
|
||
bis #v8.frm,v8.mcs(r5) ;remote form feed
|
||
clr $vsflg(r3)
|
||
exitl
|
||
>
|
||
mov $vslnk(r3),$vaxqu(r2) ;unlink this scan line
|
||
dec $vanvs(r2) ;one less scan line
|
||
inc $vanos(r2) ;another output slot
|
||
mov #-1,$vslnk(r3) ;no longer on a transmit list
|
||
cmp r3,$vaprv(r2) ;is this the previous packet
|
||
if ne,<call v8sfre> ;free the scan line
|
||
rptl ;and try again
|
||
>
|
||
pop r5,r3,r2
|
||
rti
|
||
|
||
.sbttl V80... V80 random support routines
|
||
|
||
v80wto: ;wait for an output slot
|
||
loop <
|
||
tst $vanos(r2)
|
||
exitl gt
|
||
push r0,r1,r2
|
||
add #$vanos,r2
|
||
.regs #hng.ne,#zero
|
||
.hang
|
||
pop r2,r1,r0
|
||
rptl
|
||
>
|
||
return
|
||
|
||
v80frc: loop <
|
||
tst $vanvs(r2)
|
||
exitl eq
|
||
push r0,r1,r2
|
||
add #$vanvs,r2
|
||
.regs #hng.eq,#zero
|
||
.hang
|
||
pop r2,r1,r0
|
||
>
|
||
return
|
||
|
||
v80vso: call v80wto
|
||
lock 5
|
||
clr (r3)
|
||
mov r3,@$vaxqe(r2)
|
||
mov r3,$vaxqe(r2)
|
||
inc $vanvs(r2)
|
||
dec $vanos(r2)
|
||
add $vaadd(r2),r5
|
||
bis #v8.ien,(r5)
|
||
unlock
|
||
return
|
||
|
||
.sbttl V8S... V80 scan line (de)allocation routines
|
||
|
||
;;; Versatec scan line structure
|
||
|
||
%vsnby==2112./8. ;number of bytes in a scan line
|
||
|
||
dsect <
|
||
$vslnk:: .blkw 1 ;transmit link, for packet linking
|
||
$vsskb:: .blkw 1 ;scan lines to skip before this line
|
||
$vsnum:: .blkw 1 ;number of times to do this scan line
|
||
$vsska:: .blkw 1 ;scan lines to skip after this line
|
||
$vsflg:: .blkw 1 ;flags
|
||
;; be sure to update v8sall if you change this
|
||
$vsdat:: .blkb %vsnby ;actual scan data
|
||
.even
|
||
>,l$vs
|
||
|
||
|
||
.wscalar v8vfrl ;free scan line list
|
||
.wscalar v8vnfr ;number on the freelist
|
||
|
||
v8sini: ;initialize scan lines
|
||
clr v8vfrl ;clear the head of the list
|
||
clr v8vnfr ;and nothing on it
|
||
return
|
||
|
||
;;; Free the scan line in r3
|
||
v8sfre: cmp v8vnfr,#v8cnos+2 ;should we free it?
|
||
if ge,< push r3 ;give it back to free storage
|
||
call fsmfre ;must be CALLED
|
||
inc r3 ;cause error on word reference
|
||
return>
|
||
lock 5 ;no interrupts from versatec
|
||
mov v8vfrl,(r3) ;shove the freelist into the scan
|
||
mov r3,v8vfrl ;and make it the freelist
|
||
inc v8vnfr ;one more scan line on the freelist
|
||
unlock
|
||
inc r3 ;cuase error on word reference
|
||
return
|
||
|
||
v8sfrl: push r5 ;to hold the list
|
||
mov r3,r5 ;put the list in r5
|
||
loop <
|
||
mov r5,r3 ;get the scan line
|
||
exitl eq ;finished if no packet
|
||
mov (r3),r5 ;cdr on down
|
||
call v8sfre ;free the one scan line
|
||
rptl ;and loop around
|
||
>
|
||
pop r5
|
||
return
|
||
|
||
;;; Flush the current list of available packets
|
||
|
||
v8sfls: lock 5
|
||
mov v8vfrl,r5
|
||
clr v8vfrl
|
||
clr v8vnfr
|
||
unlock
|
||
loop <
|
||
push r5
|
||
exitl eq
|
||
mov (r5),r5
|
||
call fsmfre
|
||
rptl
|
||
>
|
||
pop *
|
||
return
|
||
|
||
;;; Allocate a scan line. Return in r3 (or 0 if none)
|
||
v8sall: lock 5 ;don't allow versatec to confuse the freelist
|
||
mov v8vfrl,r3 ;get the top of the freelist
|
||
if ne,< mov (r3),v8vfrl ;unlink it
|
||
dec v8vnfr ;one less on the freelist
|
||
unlock>
|
||
else < unlock ;it is indeed safe
|
||
push #l$vs ;length of a scan line structure
|
||
call fsmall
|
||
pop r3>
|
||
push r3
|
||
if ne,<
|
||
mov #-1,(r3)+ ;not linked on any list
|
||
clr (r3)+ ;0 skip before count
|
||
clr (r3)+ ;0 times to print this one
|
||
clr (r3)+ ;0 skip after count
|
||
clr (r3)+ ;no flags
|
||
>
|
||
pop r3 ;set Z flag in the process if zero
|
||
return
|
||
|
||
|
||
.sbttl V8%... Chaos packet discombobulating
|
||
|
||
%v8eop==0
|
||
%v8rpt==000
|
||
%v8skp==100
|
||
%v8plt==200
|
||
%v8eol==300
|
||
%v8rpl==300
|
||
%v8xor==337
|
||
%v8mar==340
|
||
%v8ma1==350
|
||
|
||
;;; Conventions:
|
||
;;; r0: Number of bytes left in CHAOS packet
|
||
;;; r1: Byte pointer into CHAOS packet
|
||
;;; r2: Hardware object
|
||
;;; r3: byte pointer into current scan line
|
||
;;; r4: available
|
||
;;; r5: available
|
||
|
||
;;; push <number of args needed>
|
||
;;; call va%gar
|
||
;;; looks like it returns when all args accumulated
|
||
;;; must save r4 and r5 if you want to keep them. Do not save them on
|
||
;;; the stack
|
||
|
||
va%gar: pop $vacon(r2) ;save return address as continuation
|
||
pop $vanar(r2) ;number of args we need
|
||
mov r2,$vaarp(r2) ;setup pointer to place ...
|
||
add #$vaarg,$vaarp(r2) ;... to deposit next args
|
||
va%ga2: ;;; packet processor reenters here
|
||
mov $vanar(r2),r4 ;number of args still needed
|
||
tst r4
|
||
if ne,<
|
||
tst r0
|
||
if ne,<
|
||
cmp r0,r4
|
||
if lt,<mov r0,r4> ;take min with chaos bytes
|
||
sub r4,r0 ;number of packet bytes when finished
|
||
sub r4,$vanar(r2) ;discount it from number we need
|
||
mov $vaarp(r2),r5 ;get pointer to next place for args
|
||
loop <
|
||
movb (r1)+,(r5)+
|
||
sorl r4
|
||
>
|
||
mov r5,$vaarp(r2) ;save new value
|
||
>
|
||
>
|
||
tst $vanar(r2) ;test possible new value
|
||
if ne,<return> ;need more, return to packet processor
|
||
push $vacon(r2) ;restore return address
|
||
clr $vacon(r2) ;no continuation for next time
|
||
return ;and return to command processor
|
||
|
||
|
||
v8%eop: call v8%lfn ;finish current line
|
||
mov $vacur(r2),r3
|
||
mov #-1,$vsflg(r3)
|
||
v8%out: lock 5
|
||
mov $vaprv(r2),r3 ;get previous
|
||
if ne,<
|
||
cmp (r3),#-1 ;is it on a transmit list?
|
||
if eq,<call v8sfre> ;free it if not
|
||
>
|
||
mov $vacur(r2),r3 ;get current
|
||
mov r3,$vaprv(r2) ;new previous
|
||
unlock
|
||
mov #v8.mcs,r5 ;address offset
|
||
call v80vso
|
||
v8%new: loop <
|
||
call v8sall ;get a new one
|
||
exitl ne
|
||
push r0,r1
|
||
.regs #1,#0
|
||
.sleep
|
||
pop r1,r0
|
||
rptl
|
||
>
|
||
mov r3,$vacur(r2)
|
||
add $valft(r2),r3
|
||
mov $vawid(r2),$varem(r2)
|
||
jcall v8%clr ;clear the scan line
|
||
|
||
v8%rpt: mov r5,$vacom(r2) ;save command
|
||
push #1 ;one arg
|
||
call va%gar ;get it
|
||
mov $vacom(r2),r5 ;get command back
|
||
bic #mask6,r5
|
||
inc r5
|
||
sub r5,$varem(r2)
|
||
movb $vaarg(r2),r4 ;get the arg
|
||
loop <
|
||
movb r4,(r3)+
|
||
sorl r5
|
||
>
|
||
return
|
||
|
||
v8%skp: mov r5,$vacom(r2) ;save command
|
||
push #1 ;one arg
|
||
call va%gar ;get it
|
||
mov $vacom(r2),r5 ;get command back
|
||
bic #mask6,r5
|
||
inc r5
|
||
sub r5,$varem(r2)
|
||
add r5,r3
|
||
movb $vaarg(r2),(r3)+ ;set the byte
|
||
dec $varem(r2)
|
||
return
|
||
|
||
v8%plt: bic #mask6,r5
|
||
inc r5
|
||
mov r5,$vacom(r2) ;save nbytes as command
|
||
push r5 ;number of args needed
|
||
call va%gar
|
||
mov $vacom(r2),r5 ;get number of bytes back
|
||
|
||
sub r5,$varem(r2)
|
||
mov r2,r4
|
||
add #$vaarg,r4 ;get pointer to args
|
||
loop <
|
||
movb (r4)+,(r3)+
|
||
sorl r5
|
||
>
|
||
return
|
||
|
||
v8%eol: jcall v8%lad
|
||
|
||
v8%rpl: bic #mask5,r5
|
||
push r5
|
||
call v8%lfn
|
||
pop r5
|
||
push r3
|
||
mov $vaprv(r2),r3
|
||
lock 5
|
||
add r5,$vsnum(r3)
|
||
cmp (r3),#-1 ;is it on a transmit list
|
||
if eq,< mov #v8.mcs,r5 ;address offset
|
||
call v80vso> ;if not, put it back on
|
||
unlock
|
||
pop r3
|
||
return
|
||
|
||
v8%xor: call v8%lfn
|
||
mov #-1,$vaxor(r2)
|
||
return
|
||
|
||
v8%mar: mov r5,$vacom(r2) ;save command
|
||
push #3 ;need 3 args
|
||
call va%gar ;get them
|
||
mov $vacom(r2),r5 ;get command back
|
||
bic #mask3,r5
|
||
movb $vaarg+0(r2),r4
|
||
bic #mask8,r4
|
||
ash #3,r4
|
||
add r5,r4
|
||
dec r4 ;convert one based to zero based
|
||
mov $vacur(r2),r5 ;get current scan line
|
||
mov r4,$vsskb(r5) ;tell it to skip before the top margin
|
||
;before printing
|
||
pushb $vaarg+1(r2) ;get second arg
|
||
bic #mask8,(sp)
|
||
movb $vaarg+2(r2),r4 ;get third arg
|
||
bic #mask8,r4
|
||
v8%ma.: sub (sp),r4
|
||
inc r4
|
||
mov r4,$vawid(r2)
|
||
mov r4,$varem(r2)
|
||
mov #$vsdat-1,r3 ;point to data with conversion from one
|
||
;based to zero based.
|
||
add (sp)+,r3
|
||
mov r3,$valft(r2)
|
||
add $vacur(r2),r3
|
||
return
|
||
|
||
v8%ma1: push #4
|
||
call va%gar ;get 4 args
|
||
push $vaarg+0(r2) ;get first 2
|
||
swab (sp) ;PDP-10 to PDP-11 style
|
||
push $vaarg+2(r2) ;get second 2
|
||
swab (sp) ;pdp-10 to pdp-11 style
|
||
pop r4
|
||
br v8%ma.
|
||
|
||
v8%lfn: cmp $varem(r2),$vawid(r2)
|
||
if eq,<return>
|
||
loop <
|
||
tst $vaxor(r2)
|
||
if ne,< call v8%dxr
|
||
clr $vaxor(r2)>
|
||
exitl
|
||
v8%lad: cmp $varem(r2),$vawid(r2)
|
||
rptl ne
|
||
>
|
||
mov $vacur(r2),r3
|
||
mov #1,$vsnum(r3)
|
||
jcall v8%out
|
||
|
||
v8%clr: mov $vacur(r2),r4
|
||
add #$vsdat,r4
|
||
mov #<%vsnby+1>/2,r5
|
||
loop <
|
||
clr (r4)+
|
||
sorl r5
|
||
>
|
||
return
|
||
|
||
v8%dxr: mov $vacur(r2),r5
|
||
mov $vaprv(r2),r4
|
||
add #$vsdat,r5
|
||
add #$vsdat,r4
|
||
push r2,r3
|
||
mov #<%vsnby+1>/2,r3
|
||
loop <
|
||
mov (r4)+,r2
|
||
xor r2,(r5)+
|
||
sorl r3
|
||
>
|
||
pop r3,r2
|
||
return
|
||
|
||
.sbttl V8N... Versatec network handler
|
||
|
||
cxversatec::
|
||
v8nchaos:
|
||
cx$srv v8nopn,40,240_8,<>
|
||
|
||
v8nopn: call cpkpki ;get the RFC
|
||
if cs,<
|
||
110$: call ccnfre
|
||
.logout
|
||
>
|
||
mov #v8cnv8,r5 ;number of V80 configured
|
||
mov #v8tobj,r4 ;pointer to devices
|
||
loop <
|
||
mov (r4)+,r2 ;set the hardware object
|
||
if ne,< ;if there is something there
|
||
tst $vasta(r2) ;is it available?
|
||
exitl mi ;yup, so use it
|
||
>
|
||
sorl r5 ;else try for the next
|
||
mov (pc)+,r2
|
||
.string <All VERSATECs at this site are in use.>
|
||
120$: clr $cpknb(r1)
|
||
call cpkaz1 ;stuff message into one packet
|
||
movb #%cocls,$cpkop(r1) ;make it a close packet
|
||
call cpkpko ;output it
|
||
br 110$
|
||
>
|
||
clr $vasta(r2) ;no longer available, no status
|
||
mov $vaadd(r2),r5
|
||
mov #v8.clb,v8.pcs(r5) ;clear buffer command
|
||
mov #v8cchw,$cpkpn(r1) ;window size
|
||
movb #%coopn,$cpkop(r1) ;open packet
|
||
call cpkpko ;output packet
|
||
call v80dwn ;shut it down for good measure
|
||
clr $vaeof(r2) ;no eof packets seen yet.
|
||
loop <
|
||
lock 5
|
||
mov $vapks(r2),r1 ;get packets that may need freeing
|
||
if eq,<unlock>
|
||
else <
|
||
clr $vapks(r2)
|
||
unlock
|
||
call cpkfrl
|
||
>
|
||
call cpkpki ;get a packet
|
||
if cs,<
|
||
200$: call v80frc ;force all scans out
|
||
call v80dwn ;shut down the versatec
|
||
mov $vaadd(r2),r3
|
||
bis #v8.frm,v8.pcs(r3) ;issue form feed
|
||
mov #%vsava,$vasta(r2) ;make it available
|
||
br 110$
|
||
>
|
||
if eq,<
|
||
call cpkwti ;wait for an input packet
|
||
rptl
|
||
>
|
||
tstb $cpkop(r1) ;is it data?
|
||
if pl,<
|
||
pushb $cpkop(r1)
|
||
call cpkfre
|
||
cmpb (sp)+,#%coeof
|
||
if eq,<
|
||
inc $vaeof(r2)
|
||
cmp $vaeof(r2),#2
|
||
bge 200$
|
||
> >
|
||
else <clr $vaeof(r2)
|
||
call v8npkt> ;go process the packet
|
||
rptl
|
||
>
|
||
|
||
|
||
;;; Process the packet
|
||
|
||
v8npkt: bitb #1,$cpkop(r1) ;print or plot
|
||
if eq,< ;print
|
||
cmpb $vasta(r2),#%vsprn ;already in print?
|
||
if ne,<call v80frc> ;finish current set of commands
|
||
movb #%vsprn,$vasta(r2)
|
||
mov r1,r3
|
||
mov #v8.pcs,r5
|
||
jcall v80vso ;output the "scan line"
|
||
>
|
||
cmpb $vasta(r2),#%vsplt ;else plot packet
|
||
if ne,<call v80frc>
|
||
movb #%vsplt,$vasta(r2)
|
||
push r0,r1
|
||
tst $vacur(r2) ;is there already a scan line?
|
||
if eq,<call v8%new> ;try and get a new scan line
|
||
mov $cpknb(r1),r0 ;get byte count
|
||
add #$cpkdt,r1 ;point to data
|
||
loop < ;real loop
|
||
tst r0 ;any more packet data?
|
||
exitl le ;get out if not
|
||
loop < ;exit mechanism
|
||
tst $vacon(r2) ;is there a continuation?
|
||
if ne,< ;yup
|
||
call va%ga2 ;continue argument collection
|
||
exitl ;maybe finish command
|
||
>
|
||
dec r0 ;going to grab a byte from packet
|
||
movb (r1)+,r5
|
||
if eq,<call v8%eop
|
||
exitl>
|
||
if pl,<bit #100,r5
|
||
if eq,<call v8%rpt
|
||
exitl>
|
||
call v8%skp
|
||
exitl>
|
||
bit #100,r5
|
||
if eq,<call v8%plt
|
||
exitl>
|
||
cmpb r5,#%v8eol
|
||
if eq,<call v8%eol
|
||
exitl>
|
||
cmpb r5,#%v8xor
|
||
if lo,<call v8%rpl
|
||
exitl>
|
||
if eq,<call v8%xor
|
||
exitl>
|
||
cmpb r5,#%v8ma1
|
||
if lo,<call v8%mar
|
||
exitl>
|
||
if eq,<call v8%ma1>
|
||
>
|
||
tst $varem(r2)
|
||
if le,<call v8%lfn>
|
||
rptl
|
||
>
|
||
pop r1,r0
|
||
jcall cpkfre
|
||
|
||
|
||
****
|
||
|
||
.endc %defin
|
||
|
||
.iif nz %defin, .list ;start listing as usual
|
||
|
||
|
||
;; local modes:
|
||
;; mode:midas
|
||
;; auto fill mode:
|
||
;; fill column:75
|
||
;; comment column:32
|
||
;; compile command: :xfile dcp;\swit compil M
|
||
;; end:
|