(* VERSION 0060 *) (****************************************************************) (* *) (* This version of NSB.SRC contains a driver for the Heath H-19 *) (* or Zenith Z-19 terminal. The driver makes use of the cursor *) (* positioning and special function keys which are implemented *) (* by sequences. The auxiliary keypad has been defined*) (* to function the same as Compuview Products "VEDIT" video *) (* editor. *) (* *) (* Functions provided: *) (* *) (* F1 Enter Insert Character Mode (^F) *) (* F2 Accept Previous Command (^V) *) (* F3 Search for string (^S) *) (* F4 Insert Line (^N) *) (* F5 Search & Replace (^X) *) (* ERASE Enter Delete Line Mode (^Y) *) (* BLUE Delete Word Right (^O) *) (* RED (ESC) *) (* GREY Super Command (^Q) *) (* IC Cursor Backward Page (^R) *) (* IL Cursor Forward Page (^C) *) (* DC Delete Character Right (^G) *) (* DL Erase To End Of Line (^P) *) (* *) (* These function keys are additional ways of calling some of *) (* the services offered by SpeedProgramming. MT Microsystems *) (* original control keystroke definitions are still spplicable *) (* *) (* Note that it was necessary to compress the code generated by *) (* NSB.SRC to allow these definitions to work. This was done *) (* by shortening the signon message and removing characters *) (* in some of the messages written by the software. *) (* *) (* This code functions properly for a Z-80 processor running at *) (* 4 Mhz. The method employed by MT Microsystems to check for *) (* the availability of a character from the console precludes *) (* proper operation with a 2 Mhz clock. Overlay SPP.002 must *) (* be modified to perform a direct bios call to check for the *) (* console input status. Please see the documentation file *) (* which accompanies this software for a description of the *) (* patch which must be made, and the method to find where in *) (* SPP.002 this patch should be located. *) (* *) (* Last Modified: 25 November 1981 *) (* Modified by: J. F. Jankura *) (* *) (****************************************************************) (*$K0*) (*$K1*) (*$K2*) (*$K5*) (*$K6*) (*$K7*) (*$K8*) (*$K12*) (*$K13*) (*$K14*) (*$K15*) PROGRAM PASCAL_SPP; (*$I EDTYPES*) (*$I EDGLBLS*) TYPE CPMOPERATION = (COLDBOOT,WARMBOOT,CONSTAT,CONIN,CONOUT,LIST, PUNOUT,RDRIN,HOME,SELDSK,SETTRK,SETSEC,SETDMA, DSKREAD,DSKWRITE); FNAME = ARRAY [1..8] OF CHAR; (* CP/M FILE NAME *) EXTENSION = ARRAY [1..3] OF CHAR; (* EXTENSION TO NAME *) FCB = RECORD DSK : BYTE; FN : FNAME; EXT : EXTENSION; OTHER: ARRAY [12..36] OF BYTE END; DIRENT = RECORD ET : BYTE; FN : FNAME; EXT : EXTENSION; OTHR : ARRAY [12..31] OF BYTE END; (*$I SBIFDEF.LIB*) VAR DIRFILE: FCB; (* FOR DISPLAYING DIRECTORIES *) DIRBUF: ARRAY [0..3] OF DIRENT; FSTRING: STRING; MEMORY: ABSOLUTE [$0000] ARRAY[0..0] OF BYTE; CMDCH: CHAR; @SFP: EXTERNAL INTEGER; BUFSTAT: STATREC; INTRFACE: SB_INTERFACE; (* USED TO COMMUNICATE BETWEEN PROGRAMS *) SB_LAST_X, SB_LAST_Y: INTEGER; (* FOR SOFTWARE CLR TO EOL/ CLR TO EOS ROUTINES *) EXTERNAL FUNCTION @BDOS(PARM,FUNC:INTEGER): INTEGER; EXTERNAL [1] PROCEDURE LOGWRITER; (* LOG WRITER OVERLAY *) EXTERNAL [2] PROCEDURE SPEED; (* EDITOR OVERLAY *) EXTERNAL [3] PROCEDURE SYNCHECK; (* SYNTAX CHECKER OVERLAY *) EXTERNAL [4] PROCEDURE VARCHECK; (* UNDEF VAR CHECKER OVERLAY *) EXTERNAL [6] PROCEDURE MTRUN; (* RUN PROGRAM OVERLAY *) EXTERNAL [7] PROCEDURE DISP_DIR; (* DIRECTORY DISPLAY OVERLAY *) EXTERNAL [8] FUNCTION GETFILE: BOOLEAN; (* GET EDITOR FILE NAME, ETC. *) EXTERNAL [8] PROCEDURE INIT; (* EDITOR INIT *) EXTERNAL [9] PROCEDURE EDITWRITE; (* EDITOR WRITE BUFFER OVERLAY *) EXTERNAL [10] PROCEDURE PRETTY; (* PROGRAM REFORMATER *) (*--------------------------------------------------------------*) (* User modification area BEGINS here: *) (*--------------------------------------------------------------*) FUNCTION LINESZ : INTEGER; (* SO USER CAN SET SIZE OF A LINE *) BEGIN LINESZ := 79 (* 80 - 1 *) END; FUNCTION SCREENSZ : INTEGER; BEGIN SCREENSZ := 22 (* NUMBER OF LINES ON PHYSICAL SCREEN - 2 *) END; FUNCTION STATUSROW : INTEGER; BEGIN STATUSROW := SCREENSZ + 1 END; PROCEDURE SB_OUT_CH(CH:CHAR); BEGIN SB_BIOS_CALL(CONOUT,ORD(CH)) END; FUNCTION SB_GETCH: CHAR; VAR CH : BYTE; BEGIN SB_BIOS_CALL(CONIN,0); INLINE("STA / CH); IF CH = $1B THEN (* TEST FOR ESCAPE SEQUENCE *) BEGIN SB_BIOS_CALL (CONIN,0); INLINE ("STA / CH); CASE CH OF $1B : CH := $1B; (* ESCAPE - ESCAPE = ESCAPE *) '@' : CH := $12; (* PAGE BACK *) 'A' : CH := $B; (* CURSOR UP *) 'B' : CH := $A; (* CURSOR DOWN *) 'C' : CH := $C; (* SURSOR RIGHT *) 'D' : CH := $8; (* CURSOR LEFT *) 'H' : CH := $2; (* TOGGLE BEGINNING/END *) 'J' : CH := $19; (* ERASE= ENTER DELETE LINE MODE *) 'L' : CH := $3; (* PAGE UP *) 'M' : CH := $10; (* DELETE TO END OF LINE *) 'N' : CH := $7; (* DELETE CHAR *) 'P' : CH := $F; (* BLUE = DELETE WORD RIGHT *) 'Q' : CH := $1B; (* RED = ESCAPE KEY *) 'R' : CH := $11; (* GREY = SUPER COMMAND *) 'S' : CH := $6; (* F1 = ENTER INSERT CHAR MODE *) 'T' : CH := $16; (* F2 = ACCEPT LAST CHANGE *) 'U' : CH := $13; (* F3 = SEARCH MODE *) 'V' : CH := $E; (* F4 = INSERT LINE *) 'W' : CH := $18; (* F5 = FIND AND REPLACE *) END (* CASE STATEMENT *) END; (* IF STATEMENT *) SB_GETCH := CH END; PROCEDURE XYGOTO(X,Y:INTEGER); BEGIN SB_OUT_CH(CHR(ESC)); SB_OUT_CH('Y'); SB_OUT_CH(CHR(Y+32)); SB_OUT_CH(CHR(X+32)); SB_LAST_X := X; SB_LAST_Y := Y; (* THESE ARE USED ONLY BY USER SOFTWARE *) (* ROUTINES WHICH PERFORM CLR TO EOS AND *) (* CLR TO EOL *) END; PROCEDURE SB_CLR_SCRN; BEGIN SB_OUT_CH(CHR(ESC)); SB_OUT_CH('E') END; PROCEDURE SB_CLR_EOS; BEGIN SB_OUT_CH(CHR(ESC)); SB_OUT_CH('J'); END; PROCEDURE SB_CLR_LINE; BEGIN SB_OUT_CH(CHR(ESC)); SB_OUT_CH('K'); END; (*--------------------------------------------------------------*) (* User modification area ENDS WITH SB_CLR_LINE *) (*--------------------------------------------------------------*) PROCEDURE SB_FLUSH_BUF; VAR CH : CHAR; BEGIN IF NOT BUFSTAT.OCCUPIED THEN EXIT; REPEAT PRNT_AT(20,1,'Buffer occupied'); PRNT_AT(21,1,'Flush, Update, Write & Flush, Leave:'); CH := SB_UP_CASE(SB_GETCH); SB_OUT_CH(CH); IF CH = 'L' THEN EXIT; IF CH = 'F' THEN BEGIN IF NEWFILE THEN PURGE(F); BUFSTAT.OCCUPIED := FALSE; EXIT END; IF CH = 'W' THEN BEGIN EDITWRITE; LOGWRITER; BUFSTAT.OCCUPIED := FALSE END; IF CH = 'U' THEN BEGIN EDITWRITE; (* BUT LEAVE IT OCCUPIED *) LOGWRITER END UNTIL (CH='U') or (CH='F') OR (CH='W'); NEWFILE := FALSE; END; PROCEDURE SB_BIOS_CALL(FUNC:CPMOPERATION; PARM:INTEGER); VAR DISPATCH_LOC : INTEGER; BEGIN DISPATCH_LOC := (MEMORY[1] + SWAP(MEMORY[2])) + (ORD(FUNC)*3) - 3; INLINE("LHLD / PARM / "MOV C,L / "MOV B,H / "LHLD / DISPATCH_LOC / "PCHL); END; PROCEDURE PRNT_AT(ROW,COL:INTEGER; S:STRING); BEGIN XYGOTO(COL,ROW); WRITE([ADDR(SB_OUT_CH)],S) END; PROCEDURE MENU; BEGIN SB_CLR_SCRN; PRNT_AT(1,1,'H-19 SpeedEdit V5.5'); PRNT_AT(3,1,'Options: Edit'); prnt_at(4,20, 'Reformat'); prnt_at(5,20, 'Syntax check'); prnt_at(6,20, 'Variable check'); prnt_at(7,20, 'Xeq'); prnt_at(8,20, 'Dir'); prnt_at(9,20, 'Fast compile'); prnt_at(10,20, 'Quit'); prnt_at(22,1,'Select ') END; FUNCTION SB_UP_CASE(CH:CHAR): CHAR; BEGIN IF (CH >= 'a') AND (CH <= 'z') THEN SB_UP_CASE := CHR(CH & $DF) ELSE SB_UP_CASE := CH END; (*$E-*) FUNCTION GET_FILE_INTO_BUF: BOOLEAN; BEGIN IF NOT BUFSTAT.OCCUPIED THEN IF GETFILE THEN (* GET FILE INTO BUFFER *) INIT; GET_FILE_INTO_BUF := BUFSTAT.OCCUPIED END; (*$E+*) BEGIN BUFSZ := (@SFP - ADDR(BUF))-$100; (* SET UP EDITOR BUFFER SIZE *) BUFSTAT.OCCUPIED := FALSE; NEWFILE := FALSE; REPEAT MENU; INTRFACE.NEXT_CMD := ' '; (* DEFAULT NO NEXT PROGRAM *) INTRFACE.END_STAT := OK; CMDCH := SB_UP_CASE(SB_GETCH); SB_OUT_CH(CMDCH); (* ECHO IT *) REPEAT FSTRING := ''; (* DEFAULT IS NO PROGRAM *) CASE CMDCH OF 'D' : DISP_DIR; 'E' : BEGIN IF (BUFSTAT.OCCUPIED) AND ((INTRFACE.PREV_CMD = 'S') OR (INTERFACE.PREV_CMD = 'R')) THEN (* DO NOTHING *) ELSE SB_FLUSH_BUF; (* MAKE SURE USER WANTS TO DO THIS *) IF NOT BUFSTAT.OCCUPIED THEN (* BUFFER IS EMPTY *) BEGIN IF GETFILE THEN (* SEE IF HE WANTS A FILE *) BEGIN INIT; (* CALL EDITOR *) IF BUFSTAT.OCCUPIED THEN SPEED END END ELSE SPEED; (* BUFFER OCCUPIED, EDIT OLD *) INTRFACE.PREV_CMD := ' '; IF INTRFACE.NEXT_CMD = 'E' THEN INTRFACE.NEXT_CMD := ' '; END; 'S' : BEGIN IF GET_FILE_INTO_BUF THEN BEGIN INTRFACE.PREV_CMD := ' '; SYNCHECK; IF INTRFACE.END_STAT = SYNERR THEN INTRFACE.NEXT_CMD := 'E' END END; 'V' : IF GET_FILE_INTO_BUF THEN VARCHECK; 'R' : BEGIN IF GET_FILE_INTO_BUF THEN BEGIN INTRFACE.PREV_CMD := 'R'; PRETTY; INTRFACE.NEXT_CMD := 'E'; SB_CLR_SCRN END END; 'X' : BEGIN SB_FLUSH_BUF; FSTRING := ''; MTRUN END; 'Q' : BEGIN INTRFACE.PREV_CMD := ' '; SB_FLUSH_BUF; IF BUFSTAT.OCCUPIED THEN CMDCH := '@' ELSE BEGIN SB_CLR_SCRN; EXIT END END; 'L' : BEGIN SB_FLUSH_BUF; FSTRING := 'LINKMT'; MTRUN END; 'F' : BEGIN IF GET_FILE_INTO_BUF THEN BEGIN SB_FLUSH_BUF; FSTRING := 'FASTCOMP'; MOVE(ENDFILE,MEMORY[ADDR(BUF)-2],2); (* SET UP INTEGER *) MOVE(NAME,MEMORY[ADDR(BUF)-83],81); MTRUN END END END; CMDCH := INTRFACE.NEXT_CMD; UNTIL (CMDCH = ' ') OR (CMDCH = INTRFACE. PREV_CMD); UNTIL FALSE END.