|
|
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 );
712: col &= 0x777; /* Mask off to 512 palette(some games write 0xFFFF and read back to see if STe) */
713: Spec512_StoreCyclePalette( col, addr ); /* Store colour into CyclePalettes[] */
714: pHBLPalettes[(addr-0xff8240)/2]=col; /* Set colour x */
715: *pHBLPaletteMasks |= 1 << ((addr-0xff8240)/2); /* And mask */
716: }
717: }
718:
1.1.1.2 ! root 719: /* INTERCEPT_COLOUR0(0xff8240 word) */
1.1 root 720: void Intercept_Colour0_WriteWord(void)
721: {
722: Intercept_Colour_WriteWord( 0xff8240 );
723: }
724:
1.1.1.2 ! root 725: /* INTERCEPT_COLOUR1(0xff8242 word) */
1.1 root 726: void Intercept_Colour1_WriteWord(void)
727: {
728: Intercept_Colour_WriteWord( 0xff8242 );
729: }
730:
1.1.1.2 ! root 731: /* INTERCEPT_COLOUR2(0xff8244 word) */
1.1 root 732: void Intercept_Colour2_WriteWord(void)
733: {
734: Intercept_Colour_WriteWord( 0xff8244 );
735: }
736:
1.1.1.2 ! root 737: /* INTERCEPT_COLOUR3(0xff8246 word) */
1.1 root 738: void Intercept_Colour3_WriteWord(void)
739: {
740: Intercept_Colour_WriteWord( 0xff8246 );
741: }
742:
1.1.1.2 ! root 743: /* INTERCEPT_COLOUR4(0xff8248 word) */
1.1 root 744: void Intercept_Colour4_WriteWord(void)
745: {
746: Intercept_Colour_WriteWord( 0xff8248 );
747: }
748:
1.1.1.2 ! root 749: /* INTERCEPT_COLOUR5(0xff824a word) */
1.1 root 750: void Intercept_Colour5_WriteWord(void)
751: {
752: Intercept_Colour_WriteWord( 0xff824a );
753: }
754:
1.1.1.2 ! root 755: /* INTERCEPT_COLOUR6(0xff824c word) */
1.1 root 756: void Intercept_Colour6_WriteWord(void)
757: {
758: Intercept_Colour_WriteWord( 0xff824c );
759: }
760:
1.1.1.2 ! root 761: /* INTERCEPT_COLOUR7(0xff824e word) */
1.1 root 762: void Intercept_Colour7_WriteWord(void)
763: {
764: Intercept_Colour_WriteWord( 0xff824e );
765: }
766:
1.1.1.2 ! root 767: /* INTERCEPT_COLOUR8(0xff8250 word) */
1.1 root 768: void Intercept_Colour8_WriteWord(void)
769: {
770: Intercept_Colour_WriteWord( 0xff8250 );
771: }
772:
1.1.1.2 ! root 773: /* INTERCEPT_COLOUR9(0xff8252 word) */
1.1 root 774: void Intercept_Colour9_WriteWord(void)
775: {
776: Intercept_Colour_WriteWord( 0xff8252 );
777: }
778:
1.1.1.2 ! root 779: /* INTERCEPT_COLOUR10(0xff8254 word) */
1.1 root 780: void Intercept_Colour10_WriteWord(void)
781: {
782: Intercept_Colour_WriteWord( 0xff8254 );
783: }
784:
1.1.1.2 ! root 785: /* INTERCEPT_COLOUR11(0xff8256 word) */
1.1 root 786: void Intercept_Colour11_WriteWord(void)
787: {
788: Intercept_Colour_WriteWord( 0xff8256 );
789: }
790:
1.1.1.2 ! root 791: /* INTERCEPT_COLOUR12(0xff8258 word) */
1.1 root 792: void Intercept_Colour12_WriteWord(void)
793: {
794: Intercept_Colour_WriteWord( 0xff8258 );
795: }
796:
1.1.1.2 ! root 797: /* INTERCEPT_COLOUR13(0xff825a word) */
1.1 root 798: void Intercept_Colour13_WriteWord(void)
799: {
800: Intercept_Colour_WriteWord( 0xff825a );
801: }
802:
1.1.1.2 ! root 803: /* INTERCEPT_COLOUR14(0xff825c word) */
1.1 root 804: void Intercept_Colour14_WriteWord(void)
805: {
806: Intercept_Colour_WriteWord( 0xff825c );
807: }
808:
1.1.1.2 ! root 809: /* INTERCEPT_COLOUR15(0xff825e word) */
1.1 root 810: void Intercept_Colour15_WriteWord(void)
811: {
812: Intercept_Colour_WriteWord( 0xff825e );
813: }
814:
1.1.1.2 ! root 815: /* INTERCEPT_SHIFTERMODE(0xff8260 byte) */
1.1 root 816: void Intercept_ShifterMode_WriteByte(void)
817: {
818: if( !bUseHighRes && !bUseVDIRes ) /* Don't store if hi-res and don't store if VDI resolution */
819: {
820: VideoShifterByte = STRam[0xff8260] & 3; /* We only care for lower 2-bits */
821: Video_WriteToShifter();
822: Video_SetHBLPaletteMaskPointers();
823: *pHBLPaletteMasks &= 0xffff00ff;
824: *pHBLPaletteMasks |= (VideoShifterByte|0x04)<<8; /* Store resolution after palette mask and set resolution write bit */
825: }
826: /* FIXME: Is the pHBLPaletteMasks stuff okay? In the original source, it was: */
827: /*
828: mov ebp,[pHBLPaletteMasks] // Store resolution
829: mov bl,[VideoShifterByte]
830: mov BYTE PTR [ebp+2],bl // after palette mask
831: or BYTE PTR [ebp+2],0x04 // and set resolution write bit
832: */
833: }
834:
1.1.1.2 ! root 835: /* INTERCEPT_DISKCONTROL(0xff8604 word) */
1.1 root 836: void Intercept_DiskControl_WriteWord(void)
837: {
838: FDC_WriteDiscController( STMemory_ReadWord(0xff8604) );
839: }
840:
1.1.1.2 ! root 841: /* INTERCEPT_DMASTATUS(0xff8606 word) */
1.1 root 842: void Intercept_DmaStatus_WriteWord(void)
843: {
844: FDC_WriteDMAModeControl( STMemory_ReadWord(0xff8606) );
845: }
846:
1.1.1.2 ! root 847: /* INTERCEPT_PSG_REGISTER(0xff8800 byte) */
1.1 root 848: void Intercept_PSGRegister_WriteByte(void)
849: {
850: PSG_WriteSelectRegister( STRam[0xff8800] );
851: }
852:
1.1.1.2 ! root 853: /* INTERCEPT_PSG_DATA(0xff8802 byte) */
1.1 root 854: void Intercept_PSGData_WriteByte(void)
855: {
856: PSG_WriteDataRegister( STRam[0xff8802] );
857: }
858:
1.1.1.2 ! root 859: /* INTERCEPT_MICROWIREDATA(0xff8922 word) */
1.1 root 860: void Intercept_MicrowireData_WriteWord(void)
861: {
1.1.1.2 ! root 862: /* Nothing... */
1.1 root 863: }
864:
1.1.1.2 ! root 865: /* INTERCEPT_MONITOR(0xfffa01 byte) */
1.1 root 866: void Intercept_Monitor_WriteByte(void)
867: {
1.1.1.2 ! root 868: /* Nothing... */
1.1 root 869: }
870:
1.1.1.2 ! root 871: /* INTERCEPT_ACTIVE_EDGE(0xfffa03 byte) */
1.1 root 872: void Intercept_ActiveEdge_WriteByte(void)
873: {
874: MFP_AER = STRam[0xfffa03];
875: }
876:
1.1.1.2 ! root 877: /* INTERCEPT_DATA_DIRECTION(0xfffa05 byte) */
1.1 root 878: void Intercept_DataDirection_WriteByte(void)
879: {
880: MFP_DDR = STRam[0xfffa05];
881: }
882:
883:
1.1.1.2 ! root 884: /* INTERCEPT_ENABLE_A(0xfffa07 byte) */
1.1 root 885: void Intercept_EnableA_WriteByte(void)
886: {
887: MFP_IERA = STRam[0xfffa07];
888: MFP_IPRA &= MFP_IERA;
889: MFP_UpdateFlags();
890: /* We may have enabled Timer A or B, check */
891: MFP_StartTimerA();
892: MFP_StartTimerB();
893: }
894:
1.1.1.2 ! root 895: /* INTERCEPT_ENABLE_B(0xfffa09 byte) */
1.1 root 896: void Intercept_EnableB_WriteByte(void)
897: {
898: MFP_IERB = STRam[0xfffa09];
899: MFP_IPRB &= MFP_IERB;
900: MFP_UpdateFlags();
901: /* We may have enabled Timer C or D, check */
902: MFP_StartTimerC();
903: MFP_StartTimerD();
904: }
905:
1.1.1.2 ! root 906: /* INTERCEPT_PENDING_A(0xfffa0b byte) */
1.1 root 907: void Intercept_PendingA_WriteByte(void)
908: {
909: MFP_IPRA &= STRam[0xfffa0b]; /* Cannot set pending bits - only clear via software */
910: MFP_UpdateFlags(); /* Check if any interrupts pending */
911: }
912:
1.1.1.2 ! root 913: /* INTERCEPT_PENDING_B(0xfffa0d byte) */
1.1 root 914: void Intercept_PendingB_WriteByte(void)
915: {
916: MFP_IPRB &= STRam[0xfffa0d];
917: MFP_UpdateFlags(); /* Check if any interrupts pending */
918: }
919:
1.1.1.2 ! root 920: /* INTERCEPT_INSERVICE_A(0xfffa0f byte) */
1.1 root 921: void Intercept_InServiceA_WriteByte(void)
922: {
923: MFP_ISRA &= STRam[0xfffa0f]; /* Cannot set in-service bits - only clear via software */
924: }
925:
1.1.1.2 ! root 926: /* INTERCEPT_INSERVICE_B(0xfffa11 byte) */
1.1 root 927: void Intercept_InServiceB_WriteByte(void)
928: {
929: MFP_ISRB &= STRam[0xfffa11]; /* Cannot set in-service bits - only clear via software */
930: }
931:
1.1.1.2 ! root 932: /* INTERCEPT_MASK_A(0xfffa13 byte) */
1.1 root 933: void Intercept_MaskA_WriteByte(void)
934: {
935: MFP_IMRA = STRam[0xfffa13];
936: }
937:
1.1.1.2 ! root 938: /* INTERCEPT_MASK_B(0xfffa15 byte) */
1.1 root 939: void Intercept_MaskB_WriteByte(void)
940: {
941: MFP_IMRB = STRam[0xfffa15];
942: }
943:
1.1.1.2 ! root 944: /* INTERCEPT_VECTOR_REG(0xfffa17 byte) */
1.1 root 945: void Intercept_VectorReg_WriteByte(void)
946: {
947: unsigned short old_vr;
948: old_vr = MFP_VR; /* Copy for checking if set mode */
949: MFP_VR = STRam[0xfffa17];
950: if( (MFP_VR^old_vr)&0x08 ) /* Test change in end-of-interrupt mode */
951: if( MFP_VR&0x08 ) /* Mode did change but was it to automatic mode? (ie bit is a zero) */
952: { /* We are now in automatic mode, so clear all in-service bits! */
953: MFP_ISRA = 0;
954: MFP_ISRB = 0;
955: }
956: }
957:
1.1.1.2 ! root 958: /* INTERCEPT_TIMERA_CTRL(0xfffa19 byte) */
1.1 root 959: void Intercept_TimerACtrl_WriteByte(void)
960: {
961: unsigned short old_tacr;
962: old_tacr = MFP_TACR; /* Remember old control state */
963: MFP_TACR = STRam[0xfffa19] & 0x0f; /* Mask, Fish(auto160) writes into top nibble! */
964: if( (MFP_TACR^old_tacr)&0x0f ) /* Check if Timer A control changed */
965: MFP_StartTimerA(); /* Reset timers if need to */
966: }
967:
1.1.1.2 ! root 968: /* INTERCEPT_TIMERB_CTRL(0xfffa1b byte) */
1.1 root 969: void Intercept_TimerBCtrl_WriteByte(void)
970: {
971: unsigned short old_tbcr;
972: old_tbcr = MFP_TBCR; /* Remember old control state */
973: MFP_TBCR = STRam[0xfffa1b] & 0x0f; /* Mask, Fish(auto160) writes into top nibble! */
974: if( (MFP_TBCR^old_tbcr)&0x0f ) /* Check if Timer B control changed */
975: MFP_StartTimerB(); /* Reset timers if need to */
976: }
977:
1.1.1.2 ! root 978: /* INTERCEPT_TIMERCD_CTRL(0xfffa1d byte) */
1.1 root 979: void Intercept_TimerCDCtrl_WriteByte(void)
980: {
981: unsigned short old_tcdcr;
982: old_tcdcr = MFP_TCDCR; /* Remember old control state */
983: MFP_TCDCR = STRam[0xfffa1d]; /* Store new one */
984: if( (MFP_TCDCR^old_tcdcr)&0x70 ) /* Check if Timer C control changed */
985: MFP_StartTimerC(); /* Reset timers if need to */
986: if( (MFP_TCDCR^old_tcdcr)&0x07 ) /* Check if Timer D control changed */
987: MFP_StartTimerD(); /* Reset timers if need to */
988: }
989:
1.1.1.2 ! root 990: /* INTERCEPT_TIMERA_DATA(0xfffa1f byte) */
1.1 root 991: void Intercept_TimerAData_WriteByte(void)
992: {
993: MFP_TADR = STRam[0xfffa1f]; /* Store into data register */
994: if( MFP_TACR==0 ) /* Now check if timer is running - if so do not set */
995: {
996: MFP_TA_MAINCOUNTER = MFP_TADR; /* Timer is off, store to main counter */
997: MFP_StartTimerA(); /* Add our interrupt */
998: }
999: }
1000:
1.1.1.2 ! root 1001: /* INTERCEPT_TIMERB_DATA(0xfffa21 byte) */
1.1 root 1002: void Intercept_TimerBData_WriteByte(void)
1003: {
1004: MFP_TBDR = STRam[0xfffa21]; /* Store into data register */
1005: if( MFP_TBCR==0 ) /* Now check if timer is running - if so do not set */
1006: {
1007: MFP_TB_MAINCOUNTER = MFP_TBDR; /* Timer is off, store to main counter */
1008: MFP_StartTimerB(); /* Add our interrupt */
1009: }
1010: }
1011:
1.1.1.2 ! root 1012: /* INTERCEPT_TIMERC_DATA(0xfffa23 byte) */
1.1 root 1013: void Intercept_TimerCData_WriteByte(void)
1014: {
1015: MFP_TCDR = STRam[0xfffa23]; /* Store into data register */
1016: if( (MFP_TCDCR&0x70)==0 ) /* Now check if timer is running - if so do not set */
1017: {
1018: MFP_StartTimerC(); /* Add our interrupt */
1019: }
1020: }
1021:
1.1.1.2 ! root 1022: /* INTERCEPT_TIMERD_DATA(0xfffa25 byte) */
1.1 root 1023: void Intercept_TimerDData_WriteByte(void)
1024: {
1025: MFP_TDDR = STRam[0xfffa25]; /* Store into data register */
1026: if( (MFP_TCDCR&0x07)==0 ) /* Now check if timer is running - if so do not set */
1027: {
1028: MFP_StartTimerD(); /* Add our interrupt */
1029: }
1030: }
1031:
1.1.1.2 ! root 1032: /* INTERCEPT_KEYBOARDCONTROL(0xfffc00 byte) */
1.1 root 1033: void Intercept_KeyboardControl_WriteByte(void)
1034: {
1035: /* Nothing... */
1036: }
1037:
1.1.1.2 ! root 1038: /* INTERCEPT_KEYBOARDDATA(0xfffc02 byte) */
1.1 root 1039: void Intercept_KeyboardData_WriteByte(void)
1040: {
1041: IKBD_SendByteToKeyboardProcessor( STRam[0xfffc02] ); /* Pass our byte to the keyboard processor */
1042: }
1043:
1.1.1.2 ! root 1044: /* INTERCEPT_MIDICONTROL(0xfffc04 byte) */
1.1 root 1045: void Intercept_MidiControl_WriteByte(void)
1046: {
1047: /* Nothing... */
1048: }
1049:
1.1.1.2 ! root 1050: /* INTERCEPT_MIDIDATA(0xfffc06 byte) */
1.1 root 1051: void Intercept_MidiData_WriteByte(void)
1052: {
1053: /* Nothing... */
1054: }
1055:
1056:
1.1.1.2 ! root 1057:
! 1058: /* Address space for Bus Error in hardware mapping */
1.1 root 1059: INTERCEPT_ADDRESSRANGE InterceptBusErrors[] = {
1060: 0xff8a00,0xff8a3e, /* Blitter */
1061: 0xff8900,0xff8960, /* DMA Sound/MicroWire */
1062:
1063: 0,0 /* term */
1064: };
1065:
1066:
1.1.1.2 ! root 1067: /*-------------------------------------------------------------------------*/
! 1068: /*
! 1069: Jump to the BusError handler with the correct bus address
! 1070: */
! 1071: void Intercept_BusError(void)
! 1072: {
! 1073: M68000_BusError(BusAddressLocation);
! 1074: }
! 1075:
1.1 root 1076:
1077: /*-------------------------------------------------------------------------*/
1078: /*
1079: Modify 'intercept' tables to cause Bus Errors on addres to un-mapped
1080: hardware space (Wing Of Death addresses Blitter space which causes
1081: BusError on STfm)
1082: */
1083: void Intercept_ModifyTablesForBusErrors(void)
1084: {
1085: unsigned long *pInterceptList;
1086: unsigned int Address;
1087: int i=0;
1088:
1.1.1.2 ! root 1089: /* Set routine list */
1.1 root 1090: pInterceptList = pCurrentInterceptWorkspace;
1.1.1.2 ! root 1091: *pCurrentInterceptWorkspace++ = (unsigned long)Intercept_BusError;
1.1 root 1092: *pCurrentInterceptWorkspace++ = 0L;
1093:
1.1.1.2 ! root 1094: /* Set all 'no-mans-land' entries */
1.1 root 1095: while(InterceptBusErrors[i].Start_Address!=0) {
1.1.1.2 ! root 1096: /* Set 'no-mans-land' table */
1.1 root 1097: for(Address=InterceptBusErrors[i].Start_Address; Address<InterceptBusErrors[i].End_Address; Address++) {
1.1.1.2 ! root 1098: /* For 'read' */
1.1 root 1099: pInterceptReadByteTable[Address-0xff8000] = pInterceptList;
1100: pInterceptReadWordTable[Address-0xff8000] = pInterceptList;
1101: pInterceptReadLongTable[Address-0xff8000] = pInterceptList;
1.1.1.2 ! root 1102: /* and 'write' */
1.1 root 1103: pInterceptWriteByteTable[Address-0xff8000] = pInterceptList;
1104: pInterceptWriteWordTable[Address-0xff8000] = pInterceptList;
1105: pInterceptWriteLongTable[Address-0xff8000] = pInterceptList;
1106: }
1107:
1108: i++;
1109: }
1110: }
1111:
1.1.1.2 ! root 1112:
! 1113:
1.1 root 1114: #ifdef CHECK_FOR_NO_MANS_LAND
1115:
1.1.1.2 ! root 1116: /* List of hardware addresses which are 'no-man's-land', ie not connected on ST */
! 1117: /* NOTE PSG is mirror'd in range 0xff8004 to 0xff8900 */
1.1 root 1118: INTERCEPT_ADDRESSRANGE InterceptNoMansLand[] = {
1.1.1.2 ! root 1119: 0xff8002,0xff8200, /* All these are illegal addresses on standard STfm */
1.1 root 1120: 0xff8210,0xff8240,
1121: 0xff8262,0xff8600,
1122: 0xff860e,0xff8800,
1123: 0xff8900,0xfffa00,
1124: 0xfffa30,0xfffc00,
1125: 0xfffc20,0x1000000,
1126:
1.1.1.2 ! root 1127: 0,0 /*term*/
1.1 root 1128: };
1129:
1.1.1.2 ! root 1130: /*-----------------------------------------------------------------------*/
1.1 root 1131: /*
1.1.1.2 ! root 1132: Intercept function used on all non-documented hardware registers.
! 1133: Used to help debugging
1.1 root 1134: */
1135: void Intercept_NoMansLand_ReadWrite(void)
1136: {
1.1.1.2 ! root 1137: fprintf(stderr,"NoMansLand_ReadWrite at address $%lx , PC=$%lx\n",
! 1138: BusAddressLocation, PC);
1.1 root 1139: }
1140:
1.1.1.2 ! root 1141: /*----------------------------------------------------------------------- */
1.1 root 1142: /*
1143: Modify 'intercept' tables to check for access into 'no-mans-land', ie unknown hardware locations
1144: */
1145: void Intercept_ModifyTablesForNoMansLand(void)
1146: {
1147: unsigned long *pInterceptList;
1148: unsigned int Address;
1149: int i=0;
1150:
1.1.1.2 ! root 1151: /* Set routine list */
1.1 root 1152: pInterceptList = pCurrentInterceptWorkspace;
1153: *pCurrentInterceptWorkspace++ = (unsigned long)Intercept_NoMansLand_ReadWrite;
1154: *pCurrentInterceptWorkspace++ = NULL;
1155:
1.1.1.2 ! root 1156: /* Set all 'no-mans-land' entries */
1.1 root 1157: while(InterceptNoMansLand[i].Start_Address!=0) {
1.1.1.2 ! root 1158: /* Set 'no-mans-land' table */
1.1 root 1159: for(Address=InterceptNoMansLand[i].Start_Address; Address<InterceptNoMansLand[i].End_Address; Address++) {
1.1.1.2 ! root 1160: /* For 'read' */
1.1 root 1161: pInterceptReadByteTable[Address-0xff8000] = pInterceptList;
1162: pInterceptReadWordTable[Address-0xff8000] = pInterceptList;
1163: pInterceptReadLongTable[Address-0xff8000] = pInterceptList;
1.1.1.2 ! root 1164: /* and 'write' */
1.1 root 1165: pInterceptWriteByteTable[Address-0xff8000] = pInterceptList;
1166: pInterceptWriteWordTable[Address-0xff8000] = pInterceptList;
1167: pInterceptWriteLongTable[Address-0xff8000] = pInterceptList;
1168: }
1169:
1170: i++;
1171: }
1172: }
1173:
1.1.1.2 ! root 1174: #endif /*CHECK_FOR_NO_MANS_LAND*/
1.1 root 1175:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.