This commit is contained in:
Lane Roathe
2019-11-17 11:19:42 -08:00
25 changed files with 719 additions and 465 deletions

View File

@@ -3,12 +3,15 @@ set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
project(QAsm)
set(CMAKE_BUILD_TYPE DEBUG)
set(CIDER "0")
#set(CMAKE_BUILD_TYPE DEBUG)
set(APPVERSION "4.0.9")
set(LIBRARY_NAME pal)
set(FIND_LIBRARY_USE_LIB64_PATHS TRUE)
include(./lib${LIBRARY_NAME}/cmake/CMakeHeader.txt)
set ( PROJECT_NAME "qasm" )
set(SOURCE
@@ -20,7 +23,11 @@ set(SOURCE
)
#find_package(OpenSSL REQUIRED)
find_package(Poco REQUIRED Foundation Util XML JSON )
find_package( Poco REQUIRED Foundation Util XML JSON )
if ( ${CIDER} )
find_package( ZLIB )
endif ( ${CIDER} )
include_directories(BEFORE
${PROJECT_ROOT}
@@ -29,16 +36,30 @@ include_directories(BEFORE
${Poco_INCLUDE_DIRS}
)
add_subdirectory(${PROJECT_ROOT}/lib${LIBRARY_NAME})
include(${PROJECT_ROOT}/lib${LIBRARY_NAME}/cmake/CMakeApp.txt)
set (CIDERLIBS "" )
if ( ${CIDER} )
add_definitions(-DCIDERPRESS)
include_directories(AFTER ${PROJECT_ROOT}/ciderpress/diskimg)
add_subdirectory(${PROJECT_ROOT}/ciderpress/nufxlib)
add_subdirectory(${PROJECT_ROOT}/ciderpress/diskimg)
find_library(DISKIMG_LIB libnufx_static.a ${PROJECT_ROOT}/build )
find_library(HFS_LIB libnufx_static.a ${PROJECT_ROOT}/build )
find_library(NUFX_LIB libnufx_static.a ${PROJECT_ROOT}/build )
set (CIDERLIBS diskimg_static hfs_static nufx_static ${ZLIB_LIBRARIES})
endif ( ${CIDER} )
add_subdirectory(${PROJECT_ROOT}/lib${LIBRARY_NAME})
add_executable( ${PROJECT_NAME} ${SOURCE})
target_link_libraries (
${PROJECT_NAME}
${LIBRARY_NAME}
pthread
${CIDERLIBS}
${Poco_LIBRARIES}
)

View File

@@ -20,6 +20,17 @@ all:
-mkdir -p ./build
-cd ./build && cmake .. && $(MAKE) $S
release:
-rm -rf ./build
-mkdir -p ./build
-cd ./build && cmake -DCMAKE_BUILD_TYPE=RELEASE .. && $(MAKE) $S
debug:
-rm -rf ./build
-mkdir -p ./build
-cd ./build && cmake -DCMAKE_BUILD_TYPE=DEBUG .. && $(MAKE) $S
distclean:
rm -rf ./build

197
asm.cpp
View File

@@ -25,16 +25,16 @@ void CLASS::setError(uint32_t ecode)
void CLASS::print(uint32_t lineno)
{
int pcol;
uint32_t l, i;
//int commentcol;
uint32_t l, i, savpcol, pcol;
bool commentprinted = false;
static bool checked = false;
static bool nc1 = false;
bool nc = false;
uint8_t commentcol = tabs[2];
uint32_t b = 4; // how many bytes show on the first line
bool merlinstyle=true;
bool merlinstyle = true;
if (datafillct > 0)
{
@@ -53,7 +53,7 @@ void CLASS::print(uint32_t lineno)
if (merlinstyle)
{
//printf("errorcode=%d\n",errorcode);
printf("%s in line: %d", errStrings[errorcode].c_str(), lineno+1);
printf("\n%s in line: %d", errStrings[errorcode].c_str(), lineno + 1);
if (errorText != "")
{
printf("%s", errorText.c_str());
@@ -155,6 +155,7 @@ void CLASS::print(uint32_t lineno)
pcol += printf("%02X ", addressmode & 0xFF);
}
savpcol = pcol; // this is how many bytes are in the side margin
pcol = 0; // reset pcol here because this is where source code starts
if (empty)
@@ -168,15 +169,43 @@ void CLASS::print(uint32_t lineno)
pcol += printf(" ");
}
}
else
//else
{
pcol += printf("%s", comment.c_str());
int comct = 0;
for (uint32_t cc = 0; cc < comment.length(); cc++)
{
pcol += printf("%c", comment[cc]);
comct++;
if ((comment[cc] <= ' ') && (pcol >= (commentcol + savpcol + 10)))
{
printf("\n");
pcol = 0;
while (pcol < (commentcol + savpcol))
{
pcol += printf(" ");
}
}
}
//pcol += printf("%s", comment.c_str());
}
commentprinted = true;
}
}
else
{
pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
pcol += printf("%s ", printlable.c_str());
while (pcol < tabs[0])
{
pcol += printf(" ");
}
pcol += printf("%s ", opcode.c_str());
while (pcol < tabs[1])
{
pcol += printf(" ");
}
pcol += printf("%s ", operand.c_str());
//pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
}
if ((errorcode > 0) && (!merlinstyle))
{
@@ -186,7 +215,7 @@ void CLASS::print(uint32_t lineno)
}
pcol += printf(":[Error] %s %s", errStrings[errorcode].c_str(), errorText.c_str());
}
else
else if (!commentprinted)
{
while (pcol < commentcol)
{
@@ -208,7 +237,7 @@ void CLASS::print(uint32_t lineno)
}
uint32_t ct = 1;
if (obc > b)
if ((obc > b) && ((truncdata & 0x01) == 0))
{
ct = 0;
uint8_t db;
@@ -261,7 +290,6 @@ void CLASS::clear()
operand_expr2 = "";
addrtext = "";
linemx = 0;
commentcol = 40;
bytect = 0;
opflags = 0;
pass0bytect = 0;
@@ -787,6 +815,7 @@ CLASS::~CLASS()
}
void CLASS::init(void)
{
TFileProcessor::init();
std::string s;
lines.clear();
@@ -916,21 +945,8 @@ TSymbol *CLASS::addSymbol(std::string sym, uint32_t val, bool replace)
TSymbol *res = NULL;
TSymbol *fnd = NULL;
fnd = findSymbol(sym);
if ((fnd != NULL) && (!replace))
if (sym.length() > 0)
{
return (NULL); // it is a duplicate
}
if (fnd != NULL)
{
//printf("replacing symbol: %s %08X\n",sym.c_str(),val);
fnd->value = val;
return (fnd);
}
//printf("addSymbol |%s|\n",sym.c_str());
TSymbol s;
s.name = sym;
s.opcode = 0;
@@ -940,8 +956,58 @@ TSymbol *CLASS::addSymbol(std::string sym, uint32_t val, bool replace)
s.used = false;
s.cb = NULL;
std::pair<std::string, TSymbol> p(Poco::toUpper(sym), s);
if (sym[0] == ':')
{
//local symbol
if (currentsym == NULL)
{
goto out;
}
else
{
fnd = findSymbol(sym);
if ((fnd != NULL) && (!replace))
{
goto out;
}
if (fnd != NULL)
{
fnd->value = val;
res = fnd;
goto out;
}
if (currentsym != NULL)
{
currentsym->locals.insert(p);
}
res = findSymbol(sym);
goto out;
}
}
else
{
fnd = findSymbol(sym);
if ((fnd != NULL) && (!replace))
{
goto out;
}
if (fnd != NULL)
{
//printf("replacing symbol: %s %08X\n",sym.c_str(),val);
fnd->value = val;
res = fnd;
goto out;
}
symbols.insert(p);
res = findSymbol(sym);
}
}
out:
return (res);
}
@@ -949,15 +1015,37 @@ TSymbol *CLASS::findSymbol(std::string symname)
{
TSymbol *res = NULL;
if (symname.length() > 0)
{
if (symname[0] == ':')
{
if (currentsym == NULL)
{
goto out;
}
else
{
auto itr = currentsym->locals.find(Poco::toUpper(symname));
if (itr != currentsym->locals.end())
{
res = &itr->second;
goto out;
}
}
}
else
{
//printf("finding: %s\n",symname.c_str());
auto itr = symbols.find(Poco::toUpper(symname));
if (itr != symbols.end())
{
//printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value);
res = &itr->second;
return (res);
goto out;
}
}
}
out:
return (res);
}
@@ -1086,6 +1174,7 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
{
int res = -1;
char c;
std::string s;
if (op.length() == 4) // check for 4 digit 'L' opcodes
{
@@ -1101,7 +1190,12 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
line.flags |= FLAG_FORCELONG; // 3 byte address
break;
default: // any char but 'L' as in Merlin 16+
if ((c != 'D') || (Poco::toUpper(op) != "DEND"))
s = Poco::toUpper(op);
if ((s == "ELSE") || (s == "DEND"))
{
break;
}
if (c != 'D')
{
op = op.substr(0, 3);
line.flags |= FLAG_FORCEABS; // 2 byte address
@@ -1131,6 +1225,10 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
line.flags |= FLAG_FORCELONG;
break;
}
if (line.expr_value >= 0x100)
{
line.flags |= FLAG_FORCEABS;
}
auto itr = opcodes.find(Poco::toUpper(op));
@@ -1249,7 +1347,6 @@ void CLASS::initpass(void)
allowdup = getBool("asm.allowduplicate", true);
skiplist = false;
generateCode = true;
PC.origin = 0x8000;
PC.currentpc = PC.origin;
@@ -1283,12 +1380,13 @@ void CLASS::initpass(void)
}
relocatable = false;
currentsym = NULL;
currentsymstr="";
lineno = 0;
errorct = 0;
passcomplete = false;
dumstartaddr = 0;
dumstart = 0;
truncdata = 0;
variables.clear(); // clear the variables for each pass
while (!PCstack.empty())
@@ -1303,6 +1401,10 @@ void CLASS::initpass(void)
{
DOstack.pop();
}
while (!LSTstack.empty())
{
LSTstack.pop();
}
curLUP.clear();
curDO.clear();
savepath = "";
@@ -1317,6 +1419,10 @@ void CLASS::complete(void)
std::string currentdir = Poco::Path::current();
savepath = processFilename(savepath, currentdir, 0);
if (isDebug() >= 1)
{
savepath += "1"; // append this to the end to help with testing against other assemblers
}
printf("saving to file: %s\n", savepath.c_str());
std::ofstream f(savepath);
@@ -1583,14 +1689,15 @@ int CLASS::substituteVariables(MerlinLine & line)
return (res);
}
// this function determines if code generation is turned off (IF,DO,LUP,MAC, etc
bool CLASS::codeSkipped(void)
{
bool res = false;
if (curLUP.lupskip)
{
res = true;
}
res = (curLUP.lupskip) ? true : res;
res = (curDO.doskip) ? true : res;
//printf("codeskip: %d\n",res);
return (res);
}
@@ -1616,18 +1723,14 @@ void CLASS::process(void)
line.eval_result = 0;
line.lineno = lineno + 1;
line.truncdata = truncdata;
memcpy(line.tabs, tabs, sizeof(tabs));
//printf("lineno: %d %d |%s|\n",lineno,l,line.operand.c_str());
op = Poco::toLower(line.opcode);
operand = Poco::toLower(line.operand);
line.startpc = PC.currentpc;
line.linemx = mx;
uint16_t cc = tabs[2];
if (cc == 0)
{
cc = 40;
}
line.commentcol = cc;
line.bytect = 0;
line.showmx = showmx;
@@ -1645,13 +1748,22 @@ void CLASS::process(void)
sym = addVariable(line.lable, ls, true);
if (sym == NULL) { dupsym = true; }
break;
case ':':
break;
default:
if (pass == 0)
{
sym = addSymbol(line.lable, PC.currentpc, false);
if (sym == NULL) { dupsym = true; }
if (sym == NULL)
{
dupsym = true;
line.setError(errDupSymbol);
}
}
if (c != ':')
{
currentsym = findSymbol(line.lable);
currentsymstr=line.lable;
}
break;
}
@@ -1690,6 +1802,7 @@ void CLASS::process(void)
if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc)
{
x = 0;
line.outbytect = 0;
}
if (x > 0)

22
asm.h
View File

@@ -34,8 +34,8 @@
// these ORd bits specify specific classes of opcodes and subgroups
#define OP_STD (0x1000 | OP_CLASS1)
#define OP_ASL (0x2000 | OP_CLASS2)
#define OP_STX (0x3000 | OP_CLASS2)
#define OP_C0 (0x4000 | OP_CLASS0)
#define OP_STX (0x8000 | OP_ASL|OP_CLASS2)
enum asmErrors
{
@@ -79,10 +79,10 @@ const std::string errStrings[errMAX + 1] =
"Unimplemented Instruction",
"Fatal",
"Unsupported Addressing Mode",
"Unknown Opcode",
"Bad opcode",
"Opcode not available under CPU mode",
"Byte output differs between passes",
"Relative branch offset too large",
"Bad branch",
"Forward Reference to symbol",
"Unable to redefine symbol",
"Duplicate Symbol",
@@ -187,8 +187,9 @@ public:
std::string comment;
std::string addrtext;
uint8_t linemx;
uint16_t commentcol;
uint8_t tabs[16];
bool showmx;
uint8_t truncdata;
uint32_t lineno;
uint32_t flags;
uint16_t opflags;
@@ -223,7 +224,7 @@ protected:
std::vector<std::string> filenames;
uint8_t syntax;
uint64_t starttime;
uint8_t tabs[10];
uint8_t tabs[16];
uint32_t filecount; // how many files have been read in (because of included files from source
public:
@@ -282,11 +283,11 @@ public:
clear();
}
void clear(void) {
dooff=false;
doskip=false;
value=0;
}
uint32_t value;
bool dooff;
bool doskip;
};
class TSymbol;
@@ -330,7 +331,6 @@ class T65816Asm : public TFileProcessor
public:
// options
bool casesen;
bool listing;
bool showmx;
bool trackrep;
bool merlincompat;
@@ -345,10 +345,9 @@ public:
bool skiplist; // used if lst is on, but LST opcode turns it off
uint32_t lineno;
bool generateCode;
std::string savepath;
TSymbol *currentsym;
std::string currentsymstr;
std::vector<MerlinLine> lines;
Poco::HashMap<std::string, TSymbol>opcodes;
Poco::HashMap<std::string, TSymbol> macros;
@@ -358,10 +357,13 @@ public:
TOriginSection PC;
TLUPstruct curLUP;
TDOstruct curDO;
bool listing;
uint8_t truncdata; // for the TR opcode
std::stack<TOriginSection> PCstack;
std::stack<TLUPstruct> LUPstack;
std::stack<TDOstruct> DOstack;
std::stack<bool> LSTstack;
TPsuedoOp *psuedoops;

View File

@@ -22,6 +22,8 @@ set(CMAKE_C_FLAGS_RELEASE "${RELEASE_OPT}")
set(FIND_LIBRARY_USE_LIB64_PATHS TRUE)
add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/libhfs)
set (SOURCE
ASPI.cpp
DiskFS.cpp

View File

@@ -80,7 +80,7 @@ SST disk.
const int kNumSymbols = 256;
const int kNumFavorites = 20;
const int kRLEDelim = 0x97; // value MUST have high bit set
const int kMaxExcessByteCount = WrapperDDD::kMaxDDDZeroCount + 1;
//const int kMaxExcessByteCount = WrapperDDD::kMaxDDDZeroCount + 1;
//const int kTrackLen = 4096;
//const int kNumTracks = 35;

View File

@@ -20,7 +20,7 @@
* ===========================================================================
*/
const int kMaxSectors = 32;
//const int kMaxSectors = 32;
const int kSctSize = 256;
/* do we need a way to override these? */

View File

@@ -64,7 +64,7 @@ header followed by 6502 instructions). There's no apparent link between
the value and the type of data in the file.
*/
const int kMaxSectors = 32;
//const int kMaxSectors = 32;
const int kMaxVolNameLen = 9;
const int kSctSize = 256;
const int kVTOCTrack = 17;
@@ -73,20 +73,22 @@ const int kCatalogEntryOffset = 0x10; // first entry in cat sect starts here
const int kCatalogEntrySize = 16; // length in bytes of catalog entries
const int kCatalogEntriesPerSect = 15; // #of entries per catalog sector
const int kEntryDeleted = 0x40; // this is used to designate deleted files
const int kEntryUnused = 0x00; // this is track# in never-used entries
const int kMaxTSPairs = 0x7a; // 122 entries for 256-byte sectors
const int kTSOffset = 0x0c; // first T/S entry in a T/S list
//const int kEntryUnused = 0x00; // this is track# in never-used entries
//const int kMaxTSPairs = 0x7a; // 122 entries for 256-byte sectors
//const int kTSOffset = 0x0c; // first T/S entry in a T/S list
const int kMaxTSIterations = 32;
//const int kMaxTSIterations = 32;
/*
* Get a pointer to the Nth entry in a catalog sector.
*/
#if 0
static inline uint8_t* GetCatalogEntryPtr(uint8_t* basePtr, int entryNum)
{
assert(entryNum >= 0 && entryNum < kCatalogEntriesPerSect);
return basePtr + kCatalogEntryOffset + entryNum * kCatalogEntrySize;
}
#endif
/*

View File

@@ -1771,8 +1771,8 @@ char* A2FileHFS::GetLibHFSPathName(void) const
} else if (fileType == 0x04 && auxType == 0x0000) {
strcpy(pCreator, "pdos");
strcpy(pType, "TEXT");
} else if (fileType >= 0 && fileType <= 0xff &&
auxType >= 0 && auxType <= 0xffff)
} else if (fileType <= 0xff &&
auxType <= 0xffff)
{
pType[0] = 'p';
pType[1] = (uint8_t) fileType;

View File

@@ -53,7 +53,7 @@ const int kDataChecksumLen = 3;
const int kChunkSize35 = 175; // ceil(524 / 3)
const int kOffsetToChecksum = 699;
const int kNibblizedOutputLen = (kOffsetToChecksum + 4);
const int kMaxDataReach = 48; // should only be 6 bytes */
//const int kMaxDataReach = 48; // should only be 6 bytes */
enum {
kAddrProlog0 = 0xd5,

View File

@@ -27,12 +27,12 @@ const int kVTOCTrack = 17;
const int kVTOCSector = 0;
const int kSctSize = 256;
const int kCatalogEntrySize = 0x23; // length in bytes of catalog entries
const int kCatalogEntriesPerSect = 7; // #of entries per catalog sector
//const int kCatalogEntrySize = 0x23; // length in bytes of catalog entries
//const int kCatalogEntriesPerSect = 7; // #of entries per catalog sector
const int kMaxTSPairs = 0x7a; // 122 entries for 256-byte sectors
const int kTSOffset = 0x0c; // first T/S entry in a T/S list
//const int kTSOffset = 0x0c; // first T/S entry in a T/S list
const int kMaxTSIterations = 32;
//const int kMaxTSIterations = 32;
const int kMaxCatalogIterations = 64;

View File

@@ -20,7 +20,7 @@
const int kBlkSize = 512;
const int kVolHeaderBlock = 2; // first directory block
const int kMaxCatalogIterations = 64; // should be short, linear catalog
//const int kMaxCatalogIterations = 64; // should be short, linear catalog
const int kHugeDir = 32;
static const char* kInvalidNameChars = "$=?,[#:";
@@ -1506,7 +1506,7 @@ uint32_t A2FilePascal::GetFileType(void) const
year = ptm->tm_year; // years since 1900
if (year >= 100)
year -= 100;
if (year < 0 || year >= 100) {
if (year >= 100) {
LOGW("WHOOPS: got year %u from %d", year, ptm->tm_year);
year = 70;
}

View File

@@ -1975,7 +1975,7 @@ DIError DiskFSProDOS::CreateFile(const CreateParms* pParms, A2File** ppNewFile)
*/
dirEntryPtr[0x00] = (pParms->storageType << 4) | strlen(upperName);
strncpy((char*) &dirEntryPtr[0x01], upperName, A2FileProDOS::kMaxFileName);
if (pParms->fileType >= 0 && pParms->fileType <= 0xff)
if (pParms->fileType <= 0xff)
dirEntryPtr[0x10] = (uint8_t) pParms->fileType;
else
dirEntryPtr[0x10] = 0; // HFS long type?
@@ -1996,7 +1996,7 @@ DIError DiskFSProDOS::CreateFile(const CreateParms* pParms, A2File** ppNewFile)
PutShortLE(&dirEntryPtr[0x1c], 0); // version, min_version
}
dirEntryPtr[0x1e] = pParms->access;
if (pParms->auxType >= 0 && pParms->auxType <= 0xffff)
if (pParms->auxType <= 0xffff)
PutShortLE(&dirEntryPtr[0x1f], (uint16_t) pParms->auxType);
else
PutShortLE(&dirEntryPtr[0x1f], 0);

View File

@@ -31,13 +31,13 @@ const int kVTOCTrack = 17;
const int kVTOCSector = 0;
const int kSctSize = 256;
const int kCatalogEntrySize = 0x23; // length in bytes of catalog entries
const int kCatalogEntriesPerSect = 7; // #of entries per catalog sector
//const int kCatalogEntrySize = 0x23; // length in bytes of catalog entries
//const int kCatalogEntriesPerSect = 7; // #of entries per catalog sector
const int kMaxTSPairs = 0x7a; // 122 entries for 256-byte sectors
const int kTSOffset = 0x0c; // first T/S entry in a T/S list
//const int kTSOffset = 0x0c; // first T/S entry in a T/S list
const int kMaxTSIterations = 32;
const int kMaxCatalogIterations = 64;
//const int kMaxTSIterations = 32;
//const int kMaxCatalogIterations = 64;
/*

View File

@@ -3,7 +3,7 @@ set(CMAKE_BUILD_TYPE DEBUG)
set(BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(PROJECT_NAME diskimg)
set(PROJECT_NAME hfs)
set(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
project(${PROJECT_NAME})

View File

@@ -862,8 +862,15 @@ static NuError Nu_OpenTempFile(UNICHAR* fileNameUNI, FILE** pFp)
#else
char* result;
#if 1
DBUG(("+++ Using mktemp\n"));
result = mktemp(fileNameUNI);
#else
char fbuff[256];
sprintf(fbuff,"%s%s",fileNameUNI,"XXXXXX");
result=mkstemp();
#endif
if (result == NULL) {
Nu_ReportError(NU_BLOB, kNuErrNone, "mktemp failed on '%s'",
fileNameUNI);

View File

@@ -225,9 +225,9 @@ std::deque<Token> CLASS::shuntingYard(const std::deque<Token>& tokens)
}
else
{
//printf("symbol find |%s|\n",token.str.c_str());
sym = assembler.findSymbol(token.str);
//printf("symbol find |%s| %p\n",token.str.c_str(),sym);
if (sym != NULL)
{
sym->used = true;

View File

@@ -416,15 +416,38 @@ int CLASS::doBRANCH(MerlinLine & line, TSymbol & sym)
int32_t o32 = (int32_t)(o64 & 0xFFFFFFFF);
int32_t offset = o32 - line.startpc - res;
// SGQ should check under/over flows
bool err = false;
if (res == 2) // short branch
{
if ((offset < -128) || (offset > 127))
{
err = true;
op=0x00; // merlin does this
}
}
else if (res == 3) // long branch
{
if ((offset < -32768) || (offset > 32767))
{
err = true;
// for BRL, merlin DOES NOT kill the opcode
//op=0x00; // merlin does this
}
}
//printf("offset %d\n", offset);
setOpcode(line, op);
for (i = 0; i < (res - 1); i++)
{
line.outbytes.push_back(offset >> (i * 8));
uint8_t v=(offset >> (i*8));
v=err?0x00:v;
line.outbytes.push_back(v);
}
line.outbytect = res;
if (err)
{
line.setError(errBadBranch);
}
}
return (res);
}
@@ -449,6 +472,7 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
cc = (sym.stype >> 8) & 0x03;
amode = 0xFF;
if ((sym.stype & OP_C0) == OP_C0)
{
uint8_t cc = 0;
@@ -540,15 +564,25 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
}
if ((opflags & OP_STX) == OP_STX)
//if ((opcode == "STX") || (opcode == "LDX") || (opcode == "DEC") || (opcode == "INC"))
{
if (m == syn_implied)
{
err = true;
}
if (m == syn_absx)
if (m == syn_imm)
{
//err = true;
if ((mx & 0x01) == 0)
{
bytelen++;
}
}
if ((m == syn_absx) || (m == syn_abs) || (m == syn_absy))
{
if ((line.flags & FLAG_FORCEABS) || (line.expr_value >= 0x100))
{
bytelen++;
amode += 2;
}
}
if (cpumode >= MODE_65C02)
{
@@ -576,11 +610,25 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
}
}
}
if (line.flags&FLAG_FORCELONG)
else
{
line.setError(errBadAddressMode);
if ((m == syn_absx) || (m == syn_abs))
{
if ((line.flags & FLAG_FORCEABS) || (line.expr_value >= 0x100))
{
bytelen++;
amode += 2;
}
goto out;
}
}
if (line.flags & FLAG_FORCELONG)
{
err = errBadAddressMode;
//line.setError(errBadAddressMode);
}
goto outop;
}
if (m == syn_imm)
@@ -598,13 +646,6 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
else if ((m == syn_abs) || (m == syn_absx)
|| (m == syn_absy))
{
if (isDebug() > 2)
{
printf("flgs=%08X\n", line.flags);
}
if ((((line.flags & FLAG_DP) == 0) && ((line.flags & FLAG_FORCEDP) == 0))
|| (line.flags & FLAG_FORCEABS)
)
@@ -648,7 +689,7 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
{
if (line.flags & FLAG_FORCELONG)
{
bytelen=3;
bytelen = 3;
}
}
@@ -657,6 +698,7 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
}
outop:
op |= (amode & 0x07) << 2;
op |= cc;
@@ -738,7 +780,7 @@ void CLASS::insertOpcodes(void)
pushopcode("PAG", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("TTL", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("SKP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("TR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("TR", P_TR, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ASC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DCI", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("INV", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
@@ -751,11 +793,11 @@ void CLASS::insertOpcodes(void)
pushopcode("DFB", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DB", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADR", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADRL",P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADRL", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("HEX", P_HEX, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DO", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ELSE",P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ELSE", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("IF", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("FIN", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
@@ -773,9 +815,9 @@ void CLASS::insertOpcodes(void)
pushopcode("<<<", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADC", 0x03, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("AND", 0x01, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ASL", 0x00, OP_ASL|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ADC", 0x03, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("AND", 0x01, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ASL", 0x00, OP_ASL | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("BCC", 0x02, 0, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BLT", 0x02, 0, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BCS", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
@@ -799,25 +841,25 @@ void CLASS::insertOpcodes(void)
pushopcode("COP", 0x02, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("CPX", 0x07, OP_C0 | OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("CPY", 0x06, OP_C0 | OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("DEC", 0x06, OP_STX | OP_SPECIAL |OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("DEC", 0x06, OP_STX | OP_SPECIAL | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("DEX", 0xCA, OP_XY, OPHANDLER(&CLASS::doBYTE));
pushopcode("DEY", 0x88, OP_XY, OPHANDLER(&CLASS::doBYTE));
pushopcode("EOR", 0x02, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("INC", 0x07, OP_STX|OP_A | OP_SPECIAL, OPHANDLER(&CLASS::doBase6502));
pushopcode("EOR", 0x02, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("INC", 0x07, OP_STX | OP_A | OP_SPECIAL, OPHANDLER(&CLASS::doBase6502));
pushopcode("INX", 0xE8, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("INY", 0xC8, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("JML", 0x00, 0, OPHANDLER(&CLASS::doJMP));
pushopcode("JMP", 0x01, 0, OPHANDLER(&CLASS::doJMP));
pushopcode("JSL", 0x02, 0, OPHANDLER(&CLASS::doJMP));
pushopcode("JSR", 0x03, 0, OPHANDLER(&CLASS::doJMP));
pushopcode("LDA", 0x05, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDX", 0x05, OP_STX|OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDY", 0x05, OP_C0|OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("LSR", 0x02, OP_ASL|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDA", 0x05, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDX", 0x05, OP_STX | OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDY", 0x05, OP_C0 | OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("LSR", 0x02, OP_ASL | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("MVN", 0x00, 0, OPHANDLER(&CLASS::doMVN));
pushopcode("MVP", 0x01, 0, OPHANDLER(&CLASS::doMVN));
pushopcode("NOP", 0xEA, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("ORA", 0x00, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ORA", 0x00, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("PEA", 0xF4, 2, OPHANDLER(&CLASS::doAddress));
pushopcode("PEI", 0xD4, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("PER", 0x62, 2, OPHANDLER(&CLASS::doPER));
@@ -835,29 +877,33 @@ void CLASS::insertOpcodes(void)
pushopcode("PLX", 0xFA, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLY", 0x7A, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("REP", 0xC2, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("ROL", 0x01, OP_ASL|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ROR", 0x03, OP_ASL|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ROL", 0x01, OP_ASL | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("ROR", 0x03, OP_ASL | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("RTI", 0x40, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("RTL", 0x6B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("RTS", 0x60, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("SBC", 0x07, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("SBC", 0x07, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("SEC", 0x38, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("SED", 0xF8, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("SEI", 0x78, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("SEP", 0xE2, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("STP", 0xDB, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("STA", 0x04, OP_STD|OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("STX", 0x04, OP_STX|OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("STY", 0x04, OP_C0|OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("STA", 0x04, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
pushopcode("STX", 0x04, OP_STX | OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("STY", 0x04, OP_C0 | OP_XY, OPHANDLER(&CLASS::doBase6502));
pushopcode("STZ", 0x01, OP_A, OPHANDLER(&CLASS::doNoPattern));
pushopcode("TAX", 0xAA, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TAY", 0xA8, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TCD", 0x5B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TAD", 0x5B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TCS", 0x1B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TAS", 0x1B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TDC", 0x7B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TDA", 0x7B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TRB", 0x03, OP_A, OPHANDLER(&CLASS::doNoPattern));
pushopcode("TSB", 0x02, OP_A, OPHANDLER(&CLASS::doNoPattern));
pushopcode("TSC", 0x3B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TSA", 0x3B, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TSX", 0xBA, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TXA", 0x8A, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("TXS", 0x9A, 0, OPHANDLER(&CLASS::doBYTE));
@@ -867,6 +913,7 @@ void CLASS::insertOpcodes(void)
pushopcode("WAI", 0xCB, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("WDM", 0x42, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("XBA", 0xEB, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("SWA", 0xEB, 0, OPHANDLER(&CLASS::doBYTE));
pushopcode("XCE", 0xFB, 0, OPHANDLER(&CLASS::doBYTE));
}

View File

@@ -1,3 +0,0 @@
#pragma once

View File

@@ -22,12 +22,13 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
int64_t eval_result = 0;
uint8_t shift;
uint32_t result32;
int res = 0;
int err = 0;
std::string op = Poco::toUpper(line.opcode);
std::string oper = Poco::toUpper(line.operand);
std::string oper = line.operand_expr;
result32 = 0xFFFFFFFF;
if (op == "IF")
{
@@ -40,37 +41,47 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
if (op == "DO")
{
a.DOstack.push(a.curDO);
if (oper == "")
{
err = errIllegalCharOperand;
a.curDO.doskip = false;
goto out;
}
//line.flags |= FLAG_NOLINEPRINT;
shift = 0;
eval_result = 0;
int x = eval.evaluate(line.operand, eval_result, shift);
a.curDO.dooff = (eval_result & 0xFFFFFF); // evaluate here
int x = eval.evaluate(line.operand_expr, eval_result, shift);
if (x < 0)
{
a.curDO.dooff = false;
a.curDO.doskip = false;
err = errBadLabel;
if (a.pass == 0)
{
err = errForwardRef;
}
goto out;
}
a.DOstack.push(a.curDO);
result32 = eval_result & 0xFFFFFFFF;
a.curDO.doskip = (result32 != 0) ? false : true;
goto out;
}
if (op == "ELSE")
{
if (a.DOstack.size() > 0)
{
//line.flags |= FLAG_NOLINEPRINT;
a.curDO.dooff = !a.curDO.dooff;
a.curDO.doskip = !a.curDO.doskip;
}
else
{
err = errUnexpectedOp;
}
goto out;
}
@@ -80,20 +91,21 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
if (a.DOstack.size() > 0)
{
// kind of a silent error here, just make sure we reinitialize
a.curDO.dooff = false;
a.curDO = a.DOstack.top();
a.DOstack.pop();
}
else
{
// kind of a silent error here, just make sure we reinitialize
a.curDO.dooff = false;
err = errUnexpectedOp;
a.curDO.doskip = false;
}
goto out;
}
out:
//printf("DO eval: %08X %s\n", result32, a.curDO.doskip ? "true" : "false");
if (err > 0)
{
line.setError(err);
@@ -124,7 +136,7 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
shift = 0;
eval_result = 0;
int x = eval.evaluate(line.operand, eval_result, shift);
int x = eval.evaluate(line.operand_expr, eval_result, shift);
a.LUPstack.push(a.curLUP);
@@ -209,7 +221,7 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
int outct = 0;
int wordsize = 2;
int endian = 0;
std::string oper = line.operand;
std::string oper = line.operand_expr;
std::string op = Poco::toUpper(Poco::trim(line.opcode));
Poco::StringTokenizer tok(oper, ",", Poco::StringTokenizer::TOK_TRIM |
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
@@ -325,16 +337,6 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
line.datafillbyte = line.eval_result & 0xFF;
line.datafillct = v;
#if 0
if (a.pass > 0)
{
for (int i = 0; i < v; i++)
{
line.outbytes.push_back(0x00);
}
line.outbytect = v;
}
#endif
}
return (res);
@@ -372,8 +374,21 @@ int CLASS::doLST(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
std::string s;
if (a.pass > 0)
{
s = Poco::toUpper(Poco::trim(line.operand));
if ((s == "") || (s == "ON") || (line.expr_value > 0))
s = Poco::toUpper(Poco::trim(line.operand_expr));
if (s=="")
{
a.listing=true;
a.skiplist=true;
}
else if (s == "RTN")
{
if (a.LSTstack.size())
{
a.listing = a.LSTstack.top();
a.LSTstack.pop();
}
}
else if ((s == "ON") || (line.expr_value > 0))
{
//printf("ON\n");
a.skiplist = true;
@@ -389,11 +404,34 @@ int CLASS::doLST(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
return (0);
}
int CLASS::doTR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
UNUSED(opinfo);
std::string s;
if (a.pass > 0)
{
s = Poco::toUpper(Poco::trim(line.operand_expr));
if (s == "ADR")
{
a.truncdata |= 0x03;
}
else if ((s == "ON") || (line.expr_value > 0))
{
a.truncdata |= 0x01;;
}
else if ((s == "OFF") || (line.expr_value == 0))
{
a.truncdata = 0x00;
}
}
return (0);
}
int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
UNUSED(opinfo);
std::string os = Poco::toUpper(Poco::trim(line.operand));
std::string os = Poco::toUpper(Poco::trim(line.operand_expr));
uint32_t bytect = 0;
uint8_t b = 0;
@@ -490,7 +528,7 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
break;
case P_ORG:
if (line.operand.length() > 0)
if (line.operand_expr.length() > 0)
{
a.PC.orgsave = a.PC.currentpc;
a.PC.currentpc = line.expr_value;
@@ -521,6 +559,9 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
case P_DO:
res = doDO(a, line, opinfo);
break;
case P_TR:
res=doTR(a,line,opinfo);
break;
}
return (res);

View File

@@ -17,6 +17,7 @@ enum
P_DATA,
P_LUP,
P_DO,
P_TR,
P_MAX
};
@@ -33,9 +34,8 @@ public:
int doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);;
int doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doTR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
};
#undef CLASS

View File

@@ -1,5 +1,8 @@
#include "app.h"
#include "asm.h"
#ifdef CIDERPRESS
#include "DiskImg.h"
#endif
#define CLASS PAL_APPCLASS
@@ -28,6 +31,14 @@ void CLASS::displayVersion()
s = "-debug";
#endif
cerr << "quickASM 16++ v" << (std::string)STRINGIFY(APPVERSION) << s << endl;
#ifdef CIDERPRESS
DiskImgLib::Global::AppInit();
DiskImgLib::DiskImg prodos;
DiskImgLib::Global::AppCleanup();
#endif
}
int CLASS::runServerApp(PAL_EVENTMANAGER *em)

View File

@@ -21,7 +21,7 @@ path5=dirpath5
[asm]
casesen=true
showmx=true
showmx=false
lst=true
; can be M6502, M65C02, M65816
cpu=M65816
@@ -31,7 +31,7 @@ merlincompatible=true
symcolumns=3
[reformat]
tabs=12; 18; 30;
tabs=12; 18; 30
;tabs=0;0;0

View File

@@ -13,10 +13,10 @@
xc
mx %00
*==========================================================
* monitor addresses
TEXT = $FB39 ;Reset text window
TABV = $FB5B ;Complete vtab, using contents of 'A'
MONBELL = $FBE4 ;random bell noise!

View File

@@ -8,7 +8,7 @@ MXX = %00
mx MXX
org $4000
dp: = $A5
dp = $A5
expr = $0405
lexpr = $010203
immed = $123456
@@ -17,7 +17,7 @@ neg equ -16
]var1 = v1234
;lst off
start00:
start00
brk ;$00
ora (dp,x)
cop $BA
@@ -219,7 +219,7 @@ startA0
startB0
bcs startB0
lda (dp),y
lda dp,s
lda (dp)
lda (dp,s),y
ldy dp,x
lda dp,x