I've been working on a 24-bit virtual machine to help me learn more about computers and programming in general and was hoping to find a bit more information on memory mapped input/output and hardware interrupts.
At the moment I have most of the opcodes implemented and about have of them implementated in an assembler. At the moment I can load a 'rom' and the machine will load it into 'memory' and run through the instructions until it reaches an $FF in memory then it ends and dumps the register states to a terminal.
At the time I started this, I was interested in learning to program the snes but it seemed frustrating and somewhat unrewarding so I took what I understood about how the snes worked and tried to simplify it and make it easier (and more fun) to program.
The CPU has 16 16-bit registers that are byte or word addressable and one special 8-bit flag register modifiable through special op codes. The first 8 are general purpose registers. The upper 8 are special registers that have specific functions. It has 24-bit memory addressing using either the upper or lower byte from one register as an offset register and the word from another as the 16-bit address. Memory is separated into 256 pages of 65535 bytes each allowing 16mb of addressable memory. Instructions are read one word at a time and each instruction will move the instruction pointer to where it needs to be at the end of the instruction.
My overall goal is to allow some basic graphic output and input handling and maybe eventually simulated block devices for storage. My plan is to use BearLibTerminal for input/output. Its a fairly small, SDL, based pseudoterminal that allows characters and graphical tiles to be treated the same way. Its also a runtime library that can be configured through an external text file so the hassle of dealing with graphics stored in memory is avoided.
The part I'm not sure about is how to send input from the 'terminal' to the machine and output from the machine to the 'terminal'. I was thinking of using an area of memory to map to some basic terminal functions. Setting an address would open a terminal another would clear and refresh it. I was going to use a page or two as screen buffers that can be drawn to the screen. How they're drawn would depend on the current mode of the terminal.
Input would be mapped into a different section of memory. I was thinking of using a few bytes to store raw key presses and using an interrupt to copy them from there to a different area of memory before the next instruction is carried out.
The part I'm not sure about is exactly how interrupts work and how I can have my processor jump in the middle of an instruction to deal with an interrupt. I'm also not sure if this is even how I should go about doing this. If anyone has any experience in this and could share some advice it'd be very much appreciated. I've read through both the nes and snesdev wikis and the docs for the 6502 and 65816 processors several times and studied the memory maps for both machines. I'm programming my machine in D so I also took a look at the source for this project: https://code.dlang.org/packages/gbaid and it helped but I'm still sort of lost. Thanks in advance for any help.