diff --git a/toolbox/os.cpp b/toolbox/os.cpp index c8bfe95..290794f 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -298,16 +298,15 @@ namespace OS bool rf = trap == 0xa00a; + const char *modifier = nullptr; switch(trap) { - case 0xa000: - Log("%04x Open(%08x)\n", trap, parm); - break; case 0xa00a: - Log("%04x OpenRF(%08x)\n", trap, parm); + modifier = "RF"; break; } + Log("%04x Open%s(%08x)\n", trap, modifier, parm); //uint32_t ioCompletion = memoryReadLong(parm + 12); uint32_t namePtr = memoryReadLong(parm + 18); @@ -325,7 +324,6 @@ namespace OS memoryWriteWord(bdNamErr, parm + 16); return bdNamErr; } - Log(" Open(%s)\n", sname.c_str()); int access = 0; @@ -354,6 +352,7 @@ namespace OS sname.append(_PATH_RSRCFORKSPEC); + Log(" open(%s, %04x)\n", xname.c_str(), access); int fd = ::open(sname.c_str(), access); if (fd < 0 && ioPermission == fsCurPerm && errno == EACCES) { @@ -381,6 +380,7 @@ namespace OS uint16_t Read(uint16_t trap) { uint32_t d0; + int32_t pos; uint32_t parm = cpuGetAReg(0); Log("%04x Read(%08x)\n", trap, parm); @@ -400,61 +400,18 @@ namespace OS return d0; } - off_t currentPos = ::lseek(ioRefNum, 0, SEEK_CUR); - if (currentPos < 0) + pos = Internal::mac_seek(ioRefNum, ioPosMode, ioPosOffset); + if (pos < 0) { - if (errno != ESPIPE) - { - d0 = errno_to_oserr(errno); - memoryWriteWord(d0, parm + 16); - return d0; - } - currentPos = 0; - } - off_t pos = 0; + d0 = pos; + pos = 0; - switch(ioPosMode) - { - case fsFromStart: - pos = ioPosOffset; - break; - case fsFromMark: - pos = currentPos + ioPosOffset; - break; - case fsFromLEOF: - { - struct stat st; - int rv; - rv = ::fstat(ioRefNum, &st); - if (rv < 0) - { - - } - pos = st.st_size + ioPosOffset; - } - break; - case fsAtMark: - pos = currentPos; - break; - default: - d0 = paramErr; - memoryWriteWord(d0, parm + 16); - return d0; - break; - } - - if (pos != currentPos) - { - - int rv = ::lseek(ioRefNum, pos, SEEK_SET); - if (rv < 0) - { - d0 = paramErr; - memoryWriteWord(d0, parm + 16); - return d0; - } + memoryWriteLong(pos, parm + 46); // new offset. + memoryWriteWord(d0, parm + 16); + return d0; } + Log(" read(%04x, %08x, %08x)\n", ioRefNum, ioBuffer, ioReqCount); ssize_t count = OS::Internal::FDEntry::read(ioRefNum, memoryPointer(ioBuffer), ioReqCount); if (count >= 0) { @@ -474,11 +431,68 @@ namespace OS memoryWriteLong(pos, parm + 46); // new offset. memoryWriteWord(d0, parm + 16); - return d0; + return d0; } + uint16_t Write(uint16_t trap) + { + uint32_t d0; + int32_t pos; + uint32_t parm = cpuGetAReg(0); + + Log("%04x Write(%08x)\n", trap, parm); + + //uint32_t ioCompletion = memoryReadLong(parm + 12); + + uint16_t ioRefNum = memoryReadWord(parm + 24); + uint32_t ioBuffer = memoryReadLong(parm + 32); + int32_t ioReqCount = memoryReadLong(parm + 36); + uint16_t ioPosMode = memoryReadWord(parm + 44); + int32_t ioPosOffset = memoryReadLong(parm + 46); + + if (ioReqCount < 0) + { + d0 = paramErr; + memoryWriteWord(d0, parm + 16); + return d0; + } + + pos = Internal::mac_seek(ioRefNum, ioPosMode, ioPosOffset); + if (pos < 0) + { + d0 = pos; + pos = 0; + + memoryWriteLong(pos, parm + 46); // new offset. + memoryWriteWord(d0, parm + 16); + return d0; + + } + + + ssize_t count = OS::Internal::FDEntry::write(ioRefNum, memoryPointer(ioBuffer), ioReqCount); + if (count >= 0) + { + d0 = 0; + pos += count; + memoryWriteLong(count, parm + 40); + } + + if (count < 0) + { + d0 = errno_to_oserr(errno); + } + + memoryWriteLong(pos, parm + 46); // new offset. + memoryWriteWord(d0, parm + 16); + return d0; + + } + + + uint16_t Delete(uint16_t trap) { @@ -544,6 +558,52 @@ namespace OS return d0; } + uint16_t SetEOF(uint16_t trap) + { + uint32_t d0; + + uint32_t parm = cpuGetAReg(0); + + Log("%04x SetEOF(%08x)\n", trap, parm); + + //uint32_t ioCompletion = memoryReadLong(parm + 12); + uint16_t ioRefNum = memoryReadWord(parm + 24); + uint32_t ioMisc = memoryReadLong(parm + 28); + + int rv = ::ftruncate(ioRefNum, ioMisc); + + d0 = rv < 0 ? errno_to_oserr(errno) : 0; + + memoryWriteWord(d0, parm + 16); + return d0; + } + + uint16_t SetFPos(uint16_t trap) + { + uint32_t d0; + + uint32_t parm = cpuGetAReg(0); + + Log("%04x SetFPos(%08x)\n", trap, parm); + + //uint32_t ioCompletion = memoryReadLong(parm + 12); + uint16_t ioRefNum = memoryReadWord(parm + 24); + uint16_t ioPosMode = memoryReadWord(parm + 44); + int32_t ioPosOffset = memoryReadLong(parm + 46); + + + ioPosOffset = Internal::mac_seek(ioRefNum, ioPosMode, ioPosOffset); + d0 = 0; + if (ioPosOffset < 0) + { + d0 = ioPosOffset; + ioPosOffset = 0; + } + + memoryWriteLong(ioPosOffset, parm + 46); // new offset. + memoryWriteWord(d0, parm + 16); + return d0; + } // return the name of the default volume. diff --git a/toolbox/os.h b/toolbox/os.h index 12a00af..297ea9f 100644 --- a/toolbox/os.h +++ b/toolbox/os.h @@ -43,10 +43,15 @@ namespace OS uint16_t SetFileInfo(uint16_t trap); uint16_t GetEOF(uint16_t trap); + uint16_t SetEOF(uint16_t trap); + + uint16_t SetFPos(uint16_t trap); + uint16_t GetVol(uint16_t trap); uint16_t Open(uint16_t trap); uint16_t Read(uint16_t trap); + uint16_t Write(uint16_t trap); #pragma mark String Utilities uint16_t CmpString(uint16_t trap); diff --git a/toolbox/os_internal.cpp b/toolbox/os_internal.cpp index f16c71f..ce4bb97 100644 --- a/toolbox/os_internal.cpp +++ b/toolbox/os_internal.cpp @@ -1,4 +1,5 @@ #include "os_internal.h" +#include "os.h" #include "toolbox.h" #include @@ -41,6 +42,30 @@ namespace OS { namespace Internal { } + int32_t mac_seek(uint16_t refNum, uint16_t mode, int32_t offset) + { + off_t rv; + switch (mode & 0x03) + { + case OS::fsAtMark: + mode = SEEK_CUR; + offset = 0; + break; + case OS::fsFromStart: + mode = SEEK_SET; + break; + case OS::fsFromLEOF: + mode = SEEK_END; + break; + case OS::fsFromMark: + mode = SEEK_CUR; + break; + } + + rv = ::lseek(refNum, offset, mode); + if (rv < 0) return errno_to_oserr(errno); + return rv; + } //std::deque FDTable; diff --git a/toolbox/os_internal.h b/toolbox/os_internal.h index 5d2c3f7..639e7e0 100644 --- a/toolbox/os_internal.h +++ b/toolbox/os_internal.h @@ -13,6 +13,8 @@ namespace OS { namespace Internal { uint16_t GetFileType(const std::string &pathname, uint16_t *fileType, uint32_t *auxType); + int32_t mac_seek(uint16_t refNum, uint16_t mode, int32_t offset); + struct FDEntry { int refcount; diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 84b1ffa..7f5fe9e 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -43,6 +43,10 @@ namespace ToolBox { d0 = OS::Read(trap); break; + case 0xa003: + d0 = OS::Write(trap); + break; + case 0xa008: d0 = OS::Create(trap); break; @@ -61,14 +65,21 @@ namespace ToolBox { case 0xa011: d0 = OS::GetEOF(trap); break; + case 0xa012: + d0 = OS::SetEOF(trap); + break; case 0xa014: d0 = OS::GetVol(trap); break; - case 0xa260: - d0 = OS::HFSDispatch(trap); + case 0xa044: + d0 = OS::SetFPos(trap); break; + + //case 0xa260: + // d0 = OS::HFSDispatch(trap); + // break; case 0xaa52: d0 = OS::HighLevelHFSDispatch(trap);