TITLE CIO 17-May-82 MOST CONSOLE I/O SUBTTL MicroPro Business Confidential ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * CONSOLE I/O * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: To provide I/O for console. ; On entry: See individual routines. ; On exit: See individual routines. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * Summary of changes: * ; * 17-May-82 *3.40* Major cleanup -- Bill Haygood. * ; * 01/06/81 *2.25* made UNCR & RECR call usrcrspos more often * ; * 08/20/80 *2.14* added TRS80 equates for TRS80 I/O routines * ; * 05/06/80 *1.34* CRUP added to UNCR/RECR * ; * 03/27/80 *1.25* lin/col/offset/beg line offset transmitted to * ; * UCONO * ; * 03/24/80 *1.24* 3 sectors of pointers in disk text file * ; * 03/14/80 *1.23* calls to user-patch "SWIN" and "SWOUT" items * ; * added; (also added in TERFUN, WMV3). * ; * INCH and ipeek entries added for use in WMC2; * ; * PRINF as well as print during input wait (3/21).* ; * 02/02/80 *1.18* oc->och, convert soft hyphens for output; * ; * 04h MMOC code for echoing "not found" text. * ; * 01/04/80 *1.15* bug fix in RELOAF; boot made external symbol * ; * 12/07/79 *1.12* overlays. Dtxpts in mid-program. Rhdban entry. * ; * 10/30/79 *.946* use HIBIV with terminal also; UCONO/UCONI/UCNSTA * ; * provisions, bypassed by alt console printer * ; * driver I/O. * ; * 10/23/79 *.945* keep hi bits out of scrn image & video boards if * ; * hilite=0 (change here re menus/msgs; related * ; * change in STALIN.) * ; * 10/17/79 *.942* msgcol entry removed * ; * 10/15/79 *.941* JDISLN entry, for directory * ; * 10/11/79 *.938* redisplay stat line from here, not return z, to * ; * clear "disk wait" message, so oncmsgs don't * ; * also get cleared; old1 * ; * 10/05/79 *.936* find wsmsgs on a: or on current; vio and long3 * ; * edited out (see 0.92 or 0.93 archive) * ; * 9/23/79 *.932* INCHR and CONSTA entries for alt console printer * ; * driver * ; * 9/xx/79 *.92x* PCOLM signed 16-bit arg; MSGNTY, PTRMSG, TYINHL * ; * added. * ; * 7/20/79 *0.92* previous version * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Conditional assembly equate: ; TRS80 EQU 0 ; Set to -1 for TRS80 I/O drivers ; PAGE 62 ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * ENTRIES AND EXTERNALS * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ENTRY BUFTYA, CLRIV, CLRTYA, CONSTA, COUCH, CRLF ENTRY DISVLL, ECRIF, FETP, HMSG, INCH, INCHR ENTRY IPEEK, JOC, MMOC, OCH, OPDTX, PBLNCH ENTRY PCOLM, PPMHL, PPMSG, PTGET, PTHNTY, PTYPHL ENTRY PULLIT, PWATCH, RBLINC, RELOAF, SCRIM, SETIV ENTRY SUCK, RECR, RHDBAN, STCR, UNCR, VSUCK ENTRY WIF, JDISTR, ECRLF ; IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENTRY BLNK1, CONST2, INCHR2, PHINCH, RECR2, RETNZ ; $ ENTRY UNCR2 ; $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF ; EXTRN ADDHAH, BADVTX, BIOSP, BUFPRN, COL, COMPAR EXTRN COPY, CRBLIV, CRIV, CRPU, CRUP EXTRN DELAY1, DELAY2, DTXBUF, DTXF, DTXFCB, DTXPTE EXTRN DTXPTS, DTXSCT, DWMF, ERETBK, FETCH2, FINAL EXTRN FINOPN, FOOMSG, HELUPF, HIBIV, HILITE, HITE EXTRN INCHIP, INCHOP, INCHS, INTCR, INTF, INVSW EXTRN JTCRSR, LIN, LINCHS, M05OFF, M05ON, MCTBAS EXTRN MEMAPV, MEMMAP, MOC16D, MOC16F, MOC17A, MOC17B EXTRN MOC17C, MPBSY, MSGVER, NEREOL, NFFCB EXTRN OFFSU, ONCMSG, PAUSED, PBSY, PFCB, PFCTST EXTRN PRINF, PRINT, PVLBUF, REASEQ, REDALL, REDFIL EXTRN RFIXER, RSTTDH, RUBFXF, SCADHL, SCREND, SCRLIN EXTRN SCRN, SCRPTR, SLINL, SOFHYC, STPCHR, STPCK EXTRN STLINE, SUBHDB, SWIN, SWOUT, TCRSOR, TIVOFF EXTRN TIVON, UCNSTA, UCONI, UCONO, USELST, WID EXTRN WMSVER, ZAFCIN, ZERFIL ; IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ EXTRN TRSCI, TRSCIF, TRSCOF, TRSCON, TRSCRS, TRSCTS ; $ EXTRN TRSTAT ; $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * EQUATES * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ;BOOT EQU 0 ; Locations 1,2 point to BIOS+3 defined... ; ; ...in SYSEQA.MAC. ; ; Offsets into BIOS entry vector - add to contents of locations 1, 2. ; BCSTAT EQU 6-3 ; Console status. BCIN EQU 9-3 ; Console input. BCOUT EQU 0CH-3 ; Console out. ; ; MP/M equates. ; DISPAT EQU 8EH ; Swap users. ; ; Special WordStar characters. ; SHYPIN EQU 1EH ; Inactive soft hyphen. Must match in many... ; ...files. SHYPAC EQU 1FH ; Active (line break) soft hyphen. Must... ; ...match many files. ; INCLUDE SYSEQU.INC ; Get the ASCII equates. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * CONSOLE OUTPUT * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Notes: Console output indirects through self-relative pointers ; for RAM texts. ; Output routines accept the following special characters: ; 0EH erase to eol, cr, lf ; 0FH crlf ; SHYPIN, SHYPAC print per "SOFHYC" patch item ; See "MOC" subroutine comments for more controls. ; Other controls are printed as ^X. ; Disk texts (address in DTXPTS) are handled. ; If line wraps to next screen line, a "+" is printed in last ; column. ; ; Converting calls to pointer format: ; Change to ; PTRMSG PPMSG ; TYINHL PPMHL ; TYPHL PTYPHL ; MSGNTY XCHG / PTHNTY / XCHG (clobbers HL) ; TMSG XCHG / PTYPHL / XCHG (clobbers HL) ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * PPMSG * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: To print a message indirectly pointed to by the word pointer ; following the call instruction. ; On entry: First pointer parameter is on the Stack. ; On exit: Entering HL-reg is restored. ; Note: The DW after the call points to another DW containing the ; offset to text in RAM or pointing to a disk text pointer. ; PPMSG:: XTHL CALL PPMHL XTHL RET ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * PPMHL * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: To print a message when return address of routine with ; DW after the call is in the HL-reg. ; On entry: HL-reg points to DW pointing to 1) another DW holding offset ; to text in RAM or 2) pointing to a disk text pointer. ; On exit: The entering PSW and DE-reg are restored. The entering HL-reg ; is returned incremented by 2. The BC-reg is returned ; unchanged. ; PPMHL:: PUSH D ; Save DE-reg momentarily. MOV E,M ; Get the DW following the call. INX H ; ... MOV D,M ; ... INX H ; ... PUSH H ; Save the new HL-reg momentarily. XCHG ; Get the DW into the HL-reg. PUSH PSW ; Save the PSW momentarily. CALL PTYPHL ; Fetch/process disk or RAM pointer, display... ; ...text. POP PSW ; Restore the PSW. POP H ; HL-reg is returned incremented by 2. POP D ; Restore the entering DE-reg. RET ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * PTHNTY * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: To display message ((HL)) in pointer pointer format if no ; typeahead (and print). ; On entry: ; On exit: ; PTHNTY:: CALL PRINF## RNZ ; Fall through to PTYPHL below. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * PTYPHL * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: To display message on console. ; On entry: HL-reg points to: another DW holding offset from self to ; text in RAM or to a disk text pointer. ; On exit: No exit parameters. ; Note: Called recursively from "MOC" to output text for special ; control characters. ; PTYPHL:: CALL PTGET ; Get address of text on disk or in RAM. JMP TYPHL1 ; Go display (HL). ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * PTGET * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Get address of text into the HL-reg. ; On entry: HL-reg points to: another DW holding offset to text in RAM ; or to a disk text pointer. ; On exit: Entering DE-reg is restored. ; Note: External users include FSCRN.MAC. ; PTGET:: PUSH D ; DTGET clobbers DE-reg. CALL DTGET ; If HL-reg points to disk text pointer, get... ; ...text into RAM, return address in... ; ...HL-reg. POP D ; If not address of a disk text pointer,... ; ...return with CY = 1. RNC ; Return if disk text. HL set, DE clobbered. ; Fall through to FETP below. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * FETP * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Text is not on disk. Fetch relative pointer and address ; of text in RAM. ; On entry: ; On exit: ; FETP:: ; Entry point for RAM pointer fetch / relocate. PUSH D MOV E,M INX H MOV D,M DCX H DAD D ; Add pointer's location to its contents. POP D ; Above dad can set CY=1 if ptr negative. ORA A ; Clear CY for use from USEFOO. RET ; Text address is in HL-reg. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * CONSOLE OUTPUT * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Type characters pointed to by (HL) to a null. Uses no ; pointer if in RAM. ; On entry: HL-reg points to desired output text. ; On exit: HL-reg is updated. ; HMSG:: PUSH D ; DTGET clobbers DE-reg. CALL DTGET ; If this text is on disk (address in... POP D ; ...DTXPTS), get in RAM and change HL. ; ; Note: RELOAF called from TYPHL read next buffer when necessary. ; DTGET calls PRINF on disk read. ; TYPHL1: TYPHLL: MOV A,M ORA A JZ PRINF## ; Exit: keep printer going. CALL MOC ; Expands 0EH into erase eol, cr, lf, etc. ; Character is in A-reg, unindexed pointer... ; ...in HL-reg may be returned updated. ; *** This is the only call to MOC. *** INX H CALL RELOAF ; Reload disk buffer if incremented across... ; ...end (HL). JMP TYPHLL ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * OPDTX * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: To open disk text file if not already open, or return Z-flag ; set if no file. ; On entry: No entry parameters. ; On exit: ; Note: Called from INIT and also at each disk text reference. ; OPDTX:: LDA DTXF## ; Flag NZ if file open. ORA A RNZ ; Return if already open. ; ; Open FCB, return if not found. ; STA DTXFCB##+12 ; Set extent to 0 for open. PUSH D ; Save DE-reg momentarily. LXI D,DTXFCB## ; Point fcb. Name, etc set up in INIT.MAC. CALL FINOPN## ; Open file, return z if not found. Looks... ; ...on current drive and on drive a: POP D ; Restore the DE-reg. RZ ; Return if not found. Z=1. PUSH H ; Preserve HL-reg. MVI A,0FFH ; Say opened ok. Gets cleared if eof read. STA DTXF## ; ; Read pointers: sectors 1-3 (sector 0 is copyright). ; LXI H,DTXSCT## INR M ; Set sector to 1 (FINOPN zeroed it). LXI H,DTXPTS## ; Where to read to: pointer buffer in VARSB. PUSH D ; Save caller's DE-reg. LXI D,DTXFCB## ; FCB addrress for REASEQ. CALL REASEQ## ; Read sector 1: FCB in DE-reg, to buffer... ; ...address in HL-reg (DIO.MAC). POP D ; Restore the DE-reg. LXI H,DTXPTS##+128 ; Read sectors 2 & 3 into DTXPTS+128. XRA A ; Make DTRE2 return pointer to DTXBUF in HL. ; ; Read two sectors to ((HL)), return pointer to DTXBUF + (A-reg) in ; HL-reg. This eliminates need for special priming of check for ; already in RAM, and gets text we will want next (no-file menu) ; without dropping a turn. ; CALL DTRE2 ; (HL)=pointer to DTXBUF. CALL DTRE2 ; Read next 2 sectors to regular text buffer. ; ; Check version. If wrong, say so and allow continuation. ; PUSH D LHLD WMSVER## ; Version of this WSMSGS.MAC (label defined... XCHG ; ...in VARS.MAC). LHLD MSGVER## ; Version of WSMSGS with which this version... ; ...of WordStar is intended to work... ; ...( see FIRST.MAC). CALL COMPAR## ; Set Z if (HL)=(DE). JZ OPDT7 ; Jump if correct version. LXI H,BADVTX## ; Address of "wrong version" text. SHLD ONCMSG## ; Make it display for 1 command (see PUTHL1... OPDT7: POP D ; ...in WMV1.MAC). ; ; If any of the above reads returned EOF, DTRE2 will have cleared DTXF. ; LDA DTXF## ORA A ; Set the status flags in PSW. POP H ; Restore HL-reg. RET ; Return NZ (normally) or Z if not there... ; ...after all. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * DTGET * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Gets text (HL) in RAM, returns HL-reg pointing to actual ; text. ; On entry: HL-reg "points" to desired text. (DE) destroyed. ; On exit: HL-reg points to actual text. Returns CY=1 if not disk text. ; Notes: Called from PTGET, TYPHL and from MOC for branches. ; DTGET: ; ; Test if text on disk: if address >= DTXPTS and < DTXPTS+255, ; text is on disk, HL is address of pointer. ; LXI D,DTXPTS##-1 ; "Address" of first byte of disk text... ; ...pointers, less 1. CALL COMPAR## ; Compare to caller's HL -- return NC if... ; ...(DE) >= (HL). CMC ; Complement CY for desired return. RC ; Return CY=1 (HL) < disk text base. LXI D,DTXPTE##-1 ; Address of last byte in disk text pointers... ; ...area. CALL COMPAR## ; Compare to caller's HL, return CY if DE end DTXPTS. ; ; Open disk file & get pointers if not open, else return ; pointer to ? message. ; CALL OPDTX ; Open file if not open, or return z if not... ; ...found. JZ USEFOO ; Jump if not found, go return @@@@. CY=0. ; ; Fetch pointer into disk file from pointers table. ; CALL FETCH2## ; HL=((HL)): replace with value read from file. DCR H ; Subtract 100h to convert .COM file... ; ...location to relative offset into... ; ...file. ; ; Compute sector number in file, and offset into sector. ; MOV A,L ; Low order offset into file. ANI 7FH ; Isolate low 7 bits: offset within sector, ... ; ...clears CY. PUSH PSW ; Stack offset into sector. CY=0. DAD H ; Puts bits 14-7 (the sector number... ; ...(max 32K)) into H-reg. XCHG ; Desired sector in D-reg, offset on Stack. ; ; Test for sector already in RAM. (Assumed maximums: 127 sectors, ; 32K text. ; LDA DTXSCT## ; Next sector to read (previous 2 in RAM). DCR A ; Sector number of last sector in RAM. LXI H,DTXBUF##+128 ; Load HL-reg with its buffer address. CMP D ; Is it one we want ? JZ DTTAD1 ; Jump if yes: go return text address. ; Buffer address in HL, offset and... ; ...CY=0 on Stack. DCR A ; Sector number of first sector in RAM. CMP D ; Is it the one we want ? JZ DTTAD ; Jump if yes: go return address. Text... ; ...offset in sector is on Stack as... ; ...a PSW with CY=0. ; ; Text is not in RAM. Load buffer. ; MOV A,D ; Get the desired sector number. STA DTXSCT## ; Set in FCB. (16 bits, hi left 0). POP PSW ; Offset from beginning of sector is in... ; ...A-reg, CY=0. ; ; Entry used in reloading buffer: message longer than text initially ; read. Points HL at next text character. Called from RELOAF below. ; Note: Fall through from routine above. ; DTREL1: ; Call with A-reg clear, CY=0 to return... ; ... .DTXBUF in HL for RELOAF. LXI H,DTXBUF## ; Offset is in A-reg, buffer address in HL-reg. ; Fall through to routine below. ; ; Entry to read 2 sectors from disk text file to ((HL)), return ; DTXBUF+(A) in HL. Clears DTXF if EOF read. Used in OPDTX ; to read pointers to DTXPTS and to prime buffer. ; ; Enter with CY=0. DTRE2: ; Read 2 sectors for OPDTX to ((HL)), return... ; ...BUF+(A) in HL. PUSH PSW ; Stack offset into sector for DTGET. CY=0 ; ...where matters. ; ; Read 2 sectors into RAM buffer. ; PUSH D LXI D,DTXFCB## ; Point to disk text FCB, already set up and... ; ...opened. CALL REASEQ## ; Read sector (DEHL), then increment sector... ; ...number. CY=1 if EOF. If EOF... ; read, REASEQ clears DTXF (at... ; ...DTXFCB-1). Then file gets... ; ...reopened on next call OK. JC UFOOA ; Use @@@@ if EOF read. DE, PSW in stack. CALL PRINF## ; Keep printer going. MVI A,128 CALL ADDHAH## ; Point to next sector location in buffer. CALL REASEQ## ; Read another sector. Check CY=1 ? JC UFOOA ; If EOF read, don't use disk text. ; ...Stack= PSW (CY=0), DE. POP D ; Caller's DE-reg. ; ; Compute text address. ; DTTAD: ; Come here with offset in stack to use... ; ...first sector address. LXI H,DTXBUF## ; Base of buffer. DTTAD1: ; Come here with buffer HL, offset in stack... ; ...if sector is already in RAM. POP PSW ; Fetch the offset. JMP ADDHAH## ; Compute text address: buffer+offset. No... ; ...overflow. Returns CY=0. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * RELOAF * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Reload text buffer if (HL) points to END+1. Updates HL ; if reload occurs. ; On entry: HL-reg points to buffer end +1. ; On exit: A-reg and CY are cleared to zero. Entering DE-reg is ; restored. ; Note: Called externally from FSCRN.MAC as well as locally. ; RELOAF:: PUSH D ; Save the DE-reg momentarily. LXI D,DTXBUF##+256 ; Point to first byte after text buffer. CALL COMPAR## ; Set Z if HL = end+1 buffer. POP D ; Restore entering DE-reg. RNZ ; Return if no reload needed. XRA A ; DTREL1 needs A-reg clear. JMP DTREL1 ; If reloading needed, reload (0 in a). ; Returnss HL=.DTXBUF. ; ; Text file not found and EOF errors were returned. ; UFOOA: ; EOF read from message file (bug or user... ; ...clobbered file). POP D ; Restore DE and clear the stack. POP PSW ; Restore the offset in A-reg and CY=0. ; REASEQ zeroed DTXF, so next call opens and... ; ...determines whether really there. ; ; Come here with CY=0 to use FOO message. The stack is empty. ; Return address of "disk message not found" text. ; USEFOO: LXI H,FOOMSG## ; Address of RAM pointer to text. JMP FETP ; Fetch pointer contents and add to location. ; Returns CY=0. CY=0 means that... ; ...actual that address is now in... ; ...the HL-reg as if from disk. ; FETP clears CY. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * CONSOLE I/O and CHARACTER INPUT * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * RBLINC * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Input character to A-reg without echo, redisplaying file ; while waiting. Preserve cursor position. ; On entry: No entry parameters. ; On exit: Character is returned in the A-reg with Z=0. ; Notes: Blinks cursor on inverse video. Redisplays status line ; if print stops or pauses. See also BLNKIN in CLOOP.MAC ; which leaves cursor in file position. ; RBLINC:: CALL REDFIL## ; Redisplay file portion of screen and... ; ...status line until done or until... ; ...a keystroke occurs. Preserve... ; ...cursor position (CLOOP.MAC). CALL PBLNCH ; Input character or return Z on print... ; ...status change (only internal call... ; ...to PBLNCH. JZ RBLINC ; If print paused or ended, redisplay... ; ...status line... RET ; ...else return character in A-reg. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * PBLNCH * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Input character to A-reg without echo, or return z if print ; status changes. ; On entry: ; On exit: Z=1 and (A-reg)=0 if print is active. Stops or pauses before ; a character is input. ; Note: This is used by calling routines to redisplay status line ; and/or menu when print change occurs). Blinks cursor if on ; or adjacent to highlighted character and CRBLIV is non-zero. ; Called from RBLINC (local) and from BLNKIN in CLOOP.MAC. ; PBLNCH:: PUSH H ; IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ LDA TRSCRS## ; Test to make sure we are using... $ ORA A ; ...TRS80 terminal so that we... $ ; ...can use the same program... $ ; ...for HEATH89. $ JNZ TRSCTS## ; NZ, so call TRS80 routine to test... $ ; ...for cursor over 20H. $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF ; ; Test for inverse video under cursor, in previous column, or in next ; column. ; LDA CRIV## ; Inverse video bit for character behind... ; ...cursor. CALL SWIN## ; Enable video board to test proper memory. LHLD SCRPTR## ; Point at memory map or screen image cursor... DCX H ; ...character. ORA M ; Character before cursor: high order bit on... ; ...if inverse video. INX H ; Point cursor character (but don't use from... ; ...screen because it has inverse bit... INX H ; ...if memory mapped cursor). ORA M ; OR with character after cursor. DCX H ; HL-reg is now pointing to SCRPTR. CALL SWOUT2 ; Disable video board. ; ; 80H bit of the A-reg is on if inverse video is under or next to cursor. ; Logically AND result of text with "blink required" flag. ; LXI H,CRBLIV## ; User-patchable: FF for blink, 0 for none. ; We use the high order bit. ANA M ; Minus for blink, positive for none. ; ; If all non-inverse, no blink. ; JP PHINCH ; Cursor not on inverse video, no blink, go... ; ...get character. ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * CONSOLE INPUT * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * BLNK1 * ; * * ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Function: Blink memory mapped cursor until character input, or, for ; terminal, turn inverse video off and on. Turning inverse ; video off and on does right thing for VIO. For most other ; terminals, CRBLIV should be zero and this code is not ; executed. Also watch for print status change. ; On entry: ; On exit: ; Note: If not blinking cursor, print watch is done in "INCH". ; BLNK1:: CALL PWATCH ; Check for print status change, clear... ; ..."disk wait". JZ PBLXIT ; Jump if print active and changed: return... ; ...Z=1 (A-reg)=0 to caller. ; ; "On" cycle comes first. Cursor is displayed on arrival here. ; CALL SWIN## ; Enable video board, user saves registers. MOV A,M CALL SWOUT2 ; Call should preserve all registers. CMA ; Complement inverse video bit. CALL SETIV ; Set inverse video (A-reg) if not memmap, ... ; ...nop if memory mapped. CALL DELAY1## ; Short wait if no character ready, NZ if... ; ...character ready. If key hit, ... ; ...fall thru. Keeps concurrent... ; ...print active. ; ; "Off" cycle. Longer than "On" cycle so cursor resembles... ; background, can distinguish on inverse video from next to same. ; CALL UNCR ; Cursor off if memory mapped, NOP if not. CALL SWIN## ; Switch in video board. MOV A,M ; Get character under cursor. CALL SWOUT2 ; Should save registers. CALL SETIV ; Set inverse video to match, if non-memory... ; mapped, NOP if memory mapped. CALL DELAY2## ; Medium wait if no character ready, NZ if... ; ...character ready. CALL RECR ; Display memory mapped cursor, preserving PSW. JZ BLNK1 ; Jump if no character input: keep blinking... ; ... and keep printing going. ;qqq ;character now ready, go get it PHINCH:: ; Come here if no blink required CALL INCH ; Input char, return a=0, z iff printer changed. ; Normally returns character in a, NZ set (character cannot be 0). ; only call to INCH. PBLXIT: CALL CLRIV ; Turn terminal inverse video off - to be safe - 3/9/79 POP H RET ; ; SWOUT2: PUSH PSW ; Calls SWOUT & saves PSW / SWOUT should save rest CALL SWOUT## ; Called a few times POP PSW RET ; ; Console I/O... character input INCH ; ;inp chr to a, without echo -- internal routine. ; ; prints while awaiting input. ; clears "disk wait" message from status line if present. ; returns CY=0. Sets intf on video stop character (^s at present) ; returns z=1, a=0 if print status changed (pwatch) and pbsy<>0. ; INCH:: ; Used externally from WMC2 re mult character input; ; Used internally in pblnch. ; For normal character input, use pblnch or rblinc above, or blnkin (cloop). ; check for input character available in typeahead buffer PUSH H CALL IPEEK ; Get character in a, or z flag if none, and INCHOP in HL. JZ INCHIT ; Jump if empty, go check console ; PSW is NZ (nulls don't get into typahead buffer) ; have typahead char, return it to caller PUSH PSW ; Save chr for caller. Cy=0, NZ set MVI M,0 INX H ; Clear buf posn, step ptr MOV A,M INR A ; 0ffh marks end of buffer JNZ INCH2 LXI H,INCHS## ; Wrap ptr if at end INCH2: SHLD INCHOP## ; Store new buf ptr JMP JBUFTY ; Go buffer typahed. PSW (NZ,CY=0,char), HL in stack. ; Buf full ck not important - just made a space ; ; no buffered-ahead char, check for character at console, then print if active. ; INCHIT: POP H ; ; if print inactive, call system (to do wait there for spooler compatibility) ; .or. If input character ready now, call system to get it. ; note: cases that must blink cursor, etc, don't come here til character ready. LDA PBSY## ; Ff if printing, 0 if not CMA ; 0 if printing, ff if not ORA A ; Set flags: z if printing, NZ if not printing. CZ CSBIOS ; If printing, get NZ if character ready JNZ BIOSCI ; If character rdy .or. Not printing, go input char ; Via system and return to caller. ; ; no console character ready .and. Concurrent print active. ; print a char, loop til character avail or printer change to return to caller. CALL PRINT## ; Else print a little, CALL PRINF## ; .. (this keeps printer going (runs PRTDRV) even when ; final print "print" coroutine waiting for input). CALL PWATCH ; Check for printer change, remove "wait" msg if up, JNZ INCH ; & loop to recheck if no print change. ; nb must recheck typahed cuase print sucks character in. RET ; If print changed, ret z and 0 in a. ; Console input, etc INCH..., IPEEK, pwatch ; ; "peek" at next typed-ahead input character w/o removing it from buffer ; ; returns character in a, or z if none. Rets INCHOP in HL. ; IPEEK:: ; Used internally in INCH (just above); ; Also used externally from WMC2 re mult character input. LHLD INCHOP## ; Get pointer for removing chars from tya buffer MOV A,M ; Get next character - or 0 if none input yet ORA A ; Set z flag if none RET ; INCHOP in HL, character or 0 in a ; ;input character via BIOS, to avoid echo under CP/M. Used from INCH. ; BIOSCI: CALL CIRUBF ; Get char, mask, set intf ORA A JZ BIOSCI ; Discard nulls ORA A ; Clear cy, clear z (ie set NZ) RET ; Character is in a, CY is 0. ; ; routine to check for change in print status of concurrent print command. ; if mpbsy<>pbsy or mpause<>paused, ; sets mpbsy to pbsy, mpuase to paused, helupf to 0, and rets z=1,a=0. ; else if dwmf NZ, redisplays status line to clear "disk wait" msg *.938* ; else returns NZ. ; PWATCH:: ; check for printer status change PUSH D PUSH H LHLD MPBSY## ; Our copy of pbsy/paused XCHG LHLD PBSY## ; Print bsy flag, and print puased flag (pbsy+1) SHLD MPBSY## ; Update our copy, so happens only once CALL COMPAR## ; Different? POP H POP D JZ PWATDW ; If same, go check disk wait message XRA A STA HELUPF## ; Different, say "help" must be redisplayed RET ; Different, return z with 0 in a ; Pwatch... ; print status unchanged, check for disk wait msg displayed PWATDW: LDA DWMF## ; 0 normal, ff if message displayed CMA ; Ff normal, 0 if message displayed ORA A RNZ ; Return NZ if no "disk wait" message up *.938* ; redisplay status line locally to remove "disk wait" message. *.938* ; doing this here prevents menu redisplay and loss on "oncmsg" message. ; case in point: "warning: printing same file as editing...". ; note: helupf is always 0 if a oncmsg is up. ; note: by the time control gets here after disk wait displayed, it is ; always time to remove the "disk wait" message. PUSH H LHLD LIN## ; Cursor position: save it in HL CALL STLINE## ; Display status line. Clears dwmf, displays regardless ; of typahed if dwmf on at entry. Saves regs. CALL DCRSR## ; Restore cursor position if stline changed it POP H ORI 0FFH ; Return NZ after clearing disk wait message RET ; Console input and status... vsuck ; ; console status/video repeating command check: ; returns NZ and m if character at console, in input buffer, or if vcount non-0 ; note: vcount is 0 when not in video editor. Also inputs and buffers typahead. ; VSUCK:: ; Nb fall thru if fourt=0 ; Console input and status... suck ; Nb fall in ; ;get console status: NZ and m (3/25/79) if chr rdy at con: or in typeahead buf. ; ; inps and bufs chr. Dual function: test for character ready, buffer typahed. ; sets intf on stop char. ; SUCK:: PUSH H SUCK1: CALL CSBIOS ; Constat (via BIOS or user subr) to flags JZ SUCK4 ; Jump if no chr at console ;get chr from con: into typeahead buffer ;input all avail console chars to buffer SUCK2: CALL CSBIOS ; Check status JZ SUCK4 ; Jump if none ready. CALL PULL ; Get & buffer character (nop if ; null character or full buffer ; Pull returns new INCHIP in HL MOV A,M ; Check buffer full ORA A JZ SUCK2 ; Loop if ok ;buffer full, or 1 character from full. MVI A,'!' CALL OCH ; Display fleeting ! MVI A,CTRLG CALL JOC ; Beep terminal, dissappears on vio. CALL REDALL## ; Invoke full redisplay for video edit ;return true: at least 1 character just input from console ; (or buffer full, in which case there are chars in buffer) SUCKX: POP H ORI 0FFH ; A=ff, z=0 (NZ) and m=1 to say character ready RET ; ;no character at console, return depends on whether there are chars in buffer SUCK4: LHLD INCHOP## MOV A,M ; 0 if next slot empty => entire buffer empty ORA A ; Set z if buffer empty, clear m, leave a 0 POP H RZ ; If no chars in buffer, return a=0, z=1, m=0 RETNZ:: ; Here to return a=ff, z=0 (NZ), m=1. ORI 0FFH ; If chars in buffer, return a=ff, z=0, m=1 RET ; ;input & buffer console character, or not ; if buffer fall or character is a null ; ;returns updated "INCHIP" in HL, clobbers PSW. ; PULL: LHLD INCHIP## MOV A,M ORA A RNZ ; Rif buffer full CALL CIRUBF ; Input character with rubout special handling, mask ORA A RZ ; Discard nulls -- 0 = empty buffer slot MOV M,A ; Buffer char INX H ; Point next slot MOV A,M INR A ; Set z if ff= buf end JNZ PULL2 ; Jump iff not end LXI H,INCHS## ; Loop to beginning PULL2: SHLD INCHIP## ; Store updated pointer RET ; Console input BIOS calls cirubf ; ;input character to a via BIOS and do special stuff to handle BIOSs that ; echo backspace, space, backspace on character output after rubout input ; ; notes 7/20/79: 1. Operation of following unknown before now because character was ; not masked before rubout test. 2. Changed today for rubfxf/rfixer patches. ; 3. Outputting a null doesn't do it for sd sales system, ; hence zafcin added (in ciBIOS) ; CIRUBF: CALL CIBIOS ; Input character to a CPI RUBOUT ; Rubout? RNZ ; No, return to caller ; is rubout PUSH PSW PUSH H ; no special handling if mem mapped: 1) output not via BIOS, ; 2) would need check against storing into location before video board. ; no special handling unless enabled by user-patch flag. LDA MEMMAP## ; Ff if memory mapped CMA ; 0 if memory mapped, ff if not LXI H,RUBFXF## ; Nz to enable rubout-fix: USER.MAC ANA M ; Make NZ if enabled and not memory mapped JZ RUBFX ; output user-patch char, so BIOS does its funny stuff now. Else BIOS's ; funny stuff can delete lead-in character of next cursor sequence, making a mess. ; note: if not typahead, this place on screen will be redisplayed anyway ; in processing the rubout. If not, random place may be blanked. LDA RFIXER## ; Null or as patched (USER.MAC) CALL JOC ; Output it. Preserves PSW. ; note: joc changed 7/30/80 to not mask hi bit *2.11* ; mark character unknown in screen image LHLD SCRPTR## ; Pointer to character under cursor DCX H ; Point previous char. Note: initialization leaves an ; unused byte before screen image, in case cursor is home. MOV M,A ; Store rfixer: should be impossible graphic? ; don't try to re-output the screen character (at least not without ; setting cursor), because BIOS may not have backspaced. RUBFX: POP H POP PSW RET ; Console input BIOS calls... ciBIOS ; ;input character to a via BIOS, test for video stop char ; called in installation dialog - must work before editor is init. ; hence can't rubfix (by cirubf method - above) here. ; CIBIOS: CALL CIB ; Input character to a via BIOS or user subr *.932* *.946* ; Nb do not discard nulls here because suck would hang til ; Another character typed. PUSH H ;zero location after each character input if elected via patch in USER.MAC ; this is intended to allow disabling rubout-backspacing BIOS. 7/20/79. PUSH PSW ; Save char LHLD ZAFCIN## ; Zero or address of location to clear. USER.MAC. MOV A,H ORA L JZ CIBIO2 MVI M,0 ; Zero location CIBIO2: POP PSW ;set flag if interrupt character LXI H,STPCHR## CMP M ; Test for patchable video stop char POP H RNZ STA INTF## ; Cmd mode interrupt character and flag are same 11/31/78 RET ; Console input BIOS calls CONSTA, csBIOS ; ; get console status from BIOS or custom user subroutine. Nz if character ready. ; *.946* CSBIOS: LDA UCNSTA## ; Nz if custom subr installed ORA A JZ CSBIO2 ; Jump if no custom routine: use op system ;use user routine PUSH B ; Save registers thru it PUSH D PUSH H CALL UCNSTA## ; Call custom routine (USER.MAC patch item) ORA A ; Set flags from 0 / ff returned by routine JMP RHDB## ; Pop h, d, b and ret CSBIO2: ; Fall thru to get console status from BIOS ; ;"console status" entry for alternate console printer driver in USER.MAC. ; uses BIOS, never custom user subroutine. ; returns 0 and z if no character ready, NZ and 0ffh if character ready. CONSTA:: ; ;get console status via BIOS: z=0 (NZ) if character ready. ; IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ LDA TRSCIF## ; Non-zero if we use TRS80 input... $ ; ...routines. $ ORA A ; Test for zero. $ JNZ TRSTAT## ; Do the special TRS80 mod-1 console... $ ; ...input routines. $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF CONST2:: MVI A,BCSTAT ; Get console status via BIOS CALL BIOS ; Returns a=ff character rdy, a=0 no char ORA A RET ; Set flgs, return. ; Note: most CP/M's (eg imsai cpm 1.33, digital research CP/M, imdos) ; Return flgs set, but at least one version, lifeboat associates mini- ; Floppy CP/M, returns flgs wrong. Hence above ora a. ; Console input BIOS calls cib, INCHR, BIOS ; ; input console character to a from user routine or operating system *.946* ; CIB: ; Internal entry point LDA UCONI## ; Nz if custom routine present ORA A JZ CIB2 ; Jump if none: go use BIOS ;use user's custom routine PUSH B PUSH D PUSH H CALL UCONI## ; Custom routine: patch item in USER.MAC. Rets character a. JMP RHDB## ; Go pop h,d,b and ret CIB2: ; Fall thru to input character to a via BIOS ; ; "console character input" entry for alt console printer driver in USER.MAC. ; *.932* ; inputs character to a, using BIOS "console input" function, ; does not use user custom console input routine. *.946* ; INCHR:: IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ LDA TRSCIF## ; <>0 if we use TRS80 routines $ ORA A ; Test for 0 $ JNZ TRSCI## ; Special routine in TRS80.MAC $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF INCHR2:: MVI A,BCIN ; Offset into BIOS entry vector in a ; Fall into "BIOS". Returns character in a. ; ;call routine in BIOS for offset-3 in a. Transmit c in a also or cdos character out. ; BIOS: PUSH B PUSH D PUSH H LXI H,RHDB## PUSH H ; Set return: pops h, d, b. LHLD BIOSP## ; Addr in JMP at 0: location of BIOS, +3 (SYSEQA.MAC). CALL ADDHAH## ; Add a thereto MOV A,C ; Transmit c in a also. This is because Cromemco CDOS ; Console output character function requires character in a, ; Other CP/M's take character in c. ; No effect on other BIOS calls. PCHL ; Go there. Return already stked. ; Console status etc... buftya, clrtya ; ; input and buffer typed-ahead character, if any, saving all registers ; ;no buffer overflow check. ;called recursively from INCH, suck, xoc routines ; BUFTYA:: PUSH H PUSH PSW JBUFTY: ; JMP ENTRY, PSW, HL in stack. Used in INCH subr. CALL PULLIT ; If ready, get it. Clobbers HL,PSW. ; If buf full does not input char. LDA MPMFLG## ; Check for running under MP/M. ORA A ; MP/M ? JZ RETPH ; YES. ; PUSH B ; Save registers. PUSH D CALL SYSTEM## ; Swap users. DB DISPAT POP D ; Restore registers. POP B ; RETPH: POP PSW POP H RET ; PULLIT:: ; Calls csBIOS for loops CALL CSBIOS ; Get the character PUSH PSW ; Save status as weiter character was ready or not CNZ PULL ; Pull the char. POP PSW ; Return the outcome RET ; ; ; ;clear typahed buffer ; CLRTYA:: PUSH PSW ; PSW save required by stopsu, WMV1.MAC. PUSH B PUSH H LXI H,INCHS## ; Beginning buffer, for pointers and zerfil SHLD INCHIP## SHLD INCHOP## ; Set pointers = LXI B,LINCHS## ; INCHEN-INCHS = # bytes in tya buffer CALL ZERFIL## ; Zero it (bcHL) POP H POP B POP PSW RET ; Console I/O... Tst whether character fits present output line wif ; ;routine to ret CY=1 iff chr in a will not fit on crrent line ; recoded *.931* WIF:: CPI CR RZ CPI LF RZ ; Cr,lf always fit PUSH B MOV B,A ; Save character in b LDA COL## ; Fetch current cursor screen column *.931* MOV C,A ; ..to c for colc *.931* MOV A,B ; Restore character in a for colc CALL COLC ; Generate new column in c *.931* ; colc operates on 16 bits, but since ; max wid < 255-8, hi order won't change *.931* LDA WID## INR C CMP C ; Sets CY if new col >= width MOV A,B ; Restore character in a POP B RET ; Restore a and bc. Nb col unchanged. ; Console I/O etc: character column width stuff... Colmc ; ; subr to update screen column (c) for character (a). ; ; cr, lf should not get here. Called from "wif" and "PCOLM". ; ; does 16-bit arith on bc (for PCOLM) but b should never be ; changed if c contains a valid screen column # (always < 255) ; COLC: INX B ; Normal chars take 1 col CPI ' ' RNC ; Rif not control char INX B ; Other controls take 2, for ^x CPI TAB RNZ ; Rif not tab ; Except tab, takes to next multiple of 8 PUSH PSW DCX B ; Restore as at entry - undo above inx's DCX B ; .. MOV A,C ORI 7 ; Make multiple of 8 -1, MOV C,A INX B ; Make multiple of 8 POP PSW RET ; Console I/O etc... character column width stuff... PCOLM ; ; subr to update 16-bit signed print column ((HL)) for character (a). ; ; cr,lf don't get here. Caller should mask char. ; column # is reduced (possibly becoming negative) on backspace char. ; for finding cursor pos on cursor up,down (WMC3); marginating (WMC9). ; note: form feed is handled as a 0-col print control. ; revised *.931* PCOLM:: PUSH B MOV C,M ; Fetch column to bc INX H MOV B,M ; .. CPI ' ' ; Set CY if control character CC PFCTST## ; If a control character, call routine in print1 ; to classify. Rets CY if print control, plus z if ; 0-column, or odd parity if backspace, else its ; 1-column (even parity, NZ). JC PCOLM2 ; Jump if is a control and pfctst said a print control ; Cy=0 if not control character or not a print control: print width is ; same as screen width. CALL COLC ; Increment bc for character (a) 's screen width PCOLMX: ; PCOLM exit MOV M,B ; Store incremented column DCX H MOV M,C ; .. POP B RET ; ; character (a) was a print control: print width may be different from screen width PCOLM2: JZ PCOLMX ; Jump if 0-col control: go exit - no effect on print col ; is a 1-col control, except -1 column if odd parity on INX B ; 1 column JPE PCOLMX ; Go exit if 1 column DCX B ; Oops, its a backspace, undo increment, DCX B ; .. And decrement, possibly producing negative result JMP PCOLMX ; Console I/O... screen line/string output DISVLL/DISLIN/DISSTR ; ; display (different portion of) screen line ; ;given line must be in exact display form - tabs and controls expanded, ;no cr's or lf's included; and fit entirely on one screen line. ;crsor position indefinite afterwards - caller must reset. ; ; entry to display entire editor logical line (l) using text in vlbuf, ; except not last col of last screen line if "USELST" off. ; calls "PRINF" before displaying ************* added 3/25/80. ; nb caller must make sure no hi bits in line if hilite is zero. ; callers are: DISLIN in WMV3.MAC for file lines, ; drldis in WMV1A for directory and ruler lines. ; (status line uses JDISTR entry below.) ; DISVLL:: CALL SLINL## ; Convert editor logical line # in l to physical: PUSH PSW ; .. Add toplin to it. CRSR.MAC. Saves PSW. PUSH B PUSH D PUSH H CALL PRINF## ; Print a character if printing, character is already in ; .. Printer driver buffer, printer is not busy, and XCHG ; .. Printer has busy test. PRINT2.MAC. Alters PSW. LHLD PVLBUF## ; Get location of video line buffer in DE XCHG ;JDISLN: ; Entry for regs already stacked LDA WID## ; # chars in a screen line MOV C,A ; Set # chars in c MVI H,0 ; Set starting column ;test for last line, reduce length 1 if USELST off, to prevent scrolling. LDA HITE## DCR A SUB L ; Produce 0 if last line of screen PUSH H LXI H,USELST## ; Nz if ok to use last col of last line ORA M ; 0 if last line and not ok to use last col POP H JNZ DISALL ; Jump if ok to use entire line DCR C ; Reduce line length by 1 DISALL: ; JMP JDISTR ; Fall into JDISTR. CDEHL set. ; DISLIN/DISSTR... nb fall thru ; ; display string (de) length (c) at column (h) line (l) ; ; nb caller must make sure no hi bits in line if hilite is zero. ; JDISTR: ; Jump entry, PSW, b, d, h already stacked. ;move col to b, get screen address in HL, branch if memory mapped MOV B,H ; Column to b PUSH H ; Save crsor position PUSH D CALL SCADHL## ; Compute screen image addr to HL for cr pos HL POP D ; Restore DE - SCADHL clobbered LDA MEMMAP## ; Non-0 if memory mapped video output ORA A JNZ DISMEM ; Jump if mem map: go do direct store ;search for first difference, advancing beginning pointer to it DSL1: LDAX D ; Source char CMP M ; Screen char JNZ DISDIF ; Jump if different ; DISLIN/DISSTR... ;arg same as present screen line, this character need not be displayed. INX H ; Next char INX D ; .. INR B ; Next starting col DCR C ; Length one less JNZ DSL1 ; Loop till difference or end ;whole string identical, no display, no crsor set DISX1: POP H ; Match stk: pop crsor position JMP DISSX ; Go exit ; ;first difference found. Point end. DISDIF: PUSH D ; Save beginning of given (source) text PUSH B MVI B,0 ; Hi order 0 on length (c) for dad DAD B ; Compute end+1 of screen image address XCHG DAD B ; Compute end+1 of source text XCHG POP B ;search back to find last difference DISL2: DCX H DCX D LDAX D ; Soruce char CMP M ; Compare to present screen JNZ DISDF2 ; Jump if difference, must display to here DCR C ; This character same, reduce length JNZ DISL2 DISDF2: POP D ; Restore beginning source ;output different part - at least 1 character - c chars starting at DE. POP H ; Get back crsor position line # MOV H,B ; Update col # for same chars passed CALL TCRSOR## ; Position crsor DISOL: LDAX D ; Get a char CALL XOC ; Display it INX D ; Point next char DCR C ; Decrement character cnt JNZ DISOL ; Loop til done DISSX: ; Exit: pop all registers. Why clear cy? *1.12* RHDBAN:: ; Public return point to pop regs, clear cy, set flgs=a *1.12* POP H POP D POP B POP PSW ORA A RET ; Console I/O... DISLIN/DISSTR..., ecrlf ;DISLIN/DISSTR memory mapped video case ;just copy into video ram - faster than comparing. No crsor handling. ; DISMEM: ; C=# chars, DE=source, HL=dest in video ram CALL UNCR ; Memap cursor out during display, else get confused ; .. If character behind it changes from/to inv video MVI B,0 ; Hi order 0 to get # chars in bc XCHG ; Source HL, dest DE CALL SWIN## ; Switch video board into addr space - normally nop CALL COPY## ; Move bc chars HL+ to DE+ CALL SWOUT## ; Switch video board out of addr space - normally nop CALL RECR ; Replace cursor JMP DISX1 ; Go match stk and exit ; ***** some subrs used largely in MOC/och (which follow them) ******* ; ; erase eol, crlf if < (a) cols left on current line. Clobbers a. ; ECRIF:: PUSH H LXI H,COL## ADD M ; Compute where (a) columns would take us to INR A ; Add 1 cause can't display in last column LXI H,WID## CMP M ; Compare to screen width POP H RC ; Rif will fit ; Else fall thru to ecrlf ; ; erase to eol and leave cursor at beginning of next line ; ECRLF: PUSH PSW PUSH H CALL BUFTYA ; Buffer typahead w/o overflow typeout ;scroll now if bottom screen CALL SCRIFB ; Cursor should not be removed for doing this ;save cursor pos LHLD LIN## ; Used in HL by nereol ;erase to eol CALL NEREOL## ; Erase from cursor pos (HL) to end screen line ;cursor to beg next line JMP JCBNL ; (HL) ; MOC/och subrs... wrap ; ; wrap to next line, putting + in last column of this line ; WRAP: PUSH PSW PUSH H ;if last line on screen, scroll now, ;so independent of whether terminal scrolls on printing in last col last line CALL SCRIFB ; Scroll 1 line if bottom line of screen ;erase any character positions left on this line ; coded to handle cursor allready at or beyond last screen column, for cases ; created by ! on typahed buffer full. Note that DISLIN leaves cursor sitting ; "after" last screen col & suck called before next cursor set. LXI H,WID## ; Point # cols on a line WRAP2: LDA COL## ; Current col, 0 ... Wid-1 INR A ; +1 so last usable col=wid CMP M ; Set CY if have 2+ cols left incl col 80 JNC WRAP3 ; Jump if no cols to erase. Z set if at col 80 (1 col left) ; blank another column MVI A,' ' CALL XOC JMP WRAP2 ; Go retest ;end line with + WRAP3: ; Z set if at col 80 -> output + ; If enter at "col 81" or beyond, NZ, skip the + LHLD LIN## ; Cursor pos - save now MVI A,'+' CZ XOC ; Output + unless beyond end line ;nb cursor position now ambiguous, depending whether terminal wraps to ; next line after outputting in last column. ;nb know we have another line on screen, cuase already scrifb'd ;cursor to beginning next line ; Lin/col in HL JCBNL: INR L MVI H,0 JMP JTCRSR## ; Go diplay cursor (HL), pop h, pop PSW, ret. ; MOC/och subrs scrib, crlf ; ; scroll if bottom line ; ; call before doing erase eol/line wrap functions to keep editor ; independent of whether terminal scrolls on output to last character pos ; SCRIFB: PUSH PSW PUSH H ;test for bottom line, rif not LDA LIN## INR A LXI H,HITE## CMP M JC RETHA ; Jump if lin < hite-1: go exit ;output lf to scroll screen MVI A,LF CALL XOC ;move cursor back up to former position LHLD LIN## DCR L JMP JTCRSR## ; Go display cursor (HL), pop h, pop PSW, ret. ; ;oup crlf to con:, preserving PSW. ; CRLF:: PUSH PSW MVI A,0FH CALL MOC POP PSW RET ; Console character output MOC, MMOC ; ; message output character (a) from location (HL). Inverts video always. ; HL should point string being typed, and will be updated ; if codes 01-05 used in string ; nb caller (TYPHL/PTYPHL) handles disk buffer reload at end buffer. ; ; interprets additional control characters as follows: ; 01h absolute indirect "subr call": ; next two bytes (lohi) are absolute pointer ; to (relative) pointer to txt to insert here in message. ; **** nb argument absolute **** ; typical use: calling text in a text area or on disk from ; a text not in a text area, e.g. Signon in INITA.MAC. ; 02h relative indirect "subr call": ; next two bytes (lohi) are self-relative pointer ; to (relative) pointer to txt to insert here in message. ; **** nb argument self-relative **** ; calling & called text normally both in ram, same ovly, ; to permit linking pointers; ; could go to / from disk but not disk-disk! ; typical use: calling another text in same overlay's text ; area, e.g. In MRTAB.MAC. ; 03h absolute indirect text "branch": ; next two bytes (lohi) are absolute pointer ; to disk or ram/relative pointer to text to branch to. ; **** nb argument absolute but points to pointer **** ; 03h still needed ******* ? ; all uses removed from texts, mrtab. Check wsmsgs! ; 04h absolute direct verbatim "subr call": ; next two bytes are absolute ram addr of text to insert. ; does not interpret most controls therein: ; typical uses: "not found" error msg; echoing filenames. ; 05H PRINTS " on (OFF)" FOR Z, OR " off (ON)" FOR NZ, PER FLAG DITTO ; 0eh erase to eol, cr, lf ; 0fh cr, lf ; 10h prints "error" ; 11h prints " internal error" ; 12h prints "fatal" ; 13h prints indent for prompts: 3 inverse (inverse) video spaces ; 14h prints " name of file to " ; 15h prints "file" ; 16h prints "final-" iff final print ; 17H "Print a file ", "STOP PRINT ", OR "CONTINUE PRINT" ; 18h awaits keystroke (displaying file area), then moves cursor to ; top of screen and continues displaying ; 19h name of not-found file (via nffcb set by opnsub) w/o drive ; 1ah prints name not-found file (via nffcb set by opnsub or caller) ; (1eh,1fh) soft hyphens, interpreted in och. ; controls without special definitions print as ^x ; ; ; output character (a) from location (HL) with special chars per previous page ; MOC: CPI 0EH JZ ECRLF ; Go erase to end of line, put cursr beg next line PUSH D CALL MOCTST ; Test for specials (a), if found, ret z and txt addr DE ; Caller's HL in HL, may be updated, must ret to caller. ; MOCTST can also ret to caller. Stk=de, ret addr. JZ MOCIT ; Jump if special. Code follows "MMOC". De in stk. POP D ; Not a special interpreted here, fall thru to MMOC ; ; menu/message output character: reverse of normal inverse video. ; does not interprt specials as MOC does. ; used for input echo, in MOC, and for "05" non-interpretive call. ; MMOC:: PUSH PSW XRI 80H ; Inverse video (or not if character inverse) CALL OCH ; Output character (a). Masks hi bit if hilite is 0. POP PSW ; .. Converts soft hyphens to external display chars. RET ; Exit from MMOC or MOC call ; Console output character... MOC... ; ; "MOC" subr, continued: output special text (de). Includes "call". ; either special or calling text must be in ram. ; MOCIT: ; Special text addr in DE, caller's DE in stack. XCHG ; Preserve HL in DE, get text addr in HL CALL PTYPHL ; Type special text: includes PTGET XCHG ; Restore (updated) HL POP D ; Caller's DE RET ; Exit from MOC call ; Console character out... MOC... MOCTST ; ; test for the MOC special text cases. ; can return to caller (MOC), or to previous caller -- ; assumes stack = MOCTST return, MOC caller's DE, MOC return. ; returns NZ if a is reg char, z for print spec text (DE) then continue, ; returns to "MOC" caller with HL updated for other exceptions that ; print nothing on this call to MOC. ; see list of chars interpreted on previous page. ; MOCTST: CPI 1AH ; Text for 1ah: largest value JZ MOC1AH ; Go handle 1a: generate file name text w/o drive RNC ; Rif larger: not special. Nz. CPI 18H JZ MOC18H ; 18h is very special. JNC MOC19H ; If >18 here, must be 19, go generate file name text. CPI 16H JZ MOC16H ; 16h has two conditional texts, handle specially. JNC MOC17H ; If >16 here, must be 17. 3 txts, do specially. CPI 0FH ; Text for 0fh: smallest that is a text substitution JC MOC2 ; If smaller, go test for group w/ ptr in next 2 bytes. ; Stack=MOCTST return, caller's DE, MOC return. ;simple-text-expansion cases. Known special, ok now to clobber a. XCHG ; Save caller's HL (rest of his msg) in DE ; special byte 0fh-16h is in a LXI H,MCTBAS##-2*0FH;location of first pointer (TEXTS.MAC), offset ADD A ; Double code to get index into pointers CALL ADDHAH## ; Compute text pointer address: a+HL to HL XCHG ; Text pointer addr to DE, caller's HL (rest msg) to HL XRA A ; Return z to say DE is special msg addr RET ; Ret into "MOC", z=1, DE=spec txt addr, HL restored. ; MOC... MOCTST... ; ;MOCTST... 16h prints "final-" if final-print ; MOC16H: LDA FINAL## ORA A ; Nz if final print, z if draft print LXI D,MOC16D## ; Text for draft print. TEXTS.MAC. RZ ; Rif draft print, text DE, z set LXI D,MOC16F## ; Text for final print. TEXTS.MAC. XRA A ; Set z RET ; ;MOCTST... 17h prints one of 3 things depending on print activity ; MOC17H: LXI D,MOC17A## ; .. Used in menus for definition of "p" command LDA PBSY## ORA A RZ ; If not printing, say "print a file" LXI D,MOC17B## LDA PAUSED## ORA A RZ ; If printing active, say "stop print" LXI D,MOC17C## XRA A RET ; Else printing held, say "continue print" ;MOC17A: DB 'Print a file ',0 ; TEXTS FOR 17H. ALL SAME LENGTH: 15 COLS ;MOC17b: db 'stop print ',0 ; texts are external, in TEXTS.MAC. ;MOC17c: db 'continue print',0 ; ;MOCTST... 18h awaits keystroke between frames of message ; MOC18H: CALL ERETBK## ; Erase end line, update tdlin (WMV5.MAC) CALL RBLINC ; Redisplay file while waiting, ; get input character (CIO.MAC) CALL STPCK## ; Interrupt (no return) if ^u typed CALL RSTTDH## ; Reset tdlin etc, cursor to top screen (WMV5) JMP MOCXX ; Exit to MOC caller, skipping out of MOCTST. ; Nothing was typed, caller's inx will pass the byte ; Stack=MOCTST return, caller's DE, MOC return. ; MOC... MOCTST... ; ;MOCTST... 1ah prints name of file not found, per fcb adr saved by opnsub. ; MOC1AH: PUSH H ; Save caller's HL LHLD NFFCB## ; Address of fcb where open failed, saved in DIO.MAC. JMP MOC1A1 ; .. Or set by caller for other cases ; ;MOCTST... 19h prints name of file not found, per fcb in nffcb, w/o drive ; MOC19H: PUSH H ; Save caller's HL LHLD NFFCB## ; Address of fcb where open failed, saved in DIO.MAC. MVI M,0 ; Clear the drive: might be confusing after finopn. ; above appropriate for message and overlay files. MOC1A1: XCHG ; to DE LHLD PVLBUF## ; Use video line buffer as space to set up text PUSH H ; Save for ret to caller in DE CALL PFCB## ; Format fcb (de) into text at ((HL)). UTIL.MAC. POP D ; Text addr DE POP H ; Restore ; JMP MOC04H ; Go print text (de) literally (may be case funny chars ; Fall in ; in "bad file name" message) ; ;MOCTST... 04h prints text (in ram) addressed by nxt 2 bytes (de), ; then returns to calling text. ; argument is location of text -- no pointers followed. ; does not interpret "MOC"'s usual special characters: ; used to echo operator's search text in "not found" message, ; also to echo (possibly invalid) file names. ; ; fall in to print file name MOC04H: ; Pointer from next 2 bytes in DE, caller's HL in HL, ; Stack=MOCTST return, caller's DE, MOC return. MOC04L: ; Loop to output addressed text LDAX D ORA A JZ MOCXX ; At end, go return to "MOC" caller. ; Stack=MOCTST return, caller's DE, MOC return. CALL MMOC ; Output (a), hilited, bypassing MOC. INX D JMP MOC04L ; MOC... MOCTST... pointer cases ; ;MOCTST... pointer group test and dispatch, else return non-special ; MOC2: ; Caller's character < 0fh in a, caller's HL in HL, ; Stack=MOCTST return, caller's DE, MOC return. ; Returns NZ to MOC if non-special, z w/text addr in DE to MOC, ; or, in some cases, to MOC caller after special display. ;test for group taking ptr in next 2 bytes, else ret NZ. CPI 05 ; Largest in group JZ MOC3 RNC ; Rif larger, z clear MOC3: CPI 01 ; Smallest RC ; Rif smaller, z clear ;fetch argument pointer from next 2 bytes to DE INX H ; Point past character now in a PUSH PSW ; Save a thru RELOAFs CALL RELOAF ; Reload buffer, update HL if necessary MOV E,M INX H CALL RELOAF ; Reload buffer, update HL if necessary POP PSW ; Restore the function code (character before ptr) MOV D,M ; HL is updated to next character for caller ;dispatch on ptr-taking values ; 01 = absolute indirect "call" is all set for MOCit to complete. CPI 01 ; Absolute indirect "subr call" RZ ; Return z=1, pointer location is in DE CPI 02 ; Relative indirect "subr call" JZ MOC02H ; Nb z=1 on dispatch CPI 03 ; Absolure indirect branch JZ MOC03H CPI 04 ; Direct verbatim "subr call" JZ MOC04H ; Else must be 05 ; Nb 05h falls thru ; ;MOCTST... 05 prints " on (off)" if flag z, or " off (on)" if flag NZ ; ;MOC05h: ; Pointer in DE, caller's HL in HL LDAX D ORA A LXI D,M05OFF## RZ LXI D,M05ON## XRA A RET ;M05OFF: DB ' on (OFF)',0 ; TEXTS ARE EXTERNAL, IN TEXTS.MAC. ;M05ON: DB ' off (ON)',0 ; MOC... MOCTST... pointer cases.... ; ;MOCTXT... 02h is relative indirect "call": inserts arg text. ; MOC02H: ; Z=1, DE=arg pointer, HL=arg location+1=caller's text pointer ; argument pointer for 02h is self-relative. Add its location to it XCHG DAD D ; Pointer + location+1 fetched from. Does not change z DCX H ; Remove the +1 XCHG ; return with z set. Mocit will fetch pointer, display text, ; then exit MOC with entry HL, so caller will continue orig text. RET ; z=1 from jz that got here. ; ;MOCTST... 03h is abs indirect branch: ret new ptr in HL to "MOC" caller ; ; 03 believed now unneeded or eliminatable ********** 4/27/80 ; MOC03H: ; Ag pointer in DE, HL is caller's +2, ; Stack=MOCTST return, caller's DE, MOC return. ; arg ptr for 03 is absolute address of disk or ram pointer. XCHG ; New pointer to HL, discard old CALL PTGET ; If on disk, get into ram. ; If in ram, follow rel the pointer. Update HL. ; No chars printed this call; instead branch addr-1 ret to ; Caller so he can loop, inx, and check for string terminator. ;return to "MOC" caller, decrementing HL so caller's incr will get nxt char ;;MOCbrt: DCX H ; Unx h so caller can inx to next char ; Nb don't print 1st character here cuase must check character for 0 ; (terminator) first. This endtest is at top caller's loop. MOCXX: ; Here to exit from MOC from within MOCTST. ; Stack=MOCTST return, caller's DE, MOC return. POP D ; Discard return from "MOCTST" POP D ; Restore DE RET ; Return from "MOC". ; Character out... MOC... ; ; texts are external, in TEXTS.MAC. ; ;mctbas: ; Base address texts ;crtxt: db cr,lf,0 ;MOC11t: db ' internal ' ; Fall thru to print "error" ;MOC10t: db 'error',0 ;MOC12t: db 'fatal',0 ;MOC13t: db 0a0h,0a0h,0a0h,0 ; A0=space + 80h: invert video (another time) ;MOC14t: db ' name of ',15h,' to ',0 ; Recursive "file" ;MOC15t: db 'file',0 ; Console character out och ; ; output character to con: ; ; processes many special characters, displays soft hyphens as i.v.-, ; does tab chars, displays misc controls as ^-letter, ; forces crlf one col short of scrn width, ; handles inverse video on high order bit. ; OCH:: PUSH PSW PUSH B ;get inverse video bit in b, masked character in a. Clear inv vid bit if none. OC1: ; Return here to restrip hi bit after substitution MOV C,A LDA HILITE## ; 80h if have hilighting, 0 if not *.945* ANA C ; Inv video bit, or zero if no inv video avail *.945* MOV B,A ; B0 is recombined before print. MOV A,C ANI 7FH ; Strip i.v. Bit to facilitate testing ; A=masked char, b=i.v. Bit, (c=caller's char). ;substitute display character for soft hyphens *1.18* CPI SHYPIN ; Inactive soft hyphen code JZ OCSHYP CPI SHYPAC ; Active (line break) soft hyphen code JNZ OCNSHY OCSHYP: LDA SOFHYC## ; Get install-patchable soft hyphen display character ; N.b. Normal patching has hi bit on so displays hilighted XRA B ; Recombine with caller's i.v. Bit JMP OC1 ; And go separate again ; N.b. Sofhyc patch must <> internal char, else inf loop here. OCNSHY: ;print rubout in file as tilde CPI RUBOUT JNZ OCNSH2 MVI A,'~' ; Print rubout in file as ~ (1 col) ;force crlf if necessary OCNSH2: CALL WIF ; Set CY if character won't fit on line CC WRAP ; Print + at end line, put cursor beg next line. ;tab: convert to spaces, counting them in next tabc slot CPI TAB JNZ NOTTAB ;convert tab to spaces here, counting them. TABLUP: MVI A,' ' CALL BXOC ; Print space with plus caller's inverse video bit (b) LDA COL## ANI 7 JNZ TABLUP ; Contiue till column divisible by 8 JMP OCXIT NOTTAB: ; Console chr out... och... ;test for control char CPI ' ' JNC NOTCTL ; Jump if space or greater CPI LF JZ NOTCTL ; Lf skips ^x stuff CPI CR JZ NOTCTL ; Cr skips ^x stuff ;ctl chrs: print ^, convert to letter in stk for printing. ;tab, cr, bs don't get here PUSH PSW ; Save actual char MVI A,'^' CALL BXOC ; Print the ^ with caller's i.v. Bit POP PSW ADI 40H ; Form 2nd character of ^x in a NOTCTL: ;print character - except tab handled above ; a contains char, or character changed to letter if control ; b contains inverse video bit CALL BXOC ; Ora b then output character ;return to caller OCXIT: POP B RETA: POP PSW ; Restore caller's PSW RET ; Print it, except tabs are done. ; Console character output... xoc BXOC: ; Entry used in och to output character (a) with i.v. Bit (b) CPI ' ' ; Controls that get here are output without i.v., so iv JC XOC ; ..is turned off before cr, lf, etc (gets auto turned ORA B ; ..on again if next non-control is iv), to be independ- ; ..ent of whether terminal's i.v. Ends at end line.3/21 ; ;output chr from a. Don't print ctl chrs as ^x, etc - that's done by och. ;this entry used to bypass spcl processing, as to print in col 80. ;keeps track of crsor position for simple cases (see och for the rest). ;processes inverse video from hi order bit of char; ; masks hi bit to terminal unless HIBIV on. ; ; all uses are internal. PSW really not preserved (colac can loose it). ; rearraged to put colac after joc so lin/col can be sent to xoc *1.25* ; XOC: PUSH PSW ; Save character to output. PSW may be returned altered. ; if memory mapped, colac will do output. ; inverse video is by hi order bit in memory. LDA MEMMAP## ; Non-0 if memory mapped video in use ORA A JNZ XOC8 ; Jump if mem mapped: skip most of this subr. ; terminal: switch to/from inverse video on terminal if hi order bit changes ; and buffer type-ahead POP PSW ; Character PUSH PSW ; Keep saving, to send to colac w/ hi bit *2.11* CPI ' ' ; Set CY if non-printing (cr's &c assumed not i.v.) CZ BUFPRN## ; Buffer any typed-ahead input char, keep printer with ; Busy test going, on blank only for speed. Saves PSW. CNC SETIV ; If printing char, check inverse video state ;terminal: strip hi bit unless HIBIV on. *.946* ; thus, if no hiliting installed, hi bit is zeroed; ; terminal hilighting invoked via ivon/ivoff always sends 0 hi bit; ; terminal hilighting via HIBIV (an unlikely combination, ; except with UCONO routine driving video board) passes hi bit. ; moved here (from joc) to not mask terminal function strings *2.11* PUSH H LXI H,HIBIV## ; Nz if hi-order bit hiliting installed (USER.MAC) INR M DCR M JNZ XOC2 ; Jump if hi bit hiliting in use ANI 7FH ; Else force hi bit of character to 0 XOC2: POP H ;send character (a) to terminal CALL JOC ; Send masked character ("just output char") *2.11* ; (formerly joc masked hi bit if HIBIV off) XOC8: ; Memmap case jmps here, character in stack POP PSW ; Get back char, including hi bit *2.11* ;do accounting, update screen image (=screen if mem mapped) ; JMP COLAC ; Do col/lin/screen image accnting (a), alter PSW, ; Also outputs character if memory mapped video in use. ; Nb fall thru ; Con character output lin/col/screen image maintenace colac ; nb fall in *1.25* ; ; for character in a, do some of the line and col keeping track stuff, and maintain ; screen image in ram (thus outputting character in memory mapped video mode). ; och has already: converted tabs to spaces, converted controls to ^x, ; outputted crlf>> on line wrap. Position cursor, clear screen, etc are ; handled by separate subrs that include screen image maintainance. ; COLAC: PUSH H PUSH PSW ; Nb PSW not preserved (see lscrol exit) 4/21/79 CALL UNCR ; Remove memmap cursor LXI H,COL## ; H points col ctr. Lin ctr is at HL-1 ;tst for spcial characters handled in this routine ANI 7FH ; Ignore i.v. Bit 3/15/79 CPI LF JZ COLLF ; Jump if line feed CPI CR JZ COLCR ; Jump if carriage return ; ; ordinary, 1-column character. Hl=.col. Store it, point next character postion. ORDCHR: INR M ; Add 1 to column number. CALL SWIN## ; Switch video board in - normally nop - saves BCDEHL. LHLD SCRPTR## ; Get screen image pointer POP PSW ; Get back caller's char, with inverse video flag PUSH PSW MOV M,A ; Store character. This updates our picture in memory ; of what's on screen of non-memory mapped crt, ; or outputs character to memory-mapped video display. CALL SWOUT## ; Switch video board out again INX H ; Point next character postion COLACX: ; Come here to exit from colac, with new screen pointer in HL. CALL PTRCR ; Set pointer (HL), place new cursor POP PSW RETH: POP H RET ; Console character out... colac subr... cr, line feed ; ; carriage return. Hl=.col. Set column 0, screen postion to beg line. ; COLCR: MVI M,0 ; Cr 0's column LHLD SCRLIN## ; Beginning of line is new screen pointer JMP COLACX ; ; line feed. Point next line, or scroll screen if bottom. ; HL=.col =.lin+1 ; COLLF: DCX H ; Lxi h,lin INR M ; Next line ;ck for off bottom of screen LDA HITE## ; # lines on screen DCR A ; Last line # is #lines -1 CMP M ; Is lin > ? JC LSCROL ; If yes, go scroll ;not off bottom, crsor position and line beg advance by "wid" chars. LDA WID## ; Get screen width (line length) PUSH PSW ; Copy in stk LHLD SCRLIN## ; Pointer to beginning of screen line CALL ADDHAH## ; Add a to HL SHLD SCRLIN## ; New beginning screen line POP PSW ; Lda wid LHLD SCRPTR## ; Pointer to crrent character position CALL ADDHAH## ; HL=HL+a. Advance to next line, same position JMP COLACX ; Go store scrptr from HL and exit ; ; line feed at bottom: crsor position stays same, scroll scrn image up 1. ; LSCROL: ; HL=.lin, lin has been inr'd. DCR M ; Restore lin to bottom of screen LHLD SCRN## ; Beginning of screen image POP PSW ; Clear stack of caller's PSW - not preserved ; Caller's HL still in stack DB (CPI) ; Skip the push h at entry to scrim ; Nb scrim follows. Skip into it to scroll entire (HL) screen up 1 line. ; Console display... scrim ; Nb skip in ; ; subr to move screen image starting at (HL) up one line ; (ie to "wid" lower addresses) ; SCRIM:: ; Skip in to to line feed; ; Called from WMV3 re doing line delete. ; note: line insert handled by copy-down in WMV3. PUSH H ; Lscrol enters here (via skip) with caller's HL in stack PUSH B PUSH D CALL UNCR ; Remove mem mapped video crsor XCHG ; Beg scroll area to DE as copy destiantion ;compute beginning+1 line LHLD WID## ; Width to l MVI H,0 ; 0 hi order PUSH H ; Copy in stk for use later DAD D ; Plus beginning, to HL as copy source ;compute # bytes to copy to bc XCHG ; Beg source to DE PUSH H LHLD SCREND## ; End screen: end soucre CALL SUBHDB## ; BC=HL-DE POP H XCHG ; Beg source HL, dest DE ;copy CALL BUFTYA ; Buffer typeahed: copy is time-cnsuming CALL SWIN## ; Switch board in - saves BCDEHL - normally nop CALL COPY## ; Move bc bytes from HL... To DE..., updating DEHL. ; DE now points first byte not stored into. CALL SWOUT## ; Switch video bd out - normally nop CALL BUFTYA ; Buffer typahead again ;blnk new last line of screen (image) POP H ; Width in l: # chars to blnk CALL SWIN## ; Switch in video board via user routine MVI A,' ' ; Get a space in a LBLK: STAX D ; Blnk a column INX D ; Point next DCR L ; Decrement loop via user routine JNZ LBLK ; Loop till done ;scrlin and scrptr do not change when sceen scrolls on line feed. CALL SWOUT## ; Return video board via user routine POP D ; Restore caller's registers: note order POP B POP H JMP RECR ; Put cursor back - same place, diffrnt character - & ret ; Console character output... joc ; ; routine to just output character to conso place, diffrnt character - & ret ; Console character output... joc ; ; routine to just output character to console ; ; called from xoc; also used for terminal control sequences (TERFUN.MAC). ; character is output via custom user subroutine or operating system. *.946* ; op sys output is via BIOS, because bdos character out does a constat, ; which buffers a character ahead, which gets lost on BIOS character in. ; JOC:: PUSH PSW PUSH B MOV C,A ; Character to c register ;use user's custom output routine if present LDA UCONO## ; Nz if routine is installed ORA A ; Nz to use UCONO JZ JOC5 ; If no custom routine, use operating system PUSH D ; Save remaining regs thru user routine PUSH H MOV A,C ; Character in a, incliding hi bit if hi-bit hilighting ;info possibly useful to subr in BCDEHL. *1.25* PUSH PSW ; Save thru offsu CALL OFFSU## ; Get # character posns from beg screen to beg line in bc, & POP PSW ; # charpos from beg scrn to present pos in DE. Terfun. LHLD LIN## ; Line in l, column in h, for UCONO to use *1.25* CALL UCONO## ; Call user routine (USER.MAC) if present. Character in a. ; stack = HL, DE, BC, PSW. JMP RHDBA## ; Go pop regs and ret ;use operating system JOC5: ; "couch" (next page) joins here. Character in c; b,PSW stacked. MVI A,BCOUT ; Offset into BIOS entry vector, for BIOS subr CALL BIOS ; Call BIOS, entry offset a POP B ; note: "BIOS" puts character in a also, so POP PSW ; it will work under cdos. RET ; Console character output, etc couch, clriv, setiv ; ; console output character (a), always going through operating system. *.946* ; ; used by alternate console printer driver (USER.MAC), ; and by "not installed" err msg (VARS.MAC) - must run before ws init. ; like joc but never uses custom console out subr, doesn't alter hi bit. ; COUCH:: PUSH PSW PUSH B MOV C,A ; Character in c JMP JOC5 ; Join "joc" ; ; entry to force terminal inverse video off. Nop if memmap. Clbrs a. ; ; call before clearing screen, erasing to eol, etc, etc, ; to eliminate strange terminal-dependent cases and to ; make sure our i.v. Flag stays in sync. ; CLRIV:: PUSH PSW XRA A ; Say i.v. Off CALL SETIV POP PSW RET ; ; subr to set inverse video to match sign bit of a, and update invsw. ; ; used in xoc and rblinc and xblink (WMC5.MAC). ; nop if already correct. Updates invsw only if ivon/ivoff not installed. ; SETIV:: PUSH H LXI H,INVSW## XRA M ; Test whether a change JP SETIVX ; Jump if already correct XRA M ; Restore and test sign: m if i.v. On MOV M,A ; Update invsw: only sign bit significant POP H ; Restore HL JM TIVON## ; Turn on, preserving PSW, nop if memmap JMP TIVOFF## ; Else turn off similarly ; Tivon, tivoff are nops if no ivon/ivoff strings. SETIVX: XRA M ; Restore a POP H RET ; Console output... UNCR ; ;subroutine to remove memory-mapped video crsor, e.g. Before scrolling. ; ; also sometimes used for esthetic reasons during processing, e.g. Find. ; redundant UNCR calls do no harm if character under cursor has not changed. ; UNCR:: PUSH PSW LDA INTCR## ; Nz if mem mapped video and direct (hi order ORA A ; .. Bit) cursor display (as opposed to crpos) JZ RETPSW ; Jump if mem mapped with direct cursor PUSH H ; No need to do cursor position PUSH B CALL SWIN## ; Switch video board in - normally nop LHLD SCRPTR## IF TRS80 ; only do test if TRS80 is equated ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ LDA TRSCRS## ; Is the TRS80 cursor routine flagged ? $ ORA A ; <>0 then do TRS80 routine $ JNZ TRSCOF## ; Restore the inverse video character. $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF MOV A,M ; Crrent character ANI 7FH ; Clear inverse video/crsor bit MOV B,A LDA CRIV## ; Get former (background) value ORA B ; Combine IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ UNCR2:: ; Label needed for TRS80 routines $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF ; MOV M,A CALL SWOUT## ; Switch video board out - normally nop XRA A STA CRUP## ; Say cursor not now displayed (see UNCR) 5/6/80. POP B RETHA: POP H RETPSW: POP PSW RET ; Console output... RECR, stcr ; ;subr to set scrptr from HL and update mem mapped crsor. ; removes old crsor, sets new, then updates scrptr. ; ; called from tcrsor. ; STCR:: CALL UNCR ; Remove cursor from old location PTRCR: ; Here to set scrptr from HL, RECR. Used at colac exit. SHLD SCRPTR## ; Set new cursor location ; Fall into RECR to put cursor here ; ;subrotine to display cursor on mem mapped video screen, if not now displayed. ; RECR:: PUSH PSW LDA INTCR## ; Nz if mem map display with direct internal ORA A ; .. Cursor display via hi order bit JNZ RECR3 ; Exit if cursor display is via "crpos" subr XTRPOS: LDA MEMAPV## ; Test for memory mapped video board ORA A ; Not zero if memory mapped JZ RETPSW ; Jump if not memmaped ; Memory mapped<>0 & hibcur=0 PUSH B PUSH D PUSH H ; H,d,b,PSW,ret add. On stack LHLD LIN## ; Current line in l column in h CALL CRPU## ; Use user cursor routine for cursor POP H POP D POP B POP PSW ; Adjust the stack RET ; if HIBCR and INTCR were advertized as 0ffh, not just NZ, ; could cma and combine above test with next. ; nop if already displayed - else inverts video again. , not just NZ, ; could cma and combine above test with next. ; nop if already displayed - else inverts video again. 5/6/80 *1.34* ; case: removed during processing, then cursor moved by lower subr, ; then caller replaces. E.g. Find: FINRP.MAC removes ; while search in process, & control can get to dwmes. ; if this causes any bugs, might be that cursor doesn't appear ; at all, or doesn't move to correct place. ; ; display cursor on memory mapped machines RECR3: PUSH H LXI H,CRUP## ; Flag ff if displayed MOV A,M ORA A JNZ RECRX DCR M ; Mvi m,0ffh CALL SWIN## ; Switch video board in - normally nop LHLD SCRPTR## IF TRS80 ; Special routines for TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ LDA TRSCRS## ; Test for TRS80 video flag set $ ORA A ; <>0 then TRS80 $ JNZ TRSCON## ; Turn on the cursor $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF MOV A,M ; Get character under crsor XRI 80H ; Complement inverse video/crsor bit MOV M,A XRI 80H ; Get back the character's bit ANI 80H ; Isolate STA CRIV## ; Save background for removing cursor. ; Nb with this method reduncant RECR's fail -- hence CRUP. IF TRS80 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ RECR2:: ; Label needed for TRS80 routine. $ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDIF CALL SWOUT## ; Switch video board out - normally nop RECRX: POP H POP PSW RET ; END