New Video Mode: Mode 96

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
charliegreen
Posts: 22
Joined: Wed Jan 14, 2015 7:28 pm
Location: California, USA

New Video Mode: Mode 96

Post by charliegreen »

Hello everyone!

I've just written my first video mode, mode 96, and I want to share it with you all! It's a codetile-based mode with up to 256 6x8 1bpp tiles, where the color of each on-screen location can be set independently (eg, you can have two differently-colored 'A's on-screen at the same time without adding a second 'A' tile, and you can have tiles with many different colors on the same scanline). You can have up to 16 foreground/background color combinations on-screen at a time. I made this mode because I wanted a color text-based mode that didn't require duplicating the entire font for each additional color, but it certainly doesn't have to be used only for text-based graphics.

The best resolution I've managed so far is 36x28 tiles, but I still have some ideas for optimizing it further, so it may get wider soon! It also has a fairly low ROM footprint because it compresses its tileset: a 96-tile ASCII font fits in 2798 B (4.3% of program memory). Mode 96 has a maximum RAM footprint of 1544 B. The codetile tileset generation is done by a Python script I wrote, but I've included data/font.s (which has usage instructions at the top) in case you don't have Python 3.

In any case, it's up on GitHub now, along with some example screenshots. I still need to do some work on it, of course, but it does seem to be pretty much usable, and I'd love to hear what you think!
User avatar
ry755
Posts: 226
Joined: Mon May 22, 2017 6:01 am

Re: New Video Mode: Mode 96

Post by ry755 »

Great! Makes me want to write a text adventure game for the Uzebox. :)
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: New Video Mode: Mode 96

Post by Jubatian »

Nice!

However did you check the recently added Mode 40 & 41? Those are 40x25 capable attribute modes using "normal" fonts (2Kb for 256 characters) with foreground and background colors for each tile. They however have 8 bit FG & BG attributes, so if you would be fine with a selection of 16 colors, they certainly waste RAM (a whole kilobyte if you used Mode 40, but wanted to actually have no more than 16 colors in total). So definitely there is room for improvement or a different mode for these different demands.

To get 40x25 at 8 pixels tile width, you have to do 4 cycles / pixel by the way. At 6 pixels tile width (remaining similar to Mode 90), 6 cycles per pixel is somewhat OK (at 40 tiles width you will reproduce Mode 1's layout with 6 pixels wide tiles, the leftmost and rightmost columns might be invisible), 5.5 cycles per pixel is all right.
charliegreen
Posts: 22
Joined: Wed Jan 14, 2015 7:28 pm
Location: California, USA

Re: New Video Mode: Mode 96

Post by charliegreen »

Thanks! I hope it's useful!

And oh wow, no, I didn't know about them. They seem pretty cool! They sure do use a lot of memory, though.... Maybe I'll try to make a "mode 42" that has 4-bit FG & BG attributes (unless someone else is already working on that?).

I think mode 96 might still be better for applications that require a lot of memory, though; here's the footprint of an example with a 96-character ASCII font (though having more characters in the font wouldn't impact RAM usage at all):

Code: Select all

$ avr-size -C --mcu=atmega644 _build_/video-testing.elf
AVR Memory Usage
----------------
Device: atmega644

Program:   12114 bytes (18.5% Full)
(.text + .data + .bootloader)

Data:       2243 bytes (54.8% Full)
(.data + .bss + .noinit)
Also, I'm not sure I understand you: at 5.5 cycles/pixel, 6 pixels/tile, and 40 tiles, you'd be using only 1320 out of 1820 cycles per scanline for rendering; if I understand what's going on correctly, then with a maximum value of 258 for AUDIO_OUT_HSYNC_CYCLES, calling the hsync pulse will take 279 cycles total, leaving an entire 221 extra cycles per scanline. If you use 21 for calculations between scanlines (which seems small but is reasonable in my opinion), you could get a display 46 tiles wide, or 6.33 cycles/pixel for the 40-wide one. Is there some additional time sink I'm not taking into account?
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: New Video Mode: Mode 96

Post by Jubatian »

charliegreen wrote: Sun Dec 31, 2017 11:40 pm Thanks! I hope it's useful!

And oh wow, no, I didn't know about them. They seem pretty cool! They sure do use a lot of memory, though.... Maybe I'll try to make a "mode 42" that has 4-bit FG & BG attributes (unless someone else is already working on that?).
I considered that, probably with some kilobytes larger ROM usage it could work, derived from the M40/41 code. It would have the same RAM usage like M41 (instead of 8 bit FG attributes, it would have 4 bit FG + 4 bit BG). The current M41 example doesn't use a lot more, though (Code: 13946 bytes, Data: 2420 bytes, for a 40x25 screen, if you don't need a new BG color for every scanline, then you will have 200 additional bytes RAM unused, although as of now allocated in an array). Both modes can easily take more character data, even multiple character banks on one screen (M40 is capable to display C64 / Plus4 HiRes images).
charliegreen wrote: Sun Dec 31, 2017 11:40 pmAlso, I'm not sure I understand you: at 5.5 cycles/pixel, 6 pixels/tile, and 40 tiles, you'd be using only 1320 out of 1820 cycles per scanline for rendering; if I understand what's going on correctly, then with a maximum value of 258 for AUDIO_OUT_HSYNC_CYCLES, calling the hsync pulse will take 279 cycles total, leaving an entire 221 extra cycles per scanline. If you use 21 for calculations between scanlines (which seems small but is reasonable in my opinion), you could get a display 46 tiles wide, or 6.33 cycles/pixel for the 40-wide one. Is there some additional time sink I'm not taking into account?
There is no time sink, the width of the monitor is the constraint. Mode 1 at 240 pixels width takes 1440 cycles, and several other modes have this as max. On most monitors the leftmost and rightmost tile columns of these modes are partially or completely off-screen. The definitely visible area is narrower, about 1360 cycles centered properly seem to usually display well, but the figure may vary.

The current kernel by the way can not use more than 230 for AUDIO_OUT_HSYNC_CYCLES. You can have larger HSYNC_USABLE_CYCLES in the mode, but video frame entry has that 230 as constraint for the inline mixer.
charliegreen
Posts: 22
Joined: Wed Jan 14, 2015 7:28 pm
Location: California, USA

Re: New Video Mode: Mode 96

Post by charliegreen »

You're right, mode 41 doesn't use a huge amount more. And I didn't realize you could use multiple character sets at the same time, that's really cool! I'm trying it out for one of my games right now, and it's pretty nice! Excellent work :)

A few minor suggestions, if I may (and let me know if I should move this to the Mode 40 thread): for mode 96 I wrote colorized versions of all the standard Uzebox Print functions, which would be nice to have. Also, this isn't a huge deal, but a SetColor(x,y,color) function (or something) would be slightly easier than directly assigning to aram IMO, and calling SetFontTilesIndex here for each font would make using Print functions more convenient. If you want, I'd be happy to fork modes 40/41 and add these.
Jubatian wrote: Mon Jan 01, 2018 7:29 amThere is no time sink, the width of the monitor is the constraint. Mode 1 at 240 pixels width takes 1440 cycles, and several other modes have this as max. On most monitors the leftmost and rightmost tile columns of these modes are partially or completely off-screen. The definitely visible area is narrower, about 1360 cycles centered properly seem to usually display well, but the figure may vary.
Ah, alright. That's a shame, I thought I'd be able to get higher resolutions if I had more cycles. :/ Good to know, though, thanks!
Jubatian wrote: Mon Jan 01, 2018 7:29 amThe current kernel by the way can not use more than 230 for AUDIO_OUT_HSYNC_CYCLES. You can have larger HSYNC_USABLE_CYCLES in the mode, but video frame entry has that 230 as constraint for the inline mixer.
Oh, ok! Should this line in defines.h be updated, then?
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: New Video Mode: Mode 96

Post by Jubatian »

charliegreen wrote: Tue Jan 02, 2018 3:30 am(...) calling SetFontTilesIndex here for each font would make using Print functions more convenient. If you want, I'd be happy to fork modes 40/41 and add these.
This sadly wouldn't work. IBM ASCII and Mattel have ASCII layout, so an index of zero (I imagine it being a displacement relative to standard ASCII, not?) should work for those. The C64 alphanumeric set however is not ASCII, no displacement will work for it. You have to roll your own print functions for that if you want to print ASCII text (as you see in your text editor) with the C64 font.
charliegreen wrote: Tue Jan 02, 2018 3:30 am
Jubatian wrote: Mon Jan 01, 2018 7:29 amThe current kernel by the way can not use more than 230 for AUDIO_OUT_HSYNC_CYCLES. You can have larger HSYNC_USABLE_CYCLES in the mode, but video frame entry has that 230 as constraint for the inline mixer.
Oh, ok! Should this line in defines.h be updated, then?
No, that define represents the cycle requirements of the inline mixer in that configuration, not how many cycles fit there. This just means that the inline mixer can not be used at all in that configuration with the current kernel.

Otherwise for extra functions, maybe it could be considered what kind of API an attribute mode could receive. SetColor isn't exactly OK since there could be a foreground and a background color (which of these are you setting with SetColor? How the other color would be set? What if there is also a palette?). Keep in mind though that such API functions are slow relative to accessing the VRAM / ARAM directly (this is of course no problem when porting or recreating for example C64 Basic games as the ATMega is a lot faster than the 6510).

EDIT: OK, I found and fixed some bugs in the modes related to the kernel API: now the IBM ASCII and the Mattel charsets can be used though that interface. The C64 charsets are not possible to be used as their layout is different.
charliegreen
Posts: 22
Joined: Wed Jan 14, 2015 7:28 pm
Location: California, USA

Re: New Video Mode: Mode 96

Post by charliegreen »

Jubatian wrote: Tue Jan 02, 2018 10:11 am No, that define represents the cycle requirements of the inline mixer in that configuration, not how many cycles fit there. This just means that the inline mixer can not be used at all in that configuration with the current kernel.
Oh, alright, cool. Thanks! I'll make my HSYNC_USABLE_CYCLES 230.
Jubatian wrote: Tue Jan 02, 2018 10:11 am Otherwise for extra functions, maybe it could be considered what kind of API an attribute mode could receive. SetColor isn't exactly OK since there could be a foreground and a background color (which of these are you setting with SetColor? How the other color would be set? What if there is also a palette?). Keep in mind though that such API functions are slow relative to accessing the VRAM / ARAM directly (this is of course no problem when porting or recreating for example C64 Basic games as the ATMega is a lot faster than the 6510).
Yeah, that is a little ambiguous, and probably best left up to the author of the video mode. Still, you could get around the performance impact by making the functions inline, or even just macros.
Jubatian wrote: Tue Jan 02, 2018 10:11 am EDIT: OK, I found and fixed some bugs in the modes related to the kernel API: now the IBM ASCII and the Mattel charsets can be used though that interface. The C64 charsets are not possible to be used as their layout is different.
Thanks! :) As for making the C64 charsets work, all of the Print API uses SetFont, which is left up to the video mode; you could conceivably get it to work by having SetFont calculate the correct tile index for each input character.
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: New Video Mode: Mode 96

Post by Jubatian »

charliegreen wrote: Fri Jan 05, 2018 10:37 pm
Jubatian wrote: Tue Jan 02, 2018 10:11 am EDIT: OK, I found and fixed some bugs in the modes related to the kernel API: now the IBM ASCII and the Mattel charsets can be used though that interface. The C64 charsets are not possible to be used as their layout is different.
Thanks! :) As for making the C64 charsets work, all of the Print API uses SetFont, which is left up to the video mode; you could conceivably get it to work by having SetFont calculate the correct tile index for each input character.
Maybe I will provide an option later for user-supplied GetFont and SetFont routines so you can inject them under the kernel. If I tried to meddle with them in some unconventional manner, it would still result in non-intuitive behavior as soon as the user started to do something nontrivial. For example what if he included both a C64 charset and an IBM ASCII charset? Or if he uses the C64 charset, but wants to use some custom ASCII compatible set alongside?

Inlining is not possible for these functions as they are in different compilation units (when you are using them). Making them macros... Maybe, right now I don't know whether there is any header file with sufficient visibility, and if you had them as a C macro, assembly files attempting to call them will fail.
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: New Video Mode: Mode 96

Post by Jubatian »

I made an attempt at Mode 42, and I succeeded creating it!

I added it to the Uzebox Master, you may also see a post with a screenshot in the Mode 40 topic.

Originally I though it would have some unacceptably hairy ROM demand, but in the end with some simple common tricks it is nothing being about 6 kilobytes. So if you wanted to have some game with such a mode, now there it is! :D
Post Reply