x86 Assembly

Moderators: None (Apply to moderate this forum)
Number of threads: 4556
Number of posts: 16011

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Problem with moving cursor Posted by demon530007 on 28 Nov 2007 at 1:04 AM
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:
;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


Report
Re: Problem with moving cursor Posted by AsmGuru62 on 28 Nov 2007 at 5:03 AM
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:
+------+------+-------+
| Home | Up   | PgUp  |
+------+------+-------+
| Left |      | Right |
+------+------+-------+
| End  | Down | PgDn  |
+------+------+-------+

Report
Re: Problem with moving cursor Posted by demon530007 on 28 Nov 2007 at 5:40 AM
For the NE press up and right arrow together, SE: down and right arrow,
SW: down and left arrow so on. Thank you
Report
Re: Problem with moving cursor Posted by Bret on 28 Nov 2007 at 8:46 AM
: 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.
Report
Re: Problem with moving cursor Posted by jeffleyda on 28 Nov 2007 at 8:52 AM
READKEY1:  MOV   AH,0          ;read keyboard
          INT   16H           ;BIOS call


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!
Report
Re: Problem with moving cursor Posted by demon530007 on 28 Nov 2007 at 9:30 AM
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.
Report
Re: Problem with moving cursor Posted by Bret on 28 Nov 2007 at 2:17 PM
: 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.
Report
Re: Problem with moving cursor Posted by AsmGuru62 on 29 Nov 2007 at 4:57 AM
: : 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.
Or you can 'ask' DOS about current text mode. Then, you get more flexibility.



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.