mirror of
https://github.com/marketideas/qasm.git
synced 2024-12-26 23:29:22 +00:00
commit
661de97c2c
37
README
37
README
@ -1,29 +1,38 @@
|
||||
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.
|
||||
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
|
||||
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).
|
||||
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.
|
||||
|
||||
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.
|
||||
Merlin32 is great, but there are aspects of it that I don't like (always outputting assembly
|
||||
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
|
||||
based .2MG (or other) images. That way, after a compile, the code under test can be immediately run from a GS emulator.
|
||||
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
|
||||
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.
|
||||
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.
|
||||
|
||||
'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.
|
||||
(in a 'build' directory)
|
||||
'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. (in a 'build' directory)
|
||||
|
||||
For example:
|
||||
mkdir workdir
|
||||
|
70
asm.cpp
70
asm.cpp
@ -205,7 +205,7 @@ void CLASS::print(uint32_t lineno)
|
||||
{
|
||||
pcol += printf(" ");
|
||||
}
|
||||
if (isDebug() > 2)
|
||||
if (isDebug() > 1)
|
||||
{
|
||||
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 '<':
|
||||
line.expr_value &= 0xFF;
|
||||
line.flags |= FLAG_DP;
|
||||
break;
|
||||
case '>':
|
||||
line.expr_value >>= 8;
|
||||
line.expr_value &= 0xFFFF;
|
||||
if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||
{
|
||||
//printf("immediate mode\n");
|
||||
switch (line.expr_shift)
|
||||
{
|
||||
case '<':
|
||||
line.expr_value &= 0xFF;
|
||||
break;
|
||||
case '>':
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
line.expr_value = (line.expr_value >> 16) & 0xFFFF;
|
||||
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;
|
||||
break;
|
||||
case '^':
|
||||
//line.flags |= FLAG_FORCELONG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (line.expr_value >= 0x100)
|
||||
{
|
||||
line.flags |= FLAG_FORCEABS;
|
||||
}
|
||||
|
||||
|
||||
auto itr = opcodes.find(Poco::toUpper(op));
|
||||
if (itr != opcodes.end())
|
||||
{
|
||||
|
37
opcodes.cpp
37
opcodes.cpp
@ -95,17 +95,15 @@ int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
|
||||
{
|
||||
res = -1;
|
||||
|
||||
if (syntax==SYNTAX_MERLIN)
|
||||
{
|
||||
char buff[32];
|
||||
sprintf(buff,"$%08X",line.expr_value);
|
||||
std::string s1=buff;
|
||||
s = addVariable(line.lable, s1, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = addVariable(line.lable, line.operand, true);
|
||||
}
|
||||
#if 1
|
||||
char buff[32];
|
||||
sprintf(buff, "$%08X", line.expr_value);
|
||||
std::string s1 = buff;
|
||||
s = addVariable(line.lable, s1, true);
|
||||
#else
|
||||
// do this if you want to do this more as a #define
|
||||
s = addVariable(line.lable, line.operand, true);
|
||||
#endif
|
||||
if (s != NULL)
|
||||
{
|
||||
res = 0;
|
||||
@ -295,6 +293,19 @@ int CLASS::doAddress(MerlinLine &line, TSymbol &sym)
|
||||
res = 1 + sym.stype;
|
||||
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);
|
||||
setOpcode(line, sym.opcode);
|
||||
for (i = 0; i < (res - 1); i++)
|
||||
@ -770,13 +781,13 @@ int CLASS::doBYTE(MerlinLine & line, TSymbol & sym)
|
||||
{
|
||||
lastcarry = false;
|
||||
}
|
||||
else if (sym.opcode==0xFB) // XCE
|
||||
else if (sym.opcode == 0xFB) // XCE
|
||||
{
|
||||
if (trackrep)
|
||||
{
|
||||
if (lastcarry)
|
||||
{
|
||||
mx=0x03;
|
||||
mx = 0x03;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
psuedo.cpp
12
psuedo.cpp
@ -839,6 +839,18 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||
a.PC.currentpc = 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;
|
||||
break;
|
||||
case P_SAV:
|
||||
|
7
qasm.ini
7
qasm.ini
@ -4,10 +4,10 @@ logdir=/var/log/mylog
|
||||
logfile=mylog.log
|
||||
|
||||
[option]
|
||||
debug=1
|
||||
;==debug must be an integer. Code can use this as a level
|
||||
;debug=0
|
||||
nocolor=false
|
||||
;syntax=merlin32
|
||||
;debug must be an integer. Code can use this as a level
|
||||
|
||||
[application]
|
||||
timezone=America/Los_Angeles
|
||||
@ -33,8 +33,7 @@ merlinerrors=true
|
||||
symcolumns=3
|
||||
|
||||
[reformat]
|
||||
tabs=12; 18; 30
|
||||
;tabs=0;0;0
|
||||
tabs=12;18;30
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user