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