Operating system for the NES.

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.

Moderator: Moderators

ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Operating system for the NES.

Post by ZeroDivisionGuy »

I've had an idea: making an OS for the NES. A kernel that you can use to execute commands like on the Apple 2.
I actually did, i'm testing it on emulator(s), FCEUX, Mesen, Nestopia and EmuHawk seem to accept my ROM.

THIS IS NOT A JOKE. PLEASE STAY SERIOUS.

This is what we want:

The ROM fits only in 16 KB.
It should have 32 KB of PRG RAM. (Mappable from $4020 through $BFFF)
It must use CHR RAM.

This is how memory will be mapped:

Kernel registers from $4020 through $402F.
31.9625 KB ROM from $4030 through $BFFF.
16 KB ROM from $C000 through $FFFF.
8KB CHR RAM from $0000 through $1FFF (PPU)
2KB VRAM (will we use it anyway?) for 4 screens (Nametable)

I'm being inspired by the A2 for this. It uses a 6502 CPU too, so doing something similar on the NES should be easy to do.

Also, i think i can use the expansion port for the console to add custom hardware (like disk reader, etc...)
I thought the device for the expansion port should use a M68K or a W65C816 for processing reasons, or nothing at all. But we still need something that can make hardware like disk readers to work.
40 KB of RAM is a lot, but adding up to 64 KB would be even better. It's unfortunate that the NES doesn't decode the PPU registers properly, so it's mirrored all up to $3FFF. The 2KB SRAM is also mirrored, but i guess we have to live with that.
40 KB is still 10 times more than what the A2 had, so we shouldn't complain about that.

Now, what if we want to read from an external device???

First: We need a processing chip. M68K, W65C816, or just the W65C02 would help us do that.
Second: We need a device that reads our external device. Let's say it's a floppy reader...
Last: We need a VIA (or something else) to communicate with the external processor that will load our floppy for us.

With that, here's how it should work:

1 register for sector number.
1 register for number of sectors.
2 registers for address origin to load data to. (lo/hi)
1 register for enabling the transfer from device to RAM.
1 register for device status.

I'll use my assembly code to specify the informations. Then i'll poke a byte to the register that enables the reading. At this moment, i use this code:

Code: Select all

Wait_until_read_complete:
	LDA Device_status
	BPL Wait_until_read_complete
	xyz...
We can use a custom NMI routine that would do checks and stuff so we can have a "Loading..." screen.

At this moment, the 2A03/2A07 shouldn't access the RAM. If it does, the data is corrupted.

When the loading routine is done, when the status register bit 7 is true, we can continue.

Then, the code should be executable.

That lets us the possibility to import software to the console, like programs you saved on disk, or... BASIC???
If anybody is guessing about importing BASIC to the NES, it's another story, you have to decompile it, change things etc... Just throw that out...
How we read the keyboard? Oh yeah... oops.

Our external hardware will let us connect a PS/2 keyboard. We'll use a register for that.
Our input is sent to the external CPU. After checking and processing, it's sent to the register. The kernel will read it, then use it like actual keyboard input.

I don't know how USB works. Don't harass me with that.

Also, the idea of a "mouse" is useless for me. Use Windows 2.xx for that instead.

Now, i guess i'm done for the hardware. Regarding the software:

RAM address $0 will be used for "NMI routine ID".
0 just increments VBlank counter (address $1) then executes an RTI instruction.
1 is used by the kernel.
2 is for "custom NMIs". When NMI occurs, it just jumps to the address specified by RAM addresses $1E and $1F in little endian.
3 is used for commands from the kernel.

RAM address $1 is just a VBlank counter.

RAM addresses $2-$16 are reserved for the kernel.

RAM address $17 is what i call a "Break mode". It is used when a "BRK" instruction is executed.
0 returns to the kernel command prompt and shows registers values.
1 returns to the kernel command prompt and... that's it.

RAM addresses $18-$1D are reserved for the kernel.

RAM addresses $1E and $1F are used to specify the "custom NMI" routine address.

Finally, RAM addresses $20 through $9F are used as a command buffer, for conversions etc.

RAM page $02 ($200-$2FF) will be transferred to OAM by the kernel every frame. That lets you poking some values into CHR RAM to display sprites.

RAM page $03 ($300-$3FF) is used as a buffer for the command prompt. This is where your command goes when you type it.

Now, let's talk about interruptions, programming, etc...

The BRK instruction has an use. It's use is to stop your program and return to the kernel command prompt.
Basically, in your game, you may have a "quit" button, if you use it, your game will execute the BRK instruction. At this moment, the command prompt loads again.

WARNING: Before doing that, please clean pages $02 and $03 (RAM addresses $200-$3FF) so there's no conflicts with the kernel. Also set the "Break mode" (Address $17) value to $01.

NOW, for programming: "SEI" and "CLD" instructions are not required.
You don't need to clean the RAM. (Why wouldn't NES OS do it for you, anyway?)
The APU is already initialized.

And, for graphics: since the OS uses CHR RAM and not CHR ROM, you can change the characters and the sprites, even the ASCII characters that are already loaded! And, as i said earlier, you can display custom sprites in the command prompt.

Now, for the most exciting and final part: the commands.

Here's the commands i've implemented:

start: Executes code at the specified address.
poke: Modify one or multiple values from an address.
peek: Display a value from an address.
vpoke: Modify one or multiple values from a PPU address.
vpeek: Display a value from a PPU address.
clear: Clears the screen.
textcolor: Changes the color of the text.
shadow: Changes the color of the text shadow (there's none when you start the OS.)
bgcolor: Changes the color of the background.
light: Changes the color of the background to sky color.
night: Changes the color of the background to black.

These are the commands that i will implement:

list: Display data from an address to another.
vlist: Same, but for PPU BUS addresses.
ramclear: Clears RAM from an address to another.
vramclear: Clears VRAM from an address to another.


That's it! Honestly making an OS for the NES will just help us for making software directly on it and saving to disks etc... But it would be better in my opinion to do one for the SNES.

I'll release the ROM when it will have all commands implemented and all bugs fixed! (it still won't be finished after all...)
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Operating system for the NES.

Post by dougeff »

Vi Grey is working on an OS for the NES.

Called NEoS.

https://twitter.com/ViGreyTech/status/1 ... 73955?s=19
nesdoug.com -- blog/tutorial on programming for the NES
ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Re: Operating system for the NES.

Post by ZeroDivisionGuy »

dougeff wrote: Sat May 15, 2021 6:18 pm Vi Grey is working on an OS for the NES.

Called NEoS.

https://twitter.com/ViGreyTech/status/1 ... 73955?s=19
At least, i'm not the only person who does this, that's what i see...
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Operating system for the NES.

Post by lidnariq »

ZeroDivisionGuy wrote: Sat May 15, 2021 6:15 pm The ROM fits only in 16 KB.
Why? (Because there's not quite 48KB of available address space?)
8KB CHR RAM from $0000 through $1FFF (PPU)
2KB VRAM (will we use it anyway?) for 4 screens (Nametable)
For cost reductions reasons, you should really specify using only one external CHR memory instead of two.
But we still need something that can make hardware like disk readers to work.
What do you mean when you say "disk reader"? Apple ][ style, with the IWM? C64, with a second 6502? PC style, with an explicit FDC?
The BRK instruction has an use. It's use is to stop your program and return to the kernel command prompt.
Why? What does using it solve instead of just jumping to a certain address in ROM?


Also, you may find Contiki interesting: http://hitmen.c02.at/html/tools_contiki.html
User avatar
aquasnake
Posts: 515
Joined: Fri Sep 13, 2019 11:22 pm

Re: Operating system for the NES.

Post by aquasnake »

BRK instruction is similar to JMP ($fffe), but it will push into the stack. BRK can only jump to the IRQ vector address, while JMP ($XXXX) can go to anywhere without causing stack occupation

With BRK, you must be careful. Multiple BRK will form nesting and increase the stack length/depth. After several times, it will lead to stack overflow. You need to count BRK actively and RETI again to release the stack to infinitely use BRK
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: Operating system for the NES.

Post by calima »

"I want to compute on a NES, perhaps including a keyboard, floppy drive and printer" is already covered by many chinese famiclones.
ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Re: Operating system for the NES.

Post by ZeroDivisionGuy »

lidnariq wrote: Sat May 15, 2021 8:38 pm
ZeroDivisionGuy wrote: Sat May 15, 2021 6:15 pm The ROM fits only in 16 KB.
Why? (Because there's not quite 48KB of available address space?)

We need to reduce the cost for other chips like CHR RAM.
Also, you need space for RAM. Can you imagine how bad is using 24 KB of RAM instead of 40 KB?
8KB CHR RAM from $0000 through $1FFF (PPU)
2KB VRAM (will we use it anyway?) for 4 screens (Nametable)
For cost reductions reasons, you should really specify using only one external CHR memory instead of two.
What do you mean by "two CHR memory"? One is enough...
But we still need something that can make hardware like disk readers to work.
What do you mean when you say "disk reader"? Apple ][ style, with the IWM? C64, with a second 6502? PC style, with an explicit FDC?
I actually simplified everything. By "disk reader" i mean an external device reader, either a floppy, cassette or something else that everyone would use...
The BRK instruction has an use. It's use is to stop your program and return to the kernel command prompt.
Why? What does using it solve instead of just jumping to a certain address in ROM?
That's for simplification reasons. Yeah, you CAN use "JMP ($FFFE)", but using 1 byte instead of 3 is still better.
Also, you may find Contiki interesting: http://hitmen.c02.at/html/tools_contiki.html
This is a Desktop kernel of some kind. Mine is a command prompt.

Please take my words that i tried to simplify as best as i can.
Last edited by ZeroDivisionGuy on Sun May 16, 2021 3:40 am, edited 1 time in total.
ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Re: Operating system for the NES.

Post by ZeroDivisionGuy »

aquasnake wrote: Sat May 15, 2021 9:04 pm BRK instruction is similar to JMP ($fffe), but it will push into the stack. BRK can only jump to the IRQ vector address, while JMP ($XXXX) can go to anywhere without causing stack occupation

With BRK, you must be careful. Multiple BRK will form nesting and increase the stack length/depth. After several times, it will lead to stack overflow. You need to count BRK actively and RETI again to release the stack to infinitely use BRK
Actually, you CAN'T use multiple BRKs, unless if you want to destroy your console.
Also, I actually wanted to use "JMP ($XXXX)", so you can use routines like PPU address updating, Skip line, etc...

Another use of BRK is for dumping the program counter and displaying it on screen.
When the "Break mode" is set to 0, it will show all CPU registers, these are registers X and Y, the accumulator, the stack pointer, the procecssor status and the program counter. That's for debugging reasons.
ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Re: Operating system for the NES.

Post by ZeroDivisionGuy »

calima wrote: Sun May 16, 2021 12:02 am "I want to compute on a NES, perhaps including a keyboard, floppy drive and printer" is already covered by many chinese famiclones.
wow, not gonna lie, i don't wanna buy weird chinese products, i actually want to use the best hardware.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Operating system for the NES.

Post by lidnariq »

ZeroDivisionGuy wrote: Sun May 16, 2021 3:26 am
lidnariq wrote: Sat May 15, 2021 8:38 pm
ZeroDivisionGuy wrote: Sat May 15, 2021 6:15 pm The ROM fits only in 16 KB.
Why? (Because there's not quite 48KB of available address space?)
We need to reduce the cost for other chips like CHR RAM.
Also, you need space for RAM. Can you imagine how bad is using 24 KB of RAM instead of 40 KB?
That's ... not how this works at all. More decoding is more expensive than less decoding. You physically cannot buy a new RAM smaller than 32KB anymore, or a new 'PROM smaller than 64KB.

So why 16KB of ROM? The only reason I can think of is that it lets you use more of the address space, but that's not a particularly valuable thing: It mostly only feels wasteful.
What do you mean by "two CHR memory"? One is enough...
External PPU memory. You specified both 8KB CHR RAM for tiles and 2KB extra RAM for nametables. Fewer parts is cheaper than more. Use one 32KB RAM. Or don't use 4-screen nametables: it's just not that useful.
[using BRK is] simplification reasons. Yeah, you CAN use "JMP ($FFFE)", but using 1 byte instead of 3 is still better.
That's the wrong economy. Code size is very rarely relevant on the 6502, only data size and code speed. And BRK is slower than JSR addr. (Atari 2600 excepted)
[Contiki] is a Desktop kernel of some kind. Mine is a command prompt.
[...]
wow, not gonna lie, i don't wanna buy weird chinese products, i actually want to use the best hardware.
You should really dig in a little more to what they're doing and how they're doing things. Presuming that you can make a better design without studying the work of those who've come before you is a guaranteed way to make an inferior thing.
ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Re: Operating system for the NES.

Post by ZeroDivisionGuy »

lidnariq wrote: Sun May 16, 2021 12:03 pm You should really dig in a little more to what they're doing and how they're doing things. Presuming that you can make a better design without studying the work of those who've come before you is a guaranteed way to make an inferior thing.
Eh, it's like copying on other people... Wait, it is! I don't want to do that!
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Operating system for the NES.

Post by lidnariq »

It's more like seeing what other people did so that you don't invent a five-sided wheel :) :P
ZeroDivisionGuy
Posts: 11
Joined: Sat May 15, 2021 11:15 am

Re: Operating system for the NES.

Post by ZeroDivisionGuy »

lidnariq wrote: Sun May 16, 2021 4:28 pm It's more like seeing what other people did so that you don't invent a five-sided wheel :) :P
so, you're saying that i'm not capable of doing this? well, i'll do it myself anyways. I don't care.
this also will come to Super Nintendo and Mega Drive since i love SNES for it's graphics and the Mega Drive for it's CPU.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Operating system for the NES.

Post by lidnariq »

Ok, fine, if you want a different objection:
ZeroDivisionGuy wrote: Sun May 16, 2021 3:39 am wow, not gonna lie, i don't wanna buy weird chinese products, i actually want to use the best hardware.
ZeroDivisionGuy wrote: Sun May 16, 2021 4:20 pm Eh, it's like copying on other people... Wait, it is! I don't want to do that!
So either you don't want to copy other people, or you want "the best" hardware. Which is it? Because I can guarantee the design you've made is inferior right now.
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Operating system for the NES.

Post by Controllerhead »

ZeroDivisionGuy wrote: Fri May 21, 2021 9:22 am so, you're saying that i'm not capable of doing this? ... this also will come to Super Nintendo and Mega Drive since i love SNES for it's graphics and the Mega Drive for it's CPU.
Being "technically capable" of completing a project and "spending years of your life to see it through" are two entirely different things. It's nice to have big dreams and plans, but, the devil is in the details.

I think ignoring and dismissing both the best minds of NESdev and previous projects that have done what you're trying to accomplish are mistakes, but, no one is going to stop you from writing as much code as you want how you want to write it. Go for it. Maybe you will see it through, and i hope you do, but i won't be holding my breath.
Image
Post Reply