Annotation of hatari/src/ioMem.c, revision 1.1

1.1     ! root        1: /*
        !             2:   Hatari - ioMem.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.
        !             6: 
        !             7:   This is where we intercept read/writes to/from the hardware. The ST's memory
        !             8:   is nicely split into four main parts - the bottom area of RAM is for user
        !             9:   programs. This is followed by a large area which causes a Bus Error. After
        !            10:   this is the ROM addresses for TOS and finally an area for hardware mapping.
        !            11:   To gain speed any address in the user area can simply read/write, but anything
        !            12:   above this range needs to be checked for validity and sent to the various
        !            13:   handlers.
        !            14:   A big problem for ST emulation is the use of the hardware registers. These
        !            15:   often consist of an 'odd' byte in memory and is usually addressed as a single
        !            16:   byte. A number of applications, however, write to the address using a word or
        !            17:   even long word. So we have a list of handlers that take care of each address
        !            18:   that has to be intercepted. Eg, a long write to a PSG register (which access
        !            19:   two registers) will write the long into IO memory space and then call the two
        !            20:   handlers which read off the bytes for each register.
        !            21:   This means that any access to any hardware register in such a way will work
        !            22:   correctly - it certainly fixes a lot of bugs and means writing just one
        !            23:   routine for each hardware register we mean to intercept! Phew!
        !            24:   You have also to take into consideration that some hardware registers are
        !            25:   bigger than 1 byte (there are also word and longword registers) and that
        !            26:   a lot of addresses in between can cause a bus error - so it's not so easy
        !            27:   to cope with all type of handlers in a straight forward way.
        !            28:   Also note the 'mirror' (or shadow) registers of the PSG - this is used by most
        !            29:   games.
        !            30: */
        !            31: char IoMem_rcsid[] = "Hatari $Id: ioMem.c,v 1.8 2005/04/05 14:41:27 thothy Exp $";
        !            32: 
        !            33: #include "main.h"
        !            34: #include "configuration.h"
        !            35: #include "ioMem.h"
        !            36: #include "ioMemTables.h"
        !            37: #include "m68000.h"
        !            38: #include "uae-cpu/sysdeps.h"
        !            39: 
        !            40: 
        !            41: #define IOMEM_DEBUG 0
        !            42: 
        !            43: #if IOMEM_DEBUG
        !            44: #define Dprintf(a) printf a
        !            45: #else
        !            46: #define Dprintf(a)
        !            47: #endif
        !            48: 
        !            49: 
        !            50: 
        !            51: static void (*pInterceptReadTable[0x8000])(void);     /* Table with read access handlers */
        !            52: static void (*pInterceptWriteTable[0x8000])(void);    /* Table with write access handlers */
        !            53: 
        !            54: int nIoMemAccessSize;                                 /* Set to 1, 2 or 4 according to byte, word or long word access */
        !            55: Uint32 IoAccessBaseAddress;                           /* Stores the base address of the IO mem access */
        !            56: Uint32 IoAccessCurrentAddress;                        /* Current byte address while handling WORD and LONG accesses */
        !            57: static int nBusErrorAccesses;                         /* Needed to count bus error accesses */
        !            58: 
        !            59: 
        !            60: /*-----------------------------------------------------------------------*/
        !            61: /*
        !            62:   Fill a region with bus error handlers.
        !            63: */
        !            64: static void IoMem_SetBusErrorRegion(Uint32 startaddr, Uint32 endaddr)
        !            65: {
        !            66:        Uint32 a;
        !            67: 
        !            68:        for (a = startaddr; a <= endaddr; a++)
        !            69:        {
        !            70:                if (a & 1)
        !            71:                {
        !            72:                        pInterceptReadTable[a - 0xff8000] = IoMem_BusErrorOddReadAccess;     /* For 'read' */
        !            73:                        pInterceptWriteTable[a - 0xff8000] = IoMem_BusErrorOddWriteAccess;   /* and 'write' */
        !            74:                }
        !            75:                else
        !            76:                {
        !            77:                        pInterceptReadTable[a - 0xff8000] = IoMem_BusErrorEvenReadAccess;    /* For 'read' */
        !            78:                        pInterceptWriteTable[a - 0xff8000] = IoMem_BusErrorEvenWriteAccess;  /* and 'write' */
        !            79:                }
        !            80:        }
        !            81: }
        !            82: 
        !            83: 
        !            84: /*-----------------------------------------------------------------------*/
        !            85: /*
        !            86:   Create 'intercept' tables for hardware address access. Each 'intercept
        !            87:   table is a list of 0x8000 pointers to a list of functions to call when
        !            88:   that location in the ST's memory is accessed. 
        !            89: */
        !            90: void IoMem_Init(void)
        !            91: {
        !            92:        Uint32 addr;
        !            93:        int i;
        !            94:        INTERCEPT_ACCESS_FUNC *pInterceptAccessFuncs = NULL;
        !            95: 
        !            96:        /* Set default IO access handler (-> bus error) */
        !            97:        IoMem_SetBusErrorRegion(0xff8000, 0xffffff);
        !            98: 
        !            99:        switch (ConfigureParams.System.nMachineType)
        !           100:        {
        !           101:                case MACHINE_ST:  pInterceptAccessFuncs = IoMemTable_ST; break;
        !           102:                case MACHINE_STE: pInterceptAccessFuncs = IoMemTable_STE; break;
        !           103:        }
        !           104: 
        !           105:        /* Now set the correct handlers */
        !           106:        for (addr=0xff8000; addr <= 0xffffff; addr++)
        !           107:        {
        !           108:                /* Does this hardware location/span appear in our list of possible intercepted functions? */
        !           109:                for (i=0; pInterceptAccessFuncs[i].Address != 0; i++)
        !           110:                {
        !           111:                        if (addr >= pInterceptAccessFuncs[i].Address
        !           112:                            && addr < pInterceptAccessFuncs[i].Address+pInterceptAccessFuncs[i].SpanInBytes)
        !           113:                        {
        !           114:                                /* Security checks... */
        !           115:                                if (pInterceptReadTable[addr-0xff8000] != IoMem_BusErrorEvenReadAccess && pInterceptReadTable[addr-0xff8000] != IoMem_BusErrorOddReadAccess)
        !           116:                                        fprintf(stderr, "IoMem_Init: Warning: $%x (R) already defined\n", addr);
        !           117:                                if (pInterceptWriteTable[addr-0xff8000] != IoMem_BusErrorEvenWriteAccess && pInterceptWriteTable[addr-0xff8000] != IoMem_BusErrorOddWriteAccess)
        !           118:                                        fprintf(stderr, "IoMem_Init: Warning: $%x (W) already defined\n", addr);
        !           119: 
        !           120:                                /* This location needs to be intercepted, so add entry to list */
        !           121:                                pInterceptReadTable[addr-0xff8000] = pInterceptAccessFuncs[i].ReadFunc;
        !           122:                                pInterceptWriteTable[addr-0xff8000] = pInterceptAccessFuncs[i].WriteFunc;
        !           123:                        }
        !           124:                }
        !           125:        }
        !           126: 
        !           127:        /* Disable blitter? */
        !           128:        if (!ConfigureParams.System.bBlitter && ConfigureParams.System.nMachineType == MACHINE_ST)
        !           129:        {
        !           130:                IoMem_SetBusErrorRegion(0xff8a00, 0xff8a3f);
        !           131:        }
        !           132: 
        !           133:        /* Disable real time clock? */
        !           134:        if (!ConfigureParams.System.bRealTimeClock)
        !           135:        {
        !           136:                for (addr = 0xfffc21; addr  <= 0xfffc3f; addr++)
        !           137:                {
        !           138:                        pInterceptReadTable[addr - 0xff8000] = IoMem_VoidRead;     /* For 'read' */
        !           139:                        pInterceptWriteTable[addr - 0xff8000] = IoMem_VoidWrite;   /* and 'write' */
        !           140:                }
        !           141:        
        !           142:        }
        !           143: }
        !           144: 
        !           145: 
        !           146: /*-----------------------------------------------------------------------*/
        !           147: /*
        !           148:   Uninitialize the IoMem code (currently unused).
        !           149: */
        !           150: void IoMem_UnInit(void)
        !           151: {
        !           152: }
        !           153: 
        !           154: 
        !           155: /*-----------------------------------------------------------------------*/
        !           156: /*
        !           157:   Check if need to change our address as maybe a mirror register.
        !           158:   Currently we only have a PSG mirror area.
        !           159: */
        !           160: static Uint32 IoMem_CheckMirrorAddresses(Uint32 addr)
        !           161: {
        !           162:        if (addr>=0xff8800 && addr<0xff8900)    /* Is a PSG mirror registers? */
        !           163:                addr = 0xff8800 + (addr & 3);       /* Bring into 0xff8800-0xff8804 range */
        !           164: 
        !           165:        return addr;
        !           166: }
        !           167: 
        !           168: 
        !           169: 
        !           170: /*-----------------------------------------------------------------------*/
        !           171: /*
        !           172:   Handle byte read access from IO memory.
        !           173: */
        !           174: uae_u32 IoMem_bget(uaecptr addr)
        !           175: {
        !           176:        Dprintf(("IoMem_bget($%x)\n", addr));
        !           177: 
        !           178:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
        !           179: 
        !           180:        if (addr < 0xff8000)
        !           181:        {
        !           182:                /* invalid memory addressing --> bus error */
        !           183:                M68000_BusError(addr, 1);
        !           184:                return -1;
        !           185:        }
        !           186: 
        !           187:        IoAccessBaseAddress = addr;                   /* Store access location */
        !           188:        nIoMemAccessSize = SIZE_BYTE;
        !           189:        nBusErrorAccesses = 0;
        !           190:        addr = IoMem_CheckMirrorAddresses(addr);
        !           191: 
        !           192:        IoAccessCurrentAddress = addr;
        !           193:        pInterceptReadTable[addr-0xff8000]();         /* Call handler */
        !           194: 
        !           195:        /* Check if we read from a bus-error region */
        !           196:        if (nBusErrorAccesses == 1)
        !           197:        {
        !           198:                M68000_BusError(addr, 1);
        !           199:                return -1;
        !           200:        }
        !           201: 
        !           202:        return IoMem[addr];
        !           203: }
        !           204: 
        !           205: 
        !           206: /*-----------------------------------------------------------------------*/
        !           207: /*
        !           208:   Handle word read access from IO memory.
        !           209: */
        !           210: uae_u32 IoMem_wget(uaecptr addr)
        !           211: {
        !           212:        Uint32 idx;
        !           213: 
        !           214:        Dprintf(("IoMem_wget($%x)\n", addr));
        !           215: 
        !           216:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
        !           217: 
        !           218:        if (addr < 0xff8000)
        !           219:        {
        !           220:                /* invalid memory addressing --> bus error */
        !           221:                M68000_BusError(addr, 1);
        !           222:                return -1;
        !           223:        }
        !           224:        if (addr > 0xfffffe)
        !           225:        {
        !           226:                fprintf(stderr, "Illegal IO memory access: IoMem_wget($%x)\n", addr);
        !           227:                return -1;
        !           228:        }
        !           229: 
        !           230:        IoAccessBaseAddress = addr;                   /* Store for exception frame */
        !           231:        nIoMemAccessSize = SIZE_WORD;
        !           232:        nBusErrorAccesses = 0;
        !           233:        addr = IoMem_CheckMirrorAddresses(addr);
        !           234:        idx = addr - 0xff8000;
        !           235: 
        !           236:        IoAccessCurrentAddress = addr;
        !           237:        pInterceptReadTable[idx]();                   /* Call 1st handler */
        !           238: 
        !           239:        if (pInterceptReadTable[idx+1] != pInterceptReadTable[idx])
        !           240:        {
        !           241:                IoAccessCurrentAddress = addr + 1;
        !           242:                pInterceptReadTable[idx+1]();             /* Call 2nd handler */
        !           243:        }
        !           244: 
        !           245:        /* Check if we completely read from a bus-error region */
        !           246:        if (nBusErrorAccesses == 2)
        !           247:        {
        !           248:                M68000_BusError(addr, 1);
        !           249:                return -1;
        !           250:        }
        !           251: 
        !           252:        return IoMem_ReadWord(addr);
        !           253: }
        !           254: 
        !           255: 
        !           256: /*-----------------------------------------------------------------------*/
        !           257: /*
        !           258:   Handle long-word read access from IO memory.
        !           259: */
        !           260: uae_u32 IoMem_lget(uaecptr addr)
        !           261: {
        !           262:        Uint32 idx;
        !           263: 
        !           264:        Dprintf(("IoMem_lget($%x)\n", addr));
        !           265: 
        !           266:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
        !           267: 
        !           268:        if (addr < 0xff8000)
        !           269:        {
        !           270:                /* invalid memory addressing --> bus error */
        !           271:                M68000_BusError(addr, 1);
        !           272:                return -1;
        !           273:        }
        !           274:        if (addr > 0xfffffc)
        !           275:        {
        !           276:                fprintf(stderr, "Illegal IO memory access: IoMem_lget($%x)\n", addr);
        !           277:                return -1;
        !           278:        }
        !           279: 
        !           280:        IoAccessBaseAddress = addr;                   /* Store for exception frame */
        !           281:        nIoMemAccessSize = SIZE_LONG;
        !           282:        nBusErrorAccesses = 0;
        !           283:        addr = IoMem_CheckMirrorAddresses(addr);
        !           284:        idx = addr - 0xff8000;
        !           285: 
        !           286:        IoAccessCurrentAddress = addr;
        !           287:        pInterceptReadTable[idx]();                   /* Call 1st handler */
        !           288: 
        !           289:        if (pInterceptReadTable[idx+1] != pInterceptReadTable[idx])
        !           290:        {
        !           291:                IoAccessCurrentAddress = addr + 1;
        !           292:                pInterceptReadTable[idx+1]();             /* Call 2nd handler */
        !           293:        }
        !           294: 
        !           295:        if (pInterceptReadTable[idx+2] != pInterceptReadTable[idx+1])
        !           296:        {
        !           297:                IoAccessCurrentAddress = addr + 2;
        !           298:                pInterceptReadTable[idx+2]();             /* Call 3rd handler */
        !           299:        }
        !           300: 
        !           301:        if (pInterceptReadTable[idx+3] != pInterceptReadTable[idx+2])
        !           302:        {
        !           303:                IoAccessCurrentAddress = addr + 3;
        !           304:                pInterceptReadTable[idx+3]();             /* Call 4th handler */
        !           305:        }
        !           306: 
        !           307:        /* Check if we completely read from a bus-error region */
        !           308:        if (nBusErrorAccesses == 4)
        !           309:        {
        !           310:                M68000_BusError(addr, 1);
        !           311:                return -1;
        !           312:        }
        !           313: 
        !           314:        return IoMem_ReadLong(addr);
        !           315: }
        !           316: 
        !           317: 
        !           318: /*-----------------------------------------------------------------------*/
        !           319: /*
        !           320:   Handle byte write access to IO memory.
        !           321: */
        !           322: void IoMem_bput(uaecptr addr, uae_u32 val)
        !           323: {
        !           324:        Dprintf(("IoMem_bput($%x, $%x)\n", addr, val));
        !           325: 
        !           326:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
        !           327: 
        !           328:        if (addr < 0xff8000)
        !           329:        {
        !           330:                /* invalid memory addressing --> bus error */
        !           331:                M68000_BusError(addr, 0);
        !           332:                return;
        !           333:        }
        !           334: 
        !           335:        IoAccessBaseAddress = addr;                   /* Store for exception frame, just in case */
        !           336:        nIoMemAccessSize = SIZE_BYTE;
        !           337:        nBusErrorAccesses = 0;
        !           338:        addr = IoMem_CheckMirrorAddresses(addr);
        !           339: 
        !           340:        IoMem[addr] = val;
        !           341: 
        !           342:        IoAccessCurrentAddress = addr;
        !           343:        pInterceptWriteTable[addr-0xff8000]();        /* Call handler */
        !           344: 
        !           345:        /* Check if we wrote to a bus-error region */
        !           346:        if (nBusErrorAccesses == 1)
        !           347:        {
        !           348:                M68000_BusError(addr, 0);
        !           349:        }
        !           350: }
        !           351: 
        !           352: 
        !           353: /*-----------------------------------------------------------------------*/
        !           354: /*
        !           355:   Handle word write access to IO memory.
        !           356: */
        !           357: void IoMem_wput(uaecptr addr, uae_u32 val)
        !           358: {
        !           359:        Uint32 idx;
        !           360: 
        !           361:        Dprintf(("IoMem_wput($%x, $%x)\n", addr, val));
        !           362: 
        !           363:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
        !           364: 
        !           365:        if (addr < 0x00ff8000)
        !           366:        {
        !           367:                /* invalid memory addressing --> bus error */
        !           368:                M68000_BusError(addr, 0);
        !           369:                return;
        !           370:        }
        !           371:        if (addr > 0xfffffe)
        !           372:        {
        !           373:                fprintf(stderr, "Illegal IO memory access: IoMem_wput($%x)\n", addr);
        !           374:                return;
        !           375:        }
        !           376: 
        !           377:        IoAccessBaseAddress = addr;                   /* Store for exception frame, just in case */
        !           378:        nIoMemAccessSize = SIZE_WORD;
        !           379:        nBusErrorAccesses = 0;
        !           380:        addr = IoMem_CheckMirrorAddresses(addr);
        !           381: 
        !           382:        IoMem_WriteWord(addr, val);
        !           383:        idx = addr - 0xff8000;
        !           384: 
        !           385:        IoAccessCurrentAddress = addr;
        !           386:        pInterceptWriteTable[idx]();                  /* Call 1st handler */
        !           387: 
        !           388:        if (pInterceptWriteTable[idx+1] != pInterceptWriteTable[idx])
        !           389:        {
        !           390:                IoAccessCurrentAddress = addr + 1;
        !           391:                pInterceptWriteTable[idx+1]();            /* Call 2nd handler */
        !           392:        }
        !           393: 
        !           394:        /* Check if we wrote to a bus-error region */
        !           395:        if (nBusErrorAccesses == 2)
        !           396:        {
        !           397:                M68000_BusError(addr, 0);
        !           398:        }
        !           399: }
        !           400: 
        !           401: 
        !           402: /*-----------------------------------------------------------------------*/
        !           403: /*
        !           404:   Handle long-word write access to IO memory.
        !           405: */
        !           406: void IoMem_lput(uaecptr addr, uae_u32 val)
        !           407: {
        !           408:        Uint32 idx;
        !           409: 
        !           410:        Dprintf(("IoMem_lput($%x, $%x)\n", addr, val));
        !           411: 
        !           412:        addr &= 0x00ffffff;                           /* Use a 24 bit address */
        !           413: 
        !           414:        if (addr < 0xff8000)
        !           415:        {
        !           416:                /* invalid memory addressing --> bus error */
        !           417:                M68000_BusError(addr, 0);
        !           418:                return;
        !           419:        }
        !           420:        if (addr > 0xfffffc)
        !           421:        {
        !           422:                fprintf(stderr, "Illegal IO memory access: IoMem_lput($%x)\n", addr);
        !           423:                return;
        !           424:        }
        !           425: 
        !           426:        IoAccessBaseAddress = addr;                   /* Store for exception frame, just in case */
        !           427:        nIoMemAccessSize = SIZE_LONG;
        !           428:        nBusErrorAccesses = 0;
        !           429:        addr = IoMem_CheckMirrorAddresses(addr);
        !           430: 
        !           431:        IoMem_WriteLong(addr, val);
        !           432:        idx = addr - 0xff8000;
        !           433: 
        !           434:        IoAccessCurrentAddress = addr;
        !           435:        pInterceptWriteTable[idx]();                  /* Call handler */
        !           436: 
        !           437:        if (pInterceptWriteTable[idx+1] != pInterceptWriteTable[idx])
        !           438:        {
        !           439:                IoAccessCurrentAddress = addr + 1;
        !           440:                pInterceptWriteTable[idx+1]();            /* Call 2nd handler */
        !           441:        }
        !           442: 
        !           443:        if (pInterceptWriteTable[idx+2] != pInterceptWriteTable[idx+1])
        !           444:        {
        !           445:                IoAccessCurrentAddress = addr + 2;
        !           446:                pInterceptWriteTable[idx+2]();            /* Call 3rd handler */
        !           447:        }
        !           448: 
        !           449:        if (pInterceptWriteTable[idx+3] != pInterceptWriteTable[idx+2])
        !           450:        {
        !           451:                IoAccessCurrentAddress = addr + 3;
        !           452:                pInterceptWriteTable[idx+3]();            /* Call 4th handler */
        !           453:        }
        !           454: 
        !           455:        /* Check if we wrote to a bus-error region */
        !           456:        if (nBusErrorAccesses == 4)
        !           457:        {
        !           458:                M68000_BusError(addr, 0);
        !           459:        }
        !           460: }
        !           461: 
        !           462: 
        !           463: /*-------------------------------------------------------------------------*/
        !           464: /*
        !           465:   This handler will be called if a ST program tries to read from an address
        !           466:   that causes a bus error on a real ST. However, we can't call M68000_BusError()
        !           467:   directly: For example, a "move.b $ff8204,d0" triggers a bus error on a real ST,
        !           468:   while a "move.w $ff8204,d0" works! So we have to count the accesses to bus error
        !           469:   addresses and we only trigger a bus error later if the count matches the complete
        !           470:   access size (e.g. nBusErrorAccesses==4 for a long word access).
        !           471: */
        !           472: void IoMem_BusErrorEvenReadAccess(void)
        !           473: {
        !           474:        nBusErrorAccesses += 1;
        !           475:        IoMem[IoAccessCurrentAddress] = 0xff;
        !           476: }
        !           477: 
        !           478: /*
        !           479:   We need two handler so that the IoMem_*get functions can distinguish
        !           480:   consecutive addresses.
        !           481: */
        !           482: void IoMem_BusErrorOddReadAccess(void)
        !           483: {
        !           484:        nBusErrorAccesses += 1;
        !           485:        IoMem[IoAccessCurrentAddress] = 0xff;
        !           486: }
        !           487: 
        !           488: /*-------------------------------------------------------------------------*/
        !           489: /*
        !           490:   Same as IoMem_BusErrorReadAccess() but for write access this time.
        !           491: */
        !           492: void IoMem_BusErrorEvenWriteAccess(void)
        !           493: {
        !           494:        nBusErrorAccesses += 1;
        !           495: }
        !           496: 
        !           497: /*
        !           498:   We need two handler so that the IoMem_*put functions can distinguish
        !           499:   consecutive addresses.
        !           500: */
        !           501: void IoMem_BusErrorOddWriteAccess(void)
        !           502: {
        !           503:        nBusErrorAccesses += 1;
        !           504: }
        !           505: 
        !           506: 
        !           507: /*-------------------------------------------------------------------------*/
        !           508: /*
        !           509:   This is the read handler for the IO memory locations without an assigned
        !           510:   IO register and which also do not generate a bus error. Reading from such
        !           511:   a register will return the result 0xff.
        !           512: */
        !           513: void IoMem_VoidRead(void)
        !           514: {
        !           515:        Uint32 a;
        !           516: 
        !           517:        /* handler is probably called only once, so we have to take care of the neighbour "void IO registers" */
        !           518:        for (a = IoAccessBaseAddress; a < IoAccessBaseAddress + nIoMemAccessSize; a++)
        !           519:        {
        !           520:                if (pInterceptReadTable[a - 0xff8000] == IoMem_VoidRead)
        !           521:                {
        !           522:                        IoMem[a] = 0xff;
        !           523:                }
        !           524:        }
        !           525: }
        !           526: 
        !           527: /*-------------------------------------------------------------------------*/
        !           528: /*
        !           529:   This is the write handler for the IO memory locations without an assigned
        !           530:   IO register and which also do not generate a bus error. We simply ignore
        !           531:   a write access to these registers.
        !           532: */
        !           533: void IoMem_VoidWrite(void)
        !           534: {
        !           535:        /* Nothing... */
        !           536: }
        !           537: 
        !           538: 
        !           539: /*-------------------------------------------------------------------------*/
        !           540: /*
        !           541:   A dummy function that does nothing at all - for memory regions that don't
        !           542:   need a special handler for read access.
        !           543: */
        !           544: void IoMem_ReadWithoutInterception(void)
        !           545: {
        !           546:        /* Nothing... */
        !           547: }
        !           548: 
        !           549: /*-------------------------------------------------------------------------*/
        !           550: /*
        !           551:   A dummy function that does nothing at all - for memory regions that don't
        !           552:   need a special handler for write access.
        !           553: */
        !           554: void IoMem_WriteWithoutInterception(void)
        !           555: {
        !           556:        /* Nothing... */
        !           557: }

unix.superglobalmegacorp.com

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