Previous Thread
Next Thread
Print Thread
Page 1 of 2 1 2
#98898 03/30/15 10:30 AM
Joined: Apr 2012
Posts: 340
Likes: 60
Pernod Online Content OP
Senior Member
OP Online Content
Senior Member
Joined: Apr 2012
Posts: 340
Likes: 60
I see the internal ROM is stored as an array of 8bit values, where the rightmost 5 bits represent the actual characters to form a 5x9 grid. Is this an accurate representation of the ROM, or don't we know?

To implement the rounding I intend to copy the character into an array of 16bit values to form a 10x18 grid, formed by expanding each original bit to 4 bits, then adding subpixels to any diagonal.
ie.
. # -> . . # # -> . . # #
# . -> . . # # -> . # # #
. . -> # # . . -> # # # .
. . -> # # . . -> # # . .
Not sure yet how this will affect double height characters but will find out when this is in.
Is this the correct way to implement this, any comments?

Last edited by Pernod; 03/30/15 10:31 AM.

BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Joined: Apr 2012
Posts: 340
Likes: 60
Pernod Online Content OP
Senior Member
OP Online Content
Senior Member
Joined: Apr 2012
Posts: 340
Likes: 60
I'm in the process of making major changes to saa5050.c. I originally intended to simply implement the character rounding but soon became obvious more was required to get this character generator into shape.

The data in the 'hand made' ROM dump also contained the graphics characters which are not required, they can be generated internally so I'll be implementing the 'graphics generator'. I've removed the graphics from the saa5050 and saa5052 'dumps' and also created 'dumps' for all other character sets 5051, 5053, etc. for completeness. The saa5050 dump contained some erroneous characters which I've also fixed.

Some control codes only take effect at the next character and affected control codes are now handled correctly.

At the moment I need to convert a pixel map of '00010101' (UINT8) to '0000001100110011' (UINT16), each pixel is doubled in width. Anyone suggest a simply way of doing this, or should I check each bit separately?


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Joined: Mar 2001
Posts: 17,178
Likes: 211
R
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 17,178
Likes: 211
For a character generator inner loop, I'd suggest the classic unroll-o-matic:

Code
*dst++ = (src & 0x80) ? 0xffff : 0;
*dst++ = (src & 0x80) ? 0xffff : 0;
*dst++ = (src & 0x40) ? 0xffff : 0;
*dst++ = (src & 0x40) ? 0xffff : 0;
*dst++ = (src & 0x20) ? 0xffff : 0;
*dst++ = (src & 0x20) ? 0xffff : 0;
*dst++ = (src & 0x10) ? 0xffff : 0;
*dst++ = (src & 0x10) ? 0xffff : 0;
*dst++ = (src & 0x08) ? 0xffff : 0;
*dst++ = (src & 0x08) ? 0xffff : 0;
*dst++ = (src & 0x04) ? 0xffff : 0;
*dst++ = (src & 0x04) ? 0xffff : 0;
*dst++ = (src & 0x02) ? 0xffff : 0;
*dst++ = (src & 0x02) ? 0xffff : 0;
*dst++ = (src & 0x01) ? 0xffff : 0;
*dst++ = (src & 0x01) ? 0xffff : 0;

Joined: Jun 2001
Posts: 519
Likes: 32
O
Senior Member
Online Content
Senior Member
O
Joined: Jun 2001
Posts: 519
Likes: 32
Originally Posted by Pernod
At the moment I need to convert a pixel map of '00010101' (UINT8) to '0000001100110011' (UINT16), each pixel is doubled in width. Anyone suggest a simply way of doing this, or should I check each bit separately?

https://graphics.stanford.edu/~seander/bithacks.html

Check "Interleave bits by Binary Magic Numbers"

OG.

Joined: Apr 2012
Posts: 340
Likes: 60
Pernod Online Content OP
Senior Member
OP Online Content
Senior Member
Joined: Apr 2012
Posts: 340
Likes: 60
A quick update... the graphics generator is implemented and working in bbcb, ROM characters are unrolled in a similar way to RB's suggestion (not sure how the Binary Magic Numbers would've helped), still to fix character rounding.

Also tested poly1, p2000t, abc80x and no obvious side effects noticed so far smile


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Joined: Mar 2006
Posts: 1,079
Likes: 6
L
Very Senior Member
Offline
Very Senior Member
L
Joined: Mar 2006
Posts: 1,079
Likes: 6
character 'rounding': is this similar to the character 'stretching' done in the vt100/rainbow, where each pixel is an OR of its own source rom value and the rom value of the pixel to its left?

i.e. from the font rom the characters look like:
Code
Character: 62
........
X.......
X.......
X.XXXX..
XX....X.
X.....X.
XX....X.
X.XXXX..
........
........
while after the stretching right before being drawn to screen, characters looks like:
Code
Character: 62
........
XX......
XX......
XXXXXXX.
XXX...XX
XX....XX
XXX...XX
XXXXXXX.
........
........

The reason the gaps exist at all in the rom is because the double-width font mode on the vt100/rainbow makes the gap visible for one pixel.
I.e. the char stretch is done right before being sent to the display, so the doublewide char going into the stretch circuit looks like:
Code
Character: 62
................
XX..............
XX..............
XX..XXXXXXXX....
XXXX........XX..
XX..........XX..
XXXX........XX..
XX..XXXXXXXX....
................
................
and ends up like:
Code
Character: 62
................
XXX.............
XXX.............
XXX.XXXXXXXXX...
XXXXX.......XXX.
XXX.........XXX.
XXXXX.......XXX.
XXX.XXXXXXXXX...
................
................

LN


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Joined: Apr 2012
Posts: 340
Likes: 60
Pernod Online Content OP
Senior Member
OP Online Content
Senior Member
Joined: Apr 2012
Posts: 340
Likes: 60
Originally Posted by Lord Nightmare
character 'rounding': is this similar to the character 'stretching' done in the vt100/rainbow, where each pixel is an OR of its own source rom value and the rom value of the pixel to its left?
No, definitely different.

The ROM contains a 5x9 pixel map: (Done)
Code
Character: 62
X....
X....
XXXX.
X...X
X...X
X...X
XXXX.
.....
.....
which is then mapped to a 10x18 pixel map by doubling in both directions: (Done)
Code
Character: 62
XX........
XX........
XX........
XX........
XXXXXXXX..
XXXXXXXX..
XX......XX
XX......XX
XX......XX
XX......XX
XX......XX
XX......XX
XXXXXXXX..
XXXXXXXX..
..........
..........
..........
..........
then dot information of two rows is compared to detect any diagonal and fill in a dot to round it: (TODO)
Code
Character: 62
XX........
XX........
XX........
XX........
XXXXXXXX..
XXXXXXXXX.
XX.....XXX
XX......XX
XX......XX
XX......XX
XX......XX
XX.....XXX
XXXXXXXXX.
XXXXXXXX..
..........
..........
..........
..........
The method is a little more complex for double height characters, but we'll look at that later.


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Joined: Mar 2006
Posts: 1,079
Likes: 6
L
Very Senior Member
Offline
Very Senior Member
L
Joined: Mar 2006
Posts: 1,079
Likes: 6
so the rounding isn't something 'simple' like EPX/scale2x, its somewhat more complex? (maybe with a 3x3 '9-cell' kernel instead of a + shaped '5-cell' kernel like EPX/scale2x uses?)

Is the rounding algorithm documented anywhere?

LN


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Joined: Jan 2006
Posts: 3,691
Very Senior Member
Offline
Very Senior Member
Joined: Jan 2006
Posts: 3,691
Originally Posted by Pernod
(not sure how the Binary Magic Numbers would've helped)

by giving you an example implementation, if you needed one wink
see
https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableObvious
which applies in your case with x=y

Joined: Mar 2006
Posts: 1,079
Likes: 6
L
Very Senior Member
Offline
Very Senior Member
L
Joined: Mar 2006
Posts: 1,079
Likes: 6
hmm. if rounding is only diagonals, here's one GUESSED possibility:
1. double the character size
2. for every pixel:
Code
/*
A.B
.N.
C.D
*/
if ( (N == 0) &&
        (
            ((A == D == 1) && (B == C == 0)) ||
            ((A == D == 0) && (B == C == 1))
        )
   ) N = 1;
This is applied to all pixels at once, hence a pixel set to 1 by this equation doesn't count for calculations of other pixels?

This seems somewhat complex to implement in hardware, though, unless it is done by a circuit during output with lookback of the previous 2 lines.

Edit: easier code:
Code
/*
A.B
.N.
C.D
*/
if ( (N == 0) &&
          ((A == D) && (B == C) && (A != B))
   ) N = 1;

LN

Last edited by Lord Nightmare; 04/08/15 06:22 PM. Reason: better code

"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Page 1 of 2 1 2

Link Copied to Clipboard
Who's Online Now
1 members (Pernod), 32 guests, and 3 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,305
Posts121,668
Members5,069
Most Online1,283
Dec 21st, 2022
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Forum hosted by www.retrogamesformac.com