; PROGRAM: CPSET ; AUTHOR: Jay Sage ; DATE: October 31, 1990 version equ 13 .comment \ VERSION 1.3 Added a configurable "supress display of changes" flag which can be overridden by the Q command line option. The setting of this flag has no effect when no numeric values are given. Howard Goldstein VERSION 1.2 Modified the PARSEDATA routine to make the code reentrant as it should be. Moved the table used by the ARGV function to DSEG. The program now aborts if not running under Z System. Howard Goldstein VERSION 1.1 Previous version showed printer formfeed status correctly but it did not set it! Nelson Buck pointed this out to me. VERSION 1.0 This program replaces CPSEL (console/printer select) of the orignal ZCPR3 toolset. Since the new extended environment contains data for only one console and one printer, CPSEL should be discarded (it is potentially dangerous). CPSEL allows you to define from the command line (and hence an alias) or interactively the characteristics of the console or printer. The nominal syntax is as follows: (1) CPSET // (2) CPSET (3) CPSET CON WIDTH LENGTH TEXT (4) CPSET LST WIDTH LENGTH TEXT FORMFEED (5) CPSET PRT WIDTH LENGTH TEXT FORMFEED The first two forms display the built-in help screen; the third form redefines the console characteristics; and the fourth and fifth forms redefine the printer characterists. The actual syntax is a little more relaxed. Help is selected whenever the first parameter starts with a slash character. The console is selected whenever the first parameter begins with a 'C'. Thus 'C' alone can be used, as can the full 'CONSOLE'. This also includes forms that look like a directory specification, such as "CRT:". The same is true for the printer, and any string starting with a 'P' for 'printer' or 'L' for 'list' will work as well. All the data fields must be separated by spacess or tabs. Fields that start with characters that do not represent a valid number will be left as they are presently. This means that "CPSET CON 132" will change only the console width, and "CPSET CON: / / 19" will change only the number of text lines. The FORMFEED flag for the printer will be cleared if a value of zero is given and set if a nonzero value is given. \ false equ 0 true equ not false bell equ 7 tab equ 9 lf equ 10 cr equ 13 syntaxerr equ 4 ; Error code for syntax error tbuff equ 0080h fcb equ 005ch extrn prttype,prtname,inverror,zsyschk extrn z3init,getcrt,getprt extrn print,pstr,padc,crlf,argv,eval ; TYP3HDR.Z80, Version 1.1 entry: jr start0 ; Must use relative jump defb 0 ; Filler db 'Z3ENV' ; Type-3 environment type: db 3 z3env: dw 0 ; Filled in by Z33 dw entry ; Intended load address ; Configuration area defb 'CPSET' ; For ZCNFG defb (version/10)+'0',(version mod 10)+'0',' ' qdflt defb 0 start0: ld hl,0 ; Point to warmboot entry ld a,(hl) ; Save the byte there di ; Protect against interrupts ld (hl),0c9h ; Replace warmboot with a return opcode rst 0 ; Call address 0, pushing RETADDR onto stack retaddr: ld (hl),a ; Restore byte at 0 dec sp ; Get stack pointer to point dec sp ; ..to the value of RETADDR pop hl ; Get it into HL and restore stack ei ; We can allow interrupts again ld de,retaddr ; This is where we should be xor a ; Clear carry flag push hl ; Save address again sbc hl,de ; Subtract -- we should have 0 now pop hl ; Restore value of RETADDR jr z,start ; If addresses matched, begin real code ld de,notz33msg-retaddr ; Offset to message add hl,de ex de,hl ; Switch pointer to message into DE ld c,9 jp 0005h ; Return via BDOS print string function notz33msg: defb 'Not Z33+$' ; Abort message if not Z33-compatible start: ld (stack),sp ; Save system stack pointer ld sp,stack ; Set up working stack ld hl,(z3env) call zsyschk ; Check for Z System running jp nz,return ; Exit if not call z3init ld a,(qdflt) ; Store default quiet flag ld (qflag),a xor a ld (chgflag),a ; Clear change flag (no changes) dseg qflag: ds 1 chgflag: ds 1 cseg call parseline ; Parse command line tail ld a,(ntokens) or a jp z,showhelp ld hl,(token1) ; Get pointer to first token ld a,(hl) cp '/' jp z,showhelp cp 'C' jr z,setconsole cp 'P' jp z,setlist cp 'L' jp z,setlist ld hl,baddevmsg jp error baddevmsg: defb cr,lf defb ' *** Bad Device Specified ***' defb bell,0 ;----------------------------------------------------------------------------- ; Console Data setconsole: call getcrt ; HL points to console data ld de,width ; Copy data to internal buffer push hl push de ld bc,3 ld a,c ; Maximum number of values allowed ldir pop de ; Point to width push de call parsedata ; Convert tokens to numbers pop hl ; Pointer to WIDTH into HL pop de ; Pointer to ENV data in DE push hl ld bc,3 ldir ;-------------------- showconsole: ld a,(qflag) ; Get quiet flag ld b,a ; store in B ld a,(chgflag) ; Were changes made? and b ; And with quiet flag jp nz,return ; Return quietly if quiet flag set ; ...and changes made call print defb cr,lf defb 'Current console data:' defb cr,lf defb ' width.............' defb 0 pop de ; Get pointer to WIDTH back ld a,(de) call padc call print defb cr,lf defb ' lines on screen...' defb 0 inc de ld a,(de) call padc call print defb cr,lf defb ' lines of text.....' defb 0 inc de ld a,(de) call padc call crlf jp return dseg width: ds 1 length: ds 1 text: ds 1 formfeed: ds 1 cseg ;----------------------------------------------------------------------------- ; Printer Data setlist: call getprt ; HL points to printer data ld de,width ; Copy data to internal buffer push hl push de ld bc,4 ld a,c ; Maximum number of values allowed ldir pop de ; Point to width push de call parsedata ; Convert tokens to numbers pop hl ; Pointer to WIDTH into HL pop de ; Pointer to ENV data in DE push hl ld bc,4 ldir ; Copy new data into ENV ;-------------------- showlst: ld a,(qflag) ; Get quiet flag ld b,a ; store in B ld a,(chgflag) ; Were changes made? and b ; And with quiet flag jp nz,return ; Return quietly if quiet flag set ; ...and changes made call print defb cr,lf defb 'Current printer data:' defb cr,lf defb ' width...........' defb 0 pop de ; Get pointer to WIDTH back ld a,(de) call padc call print defb cr,lf defb ' lines on page...' defb 0 inc de ld a,(de) call padc call print defb cr,lf defb ' lines of text...' defb 0 inc de ld a,(de) call padc call print defb cr,lf defb ' formfeed used...' defb 0 inc de ld a,(de) or a jr z,noff call print defb 'YES',0 jr setlist1 noff: call print defb ' NO',0 setlist1: call crlf jr return ;----------------------------------------------------------------------------- error: push hl ; Save pointer to message call help pop hl call pstr ; Display the message ld b,syntaxerr ; Code for syntax error ld a,b ; Transient error call call inverror ; Set up error handler invocation ; Return entry point return: ld sp,(stack) ; Restore system stack ret ;----------------------------------------------------------------------------- ; PARSELINE .comment \ This routine scans the command line tail for up to seven parameters. Pointers are set to each token for use by other parts of the program. \ parseline: ld de,81h ; Point to command tail ld hl,datatable ; Place to put pointers ld (hl),7 ; Maximum number of token to parse ex de,hl ld a,0ffh ; Mark token ends with nulls jp argv ; Parse into tokens dseg datatable: ds 1 ; Maximum number of tokens to parse ntokens: ds 1 ; Number of tokens found token1: ds 2 ; Pointer to token 1 token2: ds 2 ; Pointer to token 2 token3: ds 2 ; Pointer to token 3 token4: ds 2 ; Pointer to token 4 token5: ds 2 ; Pointer to token 5 token6: ds 2 ; Pointer to token 6 token7: ds 2 ; Pointer to token 7 cseg ;-------------------- ; PARSEDATA ; Convert tokens to numeric values. On entry DE points to the destination ; for the data, and A contains the maximum number of tokens allowed. parsedata: ld hl,ntokens ld b,(hl) ; Get number of tokens dec b ; Don't count device specifier ; Look for trailing Q option. If found, flip quiet flag and reduce ; token count by 1. getq: push af ; save max allowable tokens push bc ; ..and number of tokens specified ld a,b ; get number of tokens add a ; Double it for table index inc a ; Adjust ld c,a ld b,0 add hl,bc ; Point to last token POP BC ; Restore token count ld a,(hl) inc hl ld h,(hl) ld l,a ld a,(hl) ; Get first character in last token inc hl cp '/' jr nz,getq1 ; If not a slash, check for Q ld a,(hl) inc hl getq1: cp 'Q' ; Check for Q jr nz,getq2 ld a,(hl) ; Get next character or a ; If not end of token jr nz,getq2 ; ..then we don't have our option ld a,(qflag) cpl ; We have Q option ld (qflag),a ; ..so flip flag dec b ; ..and decrement token count getq2: pop af ; Restore max tokens cp b ; Check for proper number of tokens jr c,tokenerr ; Branch if too many values given ld hl,token2-1 ; Point to 1 byte before address of 1st token ld a,b ; Get number of tokens on command line or a ret z ; Return if no tokens parsedata1: inc hl ; Point to address of next token ld a,(hl) ; Get low byte of token address inc hl ; Point to high byte push hl ; Save pointer ld h,(hl) ; Get address of token into HL ld l,a ld a,(hl) ; Check for nondigit cp '0' jr c,parsedata2 ; If less than '0', skip field cp '9'+1 jr nc,parsedata2 ; If greater than '9', skip field ld (chgflag),a ; Indicate we are changing something push de ; Save destination pointer call eval ; Evaluate the number ld a,(hl) ; Make sure terminated by end of token or a jr nz,badvalerr ld a,d ; Make sure value is one byte only or a jr nz,toobigerr ld a,e pop de ; Get destination back ld (de),a ; Store value parsedata2: inc de pop hl ; Restore pointer to token addresses djnz parsedata1 ; Process the next value ret tokenerr: ld hl,toomanymsg jperror: jp error badvalerr: ld hl,badvalmsg jp jperror toobigerr: ld hl,toobigmsg jp jperror toomanymsg: defb cr,lf defb ' *** Too Many Values Specified ***' defb bell,0 badvalmsg: defb cr,lf defb ' *** Bad Value Expression ***' defb bell,0 toobigmsg: defb cr,lf defb ' *** Value Too Big ***' defb bell,0 ;----------------------------------------------------------------------------- showhelp: call help jp return ;-------------------- help: call print defb cr,lf defb 'CPSET, Version ' defb version/10 + '0' defb '.' defb version mod 10 + '0' defb ' ' defb 0 ld a,(type) ld hl,entry call prttype call print defb ' Set/Display Console/Printer Data' defb cr,lf defb ' Syntax' defb cr,lf defb ' Enter console data:' defb cr,lf,tab defb 0 call prtname call print defb ' CON WIDTH LENGTH TEXT' defb cr,lf defb ' Enter printer data:' defb cr,lf,tab defb 0 call prtname call print defb ' LST WIDTH LENGTH TEXT FORMFEED' defb cr,lf defb ' PRT may be used instead of LST for printer' defb cr,lf defb ' Only first letter of device name is ' defb 'used (''C'', ''L'' or ''P'')' defb cr,lf defb ' Q or /Q as last item ' defb 'on command line toggles display of changes O' defb 0 ld a,(qdflt) or a jr z,showhlp1 call print defb 'n' defb 0 jr showhlp2 showhlp1: call print defb 'ff' defb 0 showhlp2: call print defb cr,lf defb ' Nonnumeric or absent data in a field for no change' defb cr,lf defb ' (e.g., "',0 call prtname call print defb ' PRT / / / 1" (formfeed on) or "' defb 0 call prtname call print defb ' CON")' defb cr,lf defb 0 ret dseg defs 40 ; Stack space stack: defs 2 ; Place to save old stack end