Category : Pascal Source Code
Archive   : TVG103-S.ZIP
Filename : TVGRAPH.IN1

 
Output of file : TVGRAPH.IN1 contained in archive : TVG103-S.ZIP
(*****************************************************************************)
(* *)
(* TVGRAPH Version 1.0 (C) C.L.Burke. Portions (C) Borland *)
(* *)
(* Display Specific routines *)
(* *)
(* 0. Do_Set_XXXXXX - sets all of the functions into the procedure array *)
(* *)
(* 1. Do_INIT_XXXXXX - should initialise all the specific hardware *)
(* 2. Do_DONE_XXXXXX - should reset all specific hardware *)
(* 3. Do_PixelAddr_XXXXXX *)
(* - in ax=y, bx=x | out AH=unshifted bit mask *)
(* - CL=bits to shift BX = byte offset *)
(* 4. TVGraphCursorOn_XXXXXX *)
(* These 3 routines assume GLOBAL TvGraphCursor *)
(* has Start in H and end in L. GLOBAL TvGraphLoc *)
(* X in L and Y in H *)
(* - Turn Cursor on check TvViziFlag *)
(* 5. TVGraphCursorOff_XXXXXX *)
(* - Turn Cursor off check TvViziFlag *)
(* 6. TVUpdateCursor_XXXXXX *)
(* - Update cursor to current specifications *)
(* 7. Do_GraphMOV_XXXXX- expect same parameters at REP MOVSW to text video *)
(* - CX = Number of words (HI=Attr,LO=Char) to move *)
(* - DS:SI = Source of words *)
(* - ES:DI = Normal TEXT destination *)
(* 8. NewJmp_GraphMOV_XXXXXX *)
(* - Replaces the CheckSnow code in Views unit *)
(* - important that the following structure is kept *)
(* *)
(* asm *)
(* call far ptr Do_GraphMOV_XXXXXX *)
(* mov si,es *)
(* pop ax *)
(* pop cx *)
(* pop di *)
(* pop ds *)
(* pop es *)
(* db 0C3H ( RET NEAR - can't use RET FAR!!! ) *)
(* end; *)
(* 9. procedure Draw_Any_Line_XXXXXX(X1,Y1,X2,Y2,Color:word); assembler; *)
(* Generic draw routine assumes X1 (* *)
(* 10. procedure Draw_Horiz_Line_XXXXXX(X1,X2,Y,Color:word); assembler; *)
(* Horizontal draw routine assumes X1 (* *)
(* 11. procedure Draw_Vert_Line_XXXXXX(X,Y1,Y2,Color:word); assembler; *)
(* Vertical draw routine assumes Y1 (* *)
(*****************************************************************************)
const (* EGA Specific constants *)
EGAVideoMemory =$A000;
EGASequencer =$03C4;
EGAGraphController =$03CE;
Set_EnableSR =$0001;
UseSR =$0F00;
UseCPUMask =$0000;
Default_EnableSR =Set_EnableSR+UseSR;
Set_RWFunction =$0003;
OverWrite =$0000;
LogicalAND =$0800;
LogicalOR =$1000;
LogicalXOR =$1800;
Default_RWFunction =Set_RWFunction+OverWrite;
Set_WriteMode =$0005;
Read_Mode_0 =$0000;
Read_Mode_1 =$0800;
Write_Mode_0 =$0000;
Write_Mode_1 =$0100;
Write_Mode_2 =$0200;
Write_Mode_3 =$0300;
Default_WriteMode =Set_WriteMode+Read_Mode_1+Write_Mode_0;
Default_ColorPlane =$0007;
Default_Mask =$FF08;

BytesInLoop =10; (* Bytes in the simulated loop *)
NumberOfLoops =16; (* Number of coded loops *)
var (* GLobal to free BP in draw line routines *)
VARSlope:byte; (* 0 = slope < 1 , 1= slope >1 *)
BitShift,ReInitBit,NegBitShift,
CharMapPtr,VARVertIncr,VARIncr1,VARIncr2:word;


Procedure Do_INIT_EGAVGA; assembler;
asm
(* Call once at start of program *)
(* all ega/vga routines should return to this state *)
push ax
push cx
push dx
push es
push si

xor ah,ah
xor ch,ch
mov ax,[GraphWidth]
div [CharWidth]
mul [GraphHeight]
mov [ColorList],ax
mov si,ax
mov ax,[VideoBufferSeg]
mov es,ax

mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_EnableSR
out dx,ax
mov ax,Set_WriteMode+Read_Mode_1+Write_Mode_2 (* For Color init next *)
out dx,ax
mov ax,Default_RWFunction
out dx,ax
mov ax,Default_Mask
out dx,ax
mov ax,Default_ColorPlane
out dx,ax


mov al,0ffh
mov ch,010h
mov cl,0
(* ES:SI = SCreen , CX=Count, DX=port *)
@L10:
and es:[si],cl
inc si
inc cl
dec ch
jnz @L10

mov ax,Default_WriteMode
out dx,ax

(* Set up 16 colors at EGAScreenSegment:[SI] where SI=max-x max-y *)
pop si
pop es
pop dx
pop cx
pop ax
ret
end;


Procedure Do_DONE_EGAVGA; assembler;
asm
(* Call once at end of program *)
push ax
push dx
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_Mask (* Restore CRT registers *)
out dx,ax
mov ax,Set_WriteMode+Read_Mode_0+Write_Mode_0
out dx,ax
mov ax,Set_RWFunction+OverWrite
out dx,ax
mov ax,Default_ColorPlane
mov ah,0Fh
out dx,ax
pop dx
pop ax
ret
end;

procedure Do_PixelAddr_EGAVGA; assembler;
asm
(* in ax=y, bx=x | *)
(* CL=bits to shift BX = byte offset *)
(* BX=Y*80+X/8 = Y*64+Y*16+X/8 = Y SHL 4 + Y SHL 6 + X SHR 3 *)
(* CL=BL and 7 *)
mov ch,bl
and ch,7 (* mask *)
mov cl,3
shr bx,cl (* bx=X/8 *)
inc cl
shl ax,cl (* ax=Y*16 *)
add bx,ax (* bx=Y*16+X/8 *)
shl ax,1
shl ax,1 (* ax=Y*64 *)
add bx,ax (* bx=Y*64+Y*16+X/8 *)
mov cl,ch
end;

procedure Do_Cursor_EGAVGA; assembler;
asm
(* Expect CH = start, CL = stop line (0..16), - in TvGraphCursor*)
(* Expect X in DL, Y in DH - character co-ords - in TvGraphPos *)
push cx
push dx
push si
push es
xor [TvViziFlag],0FFh
mov cx,[TvGraphCursor]
mov dx,[TvGraphLoc]

and cx,01F1Fh (* ensure each is 0..31 only *)
cmp cl,ch
jb @SKIP
push cx
mov al,CharHeight
mul dh (* ax:= Y*CharHeight *)

xor dh,dh
mov si,dx (* Si = X *)

xchg ch,cl
xor ch,ch
add ax,cx (* ax:= Y*CharHeight+StartLine *)
mov cx,80
mul cx (* ax:= (Y*CharHeight+StartLine)*80 *)
add ax,dx (* ax:= (Y*CharHeight+StartLine)*80 *)
add si,ax (* si:= (Y*CharHeight+StartLine)*80 + X *)
pop cx
mov al,cl
xor ah,ah
sub al,ch (* al:= (StopLine - StartLine) *)
inc al (* al:= (StopLine - StartLine)+1 *)
mov cx,ax (* use as loop count *)
mov ax,[VideoBufferSeg] (* VideoBufferSeg *)
mov es,ax
cli
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_EnableSR
out dx,ax
mov ax,Default_ColorPlane
out dx,ax
mov ax,Set_WriteMode+Read_Mode_1+Write_Mode_2
out dx,ax
mov ax,Default_Mask
out dx,ax
mov ax,Set_RWFunction+LogicalXOR
out dx,ax
mov al,0ffh

(* ES:SI = SCreen , AX=Temp, CX=Count, DX=port *)
@L10:
and es:[si],al
add si,80
loop @L10
sti
@SKIP:
pop es
pop si
pop dx
pop cx

ret
end;

procedure TVGraphCursorOn_EGAVGA; assembler;
asm
cmp TvViziFlag,0
jne @OnOK
jmp Do_Cursor_EGAVGA
@OnOK:
ret
end;

procedure TVGraphCursorOff_EGAVGA; assembler;
asm
cmp TvViziFlag,0
je @OffOK
jmp Do_Cursor_EGAVGA
@OffOK:
ret
end;

procedure TVUpdateCursor_EGAVGA; assembler;
asm
test TvGraphCursor,$E000
jz @DOIRET_ON
jmp TvGraphCursorOff_EGAVGA
@DOIRET_ON:
jmp TvGraphCursorOn_EGAVGA
end;

procedure Do_GraphMOV_EGAVGA; assembler;
asm
(* Expect CX = Number of words (HI=Attr,LO=Char) to move *)
(* Expect DS:SI = Source of words *)
(* Expect ES:DI = Normal TEXT destination *)

push es
push bp
push dx
push bx (* Save register that may be changes by a TP procedure *)
push bp

mov dx,ds
mov ax,seg @data (* Set up data segment *)
mov ds,ax
mov es,ax
mov [TextSource.S],dx
mov [TextSource.O],si
mov [Count],cx

call MouseCursorOff
call TvGraphCursorOff_EGAVGA

mov ax,di
xor dx,dx
mov cx,0A0h
div cx (* dx= O mod 160 , ax= O div 160 *)
shr dx,1
mov bx,dx (* X=bx , Y=ax *)

mul [CharHeight] (* ax := Y(text)*Rowsperline *)

mov dx,80 (*BytesPerLine*)
mul dx
add bx,ax (* End Routine PixelAddr10 *)
(* BX -> offset to Buffer *)
mov [DestOfs],bx

shr di,1 (* Convert index to one with no attributes *)
add di,offset GraphWriteAvail
mov [TextDest],di

mov al,NumberOfLoops
mov bl,BytesInLoop
sub al,[CharHeight] (* Number of loop segments to skip *)
and al,0Fh (* ensure in range 0..15 *)
mul bl (* Number of bytes to skip *)
add ax,OFFSET @STARTLP (* Location to jump to *)
mov [SaveJump],ax (* DX has offset to jump to using jmp [dx] *)

@GLP1:
les si,[TextSource]
mov ax,es:[si]

mov bl,ah (* BL has Attr *)
mov bh,ah
mov cl,4
and bl,00Fh
and bh,0F0h
shr bh,cl (* bh = background, bl = foreground *)

mov di,[TextDest]
cmp ah,0ffh
jz @NotText (* ffh is attr signal for graphics *)
mov byte ptr [di],0
jmp @IsText
@NotText:
mov byte ptr [di],al (* when attr=FF then char is window number *)
mov bx,0 (* Foreground 0 background 0 *)
mov ax,20h (* Space character *)
@IsText:
xor ah,ah (* AX has character *)

les di,[PtrFontTable] (* shl by 4 = *16 for index into font table *)
shl ax,cl
add di,ax (* ES:DI = font table for character *)

xor ch,ch

mov cl,bh (* Background color *)
mov bp,[ColorList] (* EGAScreenSegment:BP = List of colors in ega memory *)
add bp,cx (* EGAScreenSegment:BP = actual color pointer in ega *)

mov cl,[CharHeight] (* CL has height = times to do @L10 *)

mov cx,[SaveJump] (* Get the jump location *)

push ds
mov ax,[VideoBufferSeg] (* VideoBufferSeg *)
mov si,[DestOfs]
mov ds,ax (* DS:SI = Screen Address *)

(* ES:DI = Font, DS:SI = SCreen , AX=Temp, BX= attr, CX=Count, DX=port *)
(* DS:BP = location of color in ega memory *)

cli
mov dx,EGAGraphController (* Set up Graphics controller *)
mov ax,Default_EnableSR
out dx,ax
mov ax,Default_WriteMode
out dx,ax
mov ax,Default_RWFunction
out dx,ax
mov ax,Default_ColorPlane
out dx,ax

mov ah,ds:[bp] (* Latch background color to memory *)
mov al,00
mov ah,bl
out dx,ax (* foreground color to Set/Reset register *)

mov al,8
mov bl,0FFh

jmp cx (* jump to start should be 0 for 16, 2 for 14 *)

@STARTLP:
(* 0 *) (* CYCLES / BYTES *)
mov ah,es:[di] (* 4 / 3 *)
out dx,ax (* 11 / 1 *)
mov [si],bl (* 4 / 2 *)
inc di (* 2 / 1 *)
add si,80 (*BytesPerLine*) (* 2 / 3 *)
(* 1 *) (* 23 / 10 TOTAL *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 2 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 3 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 4 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 5 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 6 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 7 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 8 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(* 9 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*10 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*11 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*12 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*13 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*14 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
(*15 *)
mov ah,es:[di]
out dx,ax
mov [si],bl
inc di
add si,80 (*BytesPerLine*)
sti

pop ds
inc [TextSource.O]
inc [TextSource.O]
inc [TextDest]
inc [DestOfs]
dec [Count]
jnz @GLP1

call MouseCursorOn
call TvUpdateCursor_EGAVGA

pop bp
pop bx (* Restore registers *)
pop dx
pop bp
pop es

retf
end;

procedure NewJmp_GraphMOV_EGAVGA; assembler;
asm
call far ptr Do_GraphMOV_EGAVGA (* 5 *)
mov si,es (* 2 *) (* Normal Return code *)
pop ax (* 1 *)
pop cx (* 1 *)
pop di (* 1 *)
pop ds (* 1 *)
pop es (* 1 *)
db 0C3H (* RET NEAR *) (* 1 *)
end; (*TOTAL 13 bytes*)


procedure Do_TextAddr_EGAVGA; assembler;
asm
(* start AX=Y, BX=X
(* Output SI=CharMapPtr,BX=NegBitShift,DX=BitShift*)
(* AX=ReInitBit *)
(* Calculate the start location of bitmap *)
DIV [CharHeight]
MOV CL,AH (* Remainder = 0..Charheight-1 *)
MUL [ScreenWidth]
SHR BX,1
SHR BX,1
SHR BX,1
ADD AX,BX (* AX is offset into table *)
ADD AX,Offset GraphWriteAvail
mov SI,AX


mov ax,08000h
mov bx,ax
mov dx,ax

(* The following are used for determining when a character boundary has *)
(* Been breached in graphics mode - bx and dx give the initial amount to*)
(* rotate left - when carry inc SI i.e. adc si,0, ax give the normal one*)
(* to initialize to when carry is found *)

shr bx,cl (* Head start for shifting initial -ive*)
sub cl,[CharHeight]
neg cl
dec cl
shr dx,cl (* Head start for shifting initial +ive *)
mov cl,[CharHeight]
dec cl
shr ax,cl (* Head start for shifting normal +/- ive *)
end;



procedure Draw_Vert_Line_EGAVGA(X,Y1,Y2:word;Color:byte); assembler;
asm
(* Assumes that Y1 cli

mov ax,[Y1]
mov bx,[X]
call Do_TextAddr_EGAVGA
mov [CharMapPtr],si
mov [BitShift],dx
mov [ReInitBit],ax

mov dx,EGAGraphController

mov ah,[Color]
xor al,al
out dx,ax

mov ax,Set_EnableSR+UseSR
out dx,ax

mov ax,Default_RWFunction
mov ah,[CurrentLineWriteMode]
shl ah,1
shl ah,1
shl ah,1
out dx,ax

mov ax,Default_WriteMode
out dx,ax
mov ax,Default_ColorPlane
out dx,ax


mov si,[BytesPerLine]
mov ax,EGAVideoMemory
mov es,ax

mov ax,[y1] (* AX := y1 *)
mov bx,[y2] (* BX := y2 *)
mov cx,bx
sub cx,ax (* CX := dy *)

inc cx (* CX := # of pixels to draw *)
mov bx,[x] (* BX := x *)
push cx (* preserve this register *)
call Do_PixelAddr_EGAVGA
(* BX -> video buffer *)
(* CL := # bits to shift right *)
(* set up Graphics Controller *)
mov ah,080h
shr ah,cl (* AH := bit mask in proper position *)
mov al,8 (* AL := Bit Mask reg number *)
out dx,ax

pop cx (* restore this register *)

(* draw the line *)
(* USES ES,BX,AL,SI,CX - avail DI,DX,AH,BP *)
mov ah,[CurrentGraphWindow]
mov di,[CharMapPtr]
mov dx,[BitShift] (* get rotated left, if carry then inc *)
(* bx from CharMapPtr *)

@L32: cmp byte ptr [di],ah
jne @L32a
or es:[bx],al (* set pixel *)
@L32a: add bx,si (* increment to next line *)
rol dx,1 (* rotate left when 1 inc bx *)
jnc @L32b
add di,si
mov dx,[ReInitBit]
@L32b: loop @L32

sti
end;



procedure Draw_Horiz_Line_EGAVGA(X1,X2,Y:word;Color:byte); assembler;
asm
cli
mov ax,[Y]
mov bx,[X1]
call Do_TextAddr_EGAVGA
mov [CharMapPtr],si

mov dx,EGAGraphController

mov ah,[Color]
xor al,al
out dx,ax

mov ax,Set_EnableSR+UseSR
out dx,ax

mov ax,Default_RWFunction
mov ah,[CurrentLineWriteMode]
shl ah,1
shl ah,1
shl ah,1
out dx,ax

mov ax,Default_WriteMode
out dx,ax
mov ax,Default_ColorPlane
out dx,ax

mov si,[BytesPerLine]
mov ax,EGAVideoMemory
mov es,ax

mov ax,[Y]
mov bx,[X1]
call Do_PixelAddr_EGAVGA
(* ES:BX -> video buffer *)
(* CL := # bits to shift left *)
mov di,bx (* ES:DI -> buffer *)

mov dx,0FFFFh (* DH := unshifted bit mask for leftmost *)
(* byte *)
shr dh,cl (* DH := bit mask for first byte *)

mov cx,[x2]
and cl,7
xor cl,7 (* CL := number of bits to shift left *)
shl dl,cl (* DL := bit mask for last byte *)

(* determine byte offset of first and last pixel in the line *)

mov ax,[x2] (* AX := x2 *)
mov bx,[x1] (* BX := x1 *)

mov cl,3 (* number of bits to shift to *)
(* convert pixels to bytes *)

shr ax,cl (* AX := byte offset of x2 *)
shr bx,cl (* BX := byte offset of x1 *)
mov cx,ax
sub cx,bx (* CX := (# bytes in line) - 1 *)

(* get Graphics Controller port address into DX *)

mov bx,dx (* BH := bit mask for first byte *)
(* BL := bit mask for last byte *)
mov dx,3CEh (* DX := Graphics Controller port *)
mov al,8 (* AL := Bit Mask Register number *)
mov si,[CharMapPtr]

(* set pixels in leftmost byte of the line *)

or bh,bh
js @L43 (* jump if byte-aligned (x1 is leftmost *)
(* pixel in byte) *)
or cx,cx
jnz @L42 (* jump if more than one byte in the line *)

and bl,bh (* BL := bit mask for the line *)
jmp @L44

@L42: mov ah,bh (* AH := bit mask for 1st byte *)
mov bh,[CurrentGraphWindow]
cmp [si],bh
jnz @L42a
out dx,ax (* update Graphics Controller *)
or es:[di],al (* update bit planes *)
@L42a:
inc di
inc si
dec cx

(* use a fast 8086 machine instruction to draw the remainder of the line *)

@L43: jcxz @L44
mov ah,11111111b (* AH := bit mask *)
out dx,ax (* update Bit Mask Register *)
mov ah,[CurrentGraphWindow]

@L43a: cmp [si],ah
jnz @L43b
or es:[di],al (* update bit planes *)
@L43b: inc si
inc di
loop @L43a

(* set pixels in the rightmost byte of the line *)

@L44: mov ah,bl (* AH := bit mask for last byte *)
mov bl,[CurrentGraphWindow]
cmp [si],bl
jnz @L44a
out dx,ax (* update Graphics Controller *)
or es:[di],al
@L44a: sti

end;

(*Version 3 of this draw routine - includes partial overwrite protection *)
procedure Draw_Any_Line_EGAVGA(X1,Y1,X2,Y2:word;Color:byte); assembler;
asm
cli
push bp
mov ax,[Y1]
mov bx,[X1]
call Do_TextAddr_EGAVGA
mov [CharMapPtr],si
mov [BitShift],dx
mov [NegBitShift],bx
mov [ReInitBit],ax

mov dx,EGAGraphController

mov ah,[Color]
xor al,al
out dx,ax

mov ax,Set_EnableSR+UseSR
out dx,ax

mov ax,Default_RWFunction
mov ah,[CurrentLineWriteMode]
shl ah,1
shl ah,1
shl ah,1
out dx,ax

mov ax,Default_WriteMode
out dx,ax
mov ax,Default_ColorPlane
out dx,ax

mov si,[BytesPerLine]
mov ax,EGAVideoMemory
mov es,ax

mov cx,[x2]
sub cx,[x1]


@L01: mov bx,[y2]
sub bx,[y1] (* BX := y2 - y1 *)

jns @L03 (* jump if slope is positive *)
push [NegBitShift] (* Start with negative bit shift *)
pop [BitShift]
neg bx (* BX := y1 - y2 *)
neg si (* negate increment for buffer interleave *)

(* select appropriate routine for slope of line *)

@L03: mov [VARvertincr],si (* save vertical increment *)
mov byte ptr [VARSlope],0
cmp bx,cx
jle @L04 (* jump if dy <= dx (slope <= 1) *)
mov byte ptr [VARslope],1
xchg bx,cx (* exchange dy and dx *)

(* calculate initial decision variable and increments *)

@L04: shl bx,1 (* BX := 2 * dy *)
mov [VARincr1],bx (* incr1 := 2 * dy *)
sub bx,cx
mov si,bx (* SI := d = 2 * dy - dx *)
sub bx,cx
mov [VARincr2],bx (* incr2 := 2 * (dy - dx) *)

(* calculate first pixel address *)

push cx (* preserve this register *)
mov ax,[y1] (* AX := y *)
mov bx,[x1] (* BX := x *)
call Do_PixelAddr_EGAVGA
(* ES:BX -> buffer *)
(* CL := # bits to shift left *)

mov di,bx (* ES:DI -> buffer *)
mov ah,080h
shr ah,cl (* AH := bit mask in proper position *)
mov bl,ah (* AH,BL := bit mask *)
mov al,8 (* AL := Bit Mask Register number *)
pop cx (* restore this register *)
inc cx (* CX := # of pixels to draw *)

mov bp,[CharMapPtr]
mov bh,[CurrentGraphWindow]

cmp byte ptr [VARSlope],1
jz @HiSlopeLine

(* Use BP for CharMapPtr and BH for CurrentWindowId *)

@L10: mov ah,bl (* AH := bit mask for next pixel *)

@L11: or ah,bl (* mask current pixel position *)
ror bl,1 (* rotate pixel value *)
jc @L14 (* jump if bit mask rotated to *)
(* leftmost pixel position *)
(* bit mask not shifted out *)

or si,si (* test sign of d *)
jns @L12 (* jump if d >= 0 *)

add si,[VARincr1] (* d := d + incr1 *)
loop @L11

cmp ds:[bp],bh
jnz @L11a

out dx,ax (* update Bit Mask Register *)
or es:[di],al (* set remaining pixel(s) *)
@L11a:
jmp @LineDone

@L12: add si,[VARincr2] (* d := d + incr2 *)
cmp ds:[bp],bh
jnz @L12a

out dx,ax (* update Bit Mask Register *)
or es:[di],al (* update bit planes *)

@L12a: add di,[VARvertincr] (* increment y *)
rol word ptr [BitShift],1
jnc @L12b

add bp,[VARVertincr]
push [ReInitBit]
pop [BitShift]

@L12b: loop @L10
jmp @LineDone

(* bit mask shifted out *)

@L14: cmp ds:[bp],bh
jnz @L14a

out dx,ax (* update Bit Mask Register ... *)
or es:[di],al (* update bit planes *)

@L14a: inc di (* increment x *)
inc bp

or si,si (* test sign of d *)
jns @L15 (* jump if non-negative *)

add si,[VARincr1] (* d := d + incr1 *)
loop @L10
jmp @LineDone

@L15: add si,[VARincr2] (* d := d + incr2 *)
add di,[VARvertincr] (* vertical increment *)

rol word ptr [BitShift],1
jnc @L15a

add bp,[VARVertincr]
push [ReInitBit]
pop [BitShift]

@L15a: loop @L10
jmp @LineDone


(* routine for dy > dx (slope > 1) *)
(* ES:DI -> video buffer *)
(* AH = bit mask for 1st pixel *)
(* AL = Bit Mask Register number *)
(* CX = #pixels to draw *)
(* DX = Graphics Controller port addr *)
(* SI = decision variable *)

(* Use BP for CharMapPtr and BH for CurrentWindowId *)
@HiSlopeLine:

@L21: cmp ds:[bp],bh
jnz @L21a
out dx,ax (* update Bit Mask Register *)
or es:[di],al (* update bit planes *)
@L21a:
add di,[VARvertincr] (* increment y *)
rol word ptr [BitShift],1
jnc @L22

add bp,[VARVertincr] (* Update char position vertically *)
push [ReInitBit]
pop [BitShift]

@L22: or si,si (* test sign of d *)
jns @L23 (* jump if d >= 0 *)

add si,[VARincr1] (* d := d + incr1 *)
loop @L21
jmp @LineDone


@L23: add si,[VARincr2] (* d := d + incr2 *)

ror ah,1 (* rotate bit mask *)
adc di,0 (* increment DI if when mask rotated to *)
(* leftmost pixel position *)
rol ah,1
ror ah,1
adc bp,0 (* Update char position horizontally *)

loop @L21

@LineDone:
pop bp
sti
end;



procedure Do_Set_EGAVGA;
begin
Do_INIT_X:=Do_INIT_EGAVGA;
Do_DONE_X:=Do_DONE_EGAVGA;
TVGraphCursorOn_X:=@TVGraphCursorOn_EGAVGA;
TVGraphCursorOff_X:=@TVGraphCursorOff_EGAVGA;
TVUpdateCursor_X:=@TVUpdateCursor_EGAVGA;
Do_GraphMOV_X:=@Do_GraphMOV_EGAVGA;
NewJmp_GraphMOV_X:=@NewJmp_GraphMOV_EGAVGA;
Draw_Any_Line_X:=Draw_Any_Line_EGAVGA;
Draw_Horiz_Line_X:=Draw_Horiz_Line_EGAVGA;
Draw_Vert_Line_X:=Draw_Vert_Line_EGAVGA;
end;



  3 Responses to “Category : Pascal Source Code
Archive   : TVG103-S.ZIP
Filename : TVGRAPH.IN1

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/