home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
turbopas
/
toadln5.arc
/
TOADLN5.INC
< prev
next >
Wrap
Text File
|
1988-08-24
|
23KB
|
454 lines
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}