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