Hi
I'm now writing a routine that will get the cursor location. The routine at the moment gets the Cursor_Location_Low Register and puts it in BL and puts the Cursor_Location_High register into BH so BX has the complete location.
The problem I have is with converting the word in BX to a column row co-ordinate, what algorithm do I use?
I know that for going the other way it's
(row*width) + column
Thanks
Steven Graham
Getting Cursor Location
Re:Getting Cursor Location
if you know it one way, you know it the other way.
value / (width*2) = row
value mod (width *2) = column
value / (width*2) = row
value mod (width *2) = column
-- Stu --
Re:Getting Cursor Location
Here is my code for this (as there is no mod instruction, I am assuming mod is the same as the remainder)
the Cursor_Low_Register's value is in BL
the Cursor_High_Register's value is in BH
mov ax, 80
mov dx, 2
mul dx
mov dx, ax
mov ax, bx
div dx
mov bx, dx
After this the row is in AX and the col is in BX
The problem is that the div instruction seems to hang the machine and I know that no divide by zero is happening? What is wrong?
Thanks
Steven Graham
the Cursor_Low_Register's value is in BL
the Cursor_High_Register's value is in BH
mov ax, 80
mov dx, 2
mul dx
mov dx, ax
mov ax, bx
div dx
mov bx, dx
After this the row is in AX and the col is in BX
The problem is that the div instruction seems to hang the machine and I know that no divide by zero is happening? What is wrong?
Thanks
Steven Graham
Re:Getting Cursor Location
mod is modulous (remainder).
quicker doing SHL than mul *2
movzx eax,bx ;; move bx(value) into eax
movzx ebx,byte [col_width]
shl ebx, 1 ;; *2
idiv ebx
shr edx,1 ;; /2
edx now has COL
eax now has ROW
quicker doing SHL than mul *2
movzx eax,bx ;; move bx(value) into eax
movzx ebx,byte [col_width]
shl ebx, 1 ;; *2
idiv ebx
shr edx,1 ;; /2
edx now has COL
eax now has ROW
-- Stu --
Re:Getting Cursor Location
idiv ebx
this instruction hangs it
If it's any help, here's the whole routine (variable No_Of_Columns is a db with a value of 80):
; Get_Cursor_Pos Function --------------
; Parameters: None
; Returns: row: AX ;Return 16-bit regs so can plug straight
; col: BX ; into Set_Cursor_Pos
; Descripiton: Changes the position of the screen cursor
; Registers used: ax, bx, dx
; Flags Changed: None
Get_Cursor_Pos: ; Set CRTC Port to Register 0x0F
mov al, 0x0F
call VGA_Reg_Select
; Get the VGA Cursor Position Low Register
mov dx, crtc_addr
in al, dx
mov bl, al
; Set CRTC Port to Register 0x0E
mov al, 0x0E
call VGA_Reg_Select
; Get the VGA Cursor Position High Register
mov dx, crtc_addr
in al, dx
mov bh, al
; Now to get the figure in BX to the row and col co-ords
; value / (width*2) = row
; value mod (width*2) = col
movzx eax,bx ; move bx(value) into eax
movzx ebx, byte [No_Of_Columns]
shl ebx, 1 ;; *2
idiv ebx
shr edx,1 ;; /2
mov ebx, edx ; value in ax is row
; value in dx (the remainder)
; is now moved to BX as the
; functions return value
ret
Steven Graham
this instruction hangs it
If it's any help, here's the whole routine (variable No_Of_Columns is a db with a value of 80):
; Get_Cursor_Pos Function --------------
; Parameters: None
; Returns: row: AX ;Return 16-bit regs so can plug straight
; col: BX ; into Set_Cursor_Pos
; Descripiton: Changes the position of the screen cursor
; Registers used: ax, bx, dx
; Flags Changed: None
Get_Cursor_Pos: ; Set CRTC Port to Register 0x0F
mov al, 0x0F
call VGA_Reg_Select
; Get the VGA Cursor Position Low Register
mov dx, crtc_addr
in al, dx
mov bl, al
; Set CRTC Port to Register 0x0E
mov al, 0x0E
call VGA_Reg_Select
; Get the VGA Cursor Position High Register
mov dx, crtc_addr
in al, dx
mov bh, al
; Now to get the figure in BX to the row and col co-ords
; value / (width*2) = row
; value mod (width*2) = col
movzx eax,bx ; move bx(value) into eax
movzx ebx, byte [No_Of_Columns]
shl ebx, 1 ;; *2
idiv ebx
shr edx,1 ;; /2
mov ebx, edx ; value in ax is row
; value in dx (the remainder)
; is now moved to BX as the
; functions return value
ret
Steven Graham
Re:Getting Cursor Location
success! How come edx needed clearing? doesn't the idiv instruction do that when it writes to it?
Re:Getting Cursor Location
sure if your doing a div bx, anything in dx > 65535 doesnt count, but you should still clear dx before divide. try doign a divide with ax= 0x8000, dx = -1 and bx =100 and it wont work. its just safe to clear dx
-- Stu --
Re:Getting Cursor Location
I should've been more explicit. You can use 32 bit registers in 16-bit code, but it comes with a risk.