Annotation of hatari/src/intercept.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.