|
|
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:
1.1.1.3 root 27: /* TODO: move custom.c stuff declarations to custom.h? */
28:
29: /* declated in newcpu.c */
1.1 root 30: extern struct regstruct mmu_backup_regs;
1.1.1.3 root 31: /* declared in events.h like do_cycles_ce() */
32: unsigned long int nextevent, is_lastline, currcycle;
33: /* declared in events.h, used in events_*.h */
34: struct ev eventtab[ev_max];
35:
36: uae_u16 dmacon;
37:
1.1 root 38: static uae_u32 mmu_struct, mmu_callback, mmu_regs;
39: static uae_u32 mmu_fault_bank_addr, mmu_fault_addr;
40: static int mmu_fault_size, mmu_fault_rw;
41: static int mmu_slots;
42: static struct regstruct mmur;
43: static int userdtsc = 0;
1.1.1.3 root 44: static int qpcdivisor = 0;
1.1 root 45:
46:
47: typedef struct _LARGE_INTEGER
48: {
49: union
50: {
51: struct
52: {
53: unsigned long LowPart;
54: long HighPart;
55: };
56: int64_t QuadPart;
57: };
58: } LARGE_INTEGER, *PLARGE_INTEGER;
59:
1.1.1.3 root 60: static uae_u8 cycle_line[256];
1.1 root 61:
62: void do_cycles_ce (long cycles)
63: {
1.1.1.3 root 64: static int extra_cycle = 0;
1.1 root 65:
66: cycles += extra_cycle;
1.1.1.2 root 67:
1.1 root 68: while (cycles >= CYCLE_UNIT) {
1.1.1.2 root 69: // int hpos = current_hpos () + 1;
70: // sync_copper (hpos);
71: // decide_line (hpos);
72: // decide_fetch_ce (hpos);
73: // if (bltstate != BLT_done)
74: // decide_blitter (hpos);
1.1 root 75: do_cycles (1 * CYCLE_UNIT);
76: cycles -= CYCLE_UNIT;
77: }
1.1.1.2 root 78:
1.1 root 79: extra_cycle = cycles;
80: }
81:
82: void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
83: {
84: int hpos;
85:
86: /*
87: hpos = dma_cycle ();
88: do_cycles_ce (CYCLE_UNIT);
89: */
90: #ifdef DEBUGGER
91: if (debug_dma) {
92: int reg = 0x1100;
93: if (mode < 0)
94: reg |= 4;
95: else if (mode > 0)
96: reg |= 2;
97: else
98: reg |= 1;
99: record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
100: checknasty (hpos, vpos);
101: }
102: #endif
103:
104: if (mode < 0)
105: put_long (addr, v);
106: else if (mode > 0)
107: put_word (addr, v);
108: else if (mode == 0)
109: put_byte (addr, v);
110:
111: regs.ce020memcycles -= CYCLE_UNIT;
112: }
113:
114: uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
115: {
116: uae_u32 v = 0;
117: int hpos;
118: struct dma_rec *dr;
119:
120: /*
121: hpos = dma_cycle ();
122: do_cycles_ce (CYCLE_UNIT);
123: */
124:
125: #ifdef DEBUGGER
126: if (debug_dma) {
127: int reg = 0x1000;
128: if (mode < 0)
129: reg |= 4;
130: else if (mode > 0)
131: reg |= 2;
132: else
133: reg |= 1;
134: dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
135: checknasty (hpos, vpos);
136: }
137: #endif
138: if (mode < 0)
139: v = get_long (addr);
140: else if (mode > 0)
141: v = get_word (addr);
142: else if (mode == 0)
143: v = get_byte (addr);
144:
145: #ifdef DEBUGGER
146: if (debug_dma)
147: dr->dat = v;
148: #endif
149:
150: regs.ce020memcycles -= CYCLE_UNIT;
151: return v;
152: }
153:
154: uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
155: {
156: uae_u32 v = 0;
157: int hpos;
158: struct dma_rec *dr;
159:
160: /*
161: hpos = dma_cycle ();
162: do_cycles_ce (CYCLE_UNIT);
163: */
164:
165: #ifdef DEBUGGER
166: if (debug_dma) {
167: int reg = 0x1000;
168: if (mode < 0)
169: reg |= 4;
170: else if (mode > 0)
171: reg |= 2;
172: else
173: reg |= 1;
174: dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
175: checknasty (hpos, vpos);
176: }
177: #endif
178: if (mode < 0)
179: v = get_long (addr);
180: else if (mode > 0)
181: v = get_word (addr);
182: else if (mode == 0)
183: v = get_byte (addr);
184:
185: #ifdef DEBUGGER
186: if (debug_dma)
187: dr->dat = v;
188: #endif
189:
190: do_cycles_ce (CYCLE_UNIT);
191: return v;
192: }
193:
194: void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
195: {
196: int hpos;
197:
198: /*
199: hpos = dma_cycle ();
200: do_cycles_ce (CYCLE_UNIT);
201: */
202:
203: #ifdef DEBUGGER
204: if (debug_dma) {
205: int reg = 0x1100;
206: if (mode < 0)
207: reg |= 4;
208: else if (mode > 0)
209: reg |= 2;
210: else
211: reg |= 1;
212: record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
213: checknasty (hpos, vpos);
214: }
215: #endif
216:
217: if (mode < 0)
218: put_long (addr, v);
219: else if (mode > 0)
220: put_word (addr, v);
221: else if (mode == 0)
222: put_byte (addr, v);
223: do_cycles_ce (CYCLE_UNIT);
224:
225: }
226:
227: int is_cycle_ce (void)
228: {
229: int hpos = current_hpos ();
1.1.1.3 root 230: /* TODO: nothing sets cycle_line contents! */
1.1 root 231: return cycle_line[hpos];
232: }
233:
234: void reset_frame_rate_hack (void)
235: {
236: /* Laurent : should it be adapted or removed ?
237: if (currprefs.m68k_speed != -1)
238: return;
239:
240: if (! rpt_available) {
241: currprefs.m68k_speed = 0;
242: return;
243: }
244:
245: rpt_did_reset = 1;
246: is_lastline = 0;
247: write_log ("Resetting frame rate hack\n");
248: */
249: }
250:
251: /* Code taken from main.cpp */
252: void fixup_cpu (struct uae_prefs *p)
253: {
254: if (p->cpu_frequency == 1000000)
255: p->cpu_frequency = 0;
256: switch (p->cpu_model)
257: {
258: case 68000:
259: p->address_space_24 = 1;
260: if (p->cpu_compatible || p->cpu_cycle_exact)
261: p->fpu_model = 0;
262: break;
263: case 68010:
264: p->address_space_24 = 1;
265: if (p->cpu_compatible || p->cpu_cycle_exact)
266: p->fpu_model = 0;
267: break;
268: case 68020:
269: break;
270: case 68030:
271: p->address_space_24 = 0;
272: break;
273: case 68040:
274: p->address_space_24 = 0;
275: if (p->fpu_model)
276: p->fpu_model = 68040;
277: break;
278: case 68060:
279: p->address_space_24 = 0;
280: if (p->fpu_model)
281: p->fpu_model = 68060;
282: break;
283: }
1.1.1.4 ! root 284: if (p->cpu_model < 68020)
1.1 root 285: p->mmu_model = 0;
286: }
287:
288: /* Code taken from main.cpp*/
289: void uae_reset (int hardreset)
290: {
291: currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
292:
293: if (quit_program == 0) {
294: quit_program = -2;
295: if (hardreset)
296: quit_program = -3;
297: }
298:
299: }
300:
301: /* Code taken from debug.cpp*/
302: void mmu_do_hit (void)
303: {
304: int i;
305: uaecptr p;
306: uae_u32 pc;
307:
308: mmu_triggered = 0;
309: pc = m68k_getpc ();
310: p = mmu_regs + 18 * 4;
311: put_long (p, pc);
312: regs = mmu_backup_regs;
313: regs.intmask = 7;
314: regs.t0 = regs.t1 = 0;
315: if (!regs.s) {
316: regs.usp = m68k_areg (regs, 7);
317: if (currprefs.cpu_model >= 68020)
318: m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
319: else
320: m68k_areg (regs, 7) = regs.isp;
321: regs.s = 1;
322: }
323: MakeSR ();
324: m68k_setpc (mmu_callback);
325: fill_prefetch_slow ();
326:
327: if (currprefs.cpu_model > 68000) {
328: for (i = 0 ; i < 9; i++) {
329: m68k_areg (regs, 7) -= 4;
330: put_long (m68k_areg (regs, 7), 0);
331: }
332: m68k_areg (regs, 7) -= 4;
333: put_long (m68k_areg (regs, 7), mmu_fault_addr);
334: m68k_areg (regs, 7) -= 2;
335: put_word (m68k_areg (regs, 7), 0); /* WB1S */
336: m68k_areg (regs, 7) -= 2;
337: put_word (m68k_areg (regs, 7), 0); /* WB2S */
338: m68k_areg (regs, 7) -= 2;
339: put_word (m68k_areg (regs, 7), 0); /* WB3S */
340: m68k_areg (regs, 7) -= 2;
341: put_word (m68k_areg (regs, 7),
342: (mmu_fault_rw ? 0 : 0x100) | (mmu_fault_size << 5)); /* SSW */
343: m68k_areg (regs, 7) -= 4;
344: put_long (m68k_areg (regs, 7), mmu_fault_bank_addr);
345: m68k_areg (regs, 7) -= 2;
346: put_word (m68k_areg (regs, 7), 0x7002);
347: }
348: m68k_areg (regs, 7) -= 4;
349: put_long (m68k_areg (regs, 7), get_long (p - 4));
350: m68k_areg (regs, 7) -= 2;
351: put_word (m68k_areg (regs, 7), mmur.sr);
352: #ifdef JIT
353: set_special(SPCFLAG_END_COMPILE);
354: #endif
355: }
356:
357: /* Code taken from win32.cpp*/
358: void fpux_restore (int *v)
359: {
360: /*#ifndef _WIN64
361: if (v)
362: _controlfp (*v, _MCW_IC | _MCW_RC | _MCW_PC);
363: else
364: _controlfp (fpucontrol, _MCW_IC | _MCW_RC | _MCW_PC);
365: #endif
366: */
367: }
368:
369: /* Code taken from win32.cpp*/
370: void sleep_millis (int ms)
371: {
1.1.1.3 root 372: /* Laurent : may be coded later (DSL-Delay ?) */
1.1 root 373: }
374:
375:
376: /* Code just here to let newcpu.c link (original function is in inprec.cpp) */
377: int inprec_open(char *fname, int record)
378: {
379: return 0;
380: }
381:
382: int current_hpos (void)
383: {
384: return (get_cycles () - eventtab[ev_hsync].oldcycles) / CYCLE_UNIT;
385: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.