From 53857089e9ad41891303e550c033280496f9b597 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sat, 22 Aug 2020 13:56:57 -0700 Subject: [PATCH] Update Apple /// SOS definitions - Added SOS parameter block formatting. - Normalized SOS call names to values in SOS Reference Manual. - Added SOS call error code constants. - (from robjustice) Added more to A3-IO.sym65. Also, rearranged the ProDOS code slightly. (issue #85) --- SourceGen/RuntimeData/Apple/A3-IO.sym65 | 93 ++++-- SourceGen/RuntimeData/Apple/ProDOS8.cs | 61 ++-- SourceGen/RuntimeData/Apple/SOS.cs | 366 +++++++++++++++++++++++- SourceGen/RuntimeData/Apple/SOS.sym65 | 91 +++++- 4 files changed, 548 insertions(+), 63 deletions(-) diff --git a/SourceGen/RuntimeData/Apple/A3-IO.sym65 b/SourceGen/RuntimeData/Apple/A3-IO.sym65 index 90b2c92..a110aeb 100644 --- a/SourceGen/RuntimeData/Apple/A3-IO.sym65 +++ b/SourceGen/RuntimeData/Apple/A3-IO.sym65 @@ -6,12 +6,32 @@ *SYNOPSIS Symbols from hardware I/O areas -KBD @ $C000 ;last key pressed -KBDFLG @ $C008 ; +KBD @ $C000 ;last key pressed (KA Data) +KBDBFLG @ $C008 ;KB data KBDSTRB @ $C010 ;RW keyboard strobe SPKR @ $C030 ;RW toggle speaker (Apple II type) SPKRIII @ $C040 ;RW beeps speaker (Apple /// type) -JOYRDY @ $C066 ; +CLRTEXTGR @ $C050 ;Clear TEXT/GR mode +SETTEXTGR @ $C051 ;Set TEXT/GR mode +CLRMIX @ $C052 ;Clear MIX mode +SETMIX @ $C053 ;Set MIX mode +CLRPAGE2 @ $C054 ;Clear PAGE2 mode +SETPAGE2 @ $C055 ;Set PAGE2 mode +CLRHIRES @ $C056 ;Clear HIRES mode +SETHIRES @ $C057 ;Set HIRES mode +CLRPDL0 @ $C058 ;Clear PDL0 (A/D Addr 0) +SETPDL0 @ $C059 ;Set PDL0 (A/D Addr 0) +CLRPDL2 @ $C05A ;Clear PDL2 (A/D Addr 2) +SETPDL2 @ $C05B ;Set PDL2 (A/D Addr 2) +CLRPDLEN @ $C05C ;Clear PDLEN (A/D Ramp Start) +SETPDLEN @ $C05D ;Set PDLEN (A/D Ramp Start) +CLRPDL1 @ $C05E ;Clear PDL1 (A/D Addr 1) +SETPDL1 @ $C05F ;Set PDL1 (A/D Addr 1) +READSW0 @ $C060 ;Read SW0 +READSW1 @ $C061 ;Read SW1/MGNSW +READSW2 @ $C062 ;Read SW2 +READSW3 @ $C063 ;Read SW3/SCO +JOYRDY @ $C066 ;Read PDLOT (A/D Ramp Stop) CLOCK @ $C070 ;clock PHASOFF @ $C080 ; PHASON @ $C081 ; @@ -22,24 +42,53 @@ DRV1EN @ $C08B ; Q6L @ $C08C ; Q6H @ $C08D ; Q7L @ $C08E ; -ACIASTAT @ $C0F1 ;status of ACIA +CLRDSA0 @ $C0D0 ;Clear Drive Select A0 +SETDSA0 @ $C0D1 ;Set Drive Select A0 +CLRDSA1 @ $C0D2 ;Clear Drive Select A1 +SETDSA1 @ $C0D3 ;Set Drive Select A1 +CLREN1INT @ $C0D4 ; +SETEN1INT @ $C0D5 ; +CLRSIDE2 @ $C0D6 ; +SETSIDE2 @ $C0D7 ; +CLRSCR @ $C0D8 ;Clear Smooth Scroll (to turn smooth scroll off) +SETSCR @ $C0D9 ;Set Smooth Scroll (to turn smooth scroll on) +CLRENCWRT @ $C0DA ;Clear Char Set writing +SETENCWRT @ $C0DB ;Set Char Set writing +CLRENSEL @ $C0DC ;Clear enable silentype port (ENSEL) +SETENSEL @ $C0DD ;Set enable silentype port (ENSEL) +CLRENSIO @ $C0DE ;Clear enable silentype port (ENSIO) +SETENSIO @ $C0DF ;Set enable silentype port (ENSIO) +ACIADATA @ $C0F0 ;ACIA DATA REGISTER +ACIASTAT @ $C0F1 ;ACIA STATUS REGISTER +ACIACMD @ $C0F2 ;ACIA COMMAND REGISTER +ACIACTL @ $C0F3 ;ACIA CONTROL REGISTER ; Other hardware registers -Z_REG @ $FFD0 ;zero page register -D_DDRB @ $FFD2 ;data direction register B -D_DDRA @ $FFD3 ;data direction register A -TIMER1L @ $FFD8 -TIMLATCH @ $FFD9 -D_ACR @ $FFDB -D_PCR @ $FFDC -D_IFR @ $FFDD -D_IER @ $FFDE -E_REG @ $FFDF ;environment register -E_IORB @ $FFE0 -E_DDRB @ $FFE2 -E_DDRA @ $FFE3 -E_ACR @ $FFEB -E_PCR @ $FFEC -E_IFR @ $FFED -E_IER @ $FFEE -B_REG @ $FFEF ;bank switch register +Z_REG @ $FFD0 ;zero page register +D_DDRB @ $FFD2 ;data direction register B +D_DDRA @ $FFD3 ;data direction register A +D_TIMER1C_L @ $FFD4 +D_TIMER1C_H @ $FFD5 +D_TIMER1L_L @ $FFD6 +D_TIMER1L_H @ $FFD7 +D_TIMER2C_L @ $FFD8 +D_TIMER2C_H @ $FFD9 +D_ACR @ $FFDB +D_PCR @ $FFDC +D_IFR @ $FFDD +D_IER @ $FFDE +E_REG @ $FFDF ;environment register +E_IORB @ $FFE0 +E_DDRB @ $FFE2 +E_DDRA @ $FFE3 +E_TIMER1C_L @ $FFE6 +E_TIMER1C_H @ $FFE7 +E_TIMER1L_L @ $FFE6 +E_TIMER1L_H @ $FFE7 +E_TIMER2C_L @ $FFE8 +E_TIMER2C_H @ $FFE9 +E_ACR @ $FFEB +E_PCR @ $FFEC +E_IFR @ $FFED +E_IER @ $FFEE +B_REG @ $FFEF ;bank switch register diff --git a/SourceGen/RuntimeData/Apple/ProDOS8.cs b/SourceGen/RuntimeData/Apple/ProDOS8.cs index b751b9a..d1adfa9 100644 --- a/SourceGen/RuntimeData/Apple/ProDOS8.cs +++ b/SourceGen/RuntimeData/Apple/ProDOS8.cs @@ -15,7 +15,6 @@ */ using System; using System.Collections.Generic; - using PluginCommon; /* @@ -69,7 +68,7 @@ namespace RuntimeData.Apple { private static Param MISC2 = new Param(DataType.NumericLE, DataSubType.Hex, 2); private static Param NULL3 = new Param(DataType.NumericLE, DataSubType.Hex, 3); - private Dictionary ParamDescrs = new Dictionary() { + private Dictionary mParamDescrs = new Dictionary() { { 0x40, // ALLOC_INTERRUPT new Param[] { PARAM_COUNT, MISC1, CODEPTR } }, @@ -193,8 +192,8 @@ namespace RuntimeData.Apple { // match! byte req = mFileData[offset + 3]; - int blockAddr = Util.GetWord(mFileData, offset + 4, 2, false); if (VERBOSE) { + int blockAddr = Util.GetWord(mFileData, offset + 4, 2, false); mAppRef.DebugLog("P8 MLI call detected at +" + offset.ToString("x6") + ", cmd=$" + req.ToString("x2") + " addr=$" + blockAddr.ToString("x4")); } @@ -211,31 +210,8 @@ namespace RuntimeData.Apple { DataSubType.Address, null); Param[] parms; - if (ParamDescrs.TryGetValue(req, out parms)) { - // Try to format the parameter block. Start by figuring out how long it is. - int blockLen = 0; - foreach (Param parm in parms) { - blockLen += parm.Length; - } - - // Locate it and verify that the entire thing fits in the file. - int blockOff = mAddrTrans.AddressToOffset(offset, blockAddr); - if (Util.IsInBounds(mFileData, blockOff, blockLen)) { - if (VERBOSE) { - mAppRef.DebugLog("Formatting P8 block at +" + blockOff.ToString("x6")); - } - - foreach (Param parm in parms) { - // We could try to dereference pathname buffers to see if it's a - // fixed value and not an empty buffer, but it's hard for us to - // reliably tell the difference between a length-limited pathname - // and junk. If the length byte is bad, we run the risk of lumping - // a bunch of stuff into the pathname buffer. - mAppRef.SetInlineDataFormat(blockOff, parm.Length, parm.Type, - parm.SubType, null); - blockOff += parm.Length; - } - } + if (mParamDescrs.TryGetValue(req, out parms)) { + FormatParameterBlock(offset, parms); } if (req == 0x65) { // QUIT call @@ -243,5 +219,34 @@ namespace RuntimeData.Apple { } } } + + private void FormatParameterBlock(int offset, Param[] parms) { + int blockAddr = Util.GetWord(mFileData, offset + 4, 2, false); + + // Try to format the parameter block. Start by figuring out how long it is. + int blockLen = 0; + foreach (Param parm in parms) { + blockLen += parm.Length; + } + + // Locate it and verify that the entire thing fits in the file. + int blockOff = mAddrTrans.AddressToOffset(offset, blockAddr); + if (Util.IsInBounds(mFileData, blockOff, blockLen)) { + if (VERBOSE) { + mAppRef.DebugLog("Formatting P8 block at +" + blockOff.ToString("x6")); + } + + foreach (Param parm in parms) { + // We could try to dereference pathname buffers to see if it's a + // fixed value and not an empty buffer, but it's hard for us to + // reliably tell the difference between a length-limited pathname + // and junk. If the length byte is bad, we run the risk of lumping + // a bunch of stuff into the pathname buffer. + mAppRef.SetInlineDataFormat(blockOff, parm.Length, parm.Type, + parm.SubType, null); + blockOff += parm.Length; + } + } + } } } diff --git a/SourceGen/RuntimeData/Apple/SOS.cs b/SourceGen/RuntimeData/Apple/SOS.cs index 00ae99a..d31dbc4 100644 --- a/SourceGen/RuntimeData/Apple/SOS.cs +++ b/SourceGen/RuntimeData/Apple/SOS.cs @@ -31,11 +31,288 @@ parm_block namespace RuntimeData.Apple { public class SOS : MarshalByRefObject, IPlugin, IPlugin_SymbolList, IPlugin_InlineBrk { private const string SOS_MLI_TAG = "SOS-MLI-Functions"; // tag used in .sym65 file - private bool VERBOSE = true; + private bool VERBOSE = false; + + #region Parameter block defs + + private class Param { + public DataType Type { get; private set; } + public DataSubType SubType { get; private set; } + public int Length { get; private set; } + + public Param(DataType type, DataSubType subType, int length) { + Type = type; + SubType = subType; + Length = length; + } + } + private static Param[] NO_PARAMS = new Param[0]; + + private class ParamSet { + public Param[] Required { get; private set; } + public Param[] Optional { get; private set; } + + public ParamSet(Param[] required, Param[] optional) { + Required = required; + Optional = optional; + } + } + + private static Param PARAM_COUNT = new Param(DataType.NumericLE, DataSubType.Decimal, 1); + private static Param OPTION_LIST = new Param(DataType.NumericLE, DataSubType.Address, 2); + private static Param OPTION_LENGTH = new Param(DataType.NumericLE, DataSubType.Decimal, 1); + private static Param SEG_ADDR = new Param(DataType.NumericLE, DataSubType.Hex, 2); + private static Param SEG_ID = new Param(DataType.NumericLE, DataSubType.Hex, 1); + private static Param SEG_NUM = new Param(DataType.NumericLE, DataSubType.Hex, 1); + private static Param PATHNAME = new Param(DataType.NumericLE, DataSubType.Address, 2); + private static Param TIME_PTR = new Param(DataType.NumericLE, DataSubType.Address, 2); + private static Param POINTER = new Param(DataType.NumericLE, DataSubType.Address, 2); + private static Param REF_NUM = new Param(DataType.NumericLE, DataSubType.Decimal, 1); + private static Param ACCESS = new Param(DataType.NumericLE, DataSubType.Hex, 1); + private static Param FILE_POS = new Param(DataType.NumericLE, DataSubType.Hex, 4); + private static Param DATE_TIME = new Param(DataType.NumericLE, DataSubType.Hex, 4); + private static Param MISC1 = new Param(DataType.NumericLE, DataSubType.Hex, 1); + private static Param MISC2 = new Param(DataType.NumericLE, DataSubType.Hex, 2); + private static Param MISC4 = new Param(DataType.NumericLE, DataSubType.Hex, 4); + private static Param UNUSED7 = new Param(DataType.Dense, DataSubType.None, 7); + + private Dictionary mParamDescrs = new Dictionary() { + { 0x40, // SOS_REQUEST_SEG + new ParamSet( + new Param[] { PARAM_COUNT, SEG_ADDR, SEG_ADDR, SEG_ID, SEG_NUM }, + NO_PARAMS + ) + }, + { 0x41, // SOS_FIND_SEG + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, SEG_ID, MISC2, SEG_ADDR, SEG_ADDR, SEG_NUM }, + NO_PARAMS + ) + }, + { 0x42, // SOS_CHANGE_SEG + new ParamSet( + new Param[] { PARAM_COUNT, SEG_NUM, MISC1, MISC2 }, + NO_PARAMS + ) + }, + { 0x43, // SOS_GET_SEG_INFO + new ParamSet( + new Param[] { PARAM_COUNT, SEG_NUM, SEG_ADDR, SEG_ADDR, MISC2, SEG_ID }, + NO_PARAMS + ) + }, + { 0x44, // SOS_GET_SEG_NUM + new ParamSet( + new Param[] { PARAM_COUNT, SEG_ADDR, SEG_NUM }, + NO_PARAMS + ) + }, + { 0x45, // SOS_RELEASE_SEG + new ParamSet( + new Param[] { PARAM_COUNT, SEG_NUM }, + NO_PARAMS + ) + }, + { 0x60, // SOS_SET_FENCE + new ParamSet( + new Param[] { PARAM_COUNT, MISC1 }, + NO_PARAMS + ) + }, + { 0x61, // SOS_GET_FENCE + new ParamSet( + new Param[] { PARAM_COUNT, MISC1 }, + NO_PARAMS + ) + }, + { 0x62, // SOS_SET_TIME + new ParamSet( + new Param[] { PARAM_COUNT, TIME_PTR }, + NO_PARAMS + ) + }, + { 0x63, // SOS_GET_TIME + new ParamSet( + new Param[] { PARAM_COUNT, TIME_PTR }, + NO_PARAMS + ) + }, + { 0x64, // SOS_GET_ANALOG + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, MISC4 }, + NO_PARAMS + ) + }, + { 0x65, // SOS_TERMINATE + new ParamSet( + NO_PARAMS, + NO_PARAMS + ) + }, + { 0x80, // SOS_D_READ + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, POINTER, MISC2, MISC2, MISC2 }, + NO_PARAMS + ) + }, + { 0x81, // SOS_D_WRITE + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, POINTER, MISC2, MISC2 }, + NO_PARAMS + ) + }, + { 0x82, // SOS_D_STATUS + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, MISC1, POINTER }, + NO_PARAMS + ) + }, + { 0x83, // SOS_D_CONTROL + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, MISC1, POINTER }, + NO_PARAMS + ) + }, + { 0x84, // SOS_GET_DEV_NUM + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, MISC1 }, + NO_PARAMS + ) + }, + { 0x85, // SOS_D_INFO + new ParamSet( + new Param[] { PARAM_COUNT, MISC1, PATHNAME, OPTION_LIST, OPTION_LENGTH }, + new Param[] { MISC1, MISC1, MISC1, MISC1, MISC1, MISC2, MISC2, MISC2 } + ) + }, + { 0xc0, // SOS_CREATE + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, OPTION_LIST, OPTION_LENGTH }, + new Param[] { MISC1, MISC2, MISC1, FILE_POS } + ) + }, + { 0xc1, // SOS_DESTROY + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME }, + NO_PARAMS + ) + }, + { 0xc2, // SOS_RENAME + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, PATHNAME }, + NO_PARAMS + ) + }, + { 0xc3, // SOS_SET_FILE_INFO + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, OPTION_LIST, OPTION_LENGTH }, + new Param[] { ACCESS, MISC1, MISC2, UNUSED7, DATE_TIME } + ) + }, + { 0xc4, // SOS_GET_FILE_INFO + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, OPTION_LIST, OPTION_LENGTH }, + new Param[] { ACCESS, MISC1, MISC2, MISC1, FILE_POS, MISC2, DATE_TIME } + ) + }, + { 0xc5, // SOS_VOLUME + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, PATHNAME, MISC2, MISC2 }, + NO_PARAMS + ) + }, + { 0xc6, // SOS_SET_PREFIX + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME }, + NO_PARAMS + ) + }, + { 0xc7, // SOS_GET_PREFIX + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, MISC1 }, + NO_PARAMS + ) + }, + { 0xc8, // OPEN + new ParamSet( + new Param[] { PARAM_COUNT, PATHNAME, REF_NUM, OPTION_LIST, OPTION_LENGTH }, + new Param[] { ACCESS, MISC1, POINTER } + ) + }, + { 0xc9, // SOS_NEWLINE + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, MISC1, MISC1 }, + NO_PARAMS + ) + }, + { 0xca, // SOS_READ + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, POINTER, MISC2, MISC2 }, + NO_PARAMS + ) + }, + { 0xcb, // SOS_WRITE + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, POINTER, MISC2 }, + NO_PARAMS + ) + }, + { 0xcc, // SOS_CLOSE + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM }, + NO_PARAMS + ) + }, + { 0xcd, // SOS_FLUSH + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM }, + NO_PARAMS + ) + }, + { 0xce, // SOS_SET_MARK + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, MISC1, FILE_POS }, + NO_PARAMS + ) + }, + { 0xcf, // SOS_GET_MARK + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, FILE_POS }, + NO_PARAMS + ) + }, + { 0xd0, // SOS_SET_EOF + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, MISC1, FILE_POS }, + NO_PARAMS + ) + }, + { 0xd1, // SOS_GET_EOF + new ParamSet( + new Param[] { PARAM_COUNT, REF_NUM, FILE_POS }, + NO_PARAMS + ) + }, + { 0xd2, // SOS_SET_LEVEL + new ParamSet( + new Param[] { PARAM_COUNT, MISC1 }, + NO_PARAMS + ) + }, + { 0xd3, // SOS_GET_LEVEL + new ParamSet( + new Param[] { PARAM_COUNT, MISC1 }, + NO_PARAMS + ) + }, + }; + + #endregion Parameter block defs private IApplication mAppRef; private byte[] mFileData; private Dictionary mFunctionList; + private AddressTranslate mAddrTrans; public string Identifier { get { @@ -46,6 +323,7 @@ namespace RuntimeData.Apple { public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) { mAppRef = appRef; mFileData = fileData; + mAddrTrans = addrTrans; mAppRef.DebugLog("SOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()"); //System.Diagnostics.Debugger.Break(); @@ -54,6 +332,7 @@ namespace RuntimeData.Apple { public void Unprepare() { mAppRef = null; mFileData = null; + mAddrTrans = null; } public void UpdateSymbolList(List plSyms) { @@ -89,10 +368,91 @@ namespace RuntimeData.Apple { mAppRef.SetInlineDataFormat(offset + 2, 2, DataType.NumericLE, DataSubType.Address, null); - // Clear the "no continue" flag unless this is a QUIT call. - if (req != 0x65) { // QUIT call + ParamSet pset; + if (mParamDescrs.TryGetValue(req, out pset)) { + FormatParameterBlock(offset, pset); + } + + // Clear the "no continue" flag unless this is a TERMINATE (QUIT) call. + if (req != 0x65) { // SOS_TERMINATE noContinue = false; } } + + private void FormatParameterBlock(int offset, ParamSet pset) { + if (VERBOSE) { + mAppRef.DebugLog("SOSPARM: trying to format SOS at +" + offset.ToString("x6")); + } + int blockAddr = Util.GetWord(mFileData, offset + 2, 2, false); + + // Try to format the parameter block. Start by figuring out how long the + // required portion is. + int blockLen = 0; + foreach (Param parm in pset.Required) { + blockLen += parm.Length; + } + + int optionListAddr = -1; + int optionListLen = -1; + + // Locate it and verify that the entire thing fits in the file. + int blockOff = mAddrTrans.AddressToOffset(offset, blockAddr); + if (VERBOSE) { + mAppRef.DebugLog("SOSPARM: checking addr=$" + blockAddr.ToString("x4") + + " off=+" + blockOff.ToString("x6") + " len=" + blockLen); + } + if (Util.IsInBounds(mFileData, blockOff, blockLen)) { + if (VERBOSE) { + mAppRef.DebugLog("SOSPARM: formatting block at +" + blockOff.ToString("x6")); + } + + foreach (Param parm in pset.Required) { + // Watch for option list parameters. + if (parm == OPTION_LIST) { + optionListAddr = Util.GetWord(mFileData, blockOff, 2, false); + } else if (parm == OPTION_LENGTH) { + optionListLen = mFileData[blockOff]; + } + + // We could try to dereference pathname buffers to see if it's a + // fixed value and not an empty buffer, but it's hard for us to + // reliably tell the difference between a length-limited pathname + // and junk. If the length byte is bad, we run the risk of lumping + // a bunch of stuff into the pathname buffer. + + mAppRef.SetInlineDataFormat(blockOff, parm.Length, parm.Type, + parm.SubType, null); + blockOff += parm.Length; + } + } else { + if (VERBOSE) { + mAppRef.DebugLog("SOSPARM: NOT in bounds"); + } + } + + if (optionListAddr >= 0 && optionListLen > 0) { + if (VERBOSE) { + mAppRef.DebugLog("SOSPARM: format optionList addr=$" + + optionListAddr.ToString("x4") + " len=" + optionListLen); + } + blockOff = mAddrTrans.AddressToOffset(offset, optionListAddr); + if (Util.IsInBounds(mFileData, blockOff, optionListLen)) { + // Format the parts of the option list that are present. + int usedLen = 0; + + foreach (Param parm in pset.Optional) { + if (usedLen + parm.Length > optionListLen) { + // This parameter was not provided. + break; + } + + mAppRef.SetInlineDataFormat(blockOff, parm.Length, parm.Type, + parm.SubType, null); + blockOff += parm.Length; + usedLen += parm.Length; + } + } + } + } } } diff --git a/SourceGen/RuntimeData/Apple/SOS.sym65 b/SourceGen/RuntimeData/Apple/SOS.sym65 index e4bb56a..d98df11 100644 --- a/SourceGen/RuntimeData/Apple/SOS.sym65 +++ b/SourceGen/RuntimeData/Apple/SOS.sym65 @@ -2,9 +2,10 @@ ; See the LICENSE.txt file for distribution terms (Apache 2.0). ; ; Source: SOS programmer's guide -; SOS Reference Manual, Volume 2 (Apple 1982) +; SOS Reference Manual, Volume 1 & 2 (Apple 1982) +; Undocumented Apple /// SOS Features -*SYNOPSIS Apple /// Sophisticated Operating System constants. +*SYNOPSIS Apple III Sophisticated Operating System constants. ; SOS MLI function codes. *TAG SOS-MLI-Functions @@ -21,12 +22,12 @@ SOS_GET_FENCE = $61 SOS_SET_TIME = $62 SOS_GET_TIME = $63 SOS_GET_ANALOG = $64 -; SOS ref: "TERMINATE" +SOS_TERMINATE = $65 ; SOS ref: "No errors are possible. This is an excellent call for beginners." -SOS_QUIT = $65 -SOS_READBLOCK = $80 -SOS_WRITEBLOCK = $81 +; SOS ref does not describe D_READ and D_WRITE; see Undocumented Features doc. +SOS_D_READ = $80 +SOS_D_WRITE = $81 SOS_D_STATUS = $82 SOS_D_CONTROL = $83 SOS_GET_DEV_NUM = $84 @@ -42,10 +43,8 @@ SOS_SET_PREFIX = $C6 SOS_GET_PREFIX = $C7 SOS_OPEN = $C8 SOS_NEWLINE = $C9 -; SOS ref: "READ" -SOS_READFILE = $CA -; SOS ref: "WRITE" -SOS_WRITEFILE = $CB +SOS_READ = $CA +SOS_WRITE = $CB SOS_CLOSE = $CC SOS_FLUSH = $CD SOS_SET_MARK = $CE @@ -54,3 +53,75 @@ SOS_SET_EOF = $D0 SOS_GET_EOF = $D1 SOS_SET_LEVEL = $D2 SOS_GET_LEVEL = $D3 + +*TAG + +; +; SOS call error codes. +; +; $01-05: problem with form of call, parameters, or pointers +; $10-2f: device call errors +; $30-3f: problem with particular device +; $40-5a: file call errors +; $70-7f: utility call errors +; $e0-ef: memory call errors +; +SOS_BADSCNUM = $01 +SOS_BADCZPAGE = $02 +SOS_BADXBYTE = $03 +SOS_BADSCPCNT = $04 +SOS_BADSCBNDS = $05 + +SOS_DNFERR = $10 +SOS_BADDNUM = $11 +SOS_BADREQCODE = $20 +SOS_BADCTL = $21 +SOS_BADCTLPARM = $22 +SOS_NOTOPEN = $23 +SOS_NORESC = $25 +SOS_BADOP = $26 +SOS_IOERR = $27 +SOS_CRCERR = $2a +SOS_NOWRITE = $2b +SOS_BYTECNT = $2c +SOS_BLKNUM = $2d +SOS_DISKSW = $2e + +SOS_BADPATH = $40 +SOS_CFCBFULL = $41 +SOS_FCBFULL = $42 +SOS_BADREFNUM = $43 +SOS_PNFERR = $44 +SOS_VNFERR = $45 +SOS_FNFERR = $46 +SOS_DUPERR = $47 +SOS_OVRERR = $48 +SOS_DIRFULL = $49 +SOS_CPTERR = $4a +SOS_TYPERR = $4b +SOS_EOFERR = $4c +SOS_POSNERR = $4d +SOS_ACCSERR = $4e +SOS_BTSERR = $4f +SOS_FILBUSY = $50 +SOS_DIRERR = $51 +SOS_NOTSOS = $52 +SOS_BADLSTCNT = $53 +SOS_OUTOFMEM = $54 +SOS_BUFTBLFULL = $55 +SOS_BADSYSBUF = $56 +SOS_DUPVOL = $57 +SOS_NOTBLKDEV = $58 +SOS_LVLERR = $59 +SOS_BITMAPADR = $5a + +SOS_BADJMODE = $70 + +SOS_BADBKPG = $e0 +SOS_SEGRQDN = $e1 +SOS_SEGTBLFULL = $e2 +SOS_BADSEGNUM = $e3 +SOS_SEGNOTFND = $e4 +SOS_BADSRCHMODE = $e5 +SOS_BADCHGMODE = $e6 +SOS_BADPGCNT = $e7