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

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

unix.superglobalmegacorp.com

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