Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Problem with moving cursor

I am writting a program that will move a cursor and will draw * when a mov is given. Supposly the cursor should be able to move in any direction (E,,W,S,N,SW,EN...etc) The directions for E,W,S,N are fine but SW, EW, NW are not working. Everytime I press NE it will draw * in N, *in E then * in NE. I just want draw * in NE direction. Also, the cursor should reaches the end of the screen it should wrap around to the other side of the screen, but I have no idea how to do that? Someone please help me out, thank you for your time.
Here is my code:
[code];Program XYDRAW.ASM: Draw simple figures on a color 25 by 80 screen.
;
.MODEL SMALL
.DATA

ROW DB 12 ;initial cursor position
COL DB 40
COLOR DB 7 ;start with green
SKIP DB 0 ;start with skip FALSE (drawing)
ERASE DB 1 ;start with skip TRUE (NO ERASE)
HELP DB 'D: Draw, S: Skip, E: Erase, C:Clear Screen, Move: Arrow Keys , '
DB 'Q: Quit $'

ORG 140H

MOV DX,143H ; Initializes the port for output
MOV AL,2 ; ?
OUT DX,AL ; ?

MOV DX,140H ; ?
MOV AL,0FFH ; ?
OUT DX,AL ; ?

MOV DX,143H ; ?
MOV AL,03H ; ?
OUT DX,AL ; ?

MOV DX,143H ; Initializes the port for input
MOV AL,2 ; ?
OUT DX,AL ; ?

MOV DX,141H ; ?
MOV AL,00H ; ?
OUT DX,AL ; ?

MOV DX,143H ; ?
MOV AL,03H ; ?
OUT DX,AL ; ?


.CODE
.STARTUP
START: MOV AH,0 ;set video mode
MOV AL,3 ;80 x 25 color
INT 10H ;video BIOS call
MOV AH,2 ;set cursor position
MOV BH,0 ;display page number
MOV DH,24 ;bottom row
MOV DL,7 ;column number
INT 10H ;video BIOS call
LEA DX,HELP ;set up pointer to help message
MOV AH,9 ;display string
INT 21H ;DOS call
MOV AH,2 ;set cursor position
MOV BH,0 ;display page number
MOV DH,ROW ;row number
MOV DL,COL ;column number
INT 10H ;video BIOS call
READKEY: MOV AH,0 ;read keyboard
INT 16H ;BIOS call
CMP AL,0 ;check scan code?
JZ CSC
CMP AL,'a' ;test for lower case
JC NOLC
CMP AL,'z'+1
JNC NOLC
AND AL,0DFH ;convert to upper case
NOLC: CMP AL,'Q' ;quit?
JNZ X1
JMP EXIT
X1: CMP AL,'S' ;skip?
JZ SETSKIP
CMP AL,'D' ;draw?
JZ SETDRAW
CMP AL,'E'
JZ SETERASE
CMP AL,'C'
JZ SETCLEAR
JMP READKEY

SETCLEAR: JMP START
SETSKIP: MOV SKIP,1 ;skip is true
JMP READKEY
SETERASE: MOV ERASE,0 ;
JMP READKEY1
SETDRAW: MOV SKIP,0 ;skip is false
JMP READKEY
READKEY1: MOV AH,0 ;read keyboard
INT 16H ;BIOS call
CMP AL,0 ;check scan code?
JZ CSX
CMP AL,'a' ;test for lower case
JC NOLC
CMP AL,'z'+1
JNC NOLC
AND AL,0DFH ;convert to upper case
JMP X1





CSC: CMP AH,48h ;up arrow?
JZ GOUP
CMP AH,50H ;down arrow?
JZ GODOWN
CMP AH,4BH ;left arrow?
JZ GOLEFT
CMP AH,4DH ;right arrow?
JZ GORIGHT
JMP READKEY ;did not get a valid input
GOUP: CMP ROW,0 ;ignore if first row
JNZ GOUP2
JMP READKEY
GOUP2: SUB ROW,1
JMP PATTERN1

GODOWN: CMP ROW,23 ;ignore if last row
JNZ GODOWN2
JMP READKEY
GODOWN2: ADD ROW,1
JMP SETCUR
GOLEFT: CMP COL,0 ;ignore if first column
JNZ GOLEFT2
JMP READKEY
GOLEFT2: SUB COL,1
JMP SETCUR
GORIGHT: CMP COL,79 ;ignore if last column
JNZ GORIGHT2
JMP READKEY
GORIGHT2: ADD COL,1
SETCUR: MOV AH,2 ;set cursor position
MOV BH,0 ;display page number
MOV DH,ROW ;row number
MOV DL,COL ;column number
INT 10H ;video BIOS call
CMP SKIP,1 ;skip if true
JZ NOC
MOV AL,'*' ;write * to screen
MOV BL,COLOR
MOV CX,1
MOV AH,9
INT 10H ;video BIOS call
NOC: JMP READKEY
CSX: CMP AH,48h ;up arrow?
JZ GOUP1
CMP AH,50H ;down arrow?
JZ GODOWN1
CMP AH,4BH ;left arrow?
JZ GOLEFT1
CMP AH,4DH ;right arrow?
JZ GORIGHT1
JMP READKEY1 ;did not get a valid input
GOUP1: CMP ROW,0 ;ignore if first row
JNZ GOUP3
JMP READKEY1
GOUP3: SUB ROW,1
JMP SETCUR1 ;reposition cursor
GODOWN1: CMP ROW,23 ;ignore if last row
JNZ GODOWN3
JMP READKEY1
GODOWN3: ADD ROW,1
JMP SETCUR1
GOLEFT1: CMP COL,0 ;ignore if first column
JNZ GOLEFT3
JMP READKEY1
GOLEFT3: SUB COL,1
JMP SETCUR1
GORIGHT1: CMP COL,79 ;ignore if last column
JNZ GORIGHT3
JMP READKEY1
GORIGHT3: ADD COL,1
SETCUR1: MOV AH,2 ;set cursor position
MOV BH,0 ;display page number
MOV DH,ROW ;row number
MOV DL,COL ;column number
INT 10H ;video BIOS call
CMP ERASE,1 ;skip if true
JZ NOC
MOV AL,' ' ;write to screen
MOV BL,COLOR
MOV CX,1
MOV AH,9
INT 10H ;video BIOS call
JMP READKEY1
PATTERN1: MOV DX,140H
MOV AL,11111111B
MOV DX,140H
OUT DX,AL
JMP SETCUR ;reposition cursor

EXIT: .EXIT

END[/code]

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]So, how do you give NE command? If you first press 'N', then press 'E', than that's what the code will do: you need a single key to do every command. Maybe, try these keys - quite natural for movement:
    [code]
    +------+------+-------+
    | Home | Up | PgUp |
    +------+------+-------+
    | Left | | Right |
    +------+------+-------+
    | End | Down | PgDn |
    +------+------+-------+
    [/code]
    [/color]
  • demon530007demon530007 Member Posts: 4
    For the NE press up and right arrow together, SE: down and right arrow,
    SW: down and left arrow so on. Thank you
  • BretBret Member Posts: 114
    : For the NE press up and right arrow together, SE: down and right
    : arrow,
    : SW: down and left arrow so on. Thank you

    It's virtually impossible to press two keys at EXACTLY the same time, and even if you did, the computer would simply pick one or the other as the first one. They only go into (and get read from) the keyboard buffer one key at a time, so you can't easily tell if multiple keys were pressed at approximately the same time or not.

    There are two options that I can think of. You can either set up some sort of timing loop, where you don't actually write anything to the screen until some time after you "see" the keystroke (waiting to see if another keystroke is pressed before the timing loop expires). The other option is to use different keystrokes for the diagonal movements, as suggested earlier. Using different keystrokes is much easier to implement -- setting up timing loops can get pretty tricky.
  • jeffleydajeffleyda Member Posts: 390
    [code]
    READKEY1: MOV AH,0 ;read keyboard
    INT 16H ;BIOS call
    [/code]

    INT 16h isn't set up to handle multiple keypresses at the same time, so your up and left combo will get returned to your program as up and then left on the next int 16 call.

    http://www.delorie.com/djgpp/doc/rbinter/id/63/17.html

    I would suggest the keyboard mapping as suggested by asmGuru to allow your program to work with a single key to do diagonal movements. That's the easiest way.

    -jeff!
  • demon530007demon530007 Member Posts: 4
    Thanks all! Does anyone know how to make cursor wrap around to the other side of the screen when it reaches the end of the screen? Thanks.
  • BretBret Member Posts: 114
    : Thanks all! Does anyone know how to make cursor wrap around to the
    : other side of the screen when it reaches the end of the screen?
    : Thanks.

    You should just be able to change the row and column numbers appropriately and reposition the cursor. If you're at the right edge of the screen and move right, for example, you leave the row unchanged and change the column number to 0 (instead of incrementing by 1). Of course, such calculations require that you know how many rows and columns the screen has -- not a problem if you can guarantee the screen will always be 25 rows x 80 columns.
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : : Thanks all! Does anyone know how to make cursor wrap around to the
    : : other side of the screen when it reaches the end of the screen?
    : : Thanks.
    :
    : You should just be able to change the row and column numbers
    : appropriately and reposition the cursor. If you're at the right
    : edge of the screen and move right, for example, you leave the row
    : unchanged and change the column number to 0 (instead of incrementing
    : by 1). Of course, such calculations require that you know how many
    : rows and columns the screen has -- not a problem if you can
    : guarantee the screen will always be 25 rows x 80 columns.
    [color=Blue]Or you can 'ask' DOS about current text mode. Then, you get more flexibility.[/color]
Sign In or Register to comment.