mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-01 17:26:38 +00:00
1079 lines
38 KiB
Plaintext
1079 lines
38 KiB
Plaintext
TITLE LP2SER - LINE PRINTER SERVICE FOR LP20 CONTROLLER ON 2020 - V034
|
||
SUBTTL D. DETROY/DBD 21-JUNE-88
|
||
|
||
SEARCH F,S,DEVPRM
|
||
$RELOC
|
||
$HIGH
|
||
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
|
||
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
|
||
;
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
|
||
;1978,1979,1980,1982,1984,1986,1988.
|
||
;ALL RIGHTS RESERVED.
|
||
|
||
.CPYRT<1978,1988>
|
||
|
||
|
||
XP VLP2SR,034 ;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP
|
||
|
||
LP2SER: ENTRY LP2SER
|
||
SUBTTL LP20 REGISTER DEFINITIONS
|
||
|
||
; OFFSETS INTO THE EXTERNAL PAGE REGISTERS
|
||
|
||
LPCSRA==0 ;CONTROL AND STATUS REGISTER A
|
||
LPCSRB==2 ;CONTROL AND STATUS REGISTER B
|
||
LPBSAD==4 ;BUS ADDRESS REGISTER (CURRENT ADDRESS)
|
||
LPBCTR==6 ;BYTE COUNT REGISTER (2'S COMPLEMENT)
|
||
LPPCTR==10 ;PAGE COUNTER
|
||
LPRAMD==12 ;RAM DATA REGISTER
|
||
LPCBUF==14 ;(BYTE) CHARACTER BUFFER REGISTER
|
||
LPCCTR==15 ;(BYTE) COLUMN COUNT REGISTER
|
||
LPTDAT==16 ;(BYTE) PRINTER DATA REGISTER
|
||
LPCKSM==17 ;(BYTE) CHECKSUM REGISTER
|
||
|
||
;WORD BIT DEFINITIONS IN LPCSRA
|
||
|
||
LPWDON==000200 ;LP DONE
|
||
LPWIEN==000100 ;LP INTERRUPT ENABLE
|
||
LPWA17==40 ;B17 OF PDP-11 ADDRESS (EXTENDED)
|
||
LPWA16==20 ;B16
|
||
LPWDVU==000010 ;LOAD DAVFU
|
||
LPWTM==000004 ;TEST MODE
|
||
LPWPEN==000002 ;PARITY ENABLE
|
||
LPWGO==000001 ;GO
|
||
LPWERR==<200>B<35-8> ;ERROR (COMPOSITE)
|
||
LPWPZR==<100>B<35-8> ;PAGE COUNTER REACHED 0
|
||
LPWCI==<40>B<35-8> ;UNDEFINED CHARACTER INTERRUPT
|
||
LPWDR==<20>B<35-8> ;DAVFU READY
|
||
LPWOL==<10>B<35-8> ;ON LINE
|
||
LPWDH==<4>B<35-8> ;DELIMITER HOLD
|
||
LPWRSE==<2>B<35-8> ;RESET ERROR
|
||
LPWINT==<1>B<35-8> ;LP INITIALIZE
|
||
|
||
;BYTE BIT DEFINITIONS IN LPCSRA
|
||
|
||
LP1DON==000200 ;LP DONE
|
||
LP1IEN==000100 ;LP INTERRUPT ENABLE
|
||
LP1A17==40 ;B17 OF PDP-11 ADDRESS (EXTENDED)
|
||
LP1A16==20 ;B16
|
||
LP1DVU==000010 ;LOAD DAVFU
|
||
LP1TM==000004 ;TEST MODE
|
||
LP1PEN==000002 ;PARITY ENABLE
|
||
LP1GO==000001 ;GO
|
||
|
||
;BYTE BIT DEFINITIONS IN LPCSRA+1 (-11 LPCSRA BITS 15,14,13,12,11,10,9,8)
|
||
|
||
LP1ERR==200 ;ERROR (COMPOSITE)
|
||
LP1PZR==100 ;PAGE COUNTER REACHED 0
|
||
LP1CI==40 ;UNDEFINED CHARACTER INTERRUPT
|
||
LP1DR==20 ;DAVFU READY
|
||
LP1OL==10 ;ON LINE
|
||
LP1DH==4 ;DELIMITER HOLD
|
||
LP1RSE==2 ;RESET ERROR
|
||
LP1INT==1 ;LP INITIALIZE
|
||
;WORD LPCSRB BIT DEFINITIONS
|
||
|
||
LPWOFL==000200 ;OFF LINE
|
||
LPWDVN==000100 ;DAVFU NOT READY
|
||
LPWPER==000040 ;LINE PRINTER PARITY ERROR
|
||
LPWMPE==000020 ;MEMORY PARITY ERROR
|
||
LPWRPE==000010 ;RAM PARITY ERROR
|
||
LPWSYE==000004 ;MASTER SYNC ERROR
|
||
LPWDME==000002 ;DEMAND TIME-OUT ERROR
|
||
LPWGOE==000001 ;GO ERROR
|
||
LPWVDT==200B<35-8> ;VALID DATA
|
||
LPWPNR==40B<35-8> ;PRINTER NOT READY
|
||
LPWDPB==20B<35-8> ;LINE PRINTER DATA PARITY BIT
|
||
LPWOVF==10B<35-8> ;OPTICAL VFU
|
||
|
||
;BYTE LPCSRB BIT DEFINITIONS
|
||
|
||
LP1OFL==000200 ;OFF LINE
|
||
LP1DVN==000100 ;DAVFU NOT READY
|
||
LP1PER==000040 ;LINE PRINTER PARITY ERROR
|
||
LP1MPE==000020 ;MEMORY PARITY ERROR
|
||
LP1RPE==000010 ;RAM PARITY ERROR
|
||
LP1SYE==000004 ;MASTER SYNC ERROR
|
||
LP1DME==000002 ;DEMAND TIME-OUT ERROR
|
||
LP1GOE==000001 ;GO ERROR
|
||
|
||
;BYTE LPCSRB+1 BIT DEFS
|
||
|
||
LP1VDT==200 ;VALID DATA
|
||
LP1PNR==40 ;PRINTER NOT READY
|
||
LP1DPE==20 ;LINE PRINTER DATA PARITY ERROR
|
||
LP1OVF==10 ;OPTICAL VFU
|
||
SUBTTL LPT SPECIFIC DDB DEFINITIONS
|
||
|
||
;GENERAL BITS IN LH OF DEVIOS
|
||
IOSMON==400000 ;DEVICE IS DOING IO FROM THE MONITOR
|
||
; USED BY MAPIO ROUTINE
|
||
|
||
;DEVICE DEPENDENT BITS IN LH OF DEVIOS
|
||
LPTSYN==Z(1B11) ;CRFF AFTER CLOSE HAS BEEN SENT
|
||
LPTEND==Z(1B10) ;CLOSE UUO HAS BEEN DONE
|
||
LPTVFU==Z(1B9) ;VFU NEEDS RELOADING
|
||
LPTOPB==Z(1B8) ;POSSIBLE PARTIAL BUFFER ALREADY OUTPUT
|
||
LPTRAM==Z(1B7) ;RAM NEEDS RELOADING
|
||
LPTARW==Z(1B6) ;DOING UP-ARROW TRANSLATION
|
||
|
||
;DEVICE DEPENDENT BITS IN RH OF DEVIOS
|
||
LPTNFF==100 ;SUPPRESS FREE FORM FEEDS
|
||
|
||
;MISCELLANEY
|
||
MAXLBZ==:^D253 ;MAX WORD SIZE OF USER'S LPT BUFFERS
|
||
;(LPTSPL USES THIS NUMBER)
|
||
SUBTTL LP20 SYSERR DATA BLOCK DEFINITIONS
|
||
|
||
;WORDS ARE IN EACH LINEPRINTER DDB FOR DAEMON ERROR REPORTING.
|
||
|
||
.HCNAM==0 ;DEVICE NAME
|
||
.HCTYP==1 ;CONTROLLER/DEVICE TYPE
|
||
HC.CTL==77B5 ;CONTROLLER TYPE BYTE
|
||
.CTILL==0 ;ILLEGAL
|
||
.CTB10==1 ;BA10
|
||
.CTLP1==2 ;LP100
|
||
.CTLP2==3 ;LP20
|
||
.CTCD2==4 ;CD20
|
||
HC.DEV==77B11 ;DEVICE TYPE BYTE
|
||
.DEILL==0 ;ILLEGAL
|
||
.DELPT==1 ;LPT
|
||
.DECDR==2 ;CDR
|
||
.DECDP==3 ;CDP
|
||
.DEPLT==4 ;PLT
|
||
HC.RTY==777777B35 ;RETRY COUNT FIELD
|
||
.RTNON==1B17 ;NON-ECOVERABLE FLAG
|
||
.HCUID==2 ;PPN OF USER
|
||
.HCPGM==3 ;PROGRAM NAME
|
||
.HCSBP==4 ;SUB-BLOCK POINTER
|
||
; (XWD .HCL25-.HCSBP,,.HCL20)
|
||
.HCL20==5 ;UBA STATUS REGISTER
|
||
.HCL21==6 ;UBA MAP SLOT
|
||
.HCL22==7 ;LPCSRA,,LPCSRB
|
||
.HCL23==10 ;LPBSAD,,LPBCTR
|
||
.HCL24==11 ;LPPCTR,,LPRAMD
|
||
.HCL25==12 ;LPCBUF,,LPTDAT
|
||
|
||
.HCSIZ==13 ;SIZE OF BLOCK
|
||
SUBTTL AUTOCONFIGURE
|
||
|
||
|
||
;DRIVER CHARARCTERISTICS
|
||
; LP2 = LPTCNF
|
||
; LPT = DEVICE TYPE (LINE PRINTER)
|
||
; 7 = MAXIMUM DEVICES IN SYSTEM
|
||
; 0 = KONTROLLER TYPE
|
||
; 0 = MAXIMUM DRIVES PER KONTROLLER
|
||
; 0 = HIGHEST DRIVE NUMBER ON KONTROLLER
|
||
; MDSEC0 = SECTION FOR KDB/UDB
|
||
; MDSEC0 = SECTION FOR DDB
|
||
DRVCHR (LP2,LPT,7,0,0,0,MDSEC0,MDSEC0,<DR.GCC!DR.NET>)
|
||
|
||
.ORG DEVLSD
|
||
|
||
LPTDAP:!BLOCK 1 ;PLACE TO BUILD AOBJN POINTER TO LPTDAE
|
||
LPTDAE:!BLOCK .HCSIZ ;SYSERR BLOCK
|
||
LPTSTS:!BLOCK 1 ;MORE DEVICE STATUS
|
||
LPTRSV:!BLOCK 1 ;SAVE AREA DURING UP-ARROW TRANSLATION
|
||
LPTWSV:!BLOCK 1 ;...
|
||
LPTUDC:!BLOCK 1 ;UNDEFINED CHAR INTERRUPT DATA SAVED
|
||
LPTPAG:!BLOCK 1 ;PAGE COUNTER WORD
|
||
LPTVEC:!BLOCK 1 ;ADDRESS OF VECTOR INTERRUPT CODE
|
||
LPTBAS:!BLOCK 1 ;LP20 BASE DEVICE ADDRESS
|
||
LPTFNC:!BLOCK 1 ;CURRENT FUNCTION BITS SAVED HERE
|
||
LPTBYT:!BLOCK 1 ;OUTPUT BYTE COUNT STORED HERE
|
||
LPTCDB:!BLOCK 1 ;ADDRESS OF CHANNEL DATA BLOCK
|
||
LPTPTR:!BLOCK 1 ;IOWD POINTER TO DATA BUFFER
|
||
LPTBUF:!BLOCK <<MAXLBZ*5>/4>+1 ;ENOUGH ROOM FOR LPTSPL 7 TO 8 BIT BYTE CONVERSION
|
||
LPTBFZ==.-LPTBUF ;SIZE OF THE LPT BUFFER
|
||
LPTFRM:!BLOCK 1 ;FORMS TYPE NAME (SIXBIT)
|
||
LP2LEN:! ;LENGTH OF LPT DDB
|
||
|
||
.ORG
|
||
|
||
|
||
LP2DDB: DDBBEG (LPT,LP2LEN)
|
||
SETWRD (DEVCHR,<6*HUNGST+DVLPTL,,LPTSIZ##>) ;DEVCHR
|
||
SETWRD (DEVSER,<MCSEC0+LPTDSP>) ;DEVSER
|
||
SETWRD (DEVMOD,<DVOUT!DVLPT,,<1_A+1_AL+1_I>>) ;DEVMOD
|
||
SETWRD (DEVTYP,<<.TYLPT*.TYEST>!.SPLPT!DEPLEN,,0>) ;DEVTYP
|
||
SETWRD (DEVCPU,<LPTCHN##>) ;DEVCPU
|
||
SETWRD (LPTDAP,<-.HCSIZ,,LPTDAE>) ;LPTDAP
|
||
DDBEND
|
||
|
||
|
||
;CONSO SKIP CHAIN CODE (AUTCON WILL FILL IN THE BLANKS)
|
||
LP2ICD: PHASE 0
|
||
EXP 0 ;(00) OLD PC FLAGS
|
||
EXP 0 ;(01) OLD PC
|
||
EXP IC.UOU ;(02) NEW PC FLAGS
|
||
EXP .+1 ;(03) NEW PC
|
||
JSR PIERR## ;(04) SAVE ACS AND SETUP PDL
|
||
DMOVE T1,0 ;(05) GET INTERRUPT FLAGS AND PC
|
||
DMOVEM T1,-1 ;(06) SAVE IN TRADITIONAL PLACE FOR XJEN CH'N
|
||
SKIPA F,.+1 ;(07) SET UP DDB ADDRESS
|
||
EXP 0 ;(10) DDB ADDRESS
|
||
XJRST .+1 ;(11) CALL INTERRUPT HANDLER
|
||
EXP 0 ;(12) INTERRUPT HANDLER ADDRESS
|
||
DEPHASE
|
||
LP2ICL==.-LP2ICD ;LENGTH OF CONSO SKIP CHAIN CODE
|
||
|
||
EQUATE (LOCAL,0,<LP2CKT,LP2KDB,LP2KLN,LP2UDB,LP2ULN>)
|
||
EQUATE (LOCAL,0,<LP2ULB,LP2ULP>)
|
||
|
||
LP2DSP: DRVDSP (LP2,LPTCHN##,LP2DDB,LP2LEN,URDDIA##)
|
||
|
||
;DEFAULT MONGEN'ED DEVICE TABLE
|
||
DEFMDT: MDKS10 (7,LP11IV,LP11CA,0,0,<MD.KON>)
|
||
MDTERM
|
||
|
||
;BITS FOR MDT ENTIRES ARE ALLOCATED HERE
|
||
LPT.UC==:1 ;UPPER-CASE ONLY PRINTER
|
||
LP2CFG: XMOVEI T1,LP2MDT## ;MONGEN'ED DEVICE TABLE
|
||
XMOVEI T2,DEFMDT ;DEFAULT TABLE
|
||
MOVNI T3,1 ;NO MASSBUS UNIT OR DRIVE INFORMATION
|
||
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
|
||
PUSHJ P,AUTMDT## ;SCAN THE TABLES
|
||
JRST CPOPJ1## ;NO MATCHES
|
||
PUSH P,T1 ;PRESERVE MDT DATA
|
||
MOVEI T1,LPTBAS ;WORD CONTAINING AN I/O INSTRUCTION
|
||
PUSHJ P,AUTFND## ;SEE IF THERE'S ALREADY A DDB
|
||
JRST LP2CF1 ;JUST MAKE SURE THE NUMBERS ARE OK
|
||
PUSHJ P,AUTADN## ;ALLOCATE A DEVICE NUMBER
|
||
HRLI T1,'LPT' ;INCLUDE GENERIC DEVICE NAME
|
||
SETZ T2, ;LOCAL DEVICE
|
||
PUSHJ P,AUTDDB## ;CREATE A DDB
|
||
JRST TPOPJ## ;NO CORE
|
||
ADDM F,LPTDAP(F) ;FIX UP DAEMON ERROR POINTER
|
||
LP2CF1: LDB T1,[POINT 21,.CPDVC##,35] ;GET UNIBUS ADDRESS
|
||
MOVEM T1,LPTBAS(F) ;SAVE IN DDB
|
||
MOVSI T1,CP.LP2 ;GET CHANNEL TYPE BITS
|
||
PUSHJ P,AUTCHN## ;ALLOCATE CHANNEL DATA BLOCK
|
||
JRST LP2CF2 ;NO CORE
|
||
MOVE T1,.CPCHA## ;GET CHANNEL DATA BLOCK ADDRESS
|
||
MOVEM T1,LPTCDB(F) ;SALT IT AWAY
|
||
HLRZ T1,LPTBAS(F) ;GET UNIBUS ADAPTER NUMBER
|
||
MOVEI T2,2 ;NUMBER OF MAPPING REGISTERS NEEDED
|
||
PUSHJ P,AUTAMR## ;ALLOCATE MAPPING REGISTERS
|
||
JRST TPOPJ## ;SORRY
|
||
MOVE T4,LPTCDB(F) ;GET CHANNEL DATA BLOCK ADDRESS BACK
|
||
MOVEM T1,CHNIMR(T4) ;STORE THE DATA AWAY
|
||
MOVEM T2,CHNMRC(T4)
|
||
MOVEM T3,CHNIEA(T4)
|
||
SKIPE LPTVEC(F) ;BEEN HERE BEFORE?
|
||
JRST LP2CF4 ;THEN DON'T MESS WITH INTERRUPT CODE
|
||
MOVE T1,F ;DATA BLOCK ADDRESS
|
||
XMOVEI T2,LP2INT ;INTERRUPT SERVICE
|
||
PUSHJ P,AUTICD## ;GENERATE INTERRUPT ROUTINES
|
||
LP2CF2: SKIPA T2,F ;NO CORE
|
||
JRST LP2CF3 ;ONWARD
|
||
MOVEI T1,LP2LEN ;GET DDB LENGTH
|
||
PUSHJ P,AUTKIL## ;DELETE THE DDB
|
||
PUSHJ P,AUTDDN## ;DEALLOCATE DEVICE NUMBER
|
||
JRST TPOPJ## ;PHASE STACK AND RETURN
|
||
LP2CF3: MOVEM T2,LPTVEC(F) ;SAVE IN CASE ANYONE IS INTERESTED
|
||
PUSHJ P,AUTVII## ;COMPUTE VECTOR INSTRUCTION ADDRESS
|
||
MOVE T2,LPTVEC(F) ;GET VECTOR ROUTINE ADDRESS
|
||
HRLI T2,(XPCW) ;INTERRUPT INSTRUCTION
|
||
MOVEM T2,(T1) ;SAVE IN VECTOR TABLE
|
||
MOVE T1,DEVNAM(F) ;GET DEVICE NAME
|
||
MOVEM T1,LPTDAE+.HCNAM(F) ;SET IT UP
|
||
MOVE T1,[XWD .HCL25-.HCSBP,.HCL20] ;GET SUB-BLOCK POINTER
|
||
MOVEM T1,LPTDAE+.HCSBP(F) ;SET IT UP
|
||
LP2CF4: POP P,T1 ;RESTORE MDT DATA
|
||
MOVSI T2,DVLPTL ;LOWERCASE LPT
|
||
TRNE T1,LPT.UC ;IF AN UPPER-CASE ONLY PRINTER,
|
||
ANDCAM T2,DEVCHR(F) ;CLEAR IT FOR LPTTYP
|
||
POPJ P, ;ALL DONE
|
||
SUBTTL LPT SERVICE DISPATCH TABLE
|
||
|
||
;LINE PRINTER SERVICE DISPATCH TABLE
|
||
|
||
JRST LPTONL ;S IF LPT IS ON LINE NOW
|
||
JRST LPTDVP ;DEVOP. UUO
|
||
JRST REGSIZ## ;GET BUFFER SIZE FROM DDB
|
||
JRST LP2INI ;INITIALIZE
|
||
JRST LPTHNG ;HUNG DEVICE ERROR
|
||
LPTDSP: JRST LPTREL ;RELEASE
|
||
JRST LPTCLS ;CLOSE
|
||
JRST LPTOUT ;OUTPUT
|
||
JRST ILLINP## ;INPUT
|
||
SUBTTL SYSTEM START-UP DEVICE INITIALIZATION
|
||
|
||
;LP2INI IS CALLED AT SYSTEM INITIALIZATION TIME FROM
|
||
;IOGO IN SYSINI WITH THE DDB ADDRESS IN F
|
||
|
||
;NOTE: THE LP2INI CODE FORCES IOGO IN SYSINI TO INVOKE
|
||
; LP2INI FOR EACH LINE PRINTER ON THE SYSTEM RATHER
|
||
; THAN FOR THE NORMAL CASE WHERE IT INVOKES THE
|
||
; INITIALIZATION CODE ONCE FOR EACH DISPATCH TABLE.
|
||
;
|
||
; THEREFORE, THE CORRECT OPERATION OF THE LP2INI CODE
|
||
; IS DEPENDENT UPON THE IOGO CODE WHICH SHOULD BE:
|
||
;
|
||
; PUSHJ P,DINI(P3)
|
||
; HRRZM P3,SAVITM
|
||
|
||
LP2INI: CAIN F,LP2DDB ;PROTOTYPE?
|
||
JRST CPOPJ1## ;YES, SKIP SO IOGO CALLS INI ROUTINE AGAIN
|
||
MOVSI T4,DVOFLN ;OFF-LINE BIT
|
||
ANDCAM T4,DEVCHR(F) ;ASSUME LPT IS ON-LINE
|
||
PUSHJ P,LPTONL ;IS IT REALLY?
|
||
IORM T4,DEVCHR(F) ;NO--SET OFF-LINE BIT
|
||
TLO S,LPTRAM+LPTVFU ;MARK RAM AND VFU FOR LOADING
|
||
PUSHJ P,LPTREL ;GO THRU RELEASE CODE
|
||
PJRST CPOPJ1## ;SKIP RETURN TO FORCE CALL FOR EACH LPT
|
||
SUBTTL OUT/OUTPUT UUO
|
||
|
||
LPTOUT: TLO S,IO ;INDICATE OUTPUT
|
||
PUSHJ P,LPTOFL ;IF OFF-LINE, GET IT FIXED
|
||
TLZE S,LPTRAM ;RAM NEED DEFAULT RELOADING?
|
||
PUSHJ P,RESRAM ;YES--GO DO IT
|
||
TLNN S,LPTVFU ;VFU NEED DEFAULT RELOADING?
|
||
JRST LPTOU1 ;NO--GO ON
|
||
PUSHJ P,LPTSTV ;YES--SETUP FOR VFU LOAD
|
||
JRST LPTGO ; AND GO DO IT
|
||
LPTOU1: TRNE S,LPTNFF ;SUPPRESS FORM FEED?
|
||
TLZA S,IOBEG ;YES--CLEAR IOBEG AND OUTPUT BUFFER
|
||
TLNN S,IOBEG ;NO--1ST OUTPUT?
|
||
JRST LPTOU2 ;NO--JUST DO NEXT USER BUFFER
|
||
PUSHJ P,LPTSTI ;YES--SETUP INITIAL OUTPUT BUFFER
|
||
JRST LPTGO ; AND GO DO IT
|
||
LPTOU2: PUSHJ P,LPTSET ;SET UP USER'S OUTPUT BUFFER
|
||
PJRST STOIOS## ;ERROR IN BUFFER, RETURN
|
||
|
||
;HERE TO START THE PRINTER GOING
|
||
|
||
LPTGO: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF IO REGISTERS
|
||
MOVEI T2,7777 ;12 BITS IN THE BYTE COUNTER
|
||
TION T2,LPBCTR(T1) ;IS THERE REALLY SOMETHING TO PRINT?
|
||
JRST LPTSTP ;NO--JUST SHUT DOWN I/O
|
||
MOVEI T2,LPWRSE ;ERROR RESET BIT
|
||
BSIO T2,LPCSRA(T1) ;ENSURE LPWERR IS CLEAR
|
||
RDIO T2,LPBCTR(T1) ;COPY BYTE COUNTER TO ITSELF TO
|
||
WRIO T2,LPBCTR(T1) ; CLEAR DONE FROM LPWRSE ABOVE
|
||
RDIO T3,LPCSRA(T1) ;PICK UP CSRA
|
||
HRLM T3,LPTSTS(F) ;SAVE HERE FOR ANALYZING GO ERRORS
|
||
RDIO T3,LPCSRB(T1) ;PICK UP CSRB
|
||
HRRM T3,LPTSTS(F) ;SAVE HERE FOR ANALYZING GO ERRORS
|
||
TRO S,IOACT ;SET IOACT
|
||
MOVEM S,DEVIOS##(F)
|
||
MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF IO REGISTERS
|
||
MOVEI T2,LP1IEN+LP1PEN ;INTERRUPT ENABLE AND PARITY ENABLE BITS
|
||
BSIOB T2,LPCSRA(T1) ;SET THEM
|
||
MOVEI T2,LP1GO ;GO BIT
|
||
BSIOB T2,LPCSRA(T1) ;START THE PRINTER
|
||
PJRST SETHNG## ;SET HUNG TIMER AND RETURN
|
||
|
||
;HERE DURING OUTPUT UUO TO SEE IF DEVICE EXISTS
|
||
LPTOFL: PUSHJ P,LPTONL ;SEE IF LPT IS ON-LINE
|
||
SKIPA ;IT'S NOT, TELL THE USER
|
||
POPJ P, ;IT IS, JUST RETURN
|
||
MOVEM S,DEVIOS(F) ;YES, SAVE S (LPTRBL OFF)
|
||
MOVSI T4,DEPADV ;WANT BUFFER LEFT ALONE
|
||
IORM T4,DEVADV(F) ;
|
||
MOVSI T4,DVOFLN ;MARK LPT OFF LINE
|
||
IORM T4,DEVCHR(F)
|
||
PUSHJ P,HNGSTP## ;HALT JOB & PRINT REMINDER
|
||
MOVSI T4,DEPADV ;LOAD "DONT ADV BUFFERS"
|
||
ANDCAM T4,DEVADV(F) ;AND CLEAR IT IN THE DDB
|
||
JRST LPTOFL ;BACK HERE ON CONT, TRY AGAIN
|
||
SUBTTL CLOSE UUO - RELEASE UUO
|
||
|
||
;CLOSE UUO - WHEN A CLOSE UUO IS EXECUTED (OR CLOSE COMMAND)
|
||
; LPTCLS IS CALLED. LPTCLS RESETS SOME STATUS FLAGS AND
|
||
; LIGHTS LPTEND SO THE FINAL CRFF CAN BE SETUP NEXT TIME
|
||
; LPTOUT IS CALLED. LPTCLS RETURNS BY BRANCHING TO "OUT"
|
||
; SO THE LAST PARTIAL BUFFER IS OUTPUT.
|
||
|
||
LPTCLS: TLO S,LPTEND ;SET "CLOSE DONE"
|
||
TLZ S,LPTSYN ;MAKE SURE THIS CLEAR
|
||
MOVEM S,DEVIOS(F) ;STORE S
|
||
JRST OUT## ;AND CALL OUT FOR LAST BUFFER
|
||
|
||
|
||
|
||
;RELEASE UUO - WHEN A "RESET" IS DONE ON THE LPT, LPTREL IS
|
||
; CALLED. THE LINEPRINTER IS "TURNED-OFF" (SEE LPTSTP)
|
||
; THE PAGE COUNTER IS TURNED OFF AND THE DDB IS CLEANED UP.
|
||
|
||
LPTREL: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
PUSHJ P,UBGOOD## ;IS LP20 ALIVE ON THE UNIBUS?
|
||
JRST LPTRE1 ;NO--DON'T TRY TO ACCESS IT
|
||
MOVEI T2,LPWINT ;INITIALIZE BIT
|
||
WRIO T2,LPCSRA(T1) ;CLEAR PRINTER
|
||
PUSHJ P,LPTTYP ;SETUP LINEPRINTER TYPE
|
||
LPTRE1: MOVSI T2,DEPADV ;GET "DONT ADV BUFFER" BIT
|
||
ANDCAM T2,DEVADV(F) ;TURN IT OFF
|
||
TLZ S,LPTOPB!LPTARW!LPTSYN ;CLEAR THESE OUT
|
||
SETOM LPTPAG(F) ;TURN OFF PAGE COUNTER
|
||
PJRST LPTSTP ;CLEAR PRINTER + IOACT, SAVE S AND RETURN
|
||
|
||
|
||
LPTHNG==LPTREL ;HUNG DEVICE IS SAME AS RELEASE
|
||
SUBTTL GENERAL INTERRUPT ROUTINE
|
||
|
||
;ENTER HERE ON ALL INTERRUPTS
|
||
|
||
LP2INT: PUSHJ P,IOSET## ;SETUP ACS R AND S
|
||
LDB J,PJOBN## ;SET UP J WITH JOB NUMBER
|
||
MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
RDIO T2,LPCSRA(T1) ;PICK UP CSRA
|
||
RDIO T3,LPCSRB(T1) ;PICK UP CSRB
|
||
HRLM T2,DEVSTS(F) ;SAVE STATUS AT INTERRUPT
|
||
HRRM T3,DEVSTS(F) ;...
|
||
TRNN T2,LPWDON ;SKIP IF DONE IS UP
|
||
JRST LPTERR ;ELSE HANDLE ERROR INTERRUPT
|
||
TLZE S,LPTARW ;WAS THIS AN UP-ARROW TRANSLATION?
|
||
JRST ARWFIN ;YES--GO RESUME NORMAL PATH
|
||
SKIPE T2,LPTFNC(F) ;WERE WE LOADING THE RAM/VFU?
|
||
JRST CHKVFU ;YES--GO CHECK IF DEFAULT LOAD
|
||
TLZE S,IOBEG ;NO BUFFER ADVANCE ON 1ST OUTPUT
|
||
JRST LPTNX1 ;YES, SETUP NEXT BUFFER AND RETURN
|
||
TLZE S,LPTEND ;CLOSE DONE?
|
||
JRST LPTNX2 ;YES, OUTPUT CRFF
|
||
TLZN S,LPTSYN ;WAS CRFF JUST OUTPUT?
|
||
PUSHJ P,ADVBFE## ;NO, ADVANCE TO NEXT BUFFER
|
||
PJRST LPTSTP ;CANT ADVANCE, BUFFER UNAVAIL
|
||
PUSHJ P,SETIOD## ;ARRANGE FOR JOB TO RUN AGAIN
|
||
LPTNX1: PUSHJ P,LPTSET ;SET UP NEW BUFFER POINTER
|
||
PJRST LPTSTP ;ERROR IN BUFFER, SHUT DOWN IO
|
||
PJRST LPTGO ;GO START IT UP
|
||
LPTNX2: TRNE S,LPTNFF ;SUPPRESS FORM FEEDS?
|
||
PJRST LPTSTP ;YES--GO SHUT DOWN IO
|
||
TLO S,LPTSYN ;NO--MARK CRFF SENT SO DON'T ADVANCE BUFFERS
|
||
PUSHJ P,LPTSTI ;SET OUTPUT FOR CRFF
|
||
PJRST LPTGO ;GO START IT UP
|
||
|
||
;HERE TO CHECK IF THE VFU WAS BEING LOADED BY MONITOR
|
||
; AND NOT BY USER (DEVOP.); IF SO, OUTPUT UUO MUST BE CONTINUED
|
||
CHKVFU: CAIN T2,LPWDVU ;WERE WE LOADING THE VFU?
|
||
TLZN S,LPTVFU ;YES--WAS IT BY MONITOR, NOT USER?
|
||
PJRST LPTSTP ;NO--NOTHING ELSE TO DO NOW
|
||
PJRST LPTOU1 ;YES--CONTINUE THE OUTPUT UUO
|
||
SUBTTL ERROR INTERRUPT ROUTINES -- DISPATCH
|
||
|
||
LPTERR: TRNE T3,LPWDVN ;VFU ERROR?
|
||
JRST LPTVFE ;YES HANDLE VFU ERROR
|
||
TRNE T2,LPWPZR ;PAGE-ZERO?
|
||
JRST LPTPZR ;YES, HANDLE ZERO PAGE COUNTER
|
||
TRNE T2,LPWCI ;UNDEFINED CHARACTER?
|
||
JRST LPTUCI ;YES, HANDLE IT
|
||
TRNE T3,LPWPER ;LINE PRINTER PARITY?
|
||
JRST LPTPAR ;YES, HANDLE PARITY ERROR
|
||
TRNE T3,LPWRPE ;RAM PARITY ERROR?
|
||
JRST LPTRPE ;YES, HANDLE IT
|
||
TRNE T3,LPWSYE!LPWDME!LPWMPE ;ANY HARD ERRORS?
|
||
JRST LPTHRD ;YES, HANDLE IT
|
||
TRNE T3,LPWOFL ;OFF-LINE?
|
||
JRST LPTNOL ;YES, HANDLE IT
|
||
TRNE T3,LPWGOE ;GO ERROR?
|
||
JRST LPTGOE ;YES, HANDLE IT
|
||
|
||
;HERE IF ON-LINE OR ERROR RESET INTERRUPT
|
||
MOVSI T1,DVOFLN ;OFF-LINE BIT
|
||
TDNN T1,DEVCHR(F) ;WAS THE LPT OFF-LINE?
|
||
POPJ P, ;NO--ERROR CLEARING, JUST DISMISS
|
||
ANDCAM T1,DEVCHR(F) ;YES--CLEAR OFF-LINE BIT
|
||
PUSHJ P,PSIONL## ;TELL USER LPT IS NOW ON-LINE
|
||
POPJ P, ;DISMISS
|
||
SUBTTL ERROR INTERRUPT ROUTINES -- HANDLERS
|
||
|
||
;HERE ON PAGE-COUNTER ZERO INTERRUPT
|
||
LPTPZR: MOVE T2,LPTPAG(F) ;GET THE PAGE COUNTER
|
||
MOVEI T1,IOPLE% ;LOAD THE ERROR CODE
|
||
JUMPE T2,LPTPZ2 ;IT'S EMPTY, TELL USER
|
||
PUSHJ P,LPTSPC ;ELSE, SET IT
|
||
PJRST LPTGO ;GO RESTART PRINTER, IF NECESSARY
|
||
LPTPZ2: TLO S,LPTOPB ;SET PARTIAL BUFFER PENDING
|
||
PJRST LPTIOE ;GIVE USER ERROR AND RETURN
|
||
|
||
;HERE ON LINE-PRINTER PARITY ERROR
|
||
LPTPAR: PUSHJ P,LPTSYR ;DO SYSERR REPORTING
|
||
MOVEI T1,IOPAR% ;LOAD PARITY ERROR
|
||
PJRST LPTIOE ;GIVE USER ERROR AND RETURN
|
||
|
||
;HERE ON LINE-PRINTER VFU ERROR
|
||
LPTVFE: PUSHJ P,LPTSYR ;TELL SYSERR
|
||
PUSHJ P,LPTNOL
|
||
TLO S,LPTVFU ;MARK VFU FOR RELOADING IF USER DOESN'T
|
||
MOVEI T1,IOVFE% ;VFU ERROR
|
||
PJRST LPTIOE ;GIVE USER ERROR AND RETURN
|
||
|
||
;HERE WHEN LINE PRINTER IS OFF-LINE
|
||
LPTNOL: MOVSI T1,DVOFLN ;MARK LPT OFF-LINE
|
||
IORM T1,DEVCHR(F) ;FOR ON-LINE INTERRUPT
|
||
TLO S,LPTOPB ;INDICATE POSSIBLE PARTIAL BUFFER
|
||
PJRST DEVERR## ;CAUSE UUOCON TO RETRY ON UUO LEVEL
|
||
|
||
;HERE ON RAM PARITY ERROR
|
||
LPTRPE: PUSHJ P,LPTSYR ;DO SYSERR REPORTING
|
||
TLO S,LPTRAM ;MARK RAM FOR RELOADING IF USER DOESN'T
|
||
MOVEI T1,IORPE% ;LOAD RAM PARITY ERROR
|
||
PJRST LPTIOE ;GIVE IT TO USER
|
||
|
||
;HERE ON "HARD" ERRORS
|
||
LPTHRD: PUSHJ P,LPTSYR ;DO SYSERR REPORTING
|
||
MOVE U,LPTCDB(F) ;GET CHAN DATA BLOCK
|
||
MOVEI T1,UNBTMO!UNBBME
|
||
BSIO T1,@CHNUBA(U) ;CLEAR ANY UBA ERRORS
|
||
MOVEI T1,IODER% ;LOAD ERROR CODE
|
||
PJRST LPTIOE ;GIVE IT TO USER
|
||
|
||
;HERE ON A GO ERROR
|
||
LPTGOE: HRRZ T1,LPTSTS(F) ;GET CSRB BEFORE LAST "GO"
|
||
TRNE T1,LPWOFL ;DID THE LPT DROP OFF-LINE?
|
||
PJRST LPTGO ;YES--JUST GO RESTART IT
|
||
PUSHJ P,LPTSYR ;NO--DO SYSERR REPORTING
|
||
STOPCD CPOPJ##,JOB,ULE ;++UNEXPECTED LP20 ERROR
|
||
;HERE ON UNDEFINED CHARACTER
|
||
LPTUCI: RDIOB T3,LPRAMD(T1) ;GET RAM DATA FOR THIS CHARACTER
|
||
CAIE T3,"^" ;IS THIS FOR UP-ARROW TRANSLATION?
|
||
JRST LPTUC1 ;NO--HANDLE AS REAL ERROR
|
||
TLO S,LPTARW ;FLAG DOING UP-ARROW MODE
|
||
RDIO T3,LPBSAD(T1) ;READ CURRENT BUS ADDRESS
|
||
TRZ T2,777717 ;ISOLATE HIGH-ORDER ADDRESS BITS IN CSRA
|
||
LSH T2,14 ;SHIFT TO BITS 19-20 (16-17 OF -11)
|
||
IORI T3,(T2) ;FORM COMPLETE 18-BIT ADDRESS
|
||
HRLM T3,LPTRSV(F) ; AND SAVE IT
|
||
RDIO T2,LPBCTR(T1) ;READ CURRENT BYTE COUNTER
|
||
HRRM T2,LPTRSV(F) ; AND SAVE IT
|
||
MOVEI T2,LPTBUF(F) ;ADDRESS OF FIRST WORD IN LPT BUFFER
|
||
MOVE T3,(T2) ;GET CONTENTS
|
||
MOVEM T3,LPTWSV(F) ; AND SAVE IT
|
||
MOVEI T3,"^" ;GET AN UP-ARROW
|
||
DPB T3,[POINT 8,(T2),17] ;PUT WHERE IT WILL BE PRINTED FROM
|
||
RDIOB T3,LPCBUF(T1) ;GET THE CONTROL CHARACTER
|
||
TRO T3,100 ;MAKE IT A PRINTING CHARACTER
|
||
ANDI T3,177 ;GET RID OF ANY GARBAGE BITS
|
||
DPB T3,[POINT 10,(T2),9] ;PUT IN BUFFER & CLEAR BITS 0-1
|
||
MOVNI T2,2 ;NEGATIVE NUMBER OF CHARS TO PRINT
|
||
MOVE P3,LPTCDB(F) ;POINT TO THE CDB TO GET INITIAL ADDR
|
||
PUSHJ P,REGSE2 ;SET LP20 REGISTERS
|
||
PJRST LPTGO ;PRINT THE TWO CHARACTERS
|
||
|
||
LPTUC1: RDIO T2,LPRAMD(T1) ;GET RAM DATA
|
||
HRLM T2,LPTUDC(F) ; AND SAVE HERE (FOR POSSIBLE DEVOP.)
|
||
RDIO T2,LPCBUF(T1) ;GET CHAR BUFFER DATA
|
||
HRRM T2,LPTUDC(F) ; AND SAVE HERE
|
||
MOVEI T1,IOUNC% ;LOAD ERROR CODE
|
||
PJRST LPTIOE ;GIVE USER ERROR AND RETURN
|
||
|
||
;HERE WHEN WE FINISHED AN UP-ARROW TRANSLATION TO CONTINUE NORMAL PRINTING
|
||
ARWFIN: MOVE T2,LPTWSV(F) ;GET SAVED BUFFER WORD
|
||
MOVEM T2,LPTBUF(F) ; AND RESTORE IT
|
||
HRRZ T2,LPTRSV(F) ;GET SAVED BYTE COUNTER
|
||
WRIO T2,LPBCTR(T1) ; AND RESTORE IT
|
||
HLRZ T2,LPTRSV(F) ;GET SAVED BUS ADDRESS
|
||
PUSHJ P,REGSE3 ; AND RESTORE IT
|
||
PJRST LPTGO ;CONTINUE PRINTER
|
||
|
||
SUBTTL SETUP NEXT BUFFER ROUTINES
|
||
|
||
;HERE FOR NEXT REGULAR BUFFER (OR LAST PARTIAL)
|
||
;SKIP RETURN IF NO ERRORS
|
||
|
||
LPTSET: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
TLZN S,LPTOPB ;POSSIBLE PARTIAL BUFFER PENDING?
|
||
JRST LPTSE1 ;NO--GO AHEAD
|
||
MOVEI T3,7777 ;12 BITS IN THE BYTE COUNTER
|
||
TIOE T3,LPBCTR(T1) ;IS THERE SOMETHING LEFT?
|
||
PJRST CPOPJ1## ;YES--RETURN TO COMPLETE PARTIAL
|
||
LPTSE1: MOVEI T2,@DEVOAD(F) ;GET USER ADDR. OF CURRENT BUFFER
|
||
MOVN T3,1(T2) ;GET NEG WORD COUNT FROM BUFFER HEADER
|
||
JUMPE T3,LPTSTN ;ZERO LENGTH? SEND NULLS TO GET DONE INTERRUPT
|
||
HRLI T2,(T3) ;FORM IOWD IN T2
|
||
AOS T2 ;BUMP T2 FOR IOWD; DO THIS BUFFER
|
||
MOVN T3,T3 ;POSITIVE WORD COUNT
|
||
CAIG T3,MAXLBZ ;EXCEEDING MAX BUFFER SIZE POSSIBLE?
|
||
JRST LPTSE2 ;NO--PROCEED
|
||
TRO S,IOBKTL ;YES--SET BLOCK TOO LARGE
|
||
POPJ P, ;GIVE NON-SKIP RETURN
|
||
LPTSE2: AOS (P) ;SET FOR SKIP RETURN
|
||
IMULI T3,5 ;CONVERT WDS TO BYTES (5 7-BIT BYTES/WD)
|
||
MOVEM T3,LPTBYT(F) ;SAVE IT HERE
|
||
LPTSE3: SETZM LPTFNC(F) ;SET FOR REGULAR PRINT FUNCTION
|
||
PJRST REGSET ;GO SET IT UP
|
||
|
||
;HERE TO SETUP NEXT OUTPUT AS <NUL><NUL>
|
||
LPTSTN: AOS (P) ;SET FOR SKIP RETURN
|
||
SKIPA T2,[LPNULL-1] ;MAKE IOWD TO NULLS, FALL INTO LPTSTI
|
||
|
||
;HERE TO SETUP NEXT OUTPUT AS <CR><FF>
|
||
LPTSTI: HRRI T2,LPCRFF-1 ;MAKE IOWD TO CRFF
|
||
HRLI T2,-1 ;PUT IN WORD COUNT
|
||
MOVEI T3,2 ;BYTE COUNT
|
||
MOVEM T3,LPTBYT(F) ;SAVE IT
|
||
TLO S,IOSMON ;INDICATE MONITOR IO TO MAPIO
|
||
PJRST LPTSE3 ;GO SET IT UP
|
||
|
||
LPNULL: BYTE (7)0,0 ;<NUL><NUL>
|
||
LPCRFF: BYTE (7)15,14 ;<CR><FF>
|
||
|
||
;HERE TO SETUP NEXT OUTPUT AS THE DEFAULT VFU LOAD
|
||
|
||
LPTSTV: HRRI T2,VFUBUF-1 ;MAKE IOWD TO DATA
|
||
HRLI T2,-VFUBFZ ;PUT IN WORD COUNT
|
||
MOVE T3,VFUBUF+VFUBFZ-1 ;GET BYTE COUNT
|
||
MOVEM T3,LPTBYT(F) ;SAVE IN DDB
|
||
MOVEI T3,LPWDVU ;VFU LOAD FUNCTION BITS
|
||
MOVEM T3,LPTFNC(F) ;SAVE IN DDB
|
||
TLO S,IOSMON ;INDICATE MONITOR IO TO MAPIO
|
||
PJRST REGSET ;GO SET IT UP
|
||
SUBTTL SETUP REAL BUFFER AND LP20 REGISTERS ROUTINE
|
||
|
||
; HERE WITH IOWD IN T2 TO SETUP "REAL" OUTPUT BUFFER AND THEN
|
||
; SET THE LP20 REGISTERS.
|
||
|
||
REGSET: MOVEM T2,LPTPTR(F) ;LPTPTR GETS IOWD TO BUFFER
|
||
HRRZI T3,1(T2) ;SOURCE BUFFER ADDRESS TO RH(T3)
|
||
HRLI T3,(<POINT 7,0>);FORM BYTE POINTER TO IT
|
||
MOVE T4,LPTBYT(F) ;BYTE COUNT TO T4
|
||
MOVE U,LPTFNC(F) ;FUNCTION BITS
|
||
CAIN U,LPWDVU+LPWTM ;ARE WE LOADING THE RAM?
|
||
JRST REGSE1 ;YES--CONTINUE
|
||
MOVEI T2,LPTBUF(F) ;NO--"REAL" OUTPUT BUFFER ADDRESS TO T2
|
||
CAIN U,LPWDVU ;ARE WE LOADING THE VFU?
|
||
PUSHJ P,SHUFLR ;YES--REPACK DATA AND SKIP RETURN
|
||
PUSHJ P,SHUFL ;NO--REPACK DATA AND RETURN
|
||
HRRI T2,LPTBUF-1(F) ;BUFFER ADDRESS-1 TO T2
|
||
HRLI T2,-LPTBFZ ;FORM COMPLETE IOWD FOR MAPIO
|
||
TLO S,IOSMON ;INDICATE MONITOR IO TO MAPIO
|
||
REGSE1: SETZB P1,P4 ;FIRST CALL,NO FRAME COUNT
|
||
MOVE P3,LPTCDB(F) ;GET POINTER TO CHANNEL DATA BLOCK
|
||
PUSHJ P,MAPIO## ;SET UP UNIBUS ADAPTOR REGISTERS
|
||
JRST LPTSTP ;SHOULDN'T HAPPEN
|
||
TLZ S,IOSMON ;CLEAR MONITOR IO BIT
|
||
MOVN T2,LPTBYT(F) ;GET NEGATIVE BYTE COUNT
|
||
REGSE2: WRIO T2,LPBCTR(T1) ;SET IN BYTE COUNT REGISTER
|
||
MOVE T2,CHNIEA(P3) ;GET -11 STYLE ADDRESS
|
||
REGSE3: WRIO T2,LPBSAD(T1) ;SET IN BUS ADDRESS REGISTER
|
||
LSH T2,-14 ;ISOLATE TWO HIGH ORDER BITS OF ADDRESS
|
||
TRZ T2,777717 ; IN PROPER POSITION FOR LPCSRA
|
||
IOR T2,LPTFNC(F) ;PUT IN THE FUNCTION BITS
|
||
WRIOB T2,LPCSRA(T1) ;SET THEM
|
||
POPJ P, ; AND RETURN
|
||
SUBTTL DEVOP UUO INTERFACE -- DISPATCH
|
||
|
||
;HERE ON DISPATCH FROM UUOCON
|
||
; F=DDB
|
||
; T1=FUNCTION
|
||
|
||
LPTDVP: MOVSI T2,-LPTDVL ;GET TABLE LENGTH SETUP AOBJN PTR
|
||
LPTDV1: HLRZ T3,LPTDVT(T2) ;GET THE FUNCTION CODE
|
||
HRRZ T4,LPTDVT(T2) ;GET THE DISPATCH ADDRESS
|
||
CAMN T1,T3 ;DO CODES MATCH?
|
||
JRST (T4) ;YES, DISPATCH
|
||
AOBJN T2,LPTDV1 ;NO, LOOP
|
||
PJRST ECOD2## ;NO MATCH, GIVE AN ERROR
|
||
|
||
LPTDVT: XWD 11,DVLRAM ;LOAD RAM
|
||
XWD 12,DVLVFU ;LOAD VFU
|
||
XWD 1000,DVPC ;READ PAGE COUNTER
|
||
XWD 2000,DVPC ;SET PAGE COUNTER
|
||
XWD 1004,DVDCS ;READ DEVICE STATUS
|
||
XWD 1005,DVFRMR ;READ FORMS TYPE NAME
|
||
XWD 2005,DVFRMS ;SET FORMS TYPE NAME
|
||
LPTDVL==.-LPTDVT ;DISPATCH TABLE LENGTH
|
||
SUBTTL DEVOP UUO INTERFACE -- HANDLERS
|
||
|
||
;HERE TO LOAD RAM OR VFU WITH DATA FROM USER
|
||
DVLRAM: PUSHJ P,LPTOFL ;IF OFF-LINE, GET IT FIXED
|
||
MOVEI T3,LPWDVU+LPWTM ;FUNCTION BITS FOR RAM LOAD
|
||
TLZ S,LPTRAM ;CLEAR DEFAULT LOAD BIT
|
||
SETZ P2,0 ;RAM FLAG
|
||
JRST DVLVF0 ;CONTINUE
|
||
DVLVFU: PUSHJ P,LPTOFL ;IF OFF-LINE, GET IT FIXED
|
||
MOVEI T3,LPWDVU ;FUNCTION BITS FOR VFU LOAD
|
||
TLZ S,LPTVFU ;CLEAR DEFAULT LOAD BIT
|
||
MOVEI P2,1 ;VFU FLAG
|
||
DVLVF0: MOVEM S,DEVIOS(F) ;UPDATE DDB COPY
|
||
PUSHJ P,WAIT1## ;MAKE SURE ANY IO HAS STOPPED
|
||
PUSHJ P,GETWR1## ;GET RAM/VFU BYTE COUNT ARGUMENT
|
||
PJRST ECOD3## ;ERROR
|
||
JUMPLE T1,ECOD3## ;ERROR IF .LE. ZERO
|
||
MOVEM T1,LPTBYT(F) ;SAVE BYTE COUNT HERE
|
||
ADDI T1,3(P2) ;FUDGE REMAINDER
|
||
IDIVI T1,4(P2) ;MAKE T1 A WORD COUNT
|
||
CAILE T1,^D128 ;WITHIN RANGE?
|
||
PJRST ECOD3## ;NO--ERROR
|
||
PUSH P,T1 ;SAVE IT
|
||
MOVN T2,T1 ;NEGATIVE WORD COUNT
|
||
HRLZS T2 ;FORM LH OF IOWD
|
||
PUSHJ P,GETWR1## ;GET ADDRESS OF RAM/VFU DATA
|
||
PJRST RTM1## ;COULDN'T--GIVE ADDRESS ERROR
|
||
HRRI T2,-1(T1) ;FORM COMPLETE IOWD
|
||
MOVEM T2,LPTPTR(F) ;SAVE HERE
|
||
MOVEM T3,LPTFNC(F) ;PUT FUNCTION BITS HERE
|
||
CAIE T3,LPWDVU ;IS THIS A VFU LOAD?
|
||
JRST DVLRA1 ;NO--JUST GO ON
|
||
HRRZI T3,1(T2) ;USER VIRT ADDRESS HERE
|
||
MOVE T1,0(P) ;WORD COUNT HERE
|
||
PUSHJ P,GTEVBF## ;GO MAP THIS INTO EVM
|
||
STOPCD TPOPJ1,JOB,NEM, ;++NO EXEC VIRTUAL MEMORY
|
||
MOVEM T1,0(P) ;SAVE EVM USAGE WORD
|
||
MOVE T2,LPTPTR(F) ;GET IOWD
|
||
HRRI T2,-1(T3) ;UPDATE WITH EXEC ADDRESS
|
||
DVLRA1: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
PUSHJ P,REGSET ;GO SET UP LP20
|
||
MOVEI T1,LPWDVU ;VFU LOAD FUNCTION BITS
|
||
CAME T1,LPTFNC(F) ;LOADING THE VFU?
|
||
JRST DVLRA2 ;NO--PROCEED
|
||
MOVE T2,0(P) ;GET EVM USAGE WORD
|
||
LDB T1,[POINT 9,T2,35] ;NO. OF PAGES
|
||
PUSHJ P,GIVEVM## ;RETURN THE STUFF
|
||
DVLRA2: PUSHJ P,LPTGO ;START UP THE IO
|
||
PJRST TPOPJ1## ;GIVE A GOOD RETURN
|
||
;HERE TO READ OR SET THE PAGE COUNTER
|
||
DVPC: MOVE T3,DEVHCW(F) ;GET CHARACTERISTICS
|
||
TLNN T3,(HC.PGC) ;DEVICE HAVE PAGE COUNTER?
|
||
PJRST ECOD11## ;NO, ERROR
|
||
TRNE T1,1000 ;READ?
|
||
JRST DVPC1 ;YES
|
||
PUSHJ P,GETWR1## ;NO, SET T1=PAGE ARG
|
||
PJRST RTM1## ;ERROR
|
||
SETOM LPTPAG(F) ;ASSUME -1
|
||
JUMPE T1,CPOPJ1## ;RETURN
|
||
MOVEM T1,LPTPAG(F) ;STORE NEW PAGE COUNTER WORD
|
||
PUSHJ P,LPTSPC ;SET PAGE COUNTER
|
||
JRST CPOPJ1##
|
||
|
||
DVPC1: SKIPGE LPTPAG(F) ;ATTEMPT TO READ WHEN
|
||
PJRST ECOD10## ; NOT SET
|
||
MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
RDIO T1,LPPCTR(T1) ;GET PAGE COUNTER
|
||
ANDI T1,7777 ;ONLY THESE BITS
|
||
ADD T1,LPTPAG(F) ;ADD IN REMAINING AMOUNT
|
||
PJRST STOTC1## ;RETURN WITH PAGE COUNT IN T1
|
||
|
||
|
||
;HERE TO READ LPT STATUS
|
||
DVDCS: MOVEI T1,0 ;INITIALIZE
|
||
MOVE T2,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
RDIO T2,LPCSRB(T2) ;GET SECOND STATUS REGISTER
|
||
TRNE T2,LPWOFL ;OFF-LINE?
|
||
TLO T1,(DV.OFL) ;YES
|
||
TRNE T2,LPWDVN ;DAVFU ERROR?
|
||
TRO T1,DV.VFE ;YES
|
||
PJRST STOTC1## ;STORE STATUS/GOOD RETURN
|
||
|
||
;HERE TO READ OR SET THE FORMS TYPE NAME
|
||
DVFRMR: MOVE T1,LPTFRM(F) ;GET FORMS NAME
|
||
JRST STOTC1## ;GIVE IT TO THE USER
|
||
|
||
DVFRMS: PUSHJ P,GETWR1## ;FETCH USER'S ARGUMENT
|
||
JRST RTM1## ;ADDRESS CHECK ERROR
|
||
MOVEM T1,LPTFRM(F) ;SAVE IT FOR POSTERITY
|
||
JRST CPOPJ1## ;SUCCESS RETURN
|
||
SUBTTL VARIOUS UTILITY ROUTINES
|
||
|
||
;SUBROUTINE TO SET THE HARDWARE PAGE COUNTER
|
||
; IF SOFTWARE PAGE COUNTER WORD (SPCW) IS .EQ. 0, JUST RETURN
|
||
; ELSE SET HARDWARE PAGE COUNTER TO MAX(SPCW,7777) I IF THE
|
||
; SPCW IS NOT-NEGATIVE, DECREMENT IT BY THE AMOUNT SET.
|
||
|
||
LPTSPC: SKIPN LPTPAG(F) ;IS THERE ANYTHING TO SET?
|
||
POPJ P, ;NO, JUST RETURN
|
||
SKIPL U,LPTPAG(F) ;GET THE SPCW
|
||
CAILE U,7777 ;WITHIN RANGE OF HARDWARE?
|
||
MOVEI U,7777 ;NO, PUT WITHIN RANGE
|
||
MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
WRIO U,LPPCTR(T1) ;SET THE PAGE COUNTER
|
||
MOVNS U ;NEGATE THE AC
|
||
SKIPL LPTPAG(F) ;DONT DECREMENT IF NOT SET
|
||
ADDM U,LPTPAG(F) ;DECREMENT THE SPCW
|
||
POPJ P, ;AND RETURN
|
||
|
||
;SUBROUTINE TO SEE IF THE LPT IS ON LINE
|
||
LPTONL: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF I/O REGISTERS
|
||
PUSHJ P,UBGOOD## ;IS LP20 ALIVE ON THE UNIBUS?
|
||
POPJ P, ;NO--RETURN OFF-LINE
|
||
RDIO T2,LPCSRB(T1) ;YES--GET SECOND STATUS REGISTER
|
||
TRNN T2,LPWOFL ;IS PRINTER OFF-LINE?
|
||
AOS (P) ;NO--IT'S ON-LINE, SO SKIP RETURN
|
||
POPJ P, ;EITHER ON-LINE OR OFF
|
||
|
||
;HERE TO STOP THE LPT AND START THE USER.
|
||
LPTSTP: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF IO REGISTERS
|
||
PUSHJ P,UBGOOD## ;IS LP20 ALIVE ON THE UNIBUS?
|
||
JRST LPTST1 ;NO--DON'T TRY TO ACCESS IT
|
||
MOVEI T2,LP1IEN ;INTERRUPT ENABLE BIT
|
||
BCIOB T2,LPCSRA(T1) ;TURN'EM OFF
|
||
LPTST1: PUSHJ P,SETIOD## ;CLEAR IOW, REQUE IF NEEDED
|
||
PUSHJ P,CLRACT## ;CLEAR IOACT, UPDATE S
|
||
PJRST RTEVMO## ;RETURN ANY EVM
|
||
|
||
;HERE TO GIVE THE USER AN I/O ERROR AND DISMISS THE INTERRUPT.
|
||
; ERROR CODE IN T1.
|
||
LPTIOE: DPB T1,PDVESE## ;STORE THE ERROR CODE
|
||
TRO S,740000 ;SET ALL ERRORS
|
||
PJRST LPTSTP ;GO SHUTDOWN IO AND START USER
|
||
;HERE TO DO DAEMON ERROR REPORTING FOR SYSERR
|
||
LPTSYR: MOVE U,LPTCDB(F) ;GET CHAN DATA BLOCK
|
||
RDIO T2,@CHNUBA(U) ;READ UBA STATUS REGISTER
|
||
MOVEM T2,LPTDAE+.HCL20(F) ;SAVE IT
|
||
MOVE T1,LPTBAS(F)
|
||
RDIO T3,LPCSRA(T1) ;GET CSRA
|
||
LSH T3,-4 ;POSITION 2 BIT ADDRESS EXTENSION
|
||
RDIO T2,LPBSAD(T1) ;GET ENDING BUS ADDRESS
|
||
DPB T3,[POINT 2,T2,19] ; AND PUT IN HIGH ORDER BITS
|
||
IDIVI T2,UBAMUL ;COMPUTE MAP REGISTER OFFSET
|
||
ADDI T2,UBAEXP ;ADD IN THE BASE ADDRESS
|
||
HLL T2,CHNUBA(U) ;PUT IN PROPER UBA NUMBER
|
||
RDIO T3,(T2) ;READ OUT MAP SLOT OF LAST WORD XFER'ED
|
||
MOVEM T3,LPTDAE+.HCL21(F) ;SAVE IT
|
||
RDIO U,LPCSRA(T1) ;GET FIRST STATUS REGISTER
|
||
RDIO T2,LPCSRB(T1) ;GET SECOND STATUS REGISTER
|
||
HRLI T2,(U) ;PUT IN LH(T2)
|
||
MOVEM T2,LPTDAE+.HCL22(F) ;SAVE IT
|
||
RDIO U,LPBSAD(T1) ;GET BUS ADDRESS REGISTER
|
||
RDIO T2,LPBCTR(T1) ;GET BYTE COUNTER
|
||
HRLI T2,(U) ;PUT IN LH(T2)
|
||
MOVEM T2,LPTDAE+.HCL23(F) ;SAVE IT
|
||
RDIO U,LPPCTR(T1) ;GET PAGE COUNTER
|
||
RDIO T2,LPRAMD(T1) ;GET RAM DATA
|
||
HRLI T2,(U) ;PUT IN LH(T2)
|
||
MOVEM T2,LPTDAE+.HCL24(F) ;SAVE IT
|
||
RDIO U,LPCBUF(T1) ;GET CHAR BUFFER AND COL COUNT
|
||
RDIO T2,LPTDAT(T1) ;GET PRINTER DATA AND CHECKSUM
|
||
HRLI T2,(U) ;PUT IN LH(T2)
|
||
MOVEM T2,LPTDAE+.HCL25(F) ;SAVE IT
|
||
MOVE T2,JBTPPN##(J) ;PICK UP PPN
|
||
MOVEM T2,LPTDAE+.HCUID(F) ;SAVE IT
|
||
MOVE T2,JBTPRG##(J) ;PICK UP PROGRAM NAME
|
||
MOVEM T2,LPTDAE+.HCPGM(F) ;SAVE IT
|
||
MOVEI T1,.ERHCC ;LOAD SYSERR TYPE
|
||
HRLI T1,LPTDAP(F) ;POINTER TO AOBJN POINTER
|
||
PJRST DAEERR## ;CALL DAEMON
|
||
;HERE TO SETUP HARDWARE CHARACTERISTICS WORD AND DETERMINE CONTROLLER TYPE
|
||
LPTTYP: MOVSI T3,DVLPTL ;GET LOWER CASE PRINTER BIT
|
||
TDNN T3,DEVCHR(F) ;A LOWER CASE PRINTER?
|
||
TDZA T3,T3 ;NO, UPPER CASE
|
||
MOVSI T3,(HC.LCP) ;YES, NOTE THAT
|
||
TLNN T3,(HC.LCP) ;A LOWER CASE PRINTER?
|
||
TDZA T2,T2 ;NO, UPPER CASE
|
||
MOVEI T2,.HCC95 ;YES, THEN FLAG AS 96-CHAR SET ALSO
|
||
DPB T2,[POINT 3,T3,8] ;STORE IN HARDWARE CHARACTERISTICS
|
||
MOVEI T2,LPWOVF ;OPTICAL VFU BIT
|
||
SETZ T4, ;ASSUME WE HAVE AN OPTICAL UNIT
|
||
TION T2,LPCSRB(T1) ;DO WE?
|
||
MOVEI T4,.HCVTD ;NO, MUST BE DAVFU
|
||
DPB T4,[POINT 3,T3,5] ;STORE THAT
|
||
CAIE T4,.HCVTD ;DID WE DECIDE IT WAS A LOADABLE VFU?
|
||
TLZ S,LPTVFU ;NO, CLEAR THE FLAG REQUESTING VFU LOAD
|
||
TLO T3,(HC.PGC) ;LP20 HAS A HARDWARE PAGE COUNTER
|
||
MOVEI T2,.CTLP2 ;INDICATE LP20
|
||
DPB T2,[POINT 3,T3,11] ;STORE THAT
|
||
TLO T3,(<.HCULP>B14) ;LP05 CLASS PRINTER
|
||
HLLM T3,DEVHCW(F) ;STORE HARDWARE CHARACTERISTICS
|
||
DPB T2,[POINT 6,LPTDAE+.HCTYP(F),5] ;AND CONTROLLER TYPE
|
||
MOVEI T2,.DELPT ;INDICATE LPT DEVICE
|
||
DPB T2,[POINT 6,LPTDAE+.HCTYP(F),11] ;STORE IT
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO CLEAR AND THEN SET THE RAM FOR STANDARD SETTINGS
|
||
|
||
RESRAM: MOVE T1,LPTBAS(F) ;GET BASE ADDRESS OF IO REGISTERS
|
||
MOVEI T2,377 ;MAXIMUM RAM ADDRESS
|
||
SETZ T3, ;A ZERO
|
||
RESRA1: WRIOB T2,LPCBUF(T1) ;SET THIS RAM ADDRESS
|
||
WRIO T3,LPRAMD(T1) ;ZERO THIS RAM ENTRY
|
||
SOJGE T2,RESRA1 ;GO THRU THE WHOLE RAM
|
||
MOVEI T2,RAMTSZ-1 ;SIZE OF RAMTAB MINUS 1
|
||
RESRA2: HLRZ T3,RAMTAB(T2) ;GET RAM CHAR (=RAM ADDRESS)
|
||
WRIOB T3,LPCBUF(T1) ;SET THIS RAM ADDRESS
|
||
HRRZ T3,RAMTAB(T2) ;GET CORRESPONDING RAM BITS TO LOAD
|
||
WRIO T3,LPRAMD(T1) ;LOAD THEM
|
||
SOJGE T2,RESRA2 ;BACK FOR ANOTHER
|
||
MOVSI T2,DVLPTL ;A LOWER CASE PRINTER?
|
||
TDNE T2,DEVCHR(F)
|
||
POPJ P, ;YES--RETURN
|
||
MOVEI T2,36 ;NO--NUMBER OF LOWER CASE CODES
|
||
RESRA3: MOVEI T3,140(T2) ;THE LOWER CASE CHARACTER CODE
|
||
WRIOB T3,LPCBUF(T1) ;SET THIS RAM ADDRESS
|
||
MOVEI T3,1000-40(T3) ;TRANS BIT + UPPER CASE CODE
|
||
WRIO T3,LPRAMD(T1) ;SET IN RAM
|
||
SOJGE T2,RESRA3 ;BACK FOR ANOTHER
|
||
POPJ P, ;RETURN
|
||
|
||
RAMTAB: XWD 12,1407 ;LF,,CHANNEL 8
|
||
XWD 13,1406 ;VT,,CHANNEL 7
|
||
XWD 14,1400 ;FF,,CHANNEL 1
|
||
XWD 20,1401 ;DLE,,CHANNEL 2
|
||
XWD 21,1402 ;DC1,,CHANNEL 3
|
||
XWD 22,1403 ;DC2,,CHANNEL 4
|
||
XWD 23,1404 ;DC3,,CHANNEL 5
|
||
XWD 24,1405 ;DC4,,CHANNEL 6
|
||
|
||
RAMTSZ==.-RAMTAB ;SIZE OF RAMTAB
|
||
;ROUTINE TO CHANGE CONTIGUOUS BYTES IN -10 FORMAT TO SHUFFLED BYTES
|
||
;IN -11 FORMAT. CALL:
|
||
; T2/ ADDRESS TO RECEIVE SHUFFLED BYTES
|
||
; T3/ BYTE POINTER TO CONTIGUOUS BYTES
|
||
; T4/ NUMBER OF BYTES TO DO
|
||
|
||
SHUFL: PUSHJ P,SAVE2## ;NEED A COUPLE OF THESE REGISTERS
|
||
SHUFL1: SOJL T4,CPOPJ## ;DONE, SO QUIT
|
||
ILDB P1,T3 ;GET FIRST BYTE
|
||
SOJL T4,SHUFL3 ;DONE AFTER FIRST BYTE
|
||
ILDB P2,T3 ;GET NEXT CHARACTER
|
||
LSH P2,^D8 ;SHIFT INTO POSITION
|
||
IOR P2,P1 ;PUT CHARACTERS TOGETHER
|
||
HRLZM P2,(T2) ;STORE CHARACTERS
|
||
SOJL T4,CPOPJ## ;DONE
|
||
ILDB P1,T3 ;GET ANOTHER CHARACTER
|
||
SOJL T4,SHUFL4 ;DONE
|
||
ILDB P2,T3 ;GET LAST CHARACTER
|
||
LSH P2,^D8 ;PUT INTO POSITION
|
||
IOR P2,P1 ;PUT CHARACTERS TOGETHER
|
||
HRRM P2,(T2) ;STORE CHARACTERS
|
||
AOJA T2,SHUFL1 ;NEXT WORD
|
||
|
||
SHUFL3: HRLZM P1,(T2) ;STORE CHARACTER
|
||
POPJ P, ;RETURN
|
||
|
||
SHUFL4: HRRM P1,(T2) ;STORE CHARACTER
|
||
POPJ P, ;RETURN
|
||
;ROUTINE TO CHANGE CONTIGUOUS BYTES IN -10 FORMAT TO SHUFFLED BYTES
|
||
;IN -11 FORMAT. ALSO CONVERT BA10/LP100 START/STOP CODES TO LP20 STYLE.
|
||
;CALL:
|
||
; T2/ ADDRESS TO RECEIVE SHUFFLED BYTES
|
||
; T3/ BYTE POINTER TO CONTIGUOUS BYTES
|
||
; T4/ NUMBER OF BYTES TO DO
|
||
;GIVES A SKIP RETURN ALWAYS (FOR CONVENIENCE OF HOW IT WAS CALLED)
|
||
|
||
SHUFLR: PUSHJ P,SAVE3## ;NEED A COUPLE OF THESE REGISTERS
|
||
SETO P3, ;SET FLAG INDICATING FIRST BYTE
|
||
SHUFR1: SOJL T4,CPOPJ1## ;DONE, SO QUIT
|
||
ILDB P1,T3 ;GET FIRST BYTE
|
||
PUSHJ P,CHKSTR ;DO START CODE CONVERSION IF NEEDED
|
||
PUSHJ P,CHKST1 ;DO STOP CODE CONVERSION
|
||
SOJL T4,SHUFR3 ;DONE AFTER FIRST BYTE
|
||
ILDB P2,T3 ;GET NEXT CHARACTER
|
||
PUSHJ P,CHKST2 ;DO STOP CODE CONVERSION
|
||
LSH P2,^D8 ;SHIFT INTO POSITION
|
||
IOR P2,P1 ;PUT CHARACTERS TOGETHER
|
||
HRLZM P2,(T2) ;STORE CHARACTERS
|
||
SOJL T4,CPOPJ1## ;DONE
|
||
ILDB P1,T3 ;GET ANOTHER CHARACTER
|
||
PUSHJ P,CHKST1 ;DO STOP CODE CONVERSION
|
||
SOJL T4,SHUFR4 ;DONE
|
||
ILDB P2,T3 ;GET LAST CHARACTER
|
||
PUSHJ P,CHKST2 ;DO STOP CODE CONVERSION
|
||
LSH P2,^D8 ;PUT INTO POSITION
|
||
IOR P2,P1 ;PUT CHARACTERS TOGETHER
|
||
HRRM P2,(T2) ;STORE CHARACTERS
|
||
AOJA T2,SHUFR1 ;NEXT WORD
|
||
|
||
SHUFR3: HRLZM P1,(T2) ;STORE CHARACTER
|
||
PJRST CPOPJ1## ;RETURN
|
||
|
||
SHUFR4: HRRM P1,(T2) ;STORE CHARACTER
|
||
PJRST CPOPJ1## ;RETURN
|
||
;HERE TO DO START CODE CONVERSION
|
||
CHKSTR: SKIPN P3 ;IS THIS THE FIRST BYTE?
|
||
POPJ P, ;NO--RETURN
|
||
CAIN P1,25 ;STANDARD START CODE?
|
||
MOVEI P1,356 ;YES--LP20 VERSION
|
||
CAIN P1,26 ;6 LPI?
|
||
MOVEI P1,354 ;YES--LP20 VERSION
|
||
CAIN P1,27 ;8 LPI?
|
||
MOVEI P1,355 ;YES--LP20 VERSION
|
||
SETZ P3, ;CLEAR FIRST BYTE FLAG
|
||
POPJ P, ;RETURN
|
||
|
||
;HERE TO CONVERT STOP CODE IN P1
|
||
CHKST1: CAIN P1,126 ;IS IT THE STOP CODE?
|
||
MOVEI P1,357 ;YES--LP20 VERSION
|
||
POPJ P, ;RETURN
|
||
|
||
;HERE TO CONVERT STOP CODE IN P2
|
||
CHKST2: CAIN P2,126 ;IS IT THE STOP CODE?
|
||
MOVEI P2,357 ;YES--LP20 VERSION
|
||
POPJ P, ;RETURN
|
||
SUBTTL MACROS FOR GENERATING DEFAULT VFU DATA
|
||
|
||
; THE FOLLOWING MACROS ARE USED TO GENERATE VFUBUF, WHICH CONTAINS
|
||
; THE DEFAULT VFU DATA TO BE LOADED. THE DEFAULT DATA IN COMBINATION WITH
|
||
; THE DEFAULT RAM DATA LOADED BY THE RESRAM ROUTINE WILL MAKE
|
||
; THE LP20 AND ITS PRINTER OPERATE SIMILIARLY TO A BA10/LP100 STYLE SYSTEM.
|
||
|
||
DEFINE MOD(A,B),<A-<<A/B>*B>> ;TAKE A MODULO B
|
||
|
||
; MACRO OUTBYT - USED TO GENERATE A STREAM OF 7-BIT BYTES. CALLED EACH TIME
|
||
; A BYTE NEEDS OUTPUTING. ASSEMBLES 5 7-BIT BYTES AND THEN OUTPUTS A
|
||
; EXP PSEUDO-OP.
|
||
|
||
DEFINE OUTBYT(B),<
|
||
..BC==..BC+1 ;;INCREMENT THE BYTE COUNT
|
||
..BP==..BP+7 ;;BUMP THE POSITION POINTER BY BYTE SIZE
|
||
B==<B&177>_<^D35-..BP> ;;MAKE SURE ONLY 7 BITS WIDE AND THEN
|
||
;;SHIFT TO PROPER POSITION IN CURRENT WORD
|
||
..B==..B!B ;;PUT BYTE INTO ACCUMULATOR
|
||
IFE ..BP-^D34,< ;;IF WE'RE AT THE LAST BYTE IN CURRENT WORD
|
||
..BP==-1 ;;RESET POSITION POINTER TO BEGINNING
|
||
EXP ..B ;;ASSEMBLE THE WORD
|
||
..B=0 ;;CLEAR OUT THE ACCUMULATOR
|
||
>;END IFE
|
||
>;END DEFINE
|
||
|
||
; MACRO LASBYT - MUST BE CALLED AFTER ANY USAGE OF OUTBYT MACRO TO ENSURE
|
||
; THAT THE LAST BYTE(S) GET OUTPUT.
|
||
|
||
DEFINE LASBYT,<
|
||
IFN ..B,< ;;IF THERE IS SOMETHING LEFT IN THE ACCUMUALTOR
|
||
EXP ..B ;; ASSEMBLE IT
|
||
>;END IFN
|
||
EXP ..BC ;;ASSEMBLE BYTE COUNT AS LAST WORD
|
||
>;END DEFINE
|
||
; MACRO VFUBIT - CALLED TO OUTPUT TWO BYTES OF DATA FOR A PARTICULAR
|
||
; LINE NUMBER IN THE VFU. GENERATES CHANNEL BIT SETTINGS FOR
|
||
; A STANDARD VFU TAPE.
|
||
|
||
DEFINE VFUBIT(LINE),<
|
||
..BT==0 ;;ZERO THE BIT ACCUMULATOR
|
||
|
||
;;DO 1ST BYTE - CHANNELS 1-6
|
||
IFE LINE,<..BT==..BT!1> ;;LINE 0 GETS CHANNEL 1 (TOP OF FORM)
|
||
IFE MOD(LINE,36),<..BT==..BT!2> ;;EVERY 30 LINES GETS CHANNEL 2
|
||
IFE MOD(LINE,2),<..BT==..BT!4> ;;EVEN NUMBERED LINES GET CHANNEL 3
|
||
IFE MOD(LINE,3),<..BT==..BT!10> ;;EVERY 3RD LINE GETS CHANNEL 4
|
||
IFE MOD(LINE,12),<..BT==..BT!40>;;EVERY TEN LINES GETS CHANNEL 6
|
||
IFLE LINE-^D59,<..BT==..BT!20> ;;ALL LINES GET CHANNEL 5
|
||
IFGE LINE-^D60,<..BT==20> ;;LINES 60-65 GET ONLY CHANNEL 5
|
||
OUTBYT(..BT) ;;OUTPUT THIS BYTE
|
||
|
||
;;DO 2ND BYTE - CHANNELS 7-12
|
||
..BT==0 ;;ZERO THE BIT ACCUMULATOR
|
||
IFE MOD(LINE,24),<..BT==..BT!1> ;;EVERY 20 LINES GET CHANNEL 7
|
||
IFLE LINE-^D59,<..BT==..BT!2> ;;LINES 0-59 GET CHANNEL 8
|
||
IFE LINE-^D59,<..BT==..BT!40> ;;LINE 59 GETS CHANNEL 12
|
||
IFGE LINE-^D60,<..BT==0> ;;LINES 60-65 GET NOTHING
|
||
OUTBYT(..BT) ;;OUTPUT THIS BYTE
|
||
>;END DEFINE
|
||
SUBTTL DEFAULT VFU DATA BUFFER
|
||
|
||
..BP==-1 ;INITIALIZE POSITION FOR FIRST BYTE
|
||
..B==0 ;INITIALIZE BYTE ACCUMULATOR
|
||
..BC==0 ;INITIALIZE BYTE COUNT
|
||
|
||
..L==0 ;INITIALIZE LINE COUNTER
|
||
STARTC==25 ;DEFINE START CODE
|
||
STOPC==126 ;DEFINE STOP CODE
|
||
|
||
VFUBUF:
|
||
SALL
|
||
OUTBYT(STARTC) ;OUTPUT THE START CODE
|
||
REPEAT ^D66,< ;66 LINES/PAGE
|
||
VFUBIT(..L) ;DO BYTES FOR THIS LINE
|
||
..L==..L+1 ;BUMP LINE COUNTER
|
||
>;END REPEAT
|
||
OUTBYT(STOPC) ;OUTPUT THE STOP COODE
|
||
LASBYT ;FINISH UP
|
||
XALL
|
||
VFUBFZ==.-VFUBUF ;SIZE OF DATA BUFFER
|
||
|
||
$LIT
|
||
END
|
||
|