WITHOUT BIOS: Get Cursor X and Y
- matias_beretta
- Member
- Posts: 101
- Joined: Mon Feb 26, 2007 3:39 pm
WITHOUT BIOS: Get Cursor X and Y
How to Get Cursor X and Y without B. I. O. S.
- matias_beretta
- Member
- Posts: 101
- Joined: Mon Feb 26, 2007 3:39 pm
more info
Yes yes...Do you mean the blinking line that usually indicates where the next character will go?
Re: more info
That is a two-stroke approach. That "blinking line" does not indicate where the next character will go, but instead represents the current/next position in a properly designed CLI.matias_beretta wrote:Yes yes...Do you mean the blinking line that usually indicates where the next character will go?
The commands 0x0E and 0x0F of the VGA Index Register Port (0x03D4) allow access (at least write access to my knowledge) so go ahead and investigate that route.
All-in-all, you are dealing with direct memory access and I/O ports... not the BIOS.
You have to work with CRTC Address Register and the CRTC Data Register. The former is located at the port 0x03D4 and the latter at 0x03D5.
You can put an index into the Address Port and then read the result back from the Data Port. The location of the blinking cursor on the screen has a 16-bit value. Since you can read 8-bits at a time from each of the CRTC registers named above, you have to read the Low Order Byte and the High Order Byte of this value in two steps.
The 16-bit value that you read is the 16-bit offset of the blinking cursor from the top left corner of the screen. For example, if the cursor is at the top left corner, the value that you will get is 0. If it is at the second character on the first row, you will get 1 (0..1 = 2).
I have coded this little Assembly routine that I think will give you the idea what to do:
You can put an index into the Address Port and then read the result back from the Data Port. The location of the blinking cursor on the screen has a 16-bit value. Since you can read 8-bits at a time from each of the CRTC registers named above, you have to read the Low Order Byte and the High Order Byte of this value in two steps.
The 16-bit value that you read is the 16-bit offset of the blinking cursor from the top left corner of the screen. For example, if the cursor is at the top left corner, the value that you will get is 0. If it is at the second character on the first row, you will get 1 (0..1 = 2).
I have coded this little Assembly routine that I think will give you the idea what to do:
Code: Select all
MOV EDX , 0x00003D4 ; CRTC Address Register
MOV EAX , 0x000000E ; (Index = Cursor Location High Register)
OUT DX , AL ; Tell the CRTC about what we need
INC EDX ; EDX = CRTC Data Register (0x03D5)
IN AL , DX ; Read the High Order Byte of the cursor
MOV EBX , EAX ; Store this value in EBX
SHL EBX , 0x00000008 ; BH = High Order Byte of the cursor
MOV EAX , 0x000000F ; (Index = Cursor Location Low Register)
DEC EDX ; EDX = CRTC Address Register
OUT DX , AL ; Tell the CRTC what value we need
INC EDX ; EDX = CRTC Data Register
IN AL , DX ; Read the Low Order Byte of the cursor
OR EAX , EBX ; AH = High Order Byte, AL = Low Order Byte
XOR EDX , EDX ; Do a simple division (EDX = 0, 32-bits Div)
MOV EBX , 80 ; Divide EDX:EAX by 80 (Number of columns per row)
DIV EBX ; Divide now
; EDX = Cursor.X
; EAX = Cursor.Y
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.