Emulator Programming Memo
sorry,my English is very poor.
English grammar corrected by Stuart,thanks.
BANK MAPPING
Many consoles have bank changing (such as NES MMC),so the emulator
needs to convert to cpu addressing from the bank mapping address. for
example, banksize=0x2000:
unsigned char *bank[8]
bank[adr>>13][adr&0x1fff]
but,if bank[] is the same as the real address - just use the offset.
bank[adr>>13][adr]
BANK MAPPING WITH MMU (not test yet)
x86 higher than 386 have own MMU,virtual memory address to real memory
address converting system. Usualy, MMU is used only by the OS,but if
the user program can utelise it and emulated machine's bank size is
4096(x86 MMU's bank size) or over, BANK MAPPING will be fast.
MUST BE RAM (6502)
Usualy,memory access need
- check memory mapped I/O or memory
- convert CPU address to BANK mapped address,if memory.
so read-modify-write is heavy work. In 6502,zero page and stack
address is hard-wired. Those memory must be RAM. so zero-page access
(very used) will be fast.
MUST BE MEMORY
When emulated CPU fetch opcode,that address is not surely memory mapped I/O (or special memory such as VRAM).
Therefore,the check of memory mapped I/O or memory can be omitted.
PLANE PIXEL TO PACKED PIXEL
Many console have plane-pixel vram for BackGround/Sprite,but many host
machine have packed-pixel vram,so emulator need to convert plane-pixel
to packed-pixel. If it do each refresh screen, it is slow.
When emulated machine write vram, set dirty-flag on each BG/Sprite.
When emutator refresh screen,if dirty-flag is on, then convert and reset
dirty flag, else use previous converted data.
H-BLANK REFRESH SCREEN
Many console have an H-BLANK (Horizontal blanking) interrupt,and use
raster scrolling or some other effect. Thus many emulator use
line-by-line screen refresh to emulate it,but most scanline have same
status on most game. refresh screen can from previous H-BLANK
interrupt scanline to now H-BLANK interrupt scanline. Or, watch scroll
register or palette,etc in the VDP.
PREFETCH (not test yet)
In CPU Emulation, FLAG Emulation is heavy work. if following opecode
break same flag, previous opecode do not need to change flag.for
example,in z80:
ADD A,A (1)
ADD A,A (2)
ADD A,A (3)
opecode(1)-(2) do not need to change flag. It is probably quite slow
with interpritering this, but with recompililation it could be
noticably faster.