1 #include "burnint.h"
2 #include "tms34010/tms34010.h"
3 #include "tms34010_intf.h"
4 
5 #define ADDR_BITS   32
6 #define PAGE_SIZE   0x1000
7 #define PAGE_SIZE_8 (0x1000 >> 3)
8 #define PAGE_SHIFT  12
9 #define PAGE_MASK   0xFFF
10 #define PAGE_COUNT  (1 << (ADDR_BITS - PAGE_SHIFT))
11 #define PAGE_WADD    (PAGE_COUNT)
12 #define MAXHANDLER  32
13 #define PFN(x)  (((x) >> PAGE_SHIFT) & 0xFFFFF)
14 
15 template<typename T>
tms_fast_read(UINT8 * ptr,UINT32 adr)16 inline T tms_fast_read(UINT8 *ptr, UINT32 adr) {
17     return *((T*)  ((UINT8*) ptr + TOBYTE(adr & PAGE_MASK)));
18 }
19 
20 template<typename T>
tms_fast_write(UINT8 * xptr,UINT32 adr,T value)21 inline void tms_fast_write(UINT8 *xptr, UINT32 adr, T value) {
22     T *ptr = ((T*)  ((UINT8*) xptr + TOBYTE(adr & PAGE_MASK)));
23     *ptr = value;
24 }
25 
26 static TMS34010State tms34010;
27 static pTMS34010ScanlineRender scanlineRenderCallback = NULL;
28 
29 struct TMS34010MemoryMap
30 {
31     UINT8 *map[PAGE_COUNT * 2];
32 
33     pTMS34010ReadHandler read[MAXHANDLER];
34     pTMS34010WriteHandler write[MAXHANDLER];
35 };
36 
37 static TMS34010MemoryMap g_mmap;
38 
default_read(UINT32 address)39 static UINT16 default_read(UINT32 address) { return ~0; }
default_write(UINT32 address,UINT16 value)40 static void default_write(UINT32 address, UINT16 value) {}
default_shift_op(UINT32,void *)41 static void default_shift_op(UINT32,void*){}
42 
43 
IO_read(UINT32 address)44 static UINT16 IO_read(UINT32 address) { return tms::read_ioreg(&tms34010,address); }
IO_write(UINT32 address,UINT16 value)45 static void IO_write(UINT32 address, UINT16 value) { tms::write_ioreg(&tms34010, address, value); }
46 
47 // cheat-engine hook-up
TMS34010Open(INT32 num)48 void TMS34010Open(INT32 num)
49 {
50 	// not used, single core.
51 }
52 
TMS34010Close()53 void TMS34010Close()
54 {
55 	// not used, single core.
56 }
57 
TMS34010GetActive()58 INT32 TMS34010GetActive()
59 {
60 	return 0; // cpu is always active
61 }
62 
TMS34010Idle(int cycles)63 int TMS34010Idle(int cycles)
64 {
65     return 0; // not impl.
66 }
67 
68 void TMS34010WriteROM(UINT32 address, UINT8 value);
69 UINT8 TMS34010ReadByte(UINT32 address);
70 
TMS34010TotalCyclesi32()71 INT32 TMS34010TotalCyclesi32()
72 {
73 	return TMS34010TotalCycles();
74 }
75 
TMS34010SetIRQLine(INT32 cpu,INT32 vector,INT32 status)76 void TMS34010SetIRQLine(INT32 cpu, INT32 vector, INT32 status)
77 {
78 	if (status == CPU_IRQSTATUS_NONE) {
79 		TMS34010ClearIRQ(vector);
80 	}
81 
82 	if (status == CPU_IRQSTATUS_ACK) {
83 		TMS34010GenerateIRQ(vector);
84 	}
85 }
86 
87 cpu_core_config TMS34010Config =
88 {
89 	"TMS34010",
90 	TMS34010Open,
91 	TMS34010Close,
92 	TMS34010ReadByte,
93 	TMS34010WriteROM,
94 	TMS34010GetActive,
95 	TMS34010TotalCyclesi32,
96 	TMS34010NewFrame,
97 	TMS34010Idle,
98 	TMS34010SetIRQLine,
99 	TMS34010Run,
100 	TMS34010RunEnd,
101 	TMS34010Reset,
102 	0x100000000ULL,
103 	0
104 };
105 // end cheat-engine hook-up
106 
TMS34010Init()107 void TMS34010Init()
108 {
109     tms34010.shift_read_cycle = default_shift_op;
110     tms34010.shift_write_cycle = default_shift_op;
111 
112     // map IO registers
113     TMS34010SetHandlers(MAXHANDLER-1, IO_read, IO_write);
114 	TMS34010MapHandler(MAXHANDLER-1, 0xc0000000, 0xc00001ff, MAP_READ | MAP_WRITE);
115 
116 	CpuCheatRegister(0, &TMS34010Config);
117 }
118 
TMS34010Run(int cycles)119 int TMS34010Run(int cycles)
120 {
121     return tms::run(&tms34010, cycles);
122 }
123 
TMS34010TimerSetCB(void (* timer_cb)())124 void TMS34010TimerSetCB(void (*timer_cb)())
125 {
126 	tms::timer_set_cb(&tms34010, timer_cb);
127 }
128 
TMS34010TimerSet(int cycles)129 void TMS34010TimerSet(int cycles)
130 {
131 	tms::timer_arm(&tms34010, cycles);
132 }
133 
TMS34010TotalCycles()134 INT64 TMS34010TotalCycles()
135 {
136 	return tms::total_cycles(&tms34010);
137 }
138 
TMS34010NewFrame()139 void TMS34010NewFrame()
140 {
141 	tms::new_frame(&tms34010);
142 }
143 
TMS34010RunEnd()144 void TMS34010RunEnd()
145 {
146 	tms::stop(&tms34010);
147 }
148 
TMS34010Scan(INT32 nAction)149 void TMS34010Scan(INT32 nAction)
150 {
151 	tms::scan(&tms34010, nAction);
152 }
153 
TMS34010GetPC()154 UINT32 TMS34010GetPC()
155 {
156 	return tms::get_pc(&tms34010);
157 }
158 
TMS34010GetPPC()159 UINT32 TMS34010GetPPC()
160 {
161 	return tms::get_ppc(&tms34010);
162 }
163 
TMS34010Reset()164 void TMS34010Reset()
165 {
166     tms::reset(&tms34010);
167 }
168 
TMS34010GenerateIRQ(UINT32 line)169 void TMS34010GenerateIRQ(UINT32 line)
170 {
171     tms::generate_irq(&tms34010, line);
172 }
173 
TMS34010ClearIRQ(UINT32 line)174 void TMS34010ClearIRQ(UINT32 line)
175 {
176     tms::clear_irq(&tms34010, line);
177 }
178 
TMS34010SetScanlineRender(pTMS34010ScanlineRender sr)179 void TMS34010SetScanlineRender(pTMS34010ScanlineRender sr)
180 {
181     scanlineRenderCallback = sr;
182 }
183 
TMS34010SetToShift(void (* reader)(UINT32 addr,void * dst))184 void TMS34010SetToShift(void (*reader)(UINT32 addr, void *dst))
185 {
186     tms34010.shift_read_cycle = reader;
187 }
188 
TMS34010SetFromShift(void (* writer)(UINT32 addr,void * src))189 void TMS34010SetFromShift(void (*writer)(UINT32 addr, void *src))
190 {
191     tms34010.shift_write_cycle = writer;
192 }
193 
TMS34010GenerateScanline(int line)194 int TMS34010GenerateScanline(int line)
195 {
196     return tms::generate_scanline(&tms34010, line, scanlineRenderCallback);
197 }
198 
TMS34010GetState()199 TMS34010State *TMS34010GetState()
200 {
201     return &tms34010;
202 }
203 
TMS34010ReadByte(UINT32 address)204 UINT8 TMS34010ReadByte(UINT32 address)
205 {
206     UINT8 *pr = g_mmap.map[PFN(address)];
207     if ((uintptr_t)pr >= MAXHANDLER) {
208         // address is bit-address
209         return tms_fast_read<UINT8>(pr,address);
210     } else {
211         return g_mmap.read[(uintptr_t)pr](address);
212     }
213 }
214 
TMS34010ReadWord(UINT32 address)215 UINT16 TMS34010ReadWord(UINT32 address)
216 {
217     UINT8 *pr = g_mmap.map[PFN(address)];
218     if ((uintptr_t)pr >= MAXHANDLER) {
219         // address is bit-address
220         return BURN_ENDIAN_SWAP_INT16(tms_fast_read<UINT16>(pr,address));
221     } else {
222         return g_mmap.read[(uintptr_t)pr](address);
223     }
224 }
225 
TMS34010WriteWord(UINT32 address,UINT16 value)226 void TMS34010WriteWord(UINT32 address, UINT16 value)
227 {
228     UINT8 *pr = g_mmap.map[PAGE_WADD + PFN(address)];
229     if ((uintptr_t)pr >= MAXHANDLER) {
230         // address is bit-address
231         return tms_fast_write<UINT16>(pr,address, BURN_ENDIAN_SWAP_INT16(value));
232     } else {
233         return g_mmap.write[(uintptr_t)pr](address, value);
234     }
235 }
236 
TMS34010WriteROM(UINT32 address,UINT8 value)237 void TMS34010WriteROM(UINT32 address, UINT8 value) // for cheat-engine
238 {
239     UINT8 *pr = g_mmap.map[PAGE_WADD + PFN(address)];
240     if ((uintptr_t)pr >= MAXHANDLER) {
241         // address is bit-address
242 		tms_fast_write<UINT8>(pr,address, value);
243     } else {
244 		g_mmap.write[(uintptr_t)pr](address, value);
245 	}
246 
247 	pr = g_mmap.map[PFN(address)];
248     if ((uintptr_t)pr >= MAXHANDLER) {
249         // address is bit-address
250 		tms_fast_write<UINT8>(pr,address, value);
251 	}
252 }
253 
TMS34010MapReset()254 void TMS34010MapReset()
255 {
256     for (int page = 0; page < PAGE_COUNT; page++) {
257         g_mmap.map[page] = NULL;
258         g_mmap.map[page + PAGE_WADD] = NULL;
259     }
260     for (int handler = 0; handler < MAXHANDLER; handler++) {
261         g_mmap.read[handler] = default_read;
262         g_mmap.write[handler] = default_write;
263     }
264 }
265 
TMS34010MapMemory(UINT8 * mem,UINT32 start,UINT32 end,UINT8 type)266 void TMS34010MapMemory(UINT8 *mem, UINT32 start, UINT32 end, UINT8 type)
267 {
268     const int max_pages = (PFN(end) - PFN(start)) + 1;
269 
270     int page = PFN(start);
271     for (int i = 0; i < max_pages; i++, page++) {
272 
273         if (type & MAP_READ)
274             g_mmap.map[page] = mem + (PAGE_SIZE_8 * i);
275 
276         if (type & MAP_WRITE)
277             g_mmap.map[page + PAGE_WADD] = mem + (PAGE_SIZE_8 * i);
278     }
279 }
280 
TMS34010MapHandler(uintptr_t num,UINT32 start,UINT32 end,UINT8 type)281 void TMS34010MapHandler(uintptr_t num, UINT32 start, UINT32 end, UINT8 type)
282 {
283     const int max_pages = (PFN(end) - PFN(start)) + 1;
284 
285     int page = PFN(start);
286     for (int i = 0; i < max_pages; i++, page++) {
287 
288         if (type & MAP_READ)
289             g_mmap.map[page] = (UINT8*) num;
290 
291         if (type & MAP_WRITE)
292             g_mmap.map[page + PAGE_WADD] = (UINT8*) num;
293     }
294 }
295 
TMS34010SetReadHandler(UINT32 num,pTMS34010ReadHandler handler)296 int TMS34010SetReadHandler(UINT32 num, pTMS34010ReadHandler handler)
297 {
298     if (num >= MAXHANDLER)
299         return 1;
300     g_mmap.read[num] = handler;
301     return 0;
302 }
303 
TMS34010SetWriteHandler(UINT32 num,pTMS34010WriteHandler handler)304 int TMS34010SetWriteHandler(UINT32 num, pTMS34010WriteHandler handler)
305 {
306     if (num >= MAXHANDLER)
307         return 1;
308     g_mmap.write[num] = handler;
309     return 0;
310 }
311 
TMS34010SetHandlers(UINT32 num,pTMS34010ReadHandler rhandler,pTMS34010WriteHandler whandler)312 int TMS34010SetHandlers(UINT32 num, pTMS34010ReadHandler rhandler, pTMS34010WriteHandler whandler)
313 {
314     if (num >= MAXHANDLER)
315         return 1;
316     g_mmap.read[num] = rhandler;
317     g_mmap.write[num] = whandler;
318     return 0;
319 }
320 
321