; "WYSE50.Z80 - TeleVideo/Wyse Screen Driver - rev 3/14/87" ; no library/include files are required. WYSE equ 0ffh TVI equ 000h .z80 .xlist ; ; Assemble with ZASM and link with ZLINK as follows: ; ; ZASM WYSE50 ; ZLINK WYSE50 $R3F80 ; REN WYSE50.DRV=WYSE50.COM ; ; vers 0.8 - bmm 3/14/87 -- moved terminal-specific strings to ; immediately follow jmp tables, to permit patching for minor ; variants of the Wyse/TVI family ; ; vers 0.7 - bridger mitchell 3/2/87 for testing on Wyse 50 ; ; changed to cursor addressing on screen-restore to prevent linewrap in ; final column. ; fixed cursor-restore following screen-restrore ; ; vers 0.4 changes: ; ; AUTOFL FALSE ; ^J not ^V for DOWN ; ; vers 0.3 - if updating, set ASCVER string below ; ; Screendriver for BackGrounder ii ; BackGrounder ii is Copyright 1986 ; by Bridger Mitchell and Plu*Perfect Systems ; ; Assumes: ; 80 column mode and standard terminal settings. ; ; Important note: ; ; Terminals transmit the ~2K bytes of screen characters at ; high speed. The screendriver calls the bios for each character; ; if the bios cannot process characters fast enough, some may get ; "lost", with a garbled screen restore, or worse, a hung BGii. ; ; The best arrangement is handshaking between the bios and the ; terminal -- using "hardware handshaking" on the DTR/CTS lines -- ; or software handshaking with XON/XOFF characters. This handshaking ; is for characters sent TO the computer (there may be additional ; handshaking for characters sent FROM the computer). ; ; If the terminal has a "slow-transmit" option, experiment with ; that (usually an ESC sequence) to introduce delay between each ; character sent. ; ; If those solutions aren't available, slow the serial baud rate ; down until the screen save and restore work reliably. You should ; do the test with any interrupt devices that might delay character ; processing. ; ; ; HISTORY ; ; 1/7/87 Modified for the TeleVideo line of terminals from ; SCRK83.Z80 by Kevin Belles and Dan Baker. ; ;v0.2 1/20/87 Revised and edited for TVI and Wyse terminals, ; Bridger Mitchell. ; ;v0.3 1/21/87 Tested with TVI 955. Shortened screen init ; string, fixed some Bridger typos, applied some ; bug fixes as recommended by Bridger. Used ESC + ; instead of control-Z for clear screen - I'm not sure ; which older TVIs or Wyses can use this. This ; sequence clears the CRT and homes the cursor like ; control-Z and ESC *, but fills the screen memory ; with spaces intead of nulls. Note that there is an ; issue to resolve regarding the ZCPR3 and P*PS termcaps ; which may use clear-screen and clear-to-end-of-line ; strings incompatible with proper performance of this ; driver with programs that rely on termcaps. The driver ; seems to work well with or without auto-flip, although ; handling of inverse video (esc G4/esc G0) does not seem ; to be quite right yet. Otherwise swaps seem to be ; 100% accurate with no handshaking in either direction ; on an SB180 running at 19,200 without any screen- ; send "wait states" ("XDLY NO" on the SET-UP bottom ; status line). The SB180 has very little overhead in ; the BIOS console input, so some systems may require ; higher XDLY values to keep up with the terminal. ; Bruce Morgen ; ; ; Although to this date untested, the documentation for ; the Soroc IQ-120 and IQ-140 indicates that this driver ; will work with AUTOFL set to FALSE. ; The CUT commands available in this implementation ; are: ; HOME Homes the cursor H,h ; MARK Marks region to cut X,x, ; UNMARK Undo mark U,u ; CANCEL Abort CUT ^C ; ; ; This screen driver can be modified relatively easily ; for any terminal that supports direct cursor addressing ; and screen-transmit functions. To modify the driver ; for your terminal, perform the following steps: ; ; 1. Modify the direct-cursor-addressing routine at ; label Getcu: to match your terminal's protocol. ; ; 2. Modify the routine Savpag: to match your terminal's ; screen-transmit protocol. ; ; 3. Modify the routine Respag: to match your terminal's ; character-attribute protocol (rev. video, blink, etc.). ; ; 4. Replace the escape sequences near the end of this ; file with the appropriate escape strings for your ; terminal. Each string must end with a zero. ; ; 5. If your terminal has cursor-arrow keys that transmit ; ONLY ONE BYTE, set the equates for LEFT, RIGHT, UP, and ; DOWN to match your arrow keys, and set the equate WSFLAG ; to FALSE. If you don't have arrow keys, or if your arrow ; keys transmit more than one byte, set the equate WSFLAG ; to TRUE, and use Wordstar ((c) Micropro) arrow codes. ; ; 6. If you set WSFLAG to FALSE, edit the JOTPAD BANNER ; at the end of this file to match your terminal. ; ; 7. If your terminal either supports multiple pages or ; the ability to shut off screenwrap via escape codes, ; set AUTOFL true and modify the appropriate escape codes at the ; end of this file. If not, setting AUTOFL equate to ; FALSE will stop the screen restore functions for the ; BGII FLIP AND SWAP functions at the next to the last ; character on the screen, thus avoiding any problems ; with screenwrap scrolling the screen. This, however, ; means that the last character on a screen can be used ; by CUT and PASTE, but will not show on a SWAP or FLIP. ; ; 8. Assemble and link at 3F80 Hex. ; ; 8. Follow the Backgrounder instructions and install ; the screen-driver in your LOADBG.COM and load ; Backgrounder. ; ; See the comments at the appropriate sections of this ; program for further hints regarding modification. ; ; ; FALSE EQU 0 TRUE EQU NOT FALSE ; ; Set WSFLAG to TRUE if WS-like commands to be used in JOT ; WSFLAG EQU FALSE ; set TRUE to use Wordstar- ; like cursor keys AUTOFL EQU FALSE ; Set false if your terminal ; does not support pageflip ; CONST EQU 0 CONIN EQU 0 CONOUT EQU 0 Outch EQU 0 Puts EQU 0 Bwrch EQU 0 Bflush EQU 0 ; ; ASCII equates ; BELL EQU 07H BS EQU 08H CR EQU 0DH LF EQU 0AH ESC EQU 1BH SPACE EQU 20H DEL EQU 7FH ;========================= ; START: ; IF WYSE DB 'Wyse 50/60 Screendriver, v ' ENDIF IF TVI DB 'TVI 910/925/950/955 Screendriver, v ' ENDIF ASCVER: DB '0.8',0 IDLEN equ $ - START DS 80H-IDLEN ; ; ;------------------------------------------------------------ ; ; ; ; MODULE ENTRY HEADER ; ; EXTERNAL ADDRESSES, supplied by loader ; JJcons: JP CONST ; BIOS console status JJconi: JP CONIN ; BIOS CONIN JJouta: JP Outch ; A to CONOUT, preserving BC,de,hl JJputs: JP Puts ; HL-string to CONOUT, NUL/bit-7 term. ; ; preserving BC,DE,HL JJbrdc: JP 0 ; buffered read char from cut-swp JJbwrc: JP Bwrch ; buffered write char to cut-swp JJbflu: JP Bflush ; flush (write) buffer ; ; INTERNAL ENTRY POINTS ; Savscr: JP Savpag ; save screen Resscr: JP Respag ; restore saved screen Lastnb: JP Lstnbl ; last non-blank char in rows 1-24 Dmpchr: JP Retnch ; return next screen char Dmpcur: JP Retncu ; return buffer cursor Dmpatt: JP Retnat ; return next screen attribute Setmrk: JP Stmrks ; set region marks, move cursor Cutrg: JP Docut ; cut region Pastrg: JP Dopaste ; paste region Ininpd: JP Ininot ; initialize jotpad Putnpd: JP Putnch ; put char to jotpad ; ; patchable byte IF AUTOFL AUTOFQ: DB 0FFh ; Terminal supports auto-flip mode ELSE AUTOFQ: DB 0 ; it doesn't, don't save/send row24,col80 ENDIF ;AUTOFL ; ;************************************* ; ; TERMINAL-SPECIFIC data ; ; Screen parameters ; NCOLS EQU 80 NROWS EQU 24 ; ; ; CUT command characters ; HOME EQU 'H' ;put cursor to home MARK EQU 'X' ;set mark at cursor UNMARK EQU 'U' ;abort cut operation CANCEL EQU 'C'-40H ;abort cut operation ; ; TERMINAL-SPECIFIC EQUATES ; IF WSFLAG ; ; Cursor controls (WordStar-like) ; LEFT EQU 'S'-40H RIGHT EQU 'D'-40H UP EQU 'E'-40H DOWN EQU 'X'-40H INSERT EQU 'V'-40H DELETE EQU 'Y'-40H ; ELSE ; ; Change these to match your arrow keys: ; LEFT EQU 'H'-40H RIGHT EQU 'L'-40H UP EQU 'K'-40H IF WYSE DOWN EQU 'J'-40H ;wyse ENDIF IF TVI DOWN EQU 'V'-40H ;tvi is ^V ENDIF ; ENDIF ; WSFLAG ; ; ; Escape code definitions and support ; CLS EQU '+' ; Clear screen to SPACES CURS EQU '=' ; Cursor Positioning: ESC '=' CRBIAS EQU 20H ; Bias for cursor positioning CDIMON EQU ')' ; Turn on half-intensity/protect mode CDIMOF EQU '(' ; Turn off half-intensity/protect mode FLON EQU 'v' ; Turn on auto flip FLOFF EQU 'w' ; Turn off auto flip PBACK EQU 'J' ; Back page ATTRMK equ 'G' ; indicates attribute character follows HOMECH equ 1Eh ; Home the cursor ; EOLMRK equ 1Fh ;end of line mark, EOSMRK equ 0Dh ;end of screen mark ; ; Flag bits in status register for screen save/redraw ; ;;TOSCR$ EQU 0 ; Send to screen GRAPH$ EQU 1 ; Graphics sequence active DIM$ EQU 2 ; Half-intensity sequence active ESCMOD EQU 3 ; ESCape sequence ; ;******************************** ; ; each of these fields is 4 bytes, to permit patching w/o reassambly ; ; Cursor lead-in and command strings ; Be sure to end each command string with a 0. ; Zcurs: DB ESC,CURS ; Set cursor to colrow: DB ' ' ; row,col - modified in-line DB 0 ; must have following NUL ; Iniscr: DB ESC,CLS,0,0 ; Home and clear screen ; SCRBOT: DB ESC,CURS ; put cursor at bottom of screen DB CRBIAS+23 ; Row 23 (24th) DB CRBIAS+79,0 ; Column 79 (80th) ; Sndcur: DB ESC,'?',0,0 ; Return cursor position Sndpag: DB ESC,'7',0,0 ; Send all from top to cursor position ; HomeX: DB HOMECH,0,0,0 ; home cursor LeftX: DB LEFT,0,0,0 ; Move cursor left RightX: DB RIGHT,0,0,0 ; Move cursor right UpX: DB UP,0,0,0 ; Move cursor up DownX: DB DOWN,0,0,0 ; Move cursor down ; Inslin: DB ESC,'E',0,0 ; Insert line Dellin: DB ESC,'R',0,0 ; Delete line ; DIMON: DB ESC,CDIMON,0,0 ; Half-intensity mode on DIMOF: DB ESC,CDIMOF,0,0 ; Half-intensity mode off ; ATTSEQ: DB ESC,'G',0,0 ; Prefix for most TeleVideo screen attributes ; PROTON: DB ESC,'&',0,0 ; Protected mode on (925/950) PROTOFF:DB ESC,27H,0,0 ; Protected mode off (TV925/950) ; ENFLIP: DB ESC,FLON,0,0 ; Enable auto flip mode DISFLIP:DB ESC,PBACK ; go back a page and DB ESC,FLOFF,0 ; disable auto flip mode db 0,0,0,0 ; ;======================================== ; Ininot: ; << Generic >> ; ; Initiate Jotpad - clear screen, print banner. ; LD HL,BANNER JP JJPuts ; ;======================================== ; Putnch: ; << Generic >> ; ; Put char in A to jotpad (screen) ; Convert CR to CRLF, DEL to rubout. ; CP CR LD HL,zcrlf ; convert CR to CR,LF JP Z,JJPuts CP DEL LD HL,zrub JP Z,JJputs ; IF WSFLAG ; Use WS-like commands? ; CP LEFT JR Z,Wrtlef CP RIGHT JR Z,Wrtrit CP UP JR Z,Wrtup CP DOWN JR Z,Wrtdwn CP DELETE JR Z,Wrtdel CP INSERT JP NZ,JJouta ; ...fall thru LD HL,Inslin ; ESC code for Insert line DoWrt: JP JJputs ; send string ; Wrtlef: LD HL,LeftX ; Code for move cursor left JR DoWrt ; Wrtrit: LD HL,RightX ; Code for move cursor right JR DoWrt ; Wrtdwn: LD HL,DownX ; Code for move cursor down JR DoWrt ; Wrtup: LD HL,UpX ; Code for move cursor up JR DoWrt Wrtdel: LD HL,Dellin ; Code for Delete line JR DoWrt ; ELSE ; not WSFLAG ; JP JJouta ; echo key to terminal ; ENDIF ; WSFLAG ; ;======================================== ; Retncu: ; << Generic >> ; ; Return buffer cursor as row/col. ; ; ret: D = binary row, E= binary col ; L = ascii row, H = ascii col (for shld ...) ; LD HL,(Bcursor) ; ; Convert offset to col/row. ; exit: D = binary row, E = binary col ; H = ascii col, L = ascii row <-- NOTE ORDER ; Off2cr: LD B,0 ;convert to row,col LD DE,-NCOLS Off2c1: ADD HL,DE JR NC,Off2c2 INC B ;row count++ JR Off2c1 Off2c2: LD DE,NCOLS ADD HL,DE LD A,L ;col LD E,A ;binary col in E LD D,B ;binary row in D ADD A,CRBIAS ; + bias LD H,A ;H = ascii col LD A,B ;row ADD A,CRBIAS ; +bias LD L,A ;L = ascii row RET ; ;======================================== ; Dopaste: ; <> ; ; Paste the last-cut region onto active screen at the current cursor. ; ; 1. Get previously-cut region from external routine ; 2. Send chars to screen, avoiding boundary overflows. ; ; LD B,4 ;read 4 data bytes Dopas0: PUSH BC CALL JJbrdc POP BC DJNZ Dopas0 ; LD B,A ;4th byte is # rows PUSH BC CALL Crs2hl ;get current cursor's row/col to hl POP BC ; ; loop over rows ; Prowlp: PUSH BC PUSH HL LD E,L ;E = col no. PUSH DE CALL Stcrshl ;set cursor at H,L Pcollp: CALL JJbrdc ;read char from cut-swp CP CR JR Z,Prend LD C,A ;save char POP DE ;check for off screen LD A,E CP NCOLS INC E PUSH DE ;row/col to stack CALL C,Sendc ;to CONOUT, unless off edge JR Pcollp ; Prend: POP DE ;clear row/col POP HL POP BC INC H ;bump row LD A,H ;check for off bottom of screen CP NROWS ; Use NROWS if 25th line scrolls JR NC,Pxit DJNZ Prowlp Pxit: XOR A RET ; ;======================================== ; Docut: ; << specific >> ; ; Cut rectangular region defined by keypresses. ; 1. Parse keypresses to move cursor and mark corners. ; Highlight region as cursor is moved. ; 2. Send the marked region, row-wise to external routine. ; Append CR after each row. ; ; Data structure is: ; size (word) ; # columns (byte) ; # rows (byte) ; row 1 ; CR ; row 2 ; CR ; .... ; XOR A LD (Mrkcnt),A ;init for next time ; ; set ctcols = # cols, ctrows = # rows ; (assumes mark2 is SE of mark1) ; Cornrs: LD DE,(MARK1) LD HL,(MARK2) LD A,H ;# rows = 1 + mark2row -mark1row INC A SUB D LD H,A LD A,L ;# cols = 1 + mark2col -mark1col INC A SUB E LD L,A LD (Ctcols),HL ; ; cut rectangle [mark1...mark2] & copy to buffer ; append CR at end of each row ; EX DE,HL PUSH HL ;mark1 CALL Wrpara ;write parameters POP HL ;mark1 CALL Rc2off ;convert to scr addr LD A,(Ctrows) ;get # rows LD B,A ; ; write the cut region to external buffer ; DCrwlp: PUSH BC ;(+1 PUSH HL ;(+2 LD DE,Buf ;fetch from screen buffer ADD HL,DE ; ; write 1 row of cut region to external buffer ; LD A,(Ctcols) LD B,A ;b = # cols CUTLP: PUSH BC PUSH HL LD C,(HL) CALL FLTRC ;filter out video/graphics encoding CALL JJbwrc POP HL POP BC INC HL DJNZ CUTLP LD C,CR ;append CR to each row CALL JJbwrc POP HL ;(+1 POP BC ;(+0 LD DE,NCOLS ;bump to next row ADD HL,DE DJNZ DCrwlp ; and loop JP JJbflu ;flush the write buffer ; ; write parameters: size, # cols, # rows to swp file ; DE contains CTCOLS on entry ; Wrpara: LD B,D ;# rows LD D,0 INC E ;+1 for CR LD HL,0 ;accum. Wrpar0: ADD HL,DE DJNZ Wrpar0 LD (Ctsize),HL LD B,4 ;write 4 bytes of parameters LD HL,ctsize ; ; buffered write B chars at hl ; Bwrthl: PUSH BC PUSH HL LD C,(HL) CALL JJbwrc POP HL POP BC INC HL DJNZ Bwrthl RET ; ;======================================== ; Lstnbl: ; << Generic >> ; ; Find last non-blank line (1-24 only) in current scr buffer. ; 8-bit values (reverse video) are masked to see if they are valid chars. ; If B=0ff, save screen first. ; ; Ret: H=row, L=col of last non-blank char in rows 1-24 ; INC B CALL Z,Savpag LD BC,NROWS*100H+NCOLS ;b=# rows, c=# cols LD DE,Buf LD HL,0 Lstlp: LD A,(DE) AND 7FH ; Turn off any reverse video CP SPACE+1 ;don't count cntl chars or SPACE JR C,Lst1 CP DEL ; or DEL JR NC,Lst1 LD (savrc),HL Lst1: INC DE INC L DEC C JR NZ,Lstlp ;loop over cols INC H LD L,C ;0 LD C,NCOLS DJNZ Lstlp ;loop over rows savrc EQU $+1 LD HL,0 ;HL = last non-blank RET ; ;------------- Generic Support Routines -------------- ; Xring: LD C,BELL ; ; send C to screen, exit Z, no CY ; Sendc: LD A,C ; send A to screen, exit Z, no CY ; (this will scroll, however!) ; Send: CALL JJouta XOR A ;Z, no CY RET ; ;============================================ ; E N D O F G E N E R I C C O D E ;============================================ ; Stmrks: ; ; Move cursor and set marks. Return CY clear until exit. ; ; 1. move cursor, until: ; 2. 'X' = set 1st mark ; turn on hiliting, set mark, keep cursor at mark ; 3. move cursor right/down only ; 4. 'X' = set 2nd mark ; turn off hiliting, set 2nd mark ; exit CY (done) ; 5. cntl-C = CANCEL. ; turn off hilighting, set CY, exit ; ; PUSH AF CALL GETCU ; Where am I? LD (CUSAV),HL ; Put row at CUSAV, col at CUSAV+1 POP AF AND 7FH CP CANCEL ; Cancelling? JR Z,Abort CP LEFT ; Move left? JP Z,Goleft CP UP ; Move up? JP Z,Goup CP RIGHT ; Move right? JP Z,Gort CP DOWN ; Move down? JP Z,Godn CP CR ; Start CUT? JR Z,StmrkA AND 5FH ; Convert to Ucase CP MARK ; Start CUT? JR Z,StmrkA CP HOME ; Home the cursor? JR Z,Gohome CP UNMARK ; Undo a mark? CALL Z,Abort CALL Z,ResPag ; redisplay page XOR A ;no action RET ; StmrkA: LD HL,mrkcnt ;if no mark yet set LD A,(HL) OR A LD (HL),1 JR Z,SMARK1 ;..set mark1 CALL SMARK2 ;else set mark2 Mrkxit: XOR A LD (Mrkcnt),A ;init for next time SCF ;CY = all done RET ; Abort: CALL Normal ;restore normal video JR Mrkxit ; ;------------------------------------------- ; ; Set 1st mark, turn on half-intensity (protect mode), ; but don't move cursor. ; SMARK1: CALL Crs2hl LD (mark1),HL LD (mark2),HL LD (curcol),HL ;L->curcol,H->currow PUSH HL CALL HalfI ;Half-intensity on ; ; Blink the marked char. Cursor may itself be off, or solid. ; POP HL ;mark1 LD A,1 ;blink 1 char LD (colct),A LD (rowct),A PUSH HL CALL Showro POP HL JP Stcrshl ; ; set 2nd mark, restore normal video, set CY ; SMARK2: CALL Crs2hl LD (mark2),HL CALL Normal ; restore normal video SCF ;CY = all done RET ; ;-------------------------------------------- ; Gohome: LD HL,HomeX ;convert to video driver's cntl. char JR Ckmcnt ; Goup: LD A,(cusav) ; Get row CP CRBIAS ; Top of screen? RET Z LD HL,UpX ; Code for UP JR Ckmcnt ; Goleft: LD A,(cusav+1) ; Get column CP CRBIAS ; Left edge of screen? RET Z LD HL,LeftX Ckmcnt: LD A,(mrkcnt) OR A RET NZ JP JJputs ; ; do a cursor move until 1st mark has been set ; ; move cursor right ; Gort: LD A,(cusav+1) ; Get column CP CRBIAS+NCOLS-1 ; Right edge of screen? RET Z LD HL,RightX CALL JJputs ; Position cursor LD A,(mrkcnt) OR A ; Quit here if no mark set RET Z ; ; and hilite marked column ; Gort1: LD HL,mark2 LD A,NCOLS-2 CP (HL) Jcring: JP C,Xring INC (HL) ;bump 2nd mark-row LD HL,curcol ;bump col INC (HL) LD L,(HL) LD A,(mark1+1) ;top row LD H,A ;h=row, l=col for col to hilite Rowct EQU $+1 LD B,0 ; loop over each row in cut region ; Gorlp: PUSH BC PUSH HL ;save binary row/col LD A,1 ;display 1 char in each row CALL Showhi POP HL POP BC INC H ;next row DJNZ Gorlp LD HL,colct ;prepare to bump col cnt & exit JR Inrmbs ; ; move cursor down ; Godn: LD A,(cusav) ; Get row CP CRBIAS+NROWS-1 ; Bottom line? RET Z LD HL,DownX CALL JJputs ; Move cursor down LD A,(mrkcnt) OR A RET Z ; quit here if no marks ; ; and hilite marked row ; Godn1: LD HL,mark2+1 ;row LD A,NROWS-1 CP (HL) JR C,Jcring INC (HL) ;bump 2nd mark-col LD HL,currow ;bump row INC (HL) LD H,(HL) LD A,(MARK1) ;left col LD L,A ;h=row,l=col for row to hilite CALL Showro ;display 1 cut row LD HL,rowct ;bump row cnt Inrmbs: INC (HL) ; and exit LD HL,(curcol) JP Stcrshl ; ;-------------- ; if down: set cur at next row, left col ; send partial row ; rowcnt++ ; BS (back up 1) ; ; if right: set cur at toprow, next col ; send partial column ; colcnt++ ; ; enter: H = binary row, L= binary col ; Showro: Colct EQU $+1 LD A,0 ; ; Fetch A chars at H=binary row, L=binary col from buffer. ; Put chars to screen, setting BLINK attribute. ; Showhi: PUSH AF PUSH HL ;-- ; Positioned on bottom line? LD A,NROWS-1 SUB H LD C,A ; If so, C=0 LD A,NCOLS-1 ; Last column SUB L OR C ; If we are at bottom right-hand corner, A=0. Save it in LASTCH LD (lastch),A CALL Stcrshl ;-- POP HL ;-- CALL Rc2off LD DE,Buf ;fetch from screen buffer ADD HL,DE POP AF ;#chars LD B,A Showlp: LD C,(HL) ;fetch char from buffer CALL FLTRC ;filter out video/graphics codes PUSH HL PUSH BC ; ; If at bottom-right corner, don't echo character because screen ; might scroll. Otherwise (LASTCH > 0), echo character. Half- ; intensity mode is on, so echoed characters will be dimmer. ; LD A,(lastch) OR A ; Set flags CALL NZ,Sendc ; put to screen if not bottom-right corner POP BC POP HL INC HL DJNZ Showlp OR A ;clear CY RET ; ;======================================== ; Retnch: ; ; Return next screen char from buffer. ; ; enter: ; d = row, e = col ; b = FF ==> read screen ; c = FF ==> set bufptr ; exit: ; A = char, CY set if good ; DE -> row,col of next char, HL -> buf of next char ; CY clear if out of range ; ; This routine can be called to get successive chars from ; buffer as long as caller preserves hl,de and sets b=c=0. ; XOR A CALL Stdump RET NC LD A,(HL) ; get char CALL FILTER INC HL ; bump bufptr SCF RET ; ;-------------------- ; ; ret: NC if out of range ; else hl-> buffer char ; Stdump: INC B JR NZ,Stdum0 PUSH BC ;b == 0ff -> read screen PUSH DE PUSH HL CALL Savpag POP HL POP DE POP BC Stdum0: INC C JR NZ,Conv4 ; ; enter: D = row, E = col ; set: hl -> buffer address, cy set, preserve de ; ret: CY clear if error (off screen) ; LD A,D ;c == 0ff -> set bufptr CP NROWS+1 JR NC,ConBAD LD A,E CP NCOLS JR C,ConvOK ConBAD: XOR A ;out of range , ret NC RET ; ConvOK: PUSH DE ; Preserve col/row EX DE,HL CALL Rc2off ; Convert to Offset in HL LD DE,Buf ; ..from buffer base ADD HL,DE POP DE ; ..restore col/row ; ..fall thru.. Conv4: INC DE ;bump col LD A,E CP NCOLS RET C LD E,0 ;end of row, set col = 0 INC D ;and bump row LD A,D CP NROWS+1 RET ;NC if out of range ; ;======================================== ; Retnat: ; ; Return next screen attribute from buffer. ; ; enter: ; d = row, e = col ; b = FF ==> read screen ; c = FF ==> set bufptr ; exit: ; A = attr, CY set if good ; DE -> row,col of next char, HL -> buf of next char ; CY clear if out of range ; XOR A ;clear CY RET ; ;======================================== ; Savpag: ; << Specific >> ; ; The strategy is similar to the H19 driver. Store regular ASCII ; characters sequentially. Convert ESC sequences to an encoded ; representation of half-intensity or attributes. Half-intensity ; is bracketed by protect-mode on, protect-mode off; bit 7 is ; used for each char in that mode. Attributes occupy one char. ; space on the terminal; their ESC sequence is converted to a 1-byte ; control char (thus distinguishing it from an ascii printing char). ; ; Discard the end-of-line mark character, and the end-of-screen ; character. Thus, the buffer is 1:1 to the characters on the screen. ; ; Save screen to buffer. ; CALL Getcu ; Get ASCII row/col cursor LD (savarc),HL ; save it ; ; Get lines 1-24 ; ; TeleVideo transmits from home to current cursor position, ; so first move cursor to end of screen, then tell terminal ; to send region. ; LD HL,SCRBOT ; last position on screen CALL JJputs LD HL,PROTON ; Protected mode on, to CALL JJputs ; identify video attributes LD HL,Sndpag ; Tell terminal to send 1-24 CALL JJputs LD HL,Buf ; Start of screen buffer ; ; Get region to the HL buffer. C register holds encoding status ; for protected (half-intensity) and attribute modes ; Getrgn: LD C,0 ; Reset all flags Getrg1: LD B,NCOLS+1 ; Column counter Getplp: PUSH HL PUSH BC CALL JJconi ; Get a char POP BC POP HL CP EOLMRK ; check eoln char JR Z,Geteol CP EOSMRK ; End-of-screen char JR Z,Geteos ; Done receiving screen. CP ESC ; Is this an escape? JR Z,Getpl1 BIT ESCMOD,C ; Was last char=ESC? JR NZ,Getpl2 ; ..jump if so ; ; Set high bit of character if half-intensity video mode is on. ; Getplr: BIT DIM$,C JR Z,Getpl0 ; Jump if not half-intensity SET 7,A Getpl0: DEC B ; decrement col. count LD (HL),A ; Save screen character INC HL ; Bump ptr.. JR Getplp ; ..loop ; Geteos: call Sp2eol ; fill out final line with spaces Unprot: LD HL,PROTOFF ; TV925 protected mode off. JP JJputs ; Geteol: CALL Sp2eol ; fill out with spaces if necessary JR Getrg1 ; loop to next row ; ; fill out a short line with spaces. If clear-to-end-of-line ; or screen filled screen line with NULS, the nuls are not ; sent. ; Sp2eol: LD A,' ' JR Sp2eo2 Sp2eo1: LD (HL),A INC HL Sp2eo2: DJNZ Sp2eo1 RET ; Getpl1: SET ESCMOD,C ; Flag next as argument JR Getplp ; Getpl2: CP CDIMOF JR Z,Doff CP CDIMON JR Z,Don ; Reset esc & loop ; ; NOTE: ; All screen attributes (except half-intensity/protect) are ; represented by the Televideo 925 as ESC,G,(0-F). These ; actually take up a character position on the screen, so ; we'll convert them into special (0-F binary) codes which will occupy ; one byte (each) in the screen buffer. ; ; The encoding is: ; Set bit 7 if char is in a protected (half-intensity) region ; Encode attributes as 0-F (binary) ; CP ATTRMK ; 'G' JR NZ,Getpl3 ; Ignore it. PUSH HL PUSH DE PUSH BC CALL JJconi ; Get next character in string POP BC POP DE POP HL AND 0FH ; Convert to 0-F JR Getplr ; ... and put it in the buffer. ; Don: SET DIM$,C JR Getpl3 ; Doff: RES DIM$,C ; Getpl3: RES ESCMOD,C JR Getplp ;======================================== ; Respag: ; << Specific >> ; ; Restore saved screen from buffer. ; LD HL,iniscr ; Clear screen and Home cursor CALL JJputs CALL Unprot ; Set Unprotect mode ; LD A,(AUTOFQ) ; If autoflip is used OR A LD HL,ENFLIP ; Enable page flip CALL NZ,JJputs ; ; To screen, lines 1-24 ; LD HL,Buf xor a ; set initial row number Putsc1: ld c,a ; using normal video, C flags = 0 ; Putlp: LD (Linno),A ; Store binary line number ; LD D,A ; Save in D LD B,NCOLS ; chars per line ; LD A,(AUTOFQ) ; If autoflip is used OR A JR NZ,Putlp0 LD A,D ; check row number cp NROWS-1 ; Are we at the last line yet? JR Z, Putlpd ; Z - yes - don't send final char of last line ; Putlp0: PUSH HL ; Save buffer address CALL Sndprc ; Send processed char.. CALL Send ; ..to screen POP HL INC HL Putlpd: DJNZ Putlp0 ; Loop on line ; LD A,(Linno) ; Bump line number inc a cp NROWS ; Any more lines? JR Z,PutlpZ ; ; use cursor addressing here, so line won't wrap in final column ; PUSH AF PUSH BC PUSH HL LD H,A ;binary row num LD L,0 ;binary col num CALL Stcrshl ;set cursor to next row, col 0 POP HL POP BC POP AF JR Putlp ; ; All char's now written to screen. ; PutlpZ: LD A,(AUTOFQ) ; If autoflip is used OR A LD HL,DISFLIP ; Back up to prev. page and disable page wrap CALL NZ,JJputs ; LD HL,(savarc) ; Put saved ascii row/col into string LD (colrow),hl LD HL,zcurs ; Restore cursor CALL JJputs JP Normal ; ..and return to normal video ; ; Process character sending appropriate ESCape sequences ; and setting flags. ; Sndprc: LD A,(HL) PUSH AF BIT 7,A JR NZ,Putdim ; Jump if half-intensity BIT DIM$,C CALL NZ,PnoDim JR Sndpr2 ; Putdim: BIT DIM$,C CALL Z,Pdim Sndpr2: POP AF PUSH AF AND 70H ; Special attribute code? JR NZ,Sndpr3 ; NZ - no, its >= 20h POP AF AND 0FH OR 30H ; Make it 30H-3FH PUSH AF ; Save it... LD HL,ATTSEQ ; Send attributes flag first. CALL JJputs Sndpr3: POP AF ; Restore character. AND 7FH ; Make ASCII RET ; ; Update the flag ; Pdim: SET DIM$,C HalfI: PUSH HL ;half-intensity video LD HL,DIMON HalfI2: CALL JJputs POP HL RET ; PnoDim: RES DIM$,C Normal: PUSH HL ;normal video LD HL,DIMOF JR HalfI2 ; ; ;---------- Cursor Conversion Routines ---------- ; ; Convert binary row/col to relative offset ; Enter: H=binary row, L=binary col ; Exit: HL = Binary offset (HL = row * NCOLS + column) ; Uses: BC, DE, HL ; Rc2off: LD B,H ; B = Row LD C,L ; C = Column LD HL,0 ; zero offset value INC B LD DE,NCOLS JR Rc2bot Rc2of0: ADD HL,DE ; rows * NCOLS Rc2bot: DJNZ Rc2of0 ADD HL,BC ; add column RET ; ;============ Cursor Positioning Routines ============== ; ; Set cursor on screen. ; Enter: H=binary row, L = binary col ; Stcrshl: CALL Rc2off ; ...fall thru... ; ; Set cursor on screen by direct cursor addressing. ; Enter: HL = cursor offset relative to 0000 ; Stcrs: CALL Off2cr ;convert from offset to ascii col/row LD (colrow),HL ;put ascii col/row into string LD HL,zcurs ;send set-cursor string JP JJputs ; ;------------- ; ; Get current cursor position. ; Exit: H=binary row, L=binary col ; Uses: A, HL ; Crs2hl: CALL Getcu ;get cursor by querying terminal LD A,H ; Convert ASCII to binary.. LD H,L ; ..and reverse order SUB CRBIAS LD L,A LD A,H SUB CRBIAS LD H,A LD (Bcursor),HL ; Save it RET ; ;------------- ; ; Get cursor position ; Exit: HL Contains ASCII H=col, L=row ; Uses: A, HL ; ; Find out what your terminal sends in response to a ; 'send cursor position' command. Some terminals send ; ESC,'=',row+offset,col+offset. ; TV925 sends row+offset,col+offset,CR. We need to ignore ; all but the row and column bytes, and return these in HL. ; Getcu: LD HL,Sndcur ; Ask terminal where cursor is. CALL JJputs ; ; May need to swallow one or more characters before row ; and column. Check your terminal for protocol. ; CALL JJconi ; Get row LD L,A ; ... and save it in register L. PUSH HL CALL JJconi ; Get col POP HL LD H,A ; ... and return it in H. ; ; Need to swallow the next char. if using Televideo 925 ; PUSH HL CALL JJconi ; Televideo sends CR after row/column POP HL RET ; ; Convert special screen attribute codes to SPACE, if ; passing them to external routines. ; FILTER: AND 7FH ; Strip half-intensity bit. CP ' ' RET NC LD A,' ' RET ; FLTRC: PUSH AF LD A,C CALL FILTER LD C,A POP AF RET ; ;************************************* ; ; DATA AREA ; ; cut-region data ; CUSAV: DW 0 LASTCH: DB 0 Ctsize: DW 0 ;#cols+1 * # rows Ctcols: DB 0 ;# cols in cut region (excl. CR), A PAIR Ctrows: DB 0 ;# rows Linno: DB 0 ; Line counter for put-page ; ; mark-region data ; Mrkcnt: DB 0 Curcol: DB 0 ;A PAIR Currow: DB 0 MARK1: DW 0 ;binary row,col of upperleft mark MARK2: DW 0 ;lower right mark ZRUB: DB BS,SPACE,BS,0 ;rub-out previous char ; savarc: dw 0 ;ascii row/col of cursor ;================================ ; ; JOTPAD BANNER - just 2 lines ; ; 1. Clear screen. ; 2. Remind user of usage, to extent space is available. ; BANNER: DB ESC,CLS ;clear screen DB 'JOT: = exit, ' ; IF WSFLAG ; Use WS-like commands? ; ; The following are the generic Wordstar ((c) Micropro) ; cursor movement keys. ; DB '^V = ins line, ^Y = del line' DB CR,LF DB ' ^E - up, ^X - down, ' DB '^S - left, ^D - right' ; ELSE ; use terminal cursor keys ; ; The following is for the native cursor keys for your terminal. ; Edit these for your terminal as neccessary. ; DB 'ESC E = Ins line, ESC R = Del line' DB CR,LF DB ' Ctrl-K = UP, Ctrl-J = DOWN, ' DB 'Ctrl-H = LEFT, Ctrl-L = RIGHT' ENDIF ; WSFLAG ; Zcrlf: DB CR,LF,0 ;++++++++++++++++++++++++++++++ ; ; SCREEN BUFFER STRUCTURE ; ; The rest of the 4K block is available for the screen image and other data. ; ; addresses: ; ; use 'ds' for assemblers that can't do forward equates ; Bcursor:DS 2 ; EQU $;cursor location in saved screen Buf: DS 0 ; EQU Bcursor+2 ;start of screen buffer ; END