This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Create a 256x192 bitmap mode in C?

Create a 256x192 bitmap mode in C?
by on (#235786)
Hey guys,

Sorry, I've been away, I became involved in a _massive_ project to bring the legendary PLATO timesharing system to vintage microcomputer systems as an on-line destination, to this end, I've set up a system @ http://irata.online/ and I have written OVER A DOZEN TERMINALS FOR DIFFERENT VINTAGE COMPUTING SYSTEMS, all written in C...

...which brings me to here:

I have a working terminal that builds with CC65, it's used to target apple2, atari, c64, and c128 versions of the PLATOTerm software I am developing...

...I'd love to see if I can get a working bitmap mode on the NES that could get 256x192 resolution. If I could do this, I could get somebody to make a bridge to bring a Raspberry PI onto the cartridge bus, and provide the necessary connectivity and keyboard needed to turn the NES into a PLATO terminal.

Why? JUST BECAUSE. :) I want to port PLATOTerm _EVERYWHERE_ (I plan on over a dozen ports to more systems, this year, alone.)

How could this be done? Could I set up a raster interrupt to split the screen into thirds, and do a method similar to the GRAPHICS II mode for the TMS9918 based systems? (I support a few of those, btw, TI 99/4A, MSX, Coleco ADAM...)

I would really love to see this running on a NES, just because. :)

-Thom

p.s. here's a pic of what a 256x192 display could look like, from the ZX Spectrum port:

Attachment:
sinclair_specnotes.PNG
sinclair_specnotes.PNG [ 50.52 KiB | Viewed 5788 times ]
Re: Create a 256x192 bitmap mode in C?
by on (#235788)
By using 4 palette colours to translate the two bitplanes into 2 colours, you can double your effective pixel memory.

256 x 128 is easy enough this way. Up to 256 x 240 is very doable too with a raster split.

No special hardware would be needed for the rendering... though I'll leave it to you to figure out the communication thing. That would need hardware.

Maybe this is a good case for a sprite overflow hit to time the split, since you don't otherwise need sprites for anything.


I've been planning a monochrome NES project of my own for a while now based on this technique.
Re: Create a 256x192 bitmap mode in C?
by on (#235797)
Years ago, I made a tech demo of a VWF terminal that uses FME-7 to provide a fixed status bar at the top (needed for "West of House | Score: 0" in the Z-machine) and a scrolling main plane. This requires three split points: one below the status bar, one to change to the second CHR page, and one to change back to the first CHR page. Timing these out without mapper assistance or ludicrous spin waiting would require advanced DMC IRQ techniques. It's a lot more practical with no top status bar, as only two split points would be needed.

So:
- Is scrolling required?
- Is a Z-machine-style top status bar required?
Re: Create a 256x192 bitmap mode in C?
by on (#235805)
No scrolling is required.

No status bar is required.

-Thom
Re: Create a 256x192 bitmap mode in C?
by on (#235810)
You need 2 background palettes:

Color 00: black;
Color 01: white;
Color 10: black;
Color 11: white;

Color 00: black;
Color 01: black;
Color 10: white;
Color 11: white;

The first palette honors bit 0 of the color index and ignores bit 1, the second palette honors bit 1 and ignores bit 0. This allows you to use the 512 2-bit tiles the NES has as 1024 1-bit tiles. Wherever you use the first palette, the first plane of the tiles will be visible, wherever you use the second palette, the second plane will be visible.

In order to create a 1bpp 256x192-pixel bitmap mode on the NES you could set up a name table so that it's divided in 4 sections:

Rows 0 to 7: tiles 0 through 255 from PT $0000 using palette 0;
Rows 8 to 15: tiles 0 through 255 from PT $0000 using palette 1;
Rows 16 to 19: tiles 0 through 127 from PT $1000 using palette 0;
Rows 20 to 23: tiles 0 through 127 from PT $1000 using palette 1;

The name and attribute tables can be set just once and never touched again, but in order to switch from pattern table $0000 to $1000 you need to time a write to the $2000 register (PPU_CTRL).

Notice that tiles 128 through 255 of the pattern table haven't been used, so you can still use them for sprites normally, if you wish. If you don't need those tiles for anything, you may arrange the background in a way that's more convenient to you.

EDIT: fixed error pointed out by Jarhmander.
Re: Create a 256x192 bitmap mode in C?
by on (#235844)
tokumaru wrote:
You need 2 background palettes:

Color 00: black;
Color 01: white;
Color 10: black;
Color 11: black;

Color 00: black;
Color 01: black;
Color 10: white;
Color 11: white;

The first palette honors bit 0 of the color index and ignores bit 1, the second palette honors bit 1 and ignores bit 0. This allows you to use the 512 2-bit tiles the NES has as 1024 1-bit tiles. Wherever you use the first palette, the first plane of the tiles will be visible, wherever you use the second palette, the second plane will be visible.

The first palette should have white in its last color entry, shouldn't it?
Re: Create a 256x192 bitmap mode in C?
by on (#235846)
Jarhmander wrote:
The first palette should have white in its last color entry, shouldn't it?

You're right. Sorry for that!
Re: Create a 256x192 bitmap mode in C?
by on (#235962)
My project currently uses an NROM-256, which mapper should I move to, for the CHR-RAM?

-Thom
Re: Create a 256x192 bitmap mode in C?
by on (#235963)
NROM-256, as widely defined, accepts 8 KiB of CHR RAM. At least DABG and RHDE run in that configuration
Re: Create a 256x192 bitmap mode in C?
by on (#235964)
Any mapper can theoretically use CHR-RAM, but some emulators won't support it unless there was an existing game with it its author knew about.

If single screen nametable mirroring works, I'd suggest AxROM (mapper 7). At 32k you don't need to make any code changes vs NROM + CHR-RAM.

If horizontal or vertical mirroring us needed, UxROM (mapper 2) is probably the easiest / most common choice. You would need about 3 lines of extra code in your startup to set its banking to match NROM.
Re: Create a 256x192 bitmap mode in C?
by on (#235965)
It's true that NROM with CHR-RAM should work fine, but some emulators may reject such configuration because it was never used by official games.

BNROM (mapper 34) is the closest thing to NROM with CHR-RAM. PRG-ROM banks are 32KB, and since you only have one bank, you don't even need to initialize or switch anything, because that bank is guaranteed to be mapped on power up. Just change the header to indicate mapper 34 and 0 CHR-ROM banks, and get rid of the CHR-ROM at the end of the ROM, that's all.

BNROM is similar to AxROM, but unlike AxROM, which forces 1-screen mirroring that needs to be controlled by the game, the mirroring works as in NROM, with solder pads for H and V selection. If you want to keep everything (except for the CHR memory) identical to NROM, BNROM is the best choice.
Re: Create a 256x192 bitmap mode in C?
by on (#235987)
The reason I didn't suggest BxROM, though it is a closer match (i.e. no code changes necessary) is that it was only used in 1 game that wasn't very popular. A lot of emulators support it, and I have released a game with it myself, but a few don't, such as NES classic's built-in emulator. UxROM and AxROM on the other hand are both among the most common mappers.

Though for this particular purpose I strongly suspect single screen is a reasonable choice? AxROM seems simplest.
Re: Create a 256x192 bitmap mode in C?
by on (#235988)
I see. Yeah, for this particular project, 1-screen mirroring doesn't sound like a deal breaker at all. I wasn't aware that BNROM wasn't as well supported as those other mappers, so yeah, UxROM (mapper 2) and AxROM (mapper 7) sound like good choices too, even though they will require a single mapper write to set things up, while BNROM would've worked as is.
Re: Create a 256x192 bitmap mode in C?
by on (#236440)
I am going to try BNROM initially.

-Thom
Re: Create a 256x192 bitmap mode in C?
by on (#236441)
I suppose it's worth explicitly mentioning mapper 96.