home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 2
/
FFMCD02.bin
/
new
/
misc
/
emu
/
z80
/
z80.h
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-21
|
13KB
|
388 lines
#ifndef Z80_H
#define Z80_H
/*
* C header file for the Z80 emulator.
*
* All (or most) of these types have to be defined (and to the correct
* sizes): BYTE, UBYTE, WORD, UWORD, LONG and ULONG.
*
* If Z80_ENVDATA is defined, the last element of struct Z80_Control will
* be a structure named Envdata, of the type "struct Z80_Envdata", which
* you also must have defined.
*
*/
/* All sizes and offsets are in bytes: */
/* The amount of bytes needed for the Z80 memory space */
#define Z80_MEMSIZE 0x10000
#define Z80_LBUFSIZE 16 /* Uninteresting to the normal user */
#define Z80_HBUFSIZE 16
/* The size of the memory used for the cache.
It must be word-aligned! */
#define Z80_CACHESIZE ((2*Z80_MEMSIZE)+Z80_LBUFSIZE+Z80_HBUFSIZE)
/* The space needed for memory control flags */
#define Z80_FLAGMEMSIZE Z80_MEMSIZE
/* Memory write access control flags:
;Memory flag values (signed byte):
; -1 to -128 read-only
; 0 ok to write (no detection)
; 1 to 16 access counters 1 to 16
; 17 to 63 reserved
; 64 to 127 user exception
Call Z80_SetMemFlag (described below) to set these flags.
A zero flag marks ordinary RAM, and no detection is made.
A negative flag (use Z80_MEM_ROM) marks read-only memory. Attempts
to write are ignored.
A value in the range Z80_MEM_CNT to Z80_MEM_CNT+Z80_MEM_CNTNUM-1
corresponds to write a access counter from 0 to Z80_MEM_CNTNUM-1.
On each write access, the corresponding counter in the Z80_AccessCnt
array is incremented by one. If the corresponding flag in the
Z80_CntType array is zero, the value is written, otherwise the attempt
to write is ignored.
A value in the range Z80_MEM_USR to Z80_MEM_USR+Z80_MEM_USRNUM-1
corresponds to a user memory exception from 0 to Z80_MEM_USRNUM-1.
If the Z80_MemHandler pointer is nonzero (non-NULL), the routine it
points to is called with the following parameters:
d1 contains the exception number (word).
d2 contains the value (byte).
a1 contains the Z80 address (word).
a2 is scratch (address of user-def routine).
Changes to a1 and a2 have no effect. The handler must protect any other
registers it uses, and return the following values:
d1 zero (longword) if value should be written, nonzero if not.
d2 countains the value (byte).
The memory handler call is mostly intended for more complex cases of
write access detection than the simple counters can handle. Not many
details can be found out about the current Cpu status from the memory
handler, since it is called in mid-execution of an instruction, and only
the base pointer registers TableB, Z0, CacheB and FlagsB can be trusted
to have correct values. For a list of register aliases, see the file
Z80_coding.i.
Example in C:
Z80_SetMemFlag(Control, $4000, $1B00, Z80_MEM_CNT+5);
flags the area from $4000 to $5AFF as access counter 5.
Z80_CntType[5] = 1;
sets the type of counter 5 to 'do not write'.
(Remember: the range is from 0 to Z80_MEM_CNTNUM - 1.)
*/
#define Z80_MEM_ROM (-1)
#define Z80_MEM_CNT 1
#define Z80_MEM_CNTNUM 16
#define Z80_MEM_USR 64
#define Z80_MEM_USRNUM (128-Z80_MEM_USR)
struct Z80_Control {
LONG Workspace; /* temporary storage, byte swapping and so on */
ULONG AccessCnt[Z80_MEM_CNTNUM]; /* Memory write access counters */
#define Z80_BCDSTACKSIZE 7 /* BCD stack (must be word-aligned!) */
BYTE Z80_BCDstack[6*Z80_BCDSTACKSIZE];
BYTE CntType[Z80_MEM_CNTNUM];
/* Counter type designations. Zero for write,
nonzero for no write. */
UBYTE Parity[256]; /* Parity translation table */
/* Public: */
BYTE * Memory; /* Pointer to the Z80 address space memory */
WORD * Cachemem; /* Pointer to the cache memory */
/* Public: */
BYTE * Flagmem; /* Pointer to the flag memory */
void * MemHandler; /* Pointer to User Memory Exception Handler */
/* Public (read-only): */
BYTE * zero; /* Pointer to Z80 address 0. The (signed)
word-sized Z80 registers (like Z80_HL)
can be used as offsets from this base
to access the Z80 memory space. */
WORD * cachezero; /* Corresponds to Z80_zero in cache memory */
BYTE * flagzero; /* Corresponds to Z80_zero in flag memory */
/* Public (read-only): */
WORD Running; /* Nonzero if running, zero if not */
/* Private: */
WORD Request; /* Request pointer (offset from InstrBase) */
WORD ReqLvl; /* Priority level of current request */
UWORD alt_CCR; /* This is the internal F' in CCR format */
WORD BCD_SP; /* Stack pointer for the BCD stack */
/* Must be word-aligned here! */
/* The Cpu Status structure (public fields):
Fields storing a register have simply the register's name.
The alternative registers are referred to as alt_<register>.
<register> here is one of:
byte-valued A, B, C, D, E, H, L, F, I, R
word-valued HL, IX, IY, SP, PC
special IFF, INTMOD
Accessing HL will affect H and L and vice versa (HL is an 'alias').
Only the word-valued entries are guaranteed to also be word-aligned.
IFF and INTMOD are byte-sized, and should be interpreted as follows:
IFF Bit 7 holds IFF2. Bit 6 holds IFF1. Bits 5-0 are zero.
INTMOD The values in the range -1 to 1 correspond to interrupt
modes 0 to 2, respectively.
None of these entries should be written to (and rather not read either)
unless the emulator is stopped, since their contents are then undefined.
Most are never updated or read from except upon exiting and continuing.
*/
struct CpuStatus {
BYTE pad_d0_3, alt_A, pad_d0_1, A;
BYTE pad_d1_3, alt_B, pad_d1_1, B;
BYTE pad_d2_3, alt_C, pad_d2_1, C;
BYTE pad_d3_3, alt_D, pad_d3_1, D;
BYTE pad_d4_3, alt_E, pad_d4_1, E;
WORD pad_d5_u;
union {
WORD w; /* HL can be word-accessed as s.Cpu.HL.w */
struct {
BYTE H;
BYTE L;
} b; /* or byte accessed as s.Cpu.HL.b.H (or L) */
} HL;
WORD pad_a2_u;
WORD SP;
/* Private fields */
LONG pad_a3, pad_a4, pad_a5, pad_a6;
union {
WORD w; /* IX can be word-accessed as s.Cpu.IX.w */
struct {
BYTE H;
BYTE L;
} b; /* or byte accessed as s.Cpu.IX.b.H (or L) */
} IX;
union {
WORD w; /* IY can be word-accessed as s.Cpu.IY.w */
struct {
BYTE H;
BYTE L;
} b; /* or byte accessed as s.Cpu.IY.b.H (or L) */
} IY;
union {
WORD w; /* H'L' can be word-accessed as s.Cpu.alt_HL.w */
struct {
BYTE H;
BYTE L;
} b; /* or byte accessed as s.Cpu.alt_HL.b.H (or L) */
} alt_HL;
WORD PC; /* PC (written/read only at exit/continue) */
BYTE F; /* These flags are calculated upon exit. */
BYTE alt_F; /* During emulation, they are unused. */
BYTE IFF; /* IFF2 in bit 7, IFF1 in bit 6 */
BYTE INTMOD; /* Interruptmode (-1 to 1) = (modes 0 to 2) */
BYTE I;
BYTE R; /* Only bit 7 is valid. See "notes.txt" */
/* word aligned here */
/* These could be inspected. If nonzero, a request has been
received but not yet served. */
WORD INT_FF; /* INTreq status */
WORD NMI_FF; /* NMIreq status */
WORD RES_FF; /* RESETreq status */
WORD BCD_OP; /* BCD operation */
UWORD BCD_C; /* BCD carry, in bit 0 */
BYTE BCD_A; /* BCD destination */
BYTE BCD_B; /* BCD source */
} Cpu;
#ifdef Z80_ENVDATA
/* User environment data area. Should be word-aligned here. */
struct Z80_Envdata Envdata;
#endif
}; /* end of struct Z80_Control */
/* Function prototypes and descriptions */
int Z80_Init(struct Z80_Control *);
/* Before the emulator is started, the control structure must be
initialised by calling Z80_Init() with a pointer to the structure.
The fields Z80_Memory and Z80_Cachemem must be pointing to
allocated memory. If the memory write access checking feature is
used, the field Z80_Flagmem must also be set, and if Z80_MemHandler
is nonzero it is assumed to point to a user memory exception handler.
See memory flag definitions above for details.
The user environment data area is not changed. All other fields
are automatically initialised. The Cpu Status fields are set up as