|
|
1.1 root 1: /*
2: Hatari
3:
4: This is where we intercept read/writes to/from the hardware. The ST's memory is nicely split into
5: four main parts - the bottom area of RAM is for user programs. This is followed by a large area which
6: causes a Bus Error. After this is the ROM addresses for TOS and finally an area for hardware mapping.
7: To gain speed any address in the user area can simply read/write, but anything above this range needs
8: to be checked for validity and sent to the various handlers.
9: A big problem for ST emulation is the use of the hardware registers. These often consist of an 'odd' byte
10: in memory and is usually addressed as a single byte. A number of applications, however, write to the address
11: using a word or even long word - which may span over two hardware registers! Rather than check for any and
12: all combinations we use a tables for byte/word/long and for read/write. These are lists of functions which
13: access the ST Ram area any bytes which maybe affected by the operation. Eg, a long write to a PSG register
14: (which access two registers) will write the long into ST Ram and then call the two handlers which read off
15: the bytes for each register. This means that any access to any hardware register in such a way will work
16: correctly - it certainly fixes a lot of bugs and means writing just one routine for each hardware register
17: we mean to intercept! Phew!
18: Note the 'mirror'(or shadow) registers of the PSG - this is used by most games. We also have a means of
19: testing for addressing into 'no-mans-land' which are parts of the hardware map which are not valid on a
20: standard STfm.
21: */
22:
23: #include "main.h"
24: #include "debug.h"
25: #include "decode.h"
26: #include "dialog.h"
27: #include "fdc.h"
28: #include "int.h"
29: #include "intercept.h"
30: #include "ikbd.h"
31: #include "m68000.h"
32: #include "memAlloc.h"
33: #include "mfp.h"
34: #include "psg.h"
35: #include "screen.h"
36: #include "spec512.h"
37: #include "vdi.h"
38: #include "video.h"
39: #include "uae-cpu/sysdeps.h"
40:
41: //#define CHECK_FOR_NO_MANS_LAND /* Check for read/write from unknown hardware addresses */
42:
43: //-----------------------------------------------------------------------
44: // List of functions to handle read/write hardware intercepts. MUST match INTERCEPT_xxx enum
45: INTERCEPT_ACCESS_FUNC InterceptAccessFuncs[INTERCEPT_COUNT] = {
46: 0x0,SIZE_BYTE,NULL,NULL,
47: 0xff8205,SIZE_BYTE,Intercept_VideoHigh_ReadByte,Intercept_VideoHigh_WriteByte, // INTERCEPT_VIDEOHIGH
48: 0xff8207,SIZE_BYTE,Intercept_VideoMed_ReadByte,Intercept_VideoMed_WriteByte, // INTERCEPT_VIDEOMED
49: 0xff8209,SIZE_BYTE,Intercept_VideoLow_ReadByte,Intercept_VideoLow_WriteByte, // INTERCEPT_VIDEOLOW
50: 0xff820a,SIZE_BYTE,Intercept_VideoSync_ReadByte,Intercept_VideoSync_WriteByte, // INTERCEPT_VIDEOSYNC
51: 0xff820d,SIZE_BYTE,Intercept_VideoBaseLow_ReadByte,Intercept_VideoBaseLow_WriteByte, // INTERCEPT_VIDEOBASELOW
52: 0xff820f,SIZE_BYTE,Intercept_LineWidth_ReadByte,Intercept_LineWidth_WriteByte, // INTERCEPT_LINEWIDTH
53: 0xff8240,SIZE_WORD,Intercept_Colour0_ReadWord,Intercept_Colour0_WriteWord, // INTERCEPT_COLOUR0
54: 0xff8242,SIZE_WORD,Intercept_Colour1_ReadWord,Intercept_Colour1_WriteWord, // INTERCEPT_COLOUR1
55: 0xff8244,SIZE_WORD,Intercept_Colour2_ReadWord,Intercept_Colour2_WriteWord, // INTERCEPT_COLOUR2
56: 0xff8246,SIZE_WORD,Intercept_Colour3_ReadWord,Intercept_Colour3_WriteWord, // INTERCEPT_COLOUR3
57: 0xff8248,SIZE_WORD,Intercept_Colour4_ReadWord,Intercept_Colour4_WriteWord, // INTERCEPT_COLOUR4
58: 0xff824a,SIZE_WORD,Intercept_Colour5_ReadWord,Intercept_Colour5_WriteWord, // INTERCEPT_COLOUR5
59: 0xff824c,SIZE_WORD,Intercept_Colour6_ReadWord,Intercept_Colour6_WriteWord, // INTERCEPT_COLOUR6
60: 0xff824e,SIZE_WORD,Intercept_Colour7_ReadWord,Intercept_Colour7_WriteWord, // INTERCEPT_COLOUR7
61: 0xff8250,SIZE_WORD,Intercept_Colour8_ReadWord,Intercept_Colour8_WriteWord, // INTERCEPT_COLOUR8
62: 0xff8252,SIZE_WORD,Intercept_Colour9_ReadWord,Intercept_Colour9_WriteWord, // INTERCEPT_COLOUR9
63: 0xff8254,SIZE_WORD,Intercept_Colour10_ReadWord,Intercept_Colour10_WriteWord, // INTERCEPT_COLOUR10
64: 0xff8256,SIZE_WORD,Intercept_Colour11_ReadWord,Intercept_Colour11_WriteWord, // INTERCEPT_COLOUR11
65: 0xff8258,SIZE_WORD,Intercept_Colour12_ReadWord,Intercept_Colour12_WriteWord, // INTERCEPT_COLOUR12
66: 0xff825a,SIZE_WORD,Intercept_Colour13_ReadWord,Intercept_Colour13_WriteWord, // INTERCEPT_COLOUR13
67: 0xff825c,SIZE_WORD,Intercept_Colour14_ReadWord,Intercept_Colour14_WriteWord, // INTERCEPT_COLOUR14
68: 0xff825e,SIZE_WORD,Intercept_Colour15_ReadWord,Intercept_Colour15_WriteWord, // INTERCEPT_COLOUR15
69: 0xff8260,SIZE_BYTE,Intercept_ShifterMode_ReadByte,Intercept_ShifterMode_WriteByte, // INTERCEPT_SHIFTERMODE
70: 0xff8604,SIZE_WORD,Intercept_DiskControl_ReadWord,Intercept_DiskControl_WriteWord, // INTERCEPT_DISKCONTROL
71: 0xff8606,SIZE_WORD,Intercept_DmaStatus_ReadWord,Intercept_DmaStatus_WriteWord, // INTERCEPT_DMASTATUS
72: 0xff8800,SIZE_BYTE,Intercept_PSGRegister_ReadByte,Intercept_PSGRegister_WriteByte, // INTERCEPT_PSG_REGISTER
73: 0xff8802,SIZE_BYTE,Intercept_PSGData_ReadByte,Intercept_PSGData_WriteByte, // INTERCEPT_PSG_DATA
74: 0xff8922,SIZE_WORD,Intercept_MicrowireData_ReadWord,Intercept_MicrowireData_WriteWord, // INTERCEPT_MICROWIREDATA
75: 0xfffa01,SIZE_BYTE,Intercept_Monitor_ReadByte,Intercept_Monitor_WriteByte, // INTERCEPT_MONITOR
76: 0xfffa03,SIZE_BYTE,Intercept_ActiveEdge_ReadByte,Intercept_ActiveEdge_WriteByte, // INTERCEPT_ACTIVE_EDGE
77: 0xfffa05,SIZE_BYTE,Intercept_DataDirection_ReadByte,Intercept_DataDirection_WriteByte, // INTERCEPT_DATA_DIRECTION
78: 0xfffa07,SIZE_BYTE,Intercept_EnableA_ReadByte,Intercept_EnableA_WriteByte, // INTERCEPT_ENABLE_A
79: 0xfffa09,SIZE_BYTE,Intercept_EnableB_ReadByte,Intercept_EnableB_WriteByte, // INTERCEPT_ENABLE_B
80: 0xfffa0b,SIZE_BYTE,Intercept_PendingA_ReadByte,Intercept_PendingA_WriteByte, // INTERCEPT_PENDING_A
81: 0xfffa0d,SIZE_BYTE,Intercept_PendingB_ReadByte,Intercept_PendingB_WriteByte, // INTERCEPT_PENDING_B
82: 0xfffa0f,SIZE_BYTE,Intercept_InServiceA_ReadByte,Intercept_InServiceA_WriteByte, // INTERCEPT_INSERVICE_A
83: 0xfffa11,SIZE_BYTE,Intercept_InServiceB_ReadByte,Intercept_InServiceB_WriteByte, // INTERCEPT_INSERVICE_B
84: 0xfffa13,SIZE_BYTE,Intercept_MaskA_ReadByte,Intercept_MaskA_WriteByte, // INTERCEPT_MASK_A
85: 0xfffa15,SIZE_BYTE,Intercept_MaskB_ReadByte,Intercept_MaskB_WriteByte, // INTERCEPT_MASK_B
86: 0xfffa17,SIZE_BYTE,Intercept_VectorReg_ReadByte,Intercept_VectorReg_WriteByte, // INTERCEPT_VECTOR_REG
87: 0xfffa19,SIZE_BYTE,Intercept_TimerACtrl_ReadByte,Intercept_TimerACtrl_WriteByte, // INTERCEPT_TIMERA_CTRL
88: 0xfffa1b,SIZE_BYTE,Intercept_TimerBCtrl_ReadByte,Intercept_TimerBCtrl_WriteByte, // INTERCEPT_TIMERB_CTRL
89: 0xfffa1d,SIZE_BYTE,Intercept_TimerCDCtrl_ReadByte,Intercept_TimerCDCtrl_WriteByte, // INTERCEPT_TIMERCD_CTRL
90: 0xfffa1f,SIZE_BYTE,Intercept_TimerAData_ReadByte,Intercept_TimerAData_WriteByte, // INTERCEPT_TIMERA_DATA
91: 0xfffa21,SIZE_BYTE,Intercept_TimerBData_ReadByte,Intercept_TimerBData_WriteByte, // INTERCEPT_TIMERB_DATA
92: 0xfffa23,SIZE_BYTE,Intercept_TimerCData_ReadByte,Intercept_TimerCData_WriteByte, // INTERCEPT_TIMERC_DATA
93: 0xfffa25,SIZE_BYTE,Intercept_TimerDData_ReadByte,Intercept_TimerDData_WriteByte, // INTERCEPT_TIMERD_DATA
94: 0xfffc00,SIZE_BYTE,Intercept_KeyboardControl_ReadByte,Intercept_KeyboardControl_WriteByte, // INTERCEPT_KEYBOARDCONTROL
95: 0xfffc02,SIZE_BYTE,Intercept_KeyboardData_ReadByte,Intercept_KeyboardData_WriteByte, // INTERCEPT_KEYBOARDDATA
96: 0xfffc04,SIZE_BYTE,Intercept_MidiControl_ReadByte,Intercept_MidiControl_WriteByte, // INTERCEPT_MIDICONTROL
97: 0xfffc06,SIZE_BYTE,Intercept_MidiData_ReadByte,Intercept_MidiData_WriteByte, // INTERCEPT_MIDIDATA
98: };
99:
100: unsigned long *pInterceptWorkspace; // Memory used to store all read/write NULL terminated function call tables
101: unsigned long *pCurrentInterceptWorkspace; // Index into above
102: unsigned long *pInterceptReadByteTable[0x8000],*pInterceptReadWordTable[0x8000],*pInterceptReadLongTable[0x8000];
103: unsigned long *pInterceptWriteByteTable[0x8000],*pInterceptWriteWordTable[0x8000],*pInterceptWriteLongTable[0x8000];
104:
105: //-----------------------------------------------------------------------
106: /*
107: Create 'intercept' tables for hardware address access
108: */
109: void Intercept_Init(void)
110: {
111: // Allocate memory for intercept tables
112: pCurrentInterceptWorkspace = pInterceptWorkspace = (unsigned long *)Memory_Alloc(INTERCEPT_WORKSPACE_SIZE);
113:
114: // Clear intercept tables(NULL signifies no entries for that location)
115: Memory_Clear(pInterceptReadByteTable,sizeof(unsigned long *)*0x8000);
116: Memory_Clear(pInterceptReadWordTable,sizeof(unsigned long *)*0x8000);
117: Memory_Clear(pInterceptReadLongTable,sizeof(unsigned long *)*0x8000);
118: Memory_Clear(pInterceptWriteByteTable,sizeof(unsigned long *)*0x8000);
119: Memory_Clear(pInterceptWriteWordTable,sizeof(unsigned long *)*0x8000);
120: Memory_Clear(pInterceptWriteLongTable,sizeof(unsigned long *)*0x8000);
121:
122: // Create 'read' tables
123: Intercept_CreateTable(pInterceptReadByteTable,SIZE_BYTE,0);
124: Intercept_CreateTable(pInterceptReadWordTable,SIZE_WORD,0);
125: Intercept_CreateTable(pInterceptReadLongTable,SIZE_LONG,0);
126: // And 'write' tables
127: Intercept_CreateTable(pInterceptWriteByteTable,SIZE_BYTE,1);
128: Intercept_CreateTable(pInterceptWriteWordTable,SIZE_WORD,1);
129: Intercept_CreateTable(pInterceptWriteLongTable,SIZE_LONG,1);
130:
131: #ifdef CHECK_FOR_NO_MANS_LAND
132: // This causes a error when an application tries to access illegal hardware registers(maybe mirror'd)
133: Intercept_ModifyTablesForNoMansLand();
134: #endif //CHECK_FOR_NO_MANS_LAND
135:
136: // And modify for bus-error in hardware space
137: Intercept_ModifyTablesForBusErrors();
138: }
139:
140: //-----------------------------------------------------------------------
141: /*
142: Free 'intercept' hardware lists
143: */
144: void Intercept_UnInit(void)
145: {
146: Memory_Free(pInterceptWorkspace);
147: }
148:
149: //-----------------------------------------------------------------------
150: /*
151: Set Intercept hardware address table index's
152:
153: Each 'intercept table' is a list of 0x8000 pointers to a list of functions to call when that
154: location in the ST's memory is accessed. Each entry is terminated by a NULL
155: Eg, if we write a long word to address '0xff8800', we
156: need to call the functions 'InterceptPSGRegister_WriteByte' and then 'InterceptPSGData_WriteByte'.
157: */
158:
159: void Intercept_CreateTable(unsigned long *pInterceptTable[],int Span,int ReadWrite)
160: {
161: unsigned int Address, LowAddress, HiAddress;
162: int i;
163:
164: // Scan each hardware address
165: for(Address=0xff8000; Address<=0xffffff; Address++) {
166: // Does this hardware location/span appear in our list of possible intercepted functions?
167: for (i=0; i<INTERCEPT_COUNT; i++) {
168: LowAddress = InterceptAccessFuncs[i].Address;
169: HiAddress = InterceptAccessFuncs[i].Address+InterceptAccessFuncs[i].SpanInBytes;
170:
171: if ( (Address+Span) <= LowAddress )
172: continue;
173: if ( Address >= HiAddress )
174: continue;
175:
176: // This location needs to be intercepted, so add entry to list
177: if (pInterceptTable[Address-0xff8000]==NULL)
178: pInterceptTable[Address-0xff8000] = pCurrentInterceptWorkspace;
179: *pCurrentInterceptWorkspace++ = (unsigned long)InterceptAccessFuncs[i].ReadWriteFunc[ReadWrite];
180: }
181: // Terminate table?
182: if (pInterceptTable[Address-0xff8000])
183: *pCurrentInterceptWorkspace++ = 0L;
184: }
185: }
186:
187: //-----------------------------------------------------------------------
188: /*
189: Check list of handlers to see if address needs to be intercepted and call routines
190: 'ecx' is pointer to function list (or NULL)
191: */
192: void Intercept_ScanHandlers(unsigned long *the_func)
193: {
194: if( the_func )
195: while( *the_func ) /* Do we have any routines to run for this address? */
196: {
197: CALL_VAR(*the_func); /* Call routine */
198: the_func+=1;
199: }
200: }
201:
202: //-----------------------------------------------------------------------
203: /*
204: Check if need to change our address 'ebp' as maybe a mirror register
205: Currently we only have a PSG mirror area
206: */
207: unsigned long Intercept_CheckMirrorAddresses(unsigned long addr)
208: {
209: if( addr>=0xff8800 && addr<=0xff8900 ) /* Is a PSG mirror registers? */
210: addr = ( addr & 3) + 0xff8800; /* Bring into 0xff8800-0xff8804 range */
211: return addr;
212: }
213:
214: //-----------------------------------------------------------------------
215: uae_u32 Intercept_ReadByte(uaecptr addr)
216: {
217: //fprintf(stderr,"byte hardware read access: $%lx\n", addr);
218: addr &= 0x00ffffff; /* Use a 24 bit address */
219: if(addr >= 0x00ff8000) /* Is hardware address? */
220: {
221: BusAddressLocation=addr; /* Store for exception frame, just in case */
222: addr = Intercept_CheckMirrorAddresses(addr);
223: Intercept_ScanHandlers( pInterceptReadByteTable[ addr-0x00ff8000 ] );
224: }
225: else
226: {
227: if(addr < STRamEnd_BusErr) return 0; /* Blank area between RAM and bus error */
228: if(addr < BUS_ERROR_ADDR) { M68000_BusError(addr); return 0; } /* Is a bus error? (invalid memory addressing) */
229: }
230: return( STRam[addr] );
231: }
232:
233:
234: uae_u32 Intercept_ReadWord(uaecptr addr)
235: {
236: //fprintf(stderr,"Word hardware read access: $%lx\n", addr);
237: addr &= 0x00ffffff; /* Use a 24 bit address */
238: if( addr&1 )
239: { M68000_AddressError(addr); return 0; } /* Is address error? (not correct alignment) */
240: if(addr >= 0x00ff8000) /* Is hardware address? */
241: {
242: BusAddressLocation=addr; /* Store for exception frame, just in case */
243: addr = Intercept_CheckMirrorAddresses(addr);
244: Intercept_ScanHandlers( pInterceptReadWordTable[ addr-0x00ff8000 ] );
245: }
246: else
247: {
248: if(addr < STRamEnd_BusErr) return 0; /* Blank area between RAM and bus error */
249: if(addr < BUS_ERROR_ADDR) { M68000_BusError(addr); return 0; } /* Is a bus error? (invalid memory addressing) */
250: }
251: return STMemory_ReadWord( addr );
252: }
253:
254:
255: uae_u32 Intercept_ReadLong(uaecptr addr)
256: {
257: //fprintf(stderr,"Long hardware read access: $%lx\n", addr);
258: addr &= 0x00ffffff; /* Use a 24 bit address */
259: if( addr&1 )
260: { M68000_AddressError(addr); return 0; } /* Is address error? (not correct alignment) */
261: if(addr >= 0x00ff8000) /* Is hardware address? */
262: {
263: BusAddressLocation=addr; /* Store for exception frame, just in case */
264: addr = Intercept_CheckMirrorAddresses(addr);
265: Intercept_ScanHandlers( pInterceptReadLongTable[ addr-0x00ff8000 ] );
266: }
267: else
268: {
269: if(addr < STRamEnd_BusErr) return 0; /* Blank area between RAM and bus error */
270: if(addr < BUS_ERROR_ADDR) { M68000_BusError(addr); return 0; } /* Is a bus error? (invalid memory addressing) */
271: }
272: return STMemory_ReadLong( addr );
273: }
274:
275: //-----------------------------------------------------------------------
276: void Intercept_WriteByte(uaecptr addr, uae_u32 val)
277: {
278: //fprintf(stderr,"Byte hardware write access: $%lx\n", addr);
279: addr &= 0x00ffffff; /* Use a 24 bit address */
280: if( addr>=0x00ff8000 ) /* Is hardware address? */
281: {
282: BusAddressLocation=addr; /* Store for exception frame, just in case */
283: addr = Intercept_CheckMirrorAddresses(addr);
284: STRam[addr]=val;
285: Intercept_ScanHandlers( pInterceptWriteByteTable[ addr-0x00ff8000 ] );
286: }
287: else
288: {
289: if( addr < STRamEnd_BusErr ) return; /* Allow writes to no-mans-land(just return) */
290: if( addr < BUS_ERROR_ADDR ) { M68000_BusError(addr); return; } /* Is a bus error? (invalid memory addressing) */
291: STRam[addr]=val;
292: }
293: }
294:
295: void Intercept_WriteWord(uaecptr addr, uae_u32 val)
296: {
297: //fprintf(stderr,"Word hardware write access: $%lx\n", addr);
298: addr &= 0x00ffffff; /* Use a 24 bit address */
299: if( addr&1 )
300: { M68000_AddressError(addr); return; } /* Is address error? (not correct alignment) */
301: if( addr>=0x00ff8000 ) /* Is hardware address? */
302: {
303: BusAddressLocation=addr; /* Store for exception frame, just in case */
304: addr = Intercept_CheckMirrorAddresses(addr);
305: STMemory_WriteWord( addr, val);
306: Intercept_ScanHandlers( pInterceptWriteWordTable[ addr-0x00ff8000 ] );
307: }
308: else
309: {
310: if( addr < STRamEnd_BusErr ) return; /* Allow writes to no-mans-land(just return) */
311: if( addr < BUS_ERROR_ADDR ) { M68000_BusError(addr); return; } /* Is a bus error? (invalid memory addressing) */
312: STMemory_WriteWord( addr, val);
313: }
314: }
315:
316: void Intercept_WriteLong(uaecptr addr, uae_u32 val)
317: {
318: //fprintf(stderr,"Long hardware write access: $%lx\n", addr);
319: addr &= 0x00ffffff; /* Use a 24 bit address */
320: if( addr&1 )
321: { M68000_AddressError(addr); return; } /* Is address error? (not correct alignment) */
322: if( addr>=0x00ff8000 ) /* Is hardware address? */
323: {
324: BusAddressLocation=addr; /* Store for exception frame, just in case */
325: addr = Intercept_CheckMirrorAddresses(addr);
326: STMemory_WriteLong( addr, val);
327: Intercept_ScanHandlers( pInterceptWriteLongTable[ addr-0x00ff8000 ] );
328: }
329: else
330: {
331: if( addr < STRamEnd_BusErr ) return; /* Allow writes to no-mans-land(just return) */
332: if( addr < BUS_ERROR_ADDR ) { M68000_BusError(addr); return; } /* Is a bus error? (invalid memory addressing) */
333: STMemory_WriteLong( addr, val);
334: }
335: }
336:
337:
338: //-----------------------------------------------------------------------
339: // Read from Hardware(0x00ff8000 to 0xffffff)
340:
341: // INTERCEPT_VIDEOHIGH(0xff8205 byte)
342: void Intercept_VideoHigh_ReadByte(void)
343: {
344: STRam[0xff8205] = Video_ReadAddress() >> 16; /* Get video address high byte */
345: }
346:
347: // INTERCEPT_VIDEOMED(0xff8207 byte)
348: void Intercept_VideoMed_ReadByte(void)
349: {
350: STRam[0xff8207] = Video_ReadAddress() >> 8; /* Get video address med byte */
351: }
352:
353: // INTERCEPT_VIDEOLOW(0xff8209 byte)
354: void Intercept_VideoLow_ReadByte(void)
355: {
356: STRam[0xff8209] = Video_ReadAddress(); /* Get video address med byte */
357: }
358:
359: // INTERCEPT_VIDEOSYNC(0xff820a byte)
360: void Intercept_VideoSync_ReadByte(void)
361: {
362: /* Nothing... */
363: }
364:
365: // INTERCEPT_VIDEOBASELOW(0xff820d byte)
366: void Intercept_VideoBaseLow_ReadByte(void)
367: {
368: STRam[0xff820d] = 0; /* ST can only store screen address to 256 bytes(ie no lower byte) */
369: }
370:
371: // INTERCEPT_LINEWIDTH(0xff820f byte)
372: void Intercept_LineWidth_ReadByte(void)
373: {
374: STRam[0xff820f]=0; /* On ST this is always 0 */
375: }
376:
377: // INTERCEPT_COLOUR0(0xff8240 word)
378: void Intercept_Colour0_ReadWord(void)
379: {
380: // Nothing...
381: }
382:
383: // INTERCEPT_COLOUR1(0xff8242 word)
384: void Intercept_Colour1_ReadWord(void)
385: {
386: // Nothing...
387: }
388:
389: // INTERCEPT_COLOUR2(0xff8244 word)
390: void Intercept_Colour2_ReadWord(void)
391: {
392: // Nothing...
393: }
394:
395: // INTERCEPT_COLOUR3(0xff8246 word)
396: void Intercept_Colour3_ReadWord(void)
397: {
398: // Nothing...
399: }
400:
401: // INTERCEPT_COLOUR4(0xff8248 word)
402: void Intercept_Colour4_ReadWord(void)
403: {
404: // Nothing...
405: }
406:
407: // INTERCEPT_COLOUR5(0xff824a word)
408: void Intercept_Colour5_ReadWord(void)
409: {
410: // Nothing...
411: }
412:
413: // INTERCEPT_COLOUR6(0xff824c word)
414: void Intercept_Colour6_ReadWord(void)
415: {
416: // Nothing...
417: }
418:
419: // INTERCEPT_COLOUR7(0xff824e word)
420: void Intercept_Colour7_ReadWord(void)
421: {
422: // Nothing...
423: }
424:
425: // INTERCEPT_COLOUR8(0xff8250 word)
426: void Intercept_Colour8_ReadWord(void)
427: {
428: // Nothing...
429: }
430:
431: // INTERCEPT_COLOUR9(0xff8252 word)
432: void Intercept_Colour9_ReadWord(void)
433: {
434: // Nothing...
435: }
436:
437: // INTERCEPT_COLOUR10(0xff8254 word)
438: void Intercept_Colour10_ReadWord(void)
439: {
440: // Nothing...
441: }
442:
443: // INTERCEPT_COLOUR11(0xff8256 word)
444: void Intercept_Colour11_ReadWord(void)
445: {
446: // Nothing...
447: }
448:
449: // INTERCEPT_COLOUR12(0xff8258 word)
450: void Intercept_Colour12_ReadWord(void)
451: {
452: // Nothing...
453: }
454:
455: // INTERCEPT_COLOUR13(0xff825a word)
456: void Intercept_Colour13_ReadWord(void)
457: {
458: // Nothing...
459: }
460:
461: // INTERCEPT_COLOUR14(0xff825c word)
462: void Intercept_Colour14_ReadWord(void)
463: {
464: // Nothing...
465: }
466:
467: // INTERCEPT_COLOUR15(0xff825e word)
468: void Intercept_Colour15_ReadWord(void)
469: {
470: // Nothing...
471: }
472:
473: // INTERCEPT_SHIFTERMODE(0xff8260 byte)
474: void Intercept_ShifterMode_ReadByte(void)
475: {
476: if(bUseHighRes)
477: STRam[0xff8260]=2; /* If mono monitor, force to high resolution */
478: else
479: STRam[0xff8260]=VideoShifterByte; /* Read shifter register */
480: }
481:
482: // INTERCEPT_DISKCONTROL(0xff8604 word)
483: void Intercept_DiskControl_ReadWord(void)
484: {
485: STMemory_WriteWord( 0xff8604, FDC_ReadDiscControllerStatus() );
486: }
487:
488: // INTERCEPT_DMASTATUS(0xff8606 word)
489: void Intercept_DmaStatus_ReadWord(void)
490: {
491: STMemory_WriteWord( 0xff8606, FDC_ReadDMAStatus() );
492: }
493:
494: // INTERCEPT_PSG_REGISTER(0xff8800 byte)
495: void Intercept_PSGRegister_ReadByte(void)
496: {
497: STRam[0xff8800] = PSG_ReadSelectRegister();
498: }
499:
500: // INTERCEPT_PSG_DATA(0xff8802 byte)
501: void Intercept_PSGData_ReadByte(void)
502: {
503: STRam[0xff8802] = PSG_ReadDataRegister();
504: }
505:
506: // INTERCEPT_MICROWIREDATA(0xff8922 word)
507: void Intercept_MicrowireData_ReadWord(void)
508: {
509: STRam[0xff8922]=0;
510: }
511:
512: // INTERCEPT_MONITOR(0xfffa01 byte)
513: void Intercept_Monitor_ReadByte(void)
514: {
515: unsigned short v;
516: v=MFP_GPIP & 0x7f; /* Lower 7-bits are GPIP(Top bit is monitor type) */
517: if( !bUseHighRes ) v|=0x80; /* Colour monitor */
518: STRam[0xfffa01]=v;
519: }
520:
521: // INTERCEPT_ACTIVE_EDGE(0xfffa03 byte)
522: void Intercept_ActiveEdge_ReadByte(void)
523: {
524: STRam[0xfffa03] = MFP_AER;
525: }
526:
527: // INTERCEPT_DATA_DIRECTION(0xfffa05 byte)
528: void Intercept_DataDirection_ReadByte(void)
529: {
530: STRam[0xfffa05] = MFP_DDR;
531: }
532:
533: // INTERCEPT_ENABLE_A(0xfffa07 byte)
534: void Intercept_EnableA_ReadByte(void)
535: {
536: STRam[0xfffa07] = MFP_IERA;
537: }
538:
539: // INTERCEPT_ENABLE_B(0xfffa09 byte)
540: void Intercept_EnableB_ReadByte(void)
541: {
542: STRam[0xfffa09] = MFP_IERB;
543: }
544:
545: // INTERCEPT_PENDING_A(0xfffa0b byte)
546: void Intercept_PendingA_ReadByte(void)
547: {
548: STRam[0xfffa0b] = MFP_IPRA;
549: }
550:
551: // INTERCEPT_PENDING_B(0xfffa0d byte)
552: void Intercept_PendingB_ReadByte(void)
553: {
554: STRam[0xfffa0d] = MFP_IPRB;
555: }
556:
557: // INTERCEPT_INSERVICE_A(0xfffa0f byte)
558: void Intercept_InServiceA_ReadByte(void)
559: {
560: STRam[0xfffa0f] = MFP_ISRA;
561: }
562:
563: // INTERCEPT_INSERVICE_B(0xfffa11 byte)
564: void Intercept_InServiceB_ReadByte(void)
565: {
566: STRam[0xfffa11] = MFP_ISRB;
567: }
568:
569: // INTERCEPT_MASK_A(0xfffa13 byte)
570: void Intercept_MaskA_ReadByte(void)
571: {
572: STRam[0xfffa13] = MFP_IMRA;
573: }
574:
575: // INTERCEPT_MASK_B(0xfffa15 byte)
576: void Intercept_MaskB_ReadByte(void)
577: {
578: STRam[0xfffa15] = MFP_IMRB;
579: }
580:
581: // INTERCEPT_VECTOR_REG(0xfffa17 byte)
582: void Intercept_VectorReg_ReadByte(void)
583: {
584: STRam[0xfffa17] = MFP_VR;
585: }
586:
587: // INTERCEPT_TIMERA_CTRL(0xfffa19 byte)
588: void Intercept_TimerACtrl_ReadByte(void)
589: {
590: STRam[0xfffa19] = MFP_TACR;
591: }
592:
593: // INTERCEPT_TIMERB_CTRL(0xfffa1b byte)
594: void Intercept_TimerBCtrl_ReadByte(void)
595: {
596: STRam[0xfffa1b] = MFP_TBCR;
597: }
598:
599: // INTERCEPT_TIMERCD_CTRL(0xfffa1d byte)
600: void Intercept_TimerCDCtrl_ReadByte(void)
601: {
602: STRam[0xfffa1d] = MFP_TCDCR;
603: }
604:
605: // INTERCEPT_TIMERA_DATA(0xfffa1f byte)
606: void Intercept_TimerAData_ReadByte(void)
607: {
608: if( MFP_TACR != 8 ) /* Is event count? Need to re-calculate counter */
609: MFP_ReadTimerA(); /* Stores result in 'MFP_TA_MAINCOUNTER' */
610: STRam[0xfffa1f] = MFP_TA_MAINCOUNTER;
611: }
612:
613: // INTERCEPT_TIMERB_DATA(0xfffa21 byte)
614: void Intercept_TimerBData_ReadByte(void)
615: {
616: if(MFP_TBCR != 8) /* Is event count? Need to re-calculate counter */
617: MFP_ReadTimerB(); /* Stores result in 'MFP_TB_MAINCOUNTER' */
618: STRam[0xfffa21] = MFP_TB_MAINCOUNTER;
619: }
620:
621: // INTERCEPT_TIMERC_DATA(0xfffa23 byte)
622: void Intercept_TimerCData_ReadByte(void)
623: {
624: MFP_ReadTimerC(); /* Stores result in 'MFP_TC_MAINCOUNTER' */
625: STRam[0xfffa23] = MFP_TC_MAINCOUNTER;
626: }
627:
628: // INTERCEPT_TIMERD_DATA(0xfffa25 byte)
629: void Intercept_TimerDData_ReadByte(void)
630: {
631: MFP_ReadTimerD(); /* Stores result in 'MFP_TD_MAINCOUNTER' */
632: STRam[0xfffa25] = MFP_TD_MAINCOUNTER;
633: }
634:
635: // INTERCEPT_KEYBOARDCONTROL(0xfffc00 byte)
636: void Intercept_KeyboardControl_ReadByte(void)
637: {
638: /* For our emulation send is immediate so acknowledge buffer is empty */
639: STRam[0xfffc00] = ACIAStatusRegister | ACIA_STATUS_REGISTER__TX_BUFFER_EMPTY;
640: }
641:
642: // INTERCEPT_KEYBOARDDATA(0xfffc02 byte)
643: void Intercept_KeyboardData_ReadByte(void)
644: {
645: STRam[0xfffc02] = IKBD_GetByteFromACIA(); /* Return our byte from keyboard processor */
646: }
647:
648: // INTERCEPT_MIDICONTROL(0xfffc04 byte)
649: void Intercept_MidiControl_ReadByte(void)
650: {
651: STRam[0xfffc04] = 2; /* Should be this? */
652: }
653:
654: // INTERCEPT_MIDIDATA(0xfffc06 byte)
655: void Intercept_MidiData_ReadByte(void)
656: {
657: STRam[0xfffc06] = 1; /* Should be this? */
658: }
659:
660:
661:
662:
663: //-----------------------------------------------------------------------
664: // Write to Hardware(0x00ff8000 to 0xffffff)
665:
666: // INTERCEPT_VIDEOHIGH(0xff8205 byte)
667: void Intercept_VideoHigh_WriteByte(void)
668: {
669: // Nothing...
670: }
671:
672: // INTERCEPT_VIDEOMED(0xff8207 byte)
673: void Intercept_VideoMed_WriteByte(void)
674: {
675: // Nothing...
676: }
677:
678: // INTERCEPT_VIDEOLOW(0xff8209 byte)
679: void Intercept_VideoLow_WriteByte(void)
680: {
681: // Nothing...
682: }
683:
684: // INTERCEPT_VIDEOSYNC(0xff820a byte)
685: void Intercept_VideoSync_WriteByte(void)
686: {
687: VideoSyncByte = STRam[0xff820a] & 3; /* We're only interested in lower 2 bits(50/60Hz) */
688: Video_WriteToSync();
689: }
690:
691: // INTERCEPT_VIDEOBASELOW(0xff820d byte)
692: void Intercept_VideoBaseLow_WriteByte(void)
693: {
694: // Nothing...
695: }
696:
697: // INTERCEPT_LINEWIDTH(0xff820f byte)
698: void Intercept_LineWidth_WriteByte(void)
699: {
700: // Nothing...
701: }
702:
703: void Intercept_Colour_WriteWord(unsigned long addr)
704: {
705: if( !bUseHighRes ) /* Don't store if hi-res */
706: {
707: unsigned short col;
708: Video_SetHBLPaletteMaskPointers(); /* Set 'pHBLPalettes' etc.. according cycles into frame */
709: col = STMemory_ReadWord( addr );
710: col &= 0x777; /* Mask off to 512 palette(some games write 0xFFFF and read back to see if STe) */
711: Spec512_StoreCyclePalette( col, addr ); /* Store colour into CyclePalettes[] */
712: pHBLPalettes[(addr-0xff8240)/2]=col; /* Set colour x */
713: *pHBLPaletteMasks |= 1 << ((addr-0xff8240)/2); /* And mask */
714: }
715: }
716:
717: // INTERCEPT_COLOUR0(0xff8240 word)
718: void Intercept_Colour0_WriteWord(void)
719: {
720: Intercept_Colour_WriteWord( 0xff8240 );
721: }
722:
723: // INTERCEPT_COLOUR1(0xff8242 word)
724: void Intercept_Colour1_WriteWord(void)
725: {
726: Intercept_Colour_WriteWord( 0xff8242 );
727: }
728:
729: // INTERCEPT_COLOUR2(0xff8244 word)
730: void Intercept_Colour2_WriteWord(void)
731: {
732: Intercept_Colour_WriteWord( 0xff8244 );
733: }
734:
735: // INTERCEPT_COLOUR3(0xff8246 word)
736: void Intercept_Colour3_WriteWord(void)
737: {
738: Intercept_Colour_WriteWord( 0xff8246 );
739: }
740:
741: // INTERCEPT_COLOUR4(0xff8248 word)
742: void Intercept_Colour4_WriteWord(void)
743: {
744: Intercept_Colour_WriteWord( 0xff8248 );
745: }
746:
747: // INTERCEPT_COLOUR5(0xff824a word)
748: void Intercept_Colour5_WriteWord(void)
749: {
750: Intercept_Colour_WriteWord( 0xff824a );
751: }
752:
753: // INTERCEPT_COLOUR6(0xff824c word)
754: void Intercept_Colour6_WriteWord(void)
755: {
756: Intercept_Colour_WriteWord( 0xff824c );
757: }
758:
759: // INTERCEPT_COLOUR7(0xff824e word)
760: void Intercept_Colour7_WriteWord(void)
761: {
762: Intercept_Colour_WriteWord( 0xff824e );
763: }
764:
765: // INTERCEPT_COLOUR8(0xff8250 word)
766: void Intercept_Colour8_WriteWord(void)
767: {
768: Intercept_Colour_WriteWord( 0xff8250 );
769: }
770:
771: // INTERCEPT_COLOUR9(0xff8252 word)
772: void Intercept_Colour9_WriteWord(void)
773: {
774: Intercept_Colour_WriteWord( 0xff8252 );
775: }
776:
777: // INTERCEPT_COLOUR10(0xff8254 word)
778: void Intercept_Colour10_WriteWord(void)
779: {
780: Intercept_Colour_WriteWord( 0xff8254 );
781: }
782:
783: // INTERCEPT_COLOUR11(0xff8256 word)
784: void Intercept_Colour11_WriteWord(void)
785: {
786: Intercept_Colour_WriteWord( 0xff8256 );
787: }
788:
789: // INTERCEPT_COLOUR12(0xff8258 word)
790: void Intercept_Colour12_WriteWord(void)
791: {
792: Intercept_Colour_WriteWord( 0xff8258 );
793: }
794:
795: // INTERCEPT_COLOUR13(0xff825a word)
796: void Intercept_Colour13_WriteWord(void)
797: {
798: Intercept_Colour_WriteWord( 0xff825a );
799: }
800:
801: // INTERCEPT_COLOUR14(0xff825c word)
802: void Intercept_Colour14_WriteWord(void)
803: {
804: Intercept_Colour_WriteWord( 0xff825c );
805: }
806:
807: // INTERCEPT_COLOUR15(0xff825e word)
808: void Intercept_Colour15_WriteWord(void)
809: {
810: Intercept_Colour_WriteWord( 0xff825e );
811: }
812:
813: // INTERCEPT_SHIFTERMODE(0xff8260 byte)
814: void Intercept_ShifterMode_WriteByte(void)
815: {
816: if( !bUseHighRes && !bUseVDIRes ) /* Don't store if hi-res and don't store if VDI resolution */
817: {
818: VideoShifterByte = STRam[0xff8260] & 3; /* We only care for lower 2-bits */
819: Video_WriteToShifter();
820: Video_SetHBLPaletteMaskPointers();
821: *pHBLPaletteMasks &= 0xffff00ff;
822: *pHBLPaletteMasks |= (VideoShifterByte|0x04)<<8; /* Store resolution after palette mask and set resolution write bit */
823: }
824: /* FIXME: Is the pHBLPaletteMasks stuff okay? In the original source, it was: */
825: /*
826: mov ebp,[pHBLPaletteMasks] // Store resolution
827: mov bl,[VideoShifterByte]
828: mov BYTE PTR [ebp+2],bl // after palette mask
829: or BYTE PTR [ebp+2],0x04 // and set resolution write bit
830: */
831: }
832:
833: // INTERCEPT_DISKCONTROL(0xff8604 word)
834: void Intercept_DiskControl_WriteWord(void)
835: {
836: FDC_WriteDiscController( STMemory_ReadWord(0xff8604) );
837: }
838:
839: // INTERCEPT_DMASTATUS(0xff8606 word)
840: void Intercept_DmaStatus_WriteWord(void)
841: {
842: FDC_WriteDMAModeControl( STMemory_ReadWord(0xff8606) );
843: }
844:
845: // INTERCEPT_PSG_REGISTER(0xff8800 byte)
846: void Intercept_PSGRegister_WriteByte(void)
847: {
848: PSG_WriteSelectRegister( STRam[0xff8800] );
849: }
850:
851: // INTERCEPT_PSG_DATA(0xff8802 byte)
852: void Intercept_PSGData_WriteByte(void)
853: {
854: PSG_WriteDataRegister( STRam[0xff8802] );
855: }
856:
857: // INTERCEPT_MICROWIREDATA(0xff8922 word)
858: void Intercept_MicrowireData_WriteWord(void)
859: {
860: // Nothing...
861: }
862:
863: // INTERCEPT_MONITOR(0xfffa01 byte)
864: void Intercept_Monitor_WriteByte(void)
865: {
866: // Nothing...
867: }
868:
869: // INTERCEPT_ACTIVE_EDGE(0xfffa03 byte)
870: void Intercept_ActiveEdge_WriteByte(void)
871: {
872: MFP_AER = STRam[0xfffa03];
873: }
874:
875: // INTERCEPT_DATA_DIRECTION(0xfffa05 byte)
876: void Intercept_DataDirection_WriteByte(void)
877: {
878: MFP_DDR = STRam[0xfffa05];
879: }
880:
881:
882: // INTERCEPT_ENABLE_A(0xfffa07 byte)
883: void Intercept_EnableA_WriteByte(void)
884: {
885: MFP_IERA = STRam[0xfffa07];
886: MFP_IPRA &= MFP_IERA;
887: MFP_UpdateFlags();
888: /* We may have enabled Timer A or B, check */
889: MFP_StartTimerA();
890: MFP_StartTimerB();
891: }
892:
893: // INTERCEPT_ENABLE_B(0xfffa09 byte)
894: void Intercept_EnableB_WriteByte(void)
895: {
896: MFP_IERB = STRam[0xfffa09];
897: MFP_IPRB &= MFP_IERB;
898: MFP_UpdateFlags();
899: /* We may have enabled Timer C or D, check */
900: MFP_StartTimerC();
901: MFP_StartTimerD();
902: }
903:
904: // INTERCEPT_PENDING_A(0xfffa0b byte)
905: void Intercept_PendingA_WriteByte(void)
906: {
907: MFP_IPRA &= STRam[0xfffa0b]; /* Cannot set pending bits - only clear via software */
908: MFP_UpdateFlags(); /* Check if any interrupts pending */
909: }
910:
911: // INTERCEPT_PENDING_B(0xfffa0d byte)
912: void Intercept_PendingB_WriteByte(void)
913: {
914: MFP_IPRB &= STRam[0xfffa0d];
915: MFP_UpdateFlags(); /* Check if any interrupts pending */
916: }
917:
918: // INTERCEPT_INSERVICE_A(0xfffa0f byte)
919: void Intercept_InServiceA_WriteByte(void)
920: {
921: MFP_ISRA &= STRam[0xfffa0f]; /* Cannot set in-service bits - only clear via software */
922: }
923:
924: // INTERCEPT_INSERVICE_B(0xfffa11 byte)
925: void Intercept_InServiceB_WriteByte(void)
926: {
927: MFP_ISRB &= STRam[0xfffa11]; /* Cannot set in-service bits - only clear via software */
928: }
929:
930: // INTERCEPT_MASK_A(0xfffa13 byte)
931: void Intercept_MaskA_WriteByte(void)
932: {
933: MFP_IMRA = STRam[0xfffa13];
934: }
935:
936: // INTERCEPT_MASK_B(0xfffa15 byte)
937: void Intercept_MaskB_WriteByte(void)
938: {
939: MFP_IMRB = STRam[0xfffa15];
940: }
941:
942: // INTERCEPT_VECTOR_REG(0xfffa17 byte)
943: void Intercept_VectorReg_WriteByte(void)
944: {
945: unsigned short old_vr;
946: old_vr = MFP_VR; /* Copy for checking if set mode */
947: MFP_VR = STRam[0xfffa17];
948: if( (MFP_VR^old_vr)&0x08 ) /* Test change in end-of-interrupt mode */
949: if( MFP_VR&0x08 ) /* Mode did change but was it to automatic mode? (ie bit is a zero) */
950: { /* We are now in automatic mode, so clear all in-service bits! */
951: MFP_ISRA = 0;
952: MFP_ISRB = 0;
953: }
954: }
955:
956: // INTERCEPT_TIMERA_CTRL(0xfffa19 byte)
957: void Intercept_TimerACtrl_WriteByte(void)
958: {
959: unsigned short old_tacr;
960: old_tacr = MFP_TACR; /* Remember old control state */
961: MFP_TACR = STRam[0xfffa19] & 0x0f; /* Mask, Fish(auto160) writes into top nibble! */
962: if( (MFP_TACR^old_tacr)&0x0f ) /* Check if Timer A control changed */
963: MFP_StartTimerA(); /* Reset timers if need to */
964: }
965:
966: // INTERCEPT_TIMERB_CTRL(0xfffa1b byte)
967: void Intercept_TimerBCtrl_WriteByte(void)
968: {
969: unsigned short old_tbcr;
970: old_tbcr = MFP_TBCR; /* Remember old control state */
971: MFP_TBCR = STRam[0xfffa1b] & 0x0f; /* Mask, Fish(auto160) writes into top nibble! */
972: if( (MFP_TBCR^old_tbcr)&0x0f ) /* Check if Timer B control changed */
973: MFP_StartTimerB(); /* Reset timers if need to */
974: }
975:
976: // INTERCEPT_TIMERCD_CTRL(0xfffa1d byte)
977: void Intercept_TimerCDCtrl_WriteByte(void)
978: {
979: unsigned short old_tcdcr;
980: old_tcdcr = MFP_TCDCR; /* Remember old control state */
981: MFP_TCDCR = STRam[0xfffa1d]; /* Store new one */
982: if( (MFP_TCDCR^old_tcdcr)&0x70 ) /* Check if Timer C control changed */
983: MFP_StartTimerC(); /* Reset timers if need to */
984: if( (MFP_TCDCR^old_tcdcr)&0x07 ) /* Check if Timer D control changed */
985: MFP_StartTimerD(); /* Reset timers if need to */
986: }
987:
988: // INTERCEPT_TIMERA_DATA(0xfffa1f byte)
989: void Intercept_TimerAData_WriteByte(void)
990: {
991: MFP_TADR = STRam[0xfffa1f]; /* Store into data register */
992: if( MFP_TACR==0 ) /* Now check if timer is running - if so do not set */
993: {
994: MFP_TA_MAINCOUNTER = MFP_TADR; /* Timer is off, store to main counter */
995: MFP_StartTimerA(); /* Add our interrupt */
996: }
997: }
998:
999: // INTERCEPT_TIMERB_DATA(0xfffa21 byte)
1000: void Intercept_TimerBData_WriteByte(void)
1001: {
1002: MFP_TBDR = STRam[0xfffa21]; /* Store into data register */
1003: if( MFP_TBCR==0 ) /* Now check if timer is running - if so do not set */
1004: {
1005: MFP_TB_MAINCOUNTER = MFP_TBDR; /* Timer is off, store to main counter */
1006: MFP_StartTimerB(); /* Add our interrupt */
1007: }
1008: }
1009:
1010: // INTERCEPT_TIMERC_DATA(0xfffa23 byte)
1011: void Intercept_TimerCData_WriteByte(void)
1012: {
1013: MFP_TCDR = STRam[0xfffa23]; /* Store into data register */
1014: if( (MFP_TCDCR&0x70)==0 ) /* Now check if timer is running - if so do not set */
1015: {
1016: MFP_StartTimerC(); /* Add our interrupt */
1017: }
1018: }
1019:
1020: // INTERCEPT_TIMERD_DATA(0xfffa25 byte)
1021: void Intercept_TimerDData_WriteByte(void)
1022: {
1023: MFP_TDDR = STRam[0xfffa25]; /* Store into data register */
1024: if( (MFP_TCDCR&0x07)==0 ) /* Now check if timer is running - if so do not set */
1025: {
1026: MFP_StartTimerD(); /* Add our interrupt */
1027: }
1028: }
1029:
1030: // INTERCEPT_KEYBOARDCONTROL(0xfffc00 byte)
1031: void Intercept_KeyboardControl_WriteByte(void)
1032: {
1033: /* Nothing... */
1034: }
1035:
1036: // INTERCEPT_KEYBOARDDATA(0xfffc02 byte)
1037: void Intercept_KeyboardData_WriteByte(void)
1038: {
1039: IKBD_SendByteToKeyboardProcessor( STRam[0xfffc02] ); /* Pass our byte to the keyboard processor */
1040: }
1041:
1042: // INTERCEPT_MIDICONTROL(0xfffc04 byte)
1043: void Intercept_MidiControl_WriteByte(void)
1044: {
1045: /* Nothing... */
1046: }
1047:
1048: // INTERCEPT_MIDIDATA(0xfffc06 byte)
1049: void Intercept_MidiData_WriteByte(void)
1050: {
1051: /* Nothing... */
1052: }
1053:
1054:
1055: // Address space for Bus Error in hardware mapping
1056: INTERCEPT_ADDRESSRANGE InterceptBusErrors[] = {
1057: 0xff8a00,0xff8a3e, /* Blitter */
1058: 0xff8900,0xff8960, /* DMA Sound/MicroWire */
1059:
1060: 0,0 /* term */
1061: };
1062:
1063:
1064:
1065: /*-------------------------------------------------------------------------*/
1066: /*
1067: Modify 'intercept' tables to cause Bus Errors on addres to un-mapped
1068: hardware space (Wing Of Death addresses Blitter space which causes
1069: BusError on STfm)
1070: */
1071: void Intercept_ModifyTablesForBusErrors(void)
1072: {
1073: unsigned long *pInterceptList;
1074: unsigned int Address;
1075: int i=0;
1076:
1077: // Set routine list
1078: pInterceptList = pCurrentInterceptWorkspace;
1079: *pCurrentInterceptWorkspace++ = (unsigned long)M68000_BusError;
1080: *pCurrentInterceptWorkspace++ = 0L;
1081:
1082: // Set all 'no-mans-land' entries
1083: while(InterceptBusErrors[i].Start_Address!=0) {
1084: // Set 'no-mans-land' table
1085: for(Address=InterceptBusErrors[i].Start_Address; Address<InterceptBusErrors[i].End_Address; Address++) {
1086: // For 'read'
1087: pInterceptReadByteTable[Address-0xff8000] = pInterceptList;
1088: pInterceptReadWordTable[Address-0xff8000] = pInterceptList;
1089: pInterceptReadLongTable[Address-0xff8000] = pInterceptList;
1090: // and 'write'
1091: pInterceptWriteByteTable[Address-0xff8000] = pInterceptList;
1092: pInterceptWriteWordTable[Address-0xff8000] = pInterceptList;
1093: pInterceptWriteLongTable[Address-0xff8000] = pInterceptList;
1094: }
1095:
1096: i++;
1097: }
1098: }
1099:
1100: #ifdef CHECK_FOR_NO_MANS_LAND
1101:
1102: // List of hardware addresses which are 'no-man's-land', ie not connected on ST
1103: // NOTE PSG is mirror'd in range 0xff8004 to 0xff8900
1104: INTERCEPT_ADDRESSRANGE InterceptNoMansLand[] = {
1105: 0xff8002,0xff8200, // All these are illegal addresses on standard STfm
1106: 0xff8210,0xff8240,
1107: 0xff8262,0xff8600,
1108: 0xff860e,0xff8800,
1109: 0xff8900,0xfffa00,
1110: 0xfffa30,0xfffc00,
1111: 0xfffc20,0x1000000,
1112:
1113: 0,0 //term
1114: };
1115:
1116: //-----------------------------------------------------------------------
1117: /*
1118: Intercept function used on all non-documented hardware registers. Used to help debugging
1119: */
1120: void Intercept_NoMansLand_ReadWrite(void)
1121: {
1122: /*
1123: SAVE_ASSEM_REGS
1124: __asm {
1125: // 'ebp' will hold address we tried to access!
1126: // 'esi' is ST program counter!
1127: int 3 // Cause Windows GPF, so can see register list
1128: }
1129: */
1130: }
1131:
1132: //-----------------------------------------------------------------------
1133: /*
1134: Modify 'intercept' tables to check for access into 'no-mans-land', ie unknown hardware locations
1135: */
1136: void Intercept_ModifyTablesForNoMansLand(void)
1137: {
1138: unsigned long *pInterceptList;
1139: unsigned int Address;
1140: int i=0;
1141:
1142: // Set routine list
1143: pInterceptList = pCurrentInterceptWorkspace;
1144: *pCurrentInterceptWorkspace++ = (unsigned long)Intercept_NoMansLand_ReadWrite;
1145: *pCurrentInterceptWorkspace++ = NULL;
1146:
1147: // Set all 'no-mans-land' entries
1148: while(InterceptNoMansLand[i].Start_Address!=0) {
1149: // Set 'no-mans-land' table
1150: for(Address=InterceptNoMansLand[i].Start_Address; Address<InterceptNoMansLand[i].End_Address; Address++) {
1151: // For 'read'
1152: pInterceptReadByteTable[Address-0xff8000] = pInterceptList;
1153: pInterceptReadWordTable[Address-0xff8000] = pInterceptList;
1154: pInterceptReadLongTable[Address-0xff8000] = pInterceptList;
1155: // and 'write'
1156: pInterceptWriteByteTable[Address-0xff8000] = pInterceptList;
1157: pInterceptWriteWordTable[Address-0xff8000] = pInterceptList;
1158: pInterceptWriteLongTable[Address-0xff8000] = pInterceptList;
1159: }
1160:
1161: i++;
1162: }
1163: }
1164:
1165: #endif //CHECK_FOR_NO_MANS_LAND
1166:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.