character rom programming

character rom programming

Post by <oud.. » Thu, 14 Aug 2003 15:17:04



I am having difficulty getting the correct results accessing the character
rom. I should be getting 0 for the following code but instead it is giving
me E8h. The top byte of character bitmap 'A' is all 0, and thats what i
should be getting. I am compiling this in turbo c using large model.  The
address F000FA6E is where the character rom begins. Each chracter
takes 8 bytes, and the letter A has as offset of 65 from the beginning.
Any suggestions. Thanks.

main()
{   unsigned char far *char_rom = (unsigned char far *)0xF000FA6EL;
    printf("%x\n", *(char_rom + (65<<3))  );
    return;

Quote:}

 
 
 

character rom programming

Post by Dave Dunfie » Thu, 14 Aug 2003 20:15:03


Quote:>I am having difficulty getting the correct results accessing the character
>rom. I should be getting 0 for the following code but instead it is giving
>me E8h. The top byte of character bitmap 'A' is all 0, and thats what i
>should be getting. I am compiling this in turbo c using large model.  The
>address F000FA6E is where the character rom begins. Each chracter
>takes 8 bytes, and the letter A has as offset of 65 from the beginning.
>Any suggestions. Thanks.

>main()
>{   unsigned char far *char_rom = (unsigned char far *)0xF000FA6EL;
>    printf("%x\n", *(char_rom + (65<<3))  );
>    return;
>}

I don't know where the E8 is coming from ... on my system, this
prints '30' which is the actual top line of the 'A' character in my
BIOS 8x8 character set. Note that the charcter layout can and will
vary from one system to another (see examples below).

Here's a function which will print out the entire character:

#include <stdio.h>

#define CHAR_ROM    ((unsigned char far *)0xF000FA6EL)

draw_char(unsigned char c)
{
    unsigned x, y, i;
    unsigned char d;
    i = c << 3;
    for(y=0; y < 8; ++y) {
        d = CHAR_ROM[i++];
        printf("%02x ", d);
        for(x=0; x < 8; ++x) {
            putc((d & 0x80) ? '*' : '.', stdout);
            d <<= 1; }
        putc('\n', stdout); }

Quote:}

int main()
{
    draw_char('A');
    return 0;

Quote:}

And here's what I get on two different systems:
(Best viewed with a fixed font)

 System-1            System-2
-----------         -----------
30 ..**....         38 ..***...
78 .****...         6c .**.**..
cc **..**..         c6 **...**.
cc **..**..         c6 **...**.
fc ******..         fe *******.
cc **..**..         c6 **...**.
cc **..**..         c6 **...**.
00 ........         00 ........

E8 would be: ***.*...
which I don't see how it could be the first line of an 'A' ... perhaps
you are running under windows, and it does not preserve the BIOS character
set tables properly to the DOS box? Or perhaps your BIOS doesn't support
an 8x8 character table (Have they dropped this in recent BIOS's)?

You can check out the table with DEBUG:
Try the following both under windows and booted with pure DOS (either
"Boot in DOS mode" of W95/98, or use a DOS boot floppy):

Dump F000:FA6E, you should see 8 00 bytes, which represent the NUL (0x00)
character. The try F000:FC76, which is F000:FA6E + (65 * 8), you should
see the bit patterns for 'A'. Here is what I get:

-d F000:FA6E
F000:FA60                                            00 00                 ..
F000:FA70  00 00 00 00 00 00 7E 81-A5 81 BD 99 81 7E 7E FF   ......~......~~.
F000:FA80  DB FF C3 E7 FF 7E 6C FE-FE FE 7C 38 10 00 10 38   .....~l...|8...8
F000:FA90  7C FE 7C 38 10 00 38 7C-38 FE FE 7C 38 7C 10 10   |.|8..8|8..|8|..
F000:FAA0  38 7C FE 7C 38 7C 00 00-18 3C 3C 18 00 00 FF FF   8|.|8|...<<.....
F000:FAB0  E7 C3 C3 E7 FF FF 00 3C-66 42 42 66 3C 00 FF C3   .......<fBBf<...
F000:FAC0  99 BD BD 99 C3 FF 0F 07-0F 7D CC CC CC 78 3C 66   .........}...x<f
F000:FAD0  66 66 3C 18 7E 18 3F 33-3F 30 30 70 F0 E0 7F 63   ff<.~.?3?00p...c
F000:FAE0  7F 63 63 67 E6 C0 99 5A-3C E7 E7 3C 5A 99         .ccg...Z<..<Z.
-dF000:FC76
F000:FC70                    30 78-CC CC FC CC CC 00 FC 66         0x.......f
F000:FC80  66 7C 66 66 FC 00 3C 66-C0 C0 C0 66 3C 00 F8 6C   f|ff..<f...f<..l
F000:FC90  66 66 66 6C F8 00 7E 60-60 78 60 60 7E 00 7E 60   fffl..~``x``~.~`
F000:FCA0  60 78 60 60 60 00 3C 66-C0 C0 CE 66 3E 00 CC CC   `x```.<f...f>...
F000:FCB0  CC FC CC CC CC 00 78 30-30 30 30 30 78 00 1E 0C   ......x00000x...
F000:FCC0  0C 0C CC CC 78 00 E6 66-6C 78 6C 66 E6 00 60 60   ....x..flxlf..``
F000:FCD0  60 60 60 60 7E 00 C6 EE-FE FE D6 C6 C6 00 C6 E6   ````~...........
F000:FCE0  F6 DE CE C6 C6 00 38 6C-C6 C6 C6 6C 38 00 FC 66   ......8l...l8..f
F000:FCF0  66 7C 60 60 F0 00                                 f|``..
-q

Regards,

--
Dunfield Development Systems          http://www.dunfield.com
Low cost software development tools for embedded systems
Software/firmware development services       Fax:613-256-5821

 
 
 

character rom programming

Post by Alex Russel » Fri, 15 Aug 2003 02:24:52


"Dave Dunfield" <Dave.Dunfi...@use.techsupport.link.on.my.website> wrote in
message news:fap_a.3275$Gf3.15282@tor-nn1.netcom.ca...
> >I am having difficulty getting the correct results accessing the
character
> >rom. I should be getting 0 for the following code but instead it is
giving
> >me E8h. The top byte of character bitmap 'A' is all 0, and thats what i
> >should be getting. I am compiling this in turbo c using large model.  The
> >address F000FA6E is where the character rom begins. Each chracter
> >takes 8 bytes, and the letter A has as offset of 65 from the beginning.
> >Any suggestions. Thanks.

> >main()
> >{   unsigned char far *char_rom = (unsigned char far *)0xF000FA6EL;
> >    printf("%x\n", *(char_rom + (65<<3))  );
> >    return;
> >}

> I don't know where the E8 is coming from ... on my system, this
> prints '30' which is the actual top line of the 'A' character in my
> BIOS 8x8 character set. Note that the charcter layout can and will
> vary from one system to another (see examples below).

> Here's a function which will print out the entire character:

> #include <stdio.h>

> #define CHAR_ROM    ((unsigned char far *)0xF000FA6EL)

> draw_char(unsigned char c)
> {
>     unsigned x, y, i;
>     unsigned char d;
>     i = c << 3;
>     for(y=0; y < 8; ++y) {
>         d = CHAR_ROM[i++];
>         printf("%02x ", d);
>         for(x=0; x < 8; ++x) {
>             putc((d & 0x80) ? '*' : '.', stdout);
>             d <<= 1; }
>         putc('\n', stdout); }
> }

> int main()
> {
>     draw_char('A');
>     return 0;
> }

> And here's what I get on two different systems:
> (Best viewed with a fixed font)

>  System-1            System-2
> -----------         -----------
> 30 ..**....         38 ..***...
> 78 .****...         6c .**.**..
> cc **..**..         c6 **...**.
> cc **..**..         c6 **...**.
> fc ******..         fe *******.
> cc **..**..         c6 **...**.
> cc **..**..         c6 **...**.
> 00 ........         00 ........

> E8 would be: ***.*...
> which I don't see how it could be the first line of an 'A' ... perhaps
> you are running under windows, and it does not preserve the BIOS character
> set tables properly to the DOS box? Or perhaps your BIOS doesn't support
> an 8x8 character table (Have they dropped this in recent BIOS's)?

> You can check out the table with DEBUG:

[snip - debug output]

> Regards,

> --
> Dunfield Development Systems          http://www.dunfield.com
> Low cost software development tools for embedded systems
> Software/firmware development services       Fax:613-256-5821

/*

    font.c

    demo getting a pointer to a ROM font, and displaying
    rom font characters

    Internet: alex...@uniserve.com
    July 28 by Alex Russell
    Permission granted to use this code as you wish.

    Created - 1997/7/28

    History:
        New file

         based on code posted by

   _\|/_   Derek Wueppelmann
   (o O)    Dwuep...@chat.carleton.ca
_oOO(_)OOo__  http://www.chat.carleton.ca/~dwueppel

   July 1997, AJR - fixed a few minor bugs, added code to display
                    various ROM fonts with cmd-line parm

*/

You should ask the bios where the fonts are. They are not always at the same
location.

#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <mem.h>
#include <stdlib.h>

typedef struct
   {
   unsigned int bx;
   int height;
   }
font_init_t;

void main(int argc, char *argv[])
{
   struct REGPACK regs;
   unsigned char mask, letter;
   char far *font, far *t1;
   unsigned int segment, offset;
   int height, i, j;
   font_init_t font_init[]=
      {
      {0x0200, 14},  // value of BX, and the height of the font
      {0x0300, 8},
      {0x0400, 8},
      {0x0500, 0},   // height 0, because wierd 9 wide font
      {0x0600, 16},
      {0x0700, 0}
      };

   i=2;  // default choice
   if ( argc > 1 )
      i=atoi(argv[1]);
   if ( i < 0 || i > 4 || !font_init[i].height )
      {
      printf("Bad input value, 0,1,2, and 4 are ok\n");
      exit(1);
      }

   height=font_init[i].height;

   // call the bios int to get the address of the desired font
   regs.r_ax = 0x1130;
   regs.r_bx = font_init[i].bx;
   intr(0x10, &regs);

   // make a far pinter to the font with info returned by the bios call
   offset = regs.r_bp;
   segment = regs.r_es;
   font = MK_FP(segment, offset);

   printf("%d height = %d, press ESC to exit, any other key to display
char.\n",
          i, height);

   while ( (letter = getch()) != 27 )
      {
      clrscr();

      // make t1 point the start of the letter in the rom font
      // each character is height bytes with each bit in a byte being a
      // pixel on/off for that scan line of the charater
      t1=font + (letter*height);

      // display the selected char as a pattern of '*' chars
      for ( i=0; i < height; i++ )
         {
         // set mask to check left most bit
         mask=128; // 10000000 binary - this was main your bug - missing
this

         // for each bit, check if it is 'on'
         for ( j=0; j < 8; j++ )
            {
            if ( ((*t1) & mask) )
               printf("*");
            else
               printf(" ");

            mask>>=1;  // move mask to next bit to the right
            }

         t1++;  // t1 points to the next scanline of the current character
         printf("  <<<\n");
         }

      printf("\n %c \nESC to Exit, or char to display\n", letter);
      }

}

/* ------------------------------ EOF -------------------------------- */

And this is a ASM sample of setting up new chars:

From - Thu Mar 05 22:26:03 1998
Path:
uniserve!sunqbc.risq.qc.ca!streamer1.cleveland.iagnet.net!qual.net!iagnet.ne
t!209.98.98.14!darla.visi.com!chippy.visi.com!news-out.visi.com!pulsar.dimen
sional.com!dimensional.com!quasar.dimensional.com!nyx.net!nyx10!dgdavis
From: dgda...@nyx10.nyx.net (DONALD G. DAVIS)
Newsgroups: comp.os.msdos.programmer
Subject: Re: Mixing 80x25 Text & Graphics
Date: 5 Mar 1998 01:57:25 GMT
Organization: Nyx Public Access Internet
Lines: 144
Message-ID: <889063005.12...@iris.nyx.net>
References: <EpB8w5....@erie.ge.com>
NNTP-Posting-Host: iris.nyx.net
X-Newsreader: NN version 6.5.0 #5
X-Disclaimer: Nyx is a Free Public Access Internet Service:
http://www.nyx.net
              Our AUP / Free Speech Policy are at
http://www.nyx.net/policies/
              Direct complaints to ab...@nyx.net
X-Post-Path: iris.nyx.net!dgda...@nyx10.nyx.net
Xref: uniserve comp.os.msdos.programmer:1012646

Rich Grisier <gris...@crypt.erie.ge.com> writes:
>Is there a way to mix text & graphics when in text 80x25 mode?
>I was thinking of creating new text "characters" that get called
>when an ascii code is entered, but I'm not sure how to accomplish this.

 It is possible to remap the standard character set to create
graphics-like effects in text mode.  Appended below is a little assembly
program that demonstrates a simple case of this by remapping three
characters to create a "bat" symbol.

       --Donald Davis
========================================================================

;Displays bat symbol created by remapping character set.
;Based on feature of MOZ.EXE.  Written for assembly under MASM 5.1.

;Chars. 192-223 have an extra 9th line along the right side.  This program
; makes a bat with no gaps between the elements by remapping 2 of those
; chars. and using 224 as the right block, since it is the next one that
; lacks that extra line and will therefore make the right side symmetrical
; with the left.  If other characters are used for the left wing and body,
; there will be gaps between the elements.

;This program does not reload the default character set on terminating.
; The remapped characters will remain remapped until this is done
; (as by MODE CO80).

CSEG SEGMENT

 ASSUME CS:CSEG,DS:CSEG,ES:CSEG
 ORG 0100H

START:

 CALL BIOWRT ;Remap bits in character generator table

 MOV BX,12  ;BL: display attribute, BH: video page 0
 MOV CX,3  ;Number of characters to display
 MOV BP,OFFSET BAT ;Point BP to start of text buffer
 PUSH CX  ;Save number of characters to print
 MOV AH,3  ;Get cursor row & column into DH and DL
 INT 10H  ;Call video BIOS interrupt
 POP CX  ;Restore number of characters to print
 MOV AX,1301H ;BIOS print-string func., cursor-moving subfunc.
 INT 10H  ;Call video BIOS interrupt
 RET   ;Terminate program

BAT DB 221,222,224 ;ASCII characters to remap & display

;************************************************************************
; Replace three characters of character generator    *
; with bat components, using the BIOS function 11hex    *
;************************************************************************
BIOWRT:
 PUSH BP
 PUSH ES
 PUSH SI

 ;MOV AX,1202h ;set up 400 scan lines
 ;MOV BL,30h
 ;INT 10h

 ;MOV AX,0003 ;set up normal text mode
 ;INT 10

 MOV BP,OFFSET CMAP1 ;Offset of new bitmap must be in BP
 PUSH CS  ;Segment of new bitmap must be in ES
 POP ES
 XOR SI,SI  ;Initialize pointer to table of remapped chars.
 XOR DX,DX  ;Initialize register that holds char. number
 MOV CX,1  ;Number of chars. to remap
 MOV BL,0  ;Change table 0
 MOV BH,16  ;Bytes per character
RLOOP:
 MOV DL,BAT[SI] ;Start with first character in BAT data block
 MOV AH,11H ;Function = LOAD CHARACTER GENERATOR
 MOV AL,00H ;Subfunction = CUSTOM CHAR GEN
 INT 10H  ;Use BIOS to replace next character
 ADD BP,16
 INC SI  ;Point to the next character to replace
 CMP SI,3  ;Are we done with all characters?
 JB RLOOP  ;...No, go do next one

 POP SI
 POP ES
 POP BP
 RET

CMAP1 DB 00010000B ;Tables representing new bitmaps for characters
 DB 00011000B
 DB 00111100B
 DB 00111110B
 DB 01111111B
 DB 01111111B
 DB 11111111B
 DB 11111111B
 DB 11111111B
 DB 11111111B
 DB 11101111B
 DB 11101110B
 DB 11000100B
 DB 10000000B
 DB 10000000B
 DB 10000000B

CMAP2 DB 01000010B
 DB 01111110B
 DB 01011010B
 DB 01111110B
 DB 01111110B
 DB 11111111B
 DB 11111111B
 DB 11111111B
 DB 11111111B
 DB 11111111B
 DB 11111111B
 DB 01111100B
 DB 00111000B
...

read more »

 
 
 

character rom programming

Post by Dave Dunfie » Fri, 15 Aug 2003 20:37:03



>You should ask the bios where the fonts are. They are not always at the same
>location.
>void main(int argc, char *argv[])
>{

- Locals and argument parsing snipped -

Quote:>   // call the bios int to get the address of the desired font
>   regs.r_ax = 0x1130;
>   regs.r_bx = font_init[i].bx;
>   intr(0x10, &regs);

This is not guaranteed to work as shown ... Note the following warning
given in the Phoenix BIOS technical reference:
   Function AH=11, Subfunction: AL=30h Get font pointer information
  .- main description & register usage snipped -
  "To avoid unpredictable results, this subfunction should be issued
    immediately after a mode set."

Many programmers, not knowing this caveat, believed the function to
be unreliable, and either provided their own character set (good) or
just assumed the original IBM BIOS ROM addresses which became
a defacto standard. As a result of this almost all BIOS implementations
put the 8x8 table at F000:FA6E ... there are exceptions, possibly more
so now that the BIOS fonts have fallen into disuse.

Agreed it is a good idea to use this function - just be aware of the issue,
and be sure to set the graphics mode first, then immediatly retrieve
the font table addresses.

Regards,

--
Dunfield Development Systems          http://www.dunfield.com
Low cost software development tools for embedded systems
Software/firmware development services       Fax:613-256-5821

 
 
 

1. ROM character set location

Does anyone know the location of the ROM character set when using the
__djgpp_conventional_base offset?

It's (char far *)0xF000FA6EL when in 16bit real mode.

Is there a general way of converting base pointers from real mode to DJGPP?

--
Look at my bring and buy sale, umph pardon.

email . .

Scissorsoft online . .
http://www.geocities.com/SiliconValley/4396/

2. VC and CAPI

3. garbarge characters in dos programs

4. Help

5. Small program to count characters

6. FS:NEW 21" SGI Monitos

7. A character mapping program like the unix tr?

8. BC3.1 OWL Examples wanted, please

9. International characters in DOS-programs under BC 4.02

10. Program, uses compare() to check characters, but doesnt work

11. ? Help: Console mode program, why am I getting redundant character upon keyboard input?

12. Function for character based screen programming

13. Graphical Programming Using DOS/IBM Extended Characters