Under construction.
You'll know SNES emulator will run games on other than SNES platform.
Usual games can be emulated. But sometimes a special chip named DSP (Digital Signal Processor) is embedded in SNES cart. This is not usual program, so it cannot be directly interpreted by emulator.
DM uses DSP-2 chip. So, it is required for SNES emulator developer to write software code to emulate behavior of DSP-2 hardware, in order to play DSP-2 equipped game like Dungeon Master.
(In those days, I didn't know how this special chip DSP-2 interacts with Pictures displayed in 1st person viewport.)
Snes9X v1.39a |
Snes9X v1.40 |
zsnes 1.36 |
zsnes WIP May 8, 2004 |
On 25-Jul-2003, Snes9x developer team released Snes9X v.140.
It has capacity to emulate DSP-2 hardware's behavior, and this was the first time that you can play DM on SNES emulators.
In this time (25-Jul-2003), zsnes doesn't emulates DSP-2 yet, so I started with zsnes to study how DSP-2 works.
In those days, http://users.tpg.com.au/trauma/dsp/dsp2.html is the best open technical information about DSP-2.
That site is maintained by Overload who researched many DSP chips and contributed to SNES developer community.
In those days, their information is merely little. Look at DSP2.mht.
It is required to study SNES programming by myself and know how what is done.
Anyone will suggest disassembler tools to get disassembled source code.
However I knew offline disassembler tool won't have good output.
So I decided to built in disassembler inside zsnes source code.
The built in one also associates disassembled source with footprint.
...
Really needed thing is to study about SNES's CPU 65816. It's CPU instruction set and SNES memory map.
...
I modified zsnes and make it generate a footprint. footprint is an array of integers which records ROM address CPU walked.
The footprint costs about 400MB (about 100,000,000 CPU steps) disk space when you play game in few minutes.
...
%macro endloop 0 mov bl,[esi] inc esi sub dh,[cpucycle+ebx] jc %%cpuover Hack_Enter_Now jmp dword near [edi+ebx*4] %%cpuover ret %endmacro |
The "Hack_Enter_Now" is a macro.
If you put a macro on source code, it is extracted on compile.
"Hack_Enter_Now" is to record the current PC (program counter). PC points an address which CPU read and run next opecode.
The zsnes code "jmp dword near [edi+ebx*4]" executes one 65816 CPU instruction. Usual emulator (also zsnes) uses pointer table due to gain more running performance.
%macro Hack_Enter_Now 0 call Hacken_Enter %endmacro |
"call" means call a sub-routine.
NEWSYM Hacken_Enter pushad mov eax,esi sub eax,[romdata] dec eax cmp eax,4194304 jae .noop mov [Hackc_PB_PC],eax call Hackc_Enter .noop popad ret |
This code is to determine whether PC register points to ROM address space or not. Usual code is built in SNES cart and it exists as ROM (read only memory) form.
Because it has difference memory address space between Windows (zsnes) and 65816, memory space conversion is required. Above code does it.
Following code "Hackc_Enter" performs code traps for running Dungeon Master program.
Because I don't wanna analyze the disassembled source code, I set traps step by step (trial and errors) to know the meaining of every code part. It is very ineffective work.
...
Finally, I got 20 or 30 footprints. Next partial sample is disassembled one of them.
00/8000|18 | 1|CLC 00/8001|FB | 1|XCE 00/8002|D8 | 1|CLD 00/8003|C2 30 | 1|REP # $30 00/8005|A2 FF | 1|LDX # $1FFF 00/8008|9A | 1|TXS 00/8009|F4 00 00 | 1|PEA s 00/800C|AB | 1|PLB s 00/800D|AB | 1|PLB s 00/800E|A9 00 | 1|LDA # $0000 00/8011|5B | 1|TCD 00/8012|E2 20 | 1|SEP # $20 00/8014|A9 0F | 1|LDA # $0F 00/8016|8F 00 80 3F | 1|STA $3F8000 00/801A|8F 00 80 3F | 1|STA $3F8000 00/801E|8F 00 80 3F | 1|STA $3F8000 00/8022|8F 00 80 3F | 1|STA $3F8000 00/8026|8F 00 80 3F | 1|STA $3F8000 00/802A|8F 00 80 3F | 1|STA $3F8000 00/802E|A9 00 | 1|LDA # $00 00/8030|8D 81 21 | 1|STA $2181 00/8033|8D 82 21 | 1|STA $2182 00/8036|8D 83 21 | 1|STA $2183 00/8039|A2 00 | 1|LDX # $0000 L1.1: 00/803C|8D 80 21 | 65536|STA $2180 00/803F|8D 80 21 | 65536|STA $2180 00/8042|CA | 65536|DEX 00/8043|D0 F7 | 65536|BNE r $803C ; To L1.1-1 00/8045|C2 30 | 1|REP # $30 00/8047|22 BB 80 00 | 1|JSL $0080BB ; To L2.1-1 ... ... |
...
I got help from Snes9x software. Modify the ROM and run it on Snes9x. If I modified DSP-2 access progam, screen will be messed up.
I located it by many trial and error.
I tried to find the code such as "LDA #$01" and modify its operand to other value.
I could know what I should do because I knew about Intel x86 assembler and C++ personal programing experiences.
Sending the command code #$01 to the DSP-2 processor (addreess is $#3F8000).
00/98AF|A9 01 | 16800|LDA # $01 00/98B1|8F 00 80 3F | 16800|STA $3F8000 ... ... |
...
Access to DSP-2 chip seems to be done by reading/writing memory access.
The chip seems to occupy the memory address space from $3F8000 to $3FFFFF.
I coded the next 7 commands in C++ code at first.
...
There are many trial and error for coding.
Testing how bit-plane consists. |
Seeking how to convert 4-bit packed pixel bitmap to bit-planes. gliches on screen. |
Stretching image/transparent support failed. |
My old support code (partial). This old code is no longer used.
If you try "LDA $#3F8000" or "STA $#3F8000", this code might be called.
My latest DSP-2 support code (dsp2proc.asm) may be found at sourceforge.net.
http://cvs.sourceforge.net/viewcvs.py/zsnes/zsnes/src/chips/dsp2proc.asm?rev=1.2&view=markup
...
I tried "corruptor". If compressed picture image is damaged, it shows wrong image.
...
DM reads compressed picture image from ROM. So, I set a trap "who" reads the compressed data.
I set the trap to "LDA" CPU instruction. The decompressor may access the compressed data, and it is true.
...