1

I am trying to create a drawing program that displays a block character (ASCII 219) at the current cursor location. The up, down, left, and right keys are used to navigate on the screen. F1, F2, F3, and F4 are suppose to change the color. The escape key quits the program. When using the function keys the colors don't change as I would expect. My code is as follows:

org 100h

kol db 12
wiersz db 10
kolor db 1111b

kursor:
mov ah,3
mov bh,1
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov bl,15
int 10h    

petla:
; Get keystroke
mov ah,0
int 16h
; AH = BIOS scan code
cmp ah,48h
je gora
cmp ah,50h
je dol
cmp ah,4Bh
je lewo
cmp ah,4Dh
je prawo
cmp ah,3Bh
je F1
cmp ah,3Ch
je F2
cmp ah,3Dh
je F3
cmp ah,3Eh
je F4
cmp ah,3Fh
je F5

cmp ah,1
jne petla  ; loop until Esc is pressed

mov ah,0x4c
int 0x21

gora:
sub byte [wiersz],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bx,kolor
mov cx, 1
int 10h
jmp petla

dol:
add byte [wiersz],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bx,kolor
mov cx, 1
int 10h
jmp petla

lewo:
sub byte [kol],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bx,kolor
mov cx, 1
int 10h
jmp petla

prawo:
add byte [kol],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bx,kolor
mov cx, 1
int 10h
jmp petla

F1:
mov byte [kolor], 0111b
int 21h
jmp petla
F2:
mov byte [kolor], 1001b
int 21h
jmp petla
F3:
mov byte [kolor], 0010b
int 21h
jmp petla

F4:
mov byte [kolor], 1011b
int 21h
jmp petla
F5:
mov byte [kolor], 1100b
int 21h
jmp petla

When the program is run the cursor moves around the screen with the arrows, but the block character doesn't appear, and the colors don't change. Can anyone explain why this problem may be occurring, and how I might be able to fix this code?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Milo
  • 21
  • 2
  • software-design hint: make lookup tables to map different keys to different results, rather than also duplicating the code that uses the values. Check that the scan-code is one of the ones you're looking for, then subtract the lowest value (so your arrays don't start with a bunch of padding). See http://stackoverflow.com/a/32356125/224132 for how gcc optimizes the hell out of a `switch` that tests for a value being in a set. If the scan-codes aren't dense enough for arrays to be good, you can still just branch to set values, and factor out the `int 10h` insns (BIOS calls?) – Peter Cordes Dec 01 '15 at 02:06
  • I can't help you with the actual console text color stuff; I haven't messed around with bare-metal or DOS code. Just optimizing for performance in user-space Linux. – Peter Cordes Dec 01 '15 at 02:08

1 Answers1

2

The top of your program looks like this:

org 100h

kol db 12
wiersz db 10
kolor db 1111b

kursor:

You don't actually declare this to be data, so it will actually be executed as code. In order to separate the data from the code and have the code appear first modify it to be:

org 100h

; Declare .data section. Data section will be placed in COM program after code
section .data
kol db 12
wiersz db 10
kolor db 1111b

; .TEXT section is the code section
section .text
kursor:

In this code:

kursor:
mov ah,3        ; AH=3 read cursor? Maybe AH=2 for set cursor?
mov bh,1
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov bl,15      ; Not sure this does anything useful?
int 10h        ; Not sure this does anything useful?

I am not sure what you were trying to do in the last 2 lines of code, so I think they can be removed. The lines before that seems to have been an attempt to set the cursor to an initial location on the screen. AH=2 is for setting cursor so I think the code should have been:

kursor:
mov ah,2             ; AH=2 set cursor?
mov bh,0             ; Should be page 0 (not 1)
mov dh,byte [wiersz] ; Row
mov dl,byte [kol]    ; Column
int 10h

You have 4 lines of code (one for up, down, left and right) that look like this:

mov bx,kolor

This moves the address of the kolor variable into BX. You want to move the byte value AT kolor. So the lines should have looked like this:

mov bl,[kolor]

This will move the byte value at the memory location kolor into the BL register. NASM assumes you want to move a single byte because BL is an 8 bit register.

With the changes described above, the code you may have been looking for is:

org 100h

section .data
kol db 12
wiersz db 10
kolor db 1111b

section .text
kursor:
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h

petla:
; Get keystroke
mov ah,0
int 16h
; AH = BIOS scan code
cmp ah,48h
je gora
cmp ah,50h
je dol
cmp ah,4Bh
je lewo
cmp ah,4Dh
je prawo
cmp ah,3Bh
je F1
cmp ah,3Ch
je F2
cmp ah,3Dh
je F3
cmp ah,3Eh
je F4
cmp ah,3Fh
je F5

cmp ah,1
jne petla  ; loop until Esc is pressed

mov ah,0x4c
int 0x21

gora:
sub byte [wiersz],1
mov ah,2
mov bh,0

mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov cx, 1
int 10h
jmp petla

dol:
add byte [wiersz],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bl,[kolor]
mov cx, 1
int 10h
jmp petla

lewo:
sub byte [kol],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bl,[kolor]
mov cx, 1
int 10h
jmp petla

prawo:
add byte [kol],1
mov ah,2
mov bh,0
mov dh,byte [wiersz]
mov dl,byte [kol]
int 10h
mov ah,09h
mov al,219
mov bl,[kolor]
mov cx, 1
int 10h
jmp petla

F1:
mov byte [kolor], 0111b
int 21h
jmp petla
F2:
mov byte [kolor], 1001b
int 21h
jmp petla
F3:
mov byte [kolor], 0010b
int 21h
jmp petla

F4:
mov byte [kolor], 1011b
int 21h
jmp petla
F5:
mov byte [kolor], 1100b
int 21h
jmp petla
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • Thank you for your tips, I have already changed my other codes basing on it. In the end, the solution was square bracket.. It proves my lack of knowledge so much.. Anyway, thank you again. – Milo Dec 01 '15 at 10:16
  • 1
    It appears you are new to Stackoverflow. A couple of people have helped you recently like in the [previous question](http://stackoverflow.com/a/33962074/3857942) . If there are answers that solve your problems, you should mark them as solved and give credit to the people answering. More on how to accept and why, please see this SO information: http://meta.stackexchange.com/a/5235/271768 – Michael Petch Dec 01 '15 at 15:21
  • I am very grateful. I will read it as soon as I'll have some free time. Thanks – Milo Dec 06 '15 at 09:22