Word mmuReadWord(Word vAddr, Bool userMode) { if ((vAddr & 3) != 0) { /* throw illegal address exception */ mmuBadAccs = MMU_ACCS_READ | MMU_ACCS_WORD; mmuBadAddr = vAddr; throwException(EXC_ILL_ADDRESS); } return memoryReadWord(v2p(vAddr, userMode, false, MMU_ACCS_WORD)); }
/** * Check if data watchpoint occurs * * Output : return 1 for true * return 0 for false */ int hasDataWatchpointOccurred() { uint32_t dataRead = 0 ; if(hasDWTTrapDebugEventOccured()) memoryReadWord((uint32_t)(&DWT_COMP[1].FUNCTION),&dataRead); dataRead = (dataRead & DWT_MATCHED_MASK) >> 24 ; return (int)dataRead ; }
int isItmUnlocked(void) { uint32_t itmStatus = 0; memoryReadWord((uint32_t)&ITM->LSR, &itmStatus); if(itmStatus == 1) return ITM_UNLOCK_SUCCESS; return ITM_UNLOCK_FAILED; }
/** * Check if address watchpoint occur * * Input : dwtCompNumber is the comparator going to be checked * Possible value : * COMPARATOR_0 DWT Comparator Number 0 * COMPARATOR_1 DWT Comparator Number 1 * COMPARATOR_2 DWT Comparator Number 2 * COMPARATOR_3 DWT Comparator Number 3 * Output : return 1 for true * return 0 for false * return -1 if invalid comparator is selected */ int hasAddressWatchpointOccurred(int dwtCompNumber) { uint32_t dataRead = 0 ; int valid = 0 ; valid = checkForValidDWTComparator(dwtCompNumber) ; if(valid == -1) return valid ; if(hasDWTTrapDebugEventOccured()) memoryReadWord((uint32_t)(&DWT_COMP[dwtCompNumber].FUNCTION),&dataRead); dataRead = (dataRead & DWT_MATCHED_MASK) >> 24 ; return (int)dataRead ; }
static void fhfileBeginIO(void) { BYT error = 0; ULO unit = memoryReadLong(cpuGetAReg(1) + 24); UWO cmd = memoryReadWord(cpuGetAReg(1) + 28); switch (cmd) { case 2: error = fhfileRead(unit); break; case 3: case 11: error = fhfileWrite(unit); break; case 18: fhfileGetDriveType(unit); break; case 19: fhfileGetNumberOfTracks(unit); break; case 15: fhfileWriteProt(unit); break; case 4: case 5: case 9: case 10: case 12: case 13: case 14: case 20: case 21: fhfileIgnore(unit); break; default: error = -3; cpuSetDReg(0, 0); break; } memoryWriteByte(5, cpuGetAReg(1) + 8); /* ln_type */ memoryWriteByte(error, cpuGetAReg(1) + 31); /* ln_error */ }
void cpuInitializePrefetch(void) { cpu_prefetch_word = memoryReadWord(cpuGetPC()); }
static UWO cpuGetNextWordInternal(void) { UWO data = memoryReadWord(cpuGetPC() + 2); return data; }
void ftrap_close(uint16_t trap) { // returns an mpw_errno // close actually checks the error in the File Entry and converts that to unix. // (sigh) uint32_t d0 = 0; uint32_t sp = cpuGetAReg(7); uint32_t parm = memoryReadLong(sp + 4); MPWFile f; f.flags = memoryReadWord(parm); f.error = memoryReadWord(parm + 2); f.device = memoryReadLong(parm + 4); f.cookie = memoryReadLong(parm + 8); f.count = memoryReadLong(parm + 12); f.buffer = memoryReadLong(parm + 16); Log("%04x Close(%08x)\n", trap, parm); if (!parm) { cpuSetDReg(0, kEINVAL); return; } int fd = f.cookie; int rv = OS::Internal::FDEntry::close(fd); if (rv < 0) { f.error = MacOS::notOpenErr; d0 = kEINVAL; } else { f.error = 0; d0 = 0; } #if 0 if (fd < 0 || fd >= OS::Internal::FDTable.size()) { f.error = OS::notOpenErr; d0 = kEINVAL; } else { auto &e = OS::Internal::FDTable[fd]; if (e.refcount == 0) { f.error = OS::notOpenErr; d0 = kEINVAL; } else { if (--e.refcount == 0) { Log(" close(%02x)\n", fd); ::close(fd); } f.error = 0; d0 = 0; } } #endif memoryWriteWord(f.error, parm + 2); cpuSetDReg(0, 0); }
/* MPW's open logic pseudo code: if (flags & 0x1000) { // undocumented - use old tool calls oserr = flags & O_RSRC ? PBOPENRF() : PBOPEN(); } else { oserr = flags & O_RSRC ? PBHOPENRF() : PBHOPEN(); } if (!oserr) { if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { errno = EEXIST; return; } return; } if (oserr == file not found) { if (flags & O_CREAT) { oserr = PBCreate(); if (!oserr) { oserr = flag & O_RSRC ? PBOpenRF() : PBOpen(); } } PBGETFCBINFO(); if (file size) { if (flags & O_TRUNC) { oserr = PBSetEOF(); } if (!permission check) { errno = EPERM; PBClose(); } */ uint32_t ftrap_open(uint32_t name, uint32_t parm) { uint32_t d0; int fd; std::string sname; MPWFile f; int nativeFlags = 0; std::memset(&f, 0, sizeof(f)); f.flags = memoryReadWord(parm); nativeFlags = 0; switch (f.flags & 0x03) { case 0x01: nativeFlags = O_RDONLY; break; case 0x02: nativeFlags = O_WRONLY; break; case 0x00: // ???? case 0x03: nativeFlags = O_RDWR; break; } if (f.flags & kO_APPEND) nativeFlags |= O_APPEND; if (f.flags & kO_CREAT) nativeFlags |= O_CREAT; if (f.flags & kO_TRUNC) nativeFlags |= O_TRUNC; if (f.flags & kO_EXCL) nativeFlags |= O_EXCL; sname = ToolBox::ReadCString(name, true); std::string xname = sname; Log(" open(%s, %04x)\n", sname.c_str(), f.flags); if (f.flags & kO_RSRC) { // O_CREAT and O_EXCL apply to the file, not the fork. int flags = O_RDONLY | (nativeFlags & (O_CREAT | O_EXCL)); int parent = ::open(sname.c_str(), flags, 0666); fd = -1; if (parent >= 0) { sname.append(_PATH_RSRCFORKSPEC); nativeFlags &= ~O_EXCL; // APFS, etc - resource fork doesn't automatically exist so // need O_CREAT. if ((nativeFlags & O_ACCMODE) != O_RDONLY) nativeFlags |= O_CREAT; fd = ::open(sname.c_str(), nativeFlags, 0666); close(parent); } } else { fd = ::open(sname.c_str(), nativeFlags, 0666); } if (fd < 0) { // return an errno. d0 = 0x40000000 | mpw_errno_from_errno(); f.error = MacOS::ioErr; f.cookie = 0; } else { d0 = 0; f.error = 0; f.cookie = fd; // adjust the binary flags... // some apps are good about this but // dumpobj, makelib, linkiigs don't set O_BINARY (but should) // MPW Assembler sets O_BINARY (but shouldn't) if (OS::IsTextFile(sname)) f.flags &= ~kO_BINARY; if (OS::IsBinaryFile(sname)) f.flags |= kO_BINARY; if (f.flags & kO_RSRC) f.flags |= kO_BINARY; auto &e = OS::Internal::FDEntry::allocate(fd, std::move(xname)); e.text = !(f.flags & kO_BINARY); e.resource = f.flags & kO_RSRC; } memoryWriteWord(f.flags, parm + 0); memoryWriteWord(f.error, parm + 2); memoryWriteLong(f.cookie, parm + 8); return d0; }