I know a very optimized way to print characters in pmode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: I know a very optimized way to print characters in pmode

Post by rdos »

Why are such simple things so hard in C? :mrgreen:

Code: Select all

    mov ax,730h
    mov edi,0B8000h
    mov [edi],ax    ; will write "0" in top left corner
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: I know a very optimized way to print characters in pmode

Post by Solar »

rdos wrote:Why are such simple things so hard in C? :mrgreen:
Because your ASM example doesn't do the same thing (printing a parameterized character to a parameterized location). 8)

Moreover, your ASM source is specific to a certain assembler, and won't necessarily compile on a different one (AT&T vs. Intel syntax). The C source discussed here would compile on any C compiler. 8)
Every good solution is obvious once you've found it.
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: I know a very optimized way to print characters in pmode

Post by rdos »

Solar wrote:Because your ASM example doesn't do the same thing (printing a parameterized character to a parameterized location). 8)
That's easy to fix: :mrgreen:

Code: Select all


;  AH = attribute
;  AL = char
;  BL = row
;  BH = col

WriteChar   Proc
    push edi
    push ax
    mov al,80
    mul bl
    add al,bh
    adc ah,0
    add ax,ax
    mov edi,0B8000h
    or di,ax
    pop ax
    mov [edi],ax
    pop edi
    ret
WriteChar   Endp

Solar wrote:Moreover, your ASM source is specific to a certain assembler, and won't necessarily compile on a different one (AT&T vs. Intel syntax). The C source discussed here would compile on any C compiler. 8)
Yes, but it is unreadable.

BTW, if you also want a version that is independent of the physical location of the video-buffer, and that have forecolor and backcolor as parameters instead of the combined attribute, it looks something like this:

Code: Select all

;  AL   Char
;  BL   Fore color
;  BH   Back color
;  CX   Column
;  DX   Row

WriteChar Proc
    push ds
    push ax
    push di
    mov ah,bh
    shl ah,4
    or ah,bl
    push ax
    push dx
    mov ax,80
    mul dx
    add ax,cx
    add ax,ax
    mov di,ax
    mov ax,dosb800
    mov ds,ax
    pop dx
    pop ax
    mov [di],ax
    pop di
    pop ax
    pop ds
    ret
WriteChar   Endp
Last edited by rdos on Fri Nov 11, 2011 4:14 am, edited 1 time in total.
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: I know a very optimized way to print characters in pmode

Post by rdos »

berkus wrote:
rdos wrote:Yes, but it is unreadable.
It's unreadable because it was written in a pretty lame way. See Solar's improvement, which is heaps more readable.
Well, it consists of a set of unreadable macros instead. There is nothing more frustrating than to try to figure out how a particular #define is evaluated by the compiler when these are generated based on a zillion other defines. :evil:
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: I know a very optimized way to print characters in pmode

Post by Combuster »

The fact that you suck at chinese doesn't make it a bad thing that there are a billion people out there fluent with it.

You're breaking the language war rule, stop it please.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: I know a very optimized way to print characters in pmode

Post by Solar »

rdos wrote:
berkus wrote:
rdos wrote:Yes, but it is unreadable.
See Solar's improvement, which is heaps more readable.
Well, it consists of a set of unreadable macros instead.
Neither "unreadable" nor "a set" (since there is only one macro), hence I call "troll".

If all you have is a hammer, a screw is just a funny-looking and somewhat impractical nail...
Every good solution is obvious once you've found it.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: I know a very optimized way to print characters in pmode

Post by Brendan »

Hi,
Solar wrote:I took the liberty of optimizing your code further:
This version suffers from the same problem as the original - it fails to recognise that often you're printing a string and you only need to do the "address = start + (y * 80 + x) * 2" calculation once for the first character, then "address += 2" for each additional character. Basically, the next step in optimisation is to realise "putch()" is virtually irrelevant because you're using "putstring()" for almost everything instead.

The first step in optimising "putstring()" is to just append the new string to a buffer while checking if it contains any '\n' characters. If it does you'd copy whole lines (and never partial lines) to display memory. Basically "putstring()" would call a "putline(int y, char *string)" function that does "address = start + y * 80 * 2" for the first character and then "address += 2" for the remaining characters (or maybe a "lodsb; stosw" loop).

The next step would be to realise that this causes excessive scrolling. For example, if you add 12 lines of text at once, then you scroll 12 times (by 1 line each time) instead of only scrolling once (by 12 lines). To fix that you add a "flush_console()" function. The "putstring()" function just appends data to the buffer, and "flush_console()" counts how many lines are in the buffer, scrolls the screen once (if necessary), then copies text from the buffer to the screen.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: I know a very optimized way to print characters in pmode

Post by Solar »

Agreed.

My "optimization" was aiming at a proof that proper use of constants doesn't mean an increase in executable size. (Plus some implied hints to coding style).

As Karlosoft pointed out, the clrscr() function could be replaced by a memset() call, and you pointed out some valid issues with the underlying algorithm.

All in all, I would think twice before implementing either putch() or putstring() or whatever. Chances are you'll want to use <stdio.h>-like functionality sooner or later, and that doesn't need either putch() or putstring(), but a backend for plain old write( 1, ... ), i.e. a memcpy() capable of handling linefeeds...
Every good solution is obvious once you've found it.
Post Reply