home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
dskutl
/
reform16.arc
/
REFORMAT.IN4
< prev
next >
Wrap
Text File
|
1987-05-22
|
12KB
|
228 lines
{REFORMAT.IN4
Fast Write routine.
This does only a modicum of "flicker control" for slow or color
video cards. Other versions are available for that if you just HAVE
to have such a thing. Remember, REFORMAT is NOT a video-oriented utility.
If you have a weird video setup that doesn't permit direct write
to video memory, there's lots of "generic" code to use the regular
Turbo Pascal WRITE or WRITELN instructions.
Toad Hall.
}
PROCEDURE WriteF(col,row : INTEGER; S : Line);
{Fast direct screen memory writing utility.
Permits x/y positioning anywhere on the screen, centering
at any y coordinate, line clearing (whole line or a specified
x coordinate), and line filling (whole line or a specified
x coordinate).
Special rules:
IF the first character of the string has an ASCII value above 127,
WriteF will assume this is a repeating character and fill a whole line
with that character. Ignores rest of string (if it exists).
Naturally, if you send an ASCII 32+127, this will blank a line!
Filling starts at x coord, of course.
IF the x coordinate is 0, WriteF will center the string according to
the current window size (the global variable width).
IF the y coordinate is 0, WriteF will use the global variable toadY
as the current y coordinate (in the current window) and write this
line there. toadY will be incremented.
IF the y coordinate is NOT 0, WriteF will write at y, and will update
the global toadY to that coordinate. toadY will NOT be incremented.
IF we are filling, toadY will NOT increment.
Toad Hall.
}
BEGIN
InLine(
$1E { push DS ;actual start of code}
/$06 { push ES ;might as well save this
too}
/$8A/$96/>COL { mov DL,>col[BP] ;desired column}
/$8A/$A6/>ROW { mov AH,>row[BP] ;desired row}
/$08/$E4 { or AH,AH ;zero?}
/$75/$04 { jne W2 ; nope, got a row val}
/$8A/$26/>TOADY { mov AH,[>toadY] ; 0, so make it toadY}
{W2:}
/$88/$E6 { mov DH,AH ;we use it here}
/$8A/$2E/>WIDTH { mov CH,[>width] ;get global width variable}
{;point ES:SI to the string (relative to stack, of
course)}
/$8D/$BE/>S { lea DI,>S[BP] ;ES:SI = string vector}
/$57 { push DI}
/$5E { pop SI ;gonna use for source later}
/$36 { SS:}
/$8A/$0C { mov CL,[SI] ;get str length into CX}
/$16 { push SS ;the string var segment}
/$07 { pop ES ;ES=SS}
/$46 { inc SI ;bump past str length}
/$47 { inc DI ;here too}
{;test to see if a clear or fill.}
{;indicated by first string char being >127.}
/$31/$C0 { xor AX,AX ;clear a fill flag}
/$50 { push AX}
/$88/$F4 { mov AH,DH ;get row back}
/$FE/$C4 { inc AH ;assume we incr toadY}
/$26 { ES:}
/$8A/$04 { mov AL,[SI] ;get first char}
/$3C/$80 { cmp AL,128 ;is hi bit set?}
/$72/$12 { jb W3Y ;nope, do centering test}
/$88/$E9 { mov CL,CH ;length=window width}
/$28/$D1 { sub CL,DL ;minus col offset}
/$3C/$A0 { cmp AL,$A0 ;is it a hi-bit space?}
/$75/$08 { jne W3B ; nope}
/$FE/$C1 { inc CL}
/$B0/$20 { mov AL,$20 ; yep, make it so}
/$8A/$26/>TOADY { mov AH,[>toadY] ;insure toadY doesn't change}
{;must clear the old AX on the stack (0's, remember?)}
{;and save our new value for the screen fill.}
{W3B:}
/$5B { pop BX ;remove the zero fillflag}
/$50 { push AX ;save fillchar}
{W3Y:}
/$88/$26/>TOADY { mov [>toadY],AH ;post updated toadY}
/$08/$D2 { or DL,DL ;0 = column=centering?}
/$75/$14 { jne W3Z ; nope}
{;centering a string, compute left margin offset.}
/$B2/$01 { mov DL,1 ;assume adjusted left margin}
/$88/$E8 { mov AL,CH ;legal width}
/$28/$C8 { sub AL,CL ;left over to justify}
/$76/$0C { jbe W3Z ;<= 0 left over}
/$78/$0A { js W3Z ;new}
/$3C/$01 { cmp AL,1 ;just 1 left?}
/$74/$06 { je W3Z ;yep, start at left margin}
/$04/$02 { add AL,2 ;fixes centering for text}
/$D0/$E8 { shr AL,1 ;divide in half}
/$88/$C2 { mov DL,AL ;make THAT the col value}
{;writing at col, protect right window margin}
{W3Z:}
/$31/$C0 { xor AX,AX}
/$88/$C8 { mov AL,CL ;string length}
/$00/$D0 { add AL,DL ;add in col offset}
/$38/$E8 { cmp AL,CH ;subtract scr width}
/$76/$08 { jbe W4 ; fine, <=}
/$88/$E8 { mov AL,CH ; bad, make width - col}
/$28/$D0 { sub AL,DL}
/$FE/$C0 { inc AL ;adjust for subtract}
/$88/$C1 { mov CL,AL}
{W4:}
/$FE/$CE { dec DH}
/$FE/$CA { dec DL ;and col to 0..79}
/$02/$36/>WTOP { add DH,[>wTop] ;add in window Y coord
offset}
/$02/$16/>WLEFT { add DL,[>wLeft] ;add in window left offset}
/$30/$ED { xor CH,CH ;clear to just length in
lsb}
/$88/$F0 { mov AL,DH ;get the row value}
/$B3/$50 { mov BL,$50 ;fiddle for scrn absolute}
/$F6/$E3 { mul BL ;rows * 90}
/$29/$DB { sub BX,BX ;clear msb}
/$88/$D3 { mov BL,DL ;col for lsb}
/$01/$D8 { add AX,BX ;add them}
/$01/$C0 { add AX,AX ;*2}
/$89/$C7 { mov DI,AX ;ES:DI=screen offset}
/$00/$CA { add DL,CL ;add str length for cursor psn}
/$B4/$0F { mov AH,15 ;get cur video mode}
/$CD/$10 { int $10 ;cur video page returned in
BH}
/$88/$C3 { mov BL,AL ;save current mode in BL}
/$58 { POP AX ;get fillchar-flag back}
/$50 { PUSH AX ;save again}
/$08/$C0 { OR AL,AL ;0 means no special char}
/$74/$02 { je W4A ; no special char/clreol}
/$28/$CA { sub DL,CL ;force back to col}
{W4A:}
/$53 { push BX ;save page, mode}
{;stack now has page/mode, fillchar-flag}
/$B4/$02 { mov AH,2 ;set cursor psn svc}
/$CD/$10 { int $10 ;ROM-BIOS video}
/$5B { pop BX ;restore page/mode}
/$58 { pop AX ;restore fillchar-flag in AL}
{;stack clear}
/$8A/$26/>COLOR { mov AH,[>color] ;here's the attribute}
{;might as well do this anyway, tho not needed if}
{;just filling. test takes longer than the push/pop.}
{;here goes DS, no more variable access!}
/$06 { push ES ;string segment}
/$1F { pop DS ;DS:SI string vector}
/$BA/$00/$B0 { mov DX,$B000 ;assume mono screen}
/$80/$FB/$07 { cmp BL,7 ;mono?}
/$74/$03 { jz W4B ; yep (save this ZF)}
/$BA/$00/$B8 { mov DX,$B800 ; nope, make it color}
{W4B:}
/$8E/$C2 { mov ES,DX ;assign ES to screen}
/$89/$C3 { mov BX,AX ;will use it here}
{;AH, BH = attribute,}
{;AL, BL = fill char or 0}
/$74/$2E { jz W5 ;ZF = mono}
/$BA/$DA/$03 { mov DX,$03DA ;color board port}
{;redundant code is better than a test}
{;in the middle of our loop.}
/$08/$C0 { or AL,AL ;doing a normal write?}
/$74/$14 { je WL1 ; yep}
{;doing a fill, char in BL}
{FL1:}
/$EC { in AL,DX ;color board ready?}
/$A8/$01 { test AL,1}
/$75/$FB { jnz FL1 ; nope}
/$FA { cli ;no interrupts}
{FL2:}
/$EC { in AL,DX ;color board still ready?}
/$A8/$01 { test AL,1}
/$74/$FB { jz FL2 ; nope}
/$89/$D8 { mov AX,BX ;fill char, attrib}
/$AB { stosw ;stuff word to scr,}
{inx DI by 2}
/$E2/$F0 { loop FL1 ;test color board again}
/$28/$C0 { sub AL,AL ;dumb way to exit}
/$74/$20 { jz WX}
{;doing a normal color write, attrib already in AH}
{WL1:}
/$EC { in AL,DX ;color board ready?}
/$A8/$01 { test AL,1}
/$75/$FB { jnz WL1 ; nope}
/$FA { cli ;no interrupts}
{WL2:}
/$EC { in AL,DX ;color board still ready?}
/$A8/$01 { test AL,1}
/$74/$FB { jz WL2 ; nope}
/$AC { lodsb ;get a string byte}
/$AB { stosw ;stuff word to scr,}
/$E2/$F1 { loop WL1 ;test color board again}
/$28/$C0 { sub AL,AL ;funny test here}
/$74/$0D { jz WX ;dumb way to exit}
{;doing a mono fill}
{W5:}
/$08/$C0 { or AL,AL ;0=normal write}
/$74/$05 { je WL3 ; yep, do a string}
{;AL=fill char}
{;AH=attribute}
/$F2/$AB { rep stosw ;ES:DI stuff CX words to scr}
/$E9/$04/$00 { jmp WX ;..and exit}
{WL3:}
/$AC { lodsb ;DS:SI snarf a string char}
{ into AL}
/$AB { stosw ;ES:DI stuff word to scr}
/$E2/$FC { loop WL3 ;for whole string}
{WX:}
/$07 { pop ES ;restore seg regs}
/$1F { pop DS}
);
END; {of WriteF}