10
$\begingroup$

Suppose we have a 64-bit word-addressable computer and we want to program it to output a 5x7 character stored as a binary image bitmap (such as the one below) to a memory-mapped display.

enter image description here enter image description here

Since we have 5 x 7 = 35 pixels per character, we could store a character using 35 bits in a single word. With the least significant bit starting on the left side of the word and with each pixel in the image being represented by the nth bit as shown above, the number "3" above would be stored in memory as: 01110100010000100110000011000101110, followed by 29 unused bits set to 0.

Is this how characters were/are stored in old/modern computers? Or do they use a single byte/word per pixel instead?

If they are stored in this manner, what would the routine in assembly/machine-code (using nothing more than elementary instructions such as bitwise, arithmetic and data transport operations from the computer's Instruction Set Architecture) used to convert this data into an image on the display look like? Would it be something like:

  1. Store the x and y display coordinate for the current pixel to be updated in a certain register.
  2. Store the two chosen RGB values (in this case 0,255,0 for green and 0,0,0 for black) in two other separate registers.
  3. Have two further registers act as counters initialized to 5 and 7 to keep track of the current row and column of the image being rendered.
  4. Test if the column register is not 0. If it isn't, test if the LSB of the bitmap is set to 1, then AND the respective RGB value register with the x and y coordinate register depending on the result, then MOV that result to the display output register.
  5. Decrement the row counter register by 1, test to see if it is 0. If it is, then set it back to 5 and increment the y coordinate by 1 and decrement the column counter by 1.
  6. Shift the register holding the bitmap 1 bit to the left.
  7. JMP to instruction 4.

Is there a simpler or more efficient way to do this? It seems as though even something as simple as rendering a single small text character takes quite a large number of operations and would take around 200 CPU cycles.

Finally, are there any good books or resources on machine-level code for displaying images from scratch, because I haven't been able to find any as they either gloss over this particular subject or the code is written in a high level language or an assembler using macros, all of which are "cheating" and don't explain what is fundamentally going on at the lowest level.

$\endgroup$
3
  • 3
    $\begingroup$ The Graphics Programming Black Book is certainly a classic worth reading. A lot of oldschool black-magic in it ;) $\endgroup$
    – glampert
    Sep 27, 2015 at 19:08
  • $\begingroup$ Yes, I second the book by Michael Abrash. It is a GREAT read. There are a lot more trick in the sleeve to what is written in this book but the philosophy behind it is important (even to this day !) $\endgroup$ Sep 30, 2015 at 10:06
  • $\begingroup$ I suppose you could look at all the excellent info about this in HarfBuzz which is a very widely used text shaping engine (turns text into bitmaps using fonts.) $\endgroup$
    – Wyck
    Mar 24, 2022 at 4:08

2 Answers 2

7
$\begingroup$

You have to distinguish the text and graphical modes of the graphics board of your machine.

In the old days, mostly the text mode was supported. In this mode the board took care of storing the bitmap definition of the characters and displaying them at the current cursor position. All you had to do was to provide the ASCII code of the character (one byte per character) in a small text buffer.

Nowadays, a high-resolution raster buffer is provided, which is pixel accessible and to which you write color information in some supported format (in the "highest" mode, 3 bytes (RGB) per pixel, for a megapixel or more).

Originally, simple (packed) binary bitmaps of different sizes were used and "blittted" to the raster memory via a request to the device driver, with possible format translation.

Nowadays, characters are mostly defined as vector drawings, which are a resolution-independent description of the outlines, and need to undergo a complex rendering process that includes antialiasing for smooth results.

The rendered output can be cached for fast display, again by blitting.

The overall process is complex, can be hardware accelerated, and is handled by the operating system (GUI management) in a transparent way, together with other graphical primitive drawing operations.

$\endgroup$
1
$\begingroup$

The short answer is YES, you can not avoid doing a lot of bit manipulation if your format needs it.

Drawing a bitmap basically mean copy a pixel from a source to a destination and you have to do what it takes to do it. (Quoting Captain Obvious)

A longer answer is that if you write a software rasterizer, you can have some algorithm and trick to save you cpu time (by knowing which part you DO NOT NEED TO DRAW (transparency optimization), by having a pixel format of the source the same as the destination (directly or in a form of cache), optimally perform memcopy, etc... Basically consider the drawing loop of your rasterizer and see how you can restructure them to save CPU time. (ex : you could generate at runtime a piece of assembler code just specifically to print the letter A or have meta to your source bitmap info to tell you how to skip transparent area, etc..) Each use case may have a different solution based on CPU instruction set, buffer format, the algorithm of your rendering primitive (rotating ? stretching bitmaps ? what kind of filtering ? etc...), CPU register and cache etc...

So yes anyway, it TOOK a lot of CPU cycle to write single pixel in the old days when weird encoding & small memory were the norm. :-) But it didn't forbid 16 / 32 bit machines with 8 MHZ CPU to do things like that : https://www.youtube.com/watch?v=GWwPJU6pp30 (And a big chunk of the CPU was used also for the music)

In the case of HW rendering, HW will perform the conversion from the source format to destination format and while it will not use much of the tricks available to SW rasterizer, its generic implementation in HW will most likely beat most of the SW implementation.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.