|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Custom chip emulation
5: *
6: * Copyright 1995-2002 Bernd Schmidt
7: * Copyright 1995 Alessandro Bissacco
8: * Copyright 2000-2010 Toni Wilen
9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13: #include "compat.h"
14: #include "hatari-glue.h"
15: #include "options_cpu.h"
16: #include "custom.h"
17: #include "newcpu.h"
18: #include "main.h"
19: #include "cpummu.h"
20: #include "cpu_prefetch.h"
21: #include "m68000.h"
22: #include "debugui.h"
23: #include "debugcpu.h"
24:
25: #define WRITE_LOG_BUF_SIZE 4096
26:
27: extern struct regstruct mmu_backup_regs;
28: static uae_u32 mmu_struct, mmu_callback, mmu_regs;
29: static uae_u32 mmu_fault_bank_addr, mmu_fault_addr;
30: static int mmu_fault_size, mmu_fault_rw;
31: static int mmu_slots;
32: static struct regstruct mmur;
33: static int userdtsc = 0;
34: int qpcdivisor = 0;
35: volatile frame_time_t vsyncmintime;
36:
37: void do_cycles_ce (long cycles);
38:
39: unsigned long int event_cycles, nextevent, is_lastline, currcycle;
40: uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode);
41: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v);
42: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v);
43: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode);
44: frame_time_t read_processor_time_qpf (void);
45: frame_time_t read_processor_time_rdtsc (void);
46:
47:
48: typedef struct _LARGE_INTEGER
49: {
50: union
51: {
52: struct
53: {
54: unsigned long LowPart;
55: long HighPart;
56: };
57: int64_t QuadPart;
58: };
59: } LARGE_INTEGER, *PLARGE_INTEGER;
60:
61: uae_u16 dmacon;
62: uae_u8 cycle_line[256];
63:
64: struct ev eventtab[ev_max];
65:
66: void do_cycles_ce (long cycles)
67: {
68: static int extra_cycle;
69:
70: cycles += extra_cycle;
1.1.1.2 ! root 71:
1.1 root 72: while (cycles >= CYCLE_UNIT) {
1.1.1.2 ! root 73: // int hpos = current_hpos () + 1;
! 74: // sync_copper (hpos);
! 75: // decide_line (hpos);
! 76: // decide_fetch_ce (hpos);
! 77: // if (bltstate != BLT_done)
! 78: // decide_blitter (hpos);
1.1 root 79: do_cycles (1 * CYCLE_UNIT);
80: cycles -= CYCLE_UNIT;
81: }
1.1.1.2 ! root 82:
1.1 root 83: extra_cycle = cycles;
84: }
85:
86: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
87: {
88: int hpos;
89:
90: /*
91: hpos = dma_cycle ();
92: do_cycles_ce (CYCLE_UNIT);
93: */
94: #ifdef DEBUGGER
95: if (debug_dma) {
96: int reg = 0x1100;
97: if (mode < 0)
98: reg |= 4;
99: else if (mode > 0)
100: reg |= 2;
101: else
102: reg |= 1;
103: record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
104: checknasty (hpos, vpos);
105: }
106: #endif
107:
108: if (mode < 0)
109: put_long (addr, v);
110: else if (mode > 0)
111: put_word (addr, v);
112: else if (mode == 0)
113: put_byte (addr, v);
114:
115: regs.ce020memcycles -= CYCLE_UNIT;
116: }
117:
118: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
119: {
120: uae_u32 v = 0;
121: int hpos;
122: struct dma_rec *dr;
123:
124: /*
125: hpos = dma_cycle ();
126: do_cycles_ce (CYCLE_UNIT);
127: */
128:
129: #ifdef DEBUGGER
130: if (debug_dma) {
131: int reg = 0x1000;
132: if (mode < 0)
133: reg |= 4;
134: else if (mode > 0)
135: reg |= 2;
136: else
137: reg |= 1;
138: dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
139: checknasty (hpos, vpos);
140: }
141: #endif
142: if (mode < 0)
143: v = get_long (addr);
144: else if (mode > 0)
145: v = get_word (addr);
146: else if (mode == 0)
147: v = get_byte (addr);
148:
149: #ifdef DEBUGGER
150: if (debug_dma)
151: dr->dat = v;
152: #endif
153:
154: regs.ce020memcycles -= CYCLE_UNIT;
155: return v;
156: }
157:
158: uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
159: {
160: uae_u32 v = 0;
161: int hpos;
162: struct dma_rec *dr;
163:
164: /*
165: hpos = dma_cycle ();
166: do_cycles_ce (CYCLE_UNIT);
167: */
168:
169: #ifdef DEBUGGER
170: if (debug_dma) {
171: int reg = 0x1000;
172: if (mode < 0)
173: reg |= 4;
174: else if (mode > 0)
175: reg |= 2;
176: else
177: reg |= 1;
178: dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
179: checknasty (hpos, vpos);
180: }
181: #endif
182: if (mode < 0)
183: v = get_long (addr);
184: else if (mode > 0)
185: v = get_word (addr);
186: else if (mode == 0)
187: v = get_byte (addr);
188:
189: #ifdef DEBUGGER
190: if (debug_dma)
191: dr->dat = v;
192: #endif
193:
194: do_cycles_ce (CYCLE_UNIT);
195: return v;
196: }
197:
198: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
199: {
200: int hpos;
201:
202: /*
203: hpos = dma_cycle ();
204: do_cycles_ce (CYCLE_UNIT);
205: */
206:
207: #ifdef DEBUGGER
208: if (debug_dma) {
209: int reg = 0x1100;
210: if (mode < 0)
211: reg |= 4;
212: else if (mode > 0)
213: reg |= 2;
214: else
215: reg |= 1;
216: record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
217: checknasty (hpos, vpos);
218: }
219: #endif
220:
221: if (mode < 0)
222: put_long (addr, v);
223: else if (mode > 0)
224: put_word (addr, v);
225: else if (mode == 0)
226: put_byte (addr, v);
227: do_cycles_ce (CYCLE_UNIT);
228:
229: }
230:
231: int is_cycle_ce (void)
232: {
233: int hpos = current_hpos ();
234: return cycle_line[hpos];
235: }
236:
237: void reset_frame_rate_hack (void)
238: {
239: /* Laurent : should it be adapted or removed ?
240: if (currprefs.m68k_speed != -1)
241: return;
242:
243: if (! rpt_available) {
244: currprefs.m68k_speed = 0;
245: return;
246: }
247:
248: rpt_did_reset = 1;
249: is_lastline = 0;
250: vsyncmintime = read_processor_time () + vsynctime;
251: write_log ("Resetting frame rate hack\n");
252: */
253: }
254:
255: /* Code taken from main.cpp */
256: void fixup_cpu (struct uae_prefs *p)
257: {
258: if (p->cpu_frequency == 1000000)
259: p->cpu_frequency = 0;
260: switch (p->cpu_model)
261: {
262: case 68000:
263: p->address_space_24 = 1;
264: if (p->cpu_compatible || p->cpu_cycle_exact)
265: p->fpu_model = 0;
266: break;
267: case 68010:
268: p->address_space_24 = 1;
269: if (p->cpu_compatible || p->cpu_cycle_exact)
270: p->fpu_model = 0;
271: break;
272: case 68020:
273: break;
274: case 68030:
275: p->address_space_24 = 0;
276: break;
277: case 68040:
278: p->address_space_24 = 0;
279: if (p->fpu_model)
280: p->fpu_model = 68040;
281: break;
282: case 68060:
283: p->address_space_24 = 0;
284: if (p->fpu_model)
285: p->fpu_model = 68060;
286: break;
287: }
288: if (p->cpu_model != 68040)
289: p->mmu_model = 0;
290: }
291:
292: /* Code taken from main.cpp*/
293: void uae_reset (int hardreset)
294: {
295: currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
296:
297: if (quit_program == 0) {
298: quit_program = -2;
299: if (hardreset)
300: quit_program = -3;
301: }
302:
303: }
304:
305: /* Code taken from debug.cpp*/
306: void mmu_do_hit (void)
307: {
308: int i;
309: uaecptr p;
310: uae_u32 pc;
311:
312: mmu_triggered = 0;
313: pc = m68k_getpc ();
314: p = mmu_regs + 18 * 4;
315: put_long (p, pc);
316: regs = mmu_backup_regs;
317: regs.intmask = 7;
318: regs.t0 = regs.t1 = 0;
319: if (!regs.s) {
320: regs.usp = m68k_areg (regs, 7);
321: if (currprefs.cpu_model >= 68020)
322: m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
323: else
324: m68k_areg (regs, 7) = regs.isp;
325: regs.s = 1;
326: }
327: MakeSR ();
328: m68k_setpc (mmu_callback);
329: fill_prefetch_slow ();
330:
331: if (currprefs.cpu_model > 68000) {
332: for (i = 0 ; i < 9; i++) {
333: m68k_areg (regs, 7) -= 4;
334: put_long (m68k_areg (regs, 7), 0);
335: }
336: m68k_areg (regs, 7) -= 4;
337: put_long (m68k_areg (regs, 7), mmu_fault_addr);
338: m68k_areg (regs, 7) -= 2;
339: put_word (m68k_areg (regs, 7), 0); /* WB1S */
340: m68k_areg (regs, 7) -= 2;
341: put_word (m68k_areg (regs, 7), 0); /* WB2S */
342: m68k_areg (regs, 7) -= 2;
343: put_word (m68k_areg (regs, 7), 0); /* WB3S */
344: m68k_areg (regs, 7) -= 2;
345: put_word (m68k_areg (regs, 7),
346: (mmu_fault_rw ? 0 : 0x100) | (mmu_fault_size << 5)); /* SSW */
347: m68k_areg (regs, 7) -= 4;
348: put_long (m68k_areg (regs, 7), mmu_fault_bank_addr);
349: m68k_areg (regs, 7) -= 2;
350: put_word (m68k_areg (regs, 7), 0x7002);
351: }
352: m68k_areg (regs, 7) -= 4;
353: put_long (m68k_areg (regs, 7), get_long (p - 4));
354: m68k_areg (regs, 7) -= 2;
355: put_word (m68k_areg (regs, 7), mmur.sr);
356: #ifdef JIT
357: set_special(SPCFLAG_END_COMPILE);
358: #endif
359: }
360:
361: /* Code taken from win32.cpp*/
362: void fpux_restore (int *v)
363: {
364: /*#ifndef _WIN64
365: if (v)
366: _controlfp (*v, _MCW_IC | _MCW_RC | _MCW_PC);
367: else
368: _controlfp (fpucontrol, _MCW_IC | _MCW_RC | _MCW_PC);
369: #endif
370: */
371: }
372:
373: /* Code taken from win32.cpp*/
374: frame_time_t read_processor_time (void)
375: {
376: #if 0
377: static int cnt;
378:
379: cnt++;
380: if (cnt > 1000000) {
381: write_log(L"**************\n");
382: cnt = 0;
383: }
384: #endif
385: if (userdtsc)
386: return read_processor_time_rdtsc ();
387: else
388: return read_processor_time_qpf ();
389: }
390:
391: /* Code taken from win32.cpp*/
392: frame_time_t read_processor_time_qpf (void)
393: {
394: /* Laurent : may be coded later
395: LARGE_INTEGER counter;
396: QueryPerformanceCounter (&counter);
397: if (qpcdivisor == 0)
398: return (frame_time_t)(counter.LowPart);
399: return (frame_time_t)(counter.QuadPart >> qpcdivisor);
400: */
401: }
402:
403: /* Code taken from win32.cpp*/
404: frame_time_t read_processor_time_rdtsc (void)
405: {
406: frame_time_t foo = 0;
407: #if defined(X86_MSVC_ASSEMBLY)
408: frame_time_t bar;
409: __asm
410: {
411: rdtsc
412: mov foo, eax
413: mov bar, edx
414: }
415: /* very high speed CPU's RDTSC might overflow without this.. */
416: foo >>= 6;
417: foo |= bar << 26;
418: #endif
419: return foo;
420: }
421:
422: /* Code taken from win32.cpp*/
423: void sleep_millis (int ms)
424: {
425: /* Laurent : may be coded later (DSL-Delay ?)
426: unsigned int TimerEvent;
427: int start;
428: int cnt;
429:
430: start = read_processor_time ();
431: EnterCriticalSection (&cs_time);
432: cnt = timehandlecounter++;
433: if (timehandlecounter >= MAX_TIMEHANDLES)
434: timehandlecounter = 0;
435: LeaveCriticalSection (&cs_time);
436: TimerEvent = timeSetEvent (ms, 0, (LPTIMECALLBACK)timehandle[cnt], 0, TIME_ONESHOT | TIME_CALLBACK_EVENT_SET);
437: WaitForSingleObject (timehandle[cnt], ms);
438: ResetEvent (timehandle[cnt]);
439: timeKillEvent (TimerEvent);
440: idletime += read_processor_time () - start;
441: */
442: }
443:
444:
445: /* Code just here to let newcpu.c link (original function is in inprec.cpp) */
446: int inprec_open(char *fname, int record)
447: {
448: return 0;
449: }
450:
451: int current_hpos (void)
452: {
453: return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
454: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.