How do you divide?
Posted: Sun Jan 27, 2002 12:00 am
Greetings,
I've been fooling around with the pmode initialization
stuff, and I now need to be able to write to my CRT
once when pmode is entered. So I begin writing codes to
display on the screen by writing to the video memory.
A problem that I encountered was that I need to find out
the offset that the character is to be written, and to
record down the position, as a testing program, I've been
writin it out using NASM and whenever I try to do something like
this:
cursor_pos dw 0
;; --------------------------------------------------
;; int write_video(void* src_buffer, int old_coord)
;; * returns the current position of cursor
;; * (void*)src_buffer pointers to the 0-terminated string to be displayed
;; * every program uses their own page, so the monitor is clean by default,
;; and the cursor always begin at (0,0) if coordinate is not specified...
;; --------------------------------------------------
write_video: ;; assume to be in color_chrome CRT
push bp
mov bp,sp
call save_all ; save all the sys_reg's
cli ; lock interrupts
mov si,[bp+2] ; get the pointer inside [bp+2]
mov bx,[bp+4] ; get the old coordinates, in linear mode
mov di,[vidmem_color+bx] ; setup di to be where the video is to be written
;; parsing the 0-terminiated string...
;; no bell, bs, and other special character printed!!
;; whatever send is whatever show!
cld ; foward direction
.loop_begin:
or byte [ds:si], 0x00 ; check to see if it's 0x00
jz .done ; if true, then goto '.done'
or byte [ds:si], 0x0f ; if !(*buffer==0x0f) // 0x0f == <lf> formfeed
jnz .regular_chars ; goto .regular_chars
;; if it is a <lf>
mov ax,bx
push ax
shr ax,1 ; mem=mem/2 (bx=mem)
shr ax,4 ; divide by 4
mov bx,5
;; ---> troubling line, can't get division to work!!! <---
div ax,bx ; divide by 80 total...
;; ax:dx result: quotent(ax)-x, remainder(dx)-y
inc ax ; y++
shl ax,4 ; *16
mov cx,ax
add ax,cx
add ax,cx
add ax,cx
add ax,cx
add ax,cx ; *5
mov bx,ax
shl bx,1 ; *2
mov di,[vidmem_color+bx]
inc si
jmp .loop_begin ; continue
.regular_chars:
movsb ; move the byte there
inc bx ; increment bx so that <lf> will be valid position
push ax
mov al,0x07 ; write the display attribute
pop ax
lodsb
inc bx
jmp .loop_begin ; go back to beginning...
.done:
sti ; do interrupts again
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; have to do something with ax before goes off
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [bp+28],bx ; returning value in ax
call restore_all ; restore all the sys_reg's
pop bp ; restore bp, used before save_all
ret ; go home
The compiler tells me that i've got a invalid combination of operands,
but this syntax is exact the way taught in the NASM manual.
I tried different ways to write that line with:
div ax,dx
but i don't seem to see anything different than:
"invalid combination of opcode and operands"
i'm kind of stuck here with the coding, need a little bit
of help...and is there anyway to get (x,y) position of
the cursor than passing it back and forth?
Ben
I've been fooling around with the pmode initialization
stuff, and I now need to be able to write to my CRT
once when pmode is entered. So I begin writing codes to
display on the screen by writing to the video memory.
A problem that I encountered was that I need to find out
the offset that the character is to be written, and to
record down the position, as a testing program, I've been
writin it out using NASM and whenever I try to do something like
this:
cursor_pos dw 0
;; --------------------------------------------------
;; int write_video(void* src_buffer, int old_coord)
;; * returns the current position of cursor
;; * (void*)src_buffer pointers to the 0-terminated string to be displayed
;; * every program uses their own page, so the monitor is clean by default,
;; and the cursor always begin at (0,0) if coordinate is not specified...
;; --------------------------------------------------
write_video: ;; assume to be in color_chrome CRT
push bp
mov bp,sp
call save_all ; save all the sys_reg's
cli ; lock interrupts
mov si,[bp+2] ; get the pointer inside [bp+2]
mov bx,[bp+4] ; get the old coordinates, in linear mode
mov di,[vidmem_color+bx] ; setup di to be where the video is to be written
;; parsing the 0-terminiated string...
;; no bell, bs, and other special character printed!!
;; whatever send is whatever show!
cld ; foward direction
.loop_begin:
or byte [ds:si], 0x00 ; check to see if it's 0x00
jz .done ; if true, then goto '.done'
or byte [ds:si], 0x0f ; if !(*buffer==0x0f) // 0x0f == <lf> formfeed
jnz .regular_chars ; goto .regular_chars
;; if it is a <lf>
mov ax,bx
push ax
shr ax,1 ; mem=mem/2 (bx=mem)
shr ax,4 ; divide by 4
mov bx,5
;; ---> troubling line, can't get division to work!!! <---
div ax,bx ; divide by 80 total...
;; ax:dx result: quotent(ax)-x, remainder(dx)-y
inc ax ; y++
shl ax,4 ; *16
mov cx,ax
add ax,cx
add ax,cx
add ax,cx
add ax,cx
add ax,cx ; *5
mov bx,ax
shl bx,1 ; *2
mov di,[vidmem_color+bx]
inc si
jmp .loop_begin ; continue
.regular_chars:
movsb ; move the byte there
inc bx ; increment bx so that <lf> will be valid position
push ax
mov al,0x07 ; write the display attribute
pop ax
lodsb
inc bx
jmp .loop_begin ; go back to beginning...
.done:
sti ; do interrupts again
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; have to do something with ax before goes off
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [bp+28],bx ; returning value in ax
call restore_all ; restore all the sys_reg's
pop bp ; restore bp, used before save_all
ret ; go home
The compiler tells me that i've got a invalid combination of operands,
but this syntax is exact the way taught in the NASM manual.
I tried different ways to write that line with:
div ax,dx
but i don't seem to see anything different than:
"invalid combination of opcode and operands"
i'm kind of stuck here with the coding, need a little bit
of help...and is there anyway to get (x,y) position of
the cursor than passing it back and forth?
Ben