|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - intercept.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: This is where we intercept read/writes to/from the hardware. The ST's memory is nicely split into
8: four main parts - the bottom area of RAM is for user programs. This is followed by a large area which
9: causes a Bus Error. After this is the ROM addresses for TOS and finally an area for hardware mapping.
10: To gain speed any address in the user area can simply read/write, but anything above this range needs
11: to be checked for validity and sent to the various handlers.
12: A big problem for ST emulation is the use of the hardware registers. These often consist of an 'odd' byte
13: in memory and is usually addressed as a single byte. A number of applications, however, write to the address
14: using a word or even long word - which may span over two hardware registers! Rather than check for any and
15: all combinations we use a tables for byte/word/long and for read/write. These are lists of functions which
16: access the ST Ram area any bytes which maybe affected by the operation. Eg, a long write to a PSG register
17: (which access two registers) will write the long into ST Ram and then call the two handlers which read off
18: the bytes for each register. This means that any access to any hardware register in such a way will work
19: correctly - it certainly fixes a lot of bugs and means writing just one routine for each hardware register
20: we mean to intercept! Phew!
21: Note the 'mirror'(or shadow) registers of the PSG - this is used by most games. We also have a means of
22: testing for addressing into 'no-mans-land' which are parts of the hardware map which are not valid on a
23: standard STfm.
24: */
1.1.1.7 ! root 25: char Intercept_rcsid[] = "Hatari $Id: intercept.c,v 1.24 2004/07/25 13:50:30 thothy Exp $";
1.1 root 26:
1.1.1.5 root 27: #include <SDL_types.h>
28:
1.1 root 29: #include "main.h"
30: #include "debug.h"
31: #include "dialog.h"
32: #include "fdc.h"
33: #include "int.h"
34: #include "intercept.h"
35: #include "ikbd.h"
36: #include "m68000.h"
37: #include "memAlloc.h"
38: #include "mfp.h"
1.1.1.7 ! root 39: #include "midi.h"
1.1 root 40: #include "psg.h"
1.1.1.6 root 41: #include "rtc.h"
1.1.1.7 ! root 42: #include "rs232.h"
1.1 root 43: #include "screen.h"
44: #include "spec512.h"
1.1.1.5 root 45: #include "stMemory.h"
1.1 root 46: #include "vdi.h"
47: #include "video.h"
1.1.1.5 root 48: #include "blitter.h"
1.1 root 49: #include "uae-cpu/sysdeps.h"
1.1.1.6 root 50: #include "tos.h"
1.1.1.5 root 51:
1.1.1.2 root 52: /*#define CHECK_FOR_NO_MANS_LAND*/ /* Check for read/write from unknown hardware addresses */
1.1 root 53:
1.1.1.6 root 54:
55: /* A dummy function that does nothing at all... */
1.1.1.7 ! root 56: static void Intercept_WriteNothing(void)
1.1.1.6 root 57: {
58: /* Nothing... */
59: }
60:
61:
1.1.1.2 root 62: /*-----------------------------------------------------------------------*/
1.1.1.6 root 63: /* List of functions to handle read/write hardware intercepts. */
64: INTERCEPT_ACCESS_FUNC InterceptAccessFuncs[] =
65: {
1.1.1.5 root 66: { 0x0,SIZE_BYTE,NULL,NULL },
67: { 0xff8205,SIZE_BYTE,Intercept_VideoHigh_ReadByte,Intercept_VideoHigh_WriteByte }, /* INTERCEPT_VIDEOHIGH */
68: { 0xff8207,SIZE_BYTE,Intercept_VideoMed_ReadByte,Intercept_VideoMed_WriteByte }, /* INTERCEPT_VIDEOMED */
69: { 0xff8209,SIZE_BYTE,Intercept_VideoLow_ReadByte,Intercept_VideoLow_WriteByte }, /* INTERCEPT_VIDEOLOW */
70: { 0xff820a,SIZE_BYTE,Intercept_VideoSync_ReadByte,Intercept_VideoSync_WriteByte }, /* INTERCEPT_VIDEOSYNC */
71: { 0xff820d,SIZE_BYTE,Intercept_VideoBaseLow_ReadByte,Intercept_VideoBaseLow_WriteByte }, /* INTERCEPT_VIDEOBASELOW */
72: { 0xff820f,SIZE_BYTE,Intercept_LineWidth_ReadByte,Intercept_LineWidth_WriteByte }, /* INTERCEPT_LINEWIDTH */
73: { 0xff8240,SIZE_WORD,Intercept_Colour0_ReadWord,Intercept_Colour0_WriteWord }, /* INTERCEPT_COLOUR0 */
74: { 0xff8242,SIZE_WORD,Intercept_Colour1_ReadWord,Intercept_Colour1_WriteWord }, /* INTERCEPT_COLOUR1 */
75: { 0xff8244,SIZE_WORD,Intercept_Colour2_ReadWord,Intercept_Colour2_WriteWord }, /* INTERCEPT_COLOUR2 */
76: { 0xff8246,SIZE_WORD,Intercept_Colour3_ReadWord,Intercept_Colour3_WriteWord }, /* INTERCEPT_COLOUR3 */
77: { 0xff8248,SIZE_WORD,Intercept_Colour4_ReadWord,Intercept_Colour4_WriteWord }, /* INTERCEPT_COLOUR4 */
78: { 0xff824a,SIZE_WORD,Intercept_Colour5_ReadWord,Intercept_Colour5_WriteWord }, /* INTERCEPT_COLOUR5 */
79: { 0xff824c,SIZE_WORD,Intercept_Colour6_ReadWord,Intercept_Colour6_WriteWord }, /* INTERCEPT_COLOUR6 */
80: { 0xff824e,SIZE_WORD,Intercept_Colour7_ReadWord,Intercept_Colour7_WriteWord }, /* INTERCEPT_COLOUR7 */
81: { 0xff8250,SIZE_WORD,Intercept_Colour8_ReadWord,Intercept_Colour8_WriteWord }, /* INTERCEPT_COLOUR8 */
82: { 0xff8252,SIZE_WORD,Intercept_Colour9_ReadWord,Intercept_Colour9_WriteWord }, /* INTERCEPT_COLOUR9 */
83: { 0xff8254,SIZE_WORD,Intercept_Colour10_ReadWord,Intercept_Colour10_WriteWord }, /* INTERCEPT_COLOUR10 */
84: { 0xff8256,SIZE_WORD,Intercept_Colour11_ReadWord,Intercept_Colour11_WriteWord }, /* INTERCEPT_COLOUR11 */
85: { 0xff8258,SIZE_WORD,Intercept_Colour12_ReadWord,Intercept_Colour12_WriteWord }, /* INTERCEPT_COLOUR12 */
86: { 0xff825a,SIZE_WORD,Intercept_Colour13_ReadWord,Intercept_Colour13_WriteWord }, /* INTERCEPT_COLOUR13 */
87: { 0xff825c,SIZE_WORD,Intercept_Colour14_ReadWord,Intercept_Colour14_WriteWord }, /* INTERCEPT_COLOUR14 */
88: { 0xff825e,SIZE_WORD,Intercept_Colour15_ReadWord,Intercept_Colour15_WriteWord }, /* INTERCEPT_COLOUR15 */
89: { 0xff8260,SIZE_BYTE,Intercept_ShifterMode_ReadByte,Intercept_ShifterMode_WriteByte }, /* INTERCEPT_SHIFTERMODE */
1.1.1.6 root 90:
1.1.1.5 root 91: { 0xff8604,SIZE_WORD,Intercept_DiskControl_ReadWord,Intercept_DiskControl_WriteWord }, /* INTERCEPT_DISKCONTROL */
92: { 0xff8606,SIZE_WORD,Intercept_DmaStatus_ReadWord,Intercept_DmaStatus_WriteWord }, /* INTERCEPT_DMASTATUS */
93: { 0xff8800,SIZE_BYTE,Intercept_PSGRegister_ReadByte,Intercept_PSGRegister_WriteByte }, /* INTERCEPT_PSG_REGISTER */
94: { 0xff8802,SIZE_BYTE,Intercept_PSGData_ReadByte,Intercept_PSGData_WriteByte }, /* INTERCEPT_PSG_DATA */
95: { 0xff8922,SIZE_WORD,Intercept_MicrowireData_ReadWord,Intercept_MicrowireData_WriteWord }, /* INTERCEPT_MICROWIREDATA */
1.1.1.6 root 96:
1.1.1.5 root 97: { 0xff8a28,SIZE_WORD,Intercept_BlitterEndmask1_ReadWord,Intercept_BlitterEndmask1_WriteWord },
98: { 0xff8a2a,SIZE_WORD,Intercept_BlitterEndmask2_ReadWord,Intercept_BlitterEndmask2_WriteWord },
99: { 0xff8a2c,SIZE_WORD,Intercept_BlitterEndmask3_ReadWord,Intercept_BlitterEndmask3_WriteWord },
100: { 0xff8a32,SIZE_LONG,Intercept_BlitterDst_ReadLong,Intercept_BlitterDst_WriteLong },
101: { 0xff8a36,SIZE_WORD,Intercept_BlitterWPL_ReadWord,Intercept_BlitterWPL_WriteWord },
102: { 0xff8a38,SIZE_WORD,Intercept_BlitterLPB_ReadWord,Intercept_BlitterLPB_WriteWord },
103: { 0xff8a3a,SIZE_BYTE,Intercept_BlitterHalftoneOp_ReadByte,Intercept_BlitterHalftoneOp_WriteByte },
104: { 0xff8a3b,SIZE_BYTE,Intercept_BlitterLogOp_ReadByte,Intercept_BlitterLogOp_WriteByte },
105: { 0xff8a3c,SIZE_BYTE,Intercept_BlitterLineNum_ReadByte,Intercept_BlitterLineNum_WriteByte },
106: { 0xff8a3d,SIZE_BYTE,Intercept_BlitterSkew_ReadByte,Intercept_BlitterSkew_WriteByte },
1.1.1.6 root 107:
1.1.1.5 root 108: { 0xfffa01,SIZE_BYTE,Intercept_Monitor_ReadByte,Intercept_Monitor_WriteByte }, /* INTERCEPT_MONITOR */
109: { 0xfffa03,SIZE_BYTE,Intercept_ActiveEdge_ReadByte,Intercept_ActiveEdge_WriteByte }, /* INTERCEPT_ACTIVE_EDGE */
110: { 0xfffa05,SIZE_BYTE,Intercept_DataDirection_ReadByte,Intercept_DataDirection_WriteByte }, /* INTERCEPT_DATA_DIRECTION */
111: { 0xfffa07,SIZE_BYTE,Intercept_EnableA_ReadByte,Intercept_EnableA_WriteByte }, /* INTERCEPT_ENABLE_A */
112: { 0xfffa09,SIZE_BYTE,Intercept_EnableB_ReadByte,Intercept_EnableB_WriteByte }, /* INTERCEPT_ENABLE_B */
113: { 0xfffa0b,SIZE_BYTE,Intercept_PendingA_ReadByte,Intercept_PendingA_WriteByte }, /* INTERCEPT_PENDING_A */
114: { 0xfffa0d,SIZE_BYTE,Intercept_PendingB_ReadByte,Intercept_PendingB_WriteByte }, /* INTERCEPT_PENDING_B */
115: { 0xfffa0f,SIZE_BYTE,Intercept_InServiceA_ReadByte,Intercept_InServiceA_WriteByte }, /* INTERCEPT_INSERVICE_A */
116: { 0xfffa11,SIZE_BYTE,Intercept_InServiceB_ReadByte,Intercept_InServiceB_WriteByte }, /* INTERCEPT_INSERVICE_B */
117: { 0xfffa13,SIZE_BYTE,Intercept_MaskA_ReadByte,Intercept_MaskA_WriteByte }, /* INTERCEPT_MASK_A */
118: { 0xfffa15,SIZE_BYTE,Intercept_MaskB_ReadByte,Intercept_MaskB_WriteByte }, /* INTERCEPT_MASK_B */
119: { 0xfffa17,SIZE_BYTE,Intercept_VectorReg_ReadByte,Intercept_VectorReg_WriteByte }, /* INTERCEPT_VECTOR_REG */
120: { 0xfffa19,SIZE_BYTE,Intercept_TimerACtrl_ReadByte,Intercept_TimerACtrl_WriteByte }, /* INTERCEPT_TIMERA_CTRL */
121: { 0xfffa1b,SIZE_BYTE,Intercept_TimerBCtrl_ReadByte,Intercept_TimerBCtrl_WriteByte }, /* INTERCEPT_TIMERB_CTRL */
122: { 0xfffa1d,SIZE_BYTE,Intercept_TimerCDCtrl_ReadByte,Intercept_TimerCDCtrl_WriteByte }, /* INTERCEPT_TIMERCD_CTRL */
123: { 0xfffa1f,SIZE_BYTE,Intercept_TimerAData_ReadByte,Intercept_TimerAData_WriteByte }, /* INTERCEPT_TIMERA_DATA */
124: { 0xfffa21,SIZE_BYTE,Intercept_TimerBData_ReadByte,Intercept_TimerBData_WriteByte }, /* INTERCEPT_TIMERB_DATA */
125: { 0xfffa23,SIZE_BYTE,Intercept_TimerCData_ReadByte,Intercept_TimerCData_WriteByte }, /* INTERCEPT_TIMERC_DATA */
126: { 0xfffa25,SIZE_BYTE,Intercept_TimerDData_ReadByte,Intercept_TimerDData_WriteByte }, /* INTERCEPT_TIMERD_DATA */
1.1.1.6 root 127:
1.1.1.7 ! root 128: { 0xfffa27,SIZE_BYTE,RS232_SCR_ReadByte,RS232_SCR_WriteByte }, /* Sync character register */
! 129: { 0xfffa29,SIZE_BYTE,RS232_UCR_ReadByte,RS232_UCR_WriteByte }, /* USART control register */
! 130: { 0xfffa2b,SIZE_BYTE,RS232_RSR_ReadByte,RS232_RSR_WriteByte }, /* Receiver status register */
! 131: { 0xfffa2d,SIZE_BYTE,RS232_TSR_ReadByte,RS232_TSR_WriteByte }, /* Transmitter status register */
! 132: { 0xfffa2f,SIZE_BYTE,RS232_UDR_ReadByte,RS232_UDR_WriteByte }, /* USART data register */
! 133:
1.1.1.5 root 134: { 0xfffc00,SIZE_BYTE,Intercept_KeyboardControl_ReadByte,Intercept_KeyboardControl_WriteByte }, /* INTERCEPT_KEYBOARDCONTROL */
135: { 0xfffc02,SIZE_BYTE,Intercept_KeyboardData_ReadByte,Intercept_KeyboardData_WriteByte }, /* INTERCEPT_KEYBOARDDATA */
136: { 0xfffc04,SIZE_BYTE,Intercept_MidiControl_ReadByte,Intercept_MidiControl_WriteByte }, /* INTERCEPT_MIDICONTROL */
137: { 0xfffc06,SIZE_BYTE,Intercept_MidiData_ReadByte,Intercept_MidiData_WriteByte }, /* INTERCEPT_MIDIDATA */
1.1.1.6 root 138:
139: { 0xfffc21,SIZE_BYTE,Rtc_SecondsUnits_ReadByte,Intercept_WriteNothing },
140: { 0xfffc23,SIZE_BYTE,Rtc_SecondsTens_ReadByte,Intercept_WriteNothing },
141: { 0xfffc25,SIZE_BYTE,Rtc_MinutesUnits_ReadByte,Rtc_MinutesUnits_WriteByte },
142: { 0xfffc27,SIZE_BYTE,Rtc_MinutesTens_ReadByte,Rtc_MinutesTens_WriteByte },
143: { 0xfffc29,SIZE_BYTE,Rtc_HoursUnits_ReadByte,Intercept_WriteNothing },
144: { 0xfffc2b,SIZE_BYTE,Rtc_HoursTens_ReadByte,Intercept_WriteNothing },
145: { 0xfffc2d,SIZE_BYTE,Rtc_Weekday_ReadByte,Intercept_WriteNothing },
146: { 0xfffc2f,SIZE_BYTE,Rtc_DayUnits_ReadByte,Intercept_WriteNothing },
147: { 0xfffc31,SIZE_BYTE,Rtc_DayTens_ReadByte,Intercept_WriteNothing },
148: { 0xfffc33,SIZE_BYTE,Rtc_MonthUnits_ReadByte,Intercept_WriteNothing },
149: { 0xfffc35,SIZE_BYTE,Rtc_MonthTens_ReadByte,Intercept_WriteNothing },
150: { 0xfffc37,SIZE_BYTE,Rtc_YearUnits_ReadByte,Intercept_WriteNothing },
151: { 0xfffc39,SIZE_BYTE,Rtc_YearTens_ReadByte,Intercept_WriteNothing },
152: { 0xfffc3b,SIZE_BYTE,Rtc_ClockMod_ReadByte,Rtc_ClockMod_WriteByte },
1.1 root 153: };
154:
1.1.1.6 root 155:
1.1.1.2 root 156: unsigned long *pInterceptWorkspace; /* Memory used to store all read/write NULL terminated function call tables */
157: unsigned long *pCurrentInterceptWorkspace; /* Index into above */
1.1 root 158: unsigned long *pInterceptReadByteTable[0x8000],*pInterceptReadWordTable[0x8000],*pInterceptReadLongTable[0x8000];
159: unsigned long *pInterceptWriteByteTable[0x8000],*pInterceptWriteWordTable[0x8000],*pInterceptWriteLongTable[0x8000];
1.1.1.5 root 160: BOOL bEnableBlitter = FALSE; /* TRUE if blitter is enabled */
1.1 root 161:
1.1.1.6 root 162: #ifdef CHECK_FOR_NO_MANS_LAND
163: /* We use a well-known address for the no-mans-land workspace so we can test for it in Intercept_CreateTable() */
164: unsigned long noMansLandWorkspace[2] = { (unsigned long)Intercept_NoMansLand_ReadWrite, 0L };
165: #else
166: unsigned long noMansLandWorkspace[1] = { 0L };
167: #endif
168:
1.1.1.7 ! root 169: static int nTimerDFakeValue; /* Faked Timer-D data register for the Timer-D patch */
! 170:
1.1.1.2 root 171:
172: /*-----------------------------------------------------------------------*/
1.1 root 173: /*
174: Create 'intercept' tables for hardware address access
175: */
176: void Intercept_Init(void)
177: {
1.1.1.2 root 178: /* Allocate memory for intercept tables */
1.1 root 179: pCurrentInterceptWorkspace = pInterceptWorkspace = (unsigned long *)Memory_Alloc(INTERCEPT_WORKSPACE_SIZE);
180:
1.1.1.2 root 181: /* Clear intercept tables(NULL signifies no entries for that location) */
1.1 root 182: Memory_Clear(pInterceptReadByteTable,sizeof(unsigned long *)*0x8000);
183: Memory_Clear(pInterceptReadWordTable,sizeof(unsigned long *)*0x8000);
184: Memory_Clear(pInterceptReadLongTable,sizeof(unsigned long *)*0x8000);
185: Memory_Clear(pInterceptWriteByteTable,sizeof(unsigned long *)*0x8000);
186: Memory_Clear(pInterceptWriteWordTable,sizeof(unsigned long *)*0x8000);
187: Memory_Clear(pInterceptWriteLongTable,sizeof(unsigned long *)*0x8000);
188:
1.1.1.6 root 189: #ifdef CHECK_FOR_NO_MANS_LAND
190: /* This causes a error when an application tries to access illegal hardware registers(maybe mirror'd) */
191: Intercept_ModifyTablesForNoMansLand();
192: #endif /*CHECK_FOR_NO_MANS_LAND*/
193:
1.1.1.2 root 194: /* Create 'read' tables */
1.1 root 195: Intercept_CreateTable(pInterceptReadByteTable,SIZE_BYTE,0);
196: Intercept_CreateTable(pInterceptReadWordTable,SIZE_WORD,0);
197: Intercept_CreateTable(pInterceptReadLongTable,SIZE_LONG,0);
1.1.1.2 root 198: /* And 'write' tables */
1.1 root 199: Intercept_CreateTable(pInterceptWriteByteTable,SIZE_BYTE,1);
200: Intercept_CreateTable(pInterceptWriteWordTable,SIZE_WORD,1);
201: Intercept_CreateTable(pInterceptWriteLongTable,SIZE_LONG,1);
202:
1.1.1.2 root 203: /* And modify for bus-error in hardware space */
1.1 root 204: Intercept_ModifyTablesForBusErrors();
205: }
206:
1.1.1.5 root 207:
1.1.1.2 root 208: /*-----------------------------------------------------------------------*/
1.1 root 209: /*
210: Free 'intercept' hardware lists
211: */
212: void Intercept_UnInit(void)
213: {
214: Memory_Free(pInterceptWorkspace);
215: }
216:
1.1.1.5 root 217:
1.1.1.2 root 218: /*-----------------------------------------------------------------------*/
1.1 root 219: /*
220: Set Intercept hardware address table index's
221:
222: Each 'intercept table' is a list of 0x8000 pointers to a list of functions to call when that
223: location in the ST's memory is accessed. Each entry is terminated by a NULL
224: Eg, if we write a long word to address '0xff8800', we
225: need to call the functions 'InterceptPSGRegister_WriteByte' and then 'InterceptPSGData_WriteByte'.
226: */
227:
228: void Intercept_CreateTable(unsigned long *pInterceptTable[],int Span,int ReadWrite)
229: {
1.1.1.7 ! root 230: unsigned int Address, LowAddress, HiAddress, i;
1.1 root 231:
1.1.1.2 root 232: /* Scan each hardware address */
1.1.1.6 root 233: for(Address=0xff8000; Address<=0xffffff; Address++)
234: {
1.1.1.2 root 235: /* Does this hardware location/span appear in our list of possible intercepted functions? */
1.1.1.6 root 236: for (i=0; i<(sizeof(InterceptAccessFuncs)/sizeof(INTERCEPT_ACCESS_FUNC)); i++)
237: {
1.1 root 238: LowAddress = InterceptAccessFuncs[i].Address;
239: HiAddress = InterceptAccessFuncs[i].Address+InterceptAccessFuncs[i].SpanInBytes;
240:
241: if ( (Address+Span) <= LowAddress )
242: continue;
243: if ( Address >= HiAddress )
244: continue;
245:
1.1.1.2 root 246: /* This location needs to be intercepted, so add entry to list */
1.1.1.6 root 247: if(pInterceptTable[Address-0xff8000] == NULL
248: || pInterceptTable[Address-0xff8000] == noMansLandWorkspace)
249: {
1.1 root 250: pInterceptTable[Address-0xff8000] = pCurrentInterceptWorkspace;
1.1.1.6 root 251: }
252:
1.1.1.5 root 253: if(ReadWrite==0)
254: *pCurrentInterceptWorkspace++ = (unsigned long)InterceptAccessFuncs[i].ReadFunc;
255: else
256: *pCurrentInterceptWorkspace++ = (unsigned long)InterceptAccessFuncs[i].WriteFunc;
1.1 root 257: }
1.1.1.6 root 258:
1.1.1.2 root 259: /* Terminate table? */
1.1.1.6 root 260: if (pInterceptTable[Address-0xff8000] && pInterceptTable[Address-0xff8000] != noMansLandWorkspace)
1.1 root 261: *pCurrentInterceptWorkspace++ = 0L;
262: }
263: }
264:
1.1.1.5 root 265:
266: /*-----------------------------------------------------------------------*/
267: /*
268: Enable/disable blitter emulation
269: */
270: void Intercept_EnableBlitter(BOOL enableFlag)
271: {
272: if(bEnableBlitter!=enableFlag)
273: {
274: bEnableBlitter = enableFlag;
275: /* Ugly hack: Enable/disable the blitter emulation by
276: re-init the interception tables... */
277: Intercept_UnInit();
278: Intercept_Init();
279: }
280: }
281:
282:
1.1.1.2 root 283: /*-----------------------------------------------------------------------*/
1.1 root 284: /*
1.1.1.5 root 285: Check list of handlers to see if address needs to be intercepted and call
286: routines.
1.1 root 287: */
1.1.1.7 ! root 288: static void Intercept_ScanHandlers(unsigned long *the_func)
1.1 root 289: {
290: if( the_func )
291: while( *the_func ) /* Do we have any routines to run for this address? */
292: {
293: CALL_VAR(*the_func); /* Call routine */
294: the_func+=1;
295: }
296: }
297:
1.1.1.5 root 298:
1.1.1.2 root 299: /*-----------------------------------------------------------------------*/
1.1 root 300: /*
1.1.1.5 root 301: Check if need to change our address as maybe a mirror register.
302: Currently we only have a PSG mirror area.
1.1 root 303: */
1.1.1.5 root 304: static unsigned long Intercept_CheckMirrorAddresses(unsigned long addr)
1.1 root 305: {
1.1.1.2 root 306: if( addr>=0xff8800 && addr<0xff8900 ) /* Is a PSG mirror registers? */
307: addr = ( addr & 3) + 0xff8800; /* Bring into 0xff8800-0xff8804 range */
1.1.1.5 root 308:
1.1.1.2 root 309: return addr;
1.1 root 310: }
311:
1.1.1.5 root 312:
1.1.1.2 root 313: /*-----------------------------------------------------------------------*/
1.1.1.5 root 314:
315:
1.1 root 316: uae_u32 Intercept_ReadByte(uaecptr addr)
317: {
1.1.1.6 root 318: addr &= 0x00ffffff; /* Use a 24 bit address */
319:
320: if(addr < 0x00ff8000)
1.1.1.5 root 321: {
1.1.1.6 root 322: /* invalid memory addressing --> bus error */
1.1.1.7 ! root 323: M68000_BusError(addr, 1);
1.1.1.6 root 324: return 0;
1.1.1.5 root 325: }
1.1.1.6 root 326:
327: BusAddressLocation = addr; /* Store for exception frame, just in case */
328: addr = Intercept_CheckMirrorAddresses(addr);
329: Intercept_ScanHandlers(pInterceptReadByteTable[addr - 0x00ff8000]);
330:
1.1.1.5 root 331: return( STRam[addr] );
1.1 root 332: }
333:
334:
335: uae_u32 Intercept_ReadWord(uaecptr addr)
336: {
1.1.1.6 root 337: addr &= 0x00ffffff; /* Use a 24 bit address */
338:
1.1.1.5 root 339: if( addr&1 )
340: {
1.1.1.6 root 341: M68000_AddressError(addr); /* Is address error? (not correct alignment) */
1.1.1.5 root 342: return 0;
343: }
1.1.1.6 root 344:
345: if(addr < 0x00ff8000)
1.1.1.5 root 346: {
1.1.1.6 root 347: /* invalid memory addressing --> bus error */
1.1.1.7 ! root 348: M68000_BusError(addr, 1);
1.1.1.6 root 349: return 0;
1.1.1.5 root 350: }
1.1.1.6 root 351:
352: BusAddressLocation = addr; /* Store for exception frame, just in case */
353: addr = Intercept_CheckMirrorAddresses(addr);
354: Intercept_ScanHandlers(pInterceptReadWordTable[addr - 0x00ff8000]);
355:
356: return STMemory_ReadWord(addr);
1.1 root 357: }
358:
359:
360: uae_u32 Intercept_ReadLong(uaecptr addr)
361: {
1.1.1.6 root 362: addr &= 0x00ffffff; /* Use a 24 bit address */
363:
1.1.1.5 root 364: if( addr&1 )
365: {
1.1.1.6 root 366: M68000_AddressError(addr); /* Is address error? (not correct alignment) */
1.1.1.5 root 367: return 0;
368: }
1.1.1.6 root 369:
370: if(addr < 0x00ff8000)
1.1.1.5 root 371: {
1.1.1.6 root 372: /* invalid memory addressing --> bus error */
1.1.1.7 ! root 373: M68000_BusError(addr, 1);
1.1.1.6 root 374: return 0;
1.1.1.5 root 375: }
1.1.1.6 root 376:
377: BusAddressLocation = addr; /* Store for exception frame, just in case */
378: addr = Intercept_CheckMirrorAddresses(addr);
379: Intercept_ScanHandlers(pInterceptReadLongTable[addr - 0x00ff8000]);
380:
381: return STMemory_ReadLong(addr);
1.1 root 382: }
383:
1.1.1.2 root 384:
385: /*-----------------------------------------------------------------------*/
1.1.1.5 root 386:
387:
1.1 root 388: void Intercept_WriteByte(uaecptr addr, uae_u32 val)
389: {
1.1.1.6 root 390: addr &= 0x00ffffff; /* Use a 24 bit address */
391:
392: if(addr < 0x00ff8000)
1.1.1.5 root 393: {
1.1.1.6 root 394: /* invalid memory addressing --> bus error */
1.1.1.7 ! root 395: M68000_BusError(addr, 0);
1.1.1.6 root 396: return;
1.1.1.5 root 397: }
1.1.1.6 root 398:
399: BusAddressLocation = addr; /* Store for exception frame, just in case */
400: addr = Intercept_CheckMirrorAddresses(addr);
401: STRam[addr] = val;
402: Intercept_ScanHandlers(pInterceptWriteByteTable[addr - 0x00ff8000]);
1.1 root 403: }
404:
1.1.1.5 root 405:
1.1 root 406: void Intercept_WriteWord(uaecptr addr, uae_u32 val)
407: {
1.1.1.6 root 408: addr &= 0x00ffffff; /* Use a 24 bit address */
409:
1.1.1.5 root 410: if( addr&1 )
411: {
1.1.1.6 root 412: M68000_AddressError(addr); /* Is address error? (not correct alignment) */
1.1.1.5 root 413: return;
414: }
1.1.1.6 root 415:
416: if(addr < 0x00ff8000)
1.1.1.5 root 417: {
1.1.1.6 root 418: /* invalid memory addressing --> bus error */
1.1.1.7 ! root 419: M68000_BusError(addr, 0);
1.1.1.6 root 420: return;
1.1.1.5 root 421: }
1.1.1.6 root 422:
423: BusAddressLocation = addr; /* Store for exception frame, just in case */
424: addr = Intercept_CheckMirrorAddresses(addr);
425: STMemory_WriteWord(addr, val);
426: Intercept_ScanHandlers(pInterceptWriteWordTable[addr - 0x00ff8000]);
1.1 root 427: }
428:
1.1.1.5 root 429:
1.1 root 430: void Intercept_WriteLong(uaecptr addr, uae_u32 val)
431: {
1.1.1.6 root 432: addr &= 0x00ffffff; /* Use a 24 bit address */
433:
1.1.1.5 root 434: if( addr&1 )
435: {
1.1.1.6 root 436: M68000_AddressError(addr); /* Is address error? (not correct alignment) */
1.1.1.5 root 437: return;
438: }
1.1.1.6 root 439:
440: if(addr < 0x00ff8000)
1.1.1.5 root 441: {
1.1.1.6 root 442: /* invalid memory addressing --> bus error */
1.1.1.7 ! root 443: M68000_BusError(addr, 0);
1.1.1.6 root 444: return;
1.1.1.5 root 445: }
1.1.1.6 root 446:
447: BusAddressLocation = addr; /* Store for exception frame, just in case */
448: addr = Intercept_CheckMirrorAddresses(addr);
449: STMemory_WriteLong(addr, val);
450: Intercept_ScanHandlers(pInterceptWriteLongTable[addr - 0x00ff8000]);
1.1 root 451: }
452:
453:
1.1.1.6 root 454:
1.1.1.2 root 455: /*-----------------------------------------------------------------------*/
456: /* Read from Hardware(0x00ff8000 to 0xffffff) */
1.1 root 457:
1.1.1.2 root 458: /* INTERCEPT_VIDEOHIGH(0xff8205 byte) */
1.1 root 459: void Intercept_VideoHigh_ReadByte(void)
460: {
461: STRam[0xff8205] = Video_ReadAddress() >> 16; /* Get video address high byte */
462: }
463:
1.1.1.2 root 464: /* INTERCEPT_VIDEOMED(0xff8207 byte) */
1.1 root 465: void Intercept_VideoMed_ReadByte(void)
466: {
467: STRam[0xff8207] = Video_ReadAddress() >> 8; /* Get video address med byte */
468: }
469:
1.1.1.2 root 470: /* INTERCEPT_VIDEOLOW(0xff8209 byte) */
1.1 root 471: void Intercept_VideoLow_ReadByte(void)
472: {
473: STRam[0xff8209] = Video_ReadAddress(); /* Get video address med byte */
474: }
475:
1.1.1.2 root 476: /* INTERCEPT_VIDEOSYNC(0xff820a byte) */
1.1 root 477: void Intercept_VideoSync_ReadByte(void)
478: {
479: /* Nothing... */
480: }
481:
1.1.1.2 root 482: /* INTERCEPT_VIDEOBASELOW(0xff820d byte) */
1.1 root 483: void Intercept_VideoBaseLow_ReadByte(void)
484: {
485: STRam[0xff820d] = 0; /* ST can only store screen address to 256 bytes(ie no lower byte) */
486: }
487:
1.1.1.2 root 488: /* INTERCEPT_LINEWIDTH(0xff820f byte) */
1.1 root 489: void Intercept_LineWidth_ReadByte(void)
490: {
491: STRam[0xff820f]=0; /* On ST this is always 0 */
492: }
493:
1.1.1.2 root 494: /* INTERCEPT_COLOUR0(0xff8240 word) */
1.1 root 495: void Intercept_Colour0_ReadWord(void)
496: {
1.1.1.2 root 497: /* Nothing... */
1.1 root 498: }
499:
1.1.1.2 root 500: /* INTERCEPT_COLOUR1(0xff8242 word) */
1.1 root 501: void Intercept_Colour1_ReadWord(void)
502: {
1.1.1.2 root 503: /* Nothing... */
1.1 root 504: }
505:
1.1.1.2 root 506: /* INTERCEPT_COLOUR2(0xff8244 word) */
1.1 root 507: void Intercept_Colour2_ReadWord(void)
508: {
1.1.1.2 root 509: /* Nothing... */
1.1 root 510: }
511:
1.1.1.2 root 512: /* INTERCEPT_COLOUR3(0xff8246 word) */
1.1 root 513: void Intercept_Colour3_ReadWord(void)
514: {
1.1.1.2 root 515: /* Nothing... */
1.1 root 516: }
517:
1.1.1.2 root 518: /* INTERCEPT_COLOUR4(0xff8248 word) */
1.1 root 519: void Intercept_Colour4_ReadWord(void)
520: {
1.1.1.2 root 521: /* Nothing... */
1.1 root 522: }
523:
1.1.1.2 root 524: /* INTERCEPT_COLOUR5(0xff824a word) */
1.1 root 525: void Intercept_Colour5_ReadWord(void)
526: {
1.1.1.2 root 527: /* Nothing... */
1.1 root 528: }
529:
1.1.1.2 root 530: /* INTERCEPT_COLOUR6(0xff824c word) */
1.1 root 531: void Intercept_Colour6_ReadWord(void)
532: {
1.1.1.2 root 533: /* Nothing... */
1.1 root 534: }
535:
1.1.1.2 root 536: /* INTERCEPT_COLOUR7(0xff824e word) */
1.1 root 537: void Intercept_Colour7_ReadWord(void)
538: {
1.1.1.2 root 539: /* Nothing... */
1.1 root 540: }
541:
1.1.1.2 root 542: /* INTERCEPT_COLOUR8(0xff8250 word) */
1.1 root 543: void Intercept_Colour8_ReadWord(void)
544: {
1.1.1.2 root 545: /* Nothing... */
1.1 root 546: }
547:
1.1.1.2 root 548: /* INTERCEPT_COLOUR9(0xff8252 word) */
1.1 root 549: void Intercept_Colour9_ReadWord(void)
550: {
1.1.1.2 root 551: /* Nothing... */
1.1 root 552: }
553:
1.1.1.2 root 554: /* INTERCEPT_COLOUR10(0xff8254 word) */
1.1 root 555: void Intercept_Colour10_ReadWord(void)
556: {
1.1.1.2 root 557: /* Nothing... */
1.1 root 558: }
559:
1.1.1.2 root 560: /* INTERCEPT_COLOUR11(0xff8256 word) */
1.1 root 561: void Intercept_Colour11_ReadWord(void)
562: {
1.1.1.2 root 563: /* Nothing... */
1.1 root 564: }
565:
1.1.1.2 root 566: /* INTERCEPT_COLOUR12(0xff8258 word) */
1.1 root 567: void Intercept_Colour12_ReadWord(void)
568: {
1.1.1.2 root 569: /* Nothing... */
1.1 root 570: }
571:
1.1.1.2 root 572: /* INTERCEPT_COLOUR13(0xff825a word) */
1.1 root 573: void Intercept_Colour13_ReadWord(void)
574: {
1.1.1.2 root 575: /* Nothing... */
1.1 root 576: }
577:
1.1.1.2 root 578: /* INTERCEPT_COLOUR14(0xff825c word) */
1.1 root 579: void Intercept_Colour14_ReadWord(void)
580: {
1.1.1.2 root 581: /* Nothing... */
1.1 root 582: }
583:
1.1.1.2 root 584: /* INTERCEPT_COLOUR15(0xff825e word) */
1.1 root 585: void Intercept_Colour15_ReadWord(void)
586: {
1.1.1.2 root 587: /* Nothing... */
1.1 root 588: }
589:
1.1.1.2 root 590: /* INTERCEPT_SHIFTERMODE(0xff8260 byte) */
1.1 root 591: void Intercept_ShifterMode_ReadByte(void)
592: {
593: if(bUseHighRes)
594: STRam[0xff8260]=2; /* If mono monitor, force to high resolution */
595: else
596: STRam[0xff8260]=VideoShifterByte; /* Read shifter register */
597: }
598:
1.1.1.2 root 599: /* INTERCEPT_DISKCONTROL(0xff8604 word) */
1.1 root 600: void Intercept_DiskControl_ReadWord(void)
601: {
602: STMemory_WriteWord( 0xff8604, FDC_ReadDiscControllerStatus() );
603: }
604:
1.1.1.2 root 605: /* INTERCEPT_DMASTATUS(0xff8606 word) */
1.1 root 606: void Intercept_DmaStatus_ReadWord(void)
607: {
608: STMemory_WriteWord( 0xff8606, FDC_ReadDMAStatus() );
609: }
610:
1.1.1.2 root 611: /* INTERCEPT_PSG_REGISTER(0xff8800 byte) */
1.1 root 612: void Intercept_PSGRegister_ReadByte(void)
613: {
1.1.1.7 ! root 614: STRam[0xff8800] = PSG_ReadSelectRegister();
! 615: M68000_WaitState();
1.1 root 616: }
617:
1.1.1.2 root 618: /* INTERCEPT_PSG_DATA(0xff8802 byte) */
1.1 root 619: void Intercept_PSGData_ReadByte(void)
620: {
1.1.1.7 ! root 621: STRam[0xff8802] = PSG_ReadDataRegister();
! 622: M68000_WaitState();
1.1 root 623: }
624:
1.1.1.2 root 625: /* INTERCEPT_MICROWIREDATA(0xff8922 word) */
1.1 root 626: void Intercept_MicrowireData_ReadWord(void)
627: {
1.1.1.2 root 628: STMemory_WriteWord( 0xff8922, 0 );
1.1 root 629: }
630:
1.1.1.2 root 631: /* INTERCEPT_MONITOR(0xfffa01 byte) */
1.1 root 632: void Intercept_Monitor_ReadByte(void)
633: {
634: unsigned short v;
635: v=MFP_GPIP & 0x7f; /* Lower 7-bits are GPIP(Top bit is monitor type) */
636: if( !bUseHighRes ) v|=0x80; /* Colour monitor */
637: STRam[0xfffa01]=v;
638: }
639:
1.1.1.2 root 640: /* INTERCEPT_ACTIVE_EDGE(0xfffa03 byte) */
1.1 root 641: void Intercept_ActiveEdge_ReadByte(void)
642: {
643: STRam[0xfffa03] = MFP_AER;
644: }
645:
1.1.1.2 root 646: /* INTERCEPT_DATA_DIRECTION(0xfffa05 byte) */
1.1 root 647: void Intercept_DataDirection_ReadByte(void)
648: {
649: STRam[0xfffa05] = MFP_DDR;
650: }
651:
1.1.1.2 root 652: /* INTERCEPT_ENABLE_A(0xfffa07 byte) */
1.1 root 653: void Intercept_EnableA_ReadByte(void)
654: {
655: STRam[0xfffa07] = MFP_IERA;
656: }
657:
1.1.1.2 root 658: /* INTERCEPT_ENABLE_B(0xfffa09 byte) */
1.1 root 659: void Intercept_EnableB_ReadByte(void)
660: {
661: STRam[0xfffa09] = MFP_IERB;
662: }
663:
1.1.1.2 root 664: /* INTERCEPT_PENDING_A(0xfffa0b byte) */
1.1 root 665: void Intercept_PendingA_ReadByte(void)
666: {
667: STRam[0xfffa0b] = MFP_IPRA;
668: }
669:
1.1.1.2 root 670: /* INTERCEPT_PENDING_B(0xfffa0d byte) */
1.1 root 671: void Intercept_PendingB_ReadByte(void)
672: {
673: STRam[0xfffa0d] = MFP_IPRB;
674: }
675:
1.1.1.2 root 676: /* INTERCEPT_INSERVICE_A(0xfffa0f byte) */
1.1 root 677: void Intercept_InServiceA_ReadByte(void)
678: {
679: STRam[0xfffa0f] = MFP_ISRA;
680: }
681:
1.1.1.2 root 682: /* INTERCEPT_INSERVICE_B(0xfffa11 byte) */
1.1 root 683: void Intercept_InServiceB_ReadByte(void)
684: {
685: STRam[0xfffa11] = MFP_ISRB;
686: }
687:
1.1.1.2 root 688: /* INTERCEPT_MASK_A(0xfffa13 byte) */
1.1 root 689: void Intercept_MaskA_ReadByte(void)
690: {
691: STRam[0xfffa13] = MFP_IMRA;
692: }
693:
1.1.1.2 root 694: /* INTERCEPT_MASK_B(0xfffa15 byte) */
1.1 root 695: void Intercept_MaskB_ReadByte(void)
696: {
697: STRam[0xfffa15] = MFP_IMRB;
698: }
699:
1.1.1.2 root 700: /* INTERCEPT_VECTOR_REG(0xfffa17 byte) */
1.1 root 701: void Intercept_VectorReg_ReadByte(void)
702: {
703: STRam[0xfffa17] = MFP_VR;
704: }
705:
1.1.1.2 root 706: /* INTERCEPT_TIMERA_CTRL(0xfffa19 byte) */
1.1 root 707: void Intercept_TimerACtrl_ReadByte(void)
708: {
709: STRam[0xfffa19] = MFP_TACR;
710: }
711:
1.1.1.2 root 712: /* INTERCEPT_TIMERB_CTRL(0xfffa1b byte) */
1.1 root 713: void Intercept_TimerBCtrl_ReadByte(void)
714: {
715: STRam[0xfffa1b] = MFP_TBCR;
716: }
717:
1.1.1.2 root 718: /* INTERCEPT_TIMERCD_CTRL(0xfffa1d byte) */
1.1 root 719: void Intercept_TimerCDCtrl_ReadByte(void)
720: {
721: STRam[0xfffa1d] = MFP_TCDCR;
722: }
723:
1.1.1.2 root 724: /* INTERCEPT_TIMERA_DATA(0xfffa1f byte) */
1.1 root 725: void Intercept_TimerAData_ReadByte(void)
726: {
727: if( MFP_TACR != 8 ) /* Is event count? Need to re-calculate counter */
728: MFP_ReadTimerA(); /* Stores result in 'MFP_TA_MAINCOUNTER' */
729: STRam[0xfffa1f] = MFP_TA_MAINCOUNTER;
730: }
731:
1.1.1.2 root 732: /* INTERCEPT_TIMERB_DATA(0xfffa21 byte) */
1.1 root 733: void Intercept_TimerBData_ReadByte(void)
734: {
735: if(MFP_TBCR != 8) /* Is event count? Need to re-calculate counter */
1.1.1.2 root 736: MFP_ReadTimerB(); /* Stores result in 'MFP_TB_MAINCOUNTER' */
1.1 root 737: STRam[0xfffa21] = MFP_TB_MAINCOUNTER;
738: }
739:
1.1.1.2 root 740: /* INTERCEPT_TIMERC_DATA(0xfffa23 byte) */
1.1 root 741: void Intercept_TimerCData_ReadByte(void)
742: {
743: MFP_ReadTimerC(); /* Stores result in 'MFP_TC_MAINCOUNTER' */
744: STRam[0xfffa23] = MFP_TC_MAINCOUNTER;
745: }
746:
1.1.1.2 root 747: /* INTERCEPT_TIMERD_DATA(0xfffa25 byte) */
1.1 root 748: void Intercept_TimerDData_ReadByte(void)
749: {
1.1.1.7 ! root 750: Uint32 pc = m68k_getpc();
! 751:
! 752: if (ConfigureParams.System.bPatchTimerD && pc >= TosAddress && pc <= TosAddress + TosSize)
! 753: {
! 754: /* Trick the tos to believe it was changed: */
! 755: STRam[0xfffa25] = nTimerDFakeValue;
! 756: }
! 757: else
! 758: {
! 759: MFP_ReadTimerD(); /* Stores result in 'MFP_TD_MAINCOUNTER' */
! 760: STRam[0xfffa25] = MFP_TD_MAINCOUNTER;
! 761: }
1.1 root 762: }
763:
1.1.1.2 root 764: /* INTERCEPT_KEYBOARDCONTROL(0xfffc00 byte) */
1.1 root 765: void Intercept_KeyboardControl_ReadByte(void)
766: {
767: /* For our emulation send is immediate so acknowledge buffer is empty */
768: STRam[0xfffc00] = ACIAStatusRegister | ACIA_STATUS_REGISTER__TX_BUFFER_EMPTY;
769: }
770:
1.1.1.2 root 771: /* INTERCEPT_KEYBOARDDATA(0xfffc02 byte) */
1.1 root 772: void Intercept_KeyboardData_ReadByte(void)
773: {
774: STRam[0xfffc02] = IKBD_GetByteFromACIA(); /* Return our byte from keyboard processor */
775: }
776:
1.1.1.2 root 777: /* INTERCEPT_MIDICONTROL(0xfffc04 byte) */
1.1 root 778: void Intercept_MidiControl_ReadByte(void)
779: {
1.1.1.7 ! root 780: STRam[0xfffc04] = Midi_ReadControl();
1.1 root 781: }
782:
1.1.1.2 root 783: /* INTERCEPT_MIDIDATA(0xfffc06 byte) */
1.1 root 784: void Intercept_MidiData_ReadByte(void)
785: {
1.1.1.7 ! root 786: STRam[0xfffc06] = Midi_ReadData();
1.1 root 787: }
788:
789:
1.1.1.5 root 790: void Intercept_BlitterEndmask1_ReadWord(void)
791: {
792: STMemory_WriteWord( 0xff8a28, LOAD_W_ff8a28() );
793: }
794:
795: void Intercept_BlitterEndmask2_ReadWord(void)
796: {
797: STMemory_WriteWord( 0xff8a2a, LOAD_W_ff8a2a() );
798: }
799:
800: void Intercept_BlitterEndmask3_ReadWord(void)
801: {
802: STMemory_WriteWord( 0xff8a2c, LOAD_W_ff8a2c() );
803: }
804:
805: void Intercept_BlitterDst_ReadLong(void)
806: {
807: STMemory_WriteLong( 0xff8a32, LOAD_L_ff8a32() );
808: }
809:
810: void Intercept_BlitterWPL_ReadWord(void)
811: {
812: STMemory_WriteWord( 0xff8a36, LOAD_W_ff8a36() );
813: }
814:
815: void Intercept_BlitterLPB_ReadWord(void)
816: {
817: STMemory_WriteWord( 0xff8a38, LOAD_W_ff8a38() );
818: }
819:
820: void Intercept_BlitterHalftoneOp_ReadByte(void)
821: {
822: STMemory_WriteByte( 0xff8a3a, LOAD_B_ff8a3a() );
823: }
824:
825: void Intercept_BlitterLogOp_ReadByte(void)
826: {
827: STMemory_WriteByte( 0xff8a3b, LOAD_B_ff8a3b() );
828: }
829:
830: void Intercept_BlitterLineNum_ReadByte(void)
831: {
832: STMemory_WriteByte( 0xff8a3c, LOAD_B_ff8a3c() );
833: }
834:
835: void Intercept_BlitterSkew_ReadByte(void)
836: {
837: STMemory_WriteByte( 0xff8a3d, LOAD_B_ff8a3d() );
838: }
839:
1.1 root 840:
841:
1.1.1.2 root 842: /*-----------------------------------------------------------------------*/
843: /* Write to Hardware(0x00ff8000 to 0xffffff) */
1.1 root 844:
1.1.1.2 root 845: /* INTERCEPT_VIDEOHIGH(0xff8205 byte) */
1.1 root 846: void Intercept_VideoHigh_WriteByte(void)
847: {
1.1.1.2 root 848: /* Nothing... */
1.1 root 849: }
850:
1.1.1.2 root 851: /* INTERCEPT_VIDEOMED(0xff8207 byte) */
1.1 root 852: void Intercept_VideoMed_WriteByte(void)
853: {
1.1.1.2 root 854: /* Nothing... */
1.1 root 855: }
856:
1.1.1.2 root 857: /* INTERCEPT_VIDEOLOW(0xff8209 byte) */
1.1 root 858: void Intercept_VideoLow_WriteByte(void)
859: {
1.1.1.2 root 860: /* Nothing... */
1.1 root 861: }
862:
1.1.1.2 root 863: /* INTERCEPT_VIDEOSYNC(0xff820a byte) */
1.1 root 864: void Intercept_VideoSync_WriteByte(void)
865: {
1.1.1.7 ! root 866: /* Note: We're only interested in lower 2 bits (50/60Hz) */
! 867: Video_WriteToSync(STRam[0xff820a] & 3);
1.1 root 868: }
869:
1.1.1.2 root 870: /* INTERCEPT_VIDEOBASELOW(0xff820d byte) */
1.1 root 871: void Intercept_VideoBaseLow_WriteByte(void)
872: {
1.1.1.2 root 873: /* Nothing... */
1.1 root 874: }
875:
1.1.1.2 root 876: /* INTERCEPT_LINEWIDTH(0xff820f byte) */
1.1 root 877: void Intercept_LineWidth_WriteByte(void)
878: {
1.1.1.2 root 879: /* Nothing... */
1.1 root 880: }
881:
1.1.1.7 ! root 882: static void Intercept_Colour_WriteWord(Uint32 addr)
1.1 root 883: {
884: if( !bUseHighRes ) /* Don't store if hi-res */
885: {
886: unsigned short col;
887: Video_SetHBLPaletteMaskPointers(); /* Set 'pHBLPalettes' etc.. according cycles into frame */
888: col = STMemory_ReadWord( addr );
1.1.1.3 root 889: col &= 0x777; /* Mask off to 512 palette */
890: STMemory_WriteWord(addr, col); /* (some games write 0xFFFF and read back to see if STe) */
1.1 root 891: Spec512_StoreCyclePalette( col, addr ); /* Store colour into CyclePalettes[] */
892: pHBLPalettes[(addr-0xff8240)/2]=col; /* Set colour x */
893: *pHBLPaletteMasks |= 1 << ((addr-0xff8240)/2); /* And mask */
894: }
895: }
896:
1.1.1.2 root 897: /* INTERCEPT_COLOUR0(0xff8240 word) */
1.1 root 898: void Intercept_Colour0_WriteWord(void)
899: {
900: Intercept_Colour_WriteWord( 0xff8240 );
901: }
902:
1.1.1.2 root 903: /* INTERCEPT_COLOUR1(0xff8242 word) */
1.1 root 904: void Intercept_Colour1_WriteWord(void)
905: {
906: Intercept_Colour_WriteWord( 0xff8242 );
907: }
908:
1.1.1.2 root 909: /* INTERCEPT_COLOUR2(0xff8244 word) */
1.1 root 910: void Intercept_Colour2_WriteWord(void)
911: {
912: Intercept_Colour_WriteWord( 0xff8244 );
913: }
914:
1.1.1.2 root 915: /* INTERCEPT_COLOUR3(0xff8246 word) */
1.1 root 916: void Intercept_Colour3_WriteWord(void)
917: {
918: Intercept_Colour_WriteWord( 0xff8246 );
919: }
920:
1.1.1.2 root 921: /* INTERCEPT_COLOUR4(0xff8248 word) */
1.1 root 922: void Intercept_Colour4_WriteWord(void)
923: {
924: Intercept_Colour_WriteWord( 0xff8248 );
925: }
926:
1.1.1.2 root 927: /* INTERCEPT_COLOUR5(0xff824a word) */
1.1 root 928: void Intercept_Colour5_WriteWord(void)
929: {
930: Intercept_Colour_WriteWord( 0xff824a );
931: }
932:
1.1.1.2 root 933: /* INTERCEPT_COLOUR6(0xff824c word) */
1.1 root 934: void Intercept_Colour6_WriteWord(void)
935: {
936: Intercept_Colour_WriteWord( 0xff824c );
937: }
938:
1.1.1.2 root 939: /* INTERCEPT_COLOUR7(0xff824e word) */
1.1 root 940: void Intercept_Colour7_WriteWord(void)
941: {
942: Intercept_Colour_WriteWord( 0xff824e );
943: }
944:
1.1.1.2 root 945: /* INTERCEPT_COLOUR8(0xff8250 word) */
1.1 root 946: void Intercept_Colour8_WriteWord(void)
947: {
948: Intercept_Colour_WriteWord( 0xff8250 );
949: }
950:
1.1.1.2 root 951: /* INTERCEPT_COLOUR9(0xff8252 word) */
1.1 root 952: void Intercept_Colour9_WriteWord(void)
953: {
954: Intercept_Colour_WriteWord( 0xff8252 );
955: }
956:
1.1.1.2 root 957: /* INTERCEPT_COLOUR10(0xff8254 word) */
1.1 root 958: void Intercept_Colour10_WriteWord(void)
959: {
960: Intercept_Colour_WriteWord( 0xff8254 );
961: }
962:
1.1.1.2 root 963: /* INTERCEPT_COLOUR11(0xff8256 word) */
1.1 root 964: void Intercept_Colour11_WriteWord(void)
965: {
966: Intercept_Colour_WriteWord( 0xff8256 );
967: }
968:
1.1.1.2 root 969: /* INTERCEPT_COLOUR12(0xff8258 word) */
1.1 root 970: void Intercept_Colour12_WriteWord(void)
971: {
972: Intercept_Colour_WriteWord( 0xff8258 );
973: }
974:
1.1.1.2 root 975: /* INTERCEPT_COLOUR13(0xff825a word) */
1.1 root 976: void Intercept_Colour13_WriteWord(void)
977: {
978: Intercept_Colour_WriteWord( 0xff825a );
979: }
980:
1.1.1.2 root 981: /* INTERCEPT_COLOUR14(0xff825c word) */
1.1 root 982: void Intercept_Colour14_WriteWord(void)
983: {
984: Intercept_Colour_WriteWord( 0xff825c );
985: }
986:
1.1.1.2 root 987: /* INTERCEPT_COLOUR15(0xff825e word) */
1.1 root 988: void Intercept_Colour15_WriteWord(void)
989: {
990: Intercept_Colour_WriteWord( 0xff825e );
991: }
992:
1.1.1.2 root 993: /* INTERCEPT_SHIFTERMODE(0xff8260 byte) */
1.1 root 994: void Intercept_ShifterMode_WriteByte(void)
995: {
996: if( !bUseHighRes && !bUseVDIRes ) /* Don't store if hi-res and don't store if VDI resolution */
997: {
998: VideoShifterByte = STRam[0xff8260] & 3; /* We only care for lower 2-bits */
1.1.1.7 ! root 999: Video_WriteToShifter(VideoShifterByte);
1.1 root 1000: Video_SetHBLPaletteMaskPointers();
1.1.1.3 root 1001: *pHBLPaletteMasks &= 0xff00ffff;
1002: /* Store resolution after palette mask and set resolution write bit: */
1003: *pHBLPaletteMasks |= (((unsigned long)VideoShifterByte|0x04)<<16);
1.1 root 1004: }
1005: }
1006:
1.1.1.2 root 1007: /* INTERCEPT_DISKCONTROL(0xff8604 word) */
1.1 root 1008: void Intercept_DiskControl_WriteWord(void)
1009: {
1010: FDC_WriteDiscController( STMemory_ReadWord(0xff8604) );
1011: }
1012:
1.1.1.2 root 1013: /* INTERCEPT_DMASTATUS(0xff8606 word) */
1.1 root 1014: void Intercept_DmaStatus_WriteWord(void)
1015: {
1016: FDC_WriteDMAModeControl( STMemory_ReadWord(0xff8606) );
1017: }
1018:
1.1.1.2 root 1019: /* INTERCEPT_PSG_REGISTER(0xff8800 byte) */
1.1 root 1020: void Intercept_PSGRegister_WriteByte(void)
1021: {
1.1.1.7 ! root 1022: PSG_WriteSelectRegister( STRam[0xff8800] );
! 1023: M68000_WaitState();
1.1 root 1024: }
1025:
1.1.1.2 root 1026: /* INTERCEPT_PSG_DATA(0xff8802 byte) */
1.1 root 1027: void Intercept_PSGData_WriteByte(void)
1028: {
1.1.1.7 ! root 1029: PSG_WriteDataRegister( STRam[0xff8802] );
! 1030: M68000_WaitState();
1.1 root 1031: }
1032:
1.1.1.2 root 1033: /* INTERCEPT_MICROWIREDATA(0xff8922 word) */
1.1 root 1034: void Intercept_MicrowireData_WriteWord(void)
1035: {
1.1.1.2 root 1036: /* Nothing... */
1.1 root 1037: }
1038:
1.1.1.2 root 1039: /* INTERCEPT_MONITOR(0xfffa01 byte) */
1.1 root 1040: void Intercept_Monitor_WriteByte(void)
1041: {
1.1.1.2 root 1042: /* Nothing... */
1.1 root 1043: }
1044:
1.1.1.2 root 1045: /* INTERCEPT_ACTIVE_EDGE(0xfffa03 byte) */
1.1 root 1046: void Intercept_ActiveEdge_WriteByte(void)
1047: {
1048: MFP_AER = STRam[0xfffa03];
1049: }
1050:
1.1.1.2 root 1051: /* INTERCEPT_DATA_DIRECTION(0xfffa05 byte) */
1.1 root 1052: void Intercept_DataDirection_WriteByte(void)
1053: {
1054: MFP_DDR = STRam[0xfffa05];
1055: }
1056:
1057:
1.1.1.2 root 1058: /* INTERCEPT_ENABLE_A(0xfffa07 byte) */
1.1 root 1059: void Intercept_EnableA_WriteByte(void)
1060: {
1061: MFP_IERA = STRam[0xfffa07];
1062: MFP_IPRA &= MFP_IERA;
1063: MFP_UpdateFlags();
1064: /* We may have enabled Timer A or B, check */
1065: MFP_StartTimerA();
1066: MFP_StartTimerB();
1067: }
1068:
1.1.1.2 root 1069: /* INTERCEPT_ENABLE_B(0xfffa09 byte) */
1.1 root 1070: void Intercept_EnableB_WriteByte(void)
1071: {
1072: MFP_IERB = STRam[0xfffa09];
1073: MFP_IPRB &= MFP_IERB;
1074: MFP_UpdateFlags();
1075: /* We may have enabled Timer C or D, check */
1076: MFP_StartTimerC();
1077: MFP_StartTimerD();
1078: }
1079:
1.1.1.2 root 1080: /* INTERCEPT_PENDING_A(0xfffa0b byte) */
1.1 root 1081: void Intercept_PendingA_WriteByte(void)
1082: {
1083: MFP_IPRA &= STRam[0xfffa0b]; /* Cannot set pending bits - only clear via software */
1084: MFP_UpdateFlags(); /* Check if any interrupts pending */
1085: }
1086:
1.1.1.2 root 1087: /* INTERCEPT_PENDING_B(0xfffa0d byte) */
1.1 root 1088: void Intercept_PendingB_WriteByte(void)
1089: {
1090: MFP_IPRB &= STRam[0xfffa0d];
1091: MFP_UpdateFlags(); /* Check if any interrupts pending */
1092: }
1093:
1.1.1.2 root 1094: /* INTERCEPT_INSERVICE_A(0xfffa0f byte) */
1.1 root 1095: void Intercept_InServiceA_WriteByte(void)
1096: {
1097: MFP_ISRA &= STRam[0xfffa0f]; /* Cannot set in-service bits - only clear via software */
1098: }
1099:
1.1.1.2 root 1100: /* INTERCEPT_INSERVICE_B(0xfffa11 byte) */
1.1 root 1101: void Intercept_InServiceB_WriteByte(void)
1102: {
1103: MFP_ISRB &= STRam[0xfffa11]; /* Cannot set in-service bits - only clear via software */
1104: }
1105:
1.1.1.2 root 1106: /* INTERCEPT_MASK_A(0xfffa13 byte) */
1.1 root 1107: void Intercept_MaskA_WriteByte(void)
1108: {
1109: MFP_IMRA = STRam[0xfffa13];
1110: }
1111:
1.1.1.2 root 1112: /* INTERCEPT_MASK_B(0xfffa15 byte) */
1.1 root 1113: void Intercept_MaskB_WriteByte(void)
1114: {
1115: MFP_IMRB = STRam[0xfffa15];
1116: }
1117:
1.1.1.2 root 1118: /* INTERCEPT_VECTOR_REG(0xfffa17 byte) */
1.1 root 1119: void Intercept_VectorReg_WriteByte(void)
1120: {
1121: unsigned short old_vr;
1122: old_vr = MFP_VR; /* Copy for checking if set mode */
1123: MFP_VR = STRam[0xfffa17];
1124: if( (MFP_VR^old_vr)&0x08 ) /* Test change in end-of-interrupt mode */
1125: if( MFP_VR&0x08 ) /* Mode did change but was it to automatic mode? (ie bit is a zero) */
1126: { /* We are now in automatic mode, so clear all in-service bits! */
1127: MFP_ISRA = 0;
1128: MFP_ISRB = 0;
1129: }
1130: }
1131:
1.1.1.2 root 1132: /* INTERCEPT_TIMERA_CTRL(0xfffa19 byte) */
1.1 root 1133: void Intercept_TimerACtrl_WriteByte(void)
1134: {
1135: unsigned short old_tacr;
1136: old_tacr = MFP_TACR; /* Remember old control state */
1137: MFP_TACR = STRam[0xfffa19] & 0x0f; /* Mask, Fish(auto160) writes into top nibble! */
1138: if( (MFP_TACR^old_tacr)&0x0f ) /* Check if Timer A control changed */
1139: MFP_StartTimerA(); /* Reset timers if need to */
1140: }
1141:
1.1.1.2 root 1142: /* INTERCEPT_TIMERB_CTRL(0xfffa1b byte) */
1.1 root 1143: void Intercept_TimerBCtrl_WriteByte(void)
1144: {
1145: unsigned short old_tbcr;
1146: old_tbcr = MFP_TBCR; /* Remember old control state */
1147: MFP_TBCR = STRam[0xfffa1b] & 0x0f; /* Mask, Fish(auto160) writes into top nibble! */
1148: if( (MFP_TBCR^old_tbcr)&0x0f ) /* Check if Timer B control changed */
1149: MFP_StartTimerB(); /* Reset timers if need to */
1150: }
1151:
1.1.1.2 root 1152: /* INTERCEPT_TIMERCD_CTRL(0xfffa1d byte) */
1.1 root 1153: void Intercept_TimerCDCtrl_WriteByte(void)
1154: {
1.1.1.7 ! root 1155: unsigned short old_tcdcr;
1.1.1.6 root 1156:
1.1.1.7 ! root 1157: old_tcdcr = MFP_TCDCR; /* Remember old control state */
! 1158: MFP_TCDCR = STRam[0xfffa1d]; /* Store new one */
! 1159:
! 1160: if ((MFP_TCDCR^old_tcdcr) & 0x70) /* Check if Timer C control changed */
! 1161: MFP_StartTimerC(); /* Reset timers if need to */
! 1162:
! 1163: if ((MFP_TCDCR^old_tcdcr) & 0x07) /* Check if Timer D control changed */
! 1164: {
! 1165: Uint32 pc = m68k_getpc();
! 1166:
! 1167: /* Need to change baud rate of RS232 emulation? */
! 1168: if (ConfigureParams.RS232.bEnableRS232)
! 1169: {
! 1170: RS232_SetBaudRateFromTimerD();
! 1171: }
! 1172:
! 1173: if (ConfigureParams.System.bPatchTimerD && !bAppliedTimerDPatch
! 1174: && pc >= TosAddress && pc <= TosAddress + TosSize)
! 1175: {
! 1176: /* Slow down Timer-D if set from TOS for the first time to gain more
! 1177: * desktop performance.
! 1178: * Obviously, we need to emulate all timers correctly but TOS sets up
! 1179: * Timer-D at a very high rate (every couple of instructions). The
! 1180: * interrupt isn't enabled but the emulator still needs to process the
! 1181: * interrupt table and this HALVES our frame rate!!!
! 1182: * Some games actually reference this timer but don't set it up
! 1183: * (eg Paradroid, Speedball I) so we simply intercept the Timer-D setup
! 1184: * code in TOS and fix the numbers with more 'laid-back' values.
! 1185: * This still keeps 100% compatibility */
! 1186: MFP_TCDCR = STRam[0xfffa1d] = (STRam[0xfffa1d] & 0xf0) | 7;
! 1187: bAppliedTimerDPatch = TRUE;
! 1188: }
! 1189: MFP_StartTimerD(); /* Reset timers if need to */
! 1190: }
1.1 root 1191: }
1192:
1.1.1.2 root 1193: /* INTERCEPT_TIMERA_DATA(0xfffa1f byte) */
1.1 root 1194: void Intercept_TimerAData_WriteByte(void)
1195: {
1196: MFP_TADR = STRam[0xfffa1f]; /* Store into data register */
1197: if( MFP_TACR==0 ) /* Now check if timer is running - if so do not set */
1198: {
1199: MFP_TA_MAINCOUNTER = MFP_TADR; /* Timer is off, store to main counter */
1200: MFP_StartTimerA(); /* Add our interrupt */
1201: }
1202: }
1203:
1.1.1.2 root 1204: /* INTERCEPT_TIMERB_DATA(0xfffa21 byte) */
1.1 root 1205: void Intercept_TimerBData_WriteByte(void)
1206: {
1207: MFP_TBDR = STRam[0xfffa21]; /* Store into data register */
1208: if( MFP_TBCR==0 ) /* Now check if timer is running - if so do not set */
1209: {
1210: MFP_TB_MAINCOUNTER = MFP_TBDR; /* Timer is off, store to main counter */
1211: MFP_StartTimerB(); /* Add our interrupt */
1212: }
1213: }
1214:
1.1.1.2 root 1215: /* INTERCEPT_TIMERC_DATA(0xfffa23 byte) */
1.1 root 1216: void Intercept_TimerCData_WriteByte(void)
1217: {
1218: MFP_TCDR = STRam[0xfffa23]; /* Store into data register */
1219: if( (MFP_TCDCR&0x70)==0 ) /* Now check if timer is running - if so do not set */
1220: {
1221: MFP_StartTimerC(); /* Add our interrupt */
1222: }
1223: }
1224:
1.1.1.2 root 1225: /* INTERCEPT_TIMERD_DATA(0xfffa25 byte) */
1.1 root 1226: void Intercept_TimerDData_WriteByte(void)
1227: {
1.1.1.7 ! root 1228: Uint32 pc = m68k_getpc();
! 1229:
! 1230: /* Need to change baud rate of RS232 emulation? */
! 1231: if (ConfigureParams.RS232.bEnableRS232 && (STRam[0xfffa1d] & 0x07))
! 1232: {
! 1233: RS232_SetBaudRateFromTimerD();
! 1234: }
! 1235:
! 1236: /* Patch Timer-D for better performance? */
! 1237: if (ConfigureParams.System.bPatchTimerD && pc >= TosAddress && pc <= TosAddress + TosSize)
! 1238: {
! 1239: nTimerDFakeValue = STRam[0xfffa25];
! 1240: STRam[0xfffa25] = 0x64; /* Slow down the useless Timer-D setup from the bios */
! 1241: }
1.1.1.6 root 1242:
1.1.1.7 ! root 1243: MFP_TDDR = STRam[0xfffa25]; /* Store into data register */
! 1244: if ((MFP_TCDCR&0x07) == 0) /* Now check if timer is running - if so do not set */
1.1 root 1245: {
1.1.1.7 ! root 1246: MFP_StartTimerD(); /* Add our interrupt */
1.1 root 1247: }
1248: }
1249:
1.1.1.2 root 1250: /* INTERCEPT_KEYBOARDCONTROL(0xfffc00 byte) */
1.1 root 1251: void Intercept_KeyboardControl_WriteByte(void)
1252: {
1253: /* Nothing... */
1254: }
1255:
1.1.1.2 root 1256: /* INTERCEPT_KEYBOARDDATA(0xfffc02 byte) */
1.1 root 1257: void Intercept_KeyboardData_WriteByte(void)
1258: {
1259: IKBD_SendByteToKeyboardProcessor( STRam[0xfffc02] ); /* Pass our byte to the keyboard processor */
1260: }
1261:
1.1.1.2 root 1262: /* INTERCEPT_MIDICONTROL(0xfffc04 byte) */
1.1 root 1263: void Intercept_MidiControl_WriteByte(void)
1264: {
1.1.1.7 ! root 1265: Midi_WriteControl(STRam[0xfffc04]);
1.1 root 1266: }
1267:
1.1.1.2 root 1268: /* INTERCEPT_MIDIDATA(0xfffc06 byte) */
1.1 root 1269: void Intercept_MidiData_WriteByte(void)
1270: {
1.1.1.7 ! root 1271: Midi_WriteData(STRam[0xfffc06]);
1.1 root 1272: }
1273:
1274:
1.1.1.5 root 1275: void Intercept_BlitterEndmask1_WriteWord(void)
1276: {
1277: STORE_W_ff8a28( STMemory_ReadWord(0xff8a28) );
1278: }
1279:
1280: void Intercept_BlitterEndmask2_WriteWord(void)
1281: {
1282: STORE_W_ff8a2a( STMemory_ReadWord(0xff8a2a) );
1283: }
1284:
1285: void Intercept_BlitterEndmask3_WriteWord(void)
1286: {
1287: STORE_W_ff8a2c( STMemory_ReadWord(0xff8a2c) );
1288: }
1289:
1290: void Intercept_BlitterDst_WriteLong(void)
1291: {
1292: STORE_L_ff8a32( STMemory_ReadLong(0xff8a32) );
1293: }
1294:
1295: void Intercept_BlitterWPL_WriteWord(void)
1296: {
1297: STORE_W_ff8a36( STMemory_ReadWord(0xff8a36) );
1298: }
1299:
1300: void Intercept_BlitterLPB_WriteWord(void)
1301: {
1302: STORE_W_ff8a38( STMemory_ReadWord(0xff8a38) );
1303: }
1304:
1305: void Intercept_BlitterHalftoneOp_WriteByte(void)
1306: {
1307: STORE_B_ff8a3a( STMemory_ReadByte(0xff8a3a) );
1308: }
1309:
1310: void Intercept_BlitterLogOp_WriteByte(void)
1311: {
1312: STORE_B_ff8a3b( STMemory_ReadByte(0xff8a3b) );
1313: }
1314:
1315: void Intercept_BlitterLineNum_WriteByte(void)
1316: {
1317: STORE_B_ff8a3c( STMemory_ReadByte(0xff8a3c) );
1318: }
1319:
1320: void Intercept_BlitterSkew_WriteByte(void)
1321: {
1322: STORE_B_ff8a3d( STMemory_ReadByte(0xff8a3d) );
1323: }
1324:
1325:
1326:
1.1.1.2 root 1327:
1328: /* Address space for Bus Error in hardware mapping */
1.1.1.5 root 1329: INTERCEPT_ADDRESSRANGE InterceptBusErrors[] =
1330: {
1331: { 0xff8002,0xff8200 },
1332: { 0xff8210,0xff823e },
1333: { 0xff8280,0xff8600 }, /* Falcon VIDEL, TT Palette */
1334: { 0xff8900,0xff89fe }, /* DMA Sound/MicroWire */
1335: { 0xff8a00,0xff8a3e }, /* Blitter (now supported, but disabled by default) */
1336: { 0xff8a40,0xff8e00 },
1337: { 0xff8e10,0xfff9fe },
1338: { 0xfffa40,0xfffbfe }, /* Mega-STE FPU and 2nd (TT) MFP */
1.1.1.6 root 1339: { 0xfffe00,0xffffff },
1.1 root 1340:
1.1.1.5 root 1341: { 0,0 } /* term */
1.1 root 1342: };
1343:
1344:
1.1.1.2 root 1345: /*-------------------------------------------------------------------------*/
1346: /*
1347: Jump to the BusError handler with the correct bus address
1348: */
1.1.1.7 ! root 1349: static void Intercept_BusErrorReadAccess(void)
1.1.1.2 root 1350: {
1.1.1.7 ! root 1351: M68000_BusError(BusAddressLocation, 1);
! 1352: }
! 1353:
! 1354: static void Intercept_BusErrorWriteAccess(void)
! 1355: {
! 1356: M68000_BusError(BusAddressLocation, 0);
1.1.1.2 root 1357: }
1358:
1.1 root 1359:
1360: /*-------------------------------------------------------------------------*/
1361: /*
1362: Modify 'intercept' tables to cause Bus Errors on addres to un-mapped
1363: hardware space (Wing Of Death addresses Blitter space which causes
1364: BusError on STfm)
1365: */
1366: void Intercept_ModifyTablesForBusErrors(void)
1367: {
1.1.1.7 ! root 1368: unsigned long *pInterceptListRead, *pInterceptListWrite;
1.1 root 1369: unsigned int Address;
1.1.1.5 root 1370: int i;
1.1 root 1371:
1.1.1.2 root 1372: /* Set routine list */
1.1.1.7 ! root 1373: pInterceptListRead = pCurrentInterceptWorkspace;
! 1374: *pCurrentInterceptWorkspace++ = (unsigned long)Intercept_BusErrorReadAccess;
! 1375: *pCurrentInterceptWorkspace++ = 0L;
! 1376:
! 1377: pInterceptListWrite = pCurrentInterceptWorkspace;
! 1378: *pCurrentInterceptWorkspace++ = (unsigned long)Intercept_BusErrorWriteAccess;
1.1 root 1379: *pCurrentInterceptWorkspace++ = 0L;
1380:
1.1.1.5 root 1381: /* Set all bus-error entries */
1382: for(i=0; InterceptBusErrors[i].Start_Address!=0; i++)
1383: {
1384: if(bEnableBlitter && InterceptBusErrors[i].Start_Address==0xff8a00)
1385: continue; /* Ignore blitter area if blitter is enabled */
1386: /* Set bus-error table */
1387: for(Address=InterceptBusErrors[i].Start_Address; Address<InterceptBusErrors[i].End_Address; Address++)
1388: {
1.1.1.2 root 1389: /* For 'read' */
1.1.1.7 ! root 1390: pInterceptReadByteTable[Address-0xff8000] = pInterceptListRead;
! 1391: pInterceptReadWordTable[Address-0xff8000] = pInterceptListRead;
! 1392: pInterceptReadLongTable[Address-0xff8000] = pInterceptListRead;
1.1.1.2 root 1393: /* and 'write' */
1.1.1.7 ! root 1394: pInterceptWriteByteTable[Address-0xff8000] = pInterceptListWrite;
! 1395: pInterceptWriteWordTable[Address-0xff8000] = pInterceptListWrite;
! 1396: pInterceptWriteLongTable[Address-0xff8000] = pInterceptListWrite;
1.1 root 1397: }
1398:
1399: }
1400: }
1401:
1.1.1.2 root 1402:
1403:
1.1 root 1404: #ifdef CHECK_FOR_NO_MANS_LAND
1405:
1.1.1.2 root 1406: /*-----------------------------------------------------------------------*/
1.1 root 1407: /*
1.1.1.2 root 1408: Intercept function used on all non-documented hardware registers.
1409: Used to help debugging
1.1 root 1410: */
1411: void Intercept_NoMansLand_ReadWrite(void)
1412: {
1.1.1.2 root 1413: fprintf(stderr,"NoMansLand_ReadWrite at address $%lx , PC=$%lx\n",
1.1.1.6 root 1414: (long)BusAddressLocation, (long)m68k_getpc());
1.1 root 1415: }
1416:
1.1.1.5 root 1417: /*-----------------------------------------------------------------------*/
1.1 root 1418: /*
1.1.1.6 root 1419: Modify 'intercept' tables to check for access into 'no-mans-land',
1420: i.e. unknown hardware locations.
1421: We fill the whole IO memory address space first with the no-mans-land handler
1422: and overwrite it later in Intercept_Init with the real handlers.
1.1 root 1423: */
1424: void Intercept_ModifyTablesForNoMansLand(void)
1425: {
1426: unsigned int Address;
1427:
1.1.1.2 root 1428: /* Set all 'no-mans-land' entries */
1.1.1.6 root 1429: for(Address = 0xff8000; Address < 0xffffff; Address++)
1430: {
1431: /* For 'read' */
1432: pInterceptReadByteTable[Address-0xff8000] = noMansLandWorkspace;
1433: pInterceptReadWordTable[Address-0xff8000] = noMansLandWorkspace;
1434: pInterceptReadLongTable[Address-0xff8000] = noMansLandWorkspace;
1435: /* and 'write' */
1436: pInterceptWriteByteTable[Address-0xff8000] = noMansLandWorkspace;
1437: pInterceptWriteWordTable[Address-0xff8000] = noMansLandWorkspace;
1438: pInterceptWriteLongTable[Address-0xff8000] = noMansLandWorkspace;
1.1 root 1439: }
1440: }
1441:
1.1.1.2 root 1442: #endif /*CHECK_FOR_NO_MANS_LAND*/
1.1 root 1443:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.