;****************************************************************************!
;
;       Double-D Software Services      Dave Drake
;       4924 Chantilly                  (702) 438-2173
;       Las Vegas, Nv. 89110
;
;       Double-D Software reserves the COPYRIGHT to this program and all
;       related materials.  However, due to the percieved importance of
;       this software to the AM community, I grant unlimited use of this
;       software to anyone and everyone as long as this notice is not
;       removed.  All I ask is that if you find this software useful,
;       please send a little money ($25.00?) to the address above to help
;       recover costs of development, continuing support and distribution.
;
;       If you create a driver for a printer not currently supported,
;       please upload it to the AMUS bulletin board or to me so it
;       can be added to the list of supported printers.
;
;       PROGRAM NAME: OKI32X .M68
;
;       DATE CREATED: 11/30/88
;
;       DESCRIPTION: DDSS Generic Printer Driver for Okidata 320/321
;
;       CHANGE HISTORY:
;
;       DATE            BY      DESCRIPTION
;[101]  08/03/87        ddss    Fix for handling of unsupported commands
;[102]  05/03/88        ddss    Mod for impure flag for disabling translation
;[103]  08/03/88        ddss    Mod to have command to turn off translation
;                               Must use PX to turn back on!!
;****************************************************************************!
; Table #1 is reserved for Standardized Commands
;
; Table #2 is Reserved for Standard Color Commands
;
; Table #3 is The User Definable Table
;
; Table #4 is currently Undefined, But is tentatively reserved for graphics
;-----------------------------------------------------------------------------
;1) Pitches other than 10,12,17(sic) may be set in the optional table #3
;2) Line spaceing other than 6,8 Lpi may be set in the optional table #3
;3) Top and Bottom Margin Settings other than at current line may be
;   set in the optional table #3
;4) Left and Right Margin Settings other than at current position may be
;   set in the optional table #3
;5) Vertical and horizontal tabs may be set as need in optional table #3
;   VT and HT will be passed through driver
;6) For Color Printers that do not have background color settings, use the
;   'On White' defined commands
;7) The Print Quality and Character Per Inch Commands have been Combined
;   to provide the greatest flexibility. (Ie, some printers select CPI and
;   Print Quality Simultaneously while others do not.) If the printer doesn't
;   Support other than draft Quality, either leave the selections undefined,
;   or simply set the CPI setting into all print qualities.
;8) 4 tables is not a limitation.  More tables may be defined and appropriate
;   Code added to the program.
;-----------------------------------------------------------------------------
       ObjNam  .TDV
       Search  SYS
       Search  TRM
       Search  SysSym

       radix   8

;Conditional Assembly Equates
True    = ^H00
False   = ^H0FF
Table2  = False         ;Table #2 not Present
Table3  = True          ;Table #3     Present
Table4  = False         ;Table #4 not Present

; Control Character Equates
$Null   = ^H00
$Soh    = ^H01
$Stx    = ^H02
$Etx    = ^H03
$Eqt    = ^H04
$Enq    = ^H05
$Ack    = ^H06
$Bell   = ^H07
$Bs     = ^H08
$Ht     = ^H09
$Lf     = ^H0A
$Vt     = ^H0B
$Ff     = ^H0C
$Cr     = ^H0D
$So     = ^H0E
$Si     = ^H0F
$Dle    = ^H10
$Dc1    = ^H11
$Dc2    = ^H12
$Dc3    = ^H13
$Dc4    = ^H14
$Nak    = ^H15
$Syn    = ^H16
$Etb    = ^H17
$Can    = ^H18
$Em     = ^H19
$Sub    = ^H1A
$Esc    = ^H1B
$Fs     = ^H1C
$Gs     = ^H1D
$Rs     = ^H1E
$Us     = ^H1F

; Special Equates
$Ctl1   =$Dc1           ;Standard Table    Control Leadin
$Ctl2   =$Dc2           ;Optional Table #1 Control Leadin
$Ctl3   =$Dc3           ;Optional Table #2 Control Leadin
$Ctl4   =$Dc4           ;Optional Table #3 Control Leadin
Imp     =A0             ;A0 Generally points to Impure Area

; Impure Area Equates
OFINI
OFDEF   IdCode,4        ; Impure Identifier for PX.LIT [102]
OFDEF   CtlFlg,1        ; Control Sequence Pending Flag (Value of Leadin Char)
OFDEF   CtlCnt,1        ; Control Sequence Wait Count (To prevent Response to
                       ;                              actual command sequences)
OFDEF   Xlate,1         ;[102] Control if translations to take place
                       ;[102] 1 = Translate, 0 = don't translate
OFSIZ   ImpSiz          ; Define Impure Size
;--------------------------------------------------------------
; New Style TDV header format Setup
;
; Please notify me if I got this Wrong or you have suggestions
;   on how to use the fields meaningfully.
;--------------------------------------------------------------
 LPP=  0.      ; Lines/page
 CPL=  0.      ; columns/line
; Bitmap of defined functions (for new tdv format)
FN.0    =^B0000000000000000     ;00-15
FN.1    =^B0000000000000000     ;16-31
FN.2    =^B0000000000000000     ;32-47
FN.3    =^B0000000000000000     ;48-63
FN.4    =^B0000000000000000     ;64-79
FN.5    =^B0000000000000000     ;80-95
FN.6    =^B0000000000000000     ;96-111
FN.7    =^B0000000000000000     ;112-127
FN.8    =^B0000000000000000     ;128-143
FN.9    =^B0000000000000000     ;144-159
FN.A    =^B0000000000000000     ;160-175
FN.B    =^B0000000000000000     ;176-191
FN.C    =^B0000000000000000     ;
FN.D    =^B0000000000000000     ;
FN.E    =^B0000000000000000     ;
FN.F    =^B0000000000000000     ;
       Even
;----------------------------------------------------------------
; Terminal Driver Communications Area
;----------------------------------------------------------------
Oki32x: WORD    TD$New          ; 0.    ; Terminal Attributes
       Rtn                     ; 2.    ; No Input Routine
       Br      Output          ; 4.    ; Special Output Routine
       Rtn                     ; 6.    ; No Echo Routine
       Rtn                     ; 8.    ; No Crt Control Routine
       BR      Init            ; 10.   ; Init Routine  [102]
;
       WORD    ImpSiz          ; 12.   ; Impure area size (Bytes)
       BYTE    LPP,CPL         ; 14.   ; Screen size
       LWORD   ^H000000000
       WORD    FN.1,FN.0       ; NOTE: Screwy arangement
       WORD    FN.3,FN.2
       WORD    FN.5,FN.4
       WORD    FN.7,FN.6
       WORD    FN.9,FN.8
       WORD    FN.B,FN.A
       WORD    FN.D,FN.C
       WORD    FN.F,FN.E       ; For SuperVUE
       WORD    [   ],[   ],[   ]
       LWORD   0
;--------------------------------------------------------
; Init - Initialize driver      [102]
;--------------------------------------------------------
Init:   Push    A0              ; Save A0
       Mov     T.Imp(A5),Imp   ; index Impure
       SetB    Xlate(Imp)      ; Turn on Translation
       MovW    #[DDS],IdCode(Imp)
       MovW    #[SPX],IdCode+2(Imp)
       Pop     A0              ;
       Rtn
;--------------------------------------------------------
; Entry - Determine State and React
;--------------------------------------------------------
Output: Push    A0              ; Save A0
       Mov     T.Imp(A5),Imp   ; A0->TrmDef.Imp
       TstB    CtlFlg(Imp)     ; N\ Is there a Control intercept pending?
       Bne     DoCntl          ;   Y/ process it
       TstB    CtlCnt(Imp)     ;   N\ are we waiting for command to finish?
       Beq     TstCtl          ;    N/ continue processing
       DecB    CtlCnt(Imp)     ;    Y\ dec wait count
       Br      NorRet          ;       and pass char on
;--------------------------------------------------------
; Test for Control Sequence Leadin Characters
;--------------------------------------------------------
TstCtl: Tstb    Xlate(Imp)      ; Are we Translating?   [102]
       Beq     NorRet          ; N/ pass through       [102]
       CmpB    D1,#$Ctl1       ; Is Leadin Char1?
       Beq     SetCt1          ; Y/ set flag
       CmpB    D1,#$Ctl2       ; N\ Is Leadin Char2
       Beq     SetCt2          ;   Y/ Set Flag
       CmpB    D1,#$Ctl3       ;   N\ Is leadin Char3?
       Beq     SetCt3          ;    Y/ Set Flag
       CmpB    D1,#$Ctl4       ;    N\ Is Leadin Char4?
       Beq     SetCt3          ;     Y/ Set flag
       Br      NorRet          ;     N\ Pass on Char
;--------------------------------------------------------
; Set Flag indicating we are in a Control Sequence
;--------------------------------------------------------
SetCt1:                         ; Procedure the same for all
SetCt2:                         ;  Leadin Characters
SetCt3:                         ;
SetCt4: MovB    D1,CtlFlg(Imp)  ; Set Leadin Char into Flag
       Br      OutXit          ; Throw it away
;--------------------------------------------------------
; Normal Return - Output Char Unchanged
;--------------------------------------------------------
NorRet: Lcc     #PS.N           ;Send the char back
       Pop     A0              ;Restore Register
       Rtn                     ;Return to Trmser
;--------------------------------------------------------
; Process Second Char of Command Sequence
;--------------------------------------------------------
DoCntl: CmpB    D1,#$Dc1                ; is turn off xlate? (dc1,dc1)  [103]
       Bne     10$                     ; no, skip                      [103]
       Clrb    Xlate(Imp)              ; Yes, turn off translation     [103]
       Br      OutXit                  ; dump char and return          [103]

10$:    SubB    #41,D1                  ; Strip Ascii Offset (Space considered non-Printable)
       Asl     D1                      ; Times 2 (word offset).
       CmpB    CtlFlg(Imp),#$Ctl1      ; Is Table 1 Command
       Beq     SetTb1                  ; Y/ Process Table1 Command
       CmpB    CtlFlg(Imp),#$Ctl2      ; N\ Is Table2 Command
       Beq     SetTb2                  ; Y/ Process Table2 Command
       CmpB    CtlFlg(Imp),#$Ctl3      ; N\ Is Table3 Command
       Beq     SetTb3                  ; Y/ Process table3 Command
       CmpB    CtlFlg(Imp),#$Ctl4      ; N\ Is Table4 Command
       Beq     SetTb4                  ; Y/ Process Table4 Command
       Br      NorRet                  ; N\ Pass it Through
;--------------------------------------------------------
; Offset to Command in Table and Process it
;--------------------------------------------------------
SetQue: Add     D1,A2           ; add command code
       MovW    @A2,D1          ; Pick up the data field offset
       Add     D1,A2           ; make absolute data address
       Clr     D3              ; Clear Length register
       MovB    (A2)+,D3        ; Get Control sequence Length
       Beq     Ignore          ; If Zero length, Not Supported, Ignore [101]
                               ; [101] was Beq SndNul, Needed to pop a2
       MovB    D3,CtlCnt(Imp)  ; set to wait count
       Push    A0              ; Save Register
       Lea     A0,T.OQX(A5)    ; Outque this
       Qins    A0              ;
       Clr     (A0)+           ; Clear Command word
       Mov     D3,(A0)+        ; Tell Que How Long the Command is
       Mov     A2,@A0          ; Tell Que Where The Command Is
       Pop     A0              ; Restore Register
Ignore: Pop     A2              ; Restore Register              ![101]
       Br      SndNul          ; Ignore The Actual Character
;--------------------------------------------------------
; Exit Options
;--------------------------------------------------------
SndNul: Clr     D1              ; Send null Byte
ClrEsc: ClrB    CtlFlg(Imp)     ; Clear Ctl Flag
OutXit: LCC     #PS.Z           ; Throw away output
OutRtn: Pop     A0              ; Restore A0
       Rtn                     ; <<<
;--------------------------------------------------------
; Table 1 - Must be Here - Standard Codes
;--------------------------------------------------------
SetTb1: Cmp     D1,#Tbl1E-Tbl1S ; Valid Code
       Bhi     SndNul          ; N/ Throw it away
       Push    A2              ; Y\ Save Register
       Lea     A2,Tbl1S        ;    Index the Table
       Br      SetQue          ;    Process Command
;--------------------------------------------------------
; Table 2 - Optional Processing
;--------------------------------------------------------
If      Eq,Table2
Ift
SetTb2: Cmp     D1,#Tbl2E-Tbl2S ; Valid Code
       Bhi     SndNul          ; N/ Throw it away
       Push    A2              ; Y\ Save Register
       Lea     A2,Tbl2S        ;    Index the Table
       Br      SetQue          ;    Process Command
Iff
SetTb2: Br      SndNul          ; If No table Ignore Command
Endc
;--------------------------------------------------------
; Table 3 - Optional Processing
;--------------------------------------------------------
If      Eq,Table3
Ift
SetTb3: Cmp     D1,#Tbl3E-Tbl3S ; Valid Code
       Bhi     SndNul          ; N/ Throw it away
       Push    A2              ; Y\ Save Register
       Lea     A2,Tbl3S        ;    Index the Table
       Br      SetQue          ;    Process Command
Iff
SetTb3: Br      SndNul          ; If No table Ignore Command
Endc
;--------------------------------------------------------
; Table 4 - Optional Processing
;--------------------------------------------------------
If      Eq,Table4
Ift
SetTb4: Cmp     D1,#Tbl4E-Tbl4S ; Valid Code
       Bhi     SndNul          ; N/ Throw it away
       Push    A2              ; Y\ Save Register
       Lea     A2,Tbl4S        ;    Index the Table
       Br      SetQue          ;    Process Command
Iff
SetTb4: Br      SndNul          ; If No table Ignore Command
Endc
;--------------------------------------------------------
; Copy in Tables Here
;--------------------------------------------------------
       Copy    Oki32x.Tb1
If Eq,Table2
       Copy    Oki32x.Tb2
Endc
If Eq,Table3
       Copy    Oki32x.Tb3
Endc
If Eq,Table4
       Copy    Oki32x.Tb4
Endc
       End