home *** CD-ROM | disk | FTP | other *** search
-
- PROCEDURE ToadLn(VAR S : Str255);
- BEGIN
- Inline(
- {;v1.5}
- {; - fixed BS error}
- {; - handling/addressing local variables with conventional}
- {; .ASM format.}
- {; [bp+4] = VAR S doubleword vector}
- {; [bp-4] = string starting xy coordinates}
- {; [bp-6] = screen width}
- {; [bp-7] = insert flag}
- {; - adding insert key toggle (default insert On)}
- {;Codes returned in AX from a svc 0, Int 16H call:}
- {;CTRLU EQU 1615H ;^U}
- {;CTRLZ EQU 2C1AH ;^Z}
- {;DNARR EQU 5000H ;Cursor down}
- {;UPARR EQU 4800H ;Cursor up}
- {;HOMKEY EQU 4700H ;Home key}
- {;ENDKEY EQU 4F00H ;End key}
- {;LFTARR EQU 4B00H ;Cursor left}
- {;RTARR EQU 4D00H ;Cursor right}
- {;INSKEY EQU 5200H ;Insert key}
- {;DELKEY EQU 5300H ;Delete key}
- {;BSKEY EQU 0E08H ;Backspace/Rubout key}
- {;CRKEY EQU 1C0DH ;Return key}
-
- $81/$EC/$05/$00 { sub sp,5 ;space for 2 integers, 1 boolean}
- /$1E { push DS ;save DS}
- /$E8/$BA/$01 { call InitScr ;init screen vars}
-
- /$C5/$76/$04 { lds si,[bp+4] ;DS:SI = string vector (>S[bp])}
- /$8C/$D8 { mov ax,DS}
- /$8E/$C0 { mov ES,ax ;ES:DI also string vector}
- /$C6/$46/$F9/$FF{ mov byte [bp-7],$FF ;assume insert mode}
- /$E8/$08/$01 { call PadStr ;pad, display, home cursor}
-
- {;Clear keyboard buffer}
- {ClrKbd:}
- /$B4/$01 { mov ah,1 ;report if char is ready}
- /$CD/$16 { int $16 ;BIOS}
- /$74/$06 { jz KeyIn ;kbd buff is empty}
- /$30/$E4 { xor ah,ah ; Svc 0, read next kbd char}
- /$CD/$16 { int $16 ; BIOS}
- /$EB/$F4 { jmp short ClrKbd ; Until kbd buff is empty}
-
- {;Kbd buffer is now empty}
- {;Now get/process the user's keyboard input.}
- {KeyIn:}
- /$E8/$23/$00 { call GetKey ;Read, process kbd char}
- /$09/$C0 { or ax,ax ;no cursor moving?}
- /$74/$F9 { je KeyIn ;right, next key}
- /$3D/$0D/$1C { cmp ax,$1C0D ; Was it a CR or ^Z?}
- /$74/$05 { je ReturnStr ; yep, done}
- {;insure cursor is updated}
- /$E8/$37/$01 { call AbsCur ; repsn cursor, update len}
- /$EB/$EF { jmp short Keyin ; next key, please}
-
- {ReturnStr:}
- /$BF/$FF/$FF { mov di,$FFFF ;force char ptr to end}
- /$E8/$2F/$01 { call AbsCur ;cursor to screen end}
- /$E8/$F9/$00 { call ShowStr ;update length, display}
- /$B8/$0D/$0E { mov ax,$0E0D ;CR}
- /$CD/$10 { int $10}
- /$B0/$0A { mov al,$0A ;LF}
- /$CD/$10 { int $10}
- /$E9/$BF/$01 { jmp Done ;finished}
-
- {GetKey:}
- {;Processes the keyboard char, acts as required.}
- /$30/$E4 { xor ah,ah ;svc 0, read next kbd char}
- /$CD/$16 { int $16 ;BIOS}
- {;^U clears the string and screen line.}
- /$3D/$15/$16 { cmp ax,$1615 ;Is it a ^U?}
- /$75/$07 { jne LftArrTst ;nope}
- /$C6/$04/$00 { mov byte [si],0 ; clear str length}
- /$E8/$C7/$00 { call PadStr ; clear screen/string}
- /$C3 { ret}
-
- {LftArrTst:}
- {;Left Arrow key moves left 1 char, stops at 1st char.}
- /$3D/$00/$4B { cmp ax,$4B00 ;how about cursor left?}
- /$75/$02 { jne RtArrTst ;nope}
- /$4F { dec di ; back up ptr}
- /$C3 { ret}
-
- {RtArrTst:}
- {;Right Arrow key moves right 1 char,}
- {;stops at last char (+1 if not 255th char)}
- /$3D/$00/$4D { cmp ax,$4D00 ;right cursor?}
- /$75/$02 { jne DelTst ;nope}
- /$47 { inc di ; bump 1 to right}
- /$C3 { ret}
-
- {DelTst:}
- {;Delete key rubs out the cursor char,}
- {; does NOT move cursor, moves rest of string left.}
- /$3D/$00/$53 { cmp ax,$5300 ;Delete key?}
- /$74/$0A { je DoBS ;yep, skip to common code}
-
- {BSTst:}
- {;BS moves left 1 char and deletes THAT char.}
- {;No action if we're at first char}
- /$3D/$08/$0E { cmp ax,$0E08 ;Is it a BS? (Rubout)}
- /$75/$2A { jne DnArrTst ;nope}
-
- /$4F { dec di ;back up next char ptr}
- /$39/$F7 { cmp di,si ;did we back up to length byte}
- /$76/$21 { jbe NoBS ;yep, no action}
-
- {DoBS:}
- /$C6/$05/$B0 { mov byte [di],$B0 ;"delete" char right here}
- /$E8/$ED/$00 { call AbsCur ;fix cursor psn,current str psn}
- /$89/$F8 { mov ax,di ;new current psn}
- /$29/$F0 { sub ax,si ;- start = next char ofs}
- /$39/$C8 { cmp ax,cx ;is cursor within string? (not at end)}
- /$73/$0F { jae BSShow ;nope, at end or beyond}
-
- /$29/$C1 { sub cx,ax ;len - cur psn = bytes to move}
- /$56 { push si ;save str start}
- /$57 { push di ;save this new psn}
- /$89/$FE { mov si,di ;new char ptr}
- /$46 { inc si ;move from old char ptr}
- /$FC { cld ;insure fwd}
- /$F2/$A4 { rep movsb}
- /$C6/$05/$B0 { mov byte [di],$B0 ;clear last char}
- /$5F { pop di ;restore current psn}
- /$5E { pop si ;restore str start}
- {BSShow:}
- /$E8/$A0/$00 { call ShowStr}
- /$C3 { ret}
- {NoBS:}
- /$47 { inc di ;restore DI}
- /$31/$C0 { xor ax,ax ;flag no cursor move}
- /$C3 { ret}
-
- {DnArrTst:}
- {;Down Arrow key goes straight down 1 line,}
- {;OR to last str char (+1 if not 255th char)}
- /$3D/$00/$50 { cmp ax,$5000 ;down cursor?}
- /$75/$06 { jne EndTst ;nope}
- /$03/$7E/$FA { add di,[bp-6] ; + scr width = 1 line down}
- /$72/$06 { jc End1 ; went beyond MAXINT}
- /$C3 { ret ; done}
-
- {EndTst:}
- {;End key goes to last str char (+1 if not 255th char)}
- /$3D/$00/$4F { cmp ax,$4F00 ;End key?}
- /$75/$04 { jne UpArrTst ;nope}
- {End1:}
- /$BF/$FF/$FF { mov di,$FFFF ; max out next char ptr}
- /$C3 { ret}
-
- {UpArrTst:}
- {;Up Arrow key goes straight up 1 line,}
- {;OR to first str char.}
- /$3D/$00/$48 { cmp ax,$4800 ;up cursor?}
- /$75/$06 { jne HomTst ;nope}
- /$2B/$7E/$FA { sub di,[bp-6] ;- scr width = 1 line up}
- /$72/$06 { jb DoHome ;went negative, home}
- /$C3 { ret ;done}
-
- {HomTst:}
- {;Home key goes to first str char.}
- /$3D/$00/$47 { cmp ax,$4700 ;home key?}
- /$75/$03 { jne InsTst ;nope}
- {DoHome:}
- /$31/$FF { xor di,di ; back to start}
- /$C3 { ret}
-
- {InsTst:}
- {;Insert key toggles insert/overwrite mode}
- /$3D/$00/$52 { cmp ax,$5200 ;Insert key?}
- /$75/$06 { jne CrTst ;nope}
- /$F6/$56/$F9 { not byte [bp-7] ;reverse all the bits}
- /$31/$C0 { xor ax,ax ;no cursor updating}
- /$C3 { ret}
-
- {CrTst:}
- {;Return or ^Z terminate input, exit procedure.}
- /$3D/$0D/$1C { cmp ax,$1C0D ;Is it a CR?}
- /$74/$4C { je GetKeyX ;yep, done}
- /$3D/$1A/$2C { cmp ax,$2C1A ; how about ^Z}
- /$75/$04 { jne FunTst ; nope}
- /$B8/$0D/$1C { mov ax,$1C0D ; force to CR}
- /$C3 { ret}
-
- {FunTst:}
- {;We gobble any other function or cursor keys}
- {;so spurious chars won't get in the string.}
- /$30/$E4 { xor ah,ah ;clear msb (aux byte)}
- /$08/$C0 { or al,al ;is it a special? (cursor/function)}
- /$74/$3D { je GetKeyX ;yep, ignore it (AX=0)}
-
- {;We assume it's a legal char now, so we display it.}
- {;Legals include other control keys.}
- {;v1.5}
- {; If insert mode, we must first move the string right 1}
- {; from current char (losing chars beyond 255th).}
-
- {PrChr:}
- /$80/$7E/$F9/$00{ cmp byte [bp-7],0 ;overwrite mode?}
- /$74/$32 { jz PrC ;yep, just stuff it}
-
- /$50 { push ax ;save current char}
- /$E8/$A4/$00 { call FixLen ;CX=current length,AX=rel psn}
- /$29/$C1 { sub cx,ax ;length - cur psn = chars to move}
- /$58 { pop ax ;restore char}
- /$72/$29 { jb PrC ;curr char is next char (empty), stuff it}
- /$75/$12 { jnz Pr1 ;more than 1 char to move}
- {;We're sitting on last real char,}
- {;so just 1 to move to right. Do it manually:}
- /$8A/$25 { mov ah,[di] ; snarf old char}
- /$50 { push ax ; save}
- /$E8/$21/$00 { call PrC ; display,stuff}
- /$E8/$6E/$00 { call AbsCur ; doublecheck psn, DI, etc.}
- /$58 { pop ax ; get back char}
- /$88/$E0 { mov al,ah ; old char into AL}
- /$80/$F9/$FF { cmp cl,255 ; length maxed out?}
- /$72/$16 { jb PrC ; nope, stuff it and return}
- /$C3 { ret ; gobble last char}
-
- {Pr1:}
- /$56 { push si ;save str start}
- /$57 { push di ;save this new psn}
- /$41 { inc cx ;adjust chars to move}
- /$01/$CF { add di,cx ;curr char + chars to move}
- {;di points to last char in string}
- /$89/$FE { mov si,di ;same place}
- /$4E { dec si ;back up to char before}
- /$FD { std ;insure backward}
- /$F2/$A4 { rep movsb ;do the move DI-1 to DI}
- /$FC { cld ;be neat: forward again}
- /$5F { pop di ;restore current psn}
- /$5E { pop si ;restore str start}
- /$AA { stosb ;stuff ASCII char, bump DI}
- /$E8/$20/$00 { call ShowStr ;display the string (AX=0)}
- /$F7/$D0 { not ax ;AX <> 0,flag cursor updating}
- /$C3 { ret}
-
- {PrC:}
- /$AA { stosb ;stuff ASCII char, bump DI}
- /$B4/$0E { mov ah,$0E ;write char TTY}
- /$CD/$10 { int $10 ;BIOS}
- {GetKeyX:}
- /$C3 { ret}
-
- {PadStr:}
- {;Pads from past last char to 255 chars with graphic char.}
- {;Displays str, homes cursor.}
- {;Returns CX=str length, DI=str start}
-
- /$30/$ED { xor ch,ch ;clear msb}
- /$8A/$0C { mov cl,[si] ;get str length}
- /$89/$F7 { mov di,si ;current char = str start}
- /$47 { inc di ;bump past len byte}
- /$56 { push si ;str start}
- /$57 { push di ;and next char ptr}
-
- /$01/$CF { add di,cx ;add in length (if any)}
- /$F6/$D1 { not cl ;255-str len}
- /$B0/$B0 { mov al,$B0 ;pad with graphic char}
- /$FC { cld ;insure fwd (sigh...)}
- /$F2/$AA { rep stosb ;do the pad}
- /$5F { pop di ;restore str start}
- /$5E { pop si ;and next char ptr}
- /$8B/$56/$FC { mov dx,[bp-4] ;home cursor to str start}
- {;fall thru to ShowStr and return}
-
- {ShowStr:}
- {;Display str at starting coordinates,}
- {;Clear to EOL (e.g., full 255 chars).}
- {;Exit with CX=current str length, DI unchanged,}
- {; cursor psn unchanged.}
- /$52 { push dx ;remember current cursor psn}
- /$B4/$03 { mov ah,3 ;read cur psn (want cursor size)}
- /$CD/$10 { int $10 ;BIOS CX = current cursor size}
-
- /$51 { push cx ;save cursor size}
- /$B5/$20 { mov ch,$20 ;turn cursor off}
- /$B4/$01 { mov ah,1 ;set cursor size}
- /$CD/$10 { int $10 ;BIOS}
- /$8B/$56/$FC { mov dx,[bp-4] ;home cursor to str start}
- /$B4/$02 { mov ah,2 ;position cursor}
- /$CD/$10 { int $10 ;BIOS}
-
- {;We display all 255 chars. Str buffer may be padded}
- {;with graphic chars (not part of real length),}
- {;but we show them to "Clr EOL".}
- /$56 { push si ;str start}
- /$46 { inc si ;bump past length byte}
- /$B9/$FF/$00 { mov cx,255 ;255 chars}
- /$B4/$0E { mov ah,$0E ;BIOS display char TTY}
- /$FC { cld ;insure forward}
- {SL1:}
- /$AC { lodsb ;next string char}
- /$CD/$10 { int $10 ;display it}
- /$E2/$FB { loop SL1 ;do them all}
- /$5E { pop si ;restore str start}
-
- /$59 { pop cx ;old cursor size}
-
- /$B4/$01 { mov ah,1 ;set cursor size}
- /$CD/$10 { int $10 ;BIOS}
- /$5A { pop dx ;old cursor psn}
- /$B4/$02 { mov ah,2 ;set cursor psn}
- /$CD/$10 { int $10 ;BIOS}
- /$E8/$4C/$00 { call GetLen ;update CX=len}
- /$88/$0C { mov [si],cl ;and force into len byte}
- /$31/$C0 { xor ax,ax ;so we don't call AbsCur}
- /$C3 { ret}
-
- {AbsCur:}
- {;Absolute cursor movement to next char ptr (DI).}
- {;Enter with DI = ptr to next str char.}
- {;Test to insure DI doesn't point beyond}
- {; 255 chars past start (from FixLen)}
- {;Exit with}
- {; DX= adjusted xy coords}
- {; DI = adjusted current char ptr (from FixLen)}
- {; CX = str length (from GetLen)}
- {; cursor pointing to next str char}
-
- /$8B/$56/$FC { mov dx,[bp-4] ;get str's starting cursor psn}
- /$E8/$20/$00 { call FixLen ;check str len,char ptr}
- {;Returns CX=str len, AX=next char ofs}
- /$09/$C0 { or ax,ax ;curr char = start?}
- /$74/$17 { je PsnCur ;yep, go "home" cursor}
-
- /$48 { dec ax}
- /$51 { push cx ;save str len}
- /$8B/$4E/$FA { mov cx,[bp-6] ;get scr width}
- /$00/$D0 { add al,dl ;add in starting col}
- /$80/$D4/$00 { adc ah,0 ;in case of carry}
- {AL1:}
- /$39/$C8 { cmp ax,cx ;less than 1 line?}
- /$76/$06 { jbe A3 ;yep}
- /$29/$C8 { sub ax,cx ;>width, subtract width}
- /$FE/$C6 { inc dh ;bump row}
- /$EB/$F6 { jmp short AL1 ;until col < = width}
- {A3: ;updated DL=col,DH=row}
- /$59 { pop cx ;restore length}
- /$88/$C2 { mov dl,al ;update row}
-
- {PsnCur:}
- /$B4/$02 { mov ah,2 ;svc 2, position cursor}
- /$CD/$10 { int $10 ;BIOS}
- /$C3 { ret}
-
- {FixLen:}
- {;Insures str len (and CX) are legal,}
- {;keeps DI within legal limits (start + 0..254)}
- {;Enters with DI = current char ptr (could be beyond str length),}
- {;Exits with CX = str len, AX=rel cursor psn within string}
-
- {;first scan for our terminating $B0 graphics char}
- /$E8/$1E/$00 { call GetLen ;returns with CX=len}
- /$E3/$06 { jcxz F0 ;no str length, force to start}
- {;now insure str ptr is legal (within string)}
- /$89/$F8 { mov ax,di ;str ptr}
- /$29/$F0 { sub ax,si ;- str start = next char ofs}
- /$77/$06 { ja F1 ;ok, next char > start}
- {F0:}
- /$31/$C0 { xor ax,ax ; next char ofs = 0}
- /$89/$F7 { mov di,si ; force next char to start}
- /$47 { inc di ; bump to 1st char}
- /$C3 { ret ; done}
-
- {;at or above 1st char, how about beyond str end?}
- {F1:}
- /$39/$C8 { cmp ax,cx ;< len?}
- /$76/$0B { jbe F2 ;yep}
- /$89/$F7 { mov di,si ; start}
- /$89/$C8 { mov ax,cx ; get length}
- /$3C/$FF { cmp al,255 ; maxed out?}
- /$74/$01 { je F1A ; yep}
- /$40 { inc ax ; no, so bump to next char}
- {F1A:}
- /$01/$C7 { add di,ax ; point to last char}
- {F2:}
- /$C3 { ret}
-
- {GetLen:}
- /$57 { push di ;save next char ptr}
- /$89/$F7 { mov di,si ;start}
- /$B9/$FF/$00 { mov cx,255 ;max possible len}
- /$01/$CF { add di,cx ;point to end}
- /$FD { std ;scan backwards}
- /$B0/$B0 { mov al,$B0 ;graphics char ends it}
- /$F3/$AE { repe scasb ;scan until we run out of $B0's}
- /$FC { cld}
- {;CX points to the non-$B0 char (or 0)}
- /$74/$01 { jz G1 ;didn't find ANY}
- /$41 { inc cx ; adjust from the scasb}
- {G1:}
- /$5F { pop di ;restore next char ptr}
- /$C3 { ret ;with CX=len}
-
- {InitScr:}
- {;Get required screen stuff}
- /$B4/$0F { mov ah,$0F ;get current video mode}
- /$CD/$10 { int $10 ;BIOS}
- {;BH = active display page (protect it!)}
- /$88/$E0 { mov al,ah ;need width as LSB}
- /$30/$E4 { xor ah,ah ;clear msb}
- /$89/$46/$FA { mov [bp-6],ax ;save current scr width}
-
- {;We need 255 chars of screen space WITHOUT SCROLLING,}
- {;or our cursor positioning will be screwed up.}
- {;Test now to see if we have enough room.}
- {;If not, do our scrolling NOW instead of letting BIOS do it.}
-
- /$89/$C6 { mov si,ax ;save width in SI}
- /$B4/$03 { mov ah,3 ;get current cursor psn in DX}
- /$CD/$10 { int $10 ;BIOS}
- /$80/$FE/$15 { cmp dh,21 ;row 21 or less?}
- /$76/$25 { jbe NoScroll ;yep, scroll testing}
-
- /$88/$F0 { mov al,dh ;current row}
- /$89/$F1 { mov cx,si ;CL = width multiplier}
- /$F6/$E1 { mul cl ;AX=row * width}
- {C1:}
- /$00/$D0 { add al,dl ;add in current col}
- /$80/$D4/$00 { adc ah,0 ;in case of carry}
- /$89/$C1 { mov cx,ax ;remember as abs scr psn}
- /$05/$FF/$00 { add ax,255 ;plus full line length}
- /$89/$C7 { mov di,ax ;abs scrn psn + string}
- {CL1:}
- /$39/$CF { cmp di,cx ;less than 1 line?}
- /$76/$0B { jbe CDone ;yep, ok}
- /$B8/$0A/$0E { mov ax,$0E0A ; display LF via BIOS}
- /$CD/$10 { int $10 ; BIOS}
- /$29/$F7 { sub di,si ; subtract width}
- /$FE/$CE { dec dh ; back up 1 row}
- /$EB/$F1 { jmp short CL1}
- {CDone:}
- /$B4/$02 { mov ah,2 ;svc 2, position cursor}
- /$CD/$10 { int $10 ;BIOS}
- {NoScroll:}
- /$89/$56/$FC { mov [bp-4],dx ;now save current cursor psn}
-
- {;Get screen attributes at current cursor psn}
- /$B4/$08 { mov ah,8 ;Read char & attrib}
- /$CD/$10 { int $10 ;BIOS}
- /$88/$E3 { mov bl,ah}
- {;BL = screen attribute (protect it!)}
- /$C3 { ret}
-
- {Done:}
- /$1F { pop DS ;restore DS}
- {;let Turbo do the rest}
- );
- END; {of ToadLn}