windows Pico stuff wip
[picodrive.git] / cpu / DrZ80 / DrZ80.txt
CommitLineData
cc68a136 1\r
2___________________________________________________________________________\r
3\r
4 DrZ80 (c) Copyright 2004 Reesy. Free for non-commercial use\r
5\r
6 Reesy's e-mail: drsms_reesy(atsymbol)yahoo.co.uk\r
7 Replace (atsymbol) with @\r
8 \r
9___________________________________________________________________________\r
10\r
11\r
12What is it?\r
13-----------\r
14\r
15DrZ80 is an emulator for the Z80 microprocessor, written in ARM 32-bit assembly.\r
16It is aimed at chips such as ARM7 and ARM9 cores, StrongARM and XScale, to interpret Z80\r
17code as fast as possible.\r
18\r
19Flags are mapped onto ARM flags whenever possible, which speeds up the processing of an opcode.\r
20\r
21ARM Register Usage\r
22------------------\r
23\r
24See source code for up to date of register usage, however a summary is here:\r
25\r
26 r0-3: Temporary registers\r
27 r3 : Pointer to Opcode Jump table\r
28 r4 : T-States remaining\r
29 r5 : Pointer to Cpu Context\r
30 r6 : Current PC + Memory Base (i.e. pointer to next opcode)\r
31 r7 : Z80 A Register in top 8 bits (i.e. 0xAA000000)\r
32 r8 : Z80 F Register (Flags) (NZCV) in lowest four bits\r
33 r9 : Z80 BC Register pair in top 16 bits (i.e. 0xBBCC0000)\r
34 r10 : Z80 DE Register pair in top 16 bits (i.e. 0xDDEE0000)\r
35 r11 : Z80 HL Register pair in top 16 bits (i.e. 0xHHLL0000)\r
36 r12 : Z80 Stack + Memory Base (i.e. pointer to current stack in host system memory)\r
37\r
38( note: r3,r12 are always preserved when calling external memory functions )\r
39\r
40How to Compile\r
41--------------\r
42\r
43The core is targeted for the GNU compiler, so to compile just add the "DrZ80.o" object\r
44to your makefile and that should be it.\r
45\r
46If you want to compile it seperately, use: as -o DrZ80.o DrZ80.s\r
47\r
48( note: If you want to use DrZ80 with a different compiler you will need to run\r
49 some sort of parser through the source to make the syntax of the source\r
50 compatible with your target compiler )\r
51\r
52\r
53Adding to your project\r
54----------------------\r
55\r
56To add DrZ80 to your project, add DrZ80.o, and include DrZ80.h\r
57There is one structure: 'struct DrZ80', and three functions: DrZ80Run,DrZ80RaiseInt\r
58and DrZ80_irq_callback.\r
59\r
60Don't worry if this seem very minimal - its all you need to run as many Z80s as you want.\r
61It works with both C and C++.\r
62\r
63( Note: DrZ80_irq_callback is just a pointer to an irq call back function that needs\r
64 to be written by you )\r
65\r
66Declaring a Memory handlers\r
67---------------------------\r
68\r
69Before you can reset or execute Z80 opcodes you must first set up a set of memory handlers.\r
70There are 8 functions you have to set up per CPU, like this:\r
71\r
72 unsigned int z80_rebaseSP(unsigned short new_sp);\r
73 unsigned int z80_rebasePC(unsigned short new_pc);\r
74 unsigned char z80_read8(unsigned short a);\r
75 unsigned short z80_read16(unsigned short a);\r
76 void z80_write8(unsigned char d,unsigned short a); \r
77 void z80_write16(unsigned short d,unsigned short a); \r
78 unsigned char z80_in(unsigned char p);\r
79 void z80_out(unsigned char p,unsigned char d);\r
80 \r
81You can think of these functions representing the Z80's memory bus.\r
82The Read and Write functions are called whenever the Z80 reads or writes memory.\r
83The In and Out functions are called whenever the Z80 uses the I/O ports.\r
84The z80_rebasePC and z80_rebaseSP functions are to do with creating direct memory\r
85pointers in the host machines memory, I will explain more about this later.\r
86\r
87Declaring a CPU Context\r
88-----------------------\r
89\r
90To declare a CPU simple declare a struct Cyclone in your code. For example to declare\r
91two Z80s:\r
92\r
93 struct DrZ80 MyCpu;\r
94 struct DrZ80 MyCpu2;\r
95\r
96It's probably a good idea to initialise the memory to zero:\r
97\r
98 memset(&MyCpu, 0,sizeof(MyCpu));\r
99 memset(&MyCpu2,0,sizeof(MyCpu2));\r
100\r
101Next point to your memory handlers:\r
102\r
103 MyCpu.z80_rebasePC=z80_rebasePC;\r
104 MyCpu.z80_rebaseSP=z80_rebaseSP;\r
105 MyCpu.z80_read8 =z80_read8;\r
106 MyCpu.z80_read16 =z80_read16;\r
107 MyCpu.z80_write8 =z80_write8;\r
108 MyCpu.z80_write16 =z80_write16;\r
109 MyCpu.z80_in =z80_in;\r
110 MyCpu.z80_out =z80_out;\r
111\r
112Now you are nearly ready to reset the Z80, except you need one more function: checkpc().\r
113\r
114The z80_rebasePC() function\r
115---------------------------\r
116\r
117When DrZ80 reads opcodes, it doesn't use a memory handler every time, this would be\r
118far too slow, instead it uses a direct pointer to ARM memory.\r
119For example if your Rom image was at 0x3000000 and the program counter was $206,\r
120Cyclone's program counter would be 0x3000206.\r
121\r
122The difference between an ARM address and a Z80 address is also stored in a variable called\r
123'pc_membase'. In the above example it's 0x3000000. To retrieve the real PC, DrZ80 just\r
124subtracts 'pc_membase'.\r
125\r
126Everytime the Z80 PC is modified, i.e. by a jump,branch intructions or by an interupt, DrZ80\r
127calls the z80_rebasePC function. If the PC is in a different bank, for example Ram instead \r
128of Rom, change 'pc_membase', recalculate the new PC and return it.\r
129\r
130The z80_rebaseSP() function\r
131---------------------------\r
132\r
133When DrZ80 pushs/pops to the Z80 stack pointer, it doesn't use a memory handler every time. In\r
134order to gain more speed a direct pointer to ARM memory is used. For example if your Ram was at \r
1350x3000000 and the z80 stack pointer counter was 0xD000, DrZ80's stack pointer would be 0x300D000.\r
136\r
137The difference between an ARM address and a Z80 address is also stored in a variable called\r
138'sp_membase'. In the above example it's 0x3000000. To retrieve the real SP, DrZ80 just\r
139subtracts 'sp_membase'.\r
140\r
141Everytime the Z80 SP is modified ( i.e. set with a new value LD SP,NN etc ) DrZ80\r
142calls the z80_rebaseSP function. If the SP is in a different bank, for example Rom instead \r
143of Ram, change 'sp_membase', recalculate the new SP and return it.\r
144\r