forked from begoon/i8080-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathi8080.h
126 lines (109 loc) · 3.69 KB
/
i8080.h
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
// Intel 8080 (KR580VM80A) microprocessor core model
//
// Copyright (C) 2012 Alexander Demin <[email protected]>
// Changes 2018/11/23, Jim Battle ([email protected]) (see i8080.c)
//
// Credits
//
// Viacheslav Slavinsky, Vector-06C FPGA Replica
// http://code.google.com/p/vector06cc/
//
// Dmitry Tselikov, Bashrikia-2M and Radio-86RK on Altera DE1
// http://bashkiria-2m.narod.ru/fpga.html
//
// Ian Bartholomew, 8080/8085 CPU Exerciser
// http://www.idb.me.uk/sunhillow/8080.html
//
// Frank Cringle, The original exerciser for the Z80.
//
// Thanks to zx.pk.ru and nedopc.org/forum communities.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef I8080_H
#define I8080_H
/* enable this define if the host CPU is little endian (eg, intel CPUs) */
#define LITTLE_ENDIAN
#ifdef __cplusplus
extern "C" {
#endif
// TODO: just use <stdint.h> ?
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long int uint32_t;
typedef int rd_handler(int addr);
typedef void wr_handler(int addr, int byte);
typedef int in_handler(int addr);
typedef void out_handler(int addr, int byte);
typedef union {
struct {
#ifdef LITTLE_ENDIAN
uint8_t l, h; /* intel style */
#else
uint8_t h, l; /* motorola style */
#endif
} b;
uint16_t w;
} reg_pair;
// bits 1,3,5 are unused and not represented
typedef struct {
uint8_t carry_flag;
uint8_t parity_flag;
uint8_t half_carry_flag;
uint8_t zero_flag;
uint8_t sign_flag;
} flag_reg;
typedef struct {
/* processor state */
reg_pair sp, pc;
reg_pair af, bc, de, hl;
flag_reg f;
uint8_t inte; /* 1=interrupt enable */
uint8_t halt; /* 0=running, 1=halted */
/* external state handlers */
rd_handler *rd_func;
wr_handler *wr_func;
in_handler *in_func;
out_handler *out_func;
void *user;
} i8080;
/* create a new cpu instance
* 'user' is a pointer that is returned to the handler at callback time;
* pass a null pointer if your app doesn't need it
*/
extern i8080 *i8080_new(rd_handler *rd_func,
wr_handler *wr_func,
in_handler *in_func,
out_handler *out_func,
void *user
);
/* destroy a cpu instance */
extern void i8080_destroy(i8080 *cpu);
/* return user data pointer */
inline void *i8080_get_user(i8080 *cpu) { return cpu->user; }
extern void i8080_reset(i8080 *cpu);
/* execute one instruction and return the number of elapsed clock ticks */
extern int i8080_exec_one_op(i8080 *cpu);
/* non-maskable interrupt request */
extern void i8080_interrupt(i8080 *cpu, uint8_t op);
/* expose registers for test harness */
inline void i8080_jump(i8080 *cpu, int addr) { cpu->pc.w = addr; }
inline int i8080_pc(i8080 *cpu) { return cpu->pc.w; }
inline int i8080_regs_de(i8080 *cpu) { return cpu->de.w; }
inline int i8080_regs_c(i8080 *cpu) { return cpu->bc.b.l; }
inline int i8080_regs_e(i8080 *cpu) { return cpu->de.b.l; }
#ifdef __cplusplus
}
#endif
#endif /* I8080_H */