first commit

This commit is contained in:
Shawn Quick 2019-11-11 15:56:03 -08:00
commit b7cb4a9afa
104 changed files with 68185 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
**/build

42
CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.0)
set(CMAKE_BUILD_TYPE Debug)
set(APPVERSION "1.0.0")
set(LIBRARY_NAME pal)
include(./lib${LIBRARY_NAME}/cmake/CMakeHeader.txt)
set(SOURCE
${PROJECT_ROOT}/${PROJECT_ID}.cpp
${PROJECT_ROOT}/asm.cpp
${PROJECT_ROOT}/opcodes.cpp
${PROJECT_ROOT}/eval.cpp
)
include_directories(BEFORE
${PROJECT_ROOT}
${PROJECT_ROOT}/lib${LIBRARY_NAME}/include/${LIBRARY_NAME}
)
add_subdirectory(${PROJECT_ROOT}/lib${LIBRARY_NAME})
include(${PROJECT_ROOT}/lib${LIBRARY_NAME}/cmake/CMakeApp.txt)
add_executable( ${PROJECT_NAME} ${SOURCE})
target_link_libraries (
${PROJECT_NAME}
${LIBRARY_NAME}
pthread
PocoFoundation
PocoNet
PocoUtil
PocoNetSSL
PocoCrypto
)
include(./lib${LIBRARY_NAME}/cmake/CMakeCommands.txt)

1
LICENSE Normal file
View File

@ -0,0 +1 @@
#GPL Licence

47
Makefile Normal file
View File

@ -0,0 +1,47 @@
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
V?=
S=
ifneq ("$V","")
S="VERBOSE=1"
else
.SILENT:
endif
all:
-mkdir -p ./build
-cd ./build && cmake .. && $(MAKE) $S
distclean:
rm -rf build app/build sgqlib/build
clean:
-cd ./build && $(MAKE) clean
depend:
-cd ./build && $(MAKE) depend
rebuild:
-cd ./build && $(MAKE) rebuild_cache
lib:
-cd ./build && $(MAKE) sgq
run:
-cd ./build && $(MAKE) run
install:
-cd ./build && cmake -P cmake_install.cmake
asm:
qasm src/testfile.s
#cd src/asm && ../qasm main.s

1
README Normal file
View File

@ -0,0 +1 @@
Merlin Compatible assembler/linker (and more) for linux

1
app.h Symbolic link
View File

@ -0,0 +1 @@
qasm.h

920
asm.cpp Normal file
View File

@ -0,0 +1,920 @@
#define ADD_ERROR_STRINGS
#include "asm.h"
#include "eval.h"
#define CLASS MerlinLine
CLASS::CLASS()
{
clear();
}
CLASS::CLASS(std::string line)
{
clear();
set(line);
}
void CLASS::setError(uint32_t ecode)
{
errorcode = ecode;
}
void CLASS::print(uint32_t lineno)
{
int i, l;
l = outbytect;
if (l > 4)
{
l = 4;
}
//if ((opflags&OP_STD)!=OP_STD)
if ((opcodelower != "inc") && (opcodelower != "ldx") && (opcodelower != "stx"))
{
//return;
}
if (errorcode > 0)
{
if (errorcode >= errFatal)
{
SetColor(CL_WHITE | CL_BOLD | BG_RED);
}
else
{
SetColor(CL_YELLOW | CL_BOLD | BG_NORMAL);
}
}
else
{
SetColor(CL_WHITE | CL_BOLD | BG_NORMAL);
}
bool empty = false;
if ((lable == "") && (opcode == "") && (operand == ""))
{
empty = true;
}
int b = 4;
printf("%02X ", addressmode);
printf("%6d", lineno + 1);
if (!empty)
{
printf(" %06X:", startpc);
}
else
{
printf(" ");
}
for (i = 0; i < l; i++)
{
printf("%02X ", outbytes[i]);
}
for (i = l; i < b; i++)
{
printf(" ");
}
if (empty)
{
printf("%s", comment.c_str());
}
else
{
printf("%-12s %-8s %-10s ", lable.c_str(), opcode.c_str(), operand.c_str());
if (errorcode > 0)
{
printf(":[Error] %s", errStrings[errorcode].c_str());
}
else
{
printf("%s", comment.c_str());
}
}
if (errorcode > 0)
{
SetColor(CL_NORMAL | BG_NORMAL);
}
printf("\n");
}
void CLASS::clear()
{
syntax = SYNTAX_MERLIN;
lable = "";
opcode = "";
opcodelower = "";
operand = "";
comment = "";
operand_expr = "";
addrtext = "";
bytect = 0;
opflags = 0;
pass0bytect = 0;
startpc = 0;
errorcode = 0;
inbytect = 0;
outbytect = 0;
outbytes.clear();
addressmode = 0;
expr_value = 0;
flags = 0;
outbytes.clear();
}
void CLASS::set(std::string line)
{
int state = 0;
int l = line.length();
int i = 0;
char c,delim;
clear();
//printf("line: |%s|\n", line.c_str());
while (i < l)
{
c = line[i++];
//printf("state: %d\n",state);
switch (state)
{
case 0: // start of line state
if ((c == ';') || (c == '*'))
{
comment += c;
state = 7;
}
else if (c > ' ')
{
lable += c;
state = 1;
}
else
{
state = 2;
};
break;
case 1: // read in entire lable until whitespace
if (c > ' ')
{
lable += c;
}
else
{
state = 2;
}
break;
case 2: // read whitespace between label and opcode
if (c == ';')
{
comment += c;
state = 7;
}
else if (c > ' ')
{
opcode += c;
state = 3;
}
break;
case 3:
if (c > ' ')
{
opcode += c;
}
else
{
state = 4;
}
break;
case 4: // read whitespace between opcode and operand
if (c == ';')
{
comment += c;
state = 7;
}
else if (c > ' ')
{
operand += c;
if (c == '\'')
{
state = 8;
}
else
{
state = 5;
}
}
break;
case 5:
if ((c == '\'') || (c=='"'))
{
delim=c;
operand += c;
state = 8;
}
else if (c > ' ')
{
operand += c;
}
else
{
state = 6;
}
break;
case 6:
if (c > ' ')
{
comment += c;
state = 7;
}
break;
case 7:
comment += c;
break;
case 8:
if (c == delim)
{
operand += c;
state = 5;
}
else
{
operand += c;
}
break;
}
}
opcodelower = Poco::toLower(opcode);
}
#undef CLASS
#define CLASS TFileProcessor
CLASS::CLASS()
{
}
CLASS::~CLASS()
{
}
void CLASS::errorOut(uint16_t code)
{
printf("error: %d\n", code);
}
void CLASS::init(void)
{
syntax = SYNTAX_MERLIN;
}
void CLASS::complete(void)
{
}
void CLASS::process(void)
{
}
int CLASS::doline(int lineno, std::string line)
{
int res = -1;
return (res);
}
int CLASS::processfile(std::string &p)
{
//Poco::File fn(p);
int c;
int res = -1;
uint32_t linect;
bool done, valid;
std::string p1;
std::string line, op;
linect = 0;
done = false;
Poco::Path tp(p);
Poco::Path path = tp.makeAbsolute();
valid = true;
p1 = tp.toString();
Poco::File fn(p1);
if (!fn.exists())
{
fn = Poco::File(p1 + ".s");
if (!fn.exists())
{
fn = Poco::File(p1 + ".S");
if (!fn.exists())
{
fn = Poco::File(p1 + ".mac");
if (!fn.exists())
{
valid = false;
}
}
}
}
p1 = fn.path();
if (valid)
{
std::ifstream f(p1);
if (f.is_open())
{
//printf("file is open\n");
line = "";
while ((!done) && (f.good()) && (!f.eof()))
{
c = f.get();
if (c == 0x8D) // merlin line ending
{
c = 0x0A; // convert to linux
}
if (c == 0x8A) // possible merlin line ending
{
c = 0x00; // ignore
}
c &= 0x7F;
#if 0
//printf("%02X ",c&0x7F);
printf("%c", c);
#else
int x;
switch (c)
{
case 0x0D:
break;
case 0x09:
line += " ";
break;
case 0x0A:
linect++;
x = doline(linect, line);
if (x < 0)
{
done = true;
}
line = "";
break;
default:
if ((c >= ' ') && (c < 0x7F))
{
line += c;
}
else
{
//printf("garbage %08X\n",c);
}
break;
}
#endif
}
if ( (f.eof()))
{
res = 0;
}
}
}
else
{
printf("file %s does not exist\n", p.c_str());
}
//printf("\n\nfile read result: %d\n", res);
return (res);
}
#undef CLASS
#define CLASS T65816Asm
CLASS::CLASS()
{
lines.clear();
}
#define OPHANDLER(ACB) std::bind(ACB, this, std::placeholders::_1, std::placeholders::_2)
CLASS::~CLASS()
{
}
void CLASS::pushopcode(std::string op, uint8_t opcode, uint16_t flags, TOpCallback cb)
{
TSymbol sym;
sym.name = op;
sym.opcode = opcode;
sym.namelc = Poco::toLower(op);
sym.stype = flags;
sym.value = 0;
sym.cb = cb;
std::pair<std::string, TSymbol> p(Poco::toUpper(op), sym);
opcodes.insert(p);
}
TSymbol *CLASS::findSymbol(std::string symname)
{
TSymbol *res = NULL;
auto itr = symbols.find(Poco::toUpper(symname));
if (itr != symbols.end())
{
res = &itr->second;
return (res);
}
return (res);
}
TSymbol *CLASS::addSymbol(std::string sym, uint32_t val, bool replace)
{
TSymbol *res = NULL;
TSymbol *fnd = NULL;
fnd = findSymbol(sym);
if ((fnd != NULL) && (!replace))
{
return (NULL); // it is a duplicate
}
if (fnd != NULL)
{
fnd->value = val;
return (fnd);
}
TSymbol s;
s.name = sym;
s.opcode = 0;
s.namelc = Poco::toLower(sym);
s.stype = 0;
s.value = val;
s.cb = NULL;
std::pair<std::string, TSymbol> p(Poco::toUpper(sym), s);
symbols.insert(p);
res = findSymbol(sym);
return (res);
}
void CLASS::showSymbolTable(void)
{
// Poco::HashTable::Iterator itr;
for (auto itr = symbols.begin(); itr != symbols.end(); itr++)
{
TSymbol ptr = itr->second;
printf("Sym: %-24s 0x%08X\n", ptr.name.c_str(), ptr.value);
}
}
int CLASS::callOpCode(std::string op, MerlinLine &line)
{
int res = -1;
char c;
if (op.length() == 4) // check for 4 digit 'L' opcodes
{
c = op[3];
if ((c >= 'a') || (c <= 'z'))
{
c = c - 0x20;
}
if (c == 'L')
{
op = op.substr(0, 3);
line.flags |= FLAG_LONGADDR;
}
}
//Poco::HashMap<std::string, TSymbol>::ConstIterator ptr;
auto itr = opcodes.find(Poco::toUpper(op));
if (itr != opcodes.end())
{
TSymbol s = itr->second;
if (s.cb != NULL)
{
if (s.stype & OP_ONEBYTE)
{
line.inbytes[0] = (s.opcode);
line.inbytect = 1;
}
res = s.cb(line, s);
if (res == -1)
{
res = -2;
}
}
}
else
{
line.setError(errBadOpcode);
}
return (res);
}
//imp = <no operand>
//imm = #$00
//sr = $00,S
//dp = $00
//dpx = $00,X
//dpy = $00,Y
//idp = ($00)
//idx = ($00,X)
//idy = ($00),Y
//idl = [$00]
//idly = [$00],Y
//isy = ($00,S),Y
//abs = $0000
//abx = $0000,X
//aby = $0000,Y
//abl = $000000
//alx = $000000,X
//ind = ($0000)
//iax = ($0000,X)
//ial = [$000000]
//rel = $0000 (8 bits PC-relative)
//rell = $0000 (16 bits PC-relative)
//bm = $00,$00
typedef struct
{
std::string regEx;
uint16_t addrMode;
std::string text;
std::string expression;
} TaddrMode;
TaddrMode addrRegEx[] =
{
{ "^(?'expr'.+)\\,[s,S]{1}$", syn_s, "e,s"}, // expr,s
{"^[(]{1}(?'expr'.+)[,]{1}[(S|s)]{1}[)]{1}[,]{1}[(Y|y)]{1}$", syn_sy, "(e,s),y"}, // (expr,s),y
{"^#{1}(?'shift'[<,>,^,|]?)(.+)$", syn_imm, "immediate"}, //#expr,#^expr,#|expr,#<expr,#>expr
{"^[(]{1}(?'expr'.+)[,]{1}[x,X]{1}\\)$", syn_diix, "(e,x)"}, // (expr,x)
{"^[(]{1}(?'expr'.+)[\\)]{1}[\\,][(Y|y]{1}$", syn_diiy, "(e),y"}, //(expr),y
{"^[(]{1}(?'expr'.+)[\\)]{1}$", syn_di, "(e)"}, // (expr)
{"^\\[{1}(?'expr'.+)\\]{1}[,]{1}[(Y|y)]{1}$", syn_iyl, "[e],x"}, // [expr],y
{"^\\[(?'expr'.+)\\]$", syn_dil, "[e]"}, // [expr]
{"^(?'expr'.+)[,]{1}[(X|x)]{1}$", syn_absx, "e,x"}, // expr,x
{"^(?'expr'.+)[,]{1}[(Y|y)]{1}$", syn_absy, "e,y"}, // expr,y
{"^(?'expr'.+)[,]{1}(?'expr2'.+)$", syn_bm, "block"}, // block move expr,expr1
{"^(?'expr'.+)$", syn_abs, "absolute"}, // expr (MUST BE LAST)
{"", 0, ""}
};
// opcodes that are only 65C02 (27) - also in 65816
// 0x01 = 6502
// 0x02 = 65C02
// 0x03 = 65816
uint8_t opCodeCompatibility[256] = {
0x00,0x00,0x02,0x02,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x02,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x02,
0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x02,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x02,
0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x02,0x00,0x00,0x02,0x00,0x00,0x01,0x02,0x02,0x00,0x00,0x02,
0x00,0x00,0x02,0x02,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x02,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x02,
0x01,0x00,0x02,0x02,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x01,0x00,0x01,0x02,
0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x02,0x00,0x00,0x02,0x00,0x00,0x01,0x02,0x02,0x00,0x00,0x02,
0x00,0x00,0x02,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
0x00,0x00,0x01,0x02,0x02,0x00,0x00,0x02,0x00,0x00,0x01,0x02,0x02,0x00,0x00,0x02
};
void CLASS::init(void)
{
TFileProcessor::init();
lines.clear();
insertOpcodes();
}
void CLASS::initpass(void)
{
casesen = true;
relocatable = false;
listing = true;
origin = 0;
currentpc = 0;
cpumode = MODE_65816;
mx = 0x00;
currentsym = NULL;
totalbytes = 0;
lineno = 0;
passcomplete = false;
}
void CLASS::complete(void)
{
printf("=== Assembly Complete: %d bytes\n", totalbytes);
if (listing)
{
showSymbolTable();
}
}
int CLASS::evaluate(std::string expr, int64_t &value)
{
int res = -1;
int64_t result = 0;
if (expr.length() > 0)
{
TEvaluator eval(*this);
res = eval.evaluate(expr, result);
//printf("res=%d %08lX\n",res,result);
if (res == 0)
{
value = result;
}
}
else
{
value = 0;
res = 0;
}
return res;
}
int CLASS::getAddrMode(MerlinLine &line)
{
int res = -1;
uint16_t mode = syn_none;
int idx, x;
std::string s, oper;
std::vector<std::string> groups;
oper = line.operand;
if ((line.opcode.length() == 0) || (line.operand.length() == 0))
{
return (syn_implied);
}
idx = 0;
while (mode == syn_none)
{
s = addrRegEx[idx].regEx;
if (s == "")
{
mode = syn_err;
}
else
{
RegularExpression regex(s, 0, true);
groups.clear();
x = 0;
try
{
x = regex.split(oper, 0, groups, 0);
}
catch (...)
{
x = 0;
}
if (x > 0)
{
mode = addrRegEx[idx].addrMode;
line.addrtext = addrRegEx[idx].text;
//cout << "mode: " << line.addrtext << endl;
for (uint32_t i = 0; i < groups.size(); i++)
{
s = groups[i];
if ((s != "^") && (s != "<") && (s != ">") && (s != "|"))
{
line.operand_expr = s;
//printf("line expression=|%s|\n", s.c_str());
}
else
{
// SGQ need to set a flag for a shift and process it after eval
}
}
}
}
idx++;
}
if (mode == syn_none)
{
mode = syn_err;
}
res = mode;
//printf("syn_mode=%d\n", mode);
return (res);
}
int CLASS::parseOperand(MerlinLine &line)
{
int res = -1;
line.operand_expr = "";
int m = getAddrMode(line);
if (m >= 0)
{
res = m;
}
else
{
//errorOut(errBadAddressMode);
}
return (res);
}
void CLASS::process(void)
{
uint32_t l;
int x;
char c;
std::string op, operand;
//uint32_t operand_eval;
//uint16_t addrmode;
MerlinLine *line;
pass = 0;
while (pass < 2)
{
initpass();
l = lines.size();
while ((lineno < l) && (!passcomplete))
{
line = &lines[lineno];
//printf("lineno: %d %d |%s|\n",lineno,l,line->operand.c_str());
op = Poco::toLower(line->opcode);
operand = Poco::toLower(line->operand);
line->startpc = currentpc;
line->bytect = 0;
if ((line->lable != "") && (pass == 0))
{
c = line->lable[0];
switch (c)
{
case ']':
break;
case ':':
break;
default:
addSymbol(line->lable, currentpc, false);
break;
}
}
x = parseOperand(*line);
if (x >= 0)
{
line->addressmode = x;
}
int64_t value = -1;
x=-1;
x = evaluate(line->operand_expr, value);
if (x == 0)
{
value &= 0xFFFFFFFF;
//printf("OPERAND VALUE=%08X\n",value);
line->expr_value = value;
}
else
{
line->expr_value = 0xFFFFFFFF;
}
x = 0;
if (op.length() > 0)
{
x = callOpCode(op, *line);
}
if (x > 0)
{
line->bytect = x;
currentpc += x;
totalbytes += x;
}
if (pass == 0)
{
line->pass0bytect = line->bytect;
}
if (pass == 1)
{
if ((line->pass0bytect != line->bytect) && (line->errorcode == 0))
{
line->setError(errBadByteCount);
}
bool skip = false;
if (op == "lst")
{
if ((operand == "") || (operand == "on"))
{
listing = true;
}
else
{
skip = true;
listing = false;
}
}
if ((!skip) && (listing) && (pass == 1))
{
line->print(lineno);
}
}
lineno++;
}
pass++;
}
}
int CLASS::doline(int lineno, std::string line)
{
int res = 0;
std::string op;
MerlinLine l(line);
op = Poco::toLower(l.opcode);
if (op == "merlin")
{
syntax = SYNTAX_MERLIN;
}
else if (op == "orca")
{
syntax = SYNTAX_ORCA;
}
l.syntax = syntax;
lines.push_back(l);
if ((op == "use") || (op == "put"))
{
//printf("processing % s\n",l.operand.c_str());
processfile(l.operand);
}
return (res);
}
#undef CLASS
#define CLASS T65816Link
CLASS::CLASS()
{
}
CLASS::~CLASS()
{
}
void CLASS::init(void)
{
TFileProcessor::init();
}
void CLASS::process(void)
{
}
void CLASS::complete(void)
{
}
int CLASS::doline(int lineno, std::string line)
{
int res = 0;
return (res);
}
#undef CLASS

229
asm.h Normal file
View File

@ -0,0 +1,229 @@
#pragma once
#include "app.h"
#define OPHANDLER(ACB) std::bind(ACB, this, std::placeholders::_1, std::placeholders::_2)
#define MODE_6502 0
#define MODE_65C02 1
#define MODE_65816 2
#define SYNTAX_MERLIN 0
#define SYNTAX_APW 1
#define SYNTAX_ORCA 2
#define OP_6502 0x01
#define OP_65C02 0x02
#define OP_65816 0x04
#define OP_PSUEDO 0x08
#define OP_ONEBYTE 0x10
#define OP_SPECIAL 0x20
#define OP_CLASS0 0x0000
#define OP_CLASS1 0x0100
#define OP_CLASS2 0x0200
#define OP_CLASS3 0x0300
#define OP_CLASS4 0x0400
#define OP_STD (0x1000 | OP_CLASS1 | OP_6502)
#define OP_ASL (0x2000 | OP_CLASS2 | OP_6502)
#define OP_STX (0x3000 | OP_CLASS2 | OP_6502)
#define OP_C0 (0x4000 | OP_CLASS0 | OP_6502)
enum asmErrors
{
errNone,
errWarn,
errIncomplete,
errFatal,
errBadAddressMode,
errBadOpcode,
errIncompatibleOpcode,
errBadByteCount,
errMAX
};
#ifdef ADD_ERROR_STRINGS
std::string errStrings[errMAX] = {
"No Error",
"Warning",
"Unfinished Opcode",
"Fatal",
"Unsupported Addressing Mode",
"Unknown Opcode",
"Opcode not available under CPU selecton",
"Byte output differs between passes",
};
#else
extern std::string errStrings[errMAX];
extern uint8_t opCodeCompatibility[256];
#endif
enum
{
syn_err = -1, // error - not recognized
syn_none = 0, // should never be returned 0
syn_implied, // no operand 1
syn_s, // expr,s 2
syn_sy, // (expr,s),y 3
syn_imm, // #expr 4
syn_diix, // (expr,x) 5
syn_diiy, // (expr),y 6
syn_di, // (expr) 7
syn_iyl, // [expr],y 8
syn_dil, // [expr] 9
syn_absx, // expr,x 10
syn_absy, // expr,y 11
syn_bm, // block move 12
syn_abs, // expr 13
syn_MAX
};
#define FLAG_LONGADDR 0x01
class MerlinLine
{
public:
uint8_t syntax;
std::string lable;
std::string opcode;
std::string opcodelower;
std::string operand;
std::string operand_expr;
std::string comment;
std::string addrtext;
uint32_t flags;
uint16_t opflags;
uint32_t startpc;
uint32_t addressmode;
uint32_t expr_value;
uint32_t errorcode;
uint8_t inbytect;
uint8_t inbytes[256];
uint16_t pass0bytect;
uint16_t bytect;
uint16_t outbytect;
std::vector<uint8_t> outbytes;
public:
MerlinLine();
MerlinLine(std::string line);
void clear();
void set(std::string line);
void print(uint32_t lineno);
void setError(uint32_t ecode);
};
class TFileProcessor
{
protected:
uint8_t syntax;
public:
TFileProcessor();
virtual ~TFileProcessor();
virtual int processfile(std::string &p);
virtual void init(void);
virtual int doline(int lineno, std::string line);
virtual void process(void);
virtual void complete(void);
virtual void errorOut(uint16_t code);
};
class TSymbol;
typedef int (*TOpCB)(MerlinLine &line, TSymbol &sym);
typedef std::function<int (MerlinLine &line, TSymbol &sym)> TOpCallback;
class TSymbol
{
public:
std::string namelc;
std::string name;
uint32_t value;
uint16_t stype;
uint8_t opcode;
TOpCallback cb;
Poco::HashMap<std::string, TSymbol>locals;
TSymbol()
{
locals.clear();
};
};
class T65816Asm : public TFileProcessor
{
protected:
bool passcomplete;
bool casesen;
bool relocatable;
bool listing;
uint32_t totalbytes;
uint32_t lineno;
uint32_t origin;
uint8_t mx;
uint8_t cpumode; // 0=6502, 1=65C02, 2=65816
TSymbol *currentsym;
std::vector<MerlinLine> lines;
Poco::HashMap<std::string, TSymbol>opcodes;
Poco::HashMap<std::string, TSymbol> macros;
Poco::HashMap<std::string, TSymbol> symbols;
public:
uint16_t pass;
uint32_t currentpc;
T65816Asm();
virtual ~T65816Asm();
virtual void init(void);
virtual int doline(int lineno, std::string line);
virtual void process(void);
virtual void complete(void);
void insertOpcodes(void);
void pushopcode(std::string op, uint8_t opcode, uint16_t flags, TOpCallback cb);
int callOpCode(std::string op, MerlinLine &line);
TSymbol *findSymbol(std::string sym);
TSymbol *addSymbol(std::string sym, uint32_t val, bool replace);
void initpass(void);
void showSymbolTable(void);
int evaluate(std::string expr, int64_t &value);
int parseOperand(MerlinLine &line);
int getAddrMode(MerlinLine &line);
void setOpcode(MerlinLine &line, uint8_t op);
int doPSEUDO(MerlinLine &line, TSymbol &sym);
int doEND(MerlinLine &line, TSymbol &sym);
int doBase6502(MerlinLine &line, TSymbol &sym);
int doBRANCH(MerlinLine &line, TSymbol &sym);
int doJMP(MerlinLine &line, TSymbol &sym);
int doAddress(MerlinLine &line, TSymbol &sym);
int doNoPattern(MerlinLine &line, TSymbol &sym);
int doEQU(MerlinLine &line, TSymbol &sym);
int doXC(MerlinLine &line, TSymbol &sym);
int doMX(MerlinLine &line, TSymbol &sym);
int doBYTE(MerlinLine &line, TSymbol &sym);
int doUNK(MerlinLine &line, TSymbol &sym);
};
class T65816Link : public TFileProcessor
{
public:
T65816Link();
virtual ~T65816Link();
virtual void init(void);
virtual int doline(int lineno, std::string line);
virtual void process(void);
virtual void complete(void);
};

14
config.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
// define application options here
#define PAL_APPCLASS TMyCustomApp
//#define SERVERAPP
#define ENABLE_SSL
#define USE_LOGGER
// help text
#define HELP_USAGE "<options> filename"
#define HELP_PURPOSE "a program that does something"

609
eval.cpp Normal file
View File

@ -0,0 +1,609 @@
#include "asm.h"
#include "eval.h"
#include <string.h>
#include <stdio.h>
#define CLASS TEvaluator
std::ostream& operator<<(std::ostream& os, const Token& token)
{
os << token.str;
return os;
}
CLASS::CLASS(T65816Asm &_asm) : assembler(_asm)
{
}
CLASS::~CLASS()
{
}
std::deque<Token> CLASS::exprToTokens(const std::string& expr)
{
std::deque<Token> tokens;
int state = 0;
char c;
char delim;
std::string ident, asc;
std::string ops = "+-*//^!.&()";
std::string c1;
char *tokptr;
char *tptr;
bool numexpect;
Token::Type t;
numexpect = true;
for (const auto* p = expr.c_str(); *p; ++p)
{
c = *p;
c1 = c;
tptr = (char *)c1.c_str();
tokptr = strpbrk(tptr, (const char *)ops.c_str());
// printf("state=%d %c %p\n", state, c,tokptr);
switch (state)
{
default:
printf("bad token state\n");
state = 0;
break;
case 11:
if ((c < ' ') || (c == delim))
{
// SGQ - convert ascii to a number here
asc = "0";
//printf("ident=|%s|\n",ident.c_str());
if (ident.length() > 0)
{
// SGQ - convert ascii to a number here
}
t = Token::Type::Number;
int pr = 1; // precedence
bool ra = false; // rightAssociative
tokens.push_back(Token
{
t, asc, pr, ra
});
ident = "";
state = 0;
if (c != delim)
{
p--;
}
}
else
{
ident += c;
}
break;
case 10:
case 20:
if ((c <= ' ') || (tokptr != NULL))
{
if (ident.length() > 0)
{
if (state == 20)
{
t = Token::Type::Symbol;
}
else
{
t = Token::Type::Number;
}
int pr = 1; // precedence
bool ra = false; // rightAssociative
tokens.push_back(Token
{
t, ident, pr, ra
});
ident = "";
}
state = 0;
p--;
}
else
{
ident += c;
}
break;
case 0:
if ((c == '$') && (numexpect))
{
state = 10;
ident += c;
numexpect = false;
}
else if ((c == '*') && (numexpect))
{
numexpect = false;
state = 20;
ident += c;
}
else if ((c == '%') && (numexpect))
{
state = 10;
ident += c;
numexpect = false;
}
else if ((c == '\'') && (numexpect))
{
delim = c;
state = 11;
numexpect = false;
}
else if ((c == '"') && (numexpect))
{
delim = c;
state = 11;
numexpect = false;
}
else if (((c == '-') || (c == '+')) && (numexpect))
{
state = 10;
ident += c;
}
else if (isdigit(c))
{
state = 10;
ident += c;
numexpect = false;
}
else if ((c >= 'a') && (c <= 'z'))
{
state = 20;
ident += c;
numexpect = false;
}
else if ((c >= 'A') && (c <= 'A'))
{
state = 20;
ident += c;
numexpect = false;
}
else if ((tokptr != NULL) && (!numexpect))
{
t = Token::Type::Unknown;
int pr = -1; // precedence
bool ra = false; // rightAssociative
switch (c)
{
default: break;
case '(': t = Token::Type::LeftParen; break;
case ')': t = Token::Type::RightParen; break;
case '!': t = Token::Type::Operator; pr = 5; break;
case '.': t = Token::Type::Operator; pr = 5; break;
case '&': t = Token::Type::Operator; pr = 5; break;
case '^': t = Token::Type::Operator; pr = 4; ra = true; break;
case '*': t = Token::Type::Operator; pr = 3; break;
case '/': t = Token::Type::Operator; pr = 3; break;
case '+': t = Token::Type::Operator; pr = 2; break;
case '-': t = Token::Type::Operator; pr = 2; break;
}
tokens.push_back(Token
{
t, std::string(1, c), pr, ra
});
numexpect = true;
}
}
}
return tokens;
}
std::deque<Token> CLASS::shuntingYard(const std::deque<Token>& tokens)
{
std::deque<Token> queue;
std::vector<Token> stack;
TSymbol *sym;
char buff[128];
// While there are tokens to be read:
for (auto token : tokens)
{
// Read a token
switch (token.type)
{
case Token::Type::Symbol:
token.type = Token::Type::Number;
if (token.str == "*")
{
sprintf(buff, "%u", assembler.currentpc);
token.str = buff;
}
else
{
sym = assembler.findSymbol(token.str);
if (sym != NULL)
{
sprintf(buff, "%u", sym->value);
token.str = buff;
}
else
{
token.str = "-1";
}
}
queue.push_back(token);
break;
case Token::Type::Number:
// If the token is a number, then add it to the output queue
queue.push_back(token);
break;
case Token::Type::Operator:
{
// If the token is operator, o1, then:
const auto o1 = token;
// while there is an operator token,
while (!stack.empty())
{
// o2, at the top of stack, and
const auto o2 = stack.back();
// either o1 is left-associative and its precedence is
// *less than or equal* to that of o2,
// or o1 if right associative, and has precedence
// *less than* that of o2,
if (
(! o1.rightAssociative && o1.precedence <= o2.precedence)
|| ( o1.rightAssociative && o1.precedence < o2.precedence)
)
{
// then pop o2 off the stack,
stack.pop_back();
// onto the output queue;
queue.push_back(o2);
continue;
}
// @@ otherwise, exit.
break;
}
// push o1 onto the stack.
stack.push_back(o1);
}
break;
case Token::Type::LeftParen:
// If token is left parenthesis, then push it onto the stack
stack.push_back(token);
break;
case Token::Type::RightParen:
// If token is right parenthesis:
{
bool match = false;
while (! stack.empty())
{
// Until the token at the top of the stack
// is a left parenthesis,
const auto tos = stack.back();
if (tos.type != Token::Type::LeftParen)
{
// pop operators off the stack
stack.pop_back();
// onto the output queue.
queue.push_back(tos);
}
// Pop the left parenthesis from the stack,
// but not onto the output queue.
stack.pop_back();
match = true;
break;
}
if (!match && stack.empty())
{
// If the stack runs out without finding a left parenthesis,
// then there are mismatched parentheses.
printf("RightParen error (%s)\n", token.str.c_str());
return queue;
}
}
break;
default:
printf("error (%s)\n", token.str.c_str());
return queue;
break;
}
//debugReport(token, queue, stack);
}
// When there are no more tokens to read:
// While there are still operator tokens in the stack:
while (! stack.empty())
{
// If the operator token on the top of the stack is a parenthesis,
// then there are mismatched parentheses.
if (stack.back().type == Token::Type::LeftParen)
{
printf("Mismatched parentheses error\n");
return queue;
}
// Pop the operator onto the output queue.
queue.push_back(std::move(stack.back()));
stack.pop_back();
}
//debugReport(Token { Token::Type::Unknown, "End" }, queue, stack);
//Exit.
return queue;
}
int CLASS::parseNumber(std::string n, int64_t &val)
{
int res = -1;
int state = 0;
char c;
std::string s;
uint32_t i, l;
bool valid = false;
bool err = false;
bool neg = false;
int base = 10;
int64_t tval = 0;
val = 0;
i = 0;
l = n.length();
s = "";
for (i = 0; i < l; i++)
{
c = n[i];
switch (state)
{
case 0:
if (c == '$')
{
state = 10;
}
else if (c == '%')
{
state = 20;
}
else if ((c == '-') && (!valid))
{
neg = !neg;
}
else if (isdigit(c))
{
s += c;
valid = true;
state = 1;
tval = c - '0';
}
else
{
state = 99;
}
break;
case 1:
if (isdigit(c))
{
s += c;
tval *= 10;
tval += c - '0';
}
else
{
state = 99;
}
break;
case 10:
base = 16;
if ((c >= 'a') && (c <= 'f'))
{
c = c - 0x20; // make it uppercase
s += c;
tval <<= 4;
tval |= (c - 'A') + 10;
valid = true;
}
else if ((c >= 'A') && (c <= 'F'))
{
s += c;
tval <<= 4;
tval |= (c - 'A') + 10;
valid = true;
}
else if ((c >= '0') && (c <= '9'))
{
s += c;
tval <<= 4;;
tval += c - '0';
valid = true;
}
else { state = 99; }
break;
case 20:
base = 2;
if ((c >= '0') && (c <= '1'))
{
s += c;
tval <<= 1;
if (c == '1')
{
tval |= 1;
}
valid = true;
}
else if (c == '_')
{
// allow these in binary
}
else { state = 99; }
break;
case 99:
// if you get into this state there is an error
break;
}
}
if (tval > (int64_t)0xFFFFFFFF)
{
err = true;
}
if ((state == 99) || (err))
{
valid = false;
err = true;
val = -1;
}
if ((valid) && (!err))
{
if (neg)
{
tval = -tval;
}
val = tval;
res = 0;
}
return (res);
}
int CLASS::evaluate(std::string & e, int64_t &res)
{
// const std::string expr = "3+4*2/(1-5)^2^3"; // Wikipedia's example
// const std::string expr = "20-30/3+4*2^3";
int errcode = -1;
res = -1;
int u;
int64_t val;
std::string expr = Poco::trim(e);
expr += " "; // add a space at end to make parsing easier
const auto tokens = exprToTokens(expr);
auto queue = shuntingYard(tokens);
std::vector<int64_t> stack;
// printf("\nCalculation\n");
//printf("|%-3s|%-32s|%-10s|\n", "Tkn", "Queue", "Stack");
while (! queue.empty())
{
std::string op;
const auto token = queue.front();
queue.pop_front();
switch (token.type)
{
case Token::Type::Symbol:
stack.push_back(std::stoi((char *)"0"));
//op = "Push " + token.str;
break;
case Token::Type::Number:
val = 0;
u = parseNumber(token.str, val);
if (u < 0)
{
val = -1;
}
stack.push_back(val);
//op = "Push " + token.str;
break;
case Token::Type::Operator:
{
// SGQ
// bug here if there isn't something on both stacks for the operator to work on
auto rhs = -1;
auto lhs = -1;
if (stack.size() > 1)
{
rhs = stack.back();
stack.pop_back();
lhs = stack.back();
stack.pop_back();
}
switch (token.str[0])
{
default:
printf("Operator error [%s]\n", token.str.c_str());
return (-1);
break;
case '^':
stack.push_back(static_cast<int>(pow(lhs, rhs)));
break;
case '*':
stack.push_back(lhs * rhs);
break;
case '/':
if (rhs != 0)
{
stack.push_back(lhs / rhs);
}
else
{
stack.push_back(0);
}
break;
case '+':
stack.push_back(lhs + rhs);
break;
case '-':
stack.push_back(lhs - rhs);
break;
case '!':
stack.push_back(lhs ^ rhs);
break;
case '&':
stack.push_back(lhs & rhs);
break; case '.':
stack.push_back(lhs | rhs);
break;
}
//op = "Push " + std::to_string(lhs) + " " + token.str + " " + std::to_string(rhs);
}
break;
default:
//printf("Token error\n");
return (-1);
}
//debugReport(token, queue, stack, op);
}
int64_t v = -1;
if (stack.size() > 0)
{
v = stack.back();
}
errcode = 0;
res = v;
if (assembler.pass > 0)
{
//printf("result = %16ld 0x%08lX |%s|\n", v, v, e.c_str());
}
return (errcode);
}

90
eval.h Normal file
View File

@ -0,0 +1,90 @@
#pragma once
// Shunting-yard Algorithm
// http://en.wikipedia.org/wiki/Shunting-yard_algorithm
//
// https://ideone.com/kn4FUu
//
#include "asm.h"
#include <functional>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <stdio.h>
#include <math.h>
#define CLASS TEvaluator
class T65816Asm;
class Token
{
public:
enum Type
{
Unknown = 0,
Number,
Symbol,
Operator,
LeftParen,
RightParen,
};
Token(Type t, const std::string& s, int prec = -1, bool ra = false)
: type { t }, str ( s ), precedence { prec }, rightAssociative { ra }
{}
Type type;
std::string str;
int precedence;
bool rightAssociative;
};
class CLASS
{
protected:
T65816Asm &assembler;
public:
CLASS(T65816Asm &_asm);
~CLASS();
std::deque<Token> shuntingYard(const std::deque<Token>& tokens);
std::deque<Token> exprToTokens(const std::string& expr);
int parseNumber(std::string n, int64_t &val);
int evaluate(std::string &expr, int64_t &res);
};
//std::ostream& operator<<(std::ostream& os, const Token& token)
//{
// os << token.str;
// return os;
//}
// Debug output
template<class T, class U>
void debugReport(const Token& token, const T& queue, const U& stack, const std::string& comment = "")
{
std::ostringstream ossQueue;
for (const auto& t : queue)
{
ossQueue << " " << t;
}
std::ostringstream ossStack;
for (const auto& t : stack)
{
ossStack << " " << t;
}
printf("|%-3s|%-32s|%10s| %s\n"
, token.str.c_str()
, ossQueue.str().c_str()
, ossStack.str().c_str()
, comment.c_str()
);
}
#undef CLASS

1
libpal Symbolic link
View File

@ -0,0 +1 @@
/projects/SQ/projects/pocoproj/libpal

682
opcodes.cpp Normal file
View File

@ -0,0 +1,682 @@
#include "asm.h"
#define CLASS T65816Asm
void CLASS::setOpcode(MerlinLine &line, uint8_t op)
{
if (pass > 0)
{
if (cpumode < MODE_65816) // instructions are valid if we are in 65816
{
uint8_t m = opCodeCompatibility[op];
if ((m > 0) && (cpumode < MODE_65C02)) // if the instruction is non-zero, and we are in 6502 base mode, error
{
if (line.errorcode == 0) // don't replace other errors
{
line.setError(errIncompatibleOpcode);
}
}
}
}
line.outbytes.push_back(op);
}
int CLASS::doPSEUDO(MerlinLine &line, TSymbol &sym)
{
return (0);
}
int CLASS::doXC(MerlinLine &line, TSymbol &sym)
{
std::string s;
int res = 0;
if (cpumode < 2)
{
cpumode++;
}
if (line.operand.length() > 0)
{
s = Poco::toUpper(line.operand);
if (s == "OFF")
{
mx = 0x03;
cpumode = MODE_6502;
}
}
return (res);
}
int CLASS::doMX(MerlinLine &line, TSymbol &sym)
{
mx = (uint8_t)(line.expr_value & 0xFF);
//printf("setting MX=%02X\n",mx);
return (0);
}
int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
{
int res = 0;
if (pass == 0)
{
res = -1;
TSymbol *s;
if (line.lable.length() > 0)
{
//printf("EQU: |%s| %08X\n", line.lable.c_str(), line.expr_value);
s = addSymbol(line.lable, line.expr_value, true);
if (s != NULL)
{
res = 0;
}
}
}
return (res);
}
int CLASS::doUNK(MerlinLine &line, TSymbol &sym)
{
int res = -1;
res = 0;
if (pass > 0)
{
line.setError(errIncomplete);
//line.outbytes.push_back(0x00);
line.outbytect = res;
}
return (res);
}
int CLASS::doNoPattern(MerlinLine &line, TSymbol &sym)
{
// this handles a few opcodes that don't fit mathmatically in the opcode table
// the 'sym.opcode' table identifies what each is:
// STZ = 1
// TSB = 2
// TRB = 3
int res,i;
uint8_t err;
uint8_t op;
uint8_t m = line.addressmode;
res = 1;
op = 0x00;
err=errBadAddressMode;
switch (sym.opcode)
{
case 1: // STZ
res++;
op = (m == syn_abs ? 0x64 : op);
op = (m == syn_absx ? 0x74 : op);
if ((op != 0) && (line.expr_value >= 0x100))
{
res++;
op = (op == 0x64) ? 0x9C : op;
op = (op == 0x74) ? 0x9E : op;
}
break;
case 2: // TSB
res++;
op = (m == syn_abs ? 0x04 : op);
if ((op != 0) && (line.expr_value >= 0x100))
{
res++;
op = 0x0C;
}
break;
case 3: // TRB
res++;
op = (m == syn_abs ? 0x14 : op);
if ((op != 0) && (line.expr_value >= 0x100))
{
res++;
op = 0x1C;
}
break;
default:
op=0;
err=errBadOpcode;
break;
}
if (op == 0x00)
{
res = 0;
line.setError(err);
}
if ((pass > 0) && (res > 0))
{
setOpcode(line, op);
for (i = 0; i < (res - 1); i++)
{
line.outbytes.push_back(line.expr_value >> (8 * i));
}
line.outbytect = res;
}
return (res);
}
int CLASS::doAddress(MerlinLine &line, TSymbol &sym)
{
// this routine uses the 'opcode' specifed in the sym.opcode field.
// it also adds the number of bytes stored in the sym.stype field after doing an evaluation
int res, i;
res = 1 + sym.stype;
if (pass > 0)
{
//line.setError(errIncomplete);
setOpcode(line, sym.opcode);
for (i = 0; i < (res - 1); i++)
{
line.outbytes.push_back(line.expr_value >> (i * 8));
}
line.outbytect = res;
}
return (res);
}
int CLASS::doJMP(MerlinLine &line, TSymbol &sym)
{
int res, i;
bool err = false;
uint8_t op;
uint8_t optype = sym.opcode;
uint8_t m = line.addressmode;
res = 3;
op = 0;
if (optype & 0x02) // these are SUBROUTINES
{
op = (m == syn_abs ? 0x20 : op);
op = (m == syn_diix ? 0xFC : op);
if (!(optype & 0x01)) // jsl?
{
res++;
op = 0x22;
}
}
else
{
op = (m == syn_abs ? 0x4C : op);
op = (m == syn_di ? 0x6C : op);
op = (m == syn_diix ? 0x7C : op);
op = (m == syn_dil ? 0xDC : op);
if (!(optype & 0x01)) // JML?
{
op = (m == syn_abs ? 0x5C : op);
}
if ((op == 0xDC) || (op == 0x5C))
{
if (cpumode < MODE_65816)
{
op = 0; // can't do these without an '816
}
res++;
}
}
if (op == 0)
{
err = true;
}
if (err)
{
res = 0;
line.setError(errBadAddressMode);
}
if ((pass > 0) && (res > 0))
{
setOpcode(line, op);
for (i = 0; i < (res - 1); i++)
{
line.outbytes.push_back((line.expr_value >> (8 * i)) & 0xFF);
}
line.outbytect = res;
}
return (res);
}
int CLASS::doBRANCH(MerlinLine & line, TSymbol & sym)
{
int res, i;
res = 2;
uint8_t op = (sym.opcode << 6) & 0xC0;
op |= 0x10; // make it a branch opcode
if (sym.opcode & 0x80)
{
op |= 0x20;
}
if (sym.opcode & 0x40) // BRA
{
op = 0x80;
}
if (sym.opcode & 0x20) // BRL
{
op = 0x82;
res++;
}
if ((pass > 0) && (res > 0))
{
setOpcode(line, op);
for (i = 0; i < (res - 1); i++)
{
line.outbytes.push_back(0x00);
}
line.outbytect = res;
}
return (res);
}
// aaabbbcc
int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
{
int res = 1;
int i;
uint8_t bytelen = 1;
uint8_t cc;
uint8_t op, amode;
uint16_t opflags;
bool err = false;
//std::string opcode = Poco::toUpper(line.opcode);
line.opflags = opflags = sym.stype;
op = (sym.opcode << 5) & 0xE0;
cc = (sym.stype >> 8) & 0x03;
amode = 0xFF;
if ((sym.stype & OP_C0) == OP_C0)
{
uint8_t cc = 0;
uint8_t m = line.addressmode;
uint8_t bbb = 0xFF;
bbb = (m == syn_imm ? 0 : bbb);
bbb = (m == syn_abs ? 1 : bbb);
bbb = (m == syn_absx ? 5 : bbb);
//printf("expr_value=%08X\n",line.expr_value);
if ((sym.opcode == 1) && (m == syn_imm)) //BIT special case
{
cc = 0x01;
op = 0x80;
bbb = 0x02;
}
else if ((bbb > 0) && (line.expr_value >= 0x100))
{
bbb |= 0x02;
}
op |= (bbb << 2) | cc;
goto out;
}
if (cc == 0x01)
{
switch (line.addressmode)
{
case syn_diix: amode = 0; break;
case syn_abs: amode = 1; break;
case syn_imm: amode = 2; break;
case syn_diiy: amode = 4; break;
case syn_absx: amode = 5; break;
case syn_absy: amode = 6; break;
default:
err = true;
break;
}
}
else if (cc == 0x02)
{
switch (line.addressmode)
{
case syn_imm: amode = 0; break;
case syn_abs: amode = 1; break;
case syn_implied: amode = 2; break;
case syn_absy:
if ((opflags & OP_STX) == OP_STX)
{
amode = 5;
}
break;
case syn_absx: amode = 5; break; // this is actually Y addressing because X register is used
default:
err = true;
break;
}
if ((opflags & OP_STX) == OP_STX)
//if ((opcode == "STX") || (opcode == "LDX") || (opcode == "DEC") || (opcode == "INC"))
{
if (line.addressmode == syn_implied)
{
err = true;
}
if (line.addressmode == syn_absx)
{
//err = true;
}
if (cpumode >= MODE_65C02)
{
if (line.addressmode == syn_implied)
{
if ((opflags & (OP_STX | OP_SPECIAL)) == (OP_STX | OP_SPECIAL))
{
if (sym.opcode == 0x07) // INC
{
err = false;
op = 0x1A;
bytelen = 0;
goto out;
}
if (sym.opcode == 0x06) // DEC
{
err = false;
op = 0x3A;
bytelen = 0;
goto out;
}
}
}
}
}
}
if (line.addressmode == syn_imm)
{
uint8_t mask = 0x02;
if (cc == 0x02) // the non accumulator
{
mask = 0x01;
}
if ((mx & mask) == 0)
{
bytelen++;
}
}
else if ((line.addressmode == syn_abs) || (line.addressmode == syn_absx)
|| (line.addressmode == syn_absy))
{
// check here for zero page or not and adjust amode
//printf("addrmode=%d\n",line.addressmode);
if (line.expr_value >= 0x100)
{
bytelen++;
//if ((line.addressmode != syn_absy) && (amode != 6))
if (amode != 6)
{
amode += 2;
}
}
if (line.flags & FLAG_LONGADDR)
{
err = true;
}
}
if (err) // not a 6502 address mode
{
if (cpumode >= MODE_65816)
{
//printf("816\n");
cc = 0x03;
err = false;
switch (line.addressmode)
{
case syn_s: amode = 0; break;
case syn_sy: amode = 4; break;
case syn_di: cc = 0x02; amode = 4; break;
case syn_iyl: amode = 5; break;
case syn_dil: amode = 1; break;
case syn_absx: amode = 7; break;
case syn_abs: amode = 3; break;
default:
//printf("bad syn_mode=%d\n", line.addressmode);
err = true;
break;
}
if (!err)
{
if (line.addressmode == syn_abs)
{
if (line.flags & FLAG_LONGADDR)
{
//amode=7;
}
}
}
}
}
op |= (amode & 0x07) << 2;
op |= cc;
out:
if (err)
{
line.setError(errBadAddressMode);
//printf("bad address mode %d\n",line.addressmode);
op = 0x00;
res = 0;
bytelen = 0;
}
res += bytelen;
if ((pass > 0) && (res > 0))
{
setOpcode(line, op);
for (i = 0; i < (res - 1); i++)
{
line.outbytes.push_back(line.expr_value >> (8 * i));
}
line.outbytect = res;
}
return (res);
}
int CLASS::doEND(MerlinLine & line, TSymbol & sym)
{
int res = 0;
passcomplete = true;
return (res);
}
int CLASS::doBYTE(MerlinLine & line, TSymbol & sym)
{
int res = -1;
res = line.inbytect;
//printf("inbytes=%d %02X\n",res,line.inbytes[0]);
if (pass > 0)
{
setOpcode(line, sym.opcode);
line.outbytect = res;
}
return (res);
}
void CLASS::insertOpcodes(void)
{
pushopcode("=", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEQU));
pushopcode("EQU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEQU));
pushopcode("EXT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ENT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ORG", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DSK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("SAV", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("REL", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("OBJ", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("PUT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("USE", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("VAR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("SAV", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("TYP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("END", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEND));
pushopcode("DUM", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DEND", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("AST", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("CYC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DAT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("EXP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("LST", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("LSTDO", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
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("ASC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DCI", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("INV", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("FLS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("REV", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("STR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DA", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DW", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DDB", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DFB", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DB", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADRL", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("HEX", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DO", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ELSE", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("IF", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("FIN", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ERR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("LUP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("--^", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("MX", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doMX));
pushopcode("PAU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("SW", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("USR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("XC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doXC));
pushopcode("MAC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("EOM", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("<<<", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADC", 0x03, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("AND", 0x01, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("ASL", 0x00, OP_ASL, OPHANDLER(&CLASS::doBase6502));
pushopcode("BCC", 0x02, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BLT", 0x02, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BCS", 0x82, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BGE", 0x82, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BEQ", 0x83, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BIT", 0x01, OP_C0, OPHANDLER(&CLASS::doBase6502));
pushopcode("BMI", 0x80, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BNE", 0x03, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BPL", 0x00, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BRA", 0x40, OP_65816, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BRK", 0x00, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("BRL", 0x20, OP_65816, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BVC", 0x01, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BVS", 0x81, OP_6502, OPHANDLER(&CLASS::doBRANCH));
pushopcode("CLC", 0x18, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("CLD", 0xD8, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("CLI", 0x58, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("CLV", 0xB8, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("CMP", 0x06, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("COP", 0x02, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("CPX", 0x07, OP_C0, OPHANDLER(&CLASS::doBase6502));
pushopcode("CPY", 0x06, OP_C0, OPHANDLER(&CLASS::doBase6502));
pushopcode("DEC", 0x06, OP_STX | OP_SPECIAL, OPHANDLER(&CLASS::doBase6502));
pushopcode("DEX", 0xCA, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("DEY", 0x88, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("EOR", 0x02, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("INC", 0x07, OP_STX | OP_SPECIAL, OPHANDLER(&CLASS::doBase6502));
pushopcode("INX", 0xE8, OP_6502| OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("INY", 0xC8, OP_6502| OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("JML", 0x00, OP_65816, OPHANDLER(&CLASS::doJMP));
pushopcode("JMP", 0x01, OP_6502, OPHANDLER(&CLASS::doJMP));
pushopcode("JSL", 0x02, OP_65816, OPHANDLER(&CLASS::doJMP));
pushopcode("JSR", 0x03, OP_6502, OPHANDLER(&CLASS::doJMP));
pushopcode("LDA", 0x05, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDX", 0x05, OP_STX, OPHANDLER(&CLASS::doBase6502));
pushopcode("LDY", 0x05, OP_C0, OPHANDLER(&CLASS::doBase6502));
pushopcode("LSR", 0x02, OP_ASL, OPHANDLER(&CLASS::doBase6502));
pushopcode("MVN", 0x00, OP_6502, OPHANDLER(&CLASS::doUNK));
pushopcode("MVP", 0x00, OP_6502, OPHANDLER(&CLASS::doUNK));
pushopcode("NOP", 0xEA, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("ORA", 0x00, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("PEA", 0xF4, 2, OPHANDLER(&CLASS::doAddress));
pushopcode("PEI", 0xD4, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("PER", 0x62, 2, OPHANDLER(&CLASS::doAddress));
pushopcode("PHA", 0x48, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PHB", 0x8B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PHD", 0x0B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PHK", 0x4B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PHP", 0x08, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PHX", 0xDA, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PHY", 0x5A, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLA", 0x68, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLB", 0xAB, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLD", 0x2B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLP", 0x28, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLX", 0xFA, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("PLY", 0x7A, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("REP", 0xC2, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("ROL", 0x01, OP_ASL, OPHANDLER(&CLASS::doBase6502));
pushopcode("ROR", 0x03, OP_ASL, OPHANDLER(&CLASS::doBase6502));
pushopcode("RTI", 0x40, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("RTL", 0x6B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("RTS", 0x60, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("SBC", 0x07, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("SEC", 0x38, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("SED", 0xF8, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("SEI", 0x78, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("SEP", 0xE2, 1, OPHANDLER(&CLASS::doAddress));
pushopcode("STP", 0xDB, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("STA", 0x04, OP_STD, OPHANDLER(&CLASS::doBase6502));
pushopcode("STX", 0x04, OP_STX, OPHANDLER(&CLASS::doBase6502));
pushopcode("STY", 0x04, OP_C0, OPHANDLER(&CLASS::doBase6502));
pushopcode("STZ", 0x01, OP_6502, OPHANDLER(&CLASS::doNoPattern));
pushopcode("TAX", 0xAA, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TAY", 0xA8, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TCD", 0x5B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TCS", 0x1B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TDC", 0x7B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TRB", 0x03, OP_6502, OPHANDLER(&CLASS::doNoPattern));
pushopcode("TSB", 0x02, OP_6502, OPHANDLER(&CLASS::doNoPattern));
pushopcode("TSC", 0x3B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TSX", 0xBA, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TXA", 0x8A, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TXS", 0x9A, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TXY", 0x9B, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TYA", 0x98, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("TYX", 0xBB, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("WAI", 0xCB, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("WDM", 0x42, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("XBA", 0xEB, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
pushopcode("XCE", 0xFB, OP_6502 | OP_ONEBYTE, OPHANDLER(&CLASS::doBYTE));
}
#undef CLASS

3
opcodes.h Normal file
View File

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

1
qasm Symbolic link
View File

@ -0,0 +1 @@
./build/qasm

98
qasm.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "app.h"
#include "asm.h"
#define CLASS PAL_APPCLASS
// return a pointer to the actual Application class
PAL_BASEAPP *PAL::appFactory(void)
{
return (new CLASS());
}
// you MUST supply this array 'appOptions'. NULL line and end.
programOption PAL::appOptions[] =
{
{ "debug", "d", "enable debug info (repeat for more verbosity)", "", false, true},
{ "config-file", "f", "load configuration data from a <file>", "file", false, false},
{ "", "", "", "", false, false}
};
int CLASS::runServerApp(PAL_EVENTMANAGER *em)
{
int res = -1;
if (em != NULL)
{
PAL_BASEAPP::runServerApp(em);
PAL_HTTPSERVERTASK *server = new PAL_HTTPSERVERTASK("httptask");
if (server != NULL)
{
em->startTask(server);
server->initServer(getConfig("http.listen", "0.0.0.0:9080"), false, 64);
res = 0;
}
}
return (res);
}
int CLASS::runCommandLineApp(void)
{
TFileProcessor *t = NULL;
std::string line;
uint64_t startticks,n;
// only called if SERVERAPP not defined
int res = -1;
//LOG_DEBUG << "command line mode" << endl;
for (ArgVec::const_iterator it = commandargs.begin(); it != commandargs.end(); ++it)
{
Poco::File fn(*it);
std::string p = fn.path();
Poco::Path path(p);
//logger().information(path.toString());
std::string e = toUpper(path.getExtension());
if (e == "S")
{
//logger().information("ASM: " + path.toString());
t = new T65816Asm();
}
if (e == "LNK")
{
//logger().information("LNK: " + path.toString());
t = new T65816Link();
}
if (t != NULL)
{
startticks=GetTickCount();
t->init();
std::string f=path.toString();
t->processfile(f);
t->process();
t->complete();
n=GetTickCount();
printf("Operation time: %lu ms\n",n-startticks);
delete t;
t = NULL;
}
else
{
printf("not supported type\n");
}
//logger().information(*it);
res = 0;
}
return (res);
}

19
qasm.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <palPoco.h>
#include "pallogger.h"
#include <eventtask.h>
#include <baseapp.h>
#include <httpserver.h>
#define CLASS PAL_APPCLASS
using namespace PAL_NAMESPACE;
class CLASS : public PAL_BASEAPP
{
protected:
virtual int runCommandLineApp(void);
virtual int runServerApp(PAL_EVENTMANAGER *em);
public:
};
#undef CLASS

22
qasm.ini Normal file
View File

@ -0,0 +1,22 @@
[log]
loglevel=0;
logdir=/var/log/mylog
logfile=mylog.log
[application]
timezone=America/Los_Angeles
[qasm]
path1=
path2=
path3=
path4=
path5=
[asm]
casesen=0

4006
src/asm/asm.1.s Normal file

File diff suppressed because it is too large Load Diff

21
src/asm/asm.cmd.s Normal file
View File

@ -0,0 +1,21 @@
* ovr all
;use ../macs/tool.macs.s
;use ../macs/qatools.macs.s
;use ../macs/toolmacs.s
put asm.vars
put asm.1
put asm.eval
put asm.cond
put asm.opcodes
put asm.dsk
put asm.errors
put ../data/opdata
asm asm.header
lnk ../utility/qasmgs.l
typ exe
sav ../utility/qasmgs
mylable equ $1234
ent

2275
src/asm/asm.cond.s Normal file

File diff suppressed because it is too large Load Diff

1259
src/asm/asm.dsk.s Normal file

File diff suppressed because it is too large Load Diff

219
src/asm/asm.errors.s Normal file
View File

@ -0,0 +1,219 @@
dskerror php
rep $30
sta prodoserr
lda #doserror
jsr asmerror
plp
rts
asmerror php
rep $30
sta :errcode
_QAIncTotalErrs
pea 0
_QAGetWindow
pea $ffff
_QASetWindow
ldx #$00
]lup lda errtbl,x
beq :unknown
cmp :errcode
beq :found
inx
inx
inx
inx
jmp ]lup
:unknown psl #unknownstr
jmp :draw
:found inx
inx
phk
phk
pla
and #$00ff
pha
lda errtbl,x
pha
:draw _QADrawErrstring
jsr :gsos
psl #textstr
_QADrawErrString
lda modeflag
bit #putflag.useflag
beq :line
lda tlinenum
ldx #$00
jsr printdec
lda #' '
jsr drawchar
lda #'>'
jsr drawchar
:line lda linenum
ldx #$00
jsr printdec
:period lda #'.'
jsr drawchar
lda #$0d
jsr drawchar
_QASetWindow
plp
rts
:errcode ds 2
:gsos php
rep $30
lda :errcode
cmp #doserror
jne :xit
ldx #$00
]lup lda gstbl,x
beq :gsnfound
cmp prodoserr
beq :gfound
inx
inx
inx
inx
jmp ]lup
:gfound inx
inx
lda gstbl,x
tax
phk
phk
pla
and #$00ff
pha
phx
lda #$20
jsr drawchar
_QADrawErrString
jmp :xit
:gsnfound psl #dosstr
lda #$20
jsr drawchar
_QADrawErrString
lda prodoserr
jsr prbytel
:xit plp
rts
gstbl dw $07,gstr1
dw $10,gstr16
dw $11,gstr16
dw $27,gstr2
dw $28,gstr3
dw $2b,gstr4
dw $2e,gstr5
dw $2f,gstr6
dw $40,gstr7
dw $44,gstr8
dw $45,gstr9
dw $46,gstr10
dw $47,gstr11
dw $48,gstr12
dw $49,gstr12
dw $4e,gstr13
dw $50,gstr13
dw $51,gstr17
dw $52,gstr19
dw $57,gstr18
dw $201,gstr14
dw filemismatch,gstr15 ;error $5C
dw badsav,str25
dw $0000,$0000
errtbl dw badlable,str2
dw undeflable,str3
dw duplable,str4
dw misalignment,str5
dw badoperand,str6
dw notmacro,str7
dw badopchar,str8
dw badconditional,str9
dw badaddress,str10
dw badbranch,str11
dw forwardref,str12
dw twoexternals,str13
dw badrelative,str14
dw saneerror,str29
dw evaltoocomplex,str30
dw objectfull,str15
dw symfull,str16
dw memfull,str17
dw badput,str18
dw doserror,str19
dw relfull,str20
dw usererror,str21
dw macrofull,str22
dw badmacro,str23
dw nesterror,str24
dw badsav,str25
dw badopcode,str26
dw $201,str27
dw badinput,str28
dw relfilefull,str31
dw $0000,$0000
str2 str 'Bad label'
str3 str 'Undefined label'
str4 str 'Duplicate label'
str5 str 'Misalignment'
str6 str 'Bad operand'
str7 str 'Not a macro'
str8 str 'Illegal char in operand'
str9 str 'Bad conditional'
str10 str 'Bad address mode'
str11 str 'Bad branch'
str12 str 'Illegal forward reference'
str13 str 'Two externals'
str14 str 'Illegal relative address'
str15 str 'Object space overflow'
str16 str 'Symbol table full'
str17 str 'Memory full'
str18 str 'Bad PUT/USE'
str19 str 'GS/OS error:'
str20 str 'Relocation dictionary full'
str21 str 'Break'
str22 str 'Macro table full'
str23 str 'Bad macro'
str24 str 'Nesting error'
str25 str 'Bad SAV/DSK'
str26 str 'Bad opcode'
str27 str 'Out of Memory'
str28 str 'Bad input'
str29 str 'SANE error'
str30 str 'Expression too complex'
str31 str 'REL file too large'
gstr1 str 'GS/OS is busy'
gstr2 str 'I/O error'
gstr3 str 'No device connected'
gstr4 str 'Write protected'
gstr5 str 'Disk switched'
gstr6 str 'No disk in drive'
gstr7 str 'Invalid pathname'
gstr8 str 'Directory not found'
gstr9 str 'Volume not found'
gstr10 str 'File not found'
gstr11 str 'Duplicate filename'
gstr12 str 'Disk full'
gstr13 str 'File locked'
gstr14 str 'Memory manager: Unable to allocate memory'
gstr15 str 'File type mismatch'
gstr16 str 'Device not found'
gstr17 str 'Volume damaged'
gstr18 str 'Duplicate volume online'
gstr19 str 'Not ProDOS (GS/OS) volume'
unknownstr str 'Unknown error'
codestr str ' Code=$'
textstr str ' in line: '
dosstr str 'GS/OS Error: '

1441
src/asm/asm.eval.s Normal file

File diff suppressed because it is too large Load Diff

481
src/asm/asm.header.s Normal file
View File

@ -0,0 +1,481 @@
lst off
;cas in
tr on
exp only
rel
xc
xc
mx %00 ; make sure we're in 16-bit mode!
;use util.macs
use qatools.macs
use ../data/qa.equates
brl start
userid ds 2 ;my userid
message ds 2
subtype ds 4
asmdp ds 2
filename ds 130,0
txttypes hex 0204B0
start php
phb
phd
phk
plb
rep $30
sta userid
tdc
sta asmdp
pea 0
_QAStatus
pla
bne :ok
pld
plb
plp
rep $30
jsl prodos
dw $29
adrl :quit
:quit adrl $00
dw $00
:ok rep $30
stz prodoserr
pea 0
psl #$00
lda userid
pha
_QAGetMessagebyID
pll subtype
pla
sta message
beq :0
cmp #maxamessage
blt :call
lda #$FFFF
jmp :xit
:0 lda #$00
jmp :xit
:call dec
asl
tax
jsr (:tbl,x)
:xit rep $30
pha
lda userid
ora #asmmemid
pha
_disposeall
pla
pld
plb
plp
cmpl :one
rtl
:one dw $01
:tbl dw cmdline ;parsecmdline
dw txtfile
dw loadedfile
loadedfile php
rep $30
psl #asmstr
_QADrawString
lda #'.'
jsr drawchar
lda #$0d
jsr drawchar
jsr drawchar
ldx subtype
ldy subtype+2
jsl asm
bcc :clc
:sec rep $30
plp
sec
rts
:clc plp
clc
rts
txtfile php
rep $30
psl #pathname
_QAGetPath
lda pathname
and #$ff
jeq :notfound
tay
sep $20
]lup lda pathname,y
tyx
sta filename,x
dey
bpl ]lup
rep $30
psl #$00
psl #filename
psl #$00 ;filepos
psl #-1 ;whole file
psl #txttypes
lda userid
ora #asmmemid
pha
psl #$00
pea $8000
_QALoadfile
plx
ply
jcs :sec
phx
phy
psl #asmstr
_QADrawString
lda #' '
jsr drawchar
psl #filename
_QADrawString
lda #$0d
jsr drawchar
jsr drawchar
ply
plx
jsl asm
bcc :clc
jmp :sec
:notfound rep $30
lda #$46 ;file not found error
:sec rep $30
plp
sec
rts
:clc rep $30
lda #$00
plp
clc
rts
cmdline php
rep $30
stz pathname
psl #pathname
pea 80
_QAGetCmdLine
ldy #$01
sep $30
lda pathname
beq :notfound
]lup lda pathname,y
and #$7f
cmp #' '
blt :notfound
bne :p1
iny
jmp ]lup
:p1 iny
]lup lda pathname,y
and #$7f
cmp #' '
blt :notfound
beq :p2
iny
jmp ]lup
:p2 iny
]lup lda pathname,y
and #$7f
cmp #' '
blt :notfound
bne :ok
iny
jmp ]lup
:ok ldx #$00
sta filename+1,x
]get inx
iny
lda pathname,y
and #$7f
cmp #' '+1
blt :set
sta filename+1,x
jmp ]get
:notfound jmp :nf1
:set txa
sta filename
rep $30
lda filename
and #$ff
cmp #62
bge :nosuff
tax
lda filename,x
and #$7f
cmp #'/'
beq :nosuff
inx
lda #'.S'
sta filename,x
inx
txa
sep $20
sta filename
:nosuff rep $30
psl #$00
psl #filename
psl #$00 ;filepos
psl #-1 ;whole file
psl #txttypes
lda userid
ora #asmmemid
pha
psl #$00
pea $8000
_QALoadfile
plx
ply
bcs :xit
phy
phx
psl #asmstr
_QADrawString
lda #' '
jsr drawchar
psl #filename
_QADrawString
lda #$0d
jsr drawchar
jsr drawchar
plx
ply
jsl asm
bcc :clc1
jmp :xit
:nf1 rep $30
lda #$46
sec
jmp :xit
:clc1 rep $30
lda #$0000
:xit rep $30
plp
cmpl :one
rts
:one dw $01
asmstr str 0d,'Assembling'
prbytel
php
rep $30
phy
phx
pha
pha
_QAPrbytel
pla
plx
ply
plp
rts
prbyte
php
rep $30
phy
phx
pha
pha
_QAPrbyte
pla
plx
ply
plp
rts
drawchar php
rep $30
phx
phy
pha
and #$7f
pha
_QADrawChar
:plp pla
ply
plx
plp
rts
printdec php
rep $30
phx
pha
psl #:str
pea #11
pea $00
tll $270b
sep $30
ldy #$00
ldx #$00
]lup lda :str,x
and #$7f
cmp #' '
beq :inx
cmp #'0'
bne :draw
cpx #10
bge :draw
cpy #$00
beq :inx
:draw phy
phx
rep $30
jsr drawchar
* pha
* tll $180c
sep $30
plx
ply
iny
:inx inx
cpx #11
blt ]lup
plp
rts
:str ds 12,0
drawlable php
rep $30
pea $00
tdc
clc
adc #labstr
pha
_QADrawString
lda #$0d
jsr drawchar
plp
rts
random php ;save environment
phb
phk
plb
rep %00111001
ldx indexi
ldy indexj
lda array-2,x
adc array-2,y
sta array-2,x
dex
dex
bne :dy
ldx #17*2 ;cycle index if at end of
:dy dey ; the array
dey
bne :setix
ldy #17*2
:setix stx indexi
sty indexj
plb
plp
rts
indexi da 17*2 ;the relative positions of
indexj da 5*2 ; these indexes is crucial
array da 1,1,2,3,5,8,13,21,54,75,129,204
da 323,527,850,1377,2227
err *-array-34
*=================================================
* SEED seeds generator from 16 bit contents of AXY
*-------------------------------------------------
seed php
rep %00110000
seed2 phb
phk
plb
pha
ora #1 ;at least one must be odd
sta array
stx array+2
phx ;push index regs on stack
phy
ldx #30
]lup sta array+2,x
dex
dex
lda 1,s ;was y
sta array+2,x
dex
dex
lda 3,s ;was x
sta array+2,x
lda 5,s ;original a
dex
dex
bne ]lup
lda #17*2
sta indexi ;init proper indexes
lda #5*2 ; into array
sta indexj
jsr random ;warm the generator up.
jsr random
ply ;replace all registers
plx
pla
plb
plp
rts
*=================================================
* RANDOMIZE seed generator from system clock.
* Assumes Misc Toolset active.
*-------------------------------------------------
randomize php
rep %00110000
lda #0
pha
pha
pha
pha
ldx #$D03 ;readtimehex
jsl $E10000
pla
plx
ply
sta 1,s ;trick to pull last word
pla ; fm stack without ruining
bra seed2 ; the previous ones.
put asm.vars
put asm.1
put asm.eval
put asm.cond
put asm.opcodes
put asm.dsk
put asm.errors
put ../data/opdata
lst
chk
lst off
;typ exe
;sav utility/qasmgs.l

4673
src/asm/asm.opcodes.s Normal file

File diff suppressed because it is too large Load Diff

376
src/asm/asm.vars.s Normal file
View File

@ -0,0 +1,376 @@
tr on
tcursx equ $57b
true equ $FFFF
false equ $0
stopgo equ false
floatingpoint equ true
memid equ $100
putid equ $200
useid equ $300
initobjsize equ $FFFF
dskobjsize equ $1000
relsize equ $8000
macsize equ $C00*8
macnestmax equ 16 ;max mac nest level
maxput equ 16 ;max put OR use/lib files (each)
maxlup equ 16 ;max lup nesting
**** errcode equates ****
noerror equ $00
undeflable equ $02
duplable equ $03
misalignment equ $04
badoperand equ $05
notmacro equ $07
badopchar equ $08
badconditional equ $09
badaddress equ $0A
badbranch equ $0B
forwardref equ $0C
twoexternals equ $0D
badrelative equ $0E
saneerror equ $0F
evaltoocomplex equ $10
objectfull equ $81
symfull equ $82
memfull equ $83
badput equ $84
doserror equ $85
relfull equ $86
usererror equ $87
macrofull equ $88
badmacro equ $89
nesterror equ $8A
badsav equ $8B
badopcode equ $8C
badinput equ $8F
badlable equ $90
relfilefull equ $91
*badoperand equ $92
filemismatch equ $5C
*** Symbol Types ***
localbit = %0000_0000_0000_0001
variablebit = %0000_0000_0000_0010
macrobit = %0000_0000_0000_0100
equatebit = %0000_0000_0000_1000
externalbit = %0000_0000_0001_0000
macvarbit = %0000_0000_0010_0000
linkerbit = %0001_0000_0000_0000
usedbit = %0010_0000_0000_0000
entrybit = %0100_0000_0000_0000
absolutebit = %1000_0000_0000_0000
*** Assembly Zpage Equates ***
dum $00
labstr ds 16 ;Lable STR that we are working on
labnum ds 2 ;REC num of current lable
lableft ds 2 ;B-Tree Structures
labright ds 2
labprev ds 2
lablocal ds 2 ;REC of Local Lable Tree
labtype ds 2 ;Type of Label
labval ds 4 ;EQU value of Lable
globlab ds 2 ;REC of Current Global Lable
lineptr ds 4
printptr ds 4
linelable ds 2
linehaslab ds 2
linelabtxt ds 16,0
linenum ds 2
totallines ds 2
fileptr ds 4
flen ds 4
filehandle ds 4
filelen ds 4
lableptr ds 4
lableptr1 ds 4
nextlableptr ds 4
objzpptr ds 4
relptr ds 4
macptr ds 4
macvarptr ds 2
objct ds 2
objsize ds 2
objptr ds 4
objoffset ds 4
relct ds 2
relout ds 2
reloffset ds 4
totbytes ds 4
linerel ds 2
equateval ds 4
passnum ds 2
doneflag ds 2
modeflag ds 1
relflag = %10000000
dskflag = %01000000
putflag = %00100000
useflag = %00010000
lupflag = %00001000
dumflag = %00000100
caseflag = %00000010
doflag = %00000001
ds 1
tbxflag = %10000000
algflag = %01000000
encflag = %00100000
cycflag = %00010000
crcflag = %00001000
ifflag = %00000100
expflag = %00000010
exponly = %00000001
modeflag1 ds 1
dupok = %00000001
symflag = %00000010
ds 1
macflag ds 1
;b7 mac executing
;b6 external mac
;b5 internal mac
;b0 mac init
listflag ds 2
liston = %10000000
lstdoon = %01000000
tradron = %00100000
branchlst = %00010000
lbranchlst = %00001000
equlst = %00000100
trobjlst = %00000010
objlst = %00000001
putuse ds 2
mxflag ds 1
xcflag ds 1
forcelong ds 1
notfound ds 1
clrglob ds 1
lableused ds 2
allmath ds 2 ;true = all numbers, 0 = label (after eval)
opflags ds 2
opdata ds 2
opcodeword ds 2
lvalue ds 4
myvalue ds 4
noshift ds 4
lineobjptr ds 4
xreg ds 4 ;variables used by EVAL
yreg ds 4
val ds 4
xrel ds 2
yrel ds 2
zrel ds 2
op ds 2
top ds 2
deczp ds 2
checksum ds 1
crc16 ds 2
cycles ds 2
cycleavg ds 2
linecycles ds 2
cyclemarks ds 2
cycflags ds 1
encval ds 1
tbxand ds 1
firstchar ds 2
merrcode ds 2
linksymtbl ds 4
linksymhdl ds 4
keyflag ds 2
controld = %1000_0000
cancelflag = %0100_0000
pauseflag = %0010_0000
spaceflag = %0001_0000
workspace ds 16
err */$100
dend
* lst
*dpend equ workspace+16 ;length of DP storage
* lst rtn
*** Variables ***
loadid ds 2
putlevel ds 2
uselevel ds 2
opcode ds 32,0 ;current opcode
lastlen ds 2 ;length of last line
ds 2 ;must be before linebuff
linebuff ds 128,0 ;operand goes here
comment ds 256,0
objhdl ds 4 ;handle to object buffer
lablect ds 2
globalct ds 2
rellabct ds 2
oldglob ds 2
dolevel ds 2
domask ds 2
maclevel ds 2
maclocal ds 2
dumor ds 2
orgor ds 2
fllast ds 2
opmask ds 2 ;EVAL variables
number ds 2
bracevalid ds 2
estack ds 2
evallevel ds 2
evalrelok ds 2
offset ds 2
shiftct ds 2
bytesout ds 256+2,0
prodoserr ds 2
errorct ds 2
objtype ds 2
objfull ds 2
tlinenum ds 2
oldobj ds 4
oldoffset ds 4
orgval ds 4
extmacptr ds 4,0
dsfill ds 2
dsoffset ds 2
erraddress ds 4
errvalid ds 2
entcount ds 2
extcount ds 2
tabs dfb 26,36,41,54
macstack ds macnestmax+1*32,0
macvars ds macnestmax+1*128,0
luplevel ds 2
dskopen dw $00
adrl dskpath
adrl $0000
dskwrite dw $00
dskbuff adrl $0000
dskreq adrl $0000
dsktran adrl $0000
dskeofparm dw $00
dskeof adrl $0000
dskcreate adrl dskpath
dw $e3
dskctype dw $00
dskcaux adrl $00
dw $01
dskctime adrl $0000
dskinfo adrl dskpath
dw $00
dsktype dw $00
dskaux adrl $0000
ds 16,0
dskdelete adrl dskpath
dskclose dw $00
dskpath ds 129,0
atable ds 128*2,0
titlestr ds 256,0
converttable
hex 00000000000000000000000000000000
hex 00000000000000000000000000000000
asc ' !"#$%&'
hex 27 ;the ' character
asc '()*+,-./'
asc '0123456789'
asc ':;<=>?'
asc '@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
asc '[\]^_'
asc '@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
asc '[\]^_' ;DEL is last character
hex 00000000000000000000000000000000
hex 00000000000000000000000000000000
asc ' !"#$%&'
hex 27 ;the ' character
asc '()*+,-./'
asc '0123456789'
asc ':;<=>?'
asc '@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
asc '[\]^_'
asc '@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
asc '[\]^_' ;DEL is last character
inputtbl
hex 202020202020202020202020200d2020
hex 20202020202020202020202020202020
asc ' !"#$%&'
hex 27 ;the ' character
asc '()*+,-./'
asc '0123456789'
asc ':;<=>?'
asc '@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
asc '[\]^_'
asc '`abcdefghijklmnopqrstuvwxyz'
asc '{|}~'
hex 20 ;delete
hex 202020202020202020202020200d2020
hex 20202020202020202020202020202020
asc ' !"#$%&'
hex 27 ;the ' character
asc '()*+,-./'
asc '0123456789'
asc ':;<=>?'
asc '@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
asc '[\]^_'
asc '`abcdefghijklmnopqrstuvwxyz'
asc '{|}~'
hex 20 ;delete

109
src/data/external.s Normal file
View File

@ -0,0 +1,109 @@
lst off
tr on
exp only
typ EXE ;we are a shell 'command'
rel
xc
xc
mx %00 ; make sure we're in 16-bit mode!
use 4/util.macs
brl start ;starts with 8 branches
brl rtl
brl rtl
brl rtl
brl rtl
brl rtl
brl rtl
brl rtl
dw $00
asc 'MERLIN' ;id number
ptr equ 0
userid ds 2
commandline ds 129,0
rtl rtl
start rep $30
phk
plb
sta userid
stx ptr+2
sty ptr
ldy #$00
sep $20
]lup lda [ptr],y
and #$7f
cmp :id,y
bne :xit
iny
cpy #$08
blt ]lup
ldx #$00
]f lda [ptr],y
and #$7f
cmp #' '
blt :xit
beq :iny
cpx #$00
bne :ok
iny
jmp ]f
:iny iny
inx
jmp ]f
:ok sep $20
ldx #$00
sta commandline+1,x
]get inx
iny
lda [ptr],y
and #$7f
cmp #' '+1
blt :set
sta commandline+1,x
jmp ]get
:set txa
sta commandline
rep $30
jsr doit
:xit rep $30
jsl prodos
dw $29
adrl :quit
brk $00
:quit adrl $00
dw $00
:id asc 'MERLINGS'
doit php
rep $30
lda commandline
and #$ff
tax
lda commandline,x
and #$7f
cmp #'/'
beq :nosuff
inx
lda #'.S'
sta commandline,x
inx
txa
sep $20
sta commandline
:nosuff rep $30
psl #commandline
tll $1c0c
pea "|"
tll $180c
plp
rts
sav 6/external.l

101
src/data/globals.s Normal file
View File

@ -0,0 +1,101 @@
lst off
maxsymbols equ $2000
shellflag = %0000_0001 ;shell
asmflag = %0000_0010 ;asm
linkflag = %0000_0100 ;linker
editflag = %0000_1000 ;editor
cmddflag = %0001_0000 ;command processor
shellmemid = $100 ;these are OR'd with individual USERIDs
asmmemid = $100 ;and are GLOBAL...individual programs
linkmemid = $100 ;should request/dispose memory of an ID
editmemid = $100 ;HIGHER than these on a local basis.
cmdmemid = $100
dum $00
shelldp ds 2
globalsdp ds 2
asmdp ds 2
linkdp ds 2
editdp ds 2
cmddp ds 2
goshellptr ds 4
goasmptr ds 4
golinkptr ds 4
goeditptr ds 4
gocmdptr ds 4
idactive ds 2 ;use flags above
idloaded ds 2
shellhandle ds 4
asmhandle ds 4
linkhandle ds 4
edithandle ds 4
cmdhandle ds 4
shellptr ds 4
asmptr ds 4
linkptr ds 4
editptr ds 4
cmdptr ds 4
shelluserid ds 2
asmuserid ds 2
linkuserid ds 2
edituserid ds 2
cmduserid ds 2
shelllable ds 32 ;used to pass lables between programs
gobjtype ds 2 ;default filetype for sav/link
gobjaux ds 4 ;default auxtype for sav/link
keyquit ds 2
shellerrors ds 2 ;used to pass error counts
lasterror ds 2 ;code of last error to occur
objcodesaved ds 2 ;<>0 if object code saved by asm
linkfileptr ds 4 ;pointer to passed data for linker
linkhdlid ds 2 ;0 = command line
;1 = loaded TXT file
asmfileptr ds 4 ;pointer to passed data for assembler
asmhdlid ds 2 ;0 = command line
;1 = loaded TXT file
;2 = filename
asmfilelen ds 4 ;if above = 1 then this is length of file
editfileptr ds 4 ;pointer to passed data for editor
edithdlid ds 2 ;0 = command line
;1 = loaded TXT file
cmdfileptr ds 4 ;pointer to passed data for cmd processor
cmdhdlid ds 2 ;0 = command line
;1 = loaded TXT file
editlinenum ds 2 ;editors current line number
linksymhdl ds 4
linksymtbl ds 4
linksymnum ds 2
linklstflag ds 2
linknextlbl ds 4
linkkbdptr ds 4
extmacptr ds 4
usrptr ds 4
userptr ds 4
err */$100
dend
lst rtn

407
src/data/opcodetest.s Normal file
View File

@ -0,0 +1,407 @@
lst off
tr adr
xc
xc
cyc avg
rel
* dsk object/optest.l
mx %00
rep #$FF
sep #$FF ;so we don't mess up MX status
;each are 3 cycles
xba ;2 cycles
mx %11
;14
imediate ;# 2 and 3 cycles
ldy #$FFFF
cpy #$FFFF
cpx #$FFFF
ldx #$FFFF
ora #$FFFF
and #$FFFF
eor #$FFFF
adc #$FFFF
bit #$FFFF
lda #$FFFF
cmp #$FFFF
sbc #$FFFF
ldy #$FFFF
cpy #$FFFF
cpx #$FFFF
ldx #$FFFF
ora #$FFFF
and #$FFFF
eor #$FFFF
adc #$FFFF
bit #$FFFF
lda #$FFFF
cmp #$FFFF
sbc #$FFFF
;16
absolute ;a 4 and 5 cycles
bit $FFFF
sty $FFFF
stz $FFFF
ldy $FFFF
cpy $FFFF
cpx $FFFF
stx $FFFF
ldx $FFFF
ora $FFFF
and $FFFF
eor $FFFF
adc $FFFF
sta $FFFF
lda $FFFF
cmp $FFFF
sbc $FFFF
;8
absolutermw ;a (r/m/w) 6 and 8
asl $FFFF
rol $FFFF
lsr $FFFF
ror $FFFF
dec $FFFF
inc $FFFF
tsb $FFFF
trb $FFFF
;2
absjump
jmp $FFFF ;3 cycles
jsr $FFFF ;6 cycles
;8
abslong ;5 and 6 cycles
oral $FFFFFF
andl $FFFFFF
eorl $FFFFFF
adcl $FFFFFF
stal $FFFFFF
ldal $FFFFFF
cmpl $FFFFFF
sbcl $FFFFFF
;2
absljmp
jml $FFFFFF ;4 cycles
jsl $FFFFFF ;8 cycles
;16
direct ;d 3,4 and 5 cycles
bit $FF
sty $FF
stz $FF
ldy $FF
cpy $FF
cpx $FF
stx $FF
ldx $FF
ora $FF
and $FF
eor $FF
adc $FF
sta $FF
lda $FF
cmp $FF
sbc $FF
;8
directrmw ;d (r/m/w) 5,6,7 and 8
asl $FF
rol $FF
lsr $FF
ror $FF
dec $FF
inc $FF
tsb $FF
trb $FF
;6
areg ;2 cycles
asl
inc
rol
dec
lsr
ror
;25
implied ;2 cycles
dey
iny
inx
dex
nop
tya
tay
txa
txs
tax
tsx
tcs
tsc
tcd
tdc
txy
tyx
clc
sec
cli
sei
clv
cld
sed
;1
implied1
xba ;3 cycles
;2
wait ;3 cycles
wai
stp
;8
dii ;(d),y 5,6,7, and 8
ora ($ff),y
and ($ff),y
eor ($ff),y
adc ($ff),y
sta ($ff),y
lda ($ff),y
cmp ($ff),y
sbc ($ff),y
;8
diil ;[d],y 6,7, and 8
ora [$ff],y
and [$ff],y
eor [$ff],y
adc [$ff],y
sta [$ff],y
lda [$ff],y
cmp [$ff],y
sbc [$ff],y
;8
diix ;(d,x) 6,7, and 8
ora ($FF,X)
and ($FF,X)
eor ($FF,X)
adc ($FF,X)
sta ($FF,X)
lda ($FF,X)
cmp ($FF,X)
sbc ($FF,X)
;12
dx ;d,x 4,5, and 6
bit $FF,x
stz $FF,x
sty $FF,x
ldy $FF,x
ora $FF,x
and $FF,x
eor $FF,x
adc $FF,x
sta $FF,x
lda $FF,x
cmp $FF,x
sbc $FF,x
;6
dxrwm ;d,x (r/m/w) 6,7,8, and 9
asl $FF,x
rol $FF,x
lsr $FF,x
ror $FF,x
dec $FF,x
inc $FF,x
;2
dy ;d,y 4,5 and 6
stx $FF,y
ldx $FF,y
;11
absx ;a,x 4,5 and 6
bit $FFFF,x
ldy $FFFF,x
stz $FFFF,x
ora $FFFF,x
and $FFFF,x
eor $FFFF,x
adc $FFFF,x
sta $FFFF,x
lda $FFFF,x
cmp $FFFF,x
sbc $FFFF,x
;6
absxrmw ;a,x (r/m/w) 7 and 9
asl $FFFF,x
rol $FFFF,x
lsr $FFFF,x
ror $FFFF,x
dec $FFFF,x
inc $FFFF,x
;8
abslx ;al,x 5 and 6
oral $FFFFFF,x
andl $FFFFFF,x
eorl $FFFFFF,x
adcl $FFFFFF,x
stal $FFFFFF,x
ldal $FFFFFF,x
cmpl $FFFFFF,x
sbcl $FFFFFF,x
;9
absy ;a,y 4,5 and 6
ldx $FFFF,y
ora $FFFF,y
and $FFFF,y
eor $FFFF,y
adc $FFFF,y
sta $FFFF,y
lda $FFFF,y
cmp $FFFF,y
sbc $FFFF,y
;9
relative ;2,3 and 4
bpl relative
bmi relative
bvc relative
bvs relative
bcc relative
bcs relative
bne relative
beq relative
bra relative
;1
relativelong ;4 cycles
brl relativelong
;2
indirjmp
jmp ($FFFF) ;5 3 bytes
jml [$FFFF] ;6 3 bytes
; jml ($ffff) ;5 cycles
;8
dindirect ;(d) 5,6,and 7
ora ($ff)
and ($ff)
eor ($ff)
adc ($ff)
sta ($ff)
lda ($ff)
cmp ($ff)
sbc ($ff)
;8
dindirectl ;[d] 6,7, and 8
ora [$ff],y
and [$ff],y
eor [$ff],y
adc [$ff],y
sta [$ff],y
lda [$ff],y
cmp [$ff],y
sbc [$ff],y
;2
abdindinx
jmp ($FFFF,x) ;6
jsr ($FFFF,x) ;8
;2
interupts
brk $FF ;7 and 8 (7 if E=1)
cop $FF ;7 and 8
;3
stackreturn
rti ;6 and 7
rts ;6
rtl ;6
;7
stackpush ;3 and 4
php
pha
phy
phx
phd
phk
phb
;6
stackpull ;4 and 5
plp
pla
ply
plx
pld
plb
;3
stackadd
pei $FF ;6 and 7
pea $FFFF ;5
per $FFFF ;6
;8
stackrel ;d,s 4 and 5
ora $FF,s
and $FF,s
eor $FF,s
adc $FF,s
sta $FF,s
lda $FF,s
cmp $FF,s
sbc $FF,s
;8
stackrely ;d,s 7 and 8
ora ($FF,s),y
and ($FF,s),y
eor ($FF,s),y
adc ($FF,s),y
sta ($FF,s),y
lda ($FF,s),y
cmp ($FF,s),y
sbc ($FF,s),y
;2
move ;7 cycles per byte
mvn $123456,$123456
mvp $123456,$123456
misc wdm $FF
lst
chk
lst off
* sav object/optest.1

1371
src/data/opdata.s Normal file

File diff suppressed because it is too large Load Diff

193
src/data/qa.equates.s Normal file
View File

@ -0,0 +1,193 @@
*======================================================
* Equates used by all programs in the QuickASM system
ToolNum = 1
userorsys = $8000
ToolType = userorsys
versionnum equ $01016410
dum 1 ;Languate ID #s
shellid ds 1
asmid ds 1
linkid ds 1
editid ds 1
projectid ds 1
rezid ds 1
utilid ds 1
externalid ds 1
dend
dum $00 ;Message ID #s
nomessage ds 1
dend
dum 1 ;Application message types
startmess ds 1
runmess ds 1
eventmess ds 1
shutdownmess ds 1
dend
dum 1 ;Compiler message types
afromcmd ds 1
afromname ds 1
afromhandle ds 1
maxamessage = *
dend
dum 1 ;Linker message types
lfromcmd ds 1
lfromname ds 1
lfromhandle ds 1
lquick ds 1
lfromprojfile ds 1
lfromprojhandle ds 1
maxlmessage = *
dend
dum 0 ;Command table record
ename ds 16
etype ds 2
eid ds 2
eflags ds 2 ;b15 = restartable
;b14 = active (running)
euserid ds 2
edphandle ds 4
edp ds 2
eaddress ds 4
emesstype ds 2
emesssub ds 4
eRecSize = *
dend
**** Vector ID #'s
; Number Name
dum 1 ; ------------------------------
vprintchar ds 1 ;_QADrawChar Vector
vprintstr ds 1 ;_QADrawString Vector
verrchar ds 1 ;_QADrawErrChar Vector
verrstr ds 1 ;_QADrawErrString Vector
vprintblk ds 1 ;_QADrawCStr
verrblk ds 1 ;_QADrawErrCStr
vputop ds 1 ;_QAPutOpcode Vector
vputbyte ds 1 ;_QAPutByte Vector
veval ds 1 ;_QAEval Vector
vrelcorrect ds 1 ;_QARelCorrect Vector
vkeyavail ds 1 ;_QAKeyAvail Vector
vgetchar ds 1 ;_QAGetChar Vector
vgetline ds 1 ;_QAGetLine Vector
vtabtocol ds 1 ;_QATabToCol Vector
vexeccmd ds 1 ;EXEC program Vector
vkeymac ds 1 ;KeyBoard macro program Vector
vusr ds 1 ;USR program Vector
vuser ds 1 ;USER program Vector
vxref ds 1 ;XREF program Vector
vprintstrl ds 1 ;print a class.1 string to current window
verrstrl ds 1 ;print a class.1 string to ERR window
vtoolmacs ds 1 ;HANDLE to built in ToolBOX Macs
maxvectors = *-1
dend
*======================================================
* ToolSet Error Codes
qatoolerr = ToolNum*256.userorsys
dum qatoolerr
qanotstarted ds 1
qabadcmdfile ds 1
qacmdnotfound ds 1
qalinknotavail ds 1
qalangnotavail ds 1
qabadvectornum ds 1
qaalreadyactive ds 1
qaunknowntypestr ds 1
qatimeleverr ds 1
qatotalerrleverr ds 1
qabadpathname ds 1
qanotnumber ds 1
qanoword ds 1
qabadinput ds 1
qaeof ds 1
dend
*------------------------------------------------------
* Assember/Linker Equates
asmmemid = $100
linkmemid = $100
oldshell = 0 ;temporary DO flag
maxsymbols = $2000
*======================================================
* GSOS equates * call ID numbers
* Set 'Class1' to $2000 to use Class 1 calls, $0000 for Class 0 calls
prodos = $E100A8
prodosIL = $E100B0
inline = 1 ;stack or inline?
_Create = $0001.Class1
_Destroy = $0002.Class1
_OSShutdown = $2003 ;class '1' only
_ChangePath = $0004.Class1
_SetFileInfo = $0005.Class1
_GetFileInfo = $0006.Class1
_Volume = $0008.Class1
_SetPrefix = $0009.Class1
_GetPrefix = $000A.Class1
_ClearBackup = $000B.Class1
_SetSysPrefs = $200C ;class '1' only
_Null = $200D ;class '1' only
_ExpandPath = $000E.Class1
_GetSysPrefs = $200F ;class '1' only
_Open = $0010.Class1
_Newline = $0011.Class1
_Read = $0012.Class1
_Write = $0013.Class1
_Close = $0014.Class1
_Flush = $0015.Class1
_SetMark = $0016.Class1
_GetMark = $0017.Class1
_SetEOF = $0018.Class1
_GetEOF = $0019.Class1
_SetLevel = $001A.Class1
_GetLevel = $001B.Class1
_GetDirEntry = $001C.Class1
_BeginSession = $201D ;class '1' only
_EndSession = $201E ;class '1' only
_SessionStatus = $201F ;class '1' only
_GetDevNumber = $0020.Class1
_GetLastDev = $0021.Class1
_ReadBlock = $0022 ;class '0' only
_WriteBlock = $0023 ;class '0' only
_Format = $0024.Class1
_EraseDisk = $0025.Class1
_ResetCache = $2026 ;class '1' only
_GetName = $0027.Class1
_GetBootVol = $0028.Class1
_Quit = $0029.Class1
_GetVersion = $002A.Class1
_GetFSTInfo = $202B ;class '1' only
_DInfo = $002C.Class1
_DStatus = $202D ;class '1' only
_DControl = $202E ;class '1' only
_DRead = $202F ;class '1' only
_DWrite = $2030 ;class '1' only
_AllocInterrupt = $0031 ;P16 call
_BindInt = $2031 ;GS/OS call
_DeallocInterrupt = $0032 ;P16 call
_UnbindInt = $2032 ;GS/OS call
_AddNotifyProc = $2034 ;class '1' only
_DelNotifyProc = $2035 ;class '1' only
_DRename = $2036 ;class '1' only
_GetStdRefNum = $2037 ;class '1' only
_GetRefNum = $2038 ;class '1' only
_GetRefInfo = $2039 ;class '1' only

1383
src/data/toolmacs.s Normal file

File diff suppressed because it is too large Load Diff

492
src/docs/qasm.docs Normal file
View File

@ -0,0 +1,492 @@
QuickASM Shell v0.40 by Lane Roath
The QuickASM shell combines the best of both worlds; Graphics and Text. With this shell you can use a graphical, multi-window system similar to MPW on the Macintosh or a text based system similar to APW on the GS. Not only that, but you can switch between the two at will with a single keypress!
This version of the QuickASM shell is NOT completed, but should give you enough of a base to do serious development work in. "Not Implemented" details those features of the graphics enviroment which have not been implemented at this time.
Not Implemented
"Project" has not even begun to be implemented! However, the single option "Build Project" does allow you to select a Merlin 16+ link file to use as a bases for linking ( ___ BUGGY ___). If you have an open source window, this option will try to use it as the link file. (ie, open your link file, then edit your documents. When ready to link, just select the link file's window and choose this option!) Later, this will instead look (only???) at QuickASM project files & will work on the open project if there is one.
"Apple" - "Help" provides no such thing! Must learn the list manager...
"Document" - "Label/Line #" does nothing at this point. Use "Find" instead.
"Tools" - does nothing! (the SFDialog does appear, but nothing happens).
"GS/OS" - the only option that works is "Delete".
"Transfer" - "Launch..." allows selection of the file, but will probably crash your system
(___BUGGY___). The file list (ie, Merlin 16+) is not implemented!
Text Mode
This should all work, but extensive testing has NOT been done. To return to the graphics enviroment simply press the ESC key at the "CMD:" prompt.
To be done
"Fix Source" instead of just changing $A0 to tabs, need to format each line and replace it in the document. MUCH slower, but needed because otherwise we can't fix sources from QuickEdit or APW. Also, we leave lines which Merlin prints correctly but doesn't modify (ie, all spaces are $20) in a bad state (ie, comments with no ; preceding them).
QuickLink we need to have a way to link a project using the QuickLink.S file method, preferably with a hot key associated with it (*Ll?). This would be an "interm" idea until our project stuff is done???
_________________________________________________________________________
QuickASM Technical Information Jan 9, 1990 - 1st revision
_________________________________________________________________________
Introduction
This document will attempt give some insight on developing applications and utilities that execute under the QuickASM development environment. It describes what is available under the development system and gives examples on using the QuickASM toolset, writing SHELL programs, shell applications, utilities, additional compilers/assemblers, additional linkers, and adding additional features to the QuickASM GS assembler (such as keyboard macros, USR opcodes, and USER files).
The QuickASM development system has been designed to allow the Apple //GS software developer the flexibility and power he needs along with the ability to allow his development environment grow as his needs change. The basic system includes TWO different interfaces: a text based command line interface is available for those developers who enjoy the traditional text based programming environment similar to that of the Apple Programmer's Workshop, and a full SHR "desktop" environment that includes pull down menus, multiple edit windows, and the ability for multiple "shell applications" to execute simultaneously on the desktop.
Combined with the ability to easily add new commands and shell applications (including new compilers and linkers!) the QuickASM development system will be hard to beat for a long time to come, and will constantly be updated.
The QuickASM development environment has been designed with both APW and Merlin users in mind. It combines the power and flexibility of the APW programming environment with the ease of use and SPEED of Merlin 16+. APW users have only DREAMED they could achieve the speed of Merlin under their APW shell, and Merlin users could only wish for APW expandability and power! With QuickASM, you have the best of both worlds!
At the heart of the system is a Merlin 16+ compatible 65816 macro assembler, which, along with being 100%+ Merlin compatible at source code and link file levels, has over 40 new features (including built in GS ToolBox macros) and psuedo opcodes for even more assembly language power. Have you ever scratched your head and thought "I wish I could do this...in Merlin??" Well...now you can!
The QuickASMGS linker is also 100%+ Merlin compatible and all of your current Merlin linker command files will work perfectly without change. But we weren't satisfied with that! The QuickASM linker is also 25% faster than the Merlin linkers, generates SMALLER object files, supports GS resources, has an "auto-EXPRESS" feature (to create EXPRESSLOAD files), allows expression evaluation (like "DS reserved*2"...where "reserved" is a label in your assembly source!!!), and allows much more flexibility in program design by allowing a greater number of segments, multiple SAV's and a variety of other time and space saving features.
The QuickASM development system also includes 2 utilities for working with resource forks in your application. First, the resource compiler allows you to compile text files into resources, much like APW's REZ program. Second, the resource editor allows you to visually edit, change ID's, cut, copy, and paste resources between different programs. The resource editor has been designed to use "resource translators" so as more resource types are defined, simply adding a new translator will allow you to graphically edit the new resource. Coupled with the linker's ability to automatically link resources from "resource libraries", the QuickASM development environment delivers more power to develop programs utilizing resources than any other development system on the market.
*** A resource de-compiler will also be available that will create a resource compiler compatible text file from existing resources. ***
Also in the works is a Project Manager that will allow the developer to create "projects" that will automatically "remember" prefix settings, source files, link orders, and final "load file" segment types and position. If you are familiar with Lightspeed Pascal for the Macintosh....we have a treat for you! *** NOTE **** if you have suggestions for the project manager, be sure to let Lane know about them soon!!!
The QuickASM development system also includes a symbolic debugger (much like the APW DEBUG program) that allows the programmer to step, trace, and execute any GS program, along with setting breakpoints, viewing memory, 65816 registers, and the stack. If the program has been created with the QuickASM linker, you will also have the ability to access variables, subroutines, etc. by LABEL!!!!
Definitions
Throughout this information, you will encounter several terms which, generally speaking, may cause some confusion. The following definitions will make things clearer.
Application - Unless otherwise noted, "application" will describe a QuickASM "shell application", a program that has been specifically written to run under the QuickASM shell environment. The best way to understand these programs is to consider them to be "shell desk accessories". When these programs are executed by the user they remain active on the QuickASM "desktop" until they are closed by the user. Normally (but not limited to), these applications will put a window on the desktop and allow the user to do some action. These programs are passed "messages" by the QuickASM shell, that tell the application what action it is to take. Multiple "applications" may be open at once on the desktop and the QuickASM shell acts like a "multifinder" allowing each to handle it's own events.
Compiler - Throughout this discussion, the term "compiler" will be used to designate any program that converts the user's source code files into files that a "linker" will use to create the final GS program file. The QuickASM 65816 assembler is one example of such a program. Additional "compilers" may be added to the QuickASM development system simply by following the "Compiler Requirements" below. We anticipate other compilers, such as BASIC, PASCAL and C to become available in the future. We are also working on a Merlin compatible assembler that creates link files that are compatible with the APW linker.
Linker - the term "linker" describes any program that takes output files from different "compilers" and creates an Apple //GS "load" file from them. The QuickASM linker currently accepts Merlin type LNK files ($F8) and imediately creates GS programs in OMF format.
External Command - An external command is a disk based command, such as TYPE or DUMP. These programs are only in memory while it is executing, and is shutdown after completing its task. These programs are located in the "COMMANDS" directory (prefix #6) and are available in either the command line or graphics interface.
Internal Command - Internal commands are those commands built into the QuickASM system, such as CATALOG or DELETE. These commands are always available to the user, from either the command line or graphics shell.
Inside the Environment
When the user launches the file QASM, the QuickASM development system goes through a rather complex boot process to initialize itself. Actually, the QASM file is simply an init file responsible for:
Startup:
1: Starting up the Tool Locator, Memory Manager, Miscellaneous Tools, ADB toolset, Integer Math toolset, SANE toolset, the resource Manager, and the Text Toolset (the Text Toolset is also initialized for BASIC style input/output, the screen is cleared and the cursor is moved to home.
2: Loading the file QASYSTEM/QATOOLS using _InitialLoad, installing it as a USER toolset, and calling _QABootInit.
3: Loading the file QASYSTEM/QAINTCMD using _InitialLoad, to load the system's internal commands. The handle to this program file is saved to pass to the QA toolset.
4: Loading the file QASYSTEM/QAPREFS, which is the user's preference file and again saving the handle to this file for later.
5: Reading the user's command table (file: QASYSTEM/QACMD), which is simply a TXT or SRC file in the following format:
Command Name Type ID # Comment
TYPE E 12 ;List a TXT file
The COMMAND NAME is a valid ProDOS pathname that may be no longer than 15 characters in length. It is this name that the user will type at the command line to access the command. The commmand name may consist of upper or lower case letters, but the commands are considered case-INSENSITIVE.
The TYPE is a letter designating the type of the command: C for compiler, L for linker, I for internal command, E for external command, and A for application. The type letter may be preceded by a '*' to allow the program to be restartable from memory.
The ID NUMBER is any number from 1 to 65535 that will be used internally by the system. Duplicate IDs are allowed, but the file used by any duplicate ID numbers will be the name of the file that comes first in the list. This allows the user to have multiple commands that do the same thing.
For example:
CATALOG *E 1 ;this is the catalog command
CAT E 1 ;this will execute CATALOG
DIR E 1 ;again, same as CATALOG
The COMMENT field is not required but may be used
to describe the command.
The command file is read and stored into records of the following format:
Offset # bytes Description
+ 0 16 Command Name (P-Str, all caps)
+16 2 Type (L=1,C=2,I=3,E=4,A=5)
+18 2 ID Number (1-65535)
+20 2 Flags (b15=restartable, all others 0)
+22 2 UserID (must be zero)
+24 4 DP Handle (must be zero)
+28 2 DP address (must be zero)
+30 4 Load Address (must be zero)
+34 2 Message (must be zero)
+36 4 Message subtype (must be zero)
The INIT program should do a _QAGetCmdRecSize():recsize call to determine the length of each individual record. The current version of the toolset will return 40. This allows the extension of the records in the future as well as maintaining backward compatiblity.
** The handle to this array of commands MUST be passed to the QAToolSet. **
6: The init file must then check bit 15 of the INITFLAGS field in the QAPREFS file (which has already been loaded) and if the bit is set to 1, the init file loads the file QASYSTEM/QAGRAF using _InitialLoad. If the bit is 0 the file QASYSTEM/QATEXT is loaded using _InitialLoad. In each case, a new USERID is obtained and a $100 byte direct page is obtained from the memory manager (use the new userid)
7: _QAStartUp is then called, using the USERID of the INIT file, and a MODEFLAGS field of $00008000 (for QAGRAF) or $00000000 (for QATEXT).
8: _QASetCmdHdl is called with the handle to the command table array. _QASetParmHdl is called with the handle to QAPREFS.
9: Next, the A register is loaded with the userid of the QAGRAF or QATEXT program and the D register is loaded with the value of the $100 byte block obtained from the memory manager, the X and Y registers are currently undefined and should be set to zero. Finally, a JSL is executed to call the shell program.
Any Errors obtained at any of these levels are considered FATAL and are reported to the user using the TEXT TOOLS. All necessary shutdown is performed, (_UserShutdown, disposing of memory, etc) and control is passed back to the launching application via a GS/OS QUIT call.
ShutDown
When control passes back to the INIT file via RTL from the shell program, the status of the carry flag is checked to determine if a fatal error occurred in the shell. If carry clear, no error occurred and shutdown may proceed as normal, otherwise the error code is reported to the user via TEXT tools, shutdown is completed as described below and a GS/OS QUIT call is performed.
If no error occurred from the shell, a _QAGetQuitParms call is executed to check whether another application is to be launched or not and the GS/OS QUIT call is called accordingly after all shutdown is completed.
The INIT file must do the following:
1: Disposing of any memory that it may have obtained (commandtblhdl,parmhandle, etc).
2: If QATEXT or QAGraf was started up, a _UserShutDown call must be made to remove it from memory. (_UserShutdown will dispose of the DP handle used for it automatically if the INIT file used the shell's USERID when it requested the handle)
3: If _QAStartup was called and successful, the INIT file MUST, before calling _QAShutdown, do a _QADispose which will shutdown any and all external programs (applications, compilers, etc.) that may still be executing. The graphics shell should have done this already, but the text shell may not have....if it has already been called, no harm will be done, and it is better to be safe, than sorry!
4: ShutDown all toolsets that were started.
5: Make a GS/OS QUIT call (using results of _QAGetQuitParms if necessary..see above) to return to the system.
QATEXT/QAGRAF
These two programs are the user interface that link the user to the QAToolset and the commands, and applications available to him. QATEXT is a command line interface (much like APW) and QAGRAF is a desktop environment. In either case these programs are responsible for:
1: When control is passed to the program it is via JSL, the A reg is set to it's USERID and the D register is set to a $100 byte block of direct page. The shell must use its OWN userid for obtaining memory, and if it needs more than $100 bytes of DP it should do a _FindHandle, and a _SetHandleSize.
2: Before taking ANY steps (after saving the DP and USERID) the shell program should do a _QAStatus call (make sure you use PEA $00, not PHA, etc) to determine if the QATools are started up. If an error is returned, or the result is $00, the shell was not launched by the QuickASM development environment and should immediatly execute a GS/OS QUIT call.
3: After determining that QATools are active, the shell must load and startup any and all toolsets that it requires other than those started by the INIT program (see above). If the shell will be using the Event Manager (or TASKMASTER), it must do a _QAGetModeFlags, set bit 14 (remember MODEFLAGS is a long word!) and do a _QASetModeFlags.
4: After the shell has started up the tools it needs, setup anything else it needs (menus, windows, etc), the shell must use the call _QASetVector to set pointers to routines that will handle the I/O for commands, compilers, linkers, and applications. Text based shells need not set these vectors as the QATools defaults to standard text input and output.
Vectors of significance to the SHELL are described below:
**** Important ****
All vectors are called in full native mode (16 bit A,X,Y) with a JSL. The routines must preserve the D and B registers and return via RTL in full native mode. If an error occured, the carry must be set with the error code in A, else carry is clear with the registers set as defined below:
***************************************************************
These vector numbers are NOT SET in stone....you should use the QA.EQUATES file and use the name of the vector preceded with a 'v'. Thus, to access the PrintChar vector use '#vPrintChar'.
****************************************************************
Vector # Name Description
1 - PrintChar - Print character in A reg (low byte only, high undefined) to current display window.
2 - PrintStr - Print Pascal type string (ptr low in A, ptr high in X) to current display window.
3 - ErrChar - Print character in A reg (low byte only, high undefined) to current error output window.
4 - ErrStr - Print Pascal type string (ptr low in A, ptr high in X) to current error output window.
10 - Keyavail - Return $FFFF (true) in A if keypress, autokey available in queue. Return $0000 (false) if no keypress available. ALWAYS leave keypress in queue!
11 - GetChar - Return pending keyboard character (high bit set) in low byte in A. Return keyboard modifiers at time of press (format of $C025 keyboard register) in high byte of A. Remove keypress from queue.
12 - GetLine - Get a line of input from user. On entry, the A register holds the low word of a pointer to the parameter table, the X register holds the high word of the pointer. The parameter table is defined below. The routine should return the user's input line at the address pointed to by the LINESTR field in the table. The high bits of all input characters MUST be clear, and a <CR> character must be appended to the end of the string. LINEPTR is a Pascal Type string (with a length byte) and should be returned as such. On entry, LINESTR will hold the default text to use, or will be a NULL string if none. PROMPTPTR is a pointer to a promptstr that should be used to ask the user for input. The MAXLEN field is the maximum length of the string that the user may enter. If an error occurs, the carry should be set, and the A holds the error code on return. If no error occurs, the carry must be clear, and the A register holds $0000 if the user chose to ACCEPT the line, or $FFFF if the user canceled the operation. If CANCEL is selected, the original LINESTR MUST NOT be changed in any way.
GetLine Parameter Table:
+0 MaxLen word
+2 PromptPtr Long
+6 LineStrPtr Long
16 TabToColumn - Move cursor X position to value in A
register, if current X is >= value,
simply move X pos forward one pos,
scrolling if necessary.
5: Once all vectors are setup, the Shell starts its main event loop. During each pass through this loop, it must do the following things:
Call _QAGetQuitFlag and if the result is true, the user has selected quit somewhere (it may not be from within the shell, so you MUST check this flag) and the shell must take whatever action it needs to quit the program (see "shutdown" below).
Call _QARun. This procedure requires nothing of the shell itself, no parameters or results, it simply passes a RUN message to any shell applications that may be executing.
If after recieving an event (either from TaskMaster or the event manager), that cannot be handled by the shell itself, it must call _QAEvent with the pointer to the event record (or taskrecord) and a flag describing whether the record is an event record or a task record. This allows shell applications to handle events that were intended for them.
6: In order for the shell to execute commands that are built into the system, either external programs (commands) or internal commands, it must pass a pointer to a cmd line to the routine (_QAParse) which will determine if the command is a valid command or not, and return a type ID (1..5) and a command ID (1.65536) of a valid command, or an error if not. To actually execute the command, the shell simply calls _QAExecCommand with the typeid and commandid of the command it wants to execute, the toolbox handles all loading and unloading, obtains the necessary DP for the utility, and calls it. Most commands will require that a previous _QASetCommandLine be executed so that it may retrieve whatever parameters it needs to do its job. Even if the shell is not using a command line interface...it MUST place SOMETHING in the system command line string before calling _QAExecCommand. *** See Below....About Command Lines ***
_QAExecCommand will return no error (carry clear..toolbox convention) if the command reported no error, and the error code (carry set) in A if an error occurred or the command was not valid. The shell should report this error to the user in what ever means it sees fit.
Shell Shutdown
When the system QUITFLAG is TRUE (via _QAGetQuitFlag) the shell must do the following before returning via RTL to the INIT program.
Call _QADispose before shutting down any tools or disposing of any system handles or pointers. This will pass shutdown messages to any currently executing applications that may require them. It will also release any and all memory given to these applications and delete their USERIDs from the list of active IDs.
Call _QAResetVectors. This call resets the internal vectors to their default values, so the shell doesn't get called after it's been unloaded.
Dispose of any memory that the shell has acquired for it's own use.
Shutdown any tools (excluding those started by the INIT file..see above)
Exit via RTL with carry clear indicating NO FATAL ERROR. If the Shell can't startup correctly (can't load a tool, etc) it should exit carry set, with error code in A, so the INIT file can report it to user and shutdown the system.
***** More about Command Lines *****
The QAToolSet keeps it's own internal command line so that external commands and applications can get required parameters from them. This command line is a PType string (with a length byte) that consists of ASCII characters >=$20 (i.e. no control characters) and high bits clear. The string is also terminated by a <CR> char ($0D) and this byte is included in the length count. The MAXIMUM length of this command line is 255 characters and 1 length byte for a total of 256 bytes.
A shell program uses the call _QASetCommandline to set this command line in the system. It will automatically append any needed <CR> as well as remove control characters. Most (if not all) commands executed via _QAExecCommand will expect this command line to be valid as they will use the call _QAGetCommandLine to get their info. They will also expect to find a command word (i.e CATALOG) at the beginning of the system command line. The command word is not important in what it says.....just that it be there. External commands DO NOT check what the characters are (or else the user would not be able to rename his commands), but they do "skip" over this word to get to their parameters. Thus, any shell wishing to call _QAExecCommand MUST put at least one alphanumeric character, a space, any required paramters, and a <CR> into the system command line using _QASetCommandLine, before calling _QAExecCommand.
________________________________________________________________________
QuickASM GS Beta Test Docs
________________________________________________________________________
QuickASM is copyright 1990, QuickSoft Software Development
Merlin is copyright 1989, Roger Wagner Publishing and Glen Bredon
This file is a brief introduction to the QuickASM development environment. This is a temporary documentation file and it in no way covers EVERYTHING available in the system. It is simply a brief set of instructions in order to get you up and running. If you are recieving this file, you will also be receiving a more complete set of doc files as soon as they become available. If you are not interested in beta testing this development system or are not interested in receiving any more "junk" mail concerning this development system please contact us and we will leave you alone. You have been selected to receive these files because you have shown some interest in "taking a look" at what we have put together and because we value your input. If you find things that you would like to have included in the system, or if you find incompatibilities with QuickASM and Merlin....or if you (heaven forbid) find a bug or two, please contact either Lane Roath at 318-949-8264 (GEnie:L.Roath/Delphi:LRoath) or myself, Shawn Quick at (406) 752-0193.
We are asking you to test this system as thoroughly as you have the time to do so. With any program as complex as this development system, there are FAR more possibilities than the author can test...although I have done a very thorough job of debugging as the programs were being developed. I guess basically what I am asking is that you do anything and everything that you can think of to MAKE it break. You will undoubtably find sections of the environment that may not run as quickly as you would like (the editor for example), and these problems will be remedied in the near future.
Thanks for you time, and your input.....when the system is ready for release you will be rewarded for your efforts with a final copy of the system.....that I GUARANTEE will become your "official" development environment!!!
In order to succesfully get the system running you will need the following files in their respective directories:
QASM S16 ;the initial "boot" file (the one you launch)
QASYSTEM DIR ;System directory
QAINTCMD TOL ;Internal command handlers
QATOOLS TOL ;QuickASM ToolSet
QATEXT EXE ;The TEXT (command line) shell program
QAGRAF EXE ;The desktop shell (Lane's in charge of this)
QAPREFS BIN ;User Parameter file
QACMD TXT ;User Command File
TOOLMACS BIN ;Built in ToolBox Macros
QUICKLINK.S TXT ;System QuickLink command file
LOGIN TXT ;User LOGIN file (not implemented)
UTILITY DIR ;External Command/Languages Directory
QASMGS EXE ;QuickASM 65816 assembler
QLINKGS EXE ;QuickASM Linker
CATALOG EXE ;External Catalog command (not necessary)
DUMP EXE ;External file dump utility (originally by G. Bredon)
The QuickASM development environment has been designed to be modular. Allowing you to modify it to work the way you work. It is 100% Merlin 16+ compatible at both the source and link levels, and also includes two separate user interfaces: a text based command line interface (much like APW) and a SHR "desktop" environment (though not completed yet) that works like a "multifinder" allowing multiple "utility" programs to be active at once. The system will also allow the addition of new compilers, assemblers and linkers as they become available (such as a BASIC compiler, Pascal, or an APW compatible assembler/linker) as well as external commands and utilities much like the APW environment.
In addition to the Merlin compatible assembler and linker, the development system also includes a symbolic debugger (like APW's debug, only allowing symbolic addresses to be used) *** still in alpha testing ***, a resource compiler, decompiler, and visual resource editor *** late alpha stage ***.
Along with these utilities, you may also look forward to a complete PROJECT MANAGER (much like Lightspeed Pascal for the Macintosh), disk utilities, and a powerful EXEC language, plus keyboard macros, USR and USER files.
(*** although these files are not present in this version....the entire system has been designed to support these automatically, and in fact, all of the above mentioned programs exist in one form or another on my hard disk...just waiting for more intensive debugging!!!! ***)
Design Philosphies
In writing the QuickASM development system, I have tried to keep several goals in mind.
I wanted to create a development environment that professional Apple // developers would find powerful enough to handle any programming challenge presented to them and yet be intuitive enough that developers weren't constantly having to search through menus, or type long commands over and over, etc.
I wanted to design the FASTEST possible //GS assembler system that combined the speed of LISA, the popularity of Merlin, and the power and expandability of APW.
I wanted a development environment interface that would act as a "multifinder" that would allow multiple "applications" and utilities to be available simultaneously on the "desktop".
I wanted this new development system to be completely compatible with my already huge library of source code from my 10 years of Apple // programming.
I wanted the development system to grow and change as my needs changed. I was looking for an environment that could be updated, expanded, etc. without constantly having to mail in for "update disks". I needed an environment that third parties could add to, user's could add to, and would always be "up to date"
I wanted a development system that was integrated, yet separate. This modularity would allow it change and yet still support utilities and programs that were written for older versions. Whether I wanted "bare bones" text based programming, or a powerful "desktop" based environment.
I wanted a development environment that ran in a minimal memory configuration....yet take advantage of ALL the memory I had available. QuickASM will run quite effectively with 512K....and will still take advantage of 8 megs if you have it!!!
And most of all....I wanted a development environment that was RESPONSIVE to the base of programmers who are using it. QuickASM comes with a detailed set of technical information describing EVERY aspect of the systems internal functions. Many example programs are included which show how to add any type of utility, command, compiler/assembler, linker, built in macros, new opcodes, new shell programs, etc. If you ever have said "I wish..." QuickASM probably CAN!
QuickASM was originally created with the Merlin 16+ assembler (thanks Glen and Roger!!) and now that it is "old" enough (meaning it can assemble/link itself) it is actually used to develop itself!!!!
About the SHELL
Within this initial beta release you will find only the text based development environment. Lane Roath is working on the graphics/desktop shell which will be completed within a week or two.
After booting/launching the QASM program file you will be presented with your desired user interface (text/graphics) as set within your system preferences file. This is your interface to the entire development system that you have defined within your user command file (QASYSTEM/QACMD). Adding a new external command, utility program, or even new compilers/assemblers or linkers is as easy as entering the command in your system command table.
(*** the final docs will give technical information regarding how to write new commands and utilities as well as how to add new commands to the command table ***)
In order to get a listing of the currently defined/installed commands, simply enter HELP at the command line, or choose help from the menu bar.
All of the currently defined commands are straightforward except maybe the command ASML. ASML is equivilent to the Merlin "QuickLink" (OA-6 from the editor). This command will assemble the file given as a parameter in the command line (no .S extension), and link the resulting object file into an executable GS program file. ASML stands for assemble and link, and the "quicklink" function is described below in the section "About the Linker".
(*** ASMLG, though valid as a command is not supported in this version ***)
About the Assembler
The QuickASM assembler is initiated via the "ASM filename" command from the command line. There are various aliases to the ASM command, such as COMPILE, ASSEMBLE, etc and all serve the same purpose.
The assembler itself is 100%+ Merlin 16+ compatible and will correctly assemble ALL Merlin source codes. There are a variety of new features that the assembler supports and some of the most important features are described below:
LUP - The LUP opcode now supports up to 16 levels of nesting. This can be very helpful for building tables, etc...but it also can get confusing. Remember that any LUP's that are found within another LUP structure will be expanded multiple times. Merlin 16 allows LUP 0 and will in effect turn off assembly until the matching --^ opcode is encountered. QuickASM will generate an appropriate error message for any LUP operand that evaluates to a value less than 1.
EVL - The EVL (Evaluate) psuedo opcode enables algebraic operand evaluation for ALL operands and not just those enclosed in braces {}. EVL supports ON and OFF in the operand field to enable and disable this feature.
ENC - The ENC (encode) opcode expects an 8 bit operand and instructs the assembler to EOR every byte put into the object code with the operand value. ENC without an operand will restablish normal object code generation, as will ENC $00. This is useful for "hiding" text or object code within the resulting disk files. The program code itself is responsible for "un-encoding" these bytes before using them in the program. If the assembler finds that the ENC opcode is inappropriate (for example in REL code sections) an error message is generated. ENC is useful for hiding copyright messages and serial numbers within programs.
TBX - TBX (toolbox) enables/disables the automatic recognition of the built in GS Toolbox macros. It supports the following operands:
TBX ON (or none) - enables toolbox macro recognition
TBX OFF - disables toolbox macro recognition
TBX LC - enables recognition and all expanded macros are listed in LowerCase.
TBX UC - enables recognition and expanded macros are listed in UpperCase.
The GS toolbox macros are all defined using the toolbox name preceded with an "_". For example: _NewHandle.
TBX also enables built in GS type macros such as PSL (pushlong), PSW (pushword), JNE (Jump if not =), TLL (toolcall) etc. (** A complete list of these standard GS macros will be included in the final docs **)
If you wish to use your own toolbox macros or change the built in macros, simply create a macro in your source file that has the same name as the built in macro. For example:
TLL mac ;my macro def
ldx #]1
jsl $e10000
bcc ]2
eom
The above macro would then REPLACE the built in macro called TLL and all calls to this macro would then come from this new definition.
GS/OS (as well as ProDOS 16 and ProDOS 8) macros are also included for ease in making DOS calls. These macros are called by the syntax:
_GSOS:Open parameterlist or,
_P16:Open paramlist
_P8:Open paramlist
IN ORDER to use the built in ToolBox or DOS macros, you MUST use the SHELL command TOOLMACS before using the macros in your assemblies. This command need only be executed once (usually within your LOGIN file) and simply loads the macro definitions into memory for access by the assembler (or ANY other utility, like the symbolic debugger!!! ). If you wish to save memory, and do not use the built in macros, simply do not execute the TOOLMACS command.
DUP - DUP (duplicate) supports both ON and OFF in its operand and will enable/disable the ability of the assembler to ignore duplicate label errors if the labels are EQUated to the same value.
SYM - The SYM opcode will print the symbol table on the second pass of the assembly. This is the equivilent of the symbol table printout in Merlin at the end of assembly with listing on. QuickASM will NOT print the symbol table at the end of assembly UNLESS a SYM opcode has been encountered.
(*** In the future, SYM will also allow alphabetic and numeric listing of the symbol table, as well as saving the symbol table to disk for use by other assemblies (a kind of "preassembled" equate files ***)
RND - RND (random) will assign a 32 bit random number to the label in the label column of the RND line. Thus the line:
mylable RND ;random number
PEK - PEK (peek) will assign the label in the label column the 8 bit value at the memory location in the operand. Example:
mylable PEK $E0C000 ;read the current keyboard location
will assign mylable the value of memory location $E0C000 at the time of the assembly.
MTX - MTX (mousetext) is similar to the ASC psuedo-op but the characters are converted to mouse text before being placed in the object code.
LIB - LIB (library) is similar to USE except that the file is not accessed on the second pass of the assembly. LIB files will contain EQUs and macro definitions that are only needed on the first pass of the assembly. Using LIB instead of USE for these types of files will speed your assembly times. Caution: because LIB files are only accessed on the first pass of assembly, NO CODE MAY BE GENERATED within these files or errors will occur.
BEL - Beeps the GS's speaker on the second pass of the assembly. Most likely used at the end of a source code listing to signal that assembly is complete.
XC- - XC- (XC minus) is the reverse of the XC opcode in Merlin. XC OFF is also supported.
DL - DL (Define Long) simply another name for the ADRL psuedo-op.
BYT - BYT (Byte) same as DFB, or DB
BTR - (Branch if True) equivilent to BNE
BFL - (Branch if False) same as BEQ
Other Additions:
Macro Nesting levels have been expanded to 16 levels
DO/FIN nesting expanded to 16 levels
IF supports " IF XC" (like IF MX) to determine whether or not extended opcodes have been enabled. XC returns 0 if 6502 mode selected, 1 if 65C02 mode selected, and 3 if 65816 mode selected. Useful in macros where PEA might be used if 65816 enabled and LDA, PHA, LDA, PHA would be used for the 6502.
The assembler creates Merlin type LNK files ($f8) that are DIRECTLY compatible with the Merlin Linkers (and vice versa).
The assembler also supports the math operator MOD which is '//', thus 10 mod 3 would be expressed as: 10//3 and would evaluate to 1 (one). 10 div 3 = 3 with remainder of 1.
Things to consider:
The assembler is slightly slower than Merlin 16+ on assembly times. There are two reasons for this (both of which will be fixed in a short while). First, the macro expansion code is "slightly" sloppy and this is the main bottleneck in the assemblies. Second, because of the "modularity" of the development system, the assembler has been written to support a variety of different environments that it may be run under. For example, whether or not the Event Manager is active, whether there is a keyboard macro program installed, and/or whether the EXEC language has called the assembler. Therefore, reading the keyboard to see if the user would like to pause the listing, cancel the assembler, etc. requires a toolbox call instead of a simple read of the keyboard location. In large source files, the keyboard may be read up to 100,000 times. This overhead has been found to slow assemblies by approximately 12 seconds on a 25,000 line source code. We have developed a method that will prevent this, but at this time the code is not in place....simply twiddle your thumbs for a few seconds longer per assembly.
The assembler has been designed internally to support "precompiled" source code files.....such as those found in the LISA assembler system. It is anticipated that this precompilation of source code files (by a special editor or utility program) will cut assembly times by 50%!!!!! This is our ultimate goal. The format for this precompilation has been designed on paper, but until I can find a day or two to write a program to convert source codes....we'll have to wait.
- USR opcodes are not supported in this version. The USR routine is tied to a routine that compresses the text of the QuickASM opcodes (like LDA) and places them in the object code. This is so QuickASM can assemble itself while in the development process. USR opcodes (as well as new user opcodes that can have ANY name) will be available when the shell is complete.
KBD is not available in this version of the assembler..although labels defined via KBD will use a value passed to it from the Linker. We have to settle on a GetLine routine that will work from both text and graphics modes and when that's settled KBD will be as normal!
About the Linker
The QuickASM Linker is a superset of the Merlin 16+ linker. It supports all of the Merlin linker opcodes (except LIB...which we have decided is much more work than its worth...we have never known anyone who uses it..but if YOU do and want it....it can be put in). There are also many other features that have been added to make the linker much more powerful.
The QuickASM linker is ALWAYS a two pass linker (like the Version 2 Merlin linker)...but you will find that link times are comparable with the Merlin 1 pass linker. When using OMF version 2 you will also find that the final GS load files (programs) will be much smaller than the exact same program linked with the Merlin linker. Multi segmented files are supported (multiple SAVs) and dynamic segments are also supported.
New Linker opcodes:
AUX - places value of operand in the auxtype of the output file. Similar to ADR.
PFX - sets prefix 0 to text in operand. You may also use CMD PREFIX /DISK
IMP - Import. IMP filename. will allow ANY type of file to be linked into the output file. Inserts the file's filename into the ENTry table so that other REL files may reference it. Similar to Merlin's ability to link a BINary file....except it allows ANY file type. Periods in the filename are converted to underlines.
REZ - REZ filename. Copies the resource fork of "filename" into the resource fork of the output file. This allows you to have a file of resources (created with REZ, etc) that are placed into to final load file at link time, without having to REZ EVERY TIME!!!
ZIP - Automatically converts the final output file to EXPRESSLOAD format.
(** not quite working yet **)
POS/LEN - currently ignored because I HAVE NO IDEA what they do, nor how to use them in Merlin. When I find out, you'll be the first to know!!!
The QuickASM linker also supports expression evaluation as in the assembler. Algabraic evaluation is done within braces {}. AND you may use ENTry labels within the linker. For example, if an assembly source has an entry label called STORAGE contained within it, you may use STORAGE within the link file as long as it's use follows a "LNK filename" of the file containing the entry. This could be used, for example, as the operand in a linker DS opcode to reserve variable space.
The linker supports all expression types (binary,hex decimal,label) and all operands (+-<=>/*&.! and // (mod)). The assembler convention of "*" (current program address) is NOT supported within the linker.
QuickLINK
If you are a Merlin user you will no doubt know how useful Merlin QuickLink (OA-6) feature is. But if you ever want to do anything more in your link file besides an ASM, LNK, and a SAV, you have to create a .cmd file and type LINK xyz whenever you want to link the file. With QuickASM, the quicklink function works slightly differently. When QuickLink is chosen (currently ASML from the shell, but the editors will soon support it) the linker searches the current prefix (0) for a file named QUICKLINK.S and if found uses this as the link cmd file. Failing to find the file in the current prefix, the linker searches the system directory (QASYSTEM) for a file of the same name (QUICKLINK.S) and will use that. Normally, the system file will simply be an OVR ALL, ASM filename, LNK filename, and a SAV filename (which will accomplish the same as the Merlin quicklink function). But if you need more flexibility, simply create a cmd file with the commands you need and save it in your work directory as QUICKLINK.S. Whenever you need to do a link, OA-6 (from the editor) or ASML filename (from the shell) will execute this file and link your program with the FULL power of the linker.
Because the QuickLink function must operate with varying filenames, three variables have been defined for use within these files:
]1 = the filename of the source program itself (no .S extension)
]2 = the filename that the assembler/compiler used to save the LNK file
]3 = the filename used for the LNK file minus the last 2 characters.
Whenever the linker encounters these variables in a QuickLink file, it replaces them with the respective filename. Think of them as Link Macros, because the substitution is done exactly like that of assembler macros.
The standard QuickLink file would therefore look like this:
OVR ALL ;assemble no matter what
ASM ]1 ;assemble filename passed in command line
LNK ]2 ;link the file created by the assembler
SAV ]3 ;Drop the last 2 chars (usually .L) from
;the name to save the output file.
ONLY the "]x" part of the line is substituted so you may use lines like this:
ASM ]2.L
which would expand to:
ASM filename.L
About the Editor
The editor is pretty straightforward, (** and currently the "weak link" of the system **) The command structure is the same as the Merlin full screen editor, with these exceptions:
-Replace (OA-R) is not completed
-Goto line number or label (OA-L in Merlin) has been changed to OA-Jump
-OA-L is now "load"
-the keypad "Clear" key is used to clear the current buffer as in NEW
-Undo is not supported.
- The command box (OA-O) supports PREFIX (PFX), CATALOG, and NEW.
- BE CAREFUL with the mouse......(** in fact, don't even THINK about touching it unless you can return it to it's original position otherwise you won't be able to leave the editor without rebooting......**) I'll FIX it, don't worry.
The editor may not seem like the most responsive sports car you've ever
driven, but it is acceptable. Optimization is high on my priority list. I also intend to allow the user to select his command keys and to make find/replace, and moving throughout the document much quicker. (In fact, Shawn has a new editor which should be as fast as ROSE, and much smaller than the current editor to boot!)
We will also make available a full SHR based text editor that will allow, multiple windows, color text, multiple fonts and point sizes, etc. The ULTIMATE "pretty" source file editor!!! (ie, based on WordWorks)
Well, those are some "hilites" of the system. I hope you enjoy it, and I really appreciate your help in finalizing everything. As always, suggestions are WELCOME, whatever you would like to see just let either Lane or myself know.
Questions/Comments/Problems....(want to help write some utilities!!! hint hint!!!)
Thanks.....
Shawn Quick and Lane Roath

34
src/docs/shell.docs Normal file
View File

@ -0,0 +1,34 @@
QuickASM Shell v0.40
The QuickASM shell combines
This version of the
_________Not Implemented________
"Project" has not even
"Apple" - "Help" provides
"Document" - "Label/Line #" does
"Margins & Tabs" still uses
"Tools" - does nothing!
"GS/OS" - the only
"Transfer" - "Launch..." allows
(___BUGGY___). The file
____ Text Mode ____
This should all work,
_____To be done_____
"Fix Source" instead of just
Tabs At this time
QuickLink we need to

28
src/docs/zak.idea Normal file
View File

@ -0,0 +1,28 @@
Item 2405541 90/06/26 21:14
From: S.QUICK1 Shawn Quick
To: BRYAN.ZAK Bryan M.
cc: L.ROATH Lane Roath
Sub: QASM help
Bryan, I thought of
#util <CR> and it
SoftDisk or as shareware
Not all of these
The utilities are the
The QuickASM shell already
I think the Softdisk
Get back to me
Shawn

4719
src/edit/edit.1.s Normal file

File diff suppressed because it is too large Load Diff

869
src/edit/edit.apw.s Normal file
View File

@ -0,0 +1,869 @@
loadapw rep $30
stz :toolarge
stz :merlin
stz :openflag
stz :loaded
stz apwlen
stz apwlen+2
:open jsl prodos
dw $10 ;open
adrl :oparm
bcc :ref
jmp :err
:ref lda :oparm
sta :rparm
sta :cparm
sec
ror :openflag
lda #300 ;Read Header
sta :rin
:r1 jsl prodos
dw $12
adrl :rparm
bcc :save
jmp :err
:save jsr newdoc1
:loop rep $30
jsr :readtwo
bcs :done1
tay
and #$FF00
cmp #$D000
bne :n1
jsr :docr
bcs :done1
bra :loop
:n1 cmp #$D800
bge :loop
jsr :dotext
bcc :loop
:done1 and #$00ff
cmp #$4C
beq :done
jmp :err
:done rep $30
lda #$00
sta gotolnum
sec
ror :loaded
:sfplp rep $30
bit :openflag
bpl :set
jsl prodos
dw $14
adrl :cparm
stz :openflag
:set bit :loaded
bpl :bit
bit :merlin
bpl :zero
sep $20
:tabson ldx #$07
]lup lda tabs1,x
sta tabs,x
dex
bpl ]lup
:zero sep $30
ldx loadfilename
]lup lda loadfilename,x
and #$7f
cmp #'a'
blt :uc
cmp #'z'+1
bge :uc
and #$5f
:uc sta efilename,x
dex
bpl ]lup
:bit rep $30
bit :toolarge
bpl :sfplp1
jmp :toolarge1
:sfplp1 jsr erasebox
lda apwlen+2
beq :norm
lda #$ffff
sta flen
sta editlen
jmp :norm1
:norm lda apwlen
sta flen
sta editlen
:norm1 jsr gotoline
jsr drawmem
jsr drawtabs
jsr drawfname
:cmdxit plp
clc
rts
:err rep $30
and #$00ff
jsr doerror
stz :toolarge
jmp :sfplp
:toolarge1 lda #toobigerr
jmp :err
:merlin ds 2
:errcode ds 2
:toolarge ds 2
:loaded ds 2
:openflag ds 2
:flag ds 2
:cparm ds 2
:oparm ds 2
adrl loadfilename
adrl $0000
:rparm ds 2
:where adrl :databuff
:rin adrl $00
adrl $00
:info adrl loadfilename
ds 2
:type ds 2
:aux ds 4
ds 16
:eof ds 6
:databuff ds 512,0
:readtwo php
rep $30
lda #$02
sta :rin
stz :rin+2
jsr :read
bcs :rsec
lda :databuff
plp
clc
rts
:rsec plp
sec
rts
:read php
rep $30
jsl prodos
dw $12
adrl :rparm
bcc :rok
jmp :bad
* cmp #$4C
* jeq :bad
* jsl p8error
* bcc :read
* bra :bad
:rok plp
clc
rts
:bad plp
sec
rts
:dotext php
rep $30
tya ;Get Linerec Value
and #$00FF
sta :rin
jsr :read
bcs :txtbad
sep $30
ldy :databuff
beq :t4
:t1 lda #$20
jsr :stuffit
bcs :tmem
dey
bne :t1 ;Add Spaces
:t4 lda :databuff+$1
and #$7F
sta :len
ldy #$00
:t2 cpy :len
beq :t3
lda :databuff+$2,Y
and #$7F
cmp #$20
blt :t0
jsr :stuffit
bcs :tmem
:t0 iny
bra :t2
:t3 lda :databuff+$1
bpl :txit
lda #$0D
jsr :stuffit
bcs :tmem
:txit plp
clc
rts
:tmem lda #toobigerr
:txtbad plp
sec
rts
:len hex 0000
:docr php
tya ;Get LineRec Value
sep $30
tay
cpy #$00
beq :cr2
:cr1 lda #$20 ;SpaceChar
jsr :stuffit
bcs :memcr
dey
bne :cr1
:cr2 lda #$0D
jsr :stuffit
bcs :memcr1
plp
clc
rts
:memcr ply ;Remove counter
:memcr1 lda #toobigerr
plp
sec
rts
:stuffit phy
phx
php
rep $30
ldy apwlen+2
bne :full
ldy apwlen
cmp #$ffff
beq :full
sep $20
sta [fileptr],y
rep $20
inc apwlen
bne :ok
inc apwlen+2
:ok plp
plx
ply
clc
rts
:full sec
ror :toolarge
plp
plx
ply
sec
rts
apwlen ds 4
saveapw rep $30
lda #$00
sta :mylen
sta :mylen+2
sta :openflag
sta :loaded
lda flen
bne :sapw
clc
jmp :sapwout
:sapw lda loadfilename
and #$ff
beq :pd
tax
lda loadfilename,x
and #$7f
cmp #'!'
bne :pd
sep $20
dec loadfilename
rep $20
:pd jsl prodos
dw $06
adrl :iparm
bcs :create
lda :ftype
cmp #$1A
beq :open
lda #$1A
sta :ftype
:q1 jsl prodos
dw $05 ;set info
adrl :iparm
bcc :open
jmp :errout
:create jsl prodos
dw $01
adrl :crparm
bcc :open
cmp #$47
beq :open
jmp :errout
:open jsl prodos
dw $10
adrl :opnparm
bcc :o1
jmp :errout
:o1 lda :opnparm
sta :wparm
sta :cparm
sec
ror :openflag
jsr :write
bcs :errout
jsl prodos
dw $14
adrl :cparm
stz :openflag
sec
ror :loaded
clc
jmp :sapwout
:errout rep $30
pha
bit :openflag
bpl :err1
jsl prodos
dw $14
adrl :cparm
stz :openflag
:err1 pla
and #$00ff
jsr doerror
sec
jmp :sapwout
:sapwout rep $30
bit :loaded
bpl :sfplp
stz alldirty
sep $30
ldx loadfilename
]lup lda loadfilename,x
and #$7f
cmp #'a'
blt :uc
cmp #'z'+1
bge :uc
and #$5f
:uc sta efilename,x
dex
bpl ]lup
rep $30
jsr drawfname
:sfplp rep $30
jsr erasebox
sep $30
plp ;pull off processor placed by COMMANDS
clc
rts
:iparm adrl loadfilename
dw $00
:ftype dw $00
ds 20,0
:crparm adrl loadfilename
dw $e3
dw $1a
adrl $0000
dw $01
adrl $00
:opnparm dw $00
adrl loadfilename
adrl $0000
:wparm dw $00
:buff adrl $0000
:ct adrl $0000
:trans adrl $0000
:cparm dw $00
:openflag ds 2
:eofparm ds 2
:eof adrl $0000
:smark dw $00
:pos adrl $12c
:mylen ds 4
:loaded ds 2
:write rep $30
lda #:header
sta :buff
lda #^:header
sta :buff+$2
lda #$12C
sta :ct
lda #$00
sta :done
lda :opnparm
sta :smark
sta :eofparm
:wrt jsl prodos
dw $13
adrl :wparm
bcc :l
jmp :werr
:l lda :done
bne :exit
jsr :gline
rep $30
lda :length
and #$00ff
sta :ct
lda #$00
sta :ct+$2
lda #:line
sta :buff
lda #^:line
sta :buff+$2
jmp :wrt
:exit lda #<:end
sta :buff
lda #^:end
sta :buff+$2
lda #$04
sta :ct
lda #$00
sta :ct+2
jsl prodos
dw $13
adrl :wparm
bcc :q2
jmp :werr
:q2 jsl prodos
dw $17 ;getmark
adrl :smark
bcc :q3
jmp :werr
:q3 ldy #$02
:e1 sep $20
lda :pos,y
sta :eof,y
dey
bpl :e1
rep $20
:q4 jsl prodos
dw $18
adrl :eofparm
bcc :q5
jmp :werr
:q5 clc
rts
:werr sec
rts
:header hex 2e2200004f3d3d3d
hex 3d3d7c3d3d3d3d7c
hex 3d3d3d3d7c3d3d3d
hex 3d7c3d3d3d3d7c3d
hex 3d3d3d7c3d3d3d3d
hex 7c3d3d3d3d7c3d3d
hex 3d3d7c3d3d3d3d7c
hex 3d3d3d3d7c3d3d3d
hex 3d7c3d3d3d3d7c3d
hex 3d3d3d7c3d3d3d3d
hex 7c3d3d3d00002c22
hex 02
ds 211,0
:end hex 00d0ffff
:gline rep $30
lda #$00
sta :line
sta :line+$2
sta :length
sta :glct
sta :spc
sta :tflag
sta :txt
jmp :main
:m1 sep $30
dec :glct
:main sep $30
lda :glct
cmp #$50
jeq :glexit
jsr :gchar
bcs :glend
and #$7F
sta :char
inc :glct
lda :char
cmp #$0D
beq :cr
cmp #$20
blt :m1
beq :spc1
inc :tflag
:0 inc :txt
jmp :1
:spc1 lda :tflag
bne :0
inc :spc
:1 ldy :txt
dey
lda :char
sta :line1,y
jmp :main
:cr lda :tflag
beq :crrec
lda #$80
bne :2
:glexit lda #$00
:2 ora :txt
sta :line+$3
lda :spc
sta :line+$2
lda #$00
sta :line+$1
lda :txt
clc
adc #$02
sta :line
adc #$02
sta :length
rts
:crrec lda :spc
sta :line
lda #$D0
sta :line+$1
lda #$02
sta :length
rts
:glend lda #$01
sta :done
jmp :cr
mx %00
:gchar php
rep $30
ldy :mylen
lda [fileptr],y
and #$ff
iny
beq :gdone
sty :mylen
cpy flen
bge :gdone
plp
clc
rts
:gdone sec
ror :done
plp
sec
rts
:glct hex 0000
:tflag hex 0000
:spc hex 0000
:txt hex 0000
:char hex 0000
:done hex 0000
:length hex 0000
:line hex 00000000
:line1 ds 275,0
gopos rep $30
and #$7f
sec
sbc #$30
dec
sta :temp
pha
pha
lda flen
pha
pea $8 ;divide by 9
tll $0b0b
pla
plx
pha
pha
pha
lda :temp
pha
tll $090b
pla
sta gotoposition
pla
jsr gotopos
stz gotoposition
jsr getbuff
jsr drawline
stz pos
jsr poscurs
:cmdxit sep $30
plp
clc
rts
:temp ds 2
drawstr ;ent
php
phb
phk
plb
phd
rep $30
pha
phx
phy
tsc
tcd
lda [14]
and #$00FF
sta :len
beq :xit
phy
ldy #$01
]lup cpy :len
blt :next
beq :next
bra :xit1
:next lda [14],y
and #$7F
phy
jsl drawchar
ply
iny
bra ]lup
:xit1 ply
:xit ldx #12
]lup lda $00,X
sta $04,X
dex
dex
bne ]lup
tsc
clc
adc #$04
tcs
ply
plx
pla
pld
plb
plp
rtl
:len ds 2
drawchar ;ent
phx
php
rep $30
and #$7F
cmp #$0D
beq :cr
pha
tll $180C
sep $20
lda tcursx
inc
sta tcursx
lda tcursx
cmp #80
blt :xit
:cr1 rep $30
lda #$00
sta tcursx
lda tcursy
inc
cmp #24
blt :st
lda #23
:st sta tcursy
:xit plp
plx
rtl
mx %00
:cr pha
tll $180C
pea $0A
tll $180C
jmp :cr1
ffeed rtl
printdec ;ent
php
phb
phd
phk
plb
rep $30
stz :first
tsc
tcd
lda $08
sta :flags
lda [$0A]
ldx #$00
]lup cmp #10000
blt :thous
inx
sec
sbc #10000
jmp ]lup
:thous sta :number
txa
clc
adc #$30
jsr :draw
ldx #$00
lda :number
]lup cmp #1000
blt :hun
inx
sec
sbc #1000
jmp ]lup
:hun sta :number
txa
clc
adc #$30
jsr :draw
ldx #$00
lda :number
]lup cmp #100
blt :ten
inx
sec
sbc #100
jmp ]lup
:ten sta :number
txa
clc
adc #$30
jsr :draw
ldx #$00
lda :number
]lup cmp #10
blt :one
inx
sec
sbc #10
jmp ]lup
:one sta :number
txa
clc
adc #$30
jsr :draw
sec
ror :first
lda :number
clc
adc #$30
jsr :draw
:xit ldx #$06
]lup lda 0,x
sta 6,x
dex
dex
bpl ]lup
rep $30
tsc
clc
adc #6
tcs
pld
plb
plp
rtl
:draw cmp #'0'
beq :zero
jsl drawchar
sec
ror :first
rts
:zero bit :first
bmi :zeroout
bit :flags
bpl :rts
bvs :zeroout
lda #$20
:zeroout jsl drawchar
:rts rts
:number ds 2
:flags ds 2
:first ds 2
tprbytel ;ent
php
phb
phk
plb
rep $30
sta :byte
xba
jsl prbyte
lda :byte
jsl prbyte
plb
plp
rtl
:byte ds 2
prbyte ;ent
pha
phy
phx
php
phb
phk
plb
rep $30
pha
lsr
lsr
lsr
lsr
and #$0F
jsr :nib
pla
and #$F
jsr :nib
plb
plp
plx
ply
pla
rtl
:nib ora #"0"
cmp #"9"+1
blt :ok
adc #"A"-"9"-2
:ok and #$7F
jsl drawchar
rts

22
src/edit/edit.cmd.s Normal file
View File

@ -0,0 +1,22 @@
*======================================================
* Link file for QuickEdit v2.00
* Written by Lane Roath
*======================================================
asm edit
do err
else
lnk obj/edit.l
ds 1000
fin
typ exe
sav utility/newedit
end

81
src/edit/edit.equs.s Normal file
View File

@ -0,0 +1,81 @@
*======================================================
* Equates for QuickEdit v2.00... written by Lane Roath
cda equ 0 ;0=EXE file,1=CDA
library equ 0 ;is QE a part of another program?
softdisk equ 0 ;include SOFTDISK code?
mouse equ 0 ;allow mouse control?
debug equ 0 ;Must be ZERO
right equ 80 ;right margin value
catentries equ 9 ;how many "catalog" entries to show
dplength equ $100
dum 1
toobigerr ds 1
nottext ds 1
syntaxerr ds 1
outofmem ds 1
notdir ds 1
dend
dum $00 ;zero page usage
zpage ds 4
zpage1 ds 4
fileptr ds 4
tempzp ds 4
tempzp1 ds 4
basl ds 2
cliphandle ds 4
editbufhdl ds 4
termch ds 2
termcv ds 2
mych ds 2
mycv ds 2
base ds 2
tcursx ds 2
tcursy ds 2
dirzp ds 4
asynckey ds 2
showcr ds 2
superquit ds 2
loaderstat ds 2
oflag ds 2
linenum ds 2
gotolnum ds 2
gotoposition ds 2
marker ds 2
xval ds 2
yval ds 2
aval ds 2
emstarted ds 2
intstatus ds 2
textdevice ds 4
texttype ds 2
textor ds 2
textand ds 2
grafentry ds 2
flen ds 2
oldlen ds 2
pos ds 2
pos1 ds 2
eof ds 2
sof ds 2
position ds 2
dirty ds 2
alldirty ds 2
selstart ds 2
selend ds 2
selecting ds 2
selectflag ds 2
equitflag ds 2
workspace ds 16
err */$100
dend

84
src/edit/edit.macs.s Normal file
View File

@ -0,0 +1,84 @@
^RESTOREHANDLE MAC
PHL ]1
Tool $B02
<<<
^CHECKHANDLE MAC
PHL ]1
Tool $1E02
<<<
^SETPURGE MAC
PHWL ]1;]2
Tool $2402
<<<
^NEWHANDLE MAC
P2SL ]1
PxW ]2;]3
PHL ]4
Tool $902
<<<
^GETNEWID MAC
P1SW ]1
Tool $2003
<<<
PHWL MAC
PHW ]1
PHL ]2
<<<
PXW MAC
DO ]0/1
PHW ]1
DO ]0/2
PHW ]2
DO ]0/3
PHW ]3
DO ]0/4
PHW ]4
FIN
FIN
FIN
FIN
<<<
P2SL MAC
PHA
PHA
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
PHL MAC
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
P1SW MAC
PHA
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PHW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<

5515
src/edit/edit.s Normal file

File diff suppressed because it is too large Load Diff

278
src/edit/edit.types.s Normal file
View File

@ -0,0 +1,278 @@
lst off
do 1
filetypelist
ASC 'NON'
ASC 'BAD'
ASC '$02'
ASC '$03'
ASC 'TXT'
ASC '$05'
ASC 'BIN'
ASC '$07'
ASC '$08'
ASC '$09'
ASC '$0A'
ASC '$0B'
ASC '$0C'
ASC '$0D'
ASC '$0E'
ASC 'DIR'
ASC '$10'
ASC '$11'
ASC '$12'
ASC '$13'
ASC '$14'
ASC '$15'
ASC 'PFS'
ASC '$17'
ASC '$18'
ASC 'ADB'
ASC 'AWP'
ASC 'ASP'
ASC '$1C'
ASC '$1D'
ASC '$1E'
ASC '$1F'
ASC '$20'
ASC '$21'
ASC '$22'
ASC '$23'
ASC '$24'
ASC '$25'
ASC '$26'
ASC '$27'
ASC '$28'
ASC '$29'
ASC '$2A'
ASC '$2B'
ASC '$2C'
ASC '$2D'
ASC '$2E'
ASC '$2F'
ASC '$30'
ASC '$31'
ASC '$32'
ASC '$33'
ASC '$34'
ASC '$35'
ASC '$36'
ASC '$37'
ASC '$38'
ASC '$39'
ASC '$3A'
ASC '$3B'
ASC '$3C'
ASC '$3D'
ASC '$3E'
ASC '$3F'
ASC '$40'
ASC '$41'
ASC '$42'
ASC '$43'
ASC '$44'
ASC '$45'
ASC '$46'
ASC '$47'
ASC '$48'
ASC '$49'
ASC '$4A'
ASC '$4B'
ASC '$4C'
ASC '$4D'
ASC '$4E'
ASC '$4F'
ASC '$50'
ASC '$51'
ASC '$52'
ASC '$53'
ASC '$54'
ASC '$55'
ASC '$56'
ASC '$57'
ASC '$58'
ASC '$59'
ASC '$5A'
ASC '$5B'
ASC '$5C'
ASC '$5D'
ASC '$5E'
ASC '$5F'
ASC '$60'
ASC '$61'
ASC '$62'
ASC '$63'
ASC '$64'
ASC '$65'
ASC '$66'
ASC '$67'
ASC '$68'
ASC '$69'
ASC '$6A'
ASC '$6B'
ASC '$6C'
ASC '$6D'
ASC '$6E'
ASC '$6F'
ASC '$70'
ASC '$71'
ASC '$72'
ASC '$73'
ASC '$74'
ASC '$75'
ASC '$76'
ASC '$77'
ASC '$78'
ASC '$79'
ASC '$7A'
ASC '$7B'
ASC '$7C'
ASC '$7D'
ASC '$7E'
ASC '$7F'
ASC '$80'
ASC '$81'
ASC '$82'
ASC '$83'
ASC '$84'
ASC '$85'
ASC '$86'
ASC '$87'
ASC '$88'
ASC '$89'
ASC '$8A'
ASC '$8B'
ASC '$8C'
ASC '$8D'
ASC '$8E'
ASC '$8F'
ASC '$90'
ASC '$91'
ASC '$92'
ASC '$93'
ASC '$94'
ASC '$95'
ASC '$96'
ASC '$97'
ASC '$98'
ASC '$99'
ASC '$9A'
ASC '$9B'
ASC '$9C'
ASC '$9D'
ASC '$9E'
ASC '$9F'
ASC '$A0'
ASC '$A1'
ASC '$A2'
ASC '$A3'
ASC '$A4'
ASC '$A5'
ASC '$A6'
ASC '$A7'
ASC '$A8'
ASC '$A9'
ASC '$AA'
ASC 'BAS'
ASC 'TDF'
ASC 'DAT'
ASC '$AE'
ASC '$AF'
ASC 'SRC'
ASC 'OBJ'
ASC 'LIB'
ASC 'S16'
ASC 'RTL'
ASC 'EXE'
ASC 'PIF'
ASC 'TIF'
ASC 'NDA'
ASC 'CDA'
ASC 'TOL'
ASC 'DRV'
ASC '$BC'
ASC 'FST'
ASC '$BE'
ASC 'DOC'
ASC 'PNT'
ASC 'PIC'
ASC '$C2'
ASC '$C3'
ASC '$C4'
ASC '$C5'
ASC '$C6'
ASC '$C7'
ASC 'FON'
ASC 'FND'
ASC 'ICN'
ASC '$CB'
ASC '$CC'
ASC '$CD'
ASC '$CE'
ASC '$CF'
ASC '$D0'
ASC '$D1'
ASC '$D2'
ASC '$D3'
ASC '$D4'
ASC '$D5'
ASC '$D6'
ASC '$D7'
ASC '$D8'
ASC '$D9'
ASC '$DA'
ASC '$DB'
ASC '$DC'
ASC '$DD'
ASC '$DE'
ASC '$DF'
ASC 'TEL'
ASC '$E1'
ASC 'ATK'
ASC '$E3'
ASC '$E4'
ASC '$E5'
ASC '$E6'
ASC '$E7'
ASC '$E8'
ASC '$E9'
ASC '$EA'
ASC '$EB'
ASC '$EC'
ASC '$ED'
ASC '$EE'
ASC 'PAS'
ASC '$F0'
ASC '$F1'
ASC '$F2'
ASC '$F3'
ASC '$F4'
ASC '$F5'
ASC '$F6'
ASC '$F7'
ASC 'LNK'
ASC 'DOS'
ASC 'INT'
ASC 'IVR'
ASC 'BAS'
ASC 'VAR'
ASC 'REL'
ASC 'SYS'
fin
ftmonths
asc 'Jan-'
asc 'Feb-'
asc 'Mar-'
asc 'Apr-'
asc 'May-'
asc 'Jun-'
asc 'Jul-'
asc 'Aug-'
asc 'Sep-'
asc 'Oct-'
asc 'Nov-'
asc 'Dec-'
lst rtn

1
src/exe/ascii.s Normal file
View File

@ -0,0 +1 @@
<EFBFBD> <EFBFBD>

1
src/exe/cat.cmd.s Normal file
View File

@ -0,0 +1 @@
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

1
src/exe/cat.macs.s Normal file
View File

@ -0,0 +1 @@
<EFBFBD>涿<EFBFBD>尿<EFBFBD><EFBFBD><EFBFBD>丿<EFBFBD><EFBFBD><EFBFBD>尿尿<EFBFBD>尿尿<EFBFBD>尿尿<EFBFBD><EFBFBD>

1
src/exe/catalog.s Normal file
View File

@ -0,0 +1 @@
 μστ οζζ<EFBFBD> τς<EFBFBD> ψγ<EFBFBD> ψγ<EFBFBD> νψ ¥°°<EFBFBD><EFBFBD>½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½<EFBFBD><EFBFBD> Γαταμοη υτιμιτω ζος

1
src/exe/del.cmd.s Normal file
View File

@ -0,0 +1 @@
<EFBFBD> בףם הול<EFBFBD><EFBFBD> למכ ²¯ןגך¯הול®ל<EFBFBD><EFBFBD> הף ³°°<EFBFBD><EFBFBD> ףבצ ²¯ץפיליפש¯הולופו<EFBFBD>

1
src/exe/dump.s Normal file
View File

@ -0,0 +1 @@
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>秿秿<EFBFBD><EFBFBD><EFBFBD>尿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD>

1
src/exe/time.s Normal file
View File

@ -0,0 +1 @@
 μστ οζζ<EFBFBD> τς<EFBFBD> ψγ<EFBFBD> ψγ<EFBFBD> νψ ¥°°<EFBFBD><EFBFBD>½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½½<EFBFBD><EFBFBD> δατετινε υτιμιτω ζος

163
src/intcmd/intcmd.macs.s Normal file
View File

@ -0,0 +1,163 @@
_GSOS MAC
do inline
jsl prodos
dw ]1
adrl ]2
else
psl #]2
pea ]1
jsl prodosIL
fin
<<<
_DISPOSEHANDLE MAC
Tool $1002
<<<
^PURGEALL MAC
PHW ]1
Tool $1302
<<<
_COMPACTMEM MAC
Tool $1F02
<<<
_HLOCK MAC
Tool $2002
<<<
~QAGetWord MAC
pha
pha
psl ]1
phw ]2
phw ]3
_QAGetWord mac ;_QAGetWord(@Text,Offset,MaxLen):BegOffset,EndOffset
utool $61
<<<
PSL mac
if #,]1
pea ^]1
pea ]1
else
if :,]1
lda ]1+2
pha
lda ]1
pha
else
lda ]1+2
pha
lda ]1
pha
fin
fin
eom
PLL mac
if :,]1
pla
sta ]1
pla
sta ]1+2
else
pla
sta ]1
pla
sta ]1+2
fin
eom
TOOL mac
ldx #]1
jsl $E10000
eom
TLL mac
ldx #]1
jsl $E10000
eom
JEQ mac
bne *+5
jmp ]1
eom
JGE mac
blt *+5
jmp ]1
eom
JLT mac
bge *+5
jmp ]1
eom
JCS mac
bcc *+5
jmp ]1
eom
_QADRAWCHAR mac
utool $09
eom
_QADRAWSTRING mac
utool $0A
eom
_QADRAWSTR mac
utool $0A
eom
_QAGETPARMHDL mac
utool $12
eom
_QAGETCMDHDL mac
utool $14
eom
_QALOADFILE mac
utool $18
eom
_QAGETCMDLINE mac
utool $1B
eom
_QASETQUITFLAG mac
utool $1E
eom
_QACOMPILE mac
utool $26
eom
_QALINK mac
utool $27
eom
_QAGETVECTOR mac
utool $2E
eom
_QASETVECTOR mac
utool $2F
eom
_QATABTOCOL mac
utool $33
eom
_QASETCANCELFLAG mac
utool $40
eom
_QAGETSHELLID mac
utool $55
eom
_QASETLAUNCH mac
utool $60
eom
_QADRAWCR mac
utool $63
<<<
_QADRAWSPACE mac
utool $64
<<<
UTOOL mac
ldx #]1*256+toolnum
do userorsys
jsl $E10008
else
jsl $E10000
fin
eom
PHW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<

22
src/intcmd/qaintcmd.cmd.s Normal file
View File

@ -0,0 +1,22 @@
*======================================================
* Link file for QASM loader (launch) file
* Written by Lane Roath
*======================================================
asm qaintcmd
do err
else
lnk obj/qaintcmd.l
ds 400 ;DS_Size
typ RTL
sav qasystem/qaintcmd
fin
end

1024
src/intcmd/qaintcmd.s Normal file

File diff suppressed because it is too large Load Diff

10
src/link/link.cmd.s Normal file
View File

@ -0,0 +1,10 @@
put link.vars
put link.eval
put linker.1
put linker.2
put link.errors
asm link.header
lnk utility/qlinkgs.l
typ exe
sav utility/qlinkgs

197
src/link/link.errors.s Normal file
View File

@ -0,0 +1,197 @@
dskerror php
rep $30
sta prodoserr
lda #doserror
jsr linkerror
plp
rts
linkerror php
rep $30
sta :errcode
pea 0
_QAGetWindow
pea $FFFF
_QASetWindow
_QAIncTotalErrs
cmp #constraint
jeq :xit
cmp #notresolved
jeq :xit
:ldx ldx #$00
]lup lda errtbl,x
beq :unknown
cmp :errcode
beq :found
inx
inx
inx
inx
jmp ]lup
:unknown psl #unknownstr
jmp :draw
:found inx
inx
phk
phk
pla
and #$00ff
pha
lda errtbl,x
pha
:draw lda #$0d
jsr drawchar
_QADrawString
psl #textstr
_QADrawString
:line pea 0
lda linenum
pha
pea 0
pea 0
_QADrawDec
lda :errcode
cmp #doserror
jne :period
ldx #$00
]lup lda gstbl,x
beq :gsnfound
cmp prodoserr
beq :gfound
inx
inx
inx
inx
jmp ]lup
:gfound inx
inx
lda gstbl,x
tax
phk
phk
pla
and #$00ff
pha
phx
lda #$20
jsr drawchar
_QADrawString
jmp :period
:gsnfound psl #dosstr
lda #$20
jsr drawchar
_QADrawErrString
lda prodoserr
jsr prbytel
:period lda #'.'
jsr drawchar
* psl #codestr
* _QADrawErrString
* lda :errcode
* jsr prbyte
lda #$0d
jsr drawchar
:xit rep $30
_QASetWindow
plp
rts
:errcode ds 2
gstbl dw $07,gstr1
dw $27,gstr2
dw $28,gstr3
dw $2b,gstr4
dw $2e,gstr5
dw $2f,gstr6
dw $40,gstr7
dw $44,gstr8
dw $45,gstr9
dw $46,gstr10
dw $47,gstr11
dw $48,gstr12
dw $4e,gstr13
dw $201,gstr14
dw mismatch,gstr15 ;error $5C
dw $0000,$0000
errtbl dw syntax,str1
dw badasmcmd,str2
dw badcmd,str3
dw badlable,str4
dw outofmem,str5
dw undeflable,str6
dw badoperand,str7
dw badrelative,str8
dw symfull,str9
dw baddictionary,str10
dw badexternal,str11
dw extnotzp,str12
dw maxsegments,str13
dw relfull,str14
dw dupentry,str15
dw maxfileserr,str16
dw onesave,str17
dw badvalue,str18
dw doserror,str19
dw badalignop,str20
dw jmptblfull,str21
dw baddsop,str22
dw illegalcmd,str23
dw filetoolarge,str24
dw nesterror,str25
dw forwardref,str26
dw $0000,$0000
str1 str 'Syntax'
str2 str 'Bad ASM command'
str3 str 'Unrecognized command'
str4 str 'Bad label'
str5 str 'Out of memory'
str6 str 'Undefined label'
str7 str 'Bad operand'
str8 str 'Bad relative address'
str9 str 'Symbol table full'
str10 str 'Bad dictionary entry'
str11 str 'Bad external lable'
str12 str 'External not direct page'
str13 str 'Too many segments'
str14 str 'Relocation dictionary full'
str15 str 'Duplicate ENTry'
str16 str 'Too many files'
str17 str 'Only one SAV allowed'
str18 str 'Bad value'
str19 str 'GS/OS error'
str20 str 'Bad ALIGN'
str21 str 'Jump table full'
str22 str 'Unable to reserve DS space'
str23 str 'Illegal command'
str24 str 'File too large'
str25 str 'Conditional nesting level error'
str26 str 'Illegal forward reference'
gstr1 str '<GS/OS is busy>'
gstr2 str '<I/O error>'
gstr3 str '<No device connected>'
gstr4 str '<Write protected>'
gstr5 str '<Disk switched>'
gstr6 str '<No disk in drive>'
gstr7 str '<Invalid pathname>'
gstr8 str '<Directory not found>'
gstr9 str '<Volume not found>'
gstr10 str '<File not found>'
gstr11 str '<Duplicate filename>'
gstr12 str '<Disk full>'
gstr13 str '<File locked>'
gstr14 str '<Memory manager: Unable to allocate memory>'
gstr15 str '<File type mismatch>'
unknownstr str '<Unknown error>'
codestr str ' Code=$'
textstr str ' in line: '
dosstr str 'GS/OS Code #'

1342
src/link/link.eval.s Normal file

File diff suppressed because it is too large Load Diff

1345
src/link/link.express.s Normal file

File diff suppressed because it is too large Load Diff

501
src/link/link.header.s Normal file
View File

@ -0,0 +1,501 @@
lst off
cas in
tr on
exp only
rel
xc
xc
mx %00 ; make sure we're in 16-bit mode!
doexpress = $01
use 4/util.macs
use qatools.macs
use 2/qa.equates
brl start
put link.vars
userid ds 2 ;my userid
linkdp ds 2
filename ds 130,0
quickname ds 130,0
txttypes hex 0204B0
lnktype hex 01f8
start php
phb
phd
phk
plb
rep $30
sta userid
tdc
sta linkdp
pea 0
_QAStatus
pla
bne :ok
pld
plb
plp
rep $30
jsl prodos
dw $29
adrl :quit
:quit adrl $00
dw $00
:ok rep $30
stz prodoserr
stz quicklink
pea 0
psl #$00
lda userid
pha
_QAGetMessagebyID
pla
sta subtype
pla
sta subtype+2
pla
sta message
stz filename
lda message
beq :xit1
cmp #maxlmessage
blt :call
lda #$FFFF
jmp :xit
:call dec
asl
tax
jsr (:tbl,x)
bra :xit
:bad lda #$FFFF
bra :xit
:xit1 lda #$00
:xit rep $30
pha
lda userid
ora #linkmemid
pha
_disposeall
pla
pld
plb
plp
cmpl :one
rtl
:one dw $01
:tbl dw cmdline
dw txtfile
dw fromhandle
dw doquicklink
dw project1
dw project2
project1 php
rep $30
lda #$46
plp
cmp :one
rts
:one dw 1
project2 php
rep $30
lda #$46
plp
cmp :one
rts
:one dw 1
fromhandle php
rep $30
psl #linkstr
_QADrawString
lda #'.'
jsr drawchar
lda #$0d
jsr drawchar
ldx subtype
ldy subtype+2
jsl link
bcc :clc
:sec rep $30
plp
sec
rts
:clc rep $30
lda #$00
plp
clc
rts
txtfile php
rep $30
psl #asmpath
_QAGetPath
lda asmpath
and #$ff
jeq :notfound
tay
sep $20
]lup lda asmpath,y
tyx
and #$7f
sta filename,x
dey
bpl ]lup
lda filename
cmp #62
bge :nosufx
tax
lda filename,x
cmp #'/'
beq :nosufx
cmp #':'
beq :nosufx
inc filename
inc filename
inx
lda #'.'
sta filename,x
inx
lda #'S'
sta filename,x
:nosufx rep $30
psl #$00
psl #filename
psl #$00 ;filepos
psl #-1 ;whole file
psl #txttypes
lda userid
ora #linkmemid
pha
psl #$00
pea $8000
_QALoadfile
plx
ply
jcs :sec
phx
phy
psl #linkstr
_QADrawString
lda #' '
jsr drawchar
psl #filename
_QADrawString
lda #$0d
jsr drawchar
ply
plx
jsl link
bcc :clc
jmp :sec
:notfound rep $30
lda #$46
:sec rep $30
plp
sec
rts
:clc rep $30
lda #$0000
plp
clc
rts
doquicklink php
rep $30
lda subtype
ora subtype+2
bne :file
psl #$00
psl #qtextend-qtext
lda userid
ora #linkmemid
pha
pea $8000
psl #$00
_Newhandle
plx
ply
jcs :sec
phy
phx
psl #qtext
phy
phx
psl #qtextend-qtext
tll $2802 ;_PtrToHand
psl #quickname
_QAGetPath
lda #^quickname
sta subtype+2
lda #quickname
sta subtype
jmp :go1
:file sep $30
ldx :fname
]lup lda :fname,x
sta filename,x
dex
bpl ]lup
rep $30
psl #$00
psl #filename
psl #$00 ;filepos
psl #-1 ;whole file
psl #txttypes
lda userid
ora #linkmemid
pha
psl #$00
pea $8000
_QALoadfile
plx
ply
bcc :go
cmp #$46
beq :next
jmp :sec
:next sep $30
ldx :fname1
]lup lda :fname1,x
sta filename,x
dex
bpl ]lup
rep $30
psl #$00
psl #filename
psl #$00 ;filepos
psl #-1 ;whole file
psl #txttypes
lda userid
ora #linkmemid
pha
psl #$00
pea $8000
_QALoadfile
plx
ply
jcs :sec
:go phx
phy
:go1 psl #:quickstr
_QADrawString
lda #$FFFF
sta quicklink
psl #:zero
_QASetObjPath
ply
plx
jsl link
bcc :clc
jmp :sec
:notfound rep $30
lda #$46
:sec rep $30
plp
sec
rts
:clc rep $30
lda #$0000
plp
clc
rts
:fname str 'QuickLINK.S'
:fname1 str '1:QASYSTEM:QuickLINK.S'
:quickstr str 0d,'Linking.',0d
:zero hex 0000
qtext asc ' OVR ALL',0D
asc ' ASM ',5D,'1',0D
asc ' LNK ',5D,'2',0D
asc ' SAV ',5D,'3',0D
qtextend
cmdline php
rep $30
psl #asmpath
pea 80
_QAGetCmdLine
ldy #$01
sep $30
lda asmpath
beq :notfound
]lup lda asmpath,y
and #$7f
cmp #' '
blt :notfound
bne :p1
iny
jmp ]lup
:p1 iny
]lup lda asmpath,y
and #$7f
cmp #' '
blt :notfound
beq :p2
iny
jmp ]lup
:p2 iny
]lup lda asmpath,y
and #$7f
cmp #' '
blt :notfound
bne :ok
iny
jmp ]lup
:ok ldx #$00
sta filename+1,x
]get inx
iny
lda asmpath,y
and #$7f
cmp #' '+1
blt :set
sta filename+1,x
jmp ]get
:notfound jmp :nf1
:set txa
sta filename
rep $30
lda filename
and #$ff
cmp #62
bge :nosuff
tax
lda filename,x
and #$7f
cmp #'/'
beq :nosuff
cmp #':'
beq :nosuff
inx
lda #'.S'
sta filename,x
inx
txa
sep $20
sta filename
:nosuff rep $30
psl #$00
psl #filename
psl #$00 ;filepos
psl #-1 ;whole file
psl #txttypes
lda userid
ora #linkmemid
pha
psl #$00
pea $8000
_QALoadfile
plx
ply
jcs :xit
phy
phx
psl #linkstr
_QADrawString
lda #' '
jsr drawchar
psl #filename
_QADrawString
lda #$0d
jsr drawchar
plx
ply
jsl link
bcs :xit
jmp :clc
:nf1 rep $30
lda #$46
jmp :xit
:clc rep $30
lda #$0000
:xit rep $30
plp
cmp :one
rts
:one dw $01
linkstr str 0d,'Linking'
prbytel
php
rep $30
pha
phx
phy
pha
_QAPrbytel
ply
plx
pla
plp
rts
prbyte
php
rep $30
pha
phx
phy
pha
_QAPrbyte
ply
plx
pla
plp
rts
drawchar phx
phy
pha
php
rep $30
and #$7f
pha
_QADrawChar
:plp plp
pla
ply
plx
rts
put linker.1
put linker.2
put link.eval
do doexpress
put link.express
fin
put link.errors
tempbuff ds 130
lst
chk
lst off
typ exe
sav utility/qlinkgs.l

317
src/link/link.vars.s Normal file
View File

@ -0,0 +1,317 @@
mx %00
omfprint equ 0
maxlinklab equ $4000 ;8192 linker lables
maxfiles equ 100 ;maximum link files
maxsegs equ 256
namelen equ 10 ;length of segment names
syntax equ $01+$80
doserror equ $02+$80
mismatch equ $5C
badasmcmd equ $04
badcmd equ $06+$80
badlable equ $07
outofmem equ $08+$80
undeflable equ $09
badoperand equ $0a
badrelative equ $0b
symfull equ $0c+$80
baddictionary equ $0d+$80
badexternal equ $0e
extnotzp equ $0f
maxsegments equ $10
relfull equ $11+$80
dupentry equ $12
maxfileserr equ $13+$80
onesave equ $14+$80
badvalue equ $15+$80
badalignop equ $16
jmptblfull equ $17+$80
baddsop equ $18+$80
constraint equ $19+$80
notresolved equ $20
illegalcmd equ $21+$80
filetoolarge equ $22
nesterror equ $23+$80
forwardref equ $24
badopchar equ $25
evaltoocomplex equ $26
duplable equ $27
*** label bit flags (used in linker)
linkgeqbit = %0100_0000_0000_0000
linkequbit = %0010_0000_0000_0000
linkequ1bit = %0001_0000_0000_0000
linkentrybit = %0000_1000_0000_0000
linkabsbit = %0000_0100_0000_0000
linkusedbit = %0000_0010_0000_0000
linkequvalid = %0000_0001_0000_0000
linkentused = %0000_0000_1000_0000
*** label bit flags (used in assembler) ***
localbit = %0000_0000_0000_0001
variablebit = %0000_0000_0000_0010
macrobit = %0000_0000_0000_0100
equatebit = %0000_0000_0000_1000
externalbit = %0000_0000_0001_0000
macvarbit = %0000_0000_0010_0000
linkerbit = %0001_0000_0000_0000
usedbit = %0010_0000_0000_0000
entrybit = %0100_0000_0000_0000
absolutebit = %1000_0000_0000_0000
**** Segment Record Offsets ****
dum $00
kindfield ds 2
alignfield ds 4
dsfield ds 4
orgfield ds 4
dend
do doexpress
**** ExpressLoad equates ****
emaxsegments equ 12 ;only allow 12 segments in EXPRESS
notomf equ $8001
notomf2 equ $8002
toomanysegs equ $8003
alreadyexpressed equ $8004
badsegnum equ $8005
badomfrec equ $8006
invalidexphdr equ $8007
dum $00
oldsegnum ds 2
newsegnum ds 2
ekind ds 2
fileoffset ds 4
newfileoffset ds 4
headerlen ds 2
enamelen ds 2
processed ds 2
slcsize ds 4
srelocsize ds 4
dend
fin
**** DP storage ****
dum $00
zpage ds 4
labstr ds 16 ;Lable STR that we are working on
labnum ds 2 ;REC num of current lable
lableft ds 2 ;B-Tree Structures
labright ds 2
labprev ds 2
lablocal ds 2 ;REC of Local Lable Tree
labtype ds 2 ;Type of Label
labval ds 4 ;EQU value of Lable
foundlable ds 32 ;lable REC returned from FINDLABLE
globlab ds 2 ;REC of Current Global Lable
myvalue ds 4
lvalue ds 4
caseflag ds 2
lableptr ds 4
lableptr1 ds 4
nextlableptr ds 4
asmnextlable ds 4
lasmptr ds 4
lasmptr1 ds 4
cptr ds 4
cptr1 ds 4
clength ds 4
tempptr ds 4
tempptr1 ds 4
tempptr2 ds 4
segmentptr ds 4
relptr ds 4
filehandle ds 4
filelen ds 4
fileptr ds 4
flen ds 4
dirptr ds 4
dirct ds 2
linkaddress ds 4
lineptr ds 4
jmpptr ds 4
jmphdl ds 4
subtype ds 4
modeflag ds 2
doflag = %0000_0000_1000_0000
do doexpress
*** Express DP ***
seghdrhdl ds 4
seghdrptr ds 4
segdatahdl ds 4
segdataptr ds 4
exphdl ds 4
expptr ds 4
fin
xreg ds 4 ;variables used by EVAL
yreg ds 4
val ds 4
xrel ds 2
yrel ds 2
zrel ds 2
op ds 2
top ds 2
deczp ds 2
workspace ds 16
lst
here = *
lst off
err */$100
dend
asmpath ds 130,0
rezpath ds 130,0
loadid ds 2
do doexpress
currentseg ds 2
currentseghdr ds 2
numsegments ds 2
lcsize ds 4
relocsize ds 4
expsize ds 4
remapseg ds 2
expoffset ds 4
filemark ds 4
fin
rellength ds 4
interseg ds 2
reloffset ds 4
passnum ds 2
omfoff1 ds 2
omfoff2 ds 2
omfshift ds 2
omfbytes ds 2
omfcode ds 2
omflength ds 2
linenum ds 2
maxsegnum ds 2
message ds 2
domask ds 2
dolevel ds 2
orgval ds 4
adrval ds 4
globalhdl ds 4
segmenthdl ds 4
lnkflag ds 2
lablect ds 2
asmlablect ds 2
cancelflag ds 2
totalerrs ds 2
linkversion ds 2
omfversion ds 2
verchg ds 2
lkvchg ds 2
zipflag ds 2
notfound ds 2
opflag ds 2
shiftct ds 2
savcount ds 2
lableused ds 2
noshift ds 4
compresshdl ds 4
outfileopen ds 2
objok ds 2
linktype ds 2
totalbytes ds 4
omfok ds 2
bankorg ds 2 ;used to set segment load bank
jmplength ds 2
dynamic ds 2
extseg ds 2
quicklink ds 2
linksymhdl ds 4
linksymtbl ds 4
linksymnum ds 2
linknextlbl ds 4
opmask ds 2 ;EVAL variables
number ds 2
bracevalid ds 2
estack ds 2
evallevel ds 2
evalrelok ds 2
offset ds 2
*shiftct ds 2
errlable ds 16,0
errpos ds 2
newlable ds 18,0
segheader
bytecnt ds 4
resspc ds 4,0
seglength ds 4
lablen dw namelen*256
numlen hex 04
version hex 02
banksize adrl $10000
kind dw $1000
ds 2,0
org adrl $00
align adrl $00
numsex hex 00
hex 00
segnum ds 2
entry adrl $00
dispname dw 44
disdata dw 54+namelen
loadname ds namelen
segname ds namelen
lconst hex f2
lcbytes hex 00000000
seghdrlen dw lconst-segheader
omfheader1
blkcount ds 4
resspc1 ds 4
seglength1 ds 4
kind1 hex 00
lablen1 dfb namelen
numlen1 dfb 4
version1 dfb 1
banksize1 adrl $10000
adrl $00
org1 adrl $00
align1 adrl $00
numsex1 dfb 0
lcbank dfb 0
segnum1 dw 0
entry1 adrl 0
dispname1 ds namelen*2+4
lconst1 hex f200000000
seghdrlen1 dw lconst1-omfheader1
extrabytes ds 2

5505
src/link/linker.1.s Normal file

File diff suppressed because it is too large Load Diff

1898
src/link/linker.2.s Normal file

File diff suppressed because it is too large Load Diff

163
src/macs/intcmd.macs.s Normal file
View File

@ -0,0 +1,163 @@
_GSOS MAC
do inline
jsl prodos
dw ]1
adrl ]2
else
psl #]2
pea ]1
jsl prodosIL
fin
<<<
_DISPOSEHANDLE MAC
Tool $1002
<<<
^PURGEALL MAC
PHW ]1
Tool $1302
<<<
_COMPACTMEM MAC
Tool $1F02
<<<
_HLOCK MAC
Tool $2002
<<<
~QAGetWord MAC
pha
pha
psl ]1
phw ]2
phw ]3
_QAGetWord mac ;_QAGetWord(@Text,Offset,MaxLen):BegOffset,EndOffset
utool $61
<<<
PSL mac
if #,]1
pea ^]1
pea ]1
else
if :,]1
lda ]1+2
pha
lda ]1
pha
else
lda ]1+2
pha
lda ]1
pha
fin
fin
eom
PLL mac
if :,]1
pla
sta ]1
pla
sta ]1+2
else
pla
sta ]1
pla
sta ]1+2
fin
eom
TOOL mac
ldx #]1
jsl $E10000
eom
TLL mac
ldx #]1
jsl $E10000
eom
JEQ mac
bne *+5
jmp ]1
eom
JGE mac
blt *+5
jmp ]1
eom
JLT mac
bge *+5
jmp ]1
eom
JCS mac
bcc *+5
jmp ]1
eom
_QADRAWCHAR mac
utool $09
eom
_QADRAWSTRING mac
utool $0A
eom
_QADRAWSTR mac
utool $0A
eom
_QAGETPARMHDL mac
utool $12
eom
_QAGETCMDHDL mac
utool $14
eom
_QALOADFILE mac
utool $18
eom
_QAGETCMDLINE mac
utool $1B
eom
_QASETQUITFLAG mac
utool $1E
eom
_QACOMPILE mac
utool $26
eom
_QALINK mac
utool $27
eom
_QAGETVECTOR mac
utool $2E
eom
_QASETVECTOR mac
utool $2F
eom
_QATABTOCOL mac
utool $33
eom
_QASETCANCELFLAG mac
utool $40
eom
_QAGETSHELLID mac
utool $55
eom
_QASETLAUNCH mac
utool $60
eom
_QADRAWCR mac
utool $63
<<<
_QADRAWSPACE mac
utool $64
<<<
UTOOL mac
ldx #]1*256+toolnum
do userorsys
jsl $E10008
else
jsl $E10000
fin
eom
PHW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<

599
src/macs/qatools.macs.s Normal file
View File

@ -0,0 +1,599 @@
_QABootInit mac ;_QABootInit()
utool $01
<<<
~QAStartup MAC
psw ]1
psl ]2
_QAStartup mac ;_QAStartup(userid,modeflags/4)
utool $02
<<<
_QAShutdown mac ;_QAShutdown()
utool $03
<<<
~QAVersion MAC
pha
_QAVersion mac ;_QAVersion():versionnum
utool $04
<<<
_QAReset mac ;_QAReset()
utool $05
<<<
~QAStatus MAC
pha
_QAStatus mac ;_QAStatus():statflag
utool $06
<<<
~QADrawChar MAC
phw ]1
_QADrawChar mac ;_QADrawChar(char)
utool $09
<<<
~QADrawString MAC
~QADrawStr MAC
psl ]1
_QADrawString mac ;_QADrawString(@strptr)
_QADrawStr mac
utool $0A
<<<
~QAPrByte MAC
psw ]1
_QAPrByte mac ;_QAPrByte(byteval)
utool $0B
<<<
~QAPrByteL MAC
psw ]1
_QAPrByteL mac ;_QAPrByteL(hexval)
utool $0C
<<<
~QADrawDec MAC
psl ]1
psw ]2
ps2 ]3
_QADrawDec mac ;_QADrawDec(longint/4,flags,fieldsize)
utool $0D
<<<
~QAKeyAvail MAC
pha
_QAKeyAvail mac ;_QAKeyAvail():availflag
utool $0E
<<<
~QAGetChar MAC
pha
_QAGetChar mac ;_QAGetChar():char (char in low/modifiers in high)
utool $0F
<<<
_QAGetLine mac ;_QAGetLine(@linestr)
utool $10
<<<
~QASetParmHdl MAC
psl ]1
_QASetParmHdl mac ;_QASetParmHdl(parmhandle)
utool $11
<<<
~QAGetParmHdl MAC
pha
pha
_QAGetParmHdl mac ;_QAGetParmHdl():parmhandle
utool $12
<<<
~QASetCmdHdl MAC
psl ]1
psw ]2
_QASetCmdHdl mac ;_QASetCmdHdl(commandhandle,numcmds)
utool $13
<<<
~QAGetCmdHdl MAC
pha
pha
pha
_QAGetCmdHdl mac ;_QAGetCmdHdl():commandhandle,numcmds
utool $14
<<<
~QAReadTotalErrs MAC
pha
_QAReadTotalErrs mac ;_QAReadTotalErrs():totalerrs
utool $15
<<<
~QAGetModeFlags MAC
pha
pha
_QAGetModeFlags mac ;_QAGetModeFlags():modeflags/4
utool $16
<<<
~QASetModeFlags MAC
psl ]1
_QASetModeFlags mac ;_QASetModeFlags(modeflags/4)
utool $17
<<<
_QALoadFile mac ;_QALoadfile(@filename,filepos/4,length/4,@typelist,userid,address/4,memattrib):filehandle/4
utool $18
<<<
_QASaveFile mac ;_QASavefile(filehandle/4,@filename,filetype,auxtype/4)
utool $19
<<<
~QASetCmdLine MAC
psl ]1
_QASetCmdLine mac ;_QASetCmdLine(@strptr)
utool $1A
<<<
~QAGetCmdLine MAC
psl ]1
psw ]2
_QAGetCmdLine mac ;_QAGetCmdLine(@strptr,maxlen)
utool $1B
<<<
~QAParseCmdLine MAC
pha
pha
psl ]1
_QAParseCmdLine mac ;_QAParseCmdLine(@strptr):cmdid,cmdtype
utool $1C
<<<
~QAGetQuitFlag MAC
pha
_QAGetQuitFlag mac ;_QAGetQuitFlag():quitflag
utool $1D
<<<
~QASetQuitFlag MAC
psw ]1
_QASetQuitFlag mac ;_QASetQuitFlag(quitflag)
utool $1E
<<<
~QASetCmdTbl MAC
psl ]1
_QASetCmdTbl mac ;_QASetCmdTbl(@cmdtbl)
utool $1F
<<<
~QAGetCmdTbl MAC
pha
pha
_QAGetCmdTbl mac ;_QAGetCmdTbl():@cmdtbl
utool $20
<<<
~QAExecCommand MAC
psw ]1
psw ]2
_QAExecCommand mac ;_QAExecCommand(cmdtype,cmdid)
utool $21
<<<
~QAGetMessagebyID MAC
pha
pha
pha
psw ]1
_QAGetMessagebyID mac ;_QAGetMessagebyID(userid):message,subtype/4
utool $22
<<<
_QARun mac ;_QARun()
utool $23
<<<
_QADispose mac ;_QADispose()
utool $24
<<<
~QAShutdownID MAC
psw ]1
_QAShutdownID mac ;_QAShutDownID(userid)
utool $25
<<<
~QACompile MAC
psw ]1
psl ]2
_QACompile mac ;_QACompile(message,subtype/4)
utool $26
<<<
~QALink MAC
psw ]1
psl ]2
_QALink mac ;_QALink(message,subtype/4)
utool $27
<<<
~QACompilerActive MAC
pha
_QACompilerActive mac ;_QAComplierActive():activeflag
utool $28
<<<
~QALinkerActive MAC
pha
_QALinkerActive mac ;_QALinkerActvie():activeflag
utool $29
<<<
~QAGetCompileID MAC
pha
_QAGetCompileID mac ;_QAGetCompileID():compileID
utool $2A
<<<
~QASetCompileID MAC
psw ]1
_QASetCompileID mac ;_QASetCompileID(compileID)
utool $2B
<<<
~QAGetLinkID MAC
pha
_QAGetLinkID mac ;_QAGetLinkID():linkID
utool $2C
<<<
~QASetLinkID MAC
psw ]1
_QASetLinkID mac ;_QASetLinkID(linkID)
utool $2D
<<<
~QAGetVector MAC
pha
pha
psw ]1
_QAGetVector mac ;_QAGetVector(vect#):@address
utool $2E
<<<
~QASetVector MAC
psw ]1
psl ]2
_QASetVector mac ;_QASetVector(vect#,@address)
utool $2F
<<<
_QAResetVectors mac ;_QAResetVectors()
utool $30
<<<
~QAEvent MAC
psl ]1
psw ]2
_QAEvent mac ;_QAEvent(@eventptr,taskflag)
utool $31
<<<
~QAGetCmdRecSize MAC
pha
_QAGetCmdRecSize mac ;_QAGetCmdRecSize():recordsize
utool $32
<<<
~QATabtoCol MAC
psw ]1
_QATabtoCol mac ;_QATabtoCol(columnnum)
utool $33
<<<
~QAErrorMsg MAC
psw ]1
_QAErrorMsg mac ;_QAErrorMsg(ErrorCode)
utool $34
<<<
~QABarGraph MAC
psw ]1
psl ]2
_QABarGraph mac ;_QABarGraph(percent,@Message)
utool $35
<<<
~QAConvertPath MAC
psl ]1
psl ]2
_QAConvertPath mac ;_QAConvertPath(@oldpath,@newpath)
utool $36
<<<
~QATyp2Txt MAC
psw ]1
psl ]2
_QATyp2Txt mac
_QAConvertTyp2Txt mac ;_QAConvertTyp2Txt(filetype,@typestr)
utool $37
<<<
~QATxt2Typ MAC
pha
psl ]1
_QATxt2Typ mac
_QAConvertTxt2Typ mac ;_QAConvertTxt2Typ(@typestr):type
utool $38
<<<
~QAReadDir MAC
psl ]1
psl ]2
psw ]3
_QAReadDir mac ;_QAReadDir(@pathname,@doroutine,flags)
utool $39
<<<
~QAInitWildcard MAC
psl ]1
psw ]2
psl ]3
psw ]4
psl ]5
_QAInitWildcard mac ;_QAInitWildcard(@wcstr,ft,aux/4,ftmask,auxmask/4)
utool $3A
<<<
_QAUndefined mac ;_QAUndefined()
utool $3B
<<<
_QAInitTotalErrs mac ;_QAInitTotalErrs()
utool $3C
<<<
_QAIncTotalErrs mac ;_QAIncTotalErrs()
utool $3D
<<<
~QAGetTotalErrs MAC
pha
_QAGetTotalErrs mac ;_QAGetTotalErrs():totalerrs
utool $3E
<<<
~QAGetCancelFlag MAC
pha
_QAGetCancelFlag mac ;_QAGetCancelFlag():cancelflag
utool $3F
<<<
~QASetCancelFlag MAC
psw ]1
_QASetCancelFlag mac ;_QASetCancelFlag(cancelflag)
utool $40
<<<
_QAStartTiming mac ;_QAStartTiming()
utool $41
<<<
~QAEndTiming MAC
pha
pha
pha
_QAEndTiming mac ;_QAEndTiming():hours,minutes,seconds
utool $42
<<<
~QAGetSymTable MAC
pha
pha
pha
pha
pha
_QAGetSymTable mac ;_QAGetSymTable():@table,symhandle/4,numlabels
utool $43
<<<
~QASetSymTable MAC
psl ]1
psl ]2
psw ]3
_QASetSymTable mac ;_QASetSymTable(@table,symhandle/4,numlabels)
utool $44
<<<
~QASetPath MAC
psl ]1
_QASetPath mac ;_QASetPath(@pathname)
utool $45
<<<
~QAGetPath MAC
psl ]1
_QAGetPath mac ;_QAGetPath(@pathname)
utool $46
<<<
~QAGetObjType MAC
pha
_QAGetObjType mac ;_QAGetObjType():type
utool $47
<<<
~QASetObjType MAC
psw ]1
_QASetObjType mac ;_QASetObjType(type)
utool $48
<<<
~QAGetObjPath MAC
psl ]1
_QAGetObjPath mac ;_QAGetObjPath(@pathname)
utool $49
<<<
~QASetObjPath MAC
psl ]1
_QASetObjPath mac ;_QASetObjPath(@pathname)
utool $4A
<<<
~QACallUSR MAC
pha
psw ]1
psl ]2
_QACallUSR mac ;_QACallUSR(opcode,@operand):handled
utool $4B
<<<
~QACallUser MAC
psw ]1
psw ]2
psl ]3
psl ]4
_QACallUser mac ;_QACallUser(rngstart,rngend,texthandle/4,textlen/4)
utool $4C
<<<
~QAGoEval MAC
pha
pha
psl ]1
psw ]2
_QAGoEVAL mac ;_QAGoEVAL(@operand,offset):value/4
utool $4D
<<<
~QAGoPutByte MAC
psw ]1
_QAGoPutByte mac ;_QAGoPutByte(byte)
utool $4E
<<<
~QAGoPutOpcode MAC
psw ]1
_QAGoPutOpcode mac ;_QAGoPutOpcode(opcodebyte)
utool $4F
<<<
_QAGoRelcorrect mac ;_QAGoRelcorrect()
utool $50
<<<
~QADrawErrChar MAC
psw ]1
_QADrawErrChar mac ;_QADrawErrChar(char)
utool $51
<<<
~QADrawErrStr MAC
psl ]1
_QADrawErrStr mac
_QADrawErrString mac ;_QADrawErrString(@strptr)
utool $52
<<<
~QAGetWindow MAC
pha
pha
_QAGetWindow mac ;_QAGetWindow():windowtype
utool $53
<<<
~QASetWindow MAC
psl ]1
_QASetWindow mac ;_QASetWindow(windowtype)
utool $54
<<<
~QAGetShellID MAC
pha
_QAGetShellID mac ;_QAGetShellID():userid
utool $55
<<<
~QASetShellID MAC
psw ]1
_QASetShellID mac ;_QASetShellID(userid)
utool $56
<<<
~QAGotoXY MAC
psw ]1
psw ]2
_QAGotoXY mac ;_QAGotoXY(X,Y)
utool $57
<<<
~QAGetXY MAC
pha
pha
_QAGetXY mac ;_QAGetXY():X,Y
utool $58
<<<
~QAPrNibble MAC
psw ]1
_QAPrNibble mac ;_QAPrNibble(nibval)
utool $59
<<<
~QADrawHex MAC
psl ]1
psw ]2
psw ]3
_QADrawHex mac ;_QADrawHex(hexval/4,flags,fieldsize)
utool $5A
<<<
~QADrawCStr mac
~QADrawCString mac
psl ]1
_QADrawCStr mac
_QADrawCString mac
_QADrawBlock mac ;_QADrawBlock(@CBlock)
utool $5B
<<<
~QADrawErrCStr MAC
psl ]1
_QADrawErrCStr mac
_QADrawErrBlock mac ;_QADrawErrBlock(@CBlock)
utool $5C
<<<
~QADrawCharX MAC
psw ]1
psw ]2
_QADrawCharX mac ;_QADrawCharX(char,count)
utool $5D
<<<
~QADrawECharX MAC
psw ]1
psw ]2
_QADrawECharX mac ;_QADrawECharX(char,count)
utool $5E
<<<
~QAGetLaunch MAC
pha
pha
pha
_QAGetLaunch mac ;_QAGetLaunch():@path,flags
utool $5F
<<<
~QASetLaunch MAC
psl ]1
psw ]2
_QASetLaunch mac ;_QASetLaunch(@path,flags)
utool $60
<<<
~QAGetWord MAC
pha
pha
psl ]1
psw ]2
psw ]3
_QAGetWord mac ;_QAGetWord(@Text,Offset,MaxLen):BegOffset,EndOffset
utool $61
<<<
~QADateTime mac
psl ]1
psw ]2
_QADateTime mac ;_QADateTime(@Date,flags)
utool $62
<<<
_QADrawCR mac ;_QADrawCR()
utool $63
<<<
_QADrawSpace mac ;_QADrawSpace()
utool $64
<<<
~QADrawVersion mac
psl ]1
_QADrawVersion mac ;_QADrawVersion(Version/4)
utool $65
<<<
~QADrawBox MAC
pha
pha
psw ]1
psw ]2
psw ]3
psw ]4
_QADrawBox MAC ;_QADrawBox(x,y,width,height):buffhdl
utool $66
<<<
~QAEraseBox MAC
psl ]1
_QAEraseBox MAC ;_QAEraseBox(buffhdl)
utool $67
<<<
~QAConvertStr MAC
pha
psl ]1
psl ]2
psw ]3
_QAConvertStr MAC ;_QAConvertStr(@string/class.1,@buffer/class.1,cmdcode):rtncode
utool $68
<<<
~QADrawStrL MAC
psl ]1
_QADrawStrL MAC ;_QADrawStrL(@string/class.1)
utool $69
<<<
~QADrawErrStrL MAC
psl ]1
_QADrawErrStrL MAC ;_QADrawErrStrL(@strptr/class.1)
utool $6A
<<<
~QAGetKeyAdrs MAC
pha
pha
_QAGetKeyAdrs MAC ;_QAGetKeyAdrs():keyaddress/4
utool $6B
<<<
~QANextLine MAC
pha
pha
psl ]1
psw ]2
psw ]3
_QANextLine mac ;_QANextLine(@Text,Offset,MaxLen):NewLineOffset
utool $6C
<<<
_QAClearKey MAC ;_QAClearKey()
utool $6D
<<<
_QAParseWord MAC ;_QAParseWord(???):???
utool $6E
<<<
utool mac
ldx #]1*256+ToolNum
do userorsys
jsl $E10008
else
jsl $E10000
fin
<<<

243
src/macs/tool.macs.s Normal file
View File

@ -0,0 +1,243 @@
_NEWHANDLE MAC
Tool $902
<<<
_DISPOSEHANDLE MAC
Tool $1002
<<<
_GETHANDLESIZE MAC
Tool $1802
<<<
_SETHANDLESIZE MAC
Tool $1902
<<<
_HLOCK MAC
Tool $2002
<<<
_HUNLOCK MAC
Tool $2202
<<<
^READTIMEHEX MAC
PHS 4
Tool $D03
<<<
^READASCIITIME MAC
PHL ]1
Tool $F03
<<<
^GETNEXTEVENT MAC
PHA
PHWL ]1;]2
Tool $A06
<<<
^SETVECTOR MAC
PHWL ]1;]2
Tool $1003
<<<
^GETVECTOR MAC
P2SW ]1
Tool $1103
<<<
PHWL MAC
PHW ]1
PHL ]2
<<<
P2SW MAC
PHA
PHA
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PSW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PSL mac
if #,]1
pea ^]1
pea ]1
else
if :,]1
lda ]1+2
pha
lda ]1
pha
else
lda ]1+2
pha
lda ]1
pha
fin
fin
eom
PLL mac
if :,]1
pla
sta ]1
pla
sta ]1+2
else
pla
sta ]1
pla
sta ]1+2
fin
eom
TOOL mac
ldx #]1
jsl $E10000
eom
TLL mac
ldx #]1
jsl $E10000
eom
JMI mac
bpl *+5
jmp ]1
eom
JPL mac
bmi *+5
jmp ]1
eom
JNE mac
beq *+5
jmp ]1
eom
JEQ mac
bne *+5
jmp ]1
eom
JGE mac
blt *+5
jmp ]1
eom
JLT mac
bge *+5
jmp ]1
eom
JCS mac
bcc *+5
jmp ]1
eom
JCC mac
bcs *+5
jmp ]1
eom
_QAGotoXY mac
utool $57
eom
_QADRAWSTRING mac
utool $0A
<<<
_QADRAWSTR mac
utool $0A
<<<
_QAPRBYTE mac
utool $0B
<<<
_QAPRBYTEL mac
utool $0C
<<<
_QADRAWDEC mac
utool $0D
<<<
_QAKEYAVAIL mac
utool $0E
<<<
_QAGETCHAR mac
utool $0F
<<<
_QAGETCMDLINE mac
utool $1B
<<<
_QARUN mac
utool $23
<<<
_QADRAWERRCHAR mac
utool $51
<<<
_QADRAWERRSTRING mac
utool $52
<<<
_QADRAWHEX mac
utool $5A
<<<
^QADRAWCSTRING mac
psl ]1
utool $5B
<<<
_QADRAWCHARX mac
utool $5D
<<<
~QAGetWord MAC
pha
pha
psl ]1
psw ]2
utool $61
<<<
_GSOS MAC
do inline
jsl prodos
dw ]1
adrl ]2
else
psl #]2
pea ]1
jsl prodosIL
fin
<<<
UTOOL mac
ldx #]1*256+toolnum
do userorsys
jsl $E10008
else
jsl $E10000
fin
<<<
PHL MAC
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
PHW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PHS MAC
DO ]0
LUP ]1
PHA
--^
ELSE
PHA
FIN
<<<

1382
src/macs/toolmacs.s Normal file

File diff suppressed because it is too large Load Diff

225
src/main.s Normal file
View File

@ -0,0 +1,225 @@
;lst on
*
* main.s
* Merlin32 Test
*
* Created by Lane Roathe on 8/26/19.
* Copyright © 2019 Ideas From the Deep. All rights reserved.
*
exprdp = $A5
expr = $6789
exprL = $123456
//]XCODESTART ; Keep this at the start and put your code after this
lda expr,S
lda (expr,S),Y
lda #expr
lda (expr,X)
lda (expr),y
lda (expr)
lda [exprL],x
lda [exprL]
lda expr,x
lda expr,y
mvp expr,expr1
lda expr
lda expr
ldal expr
jmp expr
jmp (expr)
lda #<exprL
lda #>exprL
lda #^exprL
lda #|exprL
end
*==========================================================
* monitor addresses
TEXT = $FB39 ;Reset text window
TABV = $FB5B ;Complete vtab, using contents of 'A'
MONBELL = $FBE4 ;random bell noise!
HOME = $FC58 ;Clear text window
WAIT = $FCA8 ;delay routine
CROUT = $FD8E ;Print a CR
PRBYTE = $FDDA ;Print 'A' as a hex number
PRHEX = $FDE3 ;as above, but bits 0-3 only
COUT = $FDED ;Monitor char out
MOVE = $FE2C ;memory move routine
INVERSE = $FE80 ;Print in inverse
NORMAL = $FE84 ;Normal print
* Jump Vectors
CONNECT = $3EA ;Connect DOS
DOSWARM = $3D0 ;exit to DOS prompt
RSTVEC = $3F2 ;reset vector
TSTADDR = $1000 ;absolute address for testing
*==========================================================
* Data Index DUM section test
DUM 0
dum0 ds 1 ;fractional byte
dum1 ds 1
dumSize = *
DEND
*==========================================================
* zero page (all zp var names are prefixed with _)
DUM 0
_ptr ds 2
_tmp ds 2
_num1 ds dumSize ;first and second operand values
; test ORG with DUM section
ORG $20
_LFT ds 1 ;Window edge 0..39
DEND
*==========================================================
* Program Entry
;Issue #26 - This should start at the ORG in the linkscript, not at the last ORG in the DUM sections.
START
; PUT current issue here, so it's the first thing assembled.
; The rest below are unit tests to make sure future changes don't break existing code!
; START OF TESTS KNOWN TO HAVE PASSED IN PREVIOUS BUILDS
; --- Test all instructions in all their modes, with as many variants as possible ---
;adc (ZP,x)
adc (0,x)
adc ($80,x)
adc (_tmp,x)
adc (_tmp+0,x)
adc (_tmp+$10,x)
adc ($10+_tmp,x)
adc (_tmp+dum0,x)
adc (_tmp+dum1,x)
adc (_tmp+dum1+1,x)
adc (_tmp+dum0+dum1,x)
adc 0
adc $80
adc _tmp
adc #0
adc #$1111
adc $1111
; --- Other tests that have proven helpful ---
; Tests regarding issues with math and zp,x
sta TSTADDR+dum0
sta TSTADDR+_num1+dum0
sta TSTADDR+_num1+dum0,x
lda _num1+dum0
adc _num1+dum1
sbc _num1+dum1
bit _num1+dum0
sta _num1+dum0 ;(FIXED): can't use sta _num1+dum0
stz _num1+dum0
lda _num1+dum0,x
adc _num1+dum0,x
sbc _num1+dum0,x
bit _num1+dum0,x
sta _num1+dum0,x
stz _num1+dum0,x
lda _num1+dum0,y ;these assemble to abs accesses: lda $00C0,y
adc _num1+dum0,y
sbc _num1+dum0,y
sta _num1+dum0,y
; Label & branching tests
GetKey ldx $C000
bpl GetKey
]loop
dex
bne ]loop
tya
and #1
beq :err
tya
and #1
bne :good
:err
lda #0
:good
bne myQuit
nop
hex 2C ;bit
lda #1
myQuit
jmp DOSWARM
; --- Tests used when addressing issues opened against Merlin32 ---
;Issue #26 (lroathe) - ORG in DUM section is ignored, but can't mess up code ORG
org $2000
lda _LFT
ldx #_LFT
cpx #$20
org ;return to ongoing address
;Issue #16 (fadden) - Byte reference modifiers are ignored (no way to force DP)
lda <$fff0 ;zp
lda >$fff0 ;ABS (lo word)
lda ^$fff0 ;ABS (hi word)
lda |$fff0 ;ABS (long in 65816 mode)
lda <$fff0+24 ;zp
lda >$fff0+24 ;ABS (lo word)
lda ^$fff0+24 ;ABS (hi word)
lda |$fff0+24 ;ABS (long in 65816 mode)
lda #<$fff0+24 ;byte
lda #>$fff0+24 ;page
lda #^$fff0+24 ;bank
lda #<$fff0 ;byte
lda #>$fff0 ;page
lda #^$fff0 ;bank
lda $0008 ;ZP
lda $08 ;ZP
lda $ffff-$fff7 ;ZP
lda $fff0+24 ;ABS (long in 65816 mode)
;Issue #8 fadden) - STX zp,y fails to assemble
org $00bc
L00BC bit L00BC
org
stx $bc,y
ldx L00BC,y
stx L00BC,y
//]XCODEEND ; Keep this at the end and put your code above this

4002
src/merlin_convert.s Normal file

File diff suppressed because it is too large Load Diff

1
src/merlin_orig.s Normal file

File diff suppressed because one or more lines are too long

1
src/obj/qatools Normal file
View File

@ -0,0 +1 @@
Q

7
src/qasystem/login Normal file
View File

@ -0,0 +1,7 @@
*
* This is the login file for Lane's QuickASM system :)
*
set /a/work/zappa
pfx 8 2
pfx 0 2

67
src/qasystem/qacmd Normal file
View File

@ -0,0 +1,67 @@
* QuickASM command table
*
* L = Linker
* C = Compiler/Assembler
* I = Internal Command (leave the ID's alone)
* (you CAN change the command's NAME)
* E = External Command (found in prefix #6)
* A = Shell Application
* Name Type ID# Comment
*-----------------------------------------
QLINKGS *L 1 ;QuickASM Linker
QASMGS *C 1 ;QuickASM 65816/GS Merlin Assembler
QUIT I 1 ;Quit Shell
BYE I 1 ;Same as QUIT
PREFIX I 2 ;Set/Show Prefix
PFX I 2 ;Same as PREFIX
PURGE I 3 ;Purge and compact mem
HELP I 4 ;Show commands
ASM I 5 ;Assemble
ASSEMBLE I 5 ;Assemble
COMPILE I 5 ;Compile(ASM)
LINK I 6 ;Link
SHOW I 7 ;Show Prefixes and mem
STATS I 7 ;Same as SHOW
ASML I 8 ;Assemble and link
CMPL I 8 ;Compile and link
ASMLG I 9 ;Assemble, link and execute
CMPLG I 9 ;Compile, link, and exevute
SET I 10 ;Set Prefixes
POP I 11 ;Pop a prefix level
TOOLMACS I 12 ;Load Built in Macros
= I 13 ;launch/return
- I 14 ;launch/noreturn
RUN I 13 ;same as =
LAUNCH I 14 ;same as -
SHUTDOWN I 15 ;Reboot System
RESTART I 15 ;same as shutdown
ASCII I 16 ;Show ASCII table
ONLINE I 17 ;Show online volumes and devices
*TEST I 18 ;For testing commands under development
*EJECT I 19 ;Ejects all 3.5 disks online
*PARK I 20 ;Parks all HD's online
*UNPARK I 21 ;Restarts all HD's online
*APW I 22 ;boot into apw (not complete)
*MON I 23 ;Enter Monitor
*MONITOR I 23 ;Same as mon..
CATALOG *E 1 ;catalog
CAT *E 1 ;catalog
c *E 1
DUMP *E 2 ;Dump OMF file
TYPE *E 6 ;type a text file to screen
WHERE *E 7 ;show handles
DELLINK *E 10 ;delete all $F8 (LNK) files from directory(nested)
LC *E 11 ;lower case all fnames in directory
DELETE *E 12 ;delete files (supports wildcards)
REZ *E 13 ;Resource Compiler
time *E 14
EDIT *A 8 ;Edit a file

1
src/qasystem/qagraf Normal file
View File

@ -0,0 +1 @@
Z

1
src/qasystem/qaintcmd Normal file
View File

@ -0,0 +1 @@
_

1
src/qasystem/qaprefs Normal file
View File

@ -0,0 +1 @@

32
src/qasystem/qaprefs.s Normal file
View File

@ -0,0 +1,32 @@
lst off
*** LEAVE THIS WORD ALONE *****
setup dw %1000_0000_0000_0000
;b15: 1 = graphics
; 0 = text
**** YOU MAY CHANGE THESE PFX'S ****
prefixtbl
:pfx0 str ''
ds 64-{*-:pfx0}
:pfx1 str '0/'
ds 64-{*-:pfx1}
:pfx2 str '0/Library'
ds 64-{*-:pfx2}
:pfx3 str '/a/work/'
ds 64-{*-:pfx3}
:pfx4 str '/a/Merlin/Macs'
ds 64-{*-:pfx4}
:pfx5 str '9/'
ds 64-{*-:pfx5}
:pfx6 str '9/Utility'
ds 64-{*-:pfx6}
:pfx7 str '9/QASystem/Help.Files'
ds 64-{*-:pfx7}
typ $06
sav qaprefs

1
src/qasystem/qatext Normal file
View File

@ -0,0 +1 @@


1
src/qasystem/qatools Normal file
View File

@ -0,0 +1 @@
|P

1
src/qasystem/qe.prefs Normal file
View File

@ -0,0 +1 @@


5
src/qasystem/quicklink.s Normal file
View File

@ -0,0 +1,5 @@
ovr all
asm ]1
lnk ]2
sav ]3

90
src/shell/equs.s Normal file
View File

@ -0,0 +1,90 @@
*======================================================
* Some equates we need defined
TeaseWare = 0 ;1 = no saving allowed!
AppleMenu = 300
FileMenu = 255
EditMenu = 250
ProjMenu = 400
SrcMenu = 500
ToolMenu = 600
GSOSMenu = 700
TranMenu = 800
WindowMenu = 5000
TECtrlID = $69696969
WindowID = $FACE
CmdWdwID = $AAAA
ErrWdwID = $EEEE
rTEStyle = $8012
*------------------------------------------------------
* These are our zero page usage stuff
dum EndZP
SDFlg ds 2 ;shut down flag
ClickFlg ds 2 ;is there a file to load from finder?
FrontWdw ds 2 ;0 = none of ours active
WdwPtr ds 4 ;current source window
CmdPtr ds 4 ;system window
ErrPtr ds 4 ;error window
TEHdl ds 4 ;for Text Edit record
CmdTEHdl ds 4
ErrTEHdl ds 4
WdwCnt ds 2 ;# of open windows (for menu disable)
SysWdw ds 2 ;NEG = system window
PrtHdl ds 4 ;handle to print record
PPort ds 4 ;printer port handle
PrtOK? ds 2 ;is it ok to print?
WMenuRef ds 2 ;item # for window menu
LastFile ds 2 ;menu # of last file active
CaseFlg ds 2 ;case insensitive = true
FromTop ds 2 ;search from top of doc?
WordFlg ds 2 ;search for words?
LabelFlg ds 2 ;go to a label?
ClearFlg ds 2 ;bne = clear TE text
EnterFlg ds 2 ;bne = parse line via QA tools
SaveText ds 2 ;save as text only?
tFLen ds 2 ;find & replace lengths
tRLen ds 4
textLen ds 4
ToolAdr ds 4 ;address of QATools
CmdAdr ds 4 ;address of command handling code
ParmHdl ds 4 ;parms
CmdHdl ds 4 ;our command table
NumCmds ds 2 ;# of commands we know
err */$101 ;can't go past $FF
dend
*======================================================
* The various routines & variables accessable in the IFD library
* (no drawing or sound or random stuff here!)
EXT SetAPath,SetPath,ReadFile,WriteFile,GetFile,PutFile
EXT StripPath,CopyPath,CopySFPath,CallDOS
EXT SysError,TextError,CenterDialog
EXT WaitEvent,WaitEventz,VErrCheck,AskForDisk
EXT AppPath,PathParms,OpenParms,InfoParms,EOFParms
EXT ReadParms,WriteParms,DestParms,CreateParms
EXT FilePtr,PathPtr,SFTypes,SFRec,InPath
EXT getpath,VolumeName,CreateSFPath,CheckClick
EXT DSysErr,theError,ScreenWidth,TaskRc,Event,EType
EXT Time,yPos,xPos,Mod,TData,TMask
EXT Startup,Shutdown,CreateMBar,SetMenus,SetMItems,NewAlert
EXT SetDIValue,PutText,GrabText,GetInt

458
src/shell/ifd.equs.s Normal file
View File

@ -0,0 +1,458 @@
*======================================================
* Equates needed in order to use the IFD Libraries
* Design and programming by Lane Roath
* Copyright (c) 1989 Lane Roath & Ideas From the Deep
*------------------------------------------------------
yes = 1 ;readability
no = 0
*------------------------------------------------------
* First, define which routines are to be used today...
AllGrfx = no ;drawing, lines, etc
Allio = yes ;use all the disk IO routines
DrawVBL = no ;wait for VBL before draws?
EraseVBL = no ;wait for VBL before erasing?
Shadowing = no ;draw to shadow'd screen?
Border = no ;show drawing speed on border?
* Routines to draw directly to the screen, erased w/BGBuffer
Place = no ;place frame (use appr. rtns!)
FDraw = no ;direct draw (no mask)
MDraw = no ;masked draw
XMDraw = no ;EOR'd masked draw
XDraw = no ;eor'd draw (no mask)
* The following routines require a background buffer
FErase = no ;direct erase
MErase = no ;masked erase
* These erase routines erase ONLY w/color 0... limited use!
BErase = no ;black erase
ZErase = no ;zap frame erase
* Routines to draw to the screen, use an UNDO buffer to erase!
FDrawU = no ;draw w/undo saves
MDrawU = no ;masked draw w/undo saves
XMDrawU = no ;EOR'd masked draw w/undo
XDrawU = no ;EOR'd draw w/undo (no mask)
Undo = no ;undo above draws
* Define which plotting/line drawing routines to use
XLines = no ;straight line drawing XOR'd
Lines = no ;straight line drawing
QDLines = no ;QD style lines
Dots = no ;dot plotting
XBoxes = no ;box drawing routines
QDBoxes = no ;QD Boxes
* Sound playing routines
PlayHdl = no ;pass Handle to sound
PlayPtr = no ;pass Pointer to sound
PlayTbl = no ;use table & pass offset
CustSnd = no ;custom sound stuff?
* Define which disk I/O routines we will be using
ioPath = no ;path setting
ioRead = no ;read from disk
ioWrite = no ;write to disk
ioGet = no ;get file SF dialog (open)
ioPut = no ;put file SF dialog (save)
ioCopyPath = no ;track multiple paths
DocChk = no ;check for doc click
* Miscellaneous routines we have available
SysErr = yes ;system error dialog
TxtErr = yes ;error handler (text io)
WtEvt = yes ;wait event routine
CtrDlg = yes ;center a dialog
Rndm = yes ;random # routines
VErrs = yes ;volume error handler
MemStuff = no ;memory handling routines
MenuStuff = yes ;menu create/handling rtns
SS_Stuff = yes ;startup/shutdown rtns
AlertWin = yes ;Alert Window routine
DlgStuff = yes ;Misc. dialog stuff
UnPacking = no ;SHR unpacking code
*------------------------------------------------------
do Allio.ioRead.ioWrite.ioGet.ioPut.ioCopyPath
AnyIO = yes
else ;make many tests easier!
AnyIO = no
fin
*------------------------------------------------------
do AllGrfx.FDraw.MDraw.XMDraw.FDrawU.MDrawU.XMDrawU.XDraw.XDrawU
Draw = yes
else ;using any drawing routines?
Draw = no
fin
*------------------------------------------------------
do AllGrfx.MErase.FErase.Undo
Erase = yes
else ;using any erase routines?
Erase = no
fin
*------------------------------------------------------
do AllGrfx.XLines.Lines.QDLines.Dots.XBoxes.QDBoxes
Plot = yes
else ;using any plotting routines
Plot = no
fin
*------------------------------------------------------
do Draw.Plot ;all we need to check!
AnyGrfx = yes
else ;make alot of tests much easier!
AnyGrfx = no
fin
*------------------------------------------------------
do PlayHdl.PlayPtr.PlayTbl
AnySound = yes
else ;are we using any sound routines?
AnySound = no
fin
*======================================================
* Define IFD Zero page usage. We don't need much...
dum 0
Ptr ds 4 ;misc
Hdl ds 4 ;misc
ID ds 2 ;user ID's for memory allocation
ID2 ds 2
ID3 ds 2
temp ds 4
temp2 ds 4 ;we use this area for lots of shit!
temp3 ds 4
do AnyGrfx ;--- only used by grfx routines ---
ytemp ds 2 ;drawing temps!
xtemp ds 2
xloc ds 2 ;drawing coords
yloc ds 2
x_size = temp
y_add = temp2
x_loc = temp2+2 ;only used in Setup
ScnPtr = temp3+2
y_loc = ytemp
do Erase.AllGrfx
ErasePtr = * ;only used by ERASE!
fin
FramePtr ds 4 ;pointer to frame bits
MaskPtr ds 4 ;pointer to frame's mask
do Undo.AllGrfx
UndoIdx ds 2 ;length of undo buffer
UndoPtr ds 4 ;pointer to undo buffer
fin
fin
do AnySound ;only needed for sound routines
SoundOff ds 2 ;BFL = play sound, BTR = don't
fin
EndZP = * ;report size of ZP to user
dend
*------------------------------------------------------
* Define the various data definitions we use
dum 0 ;image header definition
I_Type ds 2
I_Frames ds 2
I_YSize ds 2
I_XSize ds 2
I_YHSize ds 2
I_XHSize ds 2
I_Table = * ;start of DA table
dend
dum 0 ;Sound Shop sound file def
HFileID ds 4
HDataOffset ds 4
HVersID ds 4
HDataID ds 4
HLength2 ds 2
HPbRate2 ds 2
HVolume2 ds 2
HEcho2 ds 2
HLength ds 2
HAce ds 2
HPbRate ds 2
HVolume ds 2
HStereo ds 2
HEcho ds 2
HReserved ds 2
HRepeat ds 2
HOffset1 ds 4
HExtra ds 4
HFileName ds 16
SSData = * ;start of digitized 8bit data
dend
*------------------------------------------------------
* Some general equates
ScnWidth = 640 ;width of screen in lines
ScnBytes = 160 ;bytes per scan line
ScnLines = 200 ;scan line count
do Shadowing
ScnBase = $012000 ;NOT always safe to use these!
SCBBase = $019D00
PltBase = $019E00
else
ScnBase = $E12000 ;always safe to use these!
SCBBase = $E19D00
PltBase = $E19E00
fin
SHR_size = $8000 ;size of base SHR screen
ScnSize = SHR_size
VBLReg = $E0C019 ;VBL register
VideoCounters = $E0C02E ;vertical & horizontal (word)
ShadowReg = $E0C035 ;shadowing register
Keyboard = $E0C000 ;read keypresses (BMI = new)
KeyClear = $E0C010 ;clear keypress (set ^ BPL)
KeyIsUp? = KeyClear ;BMI = key down, BPL = key up
OA_Key = $E0C061 ;BMI = pressed (buttons 0 & 1)
SA_Key = $E0C062 ;BMI = Pressed ( of joystick )
yVect = $0003F8 ;CTRL-Y vector in monitor
CR = 'M'&$1F
SPC = ' '
*=====================================================================
* These equates can be used with the GSOS.MACS in the MACRO.LIBRARY
* directory. You can also copy the data structures at the end of this
* file directly into your own source files.
*------------------------------------------------------
* File access - CreateRec, OpenRec access and requestAccess fields
readEnable = %0000001 ;read enable bit:
writeEnable = %0000010 ;write enable bit:
backupNeeded = %0010000 ;backup needed bit:must be '0' in requestAccess field )
renameEnable = %0100000 ;rename enable bit:
destroyEnable = %1000000 ;read enable bit:
* base - > setMark = ...
startPlus = $0000 ;base - setMark = displacement
eofMinus = $0001 ;base - setMark = eof - displacement
markPlus = $0002 ;base - setMark = mark + displacement
markMinus = $0003 ;base - setMark = mark - displacement
* cachePriority
noCache = $0000 ;cachePriority - do not cache blocks invloved in this read
cache = $0001 ;cachePriority - cache blocks invloved in this read if possible
*------------------------------------------------------
* GS/OS Error codes
badSystemCall = $0001 ;bad system call number
invalidPcount = $0004 ;invalid parameter count
gsosActive = $0007 ;GS/OS already active
devNotFound = $0010 ;device not found
invalidDevNum = $0011 ;invalid device number
drvrBadReq = $0020 ;bad request or command
drvrBadCode = $0021 ;bad control or status code
drvrBadParm = $0022 ;bad call parameter
drvrNotOpen = $0023 ;character device not open
drvrPriorOpen = $0024 ;character device already open
irqTableFull = $0025 ;interrupt table full
drvrNoResrc = $0026 ;resources not available
drvrIOError = $0027 ;I/O error
drvrNoDevice = $0028 ;device not connected
drvrBusy = $0029 ;call aborted, driver is busy
drvrWrtProt = $002B ;device is write protected
drvrBadCount = $002C ;invalid byte count
drvrBadBlock = $002D ;invalid block address
drvrDiskSwitch = $002E ;disk has been switched
drvrOffLine = $002F ;device off line/ no media present
badPathSyntax = $0040 ;invalid pathname syntax
invalidRefNum = $0043 ;invalid reference number
pathNotFound = $0044 ;subdirectory does not exist
volNotFound = $0045 ;volume not found
fileNotFound = $0046 ;file not found
dupPathname = $0047 ;create or rename with existing name
volumeFull = $0048 ;volume full error
volDirFull = $0049 ;volume directory full
badFileFormat = $004A ;version error (incompatible file format)
badStoreType = $004B ;unsupported (or incorrect) storage type
eofEncountered = $004C ;end-of-file encountered
outOfRange = $004D ;position out of range
invalidAccess = $004E ;access not allowed
buffTooSmall = $004F ;buffer too small
fileBusy = $0050 ;file is already open
dirError = $0051 ;directory error
unknownVol = $0052 ;unknown volume type
paramRangeErr = $0053 ;parameter out of range
outOfMem = $0054 ;out of memory
dupVolume = $0057 ;duplicate volume name
notBlockDev = $0058 ;not a block device
invalidLevel = $0059 ;specifield level outside legal range
damagedBitMap = $005A ;block number too large
badPathNames = $005B ;invalid pathnames for ChangePath
notSystemFile = $005C ;not an executable file
osUnsupported = $005D ;Operating System not supported
stackOverflow = $005F ;too many applications on stack
dataUnavail = $0060 ;Data unavailable
endOfDir = $0061 ;end of directory has been reached
invalidClass = $0062 ;invalid FST call class
resNotFound = $0063 ;file does not contain required resource
*------------------------------------------------------
* FileSysID's
proDOS = $0001 ;ProDOS/SOS
dos33 = $0002 ;DOS 3.3
dos32 = $0003 ;DOS 3.2
dos31 = $0003 ;DOS 3.1
appleIIPascal = $0004 ;Apple II Pascal
mfs = $0005 ;Macintosh (flat file system)
hfs = $0006 ;Macintosh (hierarchical file system)
lisa = $0007 ;Lisa file system
appleCPM = $0008 ;Apple CP/M
charFST = $0009 ;Character FST
msDOS = $000A ;MS/DOS
highSierra = $000B ;High Sierra
* fileSysID (NEW FOR GSOS 5.0)
ProDOSFSID = $01 ;ProDOS/SOS
dos33FSID = $02 ;DOS 3.3
dos32FSID = $03 ;DOS 3.2
dos31FSID = $03 ;DOS 3.1
appleIIPascalFSID = $04 ;Apple II Pascal
mfsFSID = $05 ;Macintosh (flat file system)
hfsFSID = $06 ;Macintosh (hierarchical file system)
lisaFSID = $07 ;Lisa file system
appleCPMFSID = $08 ;Apple CP/M
charFSTFSID = $09 ;Character FST
msDOSFSID = $0A ;MS/DOS
highSierraFSID = $0B ;High Sierra
ISO9660FSID = $0C ;ISO 9660
AppleShare = $0D ;AppleShare
* FSTInfo.attributes
characterFST = $4000 ;character FST
ucFST = $8000 ;SCM should upper case pathnames before
; passing them to the FST
* QuitRec.flags
onStack = $8000 ;place state information about quitting
; program on the quit return stack
restartable = $4000 ;the quitting program is capable of being
; restarted from its dormant memory
* StorageType
seedling = $0001 ;standard file with seedling structure
standardFile = $01 ;standard file type (no resource fork)
sapling = $0002 ;standard file with sapling structure
tree = $0003 ;standard file with tree structure
pascalRegion = $0004 ;UCSD Pascal region on a partitioned disk
extendedFile = $0005 ;extended file type (with resource fork)
directoryFile = $000D ;volume directory or subdirectory file
* version
minorRelNum = $00FF ;version - minor release number
majorRelNum = $7F00 ;version - major release number
finalRel = $8000 ;version - final release
isFileExtended = $8000
*------------------------------------------------------
* GSOS Call ID numbers
* Set 'Class1' to $2000 to use Class 1 calls, $0000 for Class 0 calls
*Class1 = $2000
prodos = $E100A8
_Create = $0001.Class1
_Destroy = $0002.Class1
_OSShutdown = $2003 ;class '1' only
_ChangePath = $0004.Class1
_SetFileInfo = $0005.Class1
_GetFileInfo = $0006.Class1
_Volume = $0008.Class1
_SetPrefix = $0009.Class1
_GetPrefix = $000A.Class1
_ClearBackup = $000B.Class1
_SetSysPrefs = $200C ;class '1' only
_Null = $200D ;class '1' only
_ExpandPath = $200E ;class '1' only
_GetSysPrefs = $200F ;class '1' only
_Open = $0010.Class1
_Newline = $0011.Class1
_Read = $0012.Class1
_Write = $0013.Class1
_Close = $0014.Class1
_Flush = $0015.Class1
_SetMark = $0016.Class1
_GetMark = $0017.Class1
_SetEOF = $0018.Class1
_GetEOF = $0019.Class1
_SetLevel = $001A.Class1
_GetLevel = $001B.Class1
_GetDirEntry = $001C.Class1
_BeginSession = $201D ;class '1' only
_EndSession = $201E ;class '1' only
_SessionStatus = $201F ;class '1' only
_GetDevNumber = $0020.Class1
_GetLastDev = $0021.Class1
_ReadBlock = $0022 ;class '0' only
_WriteBlock = $0023 ;class '0' only
_Format = $0024.Class1
_EraseDisk = $0025.Class1
_ResetCache = $2026 ;class '1' only
_GetName = $0027.Class1
_GetBootVol = $0028.Class1
_Quit = $0029.Class1
_GetVersion = $002A.Class1
_GetFSTInfo = $202B ;class '1' only
_DInfo = $002C.Class1
_DStatus = $202D ;class '1' only
_DControl = $202E ;class '1' only
_DRead = $202F ;class '1' only
_DWrite = $2030 ;class '1' only
_AllocInterrupt = $0031 ;P16 call
_BindInt = $2031 ;GS/OS call
_DeallocInterrupt = $0032 ;P16 call
_UnbindInt = $2032 'GS/OS call
_AddNotifyProc = $2034 ;class '1' only
_DelNotifyProc = $2035 ;class '1' only
_DRename = $2036 ;class '1' only
_GetStdRefNum = $2037 ;class '1' only
_GetRefNum = $2038 ;class '1' only
_GetRefInfo = $2039 ;class '1' only
fin ;--- disk IO equates ---

34
src/shell/ifd.lib.s Normal file
View File

@ -0,0 +1,34 @@
lst off
tr on
exp off
mx %00
cas se
rel ;creating a LNK library
*======================================================
* Control file needed in order to assemble the IFD Libraries
* Design and programming by Lane Roath
* Copyright (c) 1989 Lane Roath & Ideas From the Deep
*------------------------------------------------------
* 25-Oct-89 1.00 :finish first version & text it out
*======================================================
Class1 = $2000
use ifd.equs
use 3/ifdlib/macs
EXT QuickASM
jmp QuickASM
ENT ON
put 3/ifdlib/disk
put 3/ifdlib/draw
put 3/ifdlib/misc
ENT OFF
sav 2/obj/ifd.lib

35
src/shell/link.s Normal file
View File

@ -0,0 +1,35 @@
*======================================================
* Link file for the IFD TEdit word processor
* Written by Lane Roath
* Copyright (c) 1989 Ideas from the Deep
*======================================================
lkv $01 ;xtra linker, OMF 2
ver $02
FAS
if equs
asm qasm2
asm qasm1
asm qasm
fin
do err
else
CMD p,s,q
lnk 2/obj/ifd.lib
lnk 2/obj/qasm2.l
lnk 2/obj/qasm1.l
lnk 2/obj/qasm.l
ds 1024 ;buffer space
typ S16
sav 2/QASM
fin

953
src/shell/macs.s Normal file
View File

@ -0,0 +1,953 @@
utool mac
ldx #]1*256+ToolNum
do userorsys
jsl $E10008
else
jsl $E10000
fin
<<<
_QASetShellID mac
utool $56
<<<
_QARun mac
utool $23
<<<
_QAStatus mac
utool $06
<<<
~QAGetQuitFlag mac ;_QAGetQuitFlag():quitflag
pha
utool $1D
<<<
~QASetQuitFlag mac ;_QASetQuitFlag(quitflag)
psw ]1
utool $1E
<<<
~QASetLaunch MAC
psl ]1
psw ]2
_QASetLaunch mac ;_QASetLaunch(@path,flags)
utool $60
<<<
~QAGetLaunch MAC
pha
pha
pha
_QAGetLaunch mac
utool $5F
<<<
~QASetVector MAC
psw ]1
psl ]2
utool $2F
<<<
_QAResetVectors mac ;_QAResetVectors()
utool $30
<<<
~QASetCancelFlag MAC
psw ]1
utool $40
<<<
~QACompile MAC
psw ]1
psl ]2
utool $26
<<<
~QALink MAC
psw ]1
psl ]2
utool $27
<<<
~QAParseCmdLine MAC
pha
pha
psl ]1
utool $1C
<<<
_QAExecCommand mac
utool $21
<<<
~GetScrapHandle MAC
P2SW ]1
Tool $E16
<<<
~TEScroll MAC
PHW ]1
PxL ]2;]3;]4
Tool $2522
<<<
~TEPointToOffset MAC
PHS 2
PxL ]1;]2;]3
Tool $2122
<<<
~TEKey MAC
PxL ]1;]2
Tool $1422
<<<
~TEClear MAC
PHL ]1
Tool $1922
<<<
_WaitCursor MAC
Tool $A12
<<<
_InitCursor MAC
Tool $CA04
<<<
~MessageCenter MAC
PxW ]1;]2
PHL ]3
Tool $1501
<<<
~NewHandle MAC
P2SL ]1
PxW ]2;]3
PHL ]4
Tool $902
<<<
~HiliteMenu MAC
PxW ]1;]2
Tool $2C0F
<<<
~TaskMaster MAC
PHA
PHWL ]1;]2
Tool $1D0E
<<<
~FrontWindow MAC
PHS 2
Tool $150E
<<<
~CloseWindow MAC
PHL ]1
Tool $B0E
<<<
_CloseAllNDAs MAC
Tool $1D05
<<<
~DrawControls MAC
PHL ]1
Tool $1010
<<<
~NewControl2 MAC
P2SL ]1
PHWL ]2;]3
Tool $3110
<<<
~NewWindow MAC
P2SL ]1
Tool $90E
<<<
~SendBehind MAC
PxL ]1;]2
Tool $140E
<<<
~Alert MAC
PHA
PxL ]1;]2
Tool $1715
<<<
~FMGetCurFID MAC
PHS 2
Tool $1A1B
<<<
~ChooseFont MAC
P2SL ]1
PHW ]2
Tool $161B
<<<
~ItemID2FamNum MAC
P1SW ]1
Tool $171B
<<<
~TESetSelection MAC
PxL ]1;]2;]3
Tool $1D22
<<<
~DisposeHandle MAC
PHL ]1
_DisposeHandle MAC
Tool $1002
<<<
~TEInsert MAC
PHWL ]1;]2
PHLW ]3;]4
PxL ]5;]6
Tool $1A22
<<<
~TEGetSelStyle MAC
PHA
PxL ]1;]2;]3
Tool $1E22
<<<
~TEStyleChange MAC
PHW ]1
PxL ]2;]3
Tool $1F22
<<<
~TESetText MAC
PHWL ]1;]2
PHLW ]3;]4
PxL ]5;]6
Tool $B22
<<<
~TEGetText MAC
PHS 2
PHWL ]1;]2
PHLW ]3;]4
PxL ]5;]6
Tool $C22
<<<
~TEGetSelection MAC
PxL ]1;]2;]3
Tool $1C22
<<<
~TEReplace MAC
PHWL ]1;]2
PHLW ]3;]4
PxL ]5;]6
Tool $1B22
<<<
~AlertWindow MAC
P1SW ]1
PxL ]2;]3
Tool $590E
<<<
~ZoomWindow MAC
PHL ]1
Tool $270E
<<<
~TEUpdate MAC
PHL ]1
Tool $1222
<<<
~PrSetDocName MAC
PHL ]1
Tool $3713
<<<
_PrDefault MAC
Tool $0913
<<<
~PrValidate MAC
P1SL ]1
Tool $0A13
<<<
~PrJobDialog MAC
P1SL ]1
Tool $0C13
<<<
~PrOpenDoc MAC
P2SL ]1
PHL ]2
Tool $0E13
<<<
~PrCloseDoc MAC
PHL ]1
Tool $0F13
<<<
~PrOpenPage MAC
PxL ]1;]2
Tool $1013
<<<
~PrClosePage MAC
PHL ]1
Tool $1113
<<<
~PrPicFile MAC
PxL ]1;]2;]3
Tool $1213
<<<
~PrSetError MAC
PHW ]1
_PrSetError MAC
Tool $1513
<<<
~GetPortRect MAC
PHL ]1
Tool $2004
<<<
~TEPaintText MAC
P2SL ]1
PxL ]2;]3
PHWL ]4;]5
Tool $1322
<<<
~PrStlDialog MAC
P1SL ]1
Tool $0B13
<<<
~SetWRefCon MAC
PxL ]1;]2
Tool $280E
<<<
~GetWRefCon MAC
P2SL ]1
Tool $290E
<<<
~SetWTitle MAC
PxL ]1;]2
Tool $D0E
<<<
~GetWTitle MAC
P2SL ]1
Tool $E0E
<<<
~SetInfoRefCon MAC
PxL ]1;]2
Tool $360E
<<<
~GetCtlHandleFromID MAC
PHS 2
PxL ]1;]2
Tool $3010
<<<
~GetInfoRefCon MAC
P2SL ]1
Tool $350E
<<<
~CloseDialog MAC
PHL ]1
Tool $C15
<<<
~ModalDialog MAC
P1SL ]1
Tool $F15
<<<
~GetIText MAC
PHL ]1
PHWL ]2;]3
_GetIText MAC
Tool $1F15
<<<
~SetIText MAC
PHL ]1
PHWL ]2;]3
_SetIText MAC
Tool $2015
<<<
~GetNewModalDialog MAC
P2SL ]1
Tool $3215
<<<
~ShowHide MAC
PHWL ]1;]2
_ShowHide MAC
Tool $230E
<<<
~ShowWindow MAC
PHL ]1
Tool $130E
<<<
~SelectIText MAC
PHL ]1
PxW ]2;]3;]4
Tool $2115
<<<
~GetDItemValue MAC
PHA
PHLW ]1;]2
Tool $2E15
<<<
~SetDItemValue MAC
PHW ]1
PHLW ]2;]3
_SetDItemValue MAC
Tool $2F15
<<<
~SetFontFlags MAC
PHW ]1
Tool $9804
<<<
~SetPort MAC
PHL ]1
Tool $1B04
<<<
~InsertMItem MAC
PHL ]1
PxW ]2;]3
Tool $F0F
<<<
_DeleteMItem MAC
Tool $100F
<<<
~CalcMenuSize MAC
PxW ]1;]2;]3
Tool $1C0F
<<<
~CheckMItem MAC
PxW ]1;]2
Tool $320F
<<<
~SetMItemName MAC
PHLW ]1;]2
Tool $3A0F
<<<
~SelectWindow MAC
PHL ]1
_SelectWindow MAC
Tool $110E
<<<
~GetWKind MAC
P1SL ]1
Tool $2B0E
<<<
~GetNextWindow MAC
P2SL ]1
Tool $2A0E
<<<
~GetFirstWindow MAC
PHS 2
Tool $520E
<<<
~MoveWindow MAC
PxW ]1;]2
PHL ]3
Tool $190E
<<<
~SizeWindow MAC
PxW ]1;]2
PHL ]3
Tool $1C0E
<<<
~NotifyCtls MAC
PxW ]1;]2
PxL ]3;]4
Tool $2D10
<<<
~SetPortLoc MAC
PHL ]1
Tool $1D04
<<<
~GetPortLoc MAC
PHL ]1
Tool $1E04
<<<
~Dec2Int MAC
P1SL ]1
PxW ]2;]3
_Dec2Int MAC
Tool $280B
<<<
~Int2Dec MAC
PHWL ]1;]2
PxW ]3;]4
Tool $260B
<<<
~Long2Dec MAC
PxL ]1;]2
PxW ]3;]4
Tool $270B
<<<
~TECopy MAC
PHL ]1
Tool $1722
<<<
~TEGetRuler MAC
PHWL ]1;]2
PHL ]3
Tool $2322
<<<
~TESetRuler MAC
PHW ]1
PxL ]2;]3
Tool $2422
<<<
~ReadFile MAC
lda ]1
ldy ]2
jsr ReadFile
<<<
~WriteFile MAC
do ]0/3
lda ]3
sta CreateParms+8
fin
ldy ]1
lax ]2
jsr WriteFile
<<<
~GetFile MAC
lda ]1
ldx ]2
ldy ]3
_GetFile MAC
jsr GetFile
<<<
~PutFile MAC
lda ]1
ldx ]2
jsr PutFile
<<<
~PutText MAC
ldx ]1
lda ]2
_PutText MAC
jsr PutText
<<<
~GrabText MAC
ldx ]1
lda ]2
_GrabText MAC
jsr GrabText
<<<
~GetInt MAC
ldx ]1
_GetInt MAC
jsr GetInt
<<<
~TEGetLastError MAC
PHA
PHWL ]1;]2
Tool $2722
<<<
~InvalCtls MAC
PHL ]1
Tool $3710
<<<
_CreateSFPath MAC
jsr CreateSFPath
<<<
_GSOS MAC
do inline
jsl prodos
dw ]1
adrl ]2
else
psl #]2
pea ]1
jsl prodosIL
fin
<<<
~SysError MAC
ldx ]1
do ]0/2
lda ]2
fin
jsr SysError
<<<
~CenterDialog MAC
lda ]1
jsr CenterDialog
<<<
~Startup MAC
ldx ]1
ldy ]2
lda ]3
jsr Startup
<<<
_Shutdown MAC
jsr Shutdown
<<<
~CreateMBar MAC
lda ]1
ldx ]2
ldy ]3
jsr CreateMBar
<<<
_SetMenus MAC
jsr SetMenus
<<<
_SetMItems MAC
jsr SetMItems
<<<
~FreeMem MAC
PHS 2
Tool $1B02
<<<
~MaxBlock MAC
PHS 2
Tool $1C02
<<<
~TotalMem MAC
PHS 2
Tool $1D02
<<<
~RealFreeMem MAC
PHS 2
Tool $2F02
<<<
~TEGetTextInfo MAC
PHLW ]1;]2
PHL ]3
Tool $D22
<<<
~CheckClick MAC
lda #]1
jsr CheckClick
<<<
~NewAlert MAC
lda #]1
jsr NewAlert
<<<
~CreateResourceFile MAC
PHLW ]1;]2
PHWL ]3;]4
Tool $91E
<<<
~OpenResourceFile MAC
P1SW ]1
PxL ]2;]3
Tool $A1E
<<<
_CloseResourceFile MAC
Tool $B1E
<<<
~AddResource MAC
PHLW ]1;]2
PHWL ]3;]4
Tool $C1E
<<<
~LoadResource MAC
P2SW ]1
PHL ]2
Tool $E1E
<<<
~DetatchResource MAC
PHWL ]1;]2
Tool $181E
<<<
~RemoveResource MAC
PHWL ]1;]2
Tool $F1E
<<<
~HLock MAC
PHL ]1
Tool $2002
<<<
~HUnlock MAC
PHL ]1
Tool $2202
<<<
~GetHandleSize MAC
P2SL ]1
Tool $1802
<<<
~HandToHand MAC
PxL ]1;]2;]3
Tool $2A02
<<<
~InitialLoad MAC
PHS 5
PHWL ]1;]2
PHW ]3
Tool $911
<<<
~SetTSPtr MAC
PxW ]1;]2
PHL ]3
Tool $A01
<<<
_SetHandleSize MAC
Tool $1902
<<<
_QABootInit mac
utool $01
<<<
_QAStartup mac
utool $02
<<<
_QAGetLine mac
utool $10
<<<
~QASetParmHdl MAC
psl ]1
utool $11
<<<
~QASetCmdHdl MAC
psl ]1
psw ]2
utool $13
<<<
~QASetCmdTbl MAC
psl ]1
utool $1F
<<<
~QAGetCompileID MAC
pha
utool $2A
<<<
~QASetCompileID MAC
psw ]1
utool $2B
<<<
~QAGetLinkID MAC
pha
utool $2C
<<<
~QASetLinkID MAC
psw ]1
utool $2D
<<<
_QAGetCmdRecSize mac
utool $32
<<<
~QAGetWord MAC
pha
pha
psl ]1
psw ]2
psw ]3
utool $61
<<<
~QANextLine MAC
pha
psl ]1
psw ]2
psw ]3
utool $6C
<<<
~QADrawStr MAC
psl ]1
utool $0A
<<<
_QAShutdown mac
utool $03
<<<
_QADispose mac
utool $24
<<<
_QADrawBlock mac
utool $5B
<<<
~QADrawVersion mac
psl ]1
utool $65
<<<
_QAPrByteL mac
utool $0C
<<<
_QADrawCR mac
utool $63
<<<
_GrafOn MAC
Tool $A04
<<<
_GrafOff MAC
Tool $B04
<<<
_QAClearKey MAC
utool $6D
<<<
P2SW MAC
PHA
PHA
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
CmpLong MAC
LDA ]1
CMP ]2
IF #=]1
LDA ^]1
ELSE
LDA ]1+2
FIN
IF #=]2
SBC ^]2
ELSE
SBC ]2+2
FIN
<<<
Hdl_Ptr MAC
lda []1]
sta ]2
ldy #2
lda []1],y
sta ]2+2
<<<
bfl mac
beq ]1
<<<
btr mac
bne ]1
<<<
lax mac
lda ]1
if #,]1
ldx ^]1
else
ldx ]1+2
fin
<<<
sax MAC
sta ]1
stx ]1+2
<<<
P1SL MAC
PHA
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
MoveLong MAC
MoveWord ]1;]2
MoveWord ]1+2;]2+2
<<<
MoveWord MAC
LDA ]1
STA ]2
IF MX/2
LDA ]1+1
STA ]2+1
FIN
<<<
PHLW MAC
PHL ]1
PHW ]2
<<<
P1SW MAC
PHA
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PxL MAC
DO ]0/1
PHL ]1
DO ]0/2
PHL ]2
DO ]0/3
PHL ]3
DO ]0/4
PHL ]4
FIN
FIN
FIN
FIN
<<<
PHWL MAC
PHW ]1
PHL ]2
<<<
PHS MAC
DO ]0
LUP ]1
PHA
--^
ELSE
PHA
FIN
<<<
psw MAC
PushWord MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PxW MAC
DO ]0/1
PHW ]1
DO ]0/2
PHW ]2
DO ]0/3
PHW ]3
DO ]0/4
PHW ]4
FIN
FIN
FIN
FIN
<<<
P2SL MAC
PHA
PHA
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
psl mac
PHL MAC
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
PHW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PullLong MAC
DO ]0
PullWord ]1
PullWord ]1+2
ELSE
PullWord
PullWord
FIN
<<<
PullWord MAC
PLx
DO ]0
STx ]1
FIN
IF MX/2
PLx
DO ]0
STx ]1+1
FIN
FIN
<<<
LONGAX MAC
IF MX
REP %00110000
FIN
<<<
SHORTAX MAC
IF MX!%11
SEP %00110000
FIN
<<<
LONGM MAC
IF MX&2
REP %00100000
FIN
<<<
SHORTM MAC
IF MX&2
ELSE
SEP %00100000
FIN
<<<
Tool MAC
LDX #]1
JSL $E10000
<<<

1649
src/shell/qasm.s Normal file

File diff suppressed because it is too large Load Diff

1774
src/shell/qasm1.s Normal file

File diff suppressed because it is too large Load Diff

920
src/shell/qasm2.s Normal file
View File

@ -0,0 +1,920 @@
lst off
ttl "QASM text routines"
exp off
tr on
cas se
* dup
*======================================================
* Graphic Shell for QuickASM development system
* Programming by Lane Roath
* Copyright (c) 1990 Ideas From the Deep & Lane Roath
*------------------------------------------------------
* 26-Feb-90 0.10 :start working on text windows
*======================================================
rel
Class1 = $2000
lst off
use 2/data/qa.equates
use macs
use ifd.equs
use equs
lst rtn
EXT TextName,TextPath,GetTEInfo,FindNext,selStart,selEnd
EXT SetSelection,QuitPath,GetSelText,SetText,tFind,myDP
EXT HEdit,PrintBuf,CmdLine,TempBuf,SetStyle,SetRuler
*======================================================
* We redirect all text i/o to these routines
pt2c ENT
phb
phk ;need our bank
plb
SEP #$30
sta CmdLine ;save col #
lda #$20
ldx PrintBuf ;get current length
]loop
inx ;next char
beq :done
sta PrintBuf,x ; is a space
stx PrintBuf
cpx CmdLine
blt ]loop ;until reached column
:done
REP #$30
plb ;restore bank & exit
rtl
*------------------------------------------------------
pchr ENT ;print a character
clc
hex 24
pechr ENT ;error entry
sec
phb
phk ;need our bank
plb
phd
pha
lda myDP ;need our DP
tcd
pla
sta CmdLine
stz CmdLine+1 ;fake CString
lax #CmdLine
bra pblkz
*------------------------------------------------------
pblk ENT ;print a CString
clc
hex 24
peblk ENT ;error entry
sec
phb
phk ;need our bank
plb
phd
pha
lda myDP ;need our DP
tcd
pla
pblkz
sax Ptr ;point to CString
SEP #$30
ldy #0
]loop
lda [Ptr],y
beq :end ; & get it's length
iny
bne ]loop
dey ;backup!
:end
REP #$30
bra pstr2
*------------------------------------------------------
pstr ENT ;print a PString
clc
hex 24
pestr ENT ;error entry
sec
phb
phk ;need our bank
plb
phd
pha
lda myDP ;need our DP
tcd
pla
sax Ptr ;point to string
lda [Ptr]
and #$FF ;get length
tay
inc Ptr ; & skip length byte
pstr2
sty temp2 ;don't over use DP!
lda #0
ror ;place carry in BMI bit
cmp WhichWdw
beq :same ;same as last call?
pha
jsr AddText ; no- add text to prev. window
pla
:same
sta WhichWdw ;save which window we are going to
SEP #$30 ;8 bit code follows
ldy #0 ;get indexes
:loop
ldx PrintBuf
]loop
inx ;buffer overflow?
bne :ok
phy
jsr AddText ; yes- add current text
ply
bra :loop ; & restart fill
:ok
stx PrintBuf
lda [Ptr],y ;copy a char
and #$7F
cmp #' ' ;control char?
blt :ctrl ; yes- special
:char
sta PrintBuf,x ; no- just store char
:nochar
iny
cpy temp2 ;are we done?
blt ]loop
cmp #13 ; yes- last char a CR?
bne :xit
jsr AddText ; yes- add text
:xit
REP #$30
pld
plb ;restore dp,bank & exit
rtl
*------------------------------------------------------
mx %11
:ctrl
cmp #13 ;CR?
beq :char
dex
cmp #'U'&$1F ;multi char?
bne :nochar
inx
iny
lda [Ptr],y ; yes, get count
sta temp2+2
iny
lda [Ptr],y ; get char to repeat
and #$7F
]loop
stx PrintBuf
sta PrintBuf,x ;place a char
inx
bne :ok1 ;buffer overflow?
phy
pha
jsr AddText ; yes- add current text
pla
ply
ldx #1 ; & reinit index
:ok1
dec temp2+2 ;done?
bne ]loop
dex
bra :nochar ; yes- back to loop
mx %00
*------------------------------------------------------
* Add the text to the TE record of user's choice
AddText
php ;must be in 16bit mode!
SEP #$30
lda PrintBuf ;anything to print?
beq :xit
REP #$30
lda WhichWdw ; yes, to which window?
bmi :1
lax CmdTEHdl ; Command window
bra :2
:1
lax ErrTEHdl ; Error window
:2
sax QuitPath ;save TE record
~TEInsert #0;#PrintBuf;PrintBuf;#0;#0;QuitPath ; & insert in wdw
stz PrintBuf
:xit
plp
rts
WhichWdw dw 0 ;assume command
*======================================================
* Install our keypress checker into the TE record
mx %00
InstallKey ENT
lda #%1100010 ; no, update TE record
jsr SetStyle
lda #-2
ldy #8 ;adjust line spacing
jsr SetRuler
Hdl_Ptr TEHdl;Ptr ;point to command window TE record
ldy #$C8
lda #KeyFilter
sta [Ptr],y
iny
iny ;install our key filter
lda #^KeyFilter
sta [Ptr],y
rts
*======================================================
* Check for ENTER or CLEAR keypresses on keypad
* Just sets some flags, actual work done by main program!
KeyFilter
dum 4
]rtl ds 3 ;these are passed on stack
]type ds 2
]handle ds 4
]newstack = *-3 ;must be at end of passed params
dend
phd ;save DP, bank
phb
phk
plb
lda myDP ; & use ours
tcd
lda ]handle+2,s
sta Hdl+2 ;get TE handle
lda ]handle,s
sta Hdl ; & dereference for use
Hdl_Ptr Hdl;Ptr
lda ]type,s ;check for type 1
dec
bne :xit
ldy #$D8+2
lda [Ptr],y ;keypad ?
and #$2000
beq :xit ; no- exit
dey
dey
lda [Ptr],y
and #$7F ;get keypress
cmp #'X'&$1F
bne :enterchk ;CLEAR?
dec ClearFlg
bra :wedo ; yes- tell program
:enterchk
cmp #13 ;ENTER?
bne :xit
dec EnterFlg ; yes- inform program
:wedo
lda #2 ;TE... don't handle this press!
bra :xit2
:xit
lda #0 ;TE... do normal processing
:xit2
ldy #$D8+$C
sta [Ptr],y ;tell TE what to do
lda ]rtl,s
sta ]newstack,s
SEP #$30 ;remove parms
lda ]rtl+2,s
sta ]newstack+2,s
REP #$30
plb ;restore DP, bank
pld
tsc
clc
adc #]newstack-4 ;adjust stack
tcs
rtl
*======================================================
* User pressed CLEAR on the keypad, clear TE text
DoClear ENT
stz ClearFlg
lda #20 ;select entire document
jsr HEdit
~TEClear #0 ; & clear it
rts
*======================================================
* User pressed ENTER on keypad, parse QA commands
DoEnter ENT
stz EnterFlg ;we're doing it!
ldx #'H'&$1F
lda #$800 ;move to beginning of line
jsr :dokey
ldx #'U'&$1F
lda #$A00 ;select to end of line
jsr :dokey
~TECopy #0 ;copy to clipboard
bcs :err
~GetScrapHandle #0 ;get handle to copied text
PullLong Hdl
bcs :err
~HLock Hdl ;lock it down
Hdl_Ptr Hdl;Ptr
~GetHandleSize Hdl ;get size
ply
plx
bcs :err
SEP #$30
sty CmdLine ;set length
]loop dey
bmi :xit ;don't do NULL string
lda [Ptr],y
iny ;copy text to PString
sta CmdLine,y
dey
bne ]loop
REP #$30
~QAParseCmdLine #CmdLine ;let QA parse the command
plx
ply
bcc :doit ;ok?
:err
~SysError #sntx
:xit
REP #$30
rts
:doit
phx ; yes- try to run it!
phy
ldx #'U'&$1F ;move to end of line
lda #0
jsr :dokey
ldx #13 ; & insert a CR
jsr :dokey2
_QAClearKey
_QAExecCommand ;let QA do it's thing
bcs :err
rts
*------------------------------------------------------
:dokey
sta TaskRc+14
:dokey2
stx TaskRc+2 ;set keypress
lda #3 ;show keydown event
sta TaskRc
~TEKey #TaskRc;TEHdl ; & have TE do it
rts
sntx str 'Command not found!'
*======================================================
* This is the text mode handler, so we can switch back
* and forth between it and graphics quickly!!!
doTextMode ENT
_GrafOff ;back to text!
_QAResetVectors
_QAClearKey ; (w/no pending keypress!)
bra :cr
]loop
~QAGetQuitFlag
pla
bne :end ;time to quit?
_QARun
jsr GetLine ; no- get user input
bcc :cr
~QAParseCmdLine #CmdLine ;let QA parse the command
plx
ply
bcs :err ;able to parse?
phx
phy
_QAClearKey
_QAExecCommand ;let QA do it's thing
bcc ]loop
:err
pha
~QADrawStr #sntx ;show error msg
_QAPrByteL
:cr
_QADrawCR
bra ]loop
:end
_GrafOn ;back to graphics!
*======================================================
* Force printing in QuickASM to be placed in TEdit window
GrafVectors ENT
~QASetVector #1;#pchr
~QASetVector #2;#pstr ;set vectors for text output
~QASetVector #5;#pblk
~QASetVector #3;#pechr
~QASetVector #4;#pestr ;set error vectors for text output
~QASetVector #6;#peblk
~QASetVector #14;#pt2c
rts
*======================================================
* Use the QA tools to get some input in the text mode
GetLine
stz CmdLine ;force nothing in buffer
pea 0 ;room for returned stuff
pea 0
pea 0
psl #CmdLine ;pointer to my buffer
psl #:prompt ;my prompt string
lda :prompt ;calculate maximum length
and #$ff ;from prompt length
sec
sbc #79
eor #$FFFF
inc
pha
pea 0 ;start at first position
lda #"_" ;insert cursor
ora #' '*256 ;overstrike is high byte
pha
lda :cursor ;current cursor
and #$FF
ora #" "*256 ;"fill" character
pha
psl #:abortptr ;keys to abort on (besides ESC and CR)
_QAGetLine
pla
and #$FF
sta :cursor ;save user's cursor pref
pla ;pull off last position
pla ;pull last key press
and #$7f
cmp #$1b ;ESC?
bne :noesc
_GrafOn ; yes-
pla
brl GrafVectors ; exit back to graphics!
:noesc
lda CmdLine
and #$ff
beq :clc ;empty line?
tay
lda CmdLine,y
and #$7F
cmp #$0D ;look for end of input
beq :sec
inc CmdLine
lda #$0D
sta CmdLine+1,y ; insure CR at end
:sec
_QADrawCR
sec
rts
:clc
lda #$0D01
sta CmdLine
clc
rts
:cursor dw ' ' ;start with overstrike
:prompt str 'CMD:'
:abortptr dw 0 ;no keys abort
mx %00
*======================================================
* Load the QATools and QACommand table files
LoadQAStuff ENT
~InitialLoad ID2;#ToolName;#-1 ;load our special tools
plx
PullLong ToolAdr ;ignore ID, save address
plx
plx ;ignore DP/stack information
bcs :ggg
~SetTSPtr #ToolType;#ToolNum;ToolAdr ;setup in tool table
bcs :ggg
_QABootInit ;initialize the toolset
bcs :ggg
~InitialLoad ID2;#CmdName;#-1 ;load commands
plx
PullLong CmdAdr ;ignore ID, save pointer to cmd code
plx
plx ;ignore DP/stack info
bcs :ggg
~ReadFile #ParmName;#$8000 ;read parameter file
bcs :ggg
sax ParmHdl
Hdl_Ptr ParmHdl;Ptr ;deref parms
pei ID
pea #0
lda [Ptr]
and #$8000 ;text or graphics?
pha
_QAStartup ;start up tools
:ggg bcs :gxit
jsr SetCmdHdl ;read command table
bcs :gxit
~QASetCmdHdl CmdHdl;NumCmds ;let QA know abut stuff
~QASetParmHdl ParmHdl
~QASetCmdTbl CmdAdr
~ReadFile #LoginName;#0 ;read parameter file
:gxit bcs :xit
lda ReadParms+12 ; & exit if empty
beq :xit
stz temp ;init index into file
]loop
ldy temp ;is current line blank?
lda [Ptr],y
and #$7F
cmp #13
beq :nextline
cmp #';' ; no- do we have a good command?
beq :nextline
cmp #'*'
beq :nextline
dey ; yes- backup one for PString creation
bmi :xit
tya
clc
adc Ptr ;create pointer to text
sta temp2
lda Ptr+2
adc #0 ; allowing wrapping around bank!
sta temp2+2
SEP #$30 ;only need 8 bit stuff here!
ldy #1
]lup
lda [temp2],y
and #$7F ;look for EOL
cmp #'I'&$1F
beq :tab
cmp #' ' ; (anything < space 'cept tabs!)
blt :fnd
:tab
iny ;repeat until found (>255 = error)
bne ]lup
:fnd
tya ;save length!
sta [temp2] ; (only a byte)
REP #$30
~QAParseCmdLine temp2 ;parse a command line
plx
ply
bcs :xit ;able to parse?
phx
phy
_QAExecCommand ;let QA do it's thing
:nextline
~QANextLine Ptr;temp;ReadParms+12
PullWord temp
bcc ]loop ;repeat util done!
clc
:xit
rts
*======================================================
* Read the command table & create the 'commands' we know
RecSize = temp2
begword = temp3
endword = temp3+2 ;all unused at this time!!!
Ptr2 = tRLen
size = textLen
SetCmdHdl
stz CmdHdl ;we don't have one yet!
stz CmdHdl+2
pha
_QAGetCmdRecSize ;Valid even if QATools not started
pla
sta RecSize
~ReadFile #TableName;#0 ;read in command table
bcs :err
sax Hdl
Hdl_Ptr Hdl;Ptr ; & point to it
stz NumCmds ;we don't have any
~GetHandleSize Hdl ;get size of table
PullLong temp
jsr :getentry ;set all the commands
php
pha
~DisposeHandle Hdl ;get rid of data, save error status
pla
plp
:err
rts
*------------------------------------------------------
* Get the entries in the command table & set our internal
* information appropriately
:getentry
stz endword ;start at beginning of file
:gloop
ldx #eRecSize-2
]lup stz CmdLine,x ;clear buffer
dex
dex
bpl ]lup
SEP #$20
jsr :getword ;get command word w/first char in 'A'
bcc :nl0
brl :done ;reached EOF!
:nl0
cmp #'*'
beq :nl1 ;have a comment?
cmp #';'
bne :nl2
:nl1 brl :newline ; yes- skip line!
:nl2
ldx #$00
bra :c1 ; no- save first char
]loop
jsr :getchar ;get next char
bcs :nextfield
:c1
sta CmdLine+1,x ;save the command
inx
cpx #16 ; & continue for up to 15 chars
blt ]loop
dex ; (real length)
:nextfield
SEP #$10
stx CmdLine ;save length of command (byte)
REP #$10
jsr :getword ;get next word
bcs :gbad
cmp #'*' ;is this command restartable?
bne :cmp
lda #$80
tsb CmdLine+eflags+1 ; yes- show it
jsr :getchar
bcs :gbad
:cmp
ldy #1
cmp #'L' ;linker?
beq :ty
iny
cmp #'C' ;compiler?
beq :ty
iny
cmp #'I' ;internal?
beq :ty
iny
cmp #'E' ;external?
beq :ty
iny
cmp #'A' ;application?
bne :bad
:ty
sty CmdLine+etype ;save type
jsr :getword ;get next word (ID #)
:gbad bcs :bad
ldx #$00 ;save first char
bra :c2
]lup
jsr :getchar ;get next char
bcs :stx
:c2
cmp #'0'
blt :bad ;insure it's a decimal #
cmp #'9'+1
bge :bad
sta TempBuf,x ;then save it
inx
cpx #5 ; & do so for up to 4 chars
blt ]lup
dex
:stx
REP #$20 ;16 bit stuff
pha
psl #TempBuf
phx
pea 0
_Dec2Int ;convert ASCII to hex
pla
sta CmdLine+eid ; & save ID in table
inc NumCmds ;we got another!
jsr :saveit
bcs :eerr
:newline
REP #$20 ;insure 16 bit A
~QANextLine Ptr;endword;temp
PullWord endword
bcs :done
brl :gloop
:done
rep $30
lda NumCmds ;must have at least one command!
beq :bad
clc
rts
:bbad
ply ;get rid of an RTS
:bad
rep $30
lda #qabadcmdfile ;we didn't like this file!
:eerr
sec
rts
*------------------------------------------------------
:getword
REP #$20 ;force 16 bit
]loop
~QAGetWord Ptr;endword;temp ;get a word
plx
ply
beq :0 ;don't modify if no word!
stx endword
sty begword
bcc :1
tax ;real error, or just no word?
bmi :1
:0
inc endword ;no word- look for one!
bra ]loop
:1
SEP #$20
bra :gc ;get first char, uppercase!
*------------------------------------------------------
mx %10
:getchar
iny ;are we at end of word?
cpy endword
bge :gc1 ; yes- outa here!
cpy temp
bge :bbad
:gc
lda [Ptr],y
and #$7F ;create usable dude
cmp #'a'
blt :gc1 ;convert lower case
cmp #'z'+1
bge :gc2
and #$5F
:gc2
clc ;no error
:gc1
rts
*------------------------------------------------------
mx %00
:saveit
lda CmdHdl
ora CmdHdl+2 ;already started?
bne :resize
~NewHandle #1;ID2;#0;#0 ; no- need a handle!
PullLong CmdHdl
bcs :serr
:resize
~HUnlock CmdHdl ;we want to use this
psl #$00
pei NumCmds
pei RecSize
Tool $090B ;multiply # of commands by record size
lda 1,s
sta size
lda 3,s ;get result, leave on stack
sta size+2
psl CmdHdl ; to make handle the correct size
_SetHandleSize
bcc :noerr
:serr
rts ;always reached w/BCS
:noerr
~HLock CmdHdl
Hdl_Ptr CmdHdl;Ptr2 ;deref record handle
lda size
sec
sbc RecSize ;get offset to start of new record
bcs :s1
dec size+2
:s1
clc
adc Ptr2
sta Ptr2 ;adjust pointer for our use
lda Ptr2+2
adc size+2
sta Ptr2+2
ldy RecSize ;# of bytes+2 to move
]lup
dey
dey ;next word
bmi :set
lda CmdLine,y
sta [Ptr2],y ;move a word into array
bra ]lup
:set
lda CmdLine+etype ;setup system vars as found
cmp #1
beq :linker
cmp #2
bne :ul
~QAGetCompileID ;compiler ID found...already set?
pla
bne :ul
~QASetCompileID CmdLine+eid ; no- set it
bra :ul
:linker
~QAGetLinkID ;linker ID found... already set?
pla
bne :ul
~QASetLinkID CmdLine+eid ; no- set it
:ul
~HUnlock CmdHdl ;don't clog memory
rts
ToolName str '@:qasystem:qatools'
CmdName str '@:qasystem:qaintcmd'
ParmName strl '@:qasystem:qaprefs'
TableName strl '@:qasystem:qacmd'
LoginName strl '@:qasystem:login'
*======================================================
* Display the QuickASM main greeting on the text screen
PrintWelcome ENT
psl #:welcome
_QADrawBlock
~QADrawVersion #versionnum
psl #:next
_QADrawBlock
rts
:welcome
dfb 'U'&$1F,31,' '
asc 'QuickASM GS v',00
:next hex 0d
dfb 'U'&$1F,38,' '
asc 'by',0d
dfb 'U'&$1F,27,' '
asc 'Shawn Quick & Lane Roath',0d,0d
dfb 'U'&$1F,15,' '
asc 'Copyright (c) 1990 QuickSoft Software Development',0d
dfb 'U'&$1F,25,' '
asc 'All Rights Reserved Worldwide',0d
dfb 'U'&$1F,80,'_'
hex 0d0d
hex 00
lst off
sav 2/obj/qasm2.l

1
src/t1.s Normal file
View File

@ -0,0 +1 @@
 »לףפ ןזז<EFBFBD> רד ןזז<EFBFBD> רד<EFBFBD> רד<EFBFBD> םר ¥°°<EFBFBD>הנ ½ ֱµ<EFBFBD>ורנע ½ °´°µ<EFBFBD>לורנע ½ °±°²°³<EFBFBD>יםםוה ½ ±²³´µ<EFBFBD>מוח וסץ ­±<EFBFBD><EFBFBD> להר<EFBFBD> ףפר<EFBFBD> <EFBFBD>ףפבעפ°°<EFBFBD> געכ    »°°<EFBFBD> ןעב ¨הנ¬ר©<EFBFBD> דןנ £°°<EFBFBD> ןעב °°¬׃<EFBFBD> פףג הנ<EFBFBD> ןעב הנ<EFBFBD> בףל הנ<EFBFBD> ןעב <EFBFBD>הנ<EFBFBD><EFBFBD> נטנ<EFBFBD> ןעב £יםםוה<EFBFBD> בףל<EFBFBD> נטה<EFBFBD> פףג ורנע<EFBFBD> ןעב ורנע<EFBFBD> בףל ורנע<EFBFBD> ןעבל לורנע<EFBFBD><EFBFBD> »לףפ ןזז<EFBFBD> »»ומה <EFBFBD><EFBFBD>ףפבעפ±°<EFBFBD> גנל ףפבעפ±°<EFBFBD> ןעב ¨הנ©¬ש<EFBFBD> ןעב ¨הנ©<EFBFBD> ןעב ¨הנ¬ף©¬ש<EFBFBD> פעג הנ<EFBFBD> ןעב הנ¬ר<EFBFBD> בףל הנ¬ר<EFBFBD> ןעב <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> דלד<EFBFBD> ןעב ורנע¬ש<EFBFBD> ימד<EFBFBD> פדף<EFBFBD> פעג ורנע<EFBFBD> ןעב ורנע¬ר<EFBFBD> בףל ורנע¬ר<EFBFBD> ןעבל לורנע¬ר<EFBFBD><EFBFBD>ףפבעפ²°<EFBFBD> ךףע ורנע<EFBFBD> במה ¨הנ¬ר©<EFBFBD> ךףל לורנע<EFBFBD> במה הנ¬ף<EFBFBD> גיפ הנ<EFBFBD> במה הנ<EFBFBD> עןל הנ<EFBFBD> במה <EFBFBD>הנ<EFBFBD><EFBFBD> נלנ<EFBFBD> במה £יםםוה<EFBFBD> עןל<EFBFBD> נלה<EFBFBD> גיפ ורנע<EFBFBD> במה ורנע<EFBFBD> עןל ורנע<EFBFBD> במהל לורנע<EFBFBD><EFBFBD>ףפבעפ³°<EFBFBD> גםי ףפבעפ³°<EFBFBD> במה ¨הנ©¬ש<EFBFBD> במה ¨הנ©<EFBFBD> במה ¨הנ¬ף©¬ש<EFBFBD> גיפ הנ¬ר<EFBFBD> במה הנ¬ר<EFBFBD> עןל הנ¬ר<EFBFBD> במה <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> ףוד<EFBFBD> במה ורנע¬ש<EFBFBD> הוד <EFBFBD> פףד<EFBFBD> גיפ ורנע¬ר<EFBFBD> במה ורנע¬ר<EFBFBD> עןל ורנע¬ר<EFBFBD> במהל לורנע¬ר<EFBFBD><EFBFBD>ףפבעפ´°<EFBFBD> עפי<EFBFBD> וןע ¨הנ¬ר©<EFBFBD> קהם <EFBFBD> וןע הנ¬ף<EFBFBD> םצנ הנ¬הנ«±<EFBFBD> וןע הנ<EFBFBD> לףע הנ<EFBFBD> וןע <EFBFBD>הנ<EFBFBD><EFBFBD> נטב<EFBFBD> וןע £יםםוה<EFBFBD> לףע<EFBFBD> נטכ<EFBFBD> ךםנ ורנע<EFBFBD> וןע ורנע<EFBFBD> לףע ורנע<EFBFBD> וןעל לורנע<EFBFBD><EFBFBD>ףפבעפµ°<EFBFBD> גצד ףפבעפµ°<EFBFBD> וןע ¨הנ©¬ש<EFBFBD> וןע ¨הנ©<EFBFBD> וןע ¨הנ¬ף©¬ש<EFBFBD> םצמ הנ¬הנ«±<EFBFBD> וןע הנ¬ר<EFBFBD> לףע הנ¬ר<EFBFBD> וןע <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> דלי<EFBFBD> וןע ורנע¬ש<EFBFBD> נטש<EFBFBD> פדה<EFBFBD> ךםל לורנע<EFBFBD> וןע ורנע¬ר<EFBFBD> לףע ורנע¬ר<EFBFBD> וןעל לורנע¬ר<EFBFBD><EFBFBD>ףפבעפ°<EFBFBD> עפף<EFBFBD> בהד ¨הנ¬ר©<EFBFBD> נוע ורנע<EFBFBD> בהד הנ¬ף<EFBFBD> ףפת הנ<EFBFBD> בהד הנ<EFBFBD> עןע הנ<EFBFBD> בהד <EFBFBD>הנ<EFBFBD><EFBFBD> נלב<EFBFBD> בהד £יםםוה<EFBFBD> עןע<EFBFBD> עפל<EFBFBD> ךםנ ¨ורנע©<EFBFBD> בהד ורנע<EFBFBD> עןע ורנע<EFBFBD> בהדל לורנע<EFBFBD><EFBFBD>ףפבעפ·°<EFBFBD> גצף ףפבעפ·°<EFBFBD> בהד ¨הנ©¬ש<EFBFBD> בהד ¨הנ©<EFBFBD> בהד ¨הנ¬ף©¬ש<EFBFBD> ףפת הנ¬ר<EFBFBD> בהד הנ¬ר<EFBFBD> עןע הנ¬ר<EFBFBD> בהד <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> ףוי<EFBFBD> בהד ורנע¬ש<EFBFBD> נלש<EFBFBD> פהד<EFBFBD> ךםנ ¨ורנע¬ר©<EFBFBD> בהד ורנע¬ר<EFBFBD> עןע ורנע¬ר<EFBFBD> בהדל ורנע¬ר<EFBFBD><EFBFBD>ףפבעפ¸°<EFBFBD> געב ףפבעפ¸°<EFBFBD> ףפב ¨הנ¬ר©<EFBFBD> געל ףפבעפ¸°<EFBFBD> ףפב הנ¬ף<EFBFBD> ףפש הנ<EFBFBD> ףפב הנ<EFBFBD> ףפר הנ<EFBFBD> ףפב <EFBFBD>הנ<EFBFBD><EFBFBD> הוש<EFBFBD> גיפ £יםםוה<EFBFBD> פרב<EFBFBD> נטג<EFBFBD> ףפש ורנע<EFBFBD> ףפב ורנע<EFBFBD> ףפר ורנע<EFBFBD> ףפבל לורנע<EFBFBD><EFBFBD>ףפבעפ¹°<EFBFBD> גדד ףפבעפ¹°<EFBFBD> ףפב ¨הנ©¬ש<EFBFBD> ףפב ¨הנ©<EFBFBD> ףפב ¨הנ¬ף©¬ש<EFBFBD> ףפש הנ¬ר<EFBFBD> ףפב הנ¬ר<EFBFBD> ףפר הנ¬ש<EFBFBD> ףפב <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> פשב<EFBFBD> ףפב ורנע¬ש<EFBFBD> פרף<EFBFBD> פרש<EFBFBD> ףפת ורנע<EFBFBD> ףפב ורנע¬ר<EFBFBD> ףפת ורנע¬ר<EFBFBD> ףפבל לורנע¬ר<EFBFBD><EFBFBD>ףפבעפֱ°<EFBFBD> להש £יםםוה<EFBFBD> להב ¨הנ¬ר©<EFBFBD> להר £יםםוה<EFBFBD> להב הנ¬ף<EFBFBD> להש הנ<EFBFBD> להב הנ<EFBFBD> להר הנ<EFBFBD> להב <EFBFBD>הנ<EFBFBD><EFBFBD> פבש<EFBFBD> להב £יםםוה<EFBFBD> פבר<EFBFBD> נלג<EFBFBD> להש ורנע<EFBFBD> להב ורנע<EFBFBD> להר ורנע<EFBFBD> להבל לורנע<EFBFBD><EFBFBD>ףפבעפֲ°<EFBFBD> גדף ףפבעפֲ°<EFBFBD> להב ¨הנ©¬ש<EFBFBD> להב ¨הנ¬ף©<EFBFBD> להב ¨הנ¬ף©¬ש<EFBFBD> להש הנ¬ר<EFBFBD> להב הנ¬ר<EFBFBD> להר הנ¬ש<EFBFBD> להב <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> דלצ<EFBFBD> להב ורנע¬ש<EFBFBD> פףר<EFBFBD> פשר<EFBFBD> להש ורנע¬ר<EFBFBD> להב ורנע¬ר<EFBFBD> להר ורנע¬ש<EFBFBD> להבל לורנע¬ר<EFBFBD><EFBFBD>ףפבעפֳ°<EFBFBD> דנש £יםםוה<EFBFBD> דםנ ¨הנ¬ר©<EFBFBD> עונ £ֶֶ<EFBFBD> דםנ הנ¬ף<EFBFBD> דנש הנ<EFBFBD> דםנ הנ<EFBFBD> הוד הנ<EFBFBD> דםנ <EFBFBD>הנ<EFBFBD><EFBFBD> ימש<EFBFBD> דםנ £יםםוה<EFBFBD> הור<EFBFBD> קבי<EFBFBD> דנש ורנע<EFBFBD> דםנ ורנע<EFBFBD> הוד ורנע<EFBFBD> דםנל לורנע<EFBFBD><EFBFBD>ףפבעפִ°<EFBFBD> גמו ףפבעפִ°<EFBFBD> דםנ ¨הנ©¬ש<EFBFBD> דםנ ¨הנ©<EFBFBD> דםנ ¨הנ¬ף©¬ש<EFBFBD> נוי הנ<EFBFBD> דםנ הנ¬ר<EFBFBD> הוד הנ¬ר<EFBFBD> דםנ <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> דלה<EFBFBD> דםנ ורנע¬ש<EFBFBD> נטר<EFBFBD> ףפנ<EFBFBD> ךםל <EFBFBD>לורנע<EFBFBD><EFBFBD> דםנ ורנע¬ר<EFBFBD> הוד ורנע¬ר<EFBFBD> דםנל לורנע¬ר<EFBFBD><EFBFBD>ףפבעפֵ°<EFBFBD> דנר £יםםוה<EFBFBD> ףגד ¨הנ¬ר©<EFBFBD> ףונ £ֶֶ<EFBFBD> ףגד הנ¬ף<EFBFBD> דנר הנ<EFBFBD> ףגד הנ<EFBFBD> ימד הנ<EFBFBD> ףגד <EFBFBD>הנ<EFBFBD><EFBFBD> ימר <EFBFBD> ףגד £יםםוה<EFBFBD> מןנ<EFBFBD> רגב<EFBFBD> דנר ורנע<EFBFBD> ףגד ורנע<EFBFBD> ימד ורנע<EFBFBD> ףגדל לורנע<EFBFBD><EFBFBD>ףפבעפֶ°<EFBFBD> גוס ףפבעפֶ°<EFBFBD> ףגד ¨הנ©¬ש<EFBFBD> ףגד ¨הנ©<EFBFBD> ףגד ¨הנ¬ף©¬ש<EFBFBD> נוב ףפבעפֶ°<EFBFBD> ףגד הנ¬ר<EFBFBD> ימד הנ¬ר<EFBFBD> ףגד <EFBFBD>הנ<EFBFBD>¬ש<EFBFBD> ףוה<EFBFBD> ףגד ורנע¬ש<EFBFBD> נלר<EFBFBD> רדו<EFBFBD> ךףע ¨ורנע¬ר©<EFBFBD> ףגד ורנע¬ר<EFBFBD> ימד ורנע¬ר<EFBFBD> ףגדל לורנע¬ר<EFBFBD><EFBFBD> לףפ ןזז<EFBFBD>

308
src/testfile.s Normal file
View File

@ -0,0 +1,308 @@
lst off
xc off
xc
xc
mx %00
dp = $A5
expr = $0405
lexpr = $010203
immed = $123456
neg equ -16
ldx
stx
tsb #$DE
jmp [lexpr]
start00
brk ;$00
ora (dp,x)
cop #$00
ora $00,S
tsb dp
ora dp
asl dp
ora [dp]
php
ora #immed
asl
phd
tsb expr
ora expr
asl expr
oral lexpr
;lst off
;;end
start10
bpl start10
ora (dp),y
ora (dp)
ora (dp,s),y
trb dp
ora dp,x
asl dp,x
ora [dp],y
clc
ora expr,y
inc
tcs
trb expr
ora expr,x
asl expr,x
oral lexpr,x
start20
jsr expr
and (dp,x)
jsl lexpr
and dp,s
bit dp
and dp
rol dp
and [dp]
plp
and #immed
rol
pld
bit expr
and expr
rol expr
andl lexpr
start30
bmi start30
and (dp),y
and (dp)
and (dp,s),y
bit dp,x
and dp,x
rol dp,x
and [dp],y
sec
and expr,y
dec
tsc
bit expr,x
and expr,x
rol expr,x
andl lexpr,x
start40
rti
eor (dp,x)
wdm
eor dp,s
mvp dp,dp+1
eor dp
lsr dp
eor [dp]
pha
eor #immed
lsr
phk
jmp expr
eor expr
lsr expr
eorl lexpr
start50
bvc start50
eor (dp),y
eor (dp)
eor (dp,s),y
mvn dp,dp+1
eor dp,x
lsr dp,x
eor [dp],y
cli
eor expr,y
phy
tcd
jml lexpr
eor expr,x
lsr expr,x
eorl lexpr,x
start60
rts
adc (dp,x)
per expr
adc dp,s
stz dp
adc dp
ror dp
adc [dp]
pla
adc #immed
ror
rtl
jmp (expr)
adc expr
ror expr
adcl lexpr
start70
bvs start70
adc (dp),y
adc (dp)
adc (dp,s),y
stz dp,x
adc dp,x
ror dp,x
adc [dp],y
sei
adc expr,y
ply
tdc
jmp (expr,x)
adc expr,x
ror expr,x
adcl expr,x
start80
bra start80
sta (dp,x)
brl start80
sta dp,s
sty dp
sta dp
stx dp
sta [dp]
dey
bit #immed
txa
phb
sty expr
sta expr
stx expr
stal lexpr
start90
bcc start90
sta (dp),y
sta (dp)
sta (dp,s),y
sty dp,x
sta dp,x
stx dp,y
sta [dp],y
tya
sta expr,y
txs
txy
stz expr
sta expr,x
stz expr,x
stal lexpr,x
startA0
ldy #immed
lda (dp,x)
ldx #immed
lda dp,s
ldy dp
lda dp
ldx dp
lda [dp]
tay
lda #immed
tax
plb
ldy expr
lda expr
ldx expr
ldal lexpr
startB0
bcs startB0
lda (dp),y
lda (dp,s)
lda (dp,s),y
ldy dp,x
lda dp,x
ldx dp,y
lda [dp],y
clv
lda expr,y
tsx
tyx
ldy expr,x
lda expr,x
ldx expr,y
ldal lexpr,x
startC0
cpy #immed
cmp (dp,x)
rep #$FF
cmp dp,s
cpy dp
cmp dp
dec dp
cmp [dp]
iny
cmp #immed
dex
wai
cpy expr
cmp expr
dec expr
cmpl lexpr
startD0
bne startD0
cmp (dp),y
cmp (dp)
cmp (dp,s),y
pei dp
cmp dp,x
dec dp,x
cmp [dp],y
cld
cmp expr,y
phx
stp
jml [lexpr]
cmp expr,x
dec expr,x
cmpl lexpr,x
startE0
cpx #immed
sbc (dp,x)
sep #$FF
sbc dp,s
cpx dp
sbc dp
inc dp
sbc [dp]
inx
sbc #immed
nop
xba
cpx expr
sbc expr
inc expr
sbcl lexpr
startF0
beq startF0
sbc (dp),y
sbc (dp)
sbc (dp,s),y
pea startF0
sbc dp,x
inc dp,x
sbc [dp],y
sed
sbc expr,y
plx
xce
jsr (expr,x)
sbc expr,x
inc expr,x
sbcl lexpr,x
lst off

23
src/tools/link.s Normal file
View File

@ -0,0 +1,23 @@
*======================================================
* Link file for QATools
* Written by Lane Roath
*======================================================
ovr
asm qatools
do err
else
lnk 2/obj/qatools.l
ds $1000 ;DS_Size
typ tol
sav 2/qasystem/qatools
fin
end

3547
src/tools/qatools.1.s Normal file

File diff suppressed because it is too large Load Diff

598
src/tools/qatools.macs.s Normal file
View File

@ -0,0 +1,598 @@
_QABootInit mac ;_QABootInit()
utool $01
<<<
~QAStartup MAC
psw ]1
psl ]2
_QAStartup mac ;_QAStartup(userid,modeflags/4)
utool $02
<<<
_QAShutdown mac ;_QAShutdown()
utool $03
<<<
~QAVersion MAC
pha
_QAVersion mac ;_QAVersion():versionnum
utool $04
<<<
_QAReset mac ;_QAReset()
utool $05
<<<
~QAStatus MAC
pha
_QAStatus mac ;_QAStatus():statflag
utool $06
<<<
~QADrawChar MAC
phw ]1
_QADrawChar mac ;_QADrawChar(char)
utool $09
<<<
~QADrawString MAC
~QADrawStr MAC
psl ]1
_QADrawString mac ;_QADrawString(@strptr)
_QADrawStr mac
utool $0A
<<<
~QAPrByte MAC
psw ]1
_QAPrByte mac ;_QAPrByte(byteval)
utool $0B
<<<
~QAPrByteL MAC
psw ]1
_QAPrByteL mac ;_QAPrByteL(hexval)
utool $0C
<<<
~QADrawDec MAC
psl ]1
psw ]2
ps2 ]3
_QADrawDec mac ;_QADrawDec(longint/4,flags,fieldsize)
utool $0D
<<<
~QAKeyAvail MAC
pha
_QAKeyAvail mac ;_QAKeyAvail():availflag
utool $0E
<<<
~QAGetChar MAC
pha
_QAGetChar mac ;_QAGetChar():char (char in low/modifiers in high)
utool $0F
<<<
_QAGetLine mac ;_QAGetLine(@linestr)
utool $10
<<<
~QASetParmHdl MAC
psl ]1
_QASetParmHdl mac ;_QASetParmHdl(parmhandle)
utool $11
<<<
~QAGetParmHdl MAC
pha
pha
_QAGetParmHdl mac ;_QAGetParmHdl():parmhandle
utool $12
<<<
~QASetCmdHdl MAC
psl ]1
psw ]2
_QASetCmdHdl mac ;_QASetCmdHdl(commandhandle,numcmds)
utool $13
<<<
~QAGetCmdHdl MAC
pha
pha
pha
_QAGetCmdHdl mac ;_QAGetCmdHdl():commandhandle,numcmds
utool $14
<<<
~QAReadTotalErrs MAC
pha
_QAReadTotalErrs mac ;_QAReadTotalErrs():totalerrs
utool $15
<<<
~QAGetModeFlags MAC
pha
pha
_QAGetModeFlags mac ;_QAGetModeFlags():modeflags/4
utool $16
<<<
~QASetModeFlags MAC
psl ]1
_QASetModeFlags mac ;_QASetModeFlags(modeflags/4)
utool $17
<<<
_QALoadFile mac ;_QALoadfile(@filename,filepos/4,length/4,@typelist,userid,address/4,memattrib):filehandle/4
utool $18
<<<
_QASaveFile mac ;_QASavefile(filehandle/4,@filename,filetype,auxtype/4)
utool $19
<<<
~QASetCmdLine MAC
psl ]1
_QASetCmdLine mac ;_QASetCmdLine(@strptr)
utool $1A
<<<
~QAGetCmdLine MAC
psl ]1
psw ]2
_QAGetCmdLine mac ;_QAGetCmdLine(@strptr,maxlen)
utool $1B
<<<
~QAParseCmdLine MAC
pha
pha
psl ]1
_QAParseCmdLine mac ;_QAParseCmdLine(@strptr):cmdid,cmdtype
utool $1C
<<<
~QAGetQuitFlag MAC
pha
_QAGetQuitFlag mac ;_QAGetQuitFlag():quitflag
utool $1D
<<<
~QASetQuitFlag MAC
psw ]1
_QASetQuitFlag mac ;_QASetQuitFlag(quitflag)
utool $1E
<<<
~QASetCmdTbl MAC
psl ]1
_QASetCmdTbl mac ;_QASetCmdTbl(@cmdtbl)
utool $1F
<<<
~QAGetCmdTbl MAC
pha
pha
_QAGetCmdTbl mac ;_QAGetCmdTbl():@cmdtbl
utool $20
<<<
~QAExecCommand MAC
psw ]1
psw ]2
_QAExecCommand mac ;_QAExecCommand(cmdtype,cmdid)
utool $21
<<<
~QAGetMessagebyID MAC
pha
pha
pha
psw ]1
_QAGetMessagebyID mac ;_QAGetMessagebyID(userid):message,subtype/4
utool $22
<<<
_QARun mac ;_QARun()
utool $23
<<<
_QADispose mac ;_QADispose()
utool $24
<<<
~QAShutdownID MAC
psw ]1
_QAShutdownID mac ;_QAShutDownID(userid)
utool $25
<<<
~QACompile MAC
psw ]1
psl ]2
_QACompile mac ;_QACompile(message,subtype/4)
utool $26
<<<
~QALink MAC
psw ]1
psl ]2
_QALink mac ;_QALink(message,subtype/4)
utool $27
<<<
~QACompilerActive MAC
pha
_QACompilerActive mac ;_QAComplierActive():activeflag
utool $28
<<<
~QALinkerActive MAC
pha
_QALinkerActive mac ;_QALinkerActvie():activeflag
utool $29
<<<
~QAGetCompileID MAC
pha
_QAGetCompileID mac ;_QAGetCompileID():compileID
utool $2A
<<<
~QASetCompileID MAC
psw ]1
_QASetCompileID mac ;_QASetCompileID(compileID)
utool $2B
<<<
~QAGetLinkID MAC
pha
_QAGetLinkID mac ;_QAGetLinkID():linkID
utool $2C
<<<
~QASetLinkID MAC
psw ]1
_QASetLinkID mac ;_QASetLinkID(linkID)
utool $2D
<<<
~QAGetVector MAC
pha
pha
psw ]1
_QAGetVector mac ;_QAGetVector(vect#):@address
utool $2E
<<<
~QASetVector MAC
psw ]1
psl ]2
_QASetVector mac ;_QASetVector(vect#,@address)
utool $2F
<<<
_QAResetVectors mac ;_QAResetVectors()
utool $30
<<<
~QAEvent MAC
psl ]1
psw ]2
_QAEvent mac ;_QAEvent(@eventptr,taskflag)
utool $31
<<<
~QAGetCmdRecSize MAC
pha
_QAGetCmdRecSize mac ;_QAGetCmdRecSize():recordsize
utool $32
<<<
~QATabtoCol MAC
psw ]1
_QATabtoCol mac ;_QATabtoCol(columnnum)
utool $33
<<<
~QAErrorMsg MAC
psw ]1
_QAErrorMsg mac ;_QAErrorMsg(ErrorCode)
utool $34
<<<
~QABarGraph MAC
psw ]1
psl ]2
_QABarGraph mac ;_QABarGraph(percent,@Message)
utool $35
<<<
~QAConvertPath MAC
psl ]1
psl ]2
_QAConvertPath mac ;_QAConvertPath(@oldpath,@newpath)
utool $36
<<<
~QATyp2Txt MAC
psw ]1
psl ]2
_QATyp2Txt mac
_QAConvertTyp2Txt mac ;_QAConvertTyp2Txt(filetype,@typestr)
utool $37
<<<
~QATxt2Typ MAC
pha
psl ]1
_QATxt2Typ mac
_QAConvertTxt2Typ mac ;_QAConvertTxt2Typ(@typestr):type
utool $38
<<<
~QAReadDir MAC
psl ]1
psl ]2
psw ]3
_QAReadDir mac ;_QAReadDir(@pathname,@doroutine,flags)
utool $39
<<<
~QAInitWildcard MAC
psl ]1
psw ]2
psl ]3
psw ]4
psl ]5
_QAInitWildcard mac ;_QAInitWildcard(@wcstr,ft,aux/4,ftmask,auxmask/4)
utool $3A
<<<
_QAUndefined mac ;_QAUndefined()
utool $3B
<<<
_QAInitTotalErrs mac ;_QAInitTotalErrs()
utool $3C
<<<
_QAIncTotalErrs mac ;_QAIncTotalErrs()
utool $3D
<<<
~QAGetTotalErrs MAC
pha
_QAGetTotalErrs mac ;_QAGetTotalErrs():totalerrs
utool $3E
<<<
~QAGetCancelFlag MAC
pha
_QAGetCancelFlag mac ;_QAGetCancelFlag():cancelflag
utool $3F
<<<
~QASetCancelFlag MAC
psw ]1
_QASetCancelFlag mac ;_QASetCancelFlag(cancelflag)
utool $40
<<<
_QAStartTiming mac ;_QAStartTiming()
utool $41
<<<
~QAEndTiming MAC
pha
pha
pha
_QAEndTiming mac ;_QAEndTiming():hours,minutes,seconds
utool $42
<<<
~QAGetSymTable MAC
pha
pha
pha
pha
pha
_QAGetSymTable mac ;_QAGetSymTable():@table,symhandle/4,numlabels
utool $43
<<<
~QASetSymTable MAC
psl ]1
psl ]2
psw ]3
_QASetSymTable mac ;_QASetSymTable(@table,symhandle/4,numlabels)
utool $44
<<<
~QASetPath MAC
psl ]1
_QASetPath mac ;_QASetPath(@pathname)
utool $45
<<<
~QAGetPath MAC
psl ]1
_QAGetPath mac ;_QAGetPath(@pathname)
utool $46
<<<
~QAGetObjType MAC
pha
_QAGetObjType mac ;_QAGetObjType():type
utool $47
<<<
~QASetObjType MAC
psw ]1
_QASetObjType mac ;_QASetObjType(type)
utool $48
<<<
~QAGetObjPath MAC
psl ]1
_QAGetObjPath mac ;_QAGetObjPath(@pathname)
utool $49
<<<
~QASetObjPath MAC
psl ]1
_QASetObjPath mac ;_QASetObjPath(@pathname)
utool $4A
<<<
~QACallUSR MAC
pha
psw ]1
psl ]2
_QACallUSR mac ;_QACallUSR(opcode,@operand):handled
utool $4B
<<<
~QACallUser MAC
psw ]1
psw ]2
psl ]3
psl ]4
_QACallUser mac ;_QACallUser(rngstart,rngend,texthandle/4,textlen/4)
utool $4C
<<<
~QAGoEval MAC
pha
pha
psl ]1
psw ]2
_QAGoEVAL mac ;_QAGoEVAL(@operand,offset):value/4
utool $4D
<<<
~QAGoPutByte MAC
psw ]1
_QAGoPutByte mac ;_QAGoPutByte(byte)
utool $4E
<<<
~QAGoPutOpcode MAC
psw ]1
_QAGoPutOpcode mac ;_QAGoPutOpcode(opcodebyte)
utool $4F
<<<
_QAGoRelcorrect mac ;_QAGoRelcorrect()
utool $50
<<<
~QADrawErrChar MAC
psw ]1
_QADrawErrChar mac ;_QADrawErrChar(char)
utool $51
<<<
~QADrawErrStr MAC
psl ]1
_QADrawErrStr mac
_QADrawErrString mac ;_QADrawErrString(@strptr)
utool $52
<<<
~QAGetWindow MAC
pha
pha
_QAGetWindow mac ;_QAGetWindow():windowtype
utool $53
<<<
~QASetWindow MAC
psl ]1
_QASetWindow mac ;_QASetWindow(windowtype)
utool $54
<<<
~QAGetShellID MAC
pha
_QAGetShellID mac ;_QAGetShellID():userid
utool $55
<<<
~QASetShellID MAC
psw ]1
_QASetShellID mac ;_QASetShellID(userid)
utool $56
<<<
~QAGotoXY MAC
psw ]1
psw ]2
_QAGotoXY mac ;_QAGotoXY(X,Y)
utool $57
<<<
~QAGetXY MAC
pha
pha
_QAGetXY mac ;_QAGetXY():X,Y
utool $58
<<<
~QAPrNibble MAC
psw ]1
_QAPrNibble mac ;_QAPrNibble(nibval)
utool $59
<<<
~QADrawHex MAC
psl ]1
psw ]2
psw ]3
_QADrawHex mac ;_QADrawHex(hexval/4,flags,fieldsize)
utool $5A
<<<
~QADrawCStr mac
~QADrawCString mac
psl ]1
_QADrawCStr mac
_QADrawCString mac
_QADrawBlock mac ;_QADrawBlock(@CBlock)
utool $5B
<<<
~QADrawErrCStr MAC
psl ]1
_QADrawErrCStr mac
_QADrawErrBlock mac ;_QADrawErrBlock(@CBlock)
utool $5C
<<<
~QADrawCharX MAC
psw ]1
psw ]2
_QADrawCharX mac ;_QADrawCharX(char,count)
utool $5D
<<<
~QADrawECharX MAC
psw ]1
psw ]2
_QADrawECharX mac ;_QADrawECharX(char,count)
utool $5E
<<<
~QAGetLaunch MAC
pha
pha
pha
_QAGetLaunch mac ;_QAGetLaunch():@path,flags
utool $5F
<<<
~QASetLaunch MAC
psl ]1
psw ]2
_QASetLaunch mac ;_QASetLaunch(@path,flags)
utool $60
<<<
~QAGetWord MAC
pha
pha
psl ]1
psw ]2
psw ]3
_QAGetWord mac ;_QAGetWord(@Text,Offset,MaxLen):BegOffset,EndOffset
utool $61
<<<
~QADateTime mac
psl ]1
psw ]2
_QADateTime mac ;_QADateTime(@Date,flags)
utool $62
<<<
_QADrawCR mac ;_QADrawCR()
utool $63
<<<
_QADrawSpace mac ;_QADrawSpace()
utool $64
<<<
~QADrawVersion mac
psl ]1
_QADrawVersion mac ;_QADrawVersion(Version/4)
utool $65
<<<
~QADrawBox MAC
pha
pha
psw ]1
psw ]2
psw ]3
psw ]4
_QADrawBox MAC ;_QADrawBox(x,y,width,height):buffhdl
utool $66
<<<
~QAEraseBox MAC
psl ]1
_QAEraseBox MAC ;_QAEraseBox(buffhdl)
utool $67
<<<
~QAConvertStr MAC
pha
psl ]1
psl ]2
psw ]3
_QAConvertStr MAC ;_QAConvertStr(@string/class.1,@buffer/class.1,cmdcode):rtncode
utool $68
<<<
~QADrawStrL MAC
psl ]1
_QADrawStrL MAC ;_QADrawStrL(@string/class.1)
utool $69
<<<
~QADrawErrStrL MAC
psl ]1
_QADrawErrStrL MAC ;_QADrawErrStrL(@strptr/class.1)
utool $6A
<<<
~QAGetKeyAdrs MAC
pha
pha
_QAGetKeyAdrs MAC ;_QAGetKeyAdrs():keyaddress/4
utool $6B
<<<
~QANextLine MAC
pha
pha
psl ]1
psw ]2
psw ]3
_QANextLine mac ;_QANextLine(@Text,Offset,MaxLen):NewLineOffset
utool $6C
<<<
_QAClearKey MAC ;_QAClearKey()
utool $6D
<<<
_QAParseWord MAC ;_QAParseWord(???):???
utool $6E
<<<
utool mac
ldx #]1*256+ToolNum
do userorsys
jsl $E10008
else
jsl $E10000
fin
<<<

5261
src/tools/qatools.s Normal file

File diff suppressed because it is too large Load Diff

242
src/tools/tool.macs.s Normal file
View File

@ -0,0 +1,242 @@
_NEWHANDLE MAC
Tool $902
<<<
_DISPOSEHANDLE MAC
Tool $1002
<<<
_GETHANDLESIZE MAC
Tool $1802
<<<
_SETHANDLESIZE MAC
Tool $1902
<<<
_HLOCK MAC
Tool $2002
<<<
_HUNLOCK MAC
Tool $2202
<<<
^READTIMEHEX MAC
PHS 4
Tool $D03
<<<
^READASCIITIME MAC
PHL ]1
Tool $F03
<<<
^GETNEXTEVENT MAC
PHA
PHWL ]1;]2
Tool $A06
<<<
^SETVECTOR MAC
PHWL ]1;]2
Tool $1003
<<<
^GETVECTOR MAC
P2SW ]1
Tool $1103
<<<
PHWL MAC
PHW ]1
PHL ]2
<<<
P2SW MAC
PHA
PHA
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PSW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PSL mac
if #,]1
pea ^]1
pea ]1
else
if :,]1
lda ]1+2
pha
lda ]1
pha
else
lda ]1+2
pha
lda ]1
pha
fin
fin
eom
PLL mac
if :,]1
pla
sta ]1
pla
sta ]1+2
else
pla
sta ]1
pla
sta ]1+2
fin
eom
TOOL mac
ldx #]1
jsl $E10000
eom
TLL mac
ldx #]1
jsl $E10000
eom
JMI mac
bpl *+5
jmp ]1
eom
JPL mac
bmi *+5
jmp ]1
eom
JNE mac
beq *+5
jmp ]1
eom
JEQ mac
bne *+5
jmp ]1
eom
JGE mac
blt *+5
jmp ]1
eom
JLT mac
bge *+5
jmp ]1
eom
JCS mac
bcc *+5
jmp ]1
eom
JCC mac
bcs *+5
jmp ]1
eom
_QAGotoXY mac
utool $57
eom
_QADRAWSTRING mac
utool $0A
<<<
_QADRAWSTR mac
utool $0A
<<<
_QAPRBYTE mac
utool $0B
<<<
_QAPRBYTEL mac
utool $0C
<<<
_QADRAWDEC mac
utool $0D
<<<
_QAKEYAVAIL mac
utool $0E
<<<
_QAGETCHAR mac
utool $0F
<<<
_QAGETCMDLINE mac
utool $1B
<<<
_QARUN mac
utool $23
<<<
_QADRAWERRCHAR mac
utool $51
<<<
_QADRAWERRSTRING mac
utool $52
<<<
_QADRAWHEX mac
utool $5A
<<<
^QADRAWCSTRING mac
psl ]1
utool $5B
<<<
_QADRAWCHARX mac
utool $5D
<<<
~QAGetWord MAC
pha
pha
psl ]1
psw ]2
utool $61
<<<
_GSOS MAC
do inline
jsl prodos
dw ]1
adrl ]2
else
psl #]2
pea ]1
jsl prodosIL
fin
<<<
UTOOL mac
ldx #]1*256+toolnum
do userorsys
jsl $E10008
else
jsl $E10000
fin
<<<
PHL MAC
IF #=]1
PEA ^]1
ELSE
PHW ]1+2
FIN
PHW ]1
<<<
PHW MAC
IF #=]1
PEA ]1
ELSE
IF MX/2
LDA ]1+1
PHA
FIN
LDA ]1
PHA
FIN
<<<
PHS MAC
DO ]0
LUP ]1
PHA
--^
ELSE
PHA
FIN
<<<

1
src/utility/catalog Normal file
View File

@ -0,0 +1 @@
K

2
src/utility/delete Normal file
View File

@ -0,0 +1,2 @@


1
src/utility/deletelink Normal file
View File

@ -0,0 +1 @@
;

1
src/utility/dump Normal file
View File

@ -0,0 +1 @@
2

1
src/utility/edit Normal file
View File

@ -0,0 +1 @@
8(

1
src/utility/lc Normal file
View File

@ -0,0 +1 @@
<

Some files were not shown because too many files have changed in this diff Show More