;
;  PROGRAM:  CPSEL
;  VERSION:  1.0
;  DATE:  18 May 84
;  AUTHOR:  Richard Conn
;  PREVIOUS VERSIONS:  None
;
version equ     10
z3env   SET     0f400h

;
;       CPSEL (CRT/Printer Select) is a utility which permits the user
; to dynamically select the CRT (of CRT 0 and CRT 1) and Printer (of
; Printers 0, 1, 2, and 3) from the current ZCPR3 Environment Descriptor.
; This dynamically changes the characteristics of the printer which is
; used by PRINT and the other utilities which read these buffers for their
; configuration data.
;

;
;  Operating System Buffers
;
fcb     equ     5ch
tbuff   equ     80h
cr      equ     0dh
lf      equ     0ah
tab     equ     'I'-'@'

;
;  Special Equates
;
csel    equ     2FH     ;offset to CRT select byte
psel    equ     csel+1  ;offset to Printer select byte
cdata   equ     psel+1  ;offset to first CRT data record
cdsize  equ     3       ;size of CRT data record
pdata   equ     cdata+2*cdsize  ;offset to Printer data record
pdsize  equ     4       ;size of Printer data record

;
;  SYSLIB and Z3LIB References
;
       ext     z3init,envptr
       ext     epstr,eprint,cout
       ext     padc

;
; Environment Definition
;
       if      z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
       jmp     start
       db      'Z3ENV' ;This is a ZCPR3 Utility
       db      1       ;External Environment Descriptor
z3eadr:
       dw      z3env
start:
       lhld    z3eadr  ;pt to ZCPR3 environment
;
       else
;
; Internal ZCPR3 Environment Descriptor
;
       MACLIB  Z3BASE.LIB
       MACLIB  SYSENV.LIB
z3eadr:
       jmp     start
       SYSENV
start:
       lxi     h,z3eadr        ;pt to ZCPR3 environment
       endif

;
; Start of Program -- Initialize ZCPR3 Environment
;
       call    z3init  ;initialize the ZCPR3 Env and the VLIB Env

       call    eprint
       db      'CPSEL  Version '
       db      (version/10)+'0','.',(version mod 10)+'0'
       db      0

       lxi     h,tbuff+1       ;pt to buffer
       lda     fcb+1   ;check for help
       cpi     ' '
       jz      help
       cpi     '/'
       jnz     start1

;
; Print help message
;
help:
       call    eprint
       db      cr,lf,'   CPSEL cmd1 cmd2 cmd3,...'
       db      cr,lf,'Commands:'
       db      cr,lf,'  Cc, c=0 or 1  -- Select CRT 0 or 1'
       db      cr,lf,'  Pp, p=0,1,2,3 -- Select Printer 0, 1, 2, or 3'
       db      cr,lf,'  Dd, d=A (All), C (CRT), P (Printer)'
       db      cr,lf,'      -- Display Selection Values'
       db      0

       ret

;
; Process Options
;
start1:
       mov     a,m     ;get next char
       ora     a       ;done?
       rz
       inx     h       ;pt to option
       cpi     ','     ;delimiter?
       jz      start1
       cpi     ' '     ;delimiter?
       jz      start1
       cpi     tab     ;delimiter?
       jz      start1
       cpi     '/'     ;delimiter?
       jz      start1
       call    cmdchk  ;check for commands and run them
       jmp     start1

;
; Test and Run Commands
;
cmdchk:
       mov     b,a     ;save command in B
       lxi     d,ctab  ;pt to command table
cmd1:
       ldax    d       ;get char
       ora     a       ;end of table?
       jz      cmde    ;print error message
       cmp     b       ;match?
       jz      cmd2    ;process
       inx     d       ;skip to next
       inx     d
       inx     d
       jmp     cmd1
cmd2:
       xchg            ;get address
       inx     h
       mov     c,m     ;get low
       inx     h
       mov     b,m     ;get high
       xchg            ;restore hl
       push    b       ;place address on stack
       ret             ;"run" command
;
;  Command Not Found
;
cmde:
       call    eprint
       db      cr,lf,'  Command Not Found: ',0
       mov     a,b     ;get char
       jmp     cout
;
;  Command Table
;
ctab:
       db      'C'     ;select CRT
       dw      cselc
       db      'D'     ;display
       dw      disp
       db      'P'     ;select Printer
       dw      pselc
       db      0       ;end of table
;
;  Select CRT
;
cselc:
       lxi     d,csmsg ;CRT selection
       mov     a,m     ;get digit
       ora     a       ;error if null
       jz      error
       inx     h       ;pt to next
       sui     '0'     ;convert to binary
       jc      error
       cpi     2       ;range check
       jnc     error
       lxi     d,csel  ;offset for CRT select
;
;  Select Device whose value is in A and Offset in DE
;
select:
       push    h       ;save HL
       lhld    envptr  ;pt to environment
       dad     d       ;pt to buffer
       mov     m,a     ;store value
       pop     h       ;restore HL
       ret
;
;  Print Error Message
;
error:
       call    eprint
       db      cr,lf,'  Range Error on ',0
       xchg            ;HL pts to message
       call    epstr   ;print message
       xchg
       ret

;
;  Select Printer
;
pselc:
       lxi     d,psmsg ;Printer selection
       mov     a,m     ;get digit
       ora     a       ;error if null
       jz      error
       inx     h       ;pt to next
       sui     '0'     ;convert to binary
       jc      error
       cpi     4       ;range check
       jnc     error
       lxi     d,psel  ;offset for Printer select
       jmp     select  ;select device
;
;  Display
;
disp:
       mov     a,m     ;get option
       ora     a       ;end of command?
       jz      dispall ;display all
       inx     h       ;pt to next
       cpi     'A'     ;all?
       jz      dispall
       cpi     'C'     ;CRT?
       jz      dispcrt
       cpi     'P'     ;Printer?
       jz      dispprt
       lxi     d,dsmsg ;display select message
       jmp     error
;
;  Display All
;
dispall:
       call    dispcrt ;display CRT and fall thru to display Printer
;
;  Display Printer
;
dispprt:
       call    eprint
       db      cr,lf,'  Current Printer Selection: ',0
       push    h       ;save HL
       lhld    envptr
       lxi     d,psel  ;offset
       dad     d
       mov     a,m     ;get selection
       mov     c,a     ;selection in C
       adi     '0'     ;convert to ASCII
       call    cout
       mvi     b,0     ;set up loop
       lxi     d,pdata ;offset to printer data
       lhld    envptr  ;pt to environment
       dad     d       ;pt to printer data
dploop:
       call    eprint
       db      cr,lf,'  ',0
       mvi     e,' '   ;leading space for not current printer
       mov     a,c     ;see if at current printer
       cmp     b
       jnz     dpl1
       mvi     e,'*'   ;mark current printer
dpl1:
       mov     a,e
       call    cout
       call    eprint
       db      ' Prt ',0
       call    comprt  ;print common data elements
       call    eprint
       db      '  Form Feed? ',0
       mov     a,m     ;print form feed message
       ora     a
       jz      prno
       call    eprint
       db      'Yes',0
       jmp     pryes
prno:
       call    eprint
       db      'No',0
pryes:
       inx     h       ;pt to next
       inr     b       ;increment
       mov     a,b     ;done?
       cpi     4       ;limit
       jnz     dploop
       pop     h       ;restore ptr
       ret

;
;  Common Data Elements to Both Printer and CRT
;
comprt:
       mov     a,b     ;get printer number
       adi     '0'     ;to ASCII
       call    cout
       call    eprint
       db      ':  Width = ',0
       mov     a,m     ;print line width
       call    padc
       inx     h
       call    eprint
       db      '  Actual/Text Lines = ',0
       mov     a,m     ;print number of actual lines
       call    padc
       inx     h
       mvi     a,'/'
       call    cout
       mov     a,m     ;print number of text lines
       inx     h       ;pt to next
       jmp     padc

;
;  Display CRT
;
dispcrt:
       call    eprint
       db      cr,lf,'  Current CRT Selection: ',0
       push    h       ;save HL
       lhld    envptr
       lxi     d,csel  ;offset
       dad     d
       mov     a,m     ;get selection
       mov     c,a     ;save in C
       adi     '0'     ;convert to ASCII
       call    cout
       mvi     b,0     ;set up loop
       lxi     d,cdata ;offset to CRT data
       lhld    envptr  ;pt to environment
       dad     d       ;pt to printer data
dcloop:
       call    eprint
       db      cr,lf,'  ',0
       mvi     e,' '   ;leading space for not current printer
       mov     a,c     ;see if at current printer
       cmp     b
       jnz     dpc1
       mvi     e,'*'   ;mark current printer
dpc1:
       mov     a,e
       call    cout
       call    eprint
       db      ' CRT ',0
       call    comprt  ;print common data elements
       inr     b       ;increment
       mov     a,b     ;done?
       cpi     2       ;limit
       jnz     dcloop
       pop     h       ;restore ptr to next command line element
       ret

;
;  Error Messages
;
csmsg:
       db      'CRT Selection',0
dsmsg:
       db      'Display Option',0
psmsg:
       db      'Prt Selection',0

       end