1 /*###################################################################################################
2 **
3 ** TMS34010: Portable Texas Instruments TMS34010 emulator
4 **
5 ** Copyright (C) Alex Pasadyn/Zsolt Vasvari 1998
6 ** Parts based on code by Aaron Giles
7 **
8 **#################################################################################################*/
9
10 #ifndef _34010OPS_H
11 #define _34010OPS_H
12
13 #include "osd_cpu.h"
14 #include "memory.h"
15
16 /* Size of the memory buffer allocated for the shiftr register */
17 #define SHIFTREG_SIZE (8 * 512 * sizeof(UINT16))
18
19
20
21 /*###################################################################################################
22 ** MEMORY I/O MACROS
23 **#################################################################################################*/
24
25 #define TMS34010_RDMEM(A) ((unsigned)cpu_readmem29lew (A))
26 #define TMS34010_RDMEM_WORD(A) ((unsigned)cpu_readmem29lew_word (A))
TMS34010_RDMEM_DWORD(offs_t A)27 static INLINE data32_t TMS34010_RDMEM_DWORD(offs_t A)
28 {
29 UINT32 result = cpu_readmem29lew_word(A);
30 return result | (cpu_readmem29lew_word(A+2)<<16);
31 }
32
33 #define TMS34010_WRMEM(A,V) (cpu_writemem29lew(A,V))
34 #define TMS34010_WRMEM_WORD(A,V) (cpu_writemem29lew_word(A,V))
TMS34010_WRMEM_DWORD(offs_t A,data32_t V)35 static INLINE void TMS34010_WRMEM_DWORD(offs_t A,data32_t V)
36 {
37 cpu_writemem29lew_word(A,V);
38 cpu_writemem29lew_word(A+2,V>>16);
39 }
40
41
42
43 /*###################################################################################################
44 ** INTERNAL I/O CONSTANTS
45 **#################################################################################################*/
46
47 enum
48 {
49 REG_HESYNC = 0,
50 REG_HEBLNK,
51 REG_HSBLNK,
52 REG_HTOTAL,
53 REG_VESYNC,
54 REG_VEBLNK,
55 REG_VSBLNK,
56 REG_VTOTAL,
57 REG_DPYCTL,
58 REG_DPYSTRT,
59 REG_DPYINT,
60 REG_CONTROL,
61 REG_HSTDATA,
62 REG_HSTADRL,
63 REG_HSTADRH,
64 REG_HSTCTLL,
65
66 REG_HSTCTLH,
67 REG_INTENB,
68 REG_INTPEND,
69 REG_CONVSP,
70 REG_CONVDP,
71 REG_PSIZE,
72 REG_PMASK,
73 REG_UNK23,
74 REG_UNK24,
75 REG_UNK25,
76 REG_UNK26,
77 REG_DPYTAP,
78 REG_HCOUNT,
79 REG_VCOUNT,
80 REG_DPYADR,
81 REG_REFCNT
82 };
83
84 enum
85 {
86 REG020_VESYNC,
87 REG020_HESYNC,
88 REG020_VEBLNK,
89 REG020_HEBLNK,
90 REG020_VSBLNK,
91 REG020_HSBLNK,
92 REG020_VTOTAL,
93 REG020_HTOTAL,
94 REG020_DPYCTL, /* matches 010 */
95 REG020_DPYSTRT, /* matches 010 */
96 REG020_DPYINT, /* matches 010 */
97 REG020_CONTROL, /* matches 010 */
98 REG020_HSTDATA, /* matches 010 */
99 REG020_HSTADRL, /* matches 010 */
100 REG020_HSTADRH, /* matches 010 */
101 REG020_HSTCTLL, /* matches 010 */
102
103 REG020_HSTCTLH, /* matches 010 */
104 REG020_INTENB, /* matches 010 */
105 REG020_INTPEND, /* matches 010 */
106 REG020_CONVSP, /* matches 010 */
107 REG020_CONVDP, /* matches 010 */
108 REG020_PSIZE, /* matches 010 */
109 REG020_PMASKL,
110 REG020_PMASKH,
111 REG020_CONVMP,
112 REG020_CONTROL2,
113 REG020_CONFIG,
114 REG020_DPYTAP, /* matches 010 */
115 REG020_VCOUNT,
116 REG020_HCOUNT,
117 REG020_DPYADR, /* matches 010 */
118 REG020_REFADR,
119
120 REG020_DPYSTL,
121 REG020_DPYSTH,
122 REG020_DPYNXL,
123 REG020_DPYNXH,
124 REG020_DINCL,
125 REG020_DINCH,
126 REG020_RES0,
127 REG020_HESERR,
128 REG020_RES1,
129 REG020_RES2,
130 REG020_RES3,
131 REG020_RES4,
132 REG020_SCOUNT,
133 REG020_BSFLTST,
134 REG020_DPYMSK,
135 REG020_RES5,
136
137 REG020_SETVCNT,
138 REG020_SETHCNT,
139 REG020_BSFLTDL,
140 REG020_BSFLTDH,
141 REG020_RES6,
142 REG020_RES7,
143 REG020_RES8,
144 REG020_RES9,
145 REG020_IHOST1L,
146 REG020_IHOST1H,
147 REG020_IHOST2L,
148 REG020_IHOST2H,
149 REG020_IHOST3L,
150 REG020_IHOST3H,
151 REG020_IHOST4L,
152 REG020_IHOST4H
153 };
154
155 /* Interrupts that are generated by the processor internally */
156 #define TMS34010_INT1 0x0002 /* External Interrupt 1 */
157 #define TMS34010_INT2 0x0004 /* External Interrupt 2 */
158 #define TMS34010_NMI 0x0100 /* NMI Interrupt */
159 #define TMS34010_HI 0x0200 /* Host Interrupt */
160 #define TMS34010_DI 0x0400 /* Display Interrupt */
161 #define TMS34010_WV 0x0800 /* Window Violation Interrupt */
162
163 /* IO registers accessor */
164 #define IOREG(reg) (state.IOregs[reg])
165 #define SMART_IOREG(reg) (state.IOregs[state.is_34020 ? REG020_##reg : REG_##reg])
166 #define PBH (IOREG(REG_CONTROL) & 0x0100)
167 #define PBV (IOREG(REG_CONTROL) & 0x0200)
168
169
170
171 /*###################################################################################################
172 ** FIELD WRITE MACROS
173 **#################################################################################################*/
174
175 #define WFIELDMAC(MASK,MAX) \
176 UINT32 shift = offset & 0x0f; \
177 UINT32 masked_data = data & (MASK); \
178 UINT32 old; \
179 \
180 offset = TOBYTE(offset & 0xfffffff0); \
181 \
182 if (shift >= MAX) \
183 { \
184 old = (UINT32)TMS34010_RDMEM_DWORD(offset) & ~((MASK) << shift); \
185 TMS34010_WRMEM_DWORD(offset, (masked_data << shift) | old); \
186 } \
187 else \
188 { \
189 old = (UINT32)TMS34010_RDMEM_WORD(offset) & ~((MASK) << shift); \
190 TMS34010_WRMEM_WORD(offset, ((masked_data & (MASK)) << shift) | old); \
191 } \
192
193 #define WFIELDMAC_BIG(MASK,MAX) \
194 UINT32 shift = offset & 0x0f; \
195 UINT32 masked_data = data & (MASK); \
196 UINT32 old; \
197 \
198 offset = TOBYTE(offset & 0xfffffff0); \
199 \
200 old = (UINT32)TMS34010_RDMEM_DWORD(offset) & ~(UINT32)((MASK) << shift); \
201 TMS34010_WRMEM_DWORD(offset, (UINT32)(masked_data << shift) | old); \
202 if (shift >= MAX) \
203 { \
204 shift = 32 - shift; \
205 old = (UINT32)TMS34010_RDMEM_WORD(offset + 4) & ~((MASK) >> shift); \
206 TMS34010_WRMEM_WORD(offset, (masked_data >> shift) | old); \
207 } \
208
209 #define WFIELDMAC_8 \
210 if (offset & 0x07) \
211 { \
212 WFIELDMAC(0xff,9); \
213 } \
214 else \
215 TMS34010_WRMEM(TOBYTE(offset), data); \
216
217 #define RFIELDMAC_8 \
218 if (offset & 0x07) \
219 { \
220 RFIELDMAC(0xff,9); \
221 } \
222 else \
223 return TMS34010_RDMEM(TOBYTE(offset)); \
224
225 #define WFIELDMAC_32 \
226 if (offset & 0x0f) \
227 { \
228 UINT32 shift = offset&0x0f; \
229 UINT32 old; \
230 UINT32 hiword; \
231 offset &= 0xfffffff0; \
232 old = ((UINT32) TMS34010_RDMEM_DWORD (TOBYTE(offset ))&(0xffffffff>>(0x20-shift))); \
233 hiword = ((UINT32) TMS34010_RDMEM_DWORD (TOBYTE(offset+0x20))&(0xffffffff<<shift)); \
234 TMS34010_WRMEM_DWORD(TOBYTE(offset ),(data<< shift) |old); \
235 TMS34010_WRMEM_DWORD(TOBYTE(offset+0x20),(data>>(0x20-shift))|hiword); \
236 } \
237 else \
238 TMS34010_WRMEM_DWORD(TOBYTE(offset),data); \
239
240
241
242 /*###################################################################################################
243 ** FIELD READ MACROS
244 **#################################################################################################*/
245
246 #define RFIELDMAC(MASK,MAX) \
247 UINT32 shift = offset & 0x0f; \
248 offset = TOBYTE(offset & 0xfffffff0); \
249 \
250 if (shift >= MAX) \
251 ret = (TMS34010_RDMEM_DWORD(offset) >> shift) & (MASK); \
252 else \
253 ret = (TMS34010_RDMEM_WORD(offset) >> shift) & (MASK); \
254
255 #define RFIELDMAC_BIG(MASK,MAX) \
256 UINT32 shift = offset & 0x0f; \
257 offset = TOBYTE(offset & 0xfffffff0); \
258 \
259 ret = (UINT32)TMS34010_RDMEM_DWORD(offset) >> shift; \
260 if (shift >= MAX) \
261 ret |= (TMS34010_RDMEM_WORD(offset + 4) << (32 - shift)); \
262 ret &= MASK; \
263
264 #define RFIELDMAC_32 \
265 if (offset&0x0f) \
266 { \
267 UINT32 shift = offset&0x0f; \
268 offset &= 0xfffffff0; \
269 return (((UINT32)TMS34010_RDMEM_DWORD (TOBYTE(offset ))>> shift) | \
270 (TMS34010_RDMEM_DWORD (TOBYTE(offset+0x20))<<(0x20-shift)));\
271 } \
272 else \
273 return TMS34010_RDMEM_DWORD(TOBYTE(offset)); \
274
275
276
277 #endif /* _34010OPS_H */
278