Text Mode Cursor: Difference between revisions
[unchecked revision] | [unchecked revision] |
1 |
|||
Line 115: | Line 115: | ||
made by Elad Ashkcenazi |
made by Elad Ashkcenazi |
||
;============================================================================= |
;============================================================================= |
||
disable_cursor: |
disable_cursor: pushf |
||
push rax |
push rax |
||
push rdx |
push rdx |
||
Line 128: | Line 128: | ||
pop rdx |
pop rdx |
||
pop rax |
pop rax |
||
popf |
|||
ret |
ret |
||
</source> |
</source> |
||
==See Also== |
==See Also== |
Revision as of 04:52, 16 June 2017
Moving the Cursor with the BIOS
Moving the cursor with the BIOS is done through Int 0x10 (The general interrupt for screen functions) with AH set to 0x02. These are the registers used:
- AH = 0x02
- BH = Display Page (This is usually, if not always, 0)
- DH = The row
- DL = The column
Then, with a quick call to interrupt 0x10, you should have yourself a movable type cursor.
Moving the Cursor without the BIOS
Without access to BIOS calls and functions, moving the cursor requires using video hardware control. Lucky it is a simple procedure.
Note, this quick example assumes 80x25 screen mode. Also note that the base port (here assumed to be 0x3D4) should be read from the BIOS data area.
Source in C
/* void update_cursor(int row, int col)
* by Dark Fiber
*/
void update_cursor(int row, int col)
{
unsigned short position=(row*80) + col;
// cursor LOW port to vga INDEX register
outb(0x3D4, 0x0F);
outb(0x3D5, (unsigned char)(position&0xFF));
// cursor HIGH port to vga INDEX register
outb(0x3D4, 0x0E);
outb(0x3D5, (unsigned char )((position>>8)&0xFF));
}
Note that the 2 parameters 'row' & 'col' passed to the function above start from zero, not from 1. And keep in mind that in/out to VGA Hardware is a slow operation. So using the hardware registers to remember of the current character location (row, col) is bad practice -- and updating position after each displayed character is poor practice (updating it only when a line/string is complete is wiser and hiding it until a user prompt is wisest)
Source in assembly
Since BIOS services can't be accessed in 64bit long mode, the following routine shows how to move cursor without BIOS in VGA text 80x25 (can be altered a bit to fit protected mode):
; Set cursor position (text mode 80x25)
; @param BL The row on screen, starts from 0
; @param BH The column on screen, starts from 0
;=============================================================================
set_cursor: pushfq
push rax
push rbx
push rcx
push rdx
;unsigned short position = (row*80) + col;
;AX will contain 'position'
mov ax,bx
and ax,0ffh ;set AX to 'row'
mov cl,80
mul cl ;row*80
mov cx,bx
shr cx,8 ;set CX to 'col'
add ax,cx ;+ col
mov cx,ax ;store 'position' in CX
;cursor LOW port to vga INDEX register
mov al,0fh
mov dx,3d4h ;VGA port 3D4h
out dx,al
mov ax,cx ;restore 'postion' back to AX
mov dx,3d5h ;VGA port 3D5h
out dx,al ;send to VGA hardware
;cursor HIGH port to vga INDEX register
mov al,0eh
mov dx,3d4h ;VGA port 3D4h
out dx,al
mov ax,cx ;restore 'position' back to AX
shr ax,8 ;get high byte in 'position'
mov dx,3d5h ;VGA port 3D5h
out dx,al ;send to VGA hardware
pop rdx
pop rcx
pop rbx
pop rax
popfq
ret
Disabling The Cursor With the BIOS
Moving the cursor with the BIOS is done through Int 0x10 (The general interrupt for screen functions) with AH set to 0x02. These are the registers used:
- AH = 0x01
- CH = 0x3f ; bits 6-7 are unused , if bit 5 set the cursor is disable (this bit may be cleared in the interrupt caller , see "Disabling The Cursor Without the BIOS" for safer way to disable the cursor) , bits 0-4 controll the cursor shape (if bits 0-4 all set the cursor is unvisiable regradless what's bit 5's state.)
And then Interrupt 0x10 and then vuala , there is no *VISIBLE cursor on the screen
- Even on GUI modes the cursor remains active so don't think about it to much.
Disabling The Cursor Without the BIOS
Source in C
/* void disable_cursor()
* by Elad Ashkcenazi
*/
void update_cursor()
{
outb(0x3D4, 0x0A);
outb(0x3D5, 0x3f); bits 6-7 must be 0 , if bit 5 set the cursor is disable , bits 0-4 controll the cursor shape (if bits 0-4 all set the cursor is unvisiable regardless what's bit 5 state.)
// cursor shape port to vga INDEX register
}
Source in assembly
made by Elad Ashkcenazi
;=============================================================================
disable_cursor: pushf
push rax
push rdx
mov dx,0x3d4
mov al,0xa ; index 0xa is the LOW cursor shape register
out dx,al
inc dx
mov al,0x3f ; bits 6-7 must be 0 , if bit 5 set the cursor is disable , bits 0-4 controll the cursor shape (if bits 0-4 all set the cursor is unvisiable regardless what's bit 5 state.)
out dx,al
pop rdx
pop rax
popf
ret