Merge pull request #20 from marketideas/sgq_qasm_main

Sgq qasm main
This commit is contained in:
marketideas 2019-11-19 13:45:40 -08:00 committed by GitHub
commit 661de97c2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 58 deletions

37
README
View File

@ -1,29 +1,38 @@
Merlin Compatible assembler/linker (and more) for linux Merlin Compatible assembler/linker (and more) for linux
This project is FAR from complete...as I have just gotten it to compile all 256 65816 opcodes. This project is FAR from complete...as I have just gotten it to compile all 256 65816 opcodes.
The program will read/compile linux based Merlin syntax files (.s), as well as original Merlin 8/16/16+ files in Merlin format
(high bit set), compressed spaces, and only a <CR> to end lines. I plan on adding a mode that will process and convert to linux style so
files can be converted for easy editing under linux.
Merlin32 is great, but there are aspects of it that I don't like (always outputting assembly status and creating .txt file listings, etc) Update (11/19/2019) - All code generating opcodes/psuedo-ops complete.
Along time ago, in the mid 1980's I wrote a Merlin compatible assembler and programming shell (with the help of Lane Roathe) for the Apple //GS The program will read/compile linux based Merlin syntax files (.s), as well as original Merlin
Recently, Lane sent me the source code to that assembler. Unfortunately, because of some of the features we added to the assembler, it will not 8/16/16+ files in Merlin format
compile under Merlin or Merlin32. (We actually used qasm to build qasm). (high bit set), compressed spaces, and only a <CR> to end lines. I plan on adding a mode that
will process and convert to linux style so files can be converted for easy editing under linux.
This project will be a linux compatible version, that will compile/link the original source. However, due to speed and everything 'linux' Merlin32 is great, but there are aspects of it that I don't like (always outputting assembly
I doubt the original will be used much. status and creating .txt file listings, etc)
I also would like to interface with the CiderPress library to allow output from the assembler/linker to write files directly to Prodos Along time ago, in the mid 1980's I wrote a Merlin compatible assembler and programming shell
based .2MG (or other) images. That way, after a compile, the code under test can be immediately run from a GS emulator. (with the help of Lane Roathe) for the Apple //GS
Recently, Lane sent me the source code to that assembler. Unfortunately, because of some of the
features we added to the assembler, it will not compile under Merlin or Merlin32. (We actually used
qasm to build qasm).
This project will be a linux compatible version, that will compile/link the original source.
However, due to speed and everything 'linux' I doubt the original will be used much.
I also would like to interface with the CiderPress library to allow output from the assembler/linker
to write files directly to Prodos based .2MG (or other) images. That way, after a compile, the code
under test can be immediately run from a GS emulator.
This early version relies on the Poco Foundation libraries. You must have these installed. This early version relies on the Poco Foundation libraries. You must have these installed.
Additionally, this repo relies on another repo here called 'libpal'. Both repositories must be cloned at the same level. Additionally, this repo relies on another repo here called 'libpal'. Both repositories must
be cloned at the same level.
libpal does not have to be built. The 'qasm' compile will build all of those source files. libpal does not have to be built. The 'qasm' compile will build all of those source files.
'cmake' is used to build the Makefiles. There is a generic Makefile in the base directory that does all of the 'cmake' stuff for you. 'cmake' is used to build the Makefiles. There is a generic Makefile in the base directory that does
(in a 'build' directory) all of the 'cmake' stuff for you. (in a 'build' directory)
For example: For example:
mkdir workdir mkdir workdir

70
asm.cpp
View File

@ -205,7 +205,7 @@ void CLASS::print(uint32_t lineno)
{ {
pcol += printf(" "); pcol += printf(" ");
} }
if (isDebug() > 2) if (isDebug() > 1)
{ {
pcol += printf("%s ", operand.c_str()); pcol += printf("%s ", operand.c_str());
} }
@ -1325,40 +1325,56 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
} }
} }
switch (line.expr_shift) if (line.addressmode == syn_imm)
{ {
case '<': //printf("immediate mode\n");
line.expr_value &= 0xFF; switch (line.expr_shift)
line.flags |= FLAG_DP; {
break; case '<':
case '>': line.expr_value &= 0xFF;
line.expr_value >>= 8; break;
line.expr_value &= 0xFFFF; case '>':
if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32) line.expr_value >>= 8;
{ line.expr_value &= 0xFFFF;
break;
case '^':
line.expr_value = (line.expr_value >> 16) & 0xFFFF;
break;
case '|':
break;
}
}
else
{
switch (line.expr_shift)
{
case '<':
line.flags |= FLAG_DP;
break;
case '>':
if ((syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
{
// bug in M32 or not, do what it does
line.flags |= FLAG_FORCEABS;
}
else
{
line.flags |= FLAG_FORCELONG;
}
break;
case '|':
line.flags |= FLAG_FORCEABS; line.flags |= FLAG_FORCEABS;
} break;
break; case '^':
case '^': //line.flags |= FLAG_FORCELONG;
line.expr_value = (line.expr_value >> 16) & 0xFFFF; break;
if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32) }
{
line.flags |= FLAG_FORCEABS;
}
break;
case '|':
if ((line.syntax & SYNTAX_MERLIN32) != SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCELONG;
}
break;
} }
if (line.expr_value >= 0x100) if (line.expr_value >= 0x100)
{ {
line.flags |= FLAG_FORCEABS; line.flags |= FLAG_FORCEABS;
} }
auto itr = opcodes.find(Poco::toUpper(op)); auto itr = opcodes.find(Poco::toUpper(op));
if (itr != opcodes.end()) if (itr != opcodes.end())
{ {

View File

@ -95,17 +95,15 @@ int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
{ {
res = -1; res = -1;
if (syntax==SYNTAX_MERLIN) #if 1
{ char buff[32];
char buff[32]; sprintf(buff, "$%08X", line.expr_value);
sprintf(buff,"$%08X",line.expr_value); std::string s1 = buff;
std::string s1=buff; s = addVariable(line.lable, s1, true);
s = addVariable(line.lable, s1, true); #else
} // do this if you want to do this more as a #define
else s = addVariable(line.lable, line.operand, true);
{ #endif
s = addVariable(line.lable, line.operand, true);
}
if (s != NULL) if (s != NULL)
{ {
res = 0; res = 0;
@ -295,6 +293,19 @@ int CLASS::doAddress(MerlinLine &line, TSymbol &sym)
res = 1 + sym.stype; res = 1 + sym.stype;
if (pass > 0) if (pass > 0)
{ {
switch(line.expr_shift)
{
case '^':
line.expr_value=(line.expr_value>>16)&0xFFFF;
break;
case '<':
line.expr_value=(line.expr_value)&0xFF;
break;
case '>':
line.expr_value=(line.expr_value>>8)&0xFFFF;
break;
}
//line.setError(errIncomplete); //line.setError(errIncomplete);
setOpcode(line, sym.opcode); setOpcode(line, sym.opcode);
for (i = 0; i < (res - 1); i++) for (i = 0; i < (res - 1); i++)
@ -770,13 +781,13 @@ int CLASS::doBYTE(MerlinLine & line, TSymbol & sym)
{ {
lastcarry = false; lastcarry = false;
} }
else if (sym.opcode==0xFB) // XCE else if (sym.opcode == 0xFB) // XCE
{ {
if (trackrep) if (trackrep)
{ {
if (lastcarry) if (lastcarry)
{ {
mx=0x03; mx = 0x03;
} }
} }
} }

View File

@ -839,6 +839,18 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
a.PC.currentpc = a.PC.orgsave; a.PC.currentpc = a.PC.orgsave;
line.startpc = a.PC.orgsave; line.startpc = a.PC.orgsave;
} }
#if 0
// Merlin32 seems to have a bug where ORG seems like it can only be 16 bits
if ((line.syntax&SYNTAX_MERLIN32)==SYNTAX_MERLIN32)
{
// so clear the bank word in all variables
a.PC.orgsave &= 0xFFFF;
a.PC.currentpc&=0xFFFF;
line.startpc &=0xFFFF;
}
#endif
line.flags |= FLAG_FORCEADDRPRINT; line.flags |= FLAG_FORCEADDRPRINT;
break; break;
case P_SAV: case P_SAV:

View File

@ -4,10 +4,10 @@ logdir=/var/log/mylog
logfile=mylog.log logfile=mylog.log
[option] [option]
debug=1 ;==debug must be an integer. Code can use this as a level
;debug=0
nocolor=false nocolor=false
;syntax=merlin32 ;syntax=merlin32
;debug must be an integer. Code can use this as a level
[application] [application]
timezone=America/Los_Angeles timezone=America/Los_Angeles
@ -33,8 +33,7 @@ merlinerrors=true
symcolumns=3 symcolumns=3
[reformat] [reformat]
tabs=12; 18; 30 tabs=12;18;30
;tabs=0;0;0