summaryrefslogtreecommitdiff
path: root/apps/plugins/zxbox/README.Z80
blob: 39f57eff3bdc99c5f411f7336b73dc9abf1ca4bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
This file describes how to use the Z80 processor emulation as a
standalone module (without the ZX Spectrum emulation).

===========================================================================
You will need the following files:

For the 'intel x86' assembly version:
-------------------------------------

z80.c z80.h z80_type.h i386step.S i386def.S i386op1.S i386op1x.S 
i386op2.S i386op2x.S i386op3.S i386op3x.S i386op4.S i386op5.S i386op6.S 
sp_to_s.c

For the 'C' version:
--------------------

z80.c z80.h z80_type.h z80_step.c z80_def.h z80_ari.h z80optab.c z80optab.h
z80_op1.c z80_op1x.c z80_op1.h z80_op2.c z80_op2x.c z80_op2.h
z80_op3.c z80_op3x.c z80_op3.h z80_op4.c z80_op4x.c z80_op4.h
z80_op5.c z80_op5.h z80_op6.c z80_op6.h

===========================================================================
Makefile rules:

For the 'intel x86' assembly version:
-------------------------------------

CC = gcc
AR = ar
CPPFLAGS = 
CFLAGS = -Wall -O3
CPP = $(CC) -E

z80_i386_objs = z80.o i386emul.o

libz80.a: $(z80_i386_objs)
    $(AR) cr libz80.a $(z80_i386_objs)

i386emul.o: i386emul.s
    $(CC) -c $(CFLAGS) i386emul.s

i386emul.s: i386emul.sp sp_to_s
    ./sp_to_s < i386emul.sp > i386emul.s

i386emul.sp: i386step.S
    $(CPP) $(CPPFLAGS) i386step.S > i386emul.sp

sp_to_s: sp_to_s.o
    $(CC) -o sp_to_s $(LDFLAGS) sp_to_s.o

.SUFFIXES:
.SUFFIXES: .c .o

.c.o:
    $(CC) -c $(CFLAGS) $(CPPFLAGS) $<


For 'C' version:
----------------

CC = gcc
AR = ar
CPPFLAGS = -DZ80C
CFLAGS = -Wall -O3 -fomit-frame-pointer -funroll-loops

z80_c_objs = z80.o z80_step.o z80optab.o z80_op1.o z80_op2.o z80_op3.o \
             z80_op4.o z80_op5.o z80_op6.o 

libz80.a: $(z80_c_objs)
    $(AR) cr libz80.a $(z80_c_objs)

.SUFFIXES:
.SUFFIXES: .c .o

.c.o:
    $(CC) -c $(CFLAGS) $(CPPFLAGS) $<

===========================================================================
The following functions are defined by libz80.a:

void z80_init()
---------------

This function initializes the processor emulation. This must be called
only once at the beginning of the program.

int z80_step(int ticknum)
-------------------------

This function executes z80 instructions for 'ticknum' number of clock
cycles. It returns the remaining number of ticks.

NOTE: the remaining number of ticks is always zero or negative,
meaning that exactly, or more than the given 'ticknum' clock cycles
were executed. This is because WHOLE instructions are executed at a
time.

NOTE: HALT, LDDR, etc... do not count as one instruction, but as a
series of instructions (e.g. HALT is a series of NOPs).

void z80_reset()
----------------

This function resets the Z80 processor. This has the same effect as
applying a pulse to the RESET input of the processor.

NOTE: z80_init() does not reset the Z80, z80_reset() should be called
after it.

void z80_interrupt(int data)
-----------------------------

Causes a Maskable Interrupt. Interrupt mode 1 and 2 are emulated
correctly, in interrupt mode 2 'data' is used in the address
calculation. In interrupt mode 0, it is assumed (as on the ZX
Spectrum) that 0xFF is on the data bus, and always RST 38 is
generated.

NOTE: It is not emulated, that in the instruction after EI no
interrupt can be generated.

void z80_nmi()
--------------

Causes a Non Maskable Interrupt.

===========================================================================
Accessing the memory, the I/O ports and the Z80 processor's state
(i.e. registers, etc...)

To use the functions above and the variables below, include the
"z80.h" include file.

Memory
------

The memory is stored in the z80_proc.mem[] byte array, which has a
size of 65536. By default it is all RAM. To make parts of it read
only, you have to redefine the appropriate macros in i386step.S and/or
z80_def.h. (These macros are sorounded by #ifdef SPECT_MEM, #else,
#endif statements.)

The memory is initialised to random data. You must fill it in before
starting the emulation, but AFTER the call to z80_init().

I/O
---

The input port values are stored in z80_inports[] array, which has a
size of 256. The IN instruction will use the appropriate element of
this array. This array is initialised to all zeroes.

The output port values can be queried from the z80_outports[] array,
which has also a size of 256. The OUT instruction will store the value
in the element addressed by the instruction.

If you need more complex behaviour of the I/O, you must redefine the
appropriate macros in i386step.S and z80_def.h.

Processor state
---------------

You can access the processor's state with the following variables and
macros defined in "z80.h".

Registers:

Double registers: 
  normal:  BC, DE, HL, AF, IR, IX, IY, PC, SP,
  aux:     BCBK, DEBK, HLBK, AFBK

Single registers:
  RB, RC, RD, RE, RH, RL, RA, RF, RI, RR, XH, XL, YH, YL, PCH, PCL, SPH, SPL

Misc state:
  z80_proc.haltstate   (1: processor is in halt mode, 0: processor is runnig)
  z80_proc.it_mode     (interrupt mode 0, 1 or 2)
  z80_proc.iff1        (interrupt flip-flop 1)
  z80_proc.iff2        (interrupt flip-flop 2)

You need not access the other parts of z80_proc, they are meaningless
outside the z80_step() function.