; Program: XTCAP ; Version: 1.0 ; Author: Jay Sage ; Created: April 25, 1990 ; Modified: April 26, 1990 ; This is a utility for use with the ZMATE text editor. ZMATE requires for ; its operation some screen code that were not included in the original ; Z-System TCAP. There is now an extended TCAP definition that includes ; many additional functions. Only the first three extensions are needed by ; ZMATE, and this utility is designed to allow the user to add them. ; ; When this program starts running, it locates the TCAP in the running ; system and scans it to the point where the first extension belongs. It ; then prompts the user to enter each of the three sequences in order, ; and it adds them to the TCAP. Finally, it asks the user for a filename ; to use to store the new TCAP. ; Symbol definitions bell equ 7 bs equ 8 tab equ 9 lf equ 10 cr equ 13 esc equ 27 fcb1 equ 005ch ; SYSLIB references ext z3vinit,cls,ereol,gxymsg,at,gotoxy ext cin,capine,cout,print,bline ext acase1 ext z3log,zprsfn ext f$exist,f$delete,f$mopen,f$write,f$close,setdma ; Standard Z header jp start db 'Z3ENV' db 1 ; Type-1 program env: dw 0fe00h ; Z3ENV address will be filled in here ; Put coordinates for various strings here prmptcol equ 5 strcol equ prmptcol + 28 strprmpt: ; Prompt for input of strings db 1 ; Column db 14 ; Row delprmpt: ; Delete-line prompt db prmptcol db 15 delstr: ; Delete-line string entry db strcol db 15 insprmpt: ; Insert-line prompt db prmptcol db 16 insstr: ; Insert-line string entry db strcol db 16 clrprmpt: ; Clear-to-end-of-screen prompt db prmptcol db 17 clrstr: ; Clear-to-end-of-screen prompt db strcol db 17 filprmpt: ; Prompt for file name entry db 1 db 19 filstat: ; File status message location db 5 db 20 ; Start actual code here start: ; Set up a local stack ld (stack),sp ; Save the stack pointer ld sp,stack ; ..and set up new stack ; Initialize environment ld hl,(env) ; Get ENV address call z3vinit ; Initialize for graphics ; Check for help request ld a,(fcb1+1) ; See if help requested with '/' cp '/' jp nz,main ; If not help, branch ; Built-in help message help: call print db cr,lf db 'XTCAP is an interactive utility for ' db 'adding the following extended' db cr,lf db 'TCAP functions for ZMATE to a standard TCAP:',cr,lf,lf db ' delete line',cr,lf db ' insert line',cr,lf db ' clear to end of screen',cr,lf,lf db 'Before invoking XTCAP, make sure you have looked up the' db cr,lf db 'screen codes for these functions on your terminal.',cr,lf db 0 jp exit ; Exit from program ; Main function code main: call cls ; Clear the screen jr nz,signon badtcap: call print db 'The current TCAP is inadequate to run this program.' db cr,lf,0 jp exit ; Display signon message signon: ld hl,3*100h + (77-51)/2 call gotoxy jr z,badtcap ; Jump if TCAP inadequate call print db 'XTCAP Interactive Extended TCAP Installer for ZMATE' db 0 ; Check for an extended TCAP already present ld hl,(env) ; Get ENV address ld de,08fh ; Offset to end of terminal ID string add hl,de ld a,(hl) ; Check last byte (extended TCAP ID) cp ' ' ; If less than space, we have extended TCAP jr nc,main1 ; Branch if not ; Error message when we already have an extended TCAP call gxymsg db 6,1 db 'The current TCAP appears to be an extended TCAP already.' db cr,lf db 'XTCAP is terminating.',cr,lf,lf db 0 jp exit ; Terminate program main1: call gxymsg db 6,1 db 'Sequences are entered, in general, by ' db 'pressing the actual keys. Thus control',cr,lf db 'keys can be entered directly. The two ' db 'exceptions are (1) control-M or carriage',cr,lf db 'return and (2) backspace. Carriage return ' db 'is used to complete and terminate',cr,lf db 'string entry, and backspace is used to ' db 'correct errors. If you need to enter',cr,lf db 'either of these characters, press the double-quote ' db 'character first and then the',cr,lf db 'special character. A double-quote character ' db 'can be entered by pressing it',cr,lf db 'twice.' db 0 call xloc ; Locate the place to put the strings ; Set up string input prompt header ld hl,(strprmpt) ; Get screen address for the prompt call gotoxy call print db 'Enter terminal sequences (CR to end):' db 0 ; Get delete line ld hl,(delprmpt) call gotoxy call print db 'DELETE LINE ............. > ' db 0 ld hl,(delstr) ; Cursor position call getseq ; Get the sequence and add to TCAP ; Get insert line ld hl,(insprmpt) call gotoxy call print db 'INSERT LINE ............. > ' db 0 ld hl,(insstr) ; Cursor position call getseq ; Get clear to end of screen ld hl,(clrprmpt) call gotoxy call print db 'CLEAR-TO-END-OF-SCREEN .. > ' db 0 ld hl,(clrstr) ; Cursor position call getseq ; Ask user for file name getfn: ld hl,(filprmpt) call gotoxy call ereol ; Clear the line call print db 'Enter [DIR:]NAME for new TCAP file (CR to abort) > ' db 0 ld hl,inbuf ; Point to input buffer ld a,22 ; Length of buffer ld (hl),a ; Set it up call bline ; Get line from user or a ; See if character count is zero jp z,exit ; If so, exit now push hl ; Save pointer to input buffer chkch: ld a,(hl) ; Get next character from the buffer or a ; Test for null jp z,exit ; If null found before a character, quit cp ' ' ; See if a space jr nz,getfn1 ; If not, we have some input, so branch inc hl ; Else, test next character jr chkch getfn1: pop hl ; Get back pointer to user input xor a ; Scan for DIR before DU ld de,fcb1 ; Point to FCB to use call zprsfn ; Parse the file spec jr z,main2 ; Branch if not wild ld hl,(filstat) push hl ; Save screen location call gotoxy call ereol call print db bell ; Bell for error db '*** NO WILDCARD FILENAMES, PLEASE (press key to continue) *** ' db 0 call cin pop hl ; Restore screen location call gotoxy call ereol ; Clear the message jp getfn ; Force file type to Z3T main2: ld hl,fcb1+1+8 ; Point to file type ld (hl),'Z' ; Set to Z3T inc hl ld (hl),'3' inc hl ld (hl),'T' ; Log in directory and check for existence of file ld de,fcb1 ; Make sure we are pointing to FCB call z3log ; Log into specified DU call f$exist ; See if file already exists jr z,main3 ; If not, branch ; We have to prompt about erasing the file filedel: ld hl,(filstat) push hl ; Save screen position call gotoxy call ereol call print db 'File exists -- erase it (Y/N)? ' db 0 call capine ; Get user's answer, capitalized, and echo cp 'N' ; If no, jp z,getfn ; ..ask for another name cp 'Y' ; If not yes, jr nz,filedel ; ..ask again pop hl ; Restore screen position call gotoxy call ereol ; Clear the prompt ld de,fcb1 ; Make sure we are pointing to FCB call f$delete ; Delete the file ; Create new file and write TCAP data to it main3: ld de,fcb1 ; Make sure we are pointing to FCB call f$mopen ; Open a new file jr z,main4 ; Branch if successful ld hl,(filstat) call gotoxy call ereol call print db 'No room in directory -- aborting',cr,lf,lf db 0 jp exit ; Terminate program main4: ld hl,(env) ; Point to TCAP ld bc,80h add hl,bc call setdma ld de,fcb1 call f$write ; Write out the new TCAP jr z,written ; If no error, branch ; Report error error: ld hl,(filstat) call gotoxy call ereol call print db 'Error writing the file (disk full?) -- aborting',cr,lf,lf db 0 jr exit ; Terminate ; Report success written: call f$close ; Close the file jr nz,error ; Branch if error on close ld hl,(filstat) call gotoxy call ereol call print db 'New TCAP file successfully written to disk',cr,lf,lf db 0 exit: ld sp,(stack) ; Restore caller's stack ret ; ..and return ; =========================================================================== ; Subroutines ; --------------------------------------------------------------------------- ; GETSEQ -- this routine gets a terminal control sequence from the user and ; stores it into the TCAP. getseq: ld (seqloc),hl ; Save initial cursor position ld hl,strbuf ; Point to string buffer xor a ld (hl),0 ; Initialize to null string ld c,a ; Set count to 0 ld b,a ; Turn off quote flag ; Character entry loop getseq1: ld a,b ; Check quoting flag or a jr z,getseq2 ; Jump if not quoted xor a ; Clear the quoting flag ld b,a call cin ; Get a character ; Store a new character in the string store: ld (hl),a ; Add character to sequence inc hl ; Advance pointer xor a ; Put in null terminator ld (hl),a inc c ; Increment count call drawseq ; Display the whole sequence jr getseq1 ; Back for next character ; Quoting not in effect getseq2: call cin ; Get a character call acase1 ; Case table db 3 ; Three cases tested dw store ; Default is to store the character db cr ; If carriage return, put sequence into TCAP dw putseq db '"' ; If double quote, enter quoting mode dw quote db bs ; If backspace, delete last characer dw backsp ; Turn on quoting mode quote: inc b ; Make B nonzero jr getseq1 ; Back for next character ; Delete previous character backsp: ld a,c ; Check the count or a jr z,getseq1 ; If zero, go back for next character dec c ; Reduce the count dec hl ; Back up to previous character xor a ; Replace with null ld (hl),a call drawseq ; Redraw sting to this point jr getseq1 ; Back for next character ; User is finished entering the sequence; store it in TCAP putseq: xor a ; Store final null ld (hl),a ld hl,(tcapptr) ; Get pointer into TCAP ld de,strbuf ; Start at beginning of string buffer ; Loop through the characters in the sequence putseq1: ld a,(de) ; Get next new character ld (hl),a ; Store it inc de ; Advance pointers inc hl or a ; Check for ending null jr nz,putseq1 ; Loop until done ld (tcapptr),hl ; Save TCAP address pointer ret ; --------------------------------------------------------------------------- ; Display the character sequence drawseq: push hl ; Save current position in string ld hl,(seqloc) ; Go to starting call gotoxy ; ..cursor position call ereol ; Clear the line ld hl,strbuf ; Start from beginning of sequence ; Loop through characters drawseq1: ld a,(hl) ; Get next character inc hl ; Advance pointer call acase1 ; Branch table db 4 ; Four entries dw regchar ; Default case, regular character db 0 ; End of string dw nullchar db 127 ; DEL character dw delchar db esc ; ESC character dw escchar db ' ' ; See if space dw space ; End of string nullchar: pop hl ; Restore character pointer ret ; DEL character display delchar: call print db 'DEL ' db 0 jr drawseq1 ; Back for next character ; ESC character display escchar: call print db 'ESC ' db 0 jr drawseq1 ; Back for next character ; Space character display space: call print db 'SPACE ' db 0 jr drawseq1 ; Back for next character ; Regular characters regchar: cp ' ' ; See if control character jr nc,normchar ; If not, branch ld e,a ; Save character ld a,'^' ; Control prefix call cout ld a,40h ; Convert to printable character add a,e normchar: call cout ld a,' ' ; Put in a space call cout jr drawseq1 ; Back for next character ; --------------------------------------------------------------------------- ; This routine locates the point in the TCAP where the new strings should ; be placed. The address is stored in TCAPPTR. xloc: ld hl,(env) ; Get ENV address ld de,97h ; Offset to first string in TCAP add hl,de ; Calculate address ld b,7 ; Number of strings to skip over xloc1: call skip djnz xloc1 ld (tcapptr),hl ret skip: ld a,(hl) ; Get next character inc hl ; Point to next or a ; See if ending null jr nz,skip ; If not, keep skipping ret ; Otherwise, return ; =========================================================================== ; Data area dseg inbuf: ds 1 ; String input buffer size ds 23 tcapptr: ds 2 ; Pointer into TCAP seqloc: ds 2 ; Screen address scratch memory ds 200 ; Local stack space, plenty of room stack: ds 2 ; Place to keep strbuf: ; Open-ended buffer end