Skip to content

Instantly share code, notes, and snippets.

@johnhmj
Last active November 25, 2022 19:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnhmj/0d38ce5d45a0eb46d38f3536004e86c8 to your computer and use it in GitHub Desktop.
Save johnhmj/0d38ce5d45a0eb46d38f3536004e86c8 to your computer and use it in GitHub Desktop.
sic1 (c++ string method, Nov 20, 2022) of sic/xe
COPY START 1000
FIRST STL RETADR
CLOOP JSUB RDREC
LDA LENGTH
COMP ZERO
JEQ ENDFIL
JSUB WRREC
J CLOOP
ENDFIL LDA EOF
STA BUFFER
LDA THREE
STA LENGTH
JSUB WRREC
LDL RETADR
RSUB
EOF BYTE C'EOF'
THREE WORD 3
ZERO WORD 0
RETADR RESW 1
LENGTH RESW 1
BUFFER RESB 4096
.
. COMMENT
.
RDREC LDX ZERO
LDA ZERO
RLOOP TD INPUT
JEQ RLOOP
RD INPUT
COMP ZERO
JEQ EXIT
STCH BUFFER,X
TIX MAXLEN
JLT RLOOP
EXIT STX LENGTH
RSUB
INPUT BYTE X'F1'
MAXLEN WORD 4096
.
. COMMENT
.
WRREC LDX ZERO
WLOOP TD OUTPUT
JEQ WLOOP
LDCH BUFFER,X
WD OUTPUT
TIX LENGTH
JLT WLOOP
RSUB
OUTPUT BYTE X'05'
END FIRST
// ignore Compiler Warning (level 3) C4996
#pragma warning(disable:4996)
//
/*Built in Dec 10, 2005*/
/*Fixed in May 10, 2007*/
/*Fixed in May 1, 2009*/
/*Fixed in May 7, 2009*/
/*Update in Nov 20, 2022*/
#include"sic1def.h"
#define TXTERRORFILEOPEN "(ERROR) file opening failure, check files please!!"
#define TXTOK "(OK) Address Completed!!"
/*main function*/
int main(int argc, char *argv[])
{
bool _debug = false;
unsigned int sic_length = 0;
char cwdBuffer[MAXLENPATH];
std::fstream fSource, fIntermed, fSymTable;
std::string fname, pathIntermed, pathSymTable;
VerRecord(false);
if (_debug)
{
// debug: don't need to input filename while debug
fname = "..\\sic.txt";
}
else
{
if (argc != 2)
{
std::cout << "Input SIC source file name\n(e.g. 123.txt): ", std::cin >> fname;
}
}
// file open read-only
fSource.open(fname, FILEREAD);
if (!fSource.is_open())
{
std::cout << std::endl << TXTERRORFILEOPEN << std::endl;
system("pause");
return 0x0;
}
getcwd(cwdBuffer, MAXLENPATH);
pathIntermed = cwdBuffer, pathIntermed += "\\intermed\\interMed.txt";
pathSymTable = cwdBuffer, pathSymTable += "\\intermed\\symTable.txt";
mkdir(DIRFOLDER);
// file open writable
fIntermed.open(pathIntermed, FILEWRITE);
fSymTable.open(pathSymTable, FILEWRITE);
if (!fIntermed.is_open() || !fSymTable.is_open())
{
std::cout << std::endl << TXTERRORFILEOPEN << std::endl;
system("pause");
return 0x0;
}
if (funPassFirst(fSource, fIntermed, fSymTable))
{
std::cout << std::endl << TXTOK << std::endl;
}
else
{
system("pause");
return 0x0;
}
fSource.close();
fIntermed.close();
fSymTable.close();
VerRecord(true);
system("pause");
return 0x0;
}/*main function*/
// ignore Compiler Warning (level 3) C4996
#pragma warning(disable:4996)
//
#include"sic1def.h"
/*OP code Table*/
OpTable arOpTable[] = { "ADD",0x18,0x3,"ADDF",0x58,0x3,"ADDR",0x90,0x2,"AND",0x40,0x3,
"CLEAR",0xB4,0x2,"COMP",0x28,0x3,"COMPF",0x88,0x3,"COMPR",0xA0,0x2,
"DIV",0x24,0x3,"DIVF",0x64,0x3,"DIVR",0x9C,0x2,"FIX",0xC4,0x1,
"FLOAT",0xC0,0x1,"HIO",0xF4,0x1,"J",0x3C,0x3,"JEQ",0x30,0x3,
"JGT",0x34,0x3,"JLT",0x38,0x3,"JSUB",0x48,0x3,"LDA",0x00,0x3,
"LDB",0x68,0x3,"LDCH",0x50,0x3,"LDF",0x70,0x3,"LDL",0x08,0x3,
"LDS",0x6C,0x3,"LDT",0x74,0x3,"LDX",0x04,0x3,"LPS",0xD0,0x3,
"MUL",0x20,0x3,"MULF",0x60,0x3,"MULR",0x98,0x2,"NORM",0xC8,0x1,
"OR",0x44,0x3,"RD",0xD8,0x3,"RMO",0xAC,0x2,"RSUB",0x4C,0x3,
"SHIFTL",0xA4,0x2,"SHIFTR",0xA8,0x2,"SIO",0xF0,0x1,"SSK",0xEC,0x3,
"STA",0x0C,0x3,"STB",0x78,0x3,"STCH",0x54,0x3,"STF",0x80,0x3,
"STI",0xD4,0x3,"STL",0x14,0x3,"STS",0x7C,0x3,"STSW",0xE8,0x3,
"STT",0x84,0x3,"STX",0x10,0x3,"SUB",0x1C,0x3,"SUBF",0x5C,0x3,
"SUBR",0x94,0x2,"SVC",0xB0,0x2,"TD",0xE0,0x3,"TIO",0xF8,0x1,
"TIX",0x2C,0x3,"TIXR",0xB8,0x2,"WD",0xDC,3 };
/*Address Table*/
AddTable arAddTable[] = { "START",0x0,"END",0x0,"BYTE",0x1,"WORD",0x3,"RESB",0x1,"RESW",0x3 };
/*Symbol Table*/
SymTable arSymTable[MAXSYM];
//
// Class CUInt to Hex
CUInt::CUInt()
{
this->m_nValue = 0x0;
MemoryInit(this->m_buffer = new char[MAXLENSTRING], MAXLENSTRING);
}
CUInt::CUInt(const CUInt& c)
{
if (this == &c) { return; }
this->m_nValue = c.m_nValue;
this->m_sValue = c.m_sValue;
MemoryInit(this->m_buffer = new char[MAXLENSTRING], MAXLENSTRING);
}
CUInt::CUInt(unsigned int s)
{
this->m_nValue = s;
MemoryInit(this->m_buffer = new char[MAXLENSTRING], MAXLENSTRING);
this->m_sValue = IntToHex(s, this->m_buffer);
}
CUInt& CUInt::operator=(const CUInt& c)
{
if (this == &c) { return *this; }
this->m_nValue = c.m_nValue;
this->m_sValue = c.m_sValue;
return *this;
}
CUInt& CUInt::operator=(unsigned int s)
{
this->m_nValue = s;
this->m_sValue = IntToHex(s, this->m_buffer);
return *this;
}
CUInt::~CUInt() { if (this->m_buffer != NULL) { delete[] this->m_buffer; this->m_buffer = NULL; } }
std::string& CUInt::getHex()
{
this->m_sValue = IntToHex(this->m_nValue, this->m_buffer);
return this->m_sValue;
}
void CUInt::clear()
{
this->m_nValue = 0x0;
this->m_sValue.clear();
MemoryInit(this->m_buffer, MAXLENSTRING);
}
//
// temporary memory
_CTemp::_CTemp()
{
this->m_nPCtr = 0x0;
this->m_nStartAdd = 0x0;
this->m_nSymCtr = 0x0;
MemoryInit(this->m_buffer = new char[MAXLENSTRING], MAXLENSTRING);
MemoryInit(&this->m_tempOp, sizeof(OpTable));
MemoryInit(&this->m_tempSym, sizeof(SymTable));
}
_CTemp::_CTemp(const _CTemp& c) { if (this == &c) { return; } }
_CTemp& _CTemp::operator=(const _CTemp& c) { if (this == &c) { return *this; }return *this; }
_CTemp::~_CTemp() { if (this->m_buffer != NULL) { delete[] this->m_buffer; this->m_buffer = NULL; } }
//
// Class CCmdLine
CCmdLine::CCmdLine() {}
CCmdLine::CCmdLine(const CCmdLine& c)
{
if (this == &c) { return; }
this->m_sLine = c.m_sLine;
this->m_sLabel = c.m_sLabel;
this->m_sOpCode = c.m_sOpCode;
this->m_sOperand = c.m_sOpCode;
}
CCmdLine& CCmdLine::operator=(const CCmdLine& c)
{
if (this == &c) { return *this; }
this->m_sLine = c.m_sLine;
this->m_sLabel = c.m_sLabel;
this->m_sOpCode = c.m_sOpCode;
this->m_sOperand = c.m_sOpCode;
return *this;
}
CCmdLine& CCmdLine::operator=(const char* s)
{
this->setLine(s);
return *this;
}
CCmdLine::~CCmdLine() {}
void CCmdLine::setLine(const char* s)
{
std::stringstream _ss(s);
this->m_sLine = _ss.str();
switch (this->m_sLine.front())
{
case CHARPERIOD:
break;
case CHARTAB:
case CHARSPACE:
this->m_sLabel = CHARTAB;
_ss >> this->m_sOpCode;
_ss >> this->m_sOperand;
break;
default:
_ss >> this->m_sLabel;
_ss >> this->m_sOpCode;
_ss >> this->m_sOperand;
break;
}
}
std::string& CCmdLine::getLine() { return this->m_sLine; };
std::string& CCmdLine::getLabel() { return this->m_sLabel; }
std::string& CCmdLine::getOpCode() { return this->m_sOpCode; }
std::string& CCmdLine::getOperand() { return this->m_sOperand; }
unsigned int CCmdLine::getOperand(unsigned int _base) { return StrToInt(this->m_sOperand.c_str(), _base); }
bool CCmdLine::isComment() { return (this->m_sLine.front() == CHARPERIOD); }
bool CCmdLine::isOpCode(OpTable* d)
{
bool _b = false;
unsigned int _len = MemorySize(arOpTable, OpTable);
for (unsigned int i = 0; i < _len; i++)
{
if (this->m_sOpCode.compare(arOpTable[i]._name) == 0)
{
_b = true;
memcpy(d, arOpTable + i, sizeof(OpTable));
break;
}
}
return _b;
}
bool CCmdLine::isSymbol(SymTable* d)
{
bool _b = false;
unsigned int _len = MemorySize(arSymTable, SymTable);
for (unsigned int i = 0; i < _len; i++)
{
if (this->m_sLabel.compare(arSymTable[i]._name) == 0)
{
_b = true;
memcpy(d, arSymTable + i, sizeof(SymTable));
break;
}
}
return _b;
}
unsigned int CCmdLine::getByteLen()
{
unsigned int _len = 0x0;
char _temp[MAXLENSTRING], _byte[MAXLENSTRING], _sep[] = { CHARQMARK, 0x0 };
memcpy(_temp, this->getOperand().c_str(), MAXLENSTRING);
strtok(_temp, _sep);
strcpy(_byte, strtok(NULL, _sep));
switch (_temp[0])
{
case 'C':// length of a constant
_len = (unsigned int)strlen(_byte);
break;
case 'X':// reg X, length of binary
// if not a hex string
if (StrToInt(_byte, 0x10) == 0) { break; }
_len = (strlen(_byte) + (strlen(_byte) % 2 == 1 ? 1 : 0)) / 2;
break;
default:
break;
}
return _len;
}
/*Pass First*/
bool funPassFirst(std::fstream& SOURCE, std::fstream& INTERMEDIATE, std::fstream& SYMTABLE)
{
bool bFunRet = true;
CCmdLine cCLine;
_CTemp _ctmp;
CUInt cuint;
/*read first input line*/
SOURCE.getline(_ctmp.m_buffer, MAXLENSTRING);
cCLine = _ctmp.m_buffer;
/*IF OPCODE = 'START' THEN*/
if (cCLine.getOpCode() == arAddTable[0]._name)
{/*OPCODE='START'*/
/*save #[OPERAND] as starting address*/
_ctmp.m_nStartAdd = cCLine.getOperand(INTHEX);
/*initialize LOCCTR to starting address*/
_ctmp.m_nPCtr = _ctmp.m_nStartAdd;
/*write line to intermediate file*/
_ctmp.m_tempStr = cCLine.getOperand();
_ctmp.m_tempStr += CHARTAB + cCLine.getLine();
INTERMEDIATE << _ctmp.m_tempStr << std::endl;
/*read next input line*/
SOURCE.getline(_ctmp.m_buffer, MAXLENSTRING);
cCLine = _ctmp.m_buffer;
}
else
{
_ctmp.m_nPCtr = 0;
}/*if START*/
//
/*WHILE OPCODE != 'END' DO*/
while (cCLine.getOpCode() != arAddTable[1]._name)
{
/*IF this is not a comment line THEN*/
_ctmp.m_tempStr = cCLine.getLine();
if (!cCLine.isComment())
{
/*IF there is a symbol in the LABEL field THEN*/
_ctmp.m_tempStr = cCLine.getLabel();
if ((_ctmp.m_tempStr.front() != CHARTAB) && (_ctmp.m_tempStr.front() != CHARSPACE))
{
/*search SYMTAB for LABEL*/
if (cCLine.isSymbol(&_ctmp.m_tempSym))
{
/*set error flag(duplicate symbol)*/
bFunRet = false;
std::cout << "(Error) duplicate symbol." << std::endl;
return bFunRet;
}
else
{
/*insert (LABEL,LOCCTR) into SYMTAB*/
strcpy(arSymTable[_ctmp.m_nSymCtr]._name, _ctmp.m_tempStr.c_str());
arSymTable[_ctmp.m_nSymCtr]._locctr = _ctmp.m_nPCtr;
_ctmp.m_nSymCtr++;
}
}/*if symbol*/
if (cCLine.isOpCode(&_ctmp.m_tempOp))
{/*found OPCODE*/
_ctmp.m_LOCCTR = _ctmp.m_nPCtr;
//_ctmp.m_nPCtr += 0x3;
_ctmp.m_nPCtr += _ctmp.m_tempOp._format;
}
else if (cCLine.getOpCode() == arAddTable[3]._name)
{/*WORD*/
_ctmp.m_LOCCTR = _ctmp.m_nPCtr;
//_ctmp.m_nPCtr += 0x3;
_ctmp.m_nPCtr += arAddTable[3]._format;
}
else if (cCLine.getOpCode() == arAddTable[5]._name)
{/*RESW*/
_ctmp.m_LOCCTR = _ctmp.m_nPCtr;
//_ctmp.m_nPCtr += 0x3 * cCLine.getOperand(INTDEC);
_ctmp.m_nPCtr += arAddTable[5]._format * cCLine.getOperand(INTDEC);
}
else if (cCLine.getOpCode() == arAddTable[4]._name)
{/*RESB*/
_ctmp.m_LOCCTR = _ctmp.m_nPCtr;
//_ctmp.m_nPCtr += cCLine.getOperand(INTDEC);
_ctmp.m_nPCtr += arAddTable[4]._format * cCLine.getOperand(INTDEC);
}
else if (cCLine.getOpCode() == arAddTable[2]._name)
{/*BYTE*/
_ctmp.m_LOCCTR = _ctmp.m_nPCtr;
//_ctmp.m_nPCtr += cCLine.getByteLen();
_ctmp.m_nPCtr += arAddTable[2]._format * cCLine.getByteLen();
}
else
{
/*set error flag(invalid operation code)*/
bFunRet = false;
std::cout << "(Error) invalid operation code." << std::endl;
break;
}
}/*if not a comment*/
//
/*write line to intermediate file*/
_ctmp.m_tempStr = cCLine.getLine();
if (!cCLine.isComment())
{
cuint = _ctmp.m_LOCCTR;
_ctmp.m_tempStr = cuint.getHex();
_ctmp.m_tempStr += CHARTAB + cCLine.getLine();
}
INTERMEDIATE << _ctmp.m_tempStr << std::endl;
/*read next input line*/
SOURCE.getline(_ctmp.m_buffer, MAXLENSTRING);
cCLine = _ctmp.m_buffer;
}/*while not END*/
//
/*write last line to intermediate file*/
cuint = _ctmp.m_nPCtr;
INTERMEDIATE << cuint.getHex() << cCLine.getLine() << std::endl;
_ctmp.m_tempStr = ".\n.\tCOMMENT\n.\tLength_of_the_SIC_Source= ";
cuint = _ctmp.m_nPCtr - _ctmp.m_nStartAdd;
_ctmp.m_tempStr += cuint.getHex() + "\n.\n";
INTERMEDIATE << _ctmp.m_tempStr << TXTVER << std::endl;
for (unsigned int i = 0; i < _ctmp.m_nSymCtr; i++)
{
_ctmp.m_tempStr = arSymTable[i]._name;
_ctmp.m_tempStr += CHARTAB;
cuint = arSymTable[i]._locctr;
_ctmp.m_tempStr += cuint.getHex() + CHARNEWLINE;
SYMTABLE << _ctmp.m_tempStr;
}
return bFunRet;
}/*Pass First*/
void VerRecord(bool b)
{
if (!b)
{
for (unsigned int i = 0; i < 0x40; i++) { std::cout << CHAREQUAL; }
std::cout << std::endl;
std::cout << TXTVER;
for (unsigned int i = 0; i < 0x40; i++) { std::cout << CHAREQUAL; }
std::cout << std::endl;
}
else
{
std::fstream _fVer;
std::string _fname(DIRFOLDER);
_fname += "\\README.txt";
mkdir(DIRFOLDER);
_fVer.open(_fname, std::ios::out);
if (!_fVer.is_open()) { return; }
_fVer << TXTVER;
_fVer.close();
}
}
#include <iostream>
#include <fstream>
#include <sstream>
#include <direct.h>
//
#define TXTVER ".\n.\tauthor's website: http://tw.myblog.yahoo.com/mjshya/\n.\tauthor's website: http://johnmhsheep.pixnet.net/\n.\tauthor's website: https://johnmhsieh.blogspot.com/\n.\n.\t(Dec 10, 2005) sic1.c Released!!\n.\t(May 10, 2007) sic1.c Fixed!!\n.\t(May 1, 2009) sic2.c Fixed!!\n.\t(Dec 10, 2005) sic1.c Released!!\n.\t(Dec 10, 2005) sic1.c Released!!\n.\t(Nov 20, 2022) sic1.c Fixed!!\n.\n"
#define CHAREQUAL (char)0x3D
#define CHARQMARK (char)0x27
#define CHARNEWLINE (char)0xA
#define CHARPERIOD (char)0x2E
#define CHARSPACE (char)0x20
#define CHARTAB (char)0x9
#define DIRFOLDER "intermed"
#define FILEREAD std::ios::in
#define FILEWRITE std::ios::out
#define INTDEC (int)0xA
#define INTHEX (int)0x10
#define MAXLENPATH (unsigned int)0x104
#define MAXLENSTRING (unsigned int)0x80
#define MAXSYM (unsigned int)0x40
#define MemoryInit(_mem, _length) (memset((_mem), 0x0, (_length)))
#define MemorySize(_mem, _type) (sizeof(_mem) / sizeof(_type))
#define IntToHex(_d, _buffer) strupr(itoa((_d), (_buffer), INTHEX))
#define StrToInt(_d, _base) strtol((_d), NULL, (_base))
//
/*Address Table*/
typedef struct addtable
{
char _name[MAXLENSTRING];
unsigned int _format;
}AddTable;
/*OP code Table*/
typedef struct optable
{
char _name[MAXLENSTRING];
unsigned int _opcode;
unsigned int _format;
}OpTable;
/*Symbol Table*/
typedef struct symtable
{
char _name[MAXLENSTRING];
unsigned int _locctr;
}SymTable;
//
// Class CUInt to Hex
class CUInt
{
public:
CUInt();
CUInt(const CUInt& c);
CUInt(unsigned int s);
CUInt& operator=(const CUInt& c);
CUInt& operator=(unsigned int s);
~CUInt();
std::string& getHex();
void clear();
private:
unsigned int m_nValue;
std::string m_sValue;
char* m_buffer;
};
//
// temporary memory
class _CTemp
{
public:
_CTemp();
_CTemp(const _CTemp& c);
_CTemp& operator=(const _CTemp& c);
~_CTemp();
OpTable m_tempOp;
SymTable m_tempSym;
char* m_buffer;
std::string m_tempStr;
// start address, program counter
unsigned int m_nStartAdd, m_nPCtr;
// symbol table counter, LOCCTR for symbol table
unsigned int m_nSymCtr, m_LOCCTR;
};
//
// Class CCmdLine
class CCmdLine
{
public:
CCmdLine();
CCmdLine(const CCmdLine& c);
CCmdLine& operator=(const CCmdLine& c);
CCmdLine& operator=(const char* s);
~CCmdLine();
/*get a command line*/
std::string& getLine();
/*get label from command line*/
std::string& getLabel();
/*get OP code from command line*/
std::string& getOpCode();
/*get operand from command line*/
std::string& getOperand();
unsigned int getOperand(unsigned int _base);
/*check Comment*/
bool isComment();
/*check OP code Table*/
bool isOpCode(OpTable* d);
/*check symbol table*/
bool isSymbol(SymTable* d);
/*Count BYTE length*/
unsigned int getByteLen();
private:
std::string m_sLine, m_sLabel, m_sOpCode, m_sOperand;
/*set a command line*/
void setLine(const char* s);
};
//
/*Pass First*/
bool funPassFirst(std::fstream& SOURCE, std::fstream& INTERMEDIATE, std::fstream& SYMTABLE);
//
void VerRecord(bool b);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment