[comp.sys.ibm.pc] Cursor question

dougm@kuhub.cc.ukans.edu (Douglas Miller) (12/04/88)

Here is an improve version of the cursor program.  It is set up as an
assembly procedure to be linked (see DEMO) during compilation of your TURBO
4.0 program.  I have tested it on both an IBM and a ZENITH and it works.  You
should run MASM on CURSOR.asm and then place CURSOR.obj in the subdirectory
where you plan to compile.  I suppose it will also work with TURBO C but I
can't say for sure.

Doug
******************************************************************************
                             ASSEMBLY PROCEDURE TO
                                 SET THE CURSOR
******************************************************************************
                             -------cut here--------
;                          CURSOR.asm
;
; This program will turn on the cursor at the 6845 CRT controller.
;
;            Constants
;
ADDRPORT = 03D4H
DATAPORT = 03D5H
;
CODE    SEGMENT BYTE PUBLIC 'CODE'
        ASSUME CS:CODE
        PUBLIC CURSOR
CURSOR  PROC NEAR
        MOV BX,SP
        MOV AL,SS:[BX+2]                   ;Get byte passed by pascal
        CMP AL,0
        JE OFF
        CMP AL,1
        JE ON
        JMP SHORT TERM
OFF:    MOV DX,ADDRPORT
        MOV AL,10                        ;10d sent to the address port
        OUT DX,AL                        ; sets up the cursor start reg.
        MOV DX,DATAPORT
        MOV AL,20H                       ;Cursor off code
        OUT DX,AL
        JMP SHORT TERM
ON:     MOV DX,ADDRPORT
        MOV AL,10
        OUT DX,AL
        MOV DX,DATAPORT
        MOV AL,6H                        ;Standard DOS 2-line cursor
        OUT DX,AL                        ; starts at 6 and ends at 7
        MOV DX,ADDRPORT                  ;Insert other values depending on
        MOV AL,11                        ; your desires and the demands
        OUT DX,AL                        ; of your system.  I haven't tried
        MOV DX,DATAPORT                  ; on anything other than CGA.
        MOV AL,7H                        ;11d sent to the addr port sets
        OUT DX,AL                        ; up the cursor end reg.
TERM:   RET 2
CURSOR  ENDP
CODE    ENDS
        END CURSOR
                       ---------cut here--------
*****************************************************************************
                             PASCAL DEMO PROGRAM
                               (uses TURBO 4.0)
*****************************************************************************
                        ---------cut here--------
program cursor1;

uses
  Crt;

var
  c : Char;

{$L CURSOR.OBJ}
procedure cursor(off_on : Byte); external;      {[0=off, 1=on]}

begin
  writeln('Turning cursor off');
  cursor(0);
  c := ReadKey;
  writeln('Turning cursor on');
  cursor(1);
  c := ReadKey;
end.

schanck@dinghy.cis.ohio-state.edu (Christopher Schanck) (12/05/88)

In article <2021@kuhub.cc.ukans.edu> dougm@kuhub.cc.ukans.edu (Douglas Miller) writes:
>
>Here is an improve version of the cursor program.  It is set up as an
>        OUT DX,AL                        ; of your system.  I haven't tried
>        MOV DX,DATAPORT                  ; on anything other than CGA.
					    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
You would have been irked if you had; it won't work. The EGA and the BIOS
don't work towell together when it comes to scan lines. Start/End lines
which give no cursor on CGA give sort of a block on EGA. It is a colossal
pain. The following routines are for TC, but could be converted easily.

/* you will have to figure the includes */
Joel,

Try these routines; they work beautifully for me. You can see what I 
did -- judicious use of the old variable argument list makes it go. 
writef() at the moment accepts x and y coordinates, and attribute, and 
a standard cprintf call, i.e.:

writef(10,20,BLUE+(WHITE<<4),"The number is: %i\n",number);

where number is an integer. After the cputs, it moves the cursor off 
the screen. Notice you really need the x and y coords, since it 
repositions the cursor each time. But itis super nice for the job it 
was designed, and it is quick if you use directvideo and some other TC 
tricks. The cursheight routine is simple; if the height requested is 
0, it runs the cursor off. Any other number and it simply changes the 
size. For instance, in my editing routine, I use cursheight(1) for 
overwrite mode, and cursheight(3) for insert. Hope this helps.

/* you made need more includes; I pulled these routines out of other
rather large files.... */

void cursheight(int x){
   struct REGPACK sregs;
   if(x!=0){
      sregs.r_ax=256;
      sregs.r_cx=(8-x)*256+7;
   }
   else{
      sregs.r_ax=512;
      sregs.r_dx=0x1a00;
      sregs.r_bx=0;
   }
   intr(0x10,&sregs);
}

void writef(int x, int y, int attrib, va_list arg_list, ...){
   char output[129];
   char *format;
   va_list arg_ptr;
   format=arg_list;
   va_start(arg_ptr, arg_list);
   vsprintf(output, format, arg_ptr);
   textattr(attrib);
   gotoxy(x,y);
   cputs(output);
   cursheight(0);
}

Apologies to Joel, who got these yesterday.

Chris
-=-
"My brain is NOT a deadlock-free environment!!!!"
--- Christopher Schanck, mammal at large.
schanck@flounder.cis.ohio-state.edu