News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Cursor Settings

Started by parker, March 24, 2012, 06:09:52 AM

Previous topic - Next topic

parker

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?
I admire the effort of everyone who tend to share their wisdom without any kind in return. Thank you guyz...!

dedndave

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

MichaelW

#2
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

eschew obfuscation

parker

@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
I admire the effort of everyone who tend to share their wisdom without any kind in return. Thank you guyz...!

dedndave

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)

dedndave

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

MichaelW

Dave,

It probably would work under Windows 9x, and definitely will work under DOS.
eschew obfuscation

FORTRANS

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...

parker

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
I admire the effort of everyone who tend to share their wisdom without any kind in return. Thank you guyz...!

MichaelW

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).
eschew obfuscation

parker

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.

I admire the effort of everyone who tend to share their wisdom without any kind in return. Thank you guyz...!