[Back to CURSOR SWAG index] [Back to Main SWAG index] [Original]
{ Author: Chad Moore
I have been writing my own multipurpose units for projects for quite some
time now, and I noticed how all of the cursor routines in the SWAG used
BIOS calls, well, I just happened to be writing an extended display unit
for use with my display unit, and I figured you all could enjoy my
routines. They may not be as optomized as they could be, but they work.
So, in other words, rip it, steal it, use it, distribute it, etc.
Some of them may screw up while using the Crt unit, because it keeps track
of cursor movement itself... (remember, I have my OWN display unit...I
hate the Crt one) Anyway, they all DO work, but I am not responsible for
any damages caused by these routines. Oh, and the routines are all based
on 0 through whatever - 1, rather than 1 through whatever. (the way the
computer would do it)
If you would like to get information on the CRTC registers (the ones I
used for this), Mode-X, sound, XMS/EMS/conventional memory, 3-D graphics,
and much more, I recomend this book:
PC Underground Unconventional Programming Topics
from Abacus...
}
{ Extended alphanumeric display unit }
unit XDisplay;
{$G+} { Enable 286 instructions }
interface
procedure CursorOn;
{ turns the cursor ON }
procedure CursorOff;
{ turns the cursor OFF }
function CursorState : Boolean;
{ returns TRUE if the cursor is ON }
procedure CursorShape( StartScan, EndScan : Byte );
{ defines the cursor shape }
function GetCursorShape : Word;
{ high 8 bits = startscan, low 8 bits = endscan }
procedure CursorPosition( Column, Row : Byte );
{ positions the cursor }
function CursorColumn : Byte;
{ returns the cursor column }
function CursorRow : Byte;
{ returns the cursor row }
implementation
procedure CursorOn; assembler;
asm
MOV DX,03D4H { CRTC index register }
MOV AL,0AH { select register 0Ah }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
AND AL,0DFH { bit 5 = 0 (Cursor on) }
OUT DX,AL
end;
procedure CursorOff; assembler;
asm
MOV DX,03D4H { CRTC index register }
MOV AL,0AH { select register 0Ah }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
OR AL,20H { bit 5 = 1 (Cursor off) }
OUT DX,AL
end;
function CursorState : Boolean; assembler;
asm
MOV DX,03D4H { CRTC index register }
MOV AL,0AH { select register 0Ah }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
AND AL,20H { if bit 5 = 1, cursor is off }
CMP AL,20H { is bit 5 on? }
JE @@cursoroff
MOV AL,TRUE { no, cursor is on }
JMP @@done { return }
@@cursoroff:
MOV AL,FALSE { yes, cursor is off }
@@done:
end;
procedure CursorShape( StartScan, EndScan : Byte ); assembler;
asm
MOV DX,03D4H { CRTC index register }
MOV AL,0AH { select register 0Ah }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
MOV AH,StartScan
AND AL,0E0H { clear bits 0-4 }
OR AL,AH { bits 0-4 = StartScan, save bits 5-7 }
OUT DX,AL
DEC DX { CRTC index register }
MOV AL,0BH { select register 0Bh }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
MOV AH,EndScan
AND AL,0E0H { clear bits 0-4 }
OR AL,AH { bits 0-4 = EndScan, save bits 5-7 }
OUT DX,AL
end;
function GetCursorShape : Word; assembler;
asm
MOV DX,03D4H { CRTC index register }
MOV AL,0AH { select register 0Ah }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
AND AL,1FH { clear bits 5-7 }
MOV AH,AL { AH = startscan }
DEC DX { CRTC index register }
MOV AL,0BH { select register 0Bh }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get status }
AND AL,1FH { clear bits 5-7 }
end;
procedure CursorPosition( Column, Row : Byte ); assembler;
asm
{ get cursor offset into BX }
MOV DX,03D4H { CRTC index register }
MOV AL,13H { select register 13H }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX
MOV AH,AL { store row offset in AH }
DEC DX { CRTC index register }
MOV AL,14H { select register 14H }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX
SHL AH,01H { multiply by 2 }
AND AL,40H { check bit 5 for doubleword addressing }
CMP AL,00H { doubleword? }
JE @@continue { no, continue }
SHL AH,01H { yes, multiply by 2 *more* }
@@continue:
{ AH = row length }
SHR AX,08H { AX = row length }
MUL Row { row length * Row }
MOV BL,Column
XOR BH,BH
ADD AX,BX { + Column }
MOV BX,AX { BX = cursor offset }
{ send BX to CRTC }
DEC DX { CRTC index register }
MOV AL,0EH { select register 0EH (cursor offset HIGH) }
OUT DX,AL
INC DX { CRTC data register }
MOV AL,BH { get HIGH to send }
OUT DX,AL
DEC DX { CRTC index register }
MOV AL,0FH { select register 0FH (cursor offset LOW) }
OUT DX,AL
INC DX { CRTC data register }
MOV AL,BL { get LOW to send }
OUT DX,AL
end;
function CursorColumn : Byte; assembler;
asm
{ get cursor offset }
MOV DX,03D4H { CRTC index register }
MOV AL,0EH { select register 0Eh }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX
SHL AX,08H { AH = high bits }
DEC DX { CRTC index register }
MOV AL,0FH { select register 0Fh }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { AL = low bits }
MOV CX,AX { save cursor offset }
{ get chars per line }
DEC DX { CRTC index register }
MOV AL,14H { select register 14h }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { doubleword addressing? }
MOV BL,AL { save in BL }
DEC DX { CRTC index register }
MOV AL,13H { select register 13h }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get offset between 2 lines (line width) }
SHL AL,01H { multiply by 2 }
AND BL,40H { check bit 5 for doubleword addressing }
CMP BL,00H { doubleword? }
JE @@continue { no, continue }
SHL AL,01H { multiply by 2 *more* }
@@continue: { AL = chars per line }
{ calculate }
XOR AH,AH { clear upper AX }
MOV BX,AX { get chars per line in BX }
XOR DX,DX { DX:AX gets ready for div }
MOV AX,CX { get cursor offset }
DIV BX { div DX = remainder, AX = answer }
MOV AX,DX { get remainder }
end;
function CursorRow : Byte; assembler;
asm
{ get cursor offset }
MOV DX,03D4H { CRTC index register }
MOV AL,0EH { select register 0Eh }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX
SHL AX,08H { AH = high bits }
DEC DX { CRTC index register }
MOV AL,0FH { select register 0Fh }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { AL = low bits }
MOV CX,AX { save cursor offset }
{ get chars per line }
DEC DX { CRTC index register }
MOV AL,14H { select register 14h }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { doubleword addressing? }
MOV BL,AL { save in BL }
DEC DX { CRTC index register }
MOV AL,13H { select register 13h }
OUT DX,AL
INC DX { CRTC data register }
IN AL,DX { get offset between 2 lines (line width) }
SHL AL,01H { multiply by 2 }
AND BL,40H { check bit 5 for doubleword addressing }
CMP BL,00H { doubleword? }
JE @@continue { no, continue }
SHL AL,01H { multiply by 2 *more* }
@@continue: { AL = chars per line }
{ calculate }
XOR AH,AH { clear upper AX }
MOV BX,AX { get chars per line in BX }
XOR DX,DX { DX:AX gets ready for div }
MOV AX,CX { get cursor offset }
DIV BX { div DX = remainder, AX = answer }
{ returns AL }
end;
end.
[Back to CURSOR SWAG index] [Back to Main SWAG index] [Original]