upon reading i found this one,
; turns off the cursor:
CURSOROFF MACRO
PUSH AX
PUSH CX
MOV AH, 1
MOV CH, 28h
MOV CL, 09h
INT 10h
POP CX
POP AX
ENDM
; turns on the cursor:
CURSORON MACRO
PUSH AX
PUSH CX
MOV AH, 1
MOV CH, 08h
MOV CL, 09h
INT 10h
POP CX
POP AX
ENDM
and i made myself one:
;use setcursor 0 to turn off
; setcursor 1 to turn on
setcursor macro stat
local newset
push ax
push cx
xor ax,ax
mov ah,01h
mov ch,28h ; cursor off
mov cl,09h
cmp al,stat
je newset
mov ch,08h ; cursor on
newset: int 10h
pop cx
pop ax
setcursor endm
what would be the disadvantage if i use the new one?
it uses branch code to make the on/off decision
also, the original macros were a bit wasteful
MOV CH, 28h
MOV CL, 09h
could be
MOV CX, 2809h
something like this should work...
setcursor MACRO stat
push ax
push cx
mov ah,1
mov cx,809h+2000h*(stat XOR 1)
int 10h
pop cx
pop ax
setcursor ENDM
however, the values in CL and CH represent start line and stop line (character cell lines)
these may be different for different display cards/video modes, as there might be a different number of character cell lines
you may have to do a little testing :P
even so, i remember having trouble with this function
it didn't work on all graphics cards, as i recall
we used to play tricks like setting the cursor to some offscreen position - lol
i used to have a book by Ray Duncan that covered EGA and VGA internals
wish i still had it - it had a good solution
maybe there is a better way to do it by use of some of the VGA control registers
not sure any of it has meaning in the console window, where the character set is "emulated" :P
In recent times I think you can safely assume a VGA display subsystem, and not worry about the MDA/HGA/CGA/EGA specifics.
;-----------------------------------------------------------------------
; This procedure turns the hardware cursor on or off by manipulating the
; Cursor Disable Bit of the VGA CRT Controller Cursor Start Register.
;
; Note that this procedure cannot control the cursor under NTVDM.
;
; The VGA requires a relatively large number of control registers, so
; to avoid using an excessive amount of the limited (to 64K) host I/O
; port address space, the control registers for the Sequencer, CRT
; Controller, Graphics Controller, and Attribute Controller are
; accessed indirectly. This method requires only two host I/O port
; addresses per controller, one to store the address (index) of the
; target controller register, and one to read/write the controller
; register data.
;
; The value of state is interpreted as:
; 0 = turn cursor off (set Disable Bit)
; !0 = turn cursor on (clear Disable Bit)
;-----------------------------------------------------------------------
SetCursorState proc uses ax dx state:WORD
mov dx, 3d4h ; I/O port address of CRTC address register
mov al, 0ah ; index of Cursor Start Register
out dx, al ; write index to address register
mov dx, 3d5h ; I/O port address of CRTC data register
in al, dx ; read value of Cursor Start Register
test state, -1
jz @F
and al, 11011111b ; clear Disable Bit w/o changing other bits
out dx, al ; write new value to Cursor Start Register
ret
@@:
or al, 00100000b ; set Disable Bit w/o changing other bits
out dx, al ; write new value to Cursor Start Register
ret
SetCursorState endp
@Dave can you illustrate of what's happening here
mov cx,809h+2000h*(stat XOR 1)
i bitmask CX,2809H and show me something like this:
2809H = 0010_1000_0000_1001b
0809H = 0000_1000_0000_1001b
well - i we want stat=1 to be on and stat=0 to be off
but, bit 13 is the opposite, 1 iif off, 0 if on
so, i use XOR to reverse the sense of the bit
notice that this is XOR, the mathematical operator - not XOR, the instruction
also, we want the inverted value of stat to be multiplied by 2000h (bit 0 to bit 13)
stat bit 13
0 2000h
1 0000h
so, we use 2000h*(stat XOR 1)
now, we add in the other bits, which are always set (809h)
mov cx,809h+2000h*(stat XOR 1)
Michael,
Quote; Note that this procdure cannot control the cursor under NTVDM.
1) not much good, then - lol
2) typo in "procdure" :bg
it does not cause an exception
it does not work because the console window emulates the text graphics on the screen
the text graphics that are internal to the adapter are not used
i dunno if there is any way to do it, really - maybe Parker's macro works :P
seems like NTVDM ought to emulate INT 10h, function 1
Dave,
It probably would work under Windows 9x, and definitely will work under DOS.
Hi,
Well I coded up a test piece and tried it out on a few setups.
The only edits to the posted code were to make MASM 5.0
happy. I think the parameters are bad for CGA as is.
Regards,
Steve N.
Test Cursor Support
25 March 2012, from the MASM32 forum.
Cursor Settings, on: March 24, 2012, 12:09:52 am
OS/2 VDM
Full Scr, Window
"parker CURSOROFF" Works Works
"parker CURSORON"" Works Works
"dedndave setcursor" Off Works Works
"dedndave setcursor" Onf Works Works
"MichaelW SetCursorState" Off Works Works
"MichaelW SetCursorState" On Works Works
Win2k NTVDM
Full Scr, Window
"parker CURSOROFF" Works Works
"parker CURSORON"" Works Works
"dedndave setcursor" Off Works Works
"dedndave setcursor" Onf Works Works
"MichaelW SetCursorState" Off Works Nada
"MichaelW SetCursorState" On Works Nada?
WinXP NTVDM
Full Scr, Window
"parker CURSOROFF" Works Works
"parker CURSORON"" Works Works
"dedndave setcursor" Off Works Works
"dedndave setcursor" Onf Works Works
"MichaelW SetCursorState" Off Works Nada
"MichaelW SetCursorState" On Works Nada?
Win98 MS-DOS Prompt
Full Scr, Window
"parker CURSOROFF" Works Works
"parker CURSORON"" Works Works
"dedndave setcursor" Off Works Works
"dedndave setcursor" Onf Works Works
"MichaelW SetCursorState" Off Works Nada
"MichaelW SetCursorState" On Works Nada?
MS-DOS 6.22
SVGA, Pentium MMX
"parker CURSOROFF" Works
"parker CURSORON"" Works
"dedndave setcursor" Off Works
"dedndave setcursor" Onf Works
"MichaelW SetCursorState" Off Works
"MichaelW SetCursorState" On Works
MS-DOS 5.0
CGA emulation, 80186
"parker CURSOROFF" Works
After that, no cursor with unchanged parameters...
Greetings to everyone!,
Dave i made a little modification based on your previous
explaination, but i don't understand why this things work,
i don't know the value of CX after using NOT CX ::), but it works. :dazzled:
Does anyone has a program that will display the value of
all registers upon running this program, so i can visually examine
the value of all registers, thanks in advance.
setcursor MACRO stat
push ax
push cx
mov ah,1
mov cx,2000h*stat
add cx,809h
not cx
int 10h
pop cx
pop ax
setcursor ENDM
Here is the source for a test app, and a batch file that will assemble and link it, and then open it in DEBUG. From there you can just step through the code with the Proceed command (p) and watch the registers change.
;====================================================================
setcursor MACRO stat
push ax
push cx
mov ah,1
mov cx,2000h*stat
mov cx,2000h*(stat XOR 1)
add cx,809h
not cx
int 10h
pop cx
pop ax
;setcursor ENDM ; What assembler are you using?
ENDM
;====================================================================
waitkey MACRO
xor ah,ah
int 16h
ENDM
;====================================================================
.model tiny
.code
org 100h
start:
;waitkey
setcursor 0
;waitkey
setcursor 1
;waitkey
int 20h
end start
;====================================================================
set file=test
set path=d:\masm32\bin;%PATH%
ml /W3 /c %file%.asm
pause
Link16 /TINY /MAP %file%.obj,%file%.com;
pause
debug %file%.com
I am suggesting the Proceed command instead of the Trace command (t), because unlike the Trace command it will step over the interrupt calls, instead of tracing into them. The Proceed and Trace commands automatically display the registers after each step.
You can force a display of the registers with the Register command (r).
You can restart the code with the sequence:
rip <Enter>
100 <Enter>
The first Enter will cause DEBUG to prompt for the new value. Or you can use a similar sequence to edit the value of registers other than IP (for example, the sequence would start with rcx to edit the value of the CX register).
And you can exit DEBUG with the quit command (q).
Michael,
I passed this code to my pal
mov cx,2000h*stat
add cx,809h
not cx
and ask him a favor to compiled this one for me,
when i get back he mailed the video and it is working, not knowing that he use an emulator, (my apology).
But when i compiled this one using masm32 and followed the steps you gave me,
it turns not working, i also found out that after NOT CX, CX became D7F6H which is far from
2809H (off) and 0809h (on). Thanks for the procedure, honestly it's my 1st time to use DEBUG lol :lol
BTW, my o.s. is XP SP3 and AOC 917Vw+ monitor.