Author Topic: Programming question  (Read 316 times)

Charlie

  • Full Member
  • ***
  • Posts: 247
Programming question
« on: January 01, 2010, 05:47:01 AM »
Hi, all, and especially the code gurus.  Need some help here (you may have realized from some of my previous code posts that programming is not my strong point):

I started with the "HelloWorld" tutorial, and have done a lot of work studying it.  I have un-macroed the macros,
un-subbed the subroutines, un-libbed the libraries, and in general made a nice, clean linear-flow sample program that I can use to further understand TE/HUC programming. Since I am only interested in the print-to-the-display operation, I  have also removed any music/joystick/button/interrupt related code.  The result is, of course, smaller and easier to analyze code.

However, I am having some trouble understanding the font stuff.  So, I went back to the original "Helloworld" list file and I am reviewing it.  Part of the problem is that the tutorial actually seems to perform a number of functional operations twice, and each of these two code-flows seem to be attempting to achieve the same result but in somewhat (ok,...significantly...at least to me) different manners.

Here are some general questions for which I need guidance:

1. The code under consideration is "load font", part of "startup.asm".
The first function called here is "_set_font_addr". This function gets the
font address data of $0800 as defined by #FONT_VADDR, manipulates it, and stores it into
the variable "_font_base".  So...
a) Why $0800?  I do not recall any docs that indicated this is a
set-in-stone address, so why was it chosen; any specific reason? 
b) The resultant data stored in "_font_base" is $0080.  If I change the defined
address to $0810, the result is $0081.  If I use $0801, the data is $0080.  Obviously,
there is a boundary/alignment consideration here.  What is it?  (see also question #5)

2. The next font code-activity uses the two variables "_font_color" and "font_table".
The first thing I notice are the lines "stb _font_color+1,<_bl", and "lda _font_color".  These are in
preparation for the load-the-font-loop.  However, I do not notice any code preceding this where any data is
stored into that variable.  It is, however, loaded with data in the "_set_font_color.2" function,
but this routine is called by the actual user-C-code, which occurs well after the initialization
code previous indicated.  So...
a) What's the purpose of the macro "fntcpy"?  It calls "load_font", but "fntcpy" itself doesn't appear
to play any part in the code. Did I miss it?
b) What's the purpose of loading what is essentially garbage (IE: uninitialized data) into a variable, then using that variable in the load-the-font-loop. (Yes, I know the format of characters is ppppgggrrrbbb, and what it means.  But is that applicable here?).
c) Why would we care what's in the "pppp..." color portion of the character, if we are later going to
completely ignore it when we use the "_set_font_color.2" function in the user code? 

3. Again, in the user code, there is a function "_set_font_pal", which overwrites any data in the palette bits
in "_font_base".
So...
a) Why do it in the load-the-font-loop in the first place?

4). Yet again in the user code, is the function "_load_default_font".  And again,
it seems to repeat the previous functionality of "load_font", only this time using the user data.  So...
a) Why again is there this duplication of code, with data being overwritten?

5) Finally the user code function "_put_string.3" uses the variable "_font_base" (see question #1); it SEEMS to get the character  description then stores it to the VDC.  But this doesn't make sense, given that the font (which = the character description) has already been loaded into the video ram.  Or, is the use of "_font_base" actually referencing the VRAM data itself, and not the font description (loaded from "font.inc")?  If so, how does it's value relate to choosing the specific character?

As you can see, I am drawing a near-complete blank on this, although I have made good progress in everything else (so far!)

I am sure I will have more questions, based on the answers to these here.  Feel free to use my email if it seems appropriate.

Many thanks to any who can provide any guidance here.

Charlie

TheOldMan

  • Hero Member
  • *****
  • Posts: 958
Re: Programming question
« Reply #1 on: January 01, 2010, 08:41:54 AM »
I'm not 100% positive about the program you are talking about, but...
1) the standard screen (aka the Bat Table) is stored at $0000 in VRam. I haven't found a way to change that, and I've tried. For a 'standard' 256x240 screen, the end of the Bat table ends up real close to $0800. That address is the 'next available' space in VRam, which is where the font loads. [ And, just fyi, if you want a wider screen and/or scrolling, you need a bigger Bat Table, and thus have to move/re-load the font.]

2) font_color *should* get initialized to 0; I don't believe it starts out as garbage. Try just using the default font without setting the color, and see if anything shows up; if not, it's using palette block 0, and you should be able to change the font color by just setting pallet entry 1 to the color you want.

Also, I'm not too sure about the character format you're talking about; Is that the format used to define the font, or to display it? I'm pretty sure that characters get displayed by storing the value in the Bat table, which has no -rgb color- information at all; it has a palette index and a VRam offset to where the data is. Effectively, the pppp bits are the high part of the palette number, and the low bits point to the Vram data block for the character.
As to why fonts get loaded twice, that *might* be in case the screen size changed. Or, like the palette function, to make sure it is initialized correctly, in case you forget to set it.

3) put_string is actually manipulating the Bat table to display the characters; You can tell that by walking a sprite over some text, first with the sprite above the background, then with the sprite behind it.

The best way I've come up with to decipher the video and text stuff is to think of it as a group of small arrays; the first one in memory is the Bat: it contains pointers to the data it should display (and the high byte of the palette number, but that's sorta irrelevent here)
Next comes the font memory array, which is usually around $0800. It contains something similar to sprite data, but in a different layout (Nope, haven't gone into how it's stored, except to note that it's not in the standard sprite bit-plane format). Since each character takes up 16 memory locations (but don't quote me on that - I'm not that sure about the number) it kinda makes sense to drop the low 4 bits from the font character pointer.

Finally, there's the sprite data array - and that's a whole topic unto itself, with the way things are aligned in memory and stored. If you think Fonts are wierd, try writing into a sprite sometime; it drove me nuts until I walked through how it all worked, using test programs to 'see what happened'

And just for the record, most demo programs aren't done perfectly; things get left in not because they are needed, but because they *were* needed at some time, and never got taken out. It wouldn't surprise me to find out that the "hello World" example has some extra code in it that isn't needed anymore.

Charlie

  • Full Member
  • ***
  • Posts: 247
Re: Programming question
« Reply #2 on: January 01, 2010, 10:51:18 AM »
1. Ok, that seems to explain why $0800 was used.  As an FYI, no place in my proggie did I ever use, or even set/define, a BAT table.  But maybe, since I am using only a single, static screen, some kind of default action is in effect.
2. I am fairly sure there is no specific initialization of font_color, but I MAY remember reading somewhere (perhaps a posting here) that ".ds" data is automatically initialized to zero(?).  After the manipulation, the results does follow consistantly if you assume that such  initialization does occur.
3. Need to study this one.

Thanks.
Charlie

Tom

  • Guest
Re: Programming question
« Reply #3 on: January 01, 2010, 12:33:26 PM »

Quote
Here are some general questions for which I need guidance:

1. The code under consideration is "load font", part of "startup.asm".
The first function called here is "_set_font_addr". This function gets the
font address data of $0800 as defined by #FONT_VADDR, manipulates it, and stores it into
the variable "_font_base".  So...
a) Why $0800?  I do not recall any docs that indicated this is a
set-in-stone address, so why was it chosen; any specific reason? 
b) The resultant data stored in "_font_base" is $0080.  If I change the defined
address to $0810, the result is $0081.  If I use $0801, the data is $0080.  Obviously,
there is a boundary/alignment consideration here.  What is it?  (see also question #5)

 First thing, you need to remember the vram address is WORD base - not byte based. I hope *all* functions in HuC hold to this (I believe they do). Every ten words ($10) is a tile. Because $10 words is $20 bytes (32 bytes) or 1 tile. If you offset the font/tile array to an odd address, it will be unaligned. So $0810 is tile number $081. That BAT starting point is fixed at $0000 in vram. The size is dependent on an internal reg. $0000 to $0800 (remember, WORDs) is 4096 bytes - which is enough room for a 64x32 size BAT. Why they chose $800 for the start of the font location? You'd have to ask them, but regardless of the actual value - the address is static for a reason (so you can start all user tiles after the font region).

Quote
2. The next font code-activity uses the two variables "_font_color" and "font_table".
The first thing I notice are the lines "stb _font_color+1,<_bl", and "lda _font_color".  These are in
preparation for the load-the-font-loop.  However, I do not notice any code preceding this where any data is
stored into that variable.  It is, however, loaded with data in the "_set_font_color.2" function,
but this routine is called by the actual user-C-code, which occurs well after the initialization
code previous indicated.  So...
a) What's the purpose of the macro "fntcpy"?  It calls "load_font", but "fntcpy" itself doesn't appear
to play any part in the code. Did I miss it?
b) What's the purpose of loading what is essentially garbage (IE: uninitialized data) into a variable, then using that variable in the load-the-font-loop. (Yes, I know the format of characters is ppppgggrrrbbb, and what it means.  But is that applicable here?).
c) Why would we care what's in the "pppp..." color portion of the character, if we are later going to
completely ignore it when we use the "_set_font_color.2" function in the user code? 

 The fonts or tiles are indirect colors, not direct colors. Two things control the final output color. One is the subpalette number in the BAT (16 entries) and the other is the actually RGB color value in palette ram (xxxGGGRRRBBB). So you have the indirect color of the tile (1 to 16, with 0 being transparent), then the subpalette it belongs to  - that points to the color ram entry in the master palette. If pixel !=0 then, Pixel = Palette[(tile_pixel+(subpalette*16))]. The palette ram holds 512 entries, but the upper 256 is for sprites only - with the lower 256 for tiles. So for sprites, if pixel !=0 then Pixel = Palette[(sprite_pixel+(subpalette*16))+256].


Charlie

  • Full Member
  • ***
  • Posts: 247
Re: Programming question
« Reply #4 on: January 02, 2010, 01:25:54 AM »
1. Excellent, thanks.
2. Excellent, thanks

(Don't know what more to say!)

More study in process....

Charlie