Skip to content

Instantly share code, notes, and snippets.

@johnhmj
Last active November 20, 2022 15:50
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/54f0322233b1b3a61b6c997eb5091b2f to your computer and use it in GitHub Desktop.
Save johnhmj/54f0322233b1b3a61b6c997eb5091b2f to your computer and use it in GitHub Desktop.
sic1 (char 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
/*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[])
{
std::fstream fSource, fIntermediate, fSymTable;
unsigned int sic_length = 0;
char name[1][MAXLENSTRING], pathIntermediate[MAXLENPATH], pathSymbolTable[MAXLENPATH], cwdBuffer[MAXLENPATH];
VerRecord(false), VerRecord(true);
//
// debug path
// fSource.open("..\\sic.txt", std::ios::in);
if (argc != 2)
{
std::cout << "Input SIC source file name\n(e.g. 123.txt): ", std::cin >> name[0];
argv[1] = name[0];
}
fSource.open(argv[1], std::ios::in);
if (!fSource.is_open())
{
std::cout << std::endl << TXTERRORFILEOPEN << std::endl;
system("pause");
exit(0);
}
getcwd(cwdBuffer, MAXLENPATH);
strcpy(pathIntermediate, cwdBuffer);
strcat(pathIntermediate, "\\intermed\\interMed.txt");
strcpy(pathSymbolTable, cwdBuffer);
strcat(pathSymbolTable, "\\intermed\\symTable.txt");
mkdir(DIRFOLDER);
fIntermediate.open(pathIntermediate, std::ios::out);
fSymTable.open(pathSymbolTable, std::ios::out);
if (!fIntermediate.is_open())
{
std::cout << std::endl << TXTERRORFILEOPEN << std::endl;
system("pause");
exit(0);
};
if (!fSymTable.is_open())
{
std::cout << std::endl << TXTERRORFILEOPEN << std::endl;
system("pause");
exit(0);
}
if (funPassFirst(fSource, fIntermediate, fSymTable))
{
std::cout << std::endl << TXTOK << std::endl;
system("pause");
}
else
{
system("pause");
exit(0);
}
fSource.close();
fIntermediate.close();
fSymTable.close();
return 0;
}/*main function*/
#include"sic1def.h"
/*OP code Table*/
OpTable arOpTable[] = { "ADD",0x18,3,"ADDF",0x58,3,"ADDR",0x90,2,"AND",0x40,3,
"CLEAR",0xB4,2,"COMP",0x28,3,"COMPF",0x88,3,"COMPR",0xA0,2,
"DIV",0x24,3,"DIVF",0x64,3,"DIVR",0x9C,2,"FIX",0xC4,1,
"FLOAT",0xC0,1,"HIO",0xF4,1,"J",0x3C,3,"JEQ",0x30,3,
"JGT",0x34,3,"JLT",0x38,3,"JSUB",0x48,3,"LDA",0x00,3,
"LDB",0x68,3,"LDCH",0x50,3,"LDF",0x70,3,"LDL",0x08,3,
"LDS",0x6C,3,"LDT",0x74,3,"LDX",0x04,3,"LPS",0xD0,3,
"MUL",0x20,3,"MULF",0x60,3,"MULR",0x98,2,"NORM",0xC8,1,
"OR",0x44,3,"RD",0xD8,3,"RMO",0xAC,2,"RSUB",0x4C,3,
"SHIFTL",0xA4,2,"SHIFTR",0xA8,2,"SIO",0xF0,1,"SSK",0xEC,3,
"STA",0x0C,3,"STB",0x78,3,"STCH",0x54,3,"STF",0x80,3,
"STI",0xD4,3,"STL",0x14,3,"STS",0x7C,3,"STSW",0xE8,3,
"STT",0x84,3,"STX",0x10,3,"SUB",0x1C,3,"SUBF",0x5C,3,
"SUBR",0x94,2,"SVC",0xB0,2,"TD",0xE0,3,"TIO",0xF8,1,
"TIX",0x2C,3,"TIXR",0xB8,2,"WD",0xDC,3 };
/*Address Table*/
AddTable arAddTable[] = { "START",0x0,"END",0x1,"BYTE",0x2,"WORD",0x3,"RESB",0x4,"RESW",0x5 };
/*Symbol Table*/
SymTable arSymTable[MAXSYM];
//
// Class CCmdLine
CCmdLine::CCmdLine()
{
this->m_Line = new char[MAXLENSTRING];
this->m_Label = new char[MAXLENSTRING];
this->m_OpCode = new char[MAXLENSTRING];
this->m_Operand = new char[MAXLENSTRING];
MemoryInit(this->m_Line, MAXLENSTRING);
MemoryInit(this->m_Label, MAXLENSTRING);
MemoryInit(this->m_OpCode, MAXLENSTRING);
MemoryInit(this->m_Operand, MAXLENSTRING);
}
CCmdLine::CCmdLine(const CCmdLine& c)
{
if (this == &c) { return; }
memcpy(this->m_Line, c.m_Line, MAXLENSTRING);
memcpy(this->m_Label, c.m_Label, MAXLENSTRING);
memcpy(this->m_OpCode, c.m_OpCode, MAXLENSTRING);
memcpy(this->m_Operand, c.m_Operand, MAXLENSTRING);
}
CCmdLine& CCmdLine::operator=(const CCmdLine& c)
{
if (this == &c) { return *this; }
memcpy(this->m_Line, c.m_Line, MAXLENSTRING);
memcpy(this->m_Label, c.m_Label, MAXLENSTRING);
memcpy(this->m_OpCode, c.m_OpCode, MAXLENSTRING);
memcpy(this->m_Operand, c.m_Operand, MAXLENSTRING);
return *this;
}
CCmdLine& CCmdLine::operator=(const char* s)
{
char _temp[MAXLENSTRING], *_sep = "\t\n", *_sTok = NULL;
if (s == NULL) { return *this; }
memcpy(this->m_Line, s, MAXLENSTRING);
strupr(this->m_Line);
if (this->m_Line[0] == CHARPERIOD)
{
MemoryInit(this->m_Label, MAXLENSTRING);
MemoryInit(this->m_OpCode, MAXLENSTRING);
MemoryInit(this->m_Operand, MAXLENSTRING);
return *this;
}
strcpy(_temp, this->m_Line);
switch (_temp[0])
{
case CHARTAB:
case CHARSPACE:
strcpy(this->m_Label, "\t");
strcpy(this->m_OpCode, strtok(_temp, _sep));
_sTok = strtok(NULL, _sep);
strcpy(this->m_Operand, (_sTok == NULL ? "\t" : _sTok));
break;
default:
strcpy(this->m_Label, strtok(_temp, _sep));
strcpy(this->m_OpCode, strtok(NULL, _sep));
strcpy(this->m_Operand, strtok(NULL, _sep));
break;
}
return *this;
}
CCmdLine::~CCmdLine()
{
if (this->m_Line != NULL) { delete[] this->m_Line, this->m_Line = NULL; }
if (this->m_Label != NULL) { delete[] this->m_Label, this->m_Label = NULL; }
if (this->m_OpCode != NULL) { delete[] this->m_OpCode; this->m_OpCode = NULL; }
if (this->m_Operand != NULL) { delete[] this->m_Operand; this->m_Operand = NULL; }
}
void CCmdLine::setLine(const char* s, unsigned int maxlength)
{
char _temp[MAXLENSTRING], *_sep = "\t\n", *_sTok = NULL;
memcpy(this->m_Line, s, maxlength);
strupr(this->m_Line);
if (this->m_Line[0] == CHARPERIOD)
{
MemoryInit(this->m_Label, MAXLENSTRING);
MemoryInit(this->m_OpCode, MAXLENSTRING);
MemoryInit(this->m_Operand, MAXLENSTRING);
return;
}
strcpy(_temp, this->m_Line);
switch (_temp[0])
{
case CHARTAB:
case CHARSPACE:
strcpy(this->m_Label, "\t");
strcpy(this->m_OpCode, strtok(_temp, _sep));
_sTok = strtok(NULL, _sep);
strcpy(this->m_Operand, (_sTok == NULL ? "\t" : _sTok));
break;
default:
strcpy(this->m_Label, strtok(_temp, _sep));
strcpy(this->m_OpCode, strtok(NULL, _sep));
strcpy(this->m_Operand, strtok(NULL, _sep));
break;
}
}
char* CCmdLine::getLine(char* d, unsigned int maxlength)
{
memcpy(d, this->m_Line, maxlength);
return d;
}
char* CCmdLine::getLabel(char* d, unsigned int maxlength)
{
memcpy(d, this->m_Label, maxlength);
return d;
}
char* CCmdLine::getOpCode(char* d, unsigned int maxlength)
{
memcpy(d, this->m_OpCode, maxlength);
return d;
}
char* CCmdLine::getOperand(char* d, unsigned int maxlength)
{
memcpy(d, this->m_Operand, maxlength);
return d;
}
bool CCmdLine::isComment()
{
return (this->m_Line[0] == CHARPERIOD);
}
bool CCmdLine::isAddCode(AddTable* d, unsigned int _addcode)
{
bool _b = false;
unsigned int _len = MemorySize(arAddTable, AddTable);
for (unsigned int i = 0; i < _len; i++)
{
if (stricmp(this->m_OpCode, arAddTable[i]._name) == 0)
{
_b = true;
memcpy(d, arAddTable + i, sizeof(AddTable));
break;
}
}
_b = _b ? (d->_addCode == _addcode) : false;
return _b;
}
bool CCmdLine::isOpCode(OpTable* d)
{
bool _b = false;
unsigned int _len = MemorySize(arOpTable, OpTable);
for (unsigned int i = 0; i < _len; i++)
{
if (stricmp(this->m_OpCode, 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 (stricmp(this->m_Label, arSymTable[i]._name) == 0)
{
_b = true;
memcpy(d, arSymTable + i, sizeof(SymTable));
break;
}
}
return _b;
}
unsigned int getByteLen(const char *byteOperand, unsigned int maxlength)
{
unsigned int _len = 0;
char _temp[MAXLENSTRING], _byte[MAXLENSTRING], *_sep = "\'";
memcpy(_temp, byteOperand, maxlength);
strupr(_temp);
strtok(_temp, _sep);
strcpy(_byte, strtok(NULL, _sep));
switch (_temp[0])
{
case 'C':
_len = (unsigned int)strlen(_byte);
break;
case 'X':
_len = (unsigned int)(strlen(_byte) / 2);
break;
default:
break;
}
return _len;
}
/*Pass First*/
bool funPassFirst(std::fstream& SOURCE, std::fstream& INTERMEDIATE, std::fstream& SYMTABLE)
{
bool bFunRet = true;
CCmdLine cCLine;
Counters Ctrs;
_tempS _tmps;
MemoryInit(&Ctrs, sizeof(Counters));
MemoryInit(&_tmps, sizeof(_tempS));
/*read first input line*/
SOURCE.getline(_tmps._tempGet, MAXLENSTRING);
cCLine = _tmps._tempGet;
/*IF OPCODE = 'START' THEN*/
if (cCLine.isAddCode(&_tmps._tempAdd, 0x0))
{/*OPCODE='START'*/
/*save #[OPERAND] as starting address*/
Ctrs.nStartAdd = strtol(cCLine.getOperand(_tmps._tempGet, MAXLENSTRING), NULL, INTHEX);
/*initialize LOCCTR to starting address*/
Ctrs.nPCtr = Ctrs.nStartAdd;
/*write line to intermediate file*/
strcpy(_tmps._tempPut, strupr(cCLine.getOperand(_tmps._tempGet, MAXLENSTRING)));
strcat(_tmps._tempPut, "\t");
strcat(_tmps._tempPut, cCLine.getLine(_tmps._tempGet, MAXLENSTRING));
INTERMEDIATE << _tmps._tempPut << std::endl;
/*read next input line*/
SOURCE.getline(_tmps._tempGet, MAXLENSTRING);
cCLine = _tmps._tempGet;
}
else
{
Ctrs.nPCtr = 0;
}/*if START*/
//
/*WHILE OPCODE != 'END' DO*/
while (!(cCLine.isAddCode(&_tmps._tempAdd, 0x1)))
{
/*IF this is not a comment line THEN*/
cCLine.getLine(_tmps._tempGet, MAXLENSTRING);
if (!cCLine.isComment())
{
/*IF there is a symbol in the LABEL field THEN*/
cCLine.getLabel(_tmps._tempGet, MAXLENSTRING);
if ((_tmps._tempGet[0] != CHARTAB) && (_tmps._tempGet[0] != CHARSPACE))
{
/*search SYMTAB for LABEL*/
if (cCLine.isSymbol(&_tmps._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[Ctrs.nSymCtr]._name, _tmps._tempGet);
arSymTable[Ctrs.nSymCtr]._locctr = Ctrs.nPCtr;
Ctrs.nSymCtr++;
}
}/*if symbol*/
if (cCLine.isOpCode(&_tmps._tempOp))
{/*found OPCODE*/
Ctrs.LOCCTR = Ctrs.nPCtr;
Ctrs.nPCtr += 3;
}
else if (cCLine.isAddCode(&_tmps._tempAdd, 0x3))
{/*WORD*/
Ctrs.LOCCTR = Ctrs.nPCtr;
Ctrs.nPCtr += 3;
}
else if (cCLine.isAddCode(&_tmps._tempAdd, 0x5))
{/*RESW*/
Ctrs.LOCCTR = Ctrs.nPCtr;
Ctrs.nPCtr += 3 * strtol(cCLine.getOperand(_tmps._tempGet, MAXLENSTRING), NULL, INTDEC);
}
else if (cCLine.isAddCode(&_tmps._tempAdd, 0x4))
{/*RESB*/
Ctrs.LOCCTR = Ctrs.nPCtr;
Ctrs.nPCtr += strtol(cCLine.getOperand(_tmps._tempGet, MAXLENSTRING), NULL, INTDEC);
}
else if (cCLine.isAddCode(&_tmps._tempAdd, 0x2))
{/*BYTE*/
Ctrs.LOCCTR = Ctrs.nPCtr;
Ctrs.nPCtr += getByteLen(cCLine.getOperand(_tmps._tempGet, MAXLENSTRING), MAXLENSTRING);
}
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*/
cCLine.getLine(_tmps._tempGet, MAXLENSTRING);
if (!cCLine.isComment())
{
MemoryInit(_tmps._tempPut, MAXLENSTRING);
strcpy(_tmps._tempPut, strupr(itoa(Ctrs.LOCCTR, _tmps._temp, INTHEX)));
strcat(_tmps._tempPut, "\t");
strcat(_tmps._tempPut, _tmps._tempGet);
}
else
{
strcpy(_tmps._tempPut, _tmps._tempGet);
}
INTERMEDIATE << _tmps._tempPut << std::endl;
/*read next input line*/
SOURCE.getline(_tmps._tempGet, MAXLENSTRING);
cCLine = _tmps._tempGet;
}/*while not END*/
//
/*write last line to intermediate file*/
strcpy(_tmps._tempPut, cCLine.getLine(_tmps._tempGet, MAXLENSTRING));
INTERMEDIATE << _tmps._tempPut << std::endl;
strcpy(_tmps._tempPut, ".\n.\tCOMMENT\n.\tLength_of_the_SIC_Source= ");
strcat(_tmps._tempPut, strupr(itoa(Ctrs.nPCtr - Ctrs.nStartAdd, _tmps._temp, INTHEX)));
strcat(_tmps._tempPut, "\n.\n");
INTERMEDIATE << _tmps._tempPut << TXTVER << std::endl;
for (unsigned int i = 0; i < Ctrs.nSymCtr; i++)
{
strcpy(_tmps._tempPut, arSymTable[i]._name);
strcat(_tmps._tempPut, "\t");
strcat(_tmps._tempPut, strupr(itoa(arSymTable[i]._locctr, _tmps._temp, INTHEX)));
strcat(_tmps._tempPut, "\n");
SYMTABLE << _tmps._tempPut;
}
return bFunRet;
}/*Pass First*/
void VerRecord(bool b)
{
if (b)
{
for (unsigned int i = 0; i < 0x40; i++) { std::cout << "="; }
std::cout << std::endl;
std::cout << TXTVER;
for (unsigned int i = 0; i < 0x40; i++) { std::cout << "="; }
std::cout << std::endl;
}
else
{
std::fstream fVer;
mkdir(DIRFOLDER);
fVer.open("intermed\\README.txt", std::ios::out);
if (!fVer.is_open()) { return; }
fVer << TXTVER;
fVer.close();
}
}
#include <iostream>
#include <fstream>
#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 CHARPERIOD '.'
#define CHARSPACE 0x20
#define CHARTAB '\t'
#define DIRFOLDER "intermed"
#define INTDEC 0xA
#define INTHEX 0x10
#define MAXLENPATH 0x104
#define MAXLENSTRING 0x80
#define MAXSYM 0x40
#define MemoryInit(_mem, _length) (memset((_mem), 0x0, (_length)))
#define MemorySize(_mem, _type) (sizeof(_mem) / sizeof(_type))
//
/*Address Table*/
typedef struct addtable
{
char _name[MAXLENSTRING];
unsigned int _addCode;
}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;
// Counters
typedef struct counters
{
/*start address*/
unsigned int nStartAdd;
/*program counter*/
unsigned int nPCtr;
/*symbol table counter*/
unsigned int nSymCtr;
// locctr for symbol table
unsigned int LOCCTR;
}Counters;
//
// temporary memory
typedef struct _tempStruct
{
OpTable _tempOp;
AddTable _tempAdd;
SymTable _tempSym;
char _tempGet[MAXLENSTRING], _tempPut[MAXLENSTRING], _temp[MAXLENSTRING];
}_tempS;
//
// Class CCmdLine
class CCmdLine
{
public:
CCmdLine();
CCmdLine(const CCmdLine& c);
CCmdLine& operator=(const CCmdLine& c);
CCmdLine& operator=(const char* s);
~CCmdLine();
/*set a command line*/
void setLine(const char* s, unsigned int maxlength);
/*get a command line*/
char* getLine(char* d, unsigned int maxlength);
/*get label from command line*/
char* getLabel(char* d, unsigned int maxlength);
/*get OP code from command line*/
char* getOpCode(char* d, unsigned int maxlength);
/*get operand from command line*/
char* getOperand(char* d, unsigned int maxlength);
/*check Comment*/
bool isComment();
/*check Address Table*/
bool isAddCode(AddTable* d, unsigned int _addcode);
/*check OP code Table*/
bool isOpCode(OpTable* d);
/*check symbol table*/
bool isSymbol(SymTable* d);
private:
char *m_Line, *m_Label, *m_OpCode, *m_Operand;
};
void VerRecord(bool b);
/*Count BYTE length*/
unsigned int getByteLen(const char *byteOperand, unsigned int maxlength);
/*Pass First*/
bool funPassFirst(std::fstream& SOURCE, std::fstream& INTERMEDIATE, std::fstream& SYMTABLE);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment