/** * Handle long-word write access to IO memory. */ void IoMem_lput(uaecptr addr, uae_u32 val) { Uint32 idx; int n; /* Check if access is made by a new instruction or by the same instruction doing multiple long accesses */ if ( IoAccessInstrPrevClock == CyclesGlobalClockCounter ) IoAccessInstrCount++; /* Same instruction, increase access count */ else { IoAccessInstrPrevClock = CyclesGlobalClockCounter; if ( ( OpcodeFamily != i_MVMEL ) && ( OpcodeFamily != i_MVMLE ) ) IoAccessInstrCount = 0; /* Instruction is not a movem : no multiple accesses */ else IoAccessInstrCount = 1; /* 1st access of a movem.l */ } addr &= 0x00ffffff; /* Use a 24 bit address */ LOG_TRACE(TRACE_IOMEM_WR, "IO write.l $%06x = $%08x pc=%x\n", addr, val, M68000_GetPC()); if (addr < 0xff8000 || !regs.s) { /* invalid memory addressing --> bus error */ M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA); return; } if (addr > 0xfffffc) { fprintf(stderr, "Illegal IO memory access: IoMem_lput($%x)\n", addr); return; } IoAccessBaseAddress = addr; /* Store for exception frame, just in case */ nIoMemAccessSize = SIZE_LONG; nBusErrorAccesses = 0; IoMem_WriteLong(addr, val); idx = addr - 0xff8000; IoAccessCurrentAddress = addr; pInterceptWriteTable[idx](); /* Call first handler */ for (n = 1; n < nIoMemAccessSize; n++) { if (pInterceptWriteTable[idx+n] != pInterceptWriteTable[idx+n-1]) { IoAccessCurrentAddress = addr + n; pInterceptWriteTable[idx+n](); /* Call n-th handler */ } } /* Check if we wrote to a bus-error region */ if (nBusErrorAccesses == 4) { M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA); } }
/** * Handle long-word write access to IO memory. */ void IoMem_lput(uaecptr addr, uae_u32 val) { Uint32 idx; addr &= 0x00ffffff; /* Use a 24 bit address */ LOG_TRACE(TRACE_IOMEM_WR, "IO write.l $%06x = $%08x\n", addr, val); if (addr < 0xff8000 || !regs.s) { /* invalid memory addressing --> bus error */ M68000_BusError(addr, BUS_ERROR_WRITE); return; } if (addr > 0xfffffc) { fprintf(stderr, "Illegal IO memory access: IoMem_lput($%x)\n", addr); return; } IoAccessBaseAddress = addr; /* Store for exception frame, just in case */ nIoMemAccessSize = SIZE_LONG; nBusErrorAccesses = 0; IoMem_WriteLong(addr, val); idx = addr - 0xff8000; IoAccessCurrentAddress = addr; pInterceptWriteTable[idx](); /* Call handler */ if (pInterceptWriteTable[idx+1] != pInterceptWriteTable[idx]) { IoAccessCurrentAddress = addr + 1; pInterceptWriteTable[idx+1](); /* Call 2nd handler */ } if (pInterceptWriteTable[idx+2] != pInterceptWriteTable[idx+1]) { IoAccessCurrentAddress = addr + 2; pInterceptWriteTable[idx+2](); /* Call 3rd handler */ } if (pInterceptWriteTable[idx+3] != pInterceptWriteTable[idx+2]) { IoAccessCurrentAddress = addr + 3; pInterceptWriteTable[idx+3](); /* Call 4th handler */ } /* Check if we wrote to a bus-error region */ if (nBusErrorAccesses == 4) { M68000_BusError(addr, BUS_ERROR_WRITE); } }
/** * Handle long-word write access to IO memory. */ void IoMem_lput(uaecptr addr, uae_u32 val) { Uint32 idx; LOG_TRACE(TRACE_IOMEM_WR, "IO write.l $%06x = $%08x\n", addr, val); if ((addr & IO_SEG_MASK) >= IO_SIZE) { /* invalid memory addressing --> bus error */ M68000_BusError(addr, BUS_ERROR_WRITE); return; } IoAccessBaseAddress = addr; /* Store for exception frame, just in case */ nIoMemAccessSize = SIZE_LONG; nBusErrorAccesses = 0; IoMem_WriteLong(addr, val); idx = addr & IO_SEG_MASK; IoAccessCurrentAddress = addr; pInterceptWriteTable[idx](); /* Call handler */ if (pInterceptWriteTable[idx+1] != pInterceptWriteTable[idx]) { IoAccessCurrentAddress = addr + 1; pInterceptWriteTable[idx+1](); /* Call 2nd handler */ } if (pInterceptWriteTable[idx+2] != pInterceptWriteTable[idx+1]) { IoAccessCurrentAddress = addr + 2; pInterceptWriteTable[idx+2](); /* Call 3rd handler */ } if (pInterceptWriteTable[idx+3] != pInterceptWriteTable[idx+2]) { IoAccessCurrentAddress = addr + 3; pInterceptWriteTable[idx+3](); /* Call 4th handler */ } /* Check if we wrote to a bus-error region */ if (nBusErrorAccesses == 4) { M68000_BusError(addr, BUS_ERROR_WRITE); } }