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