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>
fast_read(UINT8 * ptr,UINT32 adr)16 inline T fast_read(UINT8 *ptr, UINT32 adr) {
17     return *((T*)  ((UINT8*) ptr + TOBYTE(adr & PAGE_MASK)));
18 }
19 
20 template<typename T>
fast_write(UINT8 * xptr,UINT32 adr,T value)21 inline void 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 
TMS34010Init()47 void TMS34010Init()
48 {
49     tms34010.shift_read_cycle = default_shift_op;
50     tms34010.shift_write_cycle = default_shift_op;
51 
52     // map IO registers
53     TMS34010SetHandlers(MAXHANDLER-1, IO_read, IO_write);
54     TMS34010MapHandler(MAXHANDLER-1, 0xc0000000, 0xc00001ff, MAP_READ | MAP_WRITE);
55 }
56 
TMS34010Run(int cycles)57 int TMS34010Run(int cycles)
58 {
59     return tms::run(&tms34010, cycles);
60 }
61 
TMS34010TimerCB(INT64 cycles,void (* timer_cb)())62 void TMS34010TimerCB(INT64 cycles, void (*timer_cb)())
63 {
64 	tms::timer_arm(&tms34010, cycles, timer_cb);
65 }
66 
TMS34010TotalCycles()67 INT64 TMS34010TotalCycles()
68 {
69 	return tms::total_cycles(&tms34010);
70 }
71 
TMS34010NewFrame()72 void TMS34010NewFrame()
73 {
74 	tms::new_frame(&tms34010);
75 }
76 
TMS34010RunEnd()77 void TMS34010RunEnd()
78 {
79 	tms::stop(&tms34010);
80 }
81 
TMS34010Scan(INT32 nAction)82 void TMS34010Scan(INT32 nAction)
83 {
84 	tms::scan(&tms34010, nAction);
85 }
86 
TMS34010GetPC()87 UINT32 TMS34010GetPC()
88 {
89 	return tms::get_pc(&tms34010);
90 }
91 
TMS34010GetPPC()92 UINT32 TMS34010GetPPC()
93 {
94 	return tms::get_ppc(&tms34010);
95 }
96 
TMS34010Reset()97 void TMS34010Reset()
98 {
99     tms::reset(&tms34010);
100 }
101 
TMS34010GenerateIRQ(UINT32 line)102 void TMS34010GenerateIRQ(UINT32 line)
103 {
104     tms::generate_irq(&tms34010, line);
105 }
106 
TMS34010ClearIRQ(UINT32 line)107 void TMS34010ClearIRQ(UINT32 line)
108 {
109     tms::clear_irq(&tms34010, line);
110 }
111 
TMS34010SetScanlineRender(pTMS34010ScanlineRender sr)112 void TMS34010SetScanlineRender(pTMS34010ScanlineRender sr)
113 {
114     scanlineRenderCallback = sr;
115 }
116 
TMS34010SetToShift(void (* reader)(UINT32 addr,void * dst))117 void TMS34010SetToShift(void (*reader)(UINT32 addr, void *dst))
118 {
119     tms34010.shift_read_cycle = reader;
120 }
121 
TMS34010SetFromShift(void (* writer)(UINT32 addr,void * src))122 void TMS34010SetFromShift(void (*writer)(UINT32 addr, void *src))
123 {
124     tms34010.shift_write_cycle = writer;
125 }
126 
TMS34010GenerateScanline(int line)127 int TMS34010GenerateScanline(int line)
128 {
129     return tms::generate_scanline(&tms34010, line, scanlineRenderCallback);
130 }
131 
TMS34010GetState()132 TMS34010State *TMS34010GetState()
133 {
134     return &tms34010;
135 }
136 
TMS34010ReadWord(UINT32 address)137 UINT16 TMS34010ReadWord(UINT32 address)
138 {
139     UINT8 *pr = g_mmap.map[PFN(address)];
140     if ((uintptr_t)pr >= MAXHANDLER) {
141         // address is bit-address
142         return fast_read<UINT16>(pr,address);
143     } else {
144         return g_mmap.read[(uintptr_t)pr](address);
145     }
146 }
147 
TMS34010WriteWord(UINT32 address,UINT16 value)148 void TMS34010WriteWord(UINT32 address, UINT16 value)
149 {
150     UINT8 *pr = g_mmap.map[PAGE_WADD + PFN(address)];
151     if ((uintptr_t)pr >= MAXHANDLER) {
152         // address is bit-address
153         return fast_write<UINT16>(pr,address,value);
154     } else {
155         return g_mmap.write[(uintptr_t)pr](address, value);
156     }
157 }
158 
TMS34010MapReset()159 void TMS34010MapReset()
160 {
161     for (int page = 0; page < PAGE_COUNT; page++) {
162         g_mmap.map[page] = NULL;
163         g_mmap.map[page + PAGE_WADD] = NULL;
164     }
165     for (int handler = 0; handler < MAXHANDLER; handler++) {
166         g_mmap.read[handler] = default_read;
167         g_mmap.write[handler] = default_write;
168     }
169 }
170 
TMS34010MapMemory(UINT8 * mem,UINT32 start,UINT32 end,UINT8 type)171 void TMS34010MapMemory(UINT8 *mem, UINT32 start, UINT32 end, UINT8 type)
172 {
173     const int max_pages = (PFN(end) - PFN(start)) + 1;
174 
175     int page = PFN(start);
176     for (int i = 0; i < max_pages; i++, page++) {
177 
178         if (type & MAP_READ)
179             g_mmap.map[page] = mem + (PAGE_SIZE_8 * i);
180 
181         if (type & MAP_WRITE)
182             g_mmap.map[page + PAGE_WADD] = mem + (PAGE_SIZE_8 * i);
183     }
184 }
185 
TMS34010MapHandler(uintptr_t num,UINT32 start,UINT32 end,UINT8 type)186 void TMS34010MapHandler(uintptr_t num, UINT32 start, UINT32 end, UINT8 type)
187 {
188     const int max_pages = (PFN(end) - PFN(start)) + 1;
189 
190     int page = PFN(start);
191     for (int i = 0; i < max_pages; i++, page++) {
192 
193         if (type & MAP_READ)
194             g_mmap.map[page] = (UINT8*) num;
195 
196         if (type & MAP_WRITE)
197             g_mmap.map[page + PAGE_WADD] = (UINT8*) num;
198     }
199 }
200 
TMS34010SetReadHandler(UINT32 num,pTMS34010ReadHandler handler)201 int TMS34010SetReadHandler(UINT32 num, pTMS34010ReadHandler handler)
202 {
203     if (num >= MAXHANDLER)
204         return 1;
205     g_mmap.read[num] = handler;
206     return 0;
207 }
208 
TMS34010SetWriteHandler(UINT32 num,pTMS34010WriteHandler handler)209 int TMS34010SetWriteHandler(UINT32 num, pTMS34010WriteHandler handler)
210 {
211     if (num >= MAXHANDLER)
212         return 1;
213     g_mmap.write[num] = handler;
214     return 0;
215 }
216 
TMS34010SetHandlers(UINT32 num,pTMS34010ReadHandler rhandler,pTMS34010WriteHandler whandler)217 int TMS34010SetHandlers(UINT32 num, pTMS34010ReadHandler rhandler, pTMS34010WriteHandler whandler)
218 {
219     if (num >= MAXHANDLER)
220         return 1;
221     g_mmap.read[num] = rhandler;
222     g_mmap.write[num] = whandler;
223     return 0;
224 }
225 
226