flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Something you may consider useful - Pmode cursor positioning

Author
Thread Post new topic Reply to topic
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
I just finished this, and since the forum is always answering my stupid questions I thought I should give back with what may be my first even remotely useful contribution to the board. The hardest part was finding info on how to do it, but it updates the cursor in text mode(int 10h ah=0 al=3) based on the contents of col and row. If you have any suggestions, please tell me.Smile Both vid_*_regs should be read in an outside init function from the bda, no need to refind them every cursor update.
Code:
update_cursor_pos:
   push      ebp
   mov       ebp,esp
   pushad
   xor       eax,eax
   mov       al,[row]             ; Get new row
   mov       dl,80
   mul       dl                   ; row*80
   add       al,[col]             ; row*80+col
   mov       [pos],ax             ; pos=row*80+col
   mov       al,0fh
   mov       dx,[vid_ctrl_reg]
   out       dx,al                ; Set video reg to f
   mov       ax,[pos]
   and       al,0ffh
   mov       dx,[vid_out_reg]
   out       dx,al                ; Access video reg f
   mov       al,0eh
   mov       dx,[vid_ctrl_reg]
   out       dx,al                ; Set video reg to e
   mov       ax,[pos]
   mov       al,ah
   and       al,0ffh
   mov       dx,[vid_out_reg]
   out       dx,al                ; Access video reg e
   popad
   mov       esp,ebp
   pop       ebp
   ret

vid_ctrl_reg       dw 3d4h
vid_out_reg        dw 3d5h
col                db 0
row                db 0
pos                dw 0
    
Post 26 Apr 2010, 04:48
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Tyler,

Several comments:
  1. You don't have to establish stack frame if you don't need it.
  2. Are the calculations correct? You add [col] only to lower part of 80*[row], thus row==3 and col==16 yields pos==0. Wink
  3. You don't have to mask al with 0ffh (it's 8-bit already). Wink
  4. Second mov ax,[pos] is needless — you didn't modify ah since first.
  5. Is pos variable useful? You may shave off several instructions if you set CRTC address register to 0Fh before calculations (then following out 3D5h,al frees al to be used to set CRTC address register to 0Eh).
  6. Moreover, from my (long-forgotten) days of VGA programming I remember that you can use out 3D4h,ax on later VGA cards to set CRTC/GC/sequencer register (al==address, ah==value).
  7. What about non-80-columns modes?
Post 26 Apr 2010, 07:23
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
I've gotten rid of the stack frame and the bit maskings, corrected the issue you pointed out where [pos] equals 0 incorectly. The mov ax,[pos] is just to keep from me coming back a month later, splicing my code into different places, then discovering a weird bug with no idea where it came from.

pos is used in other places, I use it here to keep all printing centered around a single place keeper.

Non 80 column modes are A LONG WAY AWAY for me, you know that. Wink

Now I've reworked my print function around the centralized pos variable, but I would appreciate your thoughts on my function made just to update pos based on col and row.
Code:
update_pos:
   pushad
   xor       eax,eax
   mov       al,[row]             ; Get new row
   mov       dl,80
   mul       dl                   ; row*80
   xor       dx,dx
   mov       dl,[col]
   add       ax,dx                ; row*80+col
   mov       [pos],eax            ; pos=row*80+col
   popad
   ret                                 
    
Post 26 Apr 2010, 23:20
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
As to pos's importance, it is useful in my print function because it is the offset from the base of video memory to print to the col and row I want.
Post 26 Apr 2010, 23:22
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Tyler,

Then your print function updates row/col as well? If their usage is infrequent, they can be dropped altogether (and recalculated from pos when needed, which in turn could be read from CRTC Wink).

BTW pos (it suddenly becomes dword) is only a half of the offset. Wink

pushad / popad seems unnecessary. Is the rest of your code suppose that all registers are preserved across calls?

xor eax, eax; mov al, [row] causes partial register stall to mul dl.
movzx edx, [row]; imul eax, edx, 80 looks better.
The same for xor dx, dx; mov dl, [col]; add ax, dx.
Post 27 Apr 2010, 06:41
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler
I use row and col to manipulate pos because rows and columns are a lot easier to comprehend than an offset.
Quote:

BTW pos (it suddenly becomes dword) is only a half of the offset.

Sorry, forgot to update the code above. I changed it to a dword for simplicity.
Quote:

pushad / popad seems unnecessary. Is the rest of your code suppose that all registers are preserved across calls?

No, but it helps in debugging when you now an entire function couldn't be what is screwing up a register. I do it because I don't need to return anything, so there's no reason to trash any regs.

Thanks for the info on the register stall thing, I didn't even know that existed. I'll use you suggestion and use your movzx+imul method. I'll come back and update the code after I get my scroll function working.
Post 28 Apr 2010, 02:35
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Tyler,

You may change row/col to dword too and use imul eax, [row], 80.

Partial register stalls are make/model-specific (Core architecture is said to have much less latency for them than NetBurst, and PPro mentioned special handling of partial register write after xor r32, r32). It's just a rule-of-thumb, I think.
Post 28 Apr 2010, 08:11
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
These are the ones i made a while back...
Code:
; Get current caret offset.

        mov     ax,0x0F0E
        mov     dx,0x03D4
        out     dx,al
        inc     dx
        in      al,dx
        xchg    ah,al
        dec     dx
        out     dx,al
        inc     dx
        in      al,dx
        ; AX = offset

; Set new caret offset.

        ; BX = offset
        mov     al,0x0E
        mov     ah,bh
        mov     dx,0x03D4
        out     dx,ax
        inc     ax
        mov     ah,bl
        out     dx,ax
    
Post 16 Jun 2010, 21:32
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.