mirror of http://shamusworld.gotdns.org/git/rmac
Added Jaguar Object Processor assembler.
Rationale for this and how it works can be found in docs/note-on-the-op-assembler.txt. Version now at 1.13.0.
This commit is contained in:
parent
ae528e6fdb
commit
261f8d9198
|
@ -2,6 +2,8 @@
|
||||||
68kgen.o
|
68kgen.o
|
||||||
68ktab.h
|
68ktab.h
|
||||||
68kmn
|
68kmn
|
||||||
|
6502kw.h
|
||||||
|
opkw.h
|
||||||
*.o
|
*.o
|
||||||
*~
|
*~
|
||||||
kwtab.h
|
kwtab.h
|
||||||
|
|
71
direct.c
71
direct.c
|
@ -79,6 +79,7 @@ int d_cstruct(void);
|
||||||
int d_prgflags(void);
|
int d_prgflags(void);
|
||||||
int d_opt(void);
|
int d_opt(void);
|
||||||
int d_dsp(void);
|
int d_dsp(void);
|
||||||
|
int d_objproc(void);
|
||||||
void SetLargestAlignment(int);
|
void SetLargestAlignment(int);
|
||||||
|
|
||||||
// Directive handler table
|
// Directive handler table
|
||||||
|
@ -149,7 +150,8 @@ int (*dirtab[])() = {
|
||||||
d_68882, // 63 .68882
|
d_68882, // 63 .68882
|
||||||
d_56001, // 64 .56001
|
d_56001, // 64 .56001
|
||||||
d_nofpu, // 65 nofpu
|
d_nofpu, // 65 nofpu
|
||||||
d_opt, // 58 .opt
|
d_opt, // 66 .opt
|
||||||
|
d_objproc, // 67 .objproc
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,8 +218,8 @@ int d_org(void)
|
||||||
{
|
{
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
|
|
||||||
if (!rgpu && !rdsp && !m6502)
|
if (!rgpu && !rdsp && !robjproc && !m6502)
|
||||||
return error(".org permitted only in gpu/dsp and 6502 sections");
|
return error(".org permitted only in GPU/DSP/OP and 6502 sections");
|
||||||
|
|
||||||
if (abs_expr(&address) == ERROR)
|
if (abs_expr(&address) == ERROR)
|
||||||
{
|
{
|
||||||
|
@ -225,7 +227,7 @@ int d_org(void)
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rgpu | rdsp)
|
if (rgpu | rdsp | robjproc)
|
||||||
{
|
{
|
||||||
orgaddr = address;
|
orgaddr = address;
|
||||||
orgactive = 1;
|
orgactive = 1;
|
||||||
|
@ -1066,9 +1068,6 @@ int d_dc(WORD siz)
|
||||||
uint16_t tdb = eattr & TDB;
|
uint16_t tdb = eattr & TDB;
|
||||||
uint16_t defined = eattr & DEFINED;
|
uint16_t defined = eattr & DEFINED;
|
||||||
|
|
||||||
if ((challoc - ch_size) < 4)
|
|
||||||
chcheck(4);
|
|
||||||
|
|
||||||
switch (siz)
|
switch (siz)
|
||||||
{
|
{
|
||||||
case SIZB:
|
case SIZB:
|
||||||
|
@ -1136,6 +1135,7 @@ int d_dc(WORD siz)
|
||||||
|
|
||||||
D_long(eval);
|
D_long(eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SIZQ:
|
case SIZQ:
|
||||||
// 64-bit size
|
// 64-bit size
|
||||||
|
@ -1144,7 +1144,17 @@ int d_dc(WORD siz)
|
||||||
|
|
||||||
// Shamus: We only handle DC.Q type stuff, will have to add fixups
|
// Shamus: We only handle DC.Q type stuff, will have to add fixups
|
||||||
// and stuff later (maybe... might not be needed...)
|
// and stuff later (maybe... might not be needed...)
|
||||||
D_quad(eval);
|
// DEFINITELY NEED FIXUPS HERE!
|
||||||
|
if (!defined)
|
||||||
|
{
|
||||||
|
AddFixup(FU_QUAD, sloc, exprbuf);
|
||||||
|
D_quad(0LL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D_quad(eval);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SIZS:
|
case SIZS:
|
||||||
// 32-bit float size
|
// 32-bit float size
|
||||||
|
@ -1158,8 +1168,9 @@ int d_dc(WORD siz)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tdb)
|
//Would this *ever* happen?
|
||||||
MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
|
// if (tdb)
|
||||||
|
// MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
|
||||||
|
|
||||||
PTR ptr;
|
PTR ptr;
|
||||||
ptr.u64 = &eval;
|
ptr.u64 = &eval;
|
||||||
|
@ -1180,8 +1191,9 @@ int d_dc(WORD siz)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tdb)
|
//Would this *ever* happen?
|
||||||
MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
|
// if (tdb)
|
||||||
|
// MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
|
||||||
|
|
||||||
PTR ptr;
|
PTR ptr;
|
||||||
ptr.u64 = &eval;
|
ptr.u64 = &eval;
|
||||||
|
@ -1204,8 +1216,9 @@ int d_dc(WORD siz)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tdb)
|
//Would this *ever* happen?
|
||||||
MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
|
// if (tdb)
|
||||||
|
// MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
|
||||||
|
|
||||||
PTR ptr;
|
PTR ptr;
|
||||||
ptr.u64 = &eval;
|
ptr.u64 = &eval;
|
||||||
|
@ -1483,7 +1496,7 @@ int d_nlist(void)
|
||||||
//
|
//
|
||||||
int d_68000(void)
|
int d_68000(void)
|
||||||
{
|
{
|
||||||
rgpu = rdsp = 0;
|
rgpu = rdsp = robjproc = 0;
|
||||||
// Switching from gpu/dsp sections should reset any ORG'd Address
|
// Switching from gpu/dsp sections should reset any ORG'd Address
|
||||||
orgactive = 0;
|
orgactive = 0;
|
||||||
orgwarning = 0;
|
orgwarning = 0;
|
||||||
|
@ -1601,6 +1614,7 @@ int d_gpu(void)
|
||||||
|
|
||||||
rgpu = 1; // Set GPU assembly
|
rgpu = 1; // Set GPU assembly
|
||||||
rdsp = 0; // Unset DSP assembly
|
rdsp = 0; // Unset DSP assembly
|
||||||
|
robjproc = 0; // Unset OP assembly
|
||||||
regbank = BANK_N; // Set no default register bank
|
regbank = BANK_N; // Set no default register bank
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1626,6 +1640,7 @@ int d_dsp(void)
|
||||||
|
|
||||||
rdsp = 1; // Set DSP assembly
|
rdsp = 1; // Set DSP assembly
|
||||||
rgpu = 0; // Unset GPU assembly
|
rgpu = 0; // Unset GPU assembly
|
||||||
|
robjproc = 0; // Unset OP assembly
|
||||||
regbank = BANK_N; // Set no default register bank
|
regbank = BANK_N; // Set no default register bank
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1876,6 +1891,32 @@ int d_cstruct(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define start of OP object list (allows the use of ORG)
|
||||||
|
//
|
||||||
|
int d_objproc(void)
|
||||||
|
{
|
||||||
|
if ((cursect != TEXT) && (cursect != DATA))
|
||||||
|
{
|
||||||
|
error(".objproc can only be used in the TEXT or DATA segments");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous section was DSP or 68000 then we need to reset ORG'd
|
||||||
|
// Addresses
|
||||||
|
if (!robjproc)
|
||||||
|
{
|
||||||
|
orgactive = 0;
|
||||||
|
orgwarning = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
robjproc = 1; // Set OP assembly
|
||||||
|
rgpu = 0; // Unset GPU assembly
|
||||||
|
rdsp = 0; // Unset DSP assembly
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Undefine a macro - .undefmac macname [, macname...]
|
// Undefine a macro - .undefmac macname [, macname...]
|
||||||
//
|
//
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
A Few Notes on the New Object Processor Assembler
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
Q: What is it?
|
||||||
|
|
||||||
|
A: An assembler to generate object lists for the Atari Jaguar's Object
|
||||||
|
processor.
|
||||||
|
|
||||||
|
|
||||||
|
Q: Why is it here?
|
||||||
|
|
||||||
|
A: To really utilize the OP properly, it needs an assembler. Otherwise, what
|
||||||
|
happens is you end up writing an assembler in your code to assemble the OP
|
||||||
|
list, and that's a real drag--something that *should* be handled by a proper
|
||||||
|
assembler.
|
||||||
|
|
||||||
|
|
||||||
|
Q: How do I use it?
|
||||||
|
|
||||||
|
A: The OP assembler works similarly to the RISC assembler; to enter the OP
|
||||||
|
assembler, you put the .objproc directive in your code (N.B.: like the RISC
|
||||||
|
assembler, it only works in a TEXT or DATA section). From there, you build
|
||||||
|
the OP list how you want it and go from there. A few caveats: you will want
|
||||||
|
to put a .org directive at the top of your list, and labels that you want to
|
||||||
|
be able to address in 68xxx code (for moving from a data section to an
|
||||||
|
address where it will be executed by the OP, for example) should be created
|
||||||
|
in .68xxx mode.
|
||||||
|
|
||||||
|
|
||||||
|
Q: What are the opcodes?
|
||||||
|
|
||||||
|
A: They are bitmap, scbitmap, gpuobj, branch, stop, nop, and jump. nop and jump
|
||||||
|
are psuedo-ops, they are there as a convenience to the coder.
|
||||||
|
|
||||||
|
|
||||||
|
Q: What are the proper forms for these opcodes?
|
||||||
|
|
||||||
|
A: They are as follows:
|
||||||
|
|
||||||
|
bitmap <data addr>, <xloc>, <yloc>, <dwidth>, <iwidth>, <iheight>, <bpp>,
|
||||||
|
<pallete idx>, <flags>, <firstpix>, <pitch>
|
||||||
|
scbitmap <data addr>, <xloc>, <yloc>, <dwidth>, <iwidth>, <iheight>,
|
||||||
|
<xscale>, <yscale>, <remainder>, <bpp>, <pallete idx>,
|
||||||
|
<flags>, <firstpix>, <pitch>
|
||||||
|
gpuobj <line #>, <userdata> (bits 14-63 of this object)
|
||||||
|
branch VC <condition (<, =, >)> <line #>, <link addr>
|
||||||
|
branch OPFLAG, <link addr>
|
||||||
|
branch SECHALF, <link addr>
|
||||||
|
stop
|
||||||
|
nop
|
||||||
|
jump <link addr>
|
||||||
|
|
||||||
|
Note that the <flags> field in bitmap and scbitmap objects consist of the
|
||||||
|
following: REFLECT, RMW, TRANS, RELEASE. They can be in any order (and
|
||||||
|
should be separated by whitespace *only*), and you can only put a maximum of
|
||||||
|
four of them in. Further note that with bitmap and scbitmap objects, all the
|
||||||
|
parameters after <data addr> are optional--if they are omitted, they will
|
||||||
|
use defaults (mostly 0, but 1 is the default for pitch). Also, in the
|
||||||
|
scbitmap object, the <xscale>, <yscale>, and <remainder> fields can be
|
||||||
|
floating point constants/expressions. <data addr> can refer to any address
|
||||||
|
defined (even external!) and the linker (rln v1.6.0 or greater) will
|
||||||
|
properly fix up the address.
|
||||||
|
|
||||||
|
|
||||||
|
Q: What do they do?
|
||||||
|
|
||||||
|
A: Pretty much what you expect. It's beyond the scope of this little note to
|
||||||
|
explain the Jaguar's Object Processor and how it operates, so you'll have to
|
||||||
|
seek explanations for how they work elsewhere.
|
||||||
|
|
||||||
|
|
||||||
|
Q: Why do I want to put a .org directive at the top of my list?
|
||||||
|
|
||||||
|
A: You want to put a .org directive at the top of your list because otherwise
|
||||||
|
the assembler will not know where in memory the object list is supposed
|
||||||
|
go--then when you move it to its destination, the object link addresses will
|
||||||
|
all be wrong and it won't work.
|
||||||
|
|
||||||
|
|
||||||
|
Q: Why would I copy my object list to another memory location?
|
||||||
|
|
||||||
|
A: Simple: because the OP destroys the list as it uses it to render the screen.
|
||||||
|
If you don't keep a fresh copy stashed away somewhere to refresh it before
|
||||||
|
the next frame is rendered, what you see on the screen will not be what you
|
||||||
|
expect, as the OP has scribbled all over it!
|
||||||
|
|
||||||
|
|
||||||
|
Q: Does the assembler do anything behind my back?
|
||||||
|
|
||||||
|
A: Yes, it will emit NOPs to ensure that bitmaps and scbitmaps are on proper
|
||||||
|
memory boundaries, and fixup link addresses as necessary. This is needed
|
||||||
|
because of a quirk in how the OP works (it ORs constants on the address
|
||||||
|
lines to get the phrases it needs and if they are not zeroes, it will fail
|
||||||
|
in bizarre ways).
|
||||||
|
|
||||||
|
|
||||||
|
Q: Why can't I define the link addresses for all the objects?
|
||||||
|
|
||||||
|
A: You really, *really* don't want to do this. Trust me on this one.
|
||||||
|
|
||||||
|
|
||||||
|
Q: How about an example of an object list?
|
||||||
|
|
||||||
|
A: Here you go:
|
||||||
|
|
||||||
|
objList = $10000
|
||||||
|
bRam = $20000
|
||||||
|
;
|
||||||
|
.68000
|
||||||
|
objects: ; This is the label you will use to address this in 68K code
|
||||||
|
.objproc ; Engage the OP assembler
|
||||||
|
.org objList ; Tell the OP assembler where the list will execute
|
||||||
|
;
|
||||||
|
branch VC < 69, .stahp ; Branch to the STOP object if VC < 69
|
||||||
|
branch VC > 241, .stahp ; Branch to the STOP object if VC > 241
|
||||||
|
bitmap bRAM, 22, 70, 24, 24, 22, 4
|
||||||
|
bitmap bRAM, 20+96+96, 70, 24, 24, 22, 4, 0, REFLECT
|
||||||
|
scbitmap tms, 20, 70, 1, 1, 8, 3.0, 3.0, 2.9999, 0, 0, TRANS
|
||||||
|
scbitmap tmsShadow, 23, 73, 1, 1, 8, 3.0, 3.0, 2.9999, 0, 3, TRANS
|
||||||
|
bitmap sbRelBM, 30, 108, 3, 3, 8, 0, 1, TRANS
|
||||||
|
bitmap txt1BM, 46, 132, 3, 3, 8, 0, 2, TRANS
|
||||||
|
bitmap txt2BM, 46, 148, 3, 3, 8, 0, 2, TRANS
|
||||||
|
bitmap txt3BM, 22, 164, 3, 3, 8, 0, 2, TRANS
|
||||||
|
jump .haha
|
||||||
|
.stahp:
|
||||||
|
stop
|
||||||
|
.haha:
|
||||||
|
jump .stahp
|
||||||
|
|
15
eagen0.c
15
eagen0.c
|
@ -214,8 +214,9 @@ int eaNgen(WORD siz)
|
||||||
// 68881/68882/68040 only
|
// 68881/68882/68040 only
|
||||||
if (w)
|
if (w)
|
||||||
{
|
{
|
||||||
if (tdb)
|
//Would a floating point value *ever* need to be fixed up as if it were an address? :-P
|
||||||
MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
|
// if (tdb)
|
||||||
|
// MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
|
||||||
|
|
||||||
// The value passed back from expr() is an internal C double;
|
// The value passed back from expr() is an internal C double;
|
||||||
// so we have to access it as such then convert it to an
|
// so we have to access it as such then convert it to an
|
||||||
|
@ -238,8 +239,9 @@ int eaNgen(WORD siz)
|
||||||
// 68881/68882/68040 only
|
// 68881/68882/68040 only
|
||||||
if (w)
|
if (w)
|
||||||
{
|
{
|
||||||
if (tdb)
|
//Would a floating point value *ever* need to be fixed up as if it were an address? :-P
|
||||||
MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
|
// if (tdb)
|
||||||
|
// MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
|
||||||
|
|
||||||
PTR p;
|
PTR p;
|
||||||
p.u64 = &aNexval;
|
p.u64 = &aNexval;
|
||||||
|
@ -258,8 +260,9 @@ int eaNgen(WORD siz)
|
||||||
// 68881/68882/68040 only
|
// 68881/68882/68040 only
|
||||||
if (w)
|
if (w)
|
||||||
{
|
{
|
||||||
if (tdb)
|
//Would a floating point value *ever* need to be fixed up as if it were an address? :-P
|
||||||
MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
|
// if (tdb)
|
||||||
|
// MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
|
||||||
|
|
||||||
PTR p;
|
PTR p;
|
||||||
p.u64 = &aNexval;
|
p.u64 = &aNexval;
|
||||||
|
|
23
fltpoint.c
23
fltpoint.c
|
@ -14,6 +14,7 @@
|
||||||
#include "fltpoint.h"
|
#include "fltpoint.h"
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check for IEEE-754 conformance (C99 compilers should be OK here)
|
// Check for IEEE-754 conformance (C99 compilers should be OK here)
|
||||||
|
@ -169,3 +170,25 @@ void DoubleToExtended(double d, uint8_t out[])
|
||||||
out[11] = intMant & 0xFF;
|
out[11] = intMant & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert a host native floating point number to a fixed point number.
|
||||||
|
//
|
||||||
|
uint64_t DoubleToFixedPoint(double d, int intBits, int fracBits)
|
||||||
|
{
|
||||||
|
uint8_t signBit = (signbit(d) ? 1 : 0);
|
||||||
|
|
||||||
|
// Ensure what we're working on is positive...
|
||||||
|
if (d < 0)
|
||||||
|
d *= -1;
|
||||||
|
|
||||||
|
double scaleFactor = (double)(1 << fracBits);
|
||||||
|
uint64_t result = (uint64_t)(d * scaleFactor);
|
||||||
|
|
||||||
|
// Invert the result, if necessary
|
||||||
|
if (signBit == 1)
|
||||||
|
result = (result = 0xFFFFFFFFFFFFFFFFLL) + 1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
//
|
//
|
||||||
// Cross-platform floating point handling
|
// Cross-platform floating point handling (fixed point handling too!)
|
||||||
//
|
//
|
||||||
// by James Hammons
|
// by James Hammons
|
||||||
// (C) 2018 Underground Software
|
// (C) 2018 Underground Software
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef __FLTPOINT_H__
|
||||||
|
#define __FLTPOINT_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
uint32_t FloatToIEEE754(float f);
|
uint32_t FloatToIEEE754(float f);
|
||||||
uint64_t DoubleToIEEE754(double d);
|
uint64_t DoubleToIEEE754(double d);
|
||||||
void DoubleToExtended(double d, uint8_t out[]);
|
void DoubleToExtended(double d, uint8_t out[]);
|
||||||
|
|
||||||
|
uint64_t DoubleToFixedPoint(double d, int intBits, int fracBits);
|
||||||
|
|
||||||
|
#endif // __FLTPOINT_H__
|
||||||
|
|
||||||
|
|
67
makefile
67
makefile
|
@ -27,15 +27,15 @@ HOSTCC = gcc
|
||||||
#CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2 -MMD
|
#CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2 -MMD
|
||||||
CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2
|
CFLAGS = -std=$(STD) -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2
|
||||||
|
|
||||||
SRCS = 6502.c amode.c debug.c direct.c eagen.c error.c expr.c fltpoint.c listing.c mach.c macro.c mark.c object.c procln.c riscasm.c rmac.c sect.c symbol.c token.c
|
SRCS = 6502.c amode.c debug.c direct.c eagen.c error.c expr.c fltpoint.c listing.c mach.c macro.c mark.c object.c op.c procln.c riscasm.c rmac.c sect.c symbol.c token.c
|
||||||
|
|
||||||
OBJS = 6502.o amode.o debug.o direct.o eagen.o error.o expr.o fltpoint.o listing.o mach.o macro.o mark.o object.o procln.o riscasm.o rmac.o sect.o symbol.o token.o
|
OBJS = 6502.o amode.o debug.o direct.o eagen.o error.o expr.o fltpoint.o listing.o mach.o macro.o mark.o object.o op.o procln.o riscasm.o rmac.o sect.o symbol.o token.o
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build everything
|
# Build everything
|
||||||
#
|
#
|
||||||
|
|
||||||
all : mntab.h 68ktab.h kwtab.h risckw.h 6502kw.h rmac
|
all : mntab.h 68ktab.h kwtab.h risckw.h 6502kw.h opkw.h rmac
|
||||||
@echo
|
@echo
|
||||||
@echo "Don't forget to bump the version number before commiting!"
|
@echo "Don't forget to bump the version number before commiting!"
|
||||||
@echo
|
@echo
|
||||||
|
@ -61,6 +61,9 @@ kwtab.h : kwtab kwgen
|
||||||
risckw.h : kwtab kwgen
|
risckw.h : kwtab kwgen
|
||||||
./kwgen mr <risctab >risckw.h
|
./kwgen mr <risctab >risckw.h
|
||||||
|
|
||||||
|
opkw.h : op.tab kwgen
|
||||||
|
./kwgen mo <op.tab >opkw.h
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build tools
|
# Build tools
|
||||||
#
|
#
|
||||||
|
@ -120,6 +123,9 @@ mark.o : mark.c mark.h
|
||||||
object.o : object.c object.h
|
object.o : object.c object.h
|
||||||
$(CC) $(CFLAGS) -c object.c
|
$(CC) $(CFLAGS) -c object.c
|
||||||
|
|
||||||
|
op.o : op.c op.h
|
||||||
|
$(CC) $(CFLAGS) -c op.c
|
||||||
|
|
||||||
procln.o : procln.c procln.h
|
procln.o : procln.c procln.h
|
||||||
$(CC) $(CFLAGS) -c procln.c
|
$(CC) $(CFLAGS) -c procln.c
|
||||||
|
|
||||||
|
@ -151,41 +157,44 @@ clean:
|
||||||
#
|
#
|
||||||
# Dependencies
|
# Dependencies
|
||||||
#
|
#
|
||||||
6502.o: 6502.c direct.h rmac.h symbol.h expr.h error.h mach.h procln.h \
|
6502.o: 6502.c direct.h rmac.h symbol.h token.h expr.h error.h mach.h \
|
||||||
token.h riscasm.h sect.h
|
procln.h riscasm.h sect.h
|
||||||
68kgen.o: 68kgen.c
|
68kgen.o: 68kgen.c
|
||||||
amode.o: amode.c amode.h rmac.h symbol.h error.h expr.h mach.h procln.h \
|
amode.o: amode.c amode.h rmac.h symbol.h error.h expr.h mach.h procln.h \
|
||||||
token.h sect.h kwtab.h mntab.h parmode.h
|
token.h sect.h kwtab.h mntab.h parmode.h
|
||||||
debug.o: debug.c debug.h rmac.h symbol.h amode.h direct.h mark.h sect.h \
|
debug.o: debug.c debug.h rmac.h symbol.h amode.h direct.h token.h expr.h \
|
||||||
token.h
|
mark.h sect.h
|
||||||
direct.o: direct.c direct.h rmac.h symbol.h 6502.h amode.h error.h expr.h \
|
direct.o: direct.c direct.h rmac.h symbol.h token.h 6502.h amode.h \
|
||||||
listing.h mach.h macro.h mark.h procln.h token.h riscasm.h sect.h \
|
error.h expr.h fltpoint.h listing.h mach.h macro.h mark.h procln.h \
|
||||||
kwtab.h fltpoint.h
|
riscasm.h sect.h kwtab.h
|
||||||
eagen.o: eagen.c eagen.h rmac.h symbol.h amode.h sect.h mark.h error.h \
|
eagen.o: eagen.c eagen.h rmac.h symbol.h amode.h error.h fltpoint.h \
|
||||||
mach.h riscasm.h eagen0.c fltpoint.h
|
mach.h mark.h riscasm.h sect.h token.h eagen0.c
|
||||||
error.o: error.c error.h rmac.h symbol.h token.h listing.h
|
error.o: error.c error.h rmac.h symbol.h listing.h token.h
|
||||||
expr.o: expr.c expr.h rmac.h symbol.h direct.h error.h listing.h mach.h \
|
expr.o: expr.c expr.h rmac.h symbol.h direct.h token.h error.h listing.h \
|
||||||
procln.h token.h riscasm.h sect.h kwtab.h
|
mach.h procln.h riscasm.h sect.h kwtab.h
|
||||||
|
fltpoint.o: fltpoint.c fltpoint.h
|
||||||
kwgen.o: kwgen.c
|
kwgen.o: kwgen.c
|
||||||
listing.o: listing.c listing.h rmac.h symbol.h error.h procln.h token.h \
|
listing.o: listing.c listing.h rmac.h symbol.h error.h procln.h token.h \
|
||||||
sect.h version.h
|
sect.h version.h
|
||||||
mach.o: mach.c mach.h rmac.h symbol.h amode.h direct.h eagen.h error.h \
|
mach.o: mach.c mach.h rmac.h symbol.h amode.h direct.h token.h eagen.h \
|
||||||
procln.h token.h riscasm.h sect.h kwtab.h 68ktab.h
|
error.h expr.h procln.h riscasm.h sect.h kwtab.h 68ktab.h
|
||||||
macro.o: macro.c macro.h rmac.h symbol.h debug.h direct.h error.h expr.h \
|
macro.o: macro.c macro.h rmac.h symbol.h debug.h direct.h token.h error.h \
|
||||||
listing.h procln.h token.h
|
expr.h listing.h procln.h
|
||||||
mark.o: mark.c mark.h rmac.h symbol.h error.h object.h riscasm.h sect.h
|
mark.o: mark.c mark.h rmac.h symbol.h error.h object.h riscasm.h sect.h
|
||||||
object.o: object.c object.h rmac.h symbol.h 6502.h error.h mark.h \
|
object.o: object.c object.h rmac.h symbol.h 6502.h direct.h token.h \
|
||||||
riscasm.h sect.h
|
error.h mark.h riscasm.h sect.h
|
||||||
|
op.o: op.c op.h rmac.h symbol.h direct.h token.h error.h expr.h \
|
||||||
|
fltpoint.h mark.h procln.h riscasm.h sect.h
|
||||||
procln.o: procln.c procln.h rmac.h symbol.h token.h 6502.h amode.h \
|
procln.o: procln.c procln.h rmac.h symbol.h token.h 6502.h amode.h \
|
||||||
direct.h error.h expr.h listing.h mach.h macro.h riscasm.h sect.h \
|
direct.h error.h expr.h listing.h mach.h macro.h op.h riscasm.h sect.h \
|
||||||
kwtab.h mntab.h risckw.h 6502kw.h
|
kwtab.h mntab.h risckw.h 6502kw.h opkw.h
|
||||||
riscasm.o: riscasm.c riscasm.h rmac.h symbol.h amode.h direct.h error.h \
|
riscasm.o: riscasm.c riscasm.h rmac.h symbol.h amode.h direct.h token.h \
|
||||||
expr.h mark.h procln.h token.h sect.h risckw.h kwtab.h
|
error.h expr.h mark.h procln.h sect.h risckw.h kwtab.h
|
||||||
rmac.o: rmac.c rmac.h symbol.h 6502.h debug.h direct.h error.h expr.h \
|
rmac.o: rmac.c rmac.h symbol.h 6502.h debug.h direct.h token.h error.h \
|
||||||
listing.h mark.h macro.h object.h procln.h token.h riscasm.h sect.h \
|
expr.h listing.h mark.h macro.h object.h procln.h riscasm.h sect.h \
|
||||||
version.h
|
version.h
|
||||||
sect.o: sect.c sect.h rmac.h symbol.h 6502.h direct.h error.h expr.h \
|
sect.o: sect.c sect.h rmac.h symbol.h 6502.h direct.h token.h error.h \
|
||||||
listing.h mach.h mark.h riscasm.h token.h
|
expr.h listing.h mach.h mark.h riscasm.h
|
||||||
symbol.o: symbol.c symbol.h error.h rmac.h listing.h object.h procln.h \
|
symbol.o: symbol.c symbol.h error.h rmac.h listing.h object.h procln.h \
|
||||||
token.h
|
token.h
|
||||||
token.o: token.c token.h rmac.h symbol.h direct.h error.h macro.h \
|
token.o: token.c token.h rmac.h symbol.h direct.h error.h macro.h \
|
||||||
|
|
38
mark.c
38
mark.c
|
@ -71,9 +71,9 @@ void StopMark(void)
|
||||||
uint32_t MarkRelocatable(uint16_t section, uint32_t loc, uint16_t to, uint16_t flags, SYM * symbol)
|
uint32_t MarkRelocatable(uint16_t section, uint32_t loc, uint16_t to, uint16_t flags, SYM * symbol)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_IMAGE_MARKING
|
#ifdef DEBUG_IMAGE_MARKING
|
||||||
printf("MarkRelocatable: section=%i, loc=$%X, to=$%X, flags=$%x, symbol=$%X\n", section, loc, to, flags, symbol);
|
printf("MarkRelocatable: section=%i, loc=$%X, to=$%X, flags=$%x, symbol=%p\n", section, loc, to, flags, symbol);
|
||||||
if (symbol)
|
if (symbol)
|
||||||
printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
|
printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%li, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((mcalloc - mcused) < MIN_MARK_MEM)
|
if ((mcalloc - mcused) < MIN_MARK_MEM)
|
||||||
|
@ -380,9 +380,13 @@ printf(" validsegment: raddr = $%08X\n", loc);
|
||||||
// This tells the linker to do a WORD relocation (otherwise it
|
// This tells the linker to do a WORD relocation (otherwise it
|
||||||
// defaults to doing a LONG, throwing things off for WORD sized
|
// defaults to doing a LONG, throwing things off for WORD sized
|
||||||
// fixups)
|
// fixups)
|
||||||
if (!(w & MLONG))
|
if (!(w & (MLONG | MQUAD)))
|
||||||
rflag |= 0x00000002;
|
rflag |= 0x00000002;
|
||||||
|
|
||||||
|
// Tell the linker that the fixup is an OL QUAD data address
|
||||||
|
if (w & MQUAD)
|
||||||
|
rflag |= 0x00000004;
|
||||||
|
|
||||||
if (symbol != NULL)
|
if (symbol != NULL)
|
||||||
{
|
{
|
||||||
// Deposit external reference
|
// Deposit external reference
|
||||||
|
@ -415,19 +419,31 @@ printf(" validsegment(3): rflag = $%08X\n", rflag);
|
||||||
if (w & (DATA | BSS))
|
if (w & (DATA | BSS))
|
||||||
{
|
{
|
||||||
uint8_t * dp = objImage + BSDHDRSIZE + loc;
|
uint8_t * dp = objImage + BSDHDRSIZE + loc;
|
||||||
|
uint32_t olBitsSave = 0;
|
||||||
|
|
||||||
// Bump the start of the section if it's DATA (& not TEXT)
|
// Bump the start of the section if it's DATA (& not TEXT)
|
||||||
if (from == DATA)
|
if (from == DATA)
|
||||||
dp += tsize;
|
dp += tsize;
|
||||||
|
|
||||||
uint32_t diff = (rflag & 0x02 ? GETBE16(dp, 0) : GETBE32(dp, 0));
|
uint32_t diff = (rflag & 0x02 ? GETBE16(dp, 0) : GETBE32(dp, 0));
|
||||||
|
|
||||||
|
// Special handling for OP (data addr) relocation...
|
||||||
|
if (rflag & 0x04)
|
||||||
|
{
|
||||||
|
olBitsSave = diff & 0x7FF;
|
||||||
|
diff = (diff & 0xFFFFF800) >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG printf("diff=%uX ==> ", diff);
|
DEBUG printf("diff=%uX ==> ", diff);
|
||||||
#ifdef DEBUG_IMAGE_MARKING
|
#ifdef DEBUG_IMAGE_MARKING
|
||||||
printf(" validsegment(4): diff = $%08X --> ", diff);
|
printf(" validsegment(4): diff = $%08X ", diff);
|
||||||
#endif
|
#endif
|
||||||
if (rflag & 0x01)
|
if (rflag & 0x01)
|
||||||
diff = WORDSWAP32(diff);
|
diff = WORDSWAP32(diff);
|
||||||
|
|
||||||
|
#ifdef DEBUG_IMAGE_MARKING
|
||||||
|
printf("(sect[TEXT].sloc=$%X) --> ", sect[TEXT].sloc);
|
||||||
|
#endif
|
||||||
diff += sect[TEXT].sloc;
|
diff += sect[TEXT].sloc;
|
||||||
|
|
||||||
if (w == BSS)
|
if (w == BSS)
|
||||||
|
@ -442,11 +458,21 @@ printf(" validsegment(4): diff = $%08X --> ", diff);
|
||||||
// thus leaving a naked semicolon afterwards to
|
// thus leaving a naked semicolon afterwards to
|
||||||
// screw up the if/else structure. This is the price
|
// screw up the if/else structure. This is the price
|
||||||
// you pay when using macros pretending to be code.
|
// you pay when using macros pretending to be code.
|
||||||
if (rflag & 0x02)
|
if (rflag & 0x02) // WORD relocation
|
||||||
{
|
{
|
||||||
SETBE16(dp, 0, diff);
|
SETBE16(dp, 0, diff);
|
||||||
}
|
}
|
||||||
else
|
else if (rflag & 0x04) // OP data address relocation
|
||||||
|
{
|
||||||
|
// We do it this way because we might have an offset
|
||||||
|
// that is not a multiple of 8 and thus we need this in
|
||||||
|
// place to prevent a bad address at link time. :-P As
|
||||||
|
// a consequence of this, the highest address we can
|
||||||
|
// have here is $1FFFF8.
|
||||||
|
diff = ((diff & 0x001FFFFF) << 11) | olBitsSave;
|
||||||
|
SETBE32(dp, 0, diff);
|
||||||
|
}
|
||||||
|
else // LONG relocation
|
||||||
{
|
{
|
||||||
SETBE32(dp, 0, diff);
|
SETBE32(dp, 0, diff);
|
||||||
}
|
}
|
||||||
|
|
7
mark.h
7
mark.h
|
@ -26,14 +26,15 @@ MCHUNK {
|
||||||
|
|
||||||
#define MWORD 0x0000 // Marked word
|
#define MWORD 0x0000 // Marked word
|
||||||
#define MLONG 0x0100 // Marked long
|
#define MLONG 0x0100 // Marked long
|
||||||
|
#define MQUAD 0x0400 // Marked quad
|
||||||
//This will have to be defined eventually. Might have to overhaul the mark
|
//This will have to be defined eventually. Might have to overhaul the mark
|
||||||
//system as 8-bits doesn't seem to be enough, at least for a bitfield (which it
|
//system as 8-bits doesn't seem to be enough, at least for a bitfield (which it
|
||||||
//might not have to be, in which case it would be big enough...)
|
//might not have to be, in which case it would be big enough...)
|
||||||
//#define MQUAD 0x // Marked quad word (TODO: merge with MDOUBLE?)
|
//#define MQUAD 0x // Marked quad word (TODO: merge with MDOUBLE?)
|
||||||
#define MMOVEI 0x0200 // Mark RISC MOVEI instruction
|
#define MMOVEI 0x0200 // Mark RISC MOVEI instruction
|
||||||
#define MDOUBLE 0x0400 // Marked double float
|
//#define MDOUBLE 0x0400 // Marked double float
|
||||||
#define MEXTEND 0x0800 // Marked extended float
|
//#define MEXTEND 0x0800 // Marked extended float
|
||||||
#define MSINGLE 0x0880 // Marked single float (TODO: merge with MLONG?)
|
//#define MSINGLE 0x0880 // Marked single float (TODO: merge with MLONG?)
|
||||||
#define MGLOBAL 0x0800 // Mark contains global
|
#define MGLOBAL 0x0800 // Mark contains global
|
||||||
#define MPCREL 0x1000 // Mark is PC-relative
|
#define MPCREL 0x1000 // Mark is PC-relative
|
||||||
#define MCHEND 0x2000 // Indicates end of mark chunk
|
#define MCHEND 0x2000 // Indicates end of mark chunk
|
||||||
|
|
8
mntab
8
mntab
|
@ -110,9 +110,10 @@ prgflags 57
|
||||||
nofpu 65
|
nofpu 65
|
||||||
.opt 66
|
.opt 66
|
||||||
opt 66
|
opt 66
|
||||||
|
.objproc 67
|
||||||
|
|
||||||
.if 500
|
.if 500
|
||||||
if 500
|
if 500
|
||||||
.else 501
|
.else 501
|
||||||
else 501
|
else 501
|
||||||
.endc 502
|
.endc 502
|
||||||
|
@ -120,7 +121,7 @@ endc 502
|
||||||
.endif 502
|
.endif 502
|
||||||
endif 502
|
endif 502
|
||||||
.iif 503
|
.iif 503
|
||||||
iif 503
|
iif 503
|
||||||
.macro 504
|
.macro 504
|
||||||
macro 504
|
macro 504
|
||||||
.endm 505
|
.endm 505
|
||||||
|
@ -131,3 +132,4 @@ rept 506
|
||||||
endr 507
|
endr 507
|
||||||
.exitm 510
|
.exitm 510
|
||||||
exitm 510
|
exitm 510
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,487 @@
|
||||||
|
//
|
||||||
|
// Jaguar Object Processor assembler
|
||||||
|
//
|
||||||
|
// by James Hammons
|
||||||
|
// (C) 2018 Underground Software
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "op.h"
|
||||||
|
#include "direct.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "expr.h"
|
||||||
|
#include "fltpoint.h"
|
||||||
|
#include "mark.h"
|
||||||
|
#include "procln.h"
|
||||||
|
#include "riscasm.h"
|
||||||
|
#include "rmac.h"
|
||||||
|
#include "sect.h"
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
// Macros to help define things (though largely unnecessary for this assembler)
|
||||||
|
#define BITMAP 3100
|
||||||
|
#define SCBITMAP 3101
|
||||||
|
#define GPUOBJ 3102
|
||||||
|
#define BRANCH 3103
|
||||||
|
#define STOP 3104
|
||||||
|
#define NOP 3105
|
||||||
|
#define JUMP 3106
|
||||||
|
|
||||||
|
// Function prototypes
|
||||||
|
int HandleBitmap(void);
|
||||||
|
int HandleScaledBitmap(void);
|
||||||
|
int HandleGPUObject(void);
|
||||||
|
int HandleBranch(void);
|
||||||
|
int HandleStop(void);
|
||||||
|
int HandleNOP(void);
|
||||||
|
int HandleJump(void);
|
||||||
|
|
||||||
|
// OP assembler vars.
|
||||||
|
static uint8_t lastObjType;
|
||||||
|
static uint32_t lastSloc;
|
||||||
|
static char scratchbuf[4096];
|
||||||
|
static TOKEN fixupExpr[4] = { CONST, 0, 0, ENDEXPR };
|
||||||
|
//static PTR fixupPtr = { .tk = (fixupExpr + 1) }; // C99 \o/
|
||||||
|
static PTR fixupPtr = { (uint8_t *)(fixupExpr + 1) }; // meh, it works
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// The main Object Processor assembler. Basically just calls the sub functions
|
||||||
|
// to generate the appropriate code.
|
||||||
|
//
|
||||||
|
int GenerateOPCode(int state)
|
||||||
|
{
|
||||||
|
if (!robjproc)
|
||||||
|
return error("opcode only valid in OP mode");
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case BITMAP:
|
||||||
|
return HandleBitmap();
|
||||||
|
case SCBITMAP:
|
||||||
|
return HandleScaledBitmap();
|
||||||
|
case GPUOBJ:
|
||||||
|
return HandleGPUObject();
|
||||||
|
case BRANCH:
|
||||||
|
return HandleBranch();
|
||||||
|
case STOP:
|
||||||
|
return HandleStop();
|
||||||
|
case NOP:
|
||||||
|
return HandleNOP();
|
||||||
|
case JUMP:
|
||||||
|
return HandleJump();
|
||||||
|
}
|
||||||
|
|
||||||
|
return error("unknown OP opcode");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void GetSymbolUCFromTokenStream(char * s)
|
||||||
|
{
|
||||||
|
strcpy(s, string[tok[1]]);
|
||||||
|
strtoupper(s);
|
||||||
|
tok += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint64_t CheckFlags(char * s)
|
||||||
|
{
|
||||||
|
GetSymbolUCFromTokenStream(s);
|
||||||
|
|
||||||
|
if (strcmp(scratchbuf, "REFLECT") == 0)
|
||||||
|
return 0x01;
|
||||||
|
else if (strcmp(scratchbuf, "RMW") == 0)
|
||||||
|
return 0x02;
|
||||||
|
else if (strcmp(scratchbuf, "TRANS") == 0)
|
||||||
|
return 0x04;
|
||||||
|
else if (strcmp(scratchbuf, "RELEASE") == 0)
|
||||||
|
return 0x08;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define a bitmap object
|
||||||
|
// Form: bitmap <data>, <xloc>, <yloc>, <dwidth>, <iwidth>, <iheight>, <bpp>,
|
||||||
|
// <pallete idx>, <flags>, <firstpix>, <pitch>
|
||||||
|
//
|
||||||
|
int HandleBitmap(void)
|
||||||
|
{
|
||||||
|
uint64_t xpos = 0;
|
||||||
|
uint64_t ypos = 0;
|
||||||
|
uint64_t iheight = 0;
|
||||||
|
uint64_t dwidth = 0;
|
||||||
|
uint64_t iwidth = 0;
|
||||||
|
uint64_t bpp = 0;
|
||||||
|
uint64_t index = 0;
|
||||||
|
uint64_t flags = 0;
|
||||||
|
uint64_t firstpix = 0;
|
||||||
|
uint64_t pitch = 1;
|
||||||
|
|
||||||
|
uint64_t eval;
|
||||||
|
uint16_t eattr;
|
||||||
|
SYM * esym = 0;
|
||||||
|
|
||||||
|
if ((orgaddr & 0x0F) != 0)
|
||||||
|
{
|
||||||
|
warn("bitmap not on double phrase boundary");
|
||||||
|
|
||||||
|
// Fixup org address (by emitting a NOP)...
|
||||||
|
HandleNOP();
|
||||||
|
|
||||||
|
// We don't need to do a fixup here, because we're guaranteed that the
|
||||||
|
// last object, if it was a scaled bitmap *or* regular bitmap, will
|
||||||
|
// already be on the correct boundary, so we won't have to fix it up.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
AddFixup(FU_QUAD | FU_OBJDATA, sloc, exprbuf);
|
||||||
|
else if (eattr & TDB)
|
||||||
|
MarkRelocatable(cursect, sloc, (eattr & TDB), MQUAD, NULL);
|
||||||
|
|
||||||
|
uint64_t dataAddr = eval & 0xFFFFF8;
|
||||||
|
uint64_t linkAddr = (orgaddr + 16) & 0x3FFFF8;
|
||||||
|
|
||||||
|
uint64_t * vars[10] = { &xpos, &ypos, &dwidth, &iwidth, &iheight, &bpp, &index, 0, &firstpix, &pitch };
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
// If there are less than 10 arguments after the data address, use
|
||||||
|
// defaults for the rest of them
|
||||||
|
// N.B.: Should there be a default minimum # of args? Like the first 5?
|
||||||
|
if (tok[0] == EOL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CHECK_COMMA;
|
||||||
|
|
||||||
|
if (i != 7)
|
||||||
|
{
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
return error("bad expression");
|
||||||
|
|
||||||
|
*vars[i] = eval;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle FLAGs. Can have at most four.
|
||||||
|
for(int j=0; j<4; j++)
|
||||||
|
{
|
||||||
|
if (tok[0] != SYMBOL)
|
||||||
|
return error("missing REFLECT, RMW, TRANS, and/or RELEASE");
|
||||||
|
|
||||||
|
flags |= CheckFlags(scratchbuf);
|
||||||
|
|
||||||
|
// Break out if no more symbols...
|
||||||
|
if (tok[0] != SYMBOL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
at_eol();
|
||||||
|
|
||||||
|
uint64_t p1 = 0x00 | ((ypos * 2) << 3) | (iheight << 14) | (linkAddr << 21) | (dataAddr << 40);
|
||||||
|
uint64_t p2 = xpos | (bpp << 12) | (pitch << 15) | (dwidth << 18) | (iwidth << 28) | (index << 38) | (flags << 45) | (firstpix << 49);
|
||||||
|
|
||||||
|
lastSloc = sloc;
|
||||||
|
lastObjType = 0;
|
||||||
|
D_quad(p1);
|
||||||
|
D_quad(p2);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define a scaled bitmap object
|
||||||
|
// Form: scbitmap <data>, <xloc>, <yloc>, <dwidth>, <iwidth>, <iheight>,
|
||||||
|
// <xscale>, <yscale>, <remainder>, <bpp>, <pallete idx>,
|
||||||
|
// <flags>, <firstpix>, <pitch>
|
||||||
|
//
|
||||||
|
int HandleScaledBitmap(void)
|
||||||
|
{
|
||||||
|
uint64_t xpos = 0;
|
||||||
|
uint64_t ypos = 0;
|
||||||
|
uint64_t iheight = 0;
|
||||||
|
uint64_t dwidth = 0;
|
||||||
|
uint64_t iwidth = 0;
|
||||||
|
uint64_t bpp = 0;
|
||||||
|
uint64_t index = 0;
|
||||||
|
uint64_t flags = 0;
|
||||||
|
uint64_t firstpix = 0;
|
||||||
|
uint64_t pitch = 1;
|
||||||
|
uint64_t xscale = 0;
|
||||||
|
uint64_t yscale = 0;
|
||||||
|
uint64_t remainder = 0;
|
||||||
|
|
||||||
|
uint64_t eval;
|
||||||
|
uint16_t eattr;
|
||||||
|
SYM * esym = 0;
|
||||||
|
|
||||||
|
if ((orgaddr & 0x1F) != 0)
|
||||||
|
{
|
||||||
|
warn("scaled bitmap not on quad phrase boundary");
|
||||||
|
|
||||||
|
// We only have to do a fixup here if the previous object was a bitmap,
|
||||||
|
// as it can live on a 16-byte boundary while scaled bitmaps can't. If
|
||||||
|
// the previous object was a scaled bitmap, it is guaranteed to have
|
||||||
|
// been aligned, therefore no fixup is necessary.
|
||||||
|
if (lastObjType == 0)
|
||||||
|
{
|
||||||
|
*fixupPtr.u64 = (orgaddr + 0x18) & 0xFFFFFFE0;
|
||||||
|
AddFixup(FU_QUAD | FU_OBJLINK, lastSloc, fixupExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (orgaddr & 0x1F)
|
||||||
|
{
|
||||||
|
case 0x08: HandleNOP(); // Emit 3 NOPs
|
||||||
|
case 0x10: HandleNOP(); // Emit 2 NOPs
|
||||||
|
case 0x18: HandleNOP(); // Emit 1 NOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
AddFixup(FU_QUAD | FU_OBJDATA, sloc, exprbuf);
|
||||||
|
else if (eattr & TDB)
|
||||||
|
MarkRelocatable(cursect, sloc, (eattr & TDB), MQUAD, NULL);
|
||||||
|
|
||||||
|
uint64_t dataAddr = eval & 0xFFFFF8;
|
||||||
|
uint64_t linkAddr = (orgaddr + 32) & 0x3FFFF8;
|
||||||
|
|
||||||
|
uint64_t * vars[13] = { &xpos, &ypos, &dwidth, &iwidth, &iheight, &xscale, &yscale, &remainder, &bpp, &index, 0, &firstpix, &pitch };
|
||||||
|
|
||||||
|
for(int i=0; i<13; i++)
|
||||||
|
{
|
||||||
|
// If there are less than 13 arguments after the data address, use
|
||||||
|
// defaults for the rest of them
|
||||||
|
// N.B.: Should there be a default minimum # of args? Like the first 5?
|
||||||
|
if (tok[0] == EOL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CHECK_COMMA;
|
||||||
|
|
||||||
|
if (i != 10)
|
||||||
|
{
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
return error("bad expression");
|
||||||
|
|
||||||
|
// Handle 3.5 fixed point nums (if any)...
|
||||||
|
if ((i >= 5) && (i <= 7))
|
||||||
|
{
|
||||||
|
if (eattr & FLOAT) // Handle floats
|
||||||
|
{
|
||||||
|
// PTR p = { .u64 = &eval }; // C99 \o/
|
||||||
|
PTR p = { (uint8_t *)&eval }; // Meh, it works
|
||||||
|
eval = DoubleToFixedPoint(*p.dp, 3, 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
eval <<= 5; // Otherwise, it's just an int...
|
||||||
|
}
|
||||||
|
|
||||||
|
*vars[i] = eval;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle FLAGs. Can have at most four.
|
||||||
|
for(int j=0; j<4; j++)
|
||||||
|
{
|
||||||
|
if (tok[0] != SYMBOL)
|
||||||
|
return error("missing REFLECT, RMW, TRANS, and/or RELEASE");
|
||||||
|
|
||||||
|
flags |= CheckFlags(scratchbuf);
|
||||||
|
|
||||||
|
// Break out if no more symbols...
|
||||||
|
if (tok[0] != SYMBOL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
at_eol();
|
||||||
|
|
||||||
|
uint64_t p1 = 0x01 | ((ypos * 2) << 3) | (iheight << 14) | (linkAddr << 21) | (dataAddr << 40);
|
||||||
|
uint64_t p2 = xpos | (bpp << 12) | (pitch << 15) | (dwidth << 18) | (iwidth << 28) | (index << 38) | (flags << 45) | (firstpix << 49);
|
||||||
|
uint64_t p3 = (xscale & 0xFF) | (yscale & 0xFF) << 8 | (remainder & 0xFF) << 16;
|
||||||
|
|
||||||
|
lastSloc = sloc;
|
||||||
|
lastObjType = 1;
|
||||||
|
D_quad(p1);
|
||||||
|
D_quad(p2);
|
||||||
|
D_quad(p3);
|
||||||
|
D_quad(0LL);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert GPU object
|
||||||
|
// Form: gpuobj <line #>, <userdata> (bits 14-63 of this object)
|
||||||
|
//
|
||||||
|
int HandleGPUObject(void)
|
||||||
|
{
|
||||||
|
uint64_t eval;
|
||||||
|
uint16_t eattr;
|
||||||
|
SYM * esym = 0;
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
return error("bad expression in y position");
|
||||||
|
|
||||||
|
uint64_t ypos = eval;
|
||||||
|
|
||||||
|
CHECK_COMMA;
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
return error("bad expression in data");
|
||||||
|
|
||||||
|
at_eol();
|
||||||
|
|
||||||
|
uint64_t p1 = 0x02 | ((ypos * 2) << 3) | (eval << 14);
|
||||||
|
|
||||||
|
lastObjType = 2;
|
||||||
|
D_quad(p1);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert a branch object
|
||||||
|
// Form: branch VC <condition (<, =, >)> <line #>, <link addr>
|
||||||
|
// branch OPFLAG, <link addr>
|
||||||
|
// branch SECHALF, <link addr>
|
||||||
|
//
|
||||||
|
int HandleBranch(void)
|
||||||
|
{
|
||||||
|
char missingKeyword[] = "missing VC, OPFLAG, or SECHALF in branch";
|
||||||
|
uint32_t cc = 0;
|
||||||
|
uint32_t ypos = 0;
|
||||||
|
uint64_t eval;
|
||||||
|
uint16_t eattr;
|
||||||
|
SYM * esym = 0;
|
||||||
|
|
||||||
|
if (tok[0] != SYMBOL)
|
||||||
|
return error(missingKeyword);
|
||||||
|
|
||||||
|
GetSymbolUCFromTokenStream(scratchbuf);
|
||||||
|
|
||||||
|
if (strcmp(scratchbuf, "VC") == 0)
|
||||||
|
{
|
||||||
|
switch (*tok++)
|
||||||
|
{
|
||||||
|
case '=': cc = 0; break;
|
||||||
|
case '<': cc = 1; break;
|
||||||
|
case '>': cc = 2; break;
|
||||||
|
default:
|
||||||
|
return error("missing '<', '>', or '='");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
return error("bad expression");
|
||||||
|
|
||||||
|
ypos = (uint32_t)eval;
|
||||||
|
}
|
||||||
|
else if (strcmp(scratchbuf, "OPFLAG") == 0)
|
||||||
|
cc = 3;
|
||||||
|
else if (strcmp(scratchbuf, "SECHALF") == 0)
|
||||||
|
cc = 4;
|
||||||
|
else
|
||||||
|
return error(missingKeyword);
|
||||||
|
|
||||||
|
CHECK_COMMA;
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
AddFixup(FU_QUAD | FU_OBJLINK, sloc, exprbuf);
|
||||||
|
|
||||||
|
at_eol();
|
||||||
|
|
||||||
|
uint64_t p1 = 0x03 | (cc << 14) | ((ypos * 2) << 3) | ((eval & 0x3FFFF8) << 21);
|
||||||
|
|
||||||
|
lastObjType = 3;
|
||||||
|
D_quad(p1);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert a stop object
|
||||||
|
// Form: stop
|
||||||
|
//
|
||||||
|
int HandleStop(void)
|
||||||
|
{
|
||||||
|
lastObjType = 4;
|
||||||
|
D_quad(4LL);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert a phrase sized "NOP" in the object list (psuedo-op)
|
||||||
|
// Form: nop
|
||||||
|
//
|
||||||
|
int HandleNOP(void)
|
||||||
|
{
|
||||||
|
uint64_t eval = (orgaddr + 8) & 0x3FFFF8;
|
||||||
|
// This is "branch if VC > 2047". Branch addr is next phrase, so either way
|
||||||
|
// it will pass by this phrase.
|
||||||
|
uint64_t p1 = 0x03 | (2 << 14) | (0x7FF << 3) | (eval << 21);
|
||||||
|
|
||||||
|
lastObjType = 3;
|
||||||
|
D_quad(p1);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert an unconditional jump in the object list (psuedo-op)
|
||||||
|
// Form: jump <link addr>
|
||||||
|
//
|
||||||
|
int HandleJump(void)
|
||||||
|
{
|
||||||
|
uint64_t eval;
|
||||||
|
uint16_t eattr;
|
||||||
|
SYM * esym = 0;
|
||||||
|
|
||||||
|
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if (!(eattr & DEFINED))
|
||||||
|
AddFixup(FU_QUAD | FU_OBJLINK, sloc, exprbuf);
|
||||||
|
|
||||||
|
at_eol();
|
||||||
|
|
||||||
|
// This is "branch if VC < 2047", which pretty much guarantees the branch.
|
||||||
|
uint64_t p1 = 0x03 | (1 << 14) | (0x7FF << 3) | ((eval & 0x3FFFF8) << 21);
|
||||||
|
|
||||||
|
lastObjType = 3;
|
||||||
|
D_quad(p1);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// Object Processor assembler
|
||||||
|
//
|
||||||
|
// by James Hammons
|
||||||
|
// (C) 2018 Underground Software
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __OP_H__
|
||||||
|
#define __OP_H__
|
||||||
|
|
||||||
|
// Exported functions
|
||||||
|
int GenerateOPCode(int);
|
||||||
|
|
||||||
|
#endif // __OP_H__
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#
|
||||||
|
# Jaguar Object Processor mnemonics
|
||||||
|
#
|
||||||
|
bitmap 3100
|
||||||
|
scbitmap 3101
|
||||||
|
gpuobj 3102
|
||||||
|
branch 3103
|
||||||
|
stop 3104
|
||||||
|
nop 3105
|
||||||
|
jump 3106
|
||||||
|
|
37
procln.c
37
procln.c
|
@ -15,6 +15,7 @@
|
||||||
#include "listing.h"
|
#include "listing.h"
|
||||||
#include "mach.h"
|
#include "mach.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "op.h"
|
||||||
#include "riscasm.h"
|
#include "riscasm.h"
|
||||||
#include "sect.h"
|
#include "sect.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
@ -34,6 +35,10 @@
|
||||||
#define DECL_MP // Include 6502 keyword state machine tables
|
#define DECL_MP // Include 6502 keyword state machine tables
|
||||||
#include "6502kw.h"
|
#include "6502kw.h"
|
||||||
|
|
||||||
|
#define DEF_MO // Include OP keyword definitions
|
||||||
|
#define DECL_MO // Include OP keyword state machine tables
|
||||||
|
#include "opkw.h"
|
||||||
|
|
||||||
IFENT * ifent; // Current ifent
|
IFENT * ifent; // Current ifent
|
||||||
static IFENT ifent0; // Root ifent
|
static IFENT ifent0; // Root ifent
|
||||||
IFENT * f_ifent; // Freelist of ifents
|
IFENT * f_ifent; // Freelist of ifents
|
||||||
|
@ -659,6 +664,38 @@ When checking to see if it's already been equated, issue a warning.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are in OP mode and still in need of a mnemonic then search for one
|
||||||
|
if (robjproc && ((state < 0) || (state >= 1000)))
|
||||||
|
{
|
||||||
|
for(state=0, p=opname; state>=0;)
|
||||||
|
{
|
||||||
|
j = mobase[state] + (int)tolowertab[*p];
|
||||||
|
|
||||||
|
// Reject, character doesn't match
|
||||||
|
if (mocheck[j] != state)
|
||||||
|
{
|
||||||
|
state = -1; // No match
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must accept or reject at EOS
|
||||||
|
if (!*++p)
|
||||||
|
{
|
||||||
|
state = moaccept[j]; // (-1 on no terminal match)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = motab[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call OP code generator if we found a mnemonic
|
||||||
|
if (state >= 3100)
|
||||||
|
{
|
||||||
|
GenerateOPCode(state);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke macro or complain about bad mnemonic
|
// Invoke macro or complain about bad mnemonic
|
||||||
if (state < 0)
|
if (state < 0)
|
||||||
{
|
{
|
||||||
|
|
11
riscasm.c
11
riscasm.c
|
@ -13,6 +13,7 @@
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "mark.h"
|
#include "mark.h"
|
||||||
#include "procln.h"
|
#include "procln.h"
|
||||||
|
#include "rmac.h"
|
||||||
#include "sect.h"
|
#include "sect.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
@ -134,16 +135,6 @@ static const char * malformErr[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Convert a string to uppercase
|
|
||||||
//
|
|
||||||
static void strtoupper(char * s)
|
|
||||||
{
|
|
||||||
while (*s)
|
|
||||||
*s++ &= 0xDF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Function to return "malformed expression" error
|
// Function to return "malformed expression" error
|
||||||
// This is done mainly to remove a bunch of GOTO statements in the parser
|
// This is done mainly to remove a bunch of GOTO statements in the parser
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#define GPUONLY 0x4000 // Opcode is for the GPU Only
|
#define GPUONLY 0x4000 // Opcode is for the GPU Only
|
||||||
#define DSPONLY 0x8000 // Opcode is for the DSP Only
|
#define DSPONLY 0x8000 // Opcode is for the DSP Only
|
||||||
|
|
||||||
#define CHECK_COMMA if(*tok++ != ',') { error(comma_error); return(ERROR); }
|
#define CHECK_COMMA if (*tok++ != ',') { return error(comma_error); }
|
||||||
|
|
||||||
// Globals, externals etc
|
// Globals, externals etc
|
||||||
extern unsigned orgactive;
|
extern unsigned orgactive;
|
||||||
|
|
12
rmac.c
12
rmac.c
|
@ -40,6 +40,7 @@ int debug; // [1..9] Enable debugging levels
|
||||||
int err_flag; // '-e' specified
|
int err_flag; // '-e' specified
|
||||||
int err_fd; // File to write error messages to
|
int err_fd; // File to write error messages to
|
||||||
int rgpu, rdsp; // Assembling Jaguar GPU or DSP code
|
int rgpu, rdsp; // Assembling Jaguar GPU or DSP code
|
||||||
|
int robjproc; // Assembling Jaguar Object Processor code
|
||||||
int dsp56001; // Assembling DSP 56001 code
|
int dsp56001; // Assembling DSP 56001 code
|
||||||
int list_fd; // File to write listing to
|
int list_fd; // File to write listing to
|
||||||
int regbank; // RISC register bank
|
int regbank; // RISC register bank
|
||||||
|
@ -55,6 +56,16 @@ int activecpu = CPU_68000; // Active 68k CPU (68000 by default)
|
||||||
int activefpu = FPU_NONE; // Active FPU (none by default)
|
int activefpu = FPU_NONE; // Active FPU (none by default)
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert a string to uppercase
|
||||||
|
//
|
||||||
|
void strtoupper(char * s)
|
||||||
|
{
|
||||||
|
while (*s)
|
||||||
|
*s++ &= 0xDF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Manipulate file extension.
|
// Manipulate file extension.
|
||||||
//
|
//
|
||||||
|
@ -271,6 +282,7 @@ int Process(int argc, char ** argv)
|
||||||
err_flag = 0; // Initialise error flag
|
err_flag = 0; // Initialise error flag
|
||||||
rgpu = 0; // Initialise GPU assembly flag
|
rgpu = 0; // Initialise GPU assembly flag
|
||||||
rdsp = 0; // Initialise DSP assembly flag
|
rdsp = 0; // Initialise DSP assembly flag
|
||||||
|
robjproc = 0; // Initialise OP assembly flag
|
||||||
lsym_flag = 1; // Include local symbols in object file
|
lsym_flag = 1; // Include local symbols in object file
|
||||||
regbank = BANK_N; // No RISC register bank specified
|
regbank = BANK_N; // No RISC register bank specified
|
||||||
orgactive = 0; // Not in RISC org section
|
orgactive = 0; // Not in RISC org section
|
||||||
|
|
2
rmac.h
2
rmac.h
|
@ -284,6 +284,7 @@ enum
|
||||||
extern int verb_flag;
|
extern int verb_flag;
|
||||||
extern int debug;
|
extern int debug;
|
||||||
extern int rgpu, rdsp;
|
extern int rgpu, rdsp;
|
||||||
|
extern int robjproc;
|
||||||
extern int dsp56001;
|
extern int dsp56001;
|
||||||
extern int err_flag;
|
extern int err_flag;
|
||||||
extern int err_fd;
|
extern int err_fd;
|
||||||
|
@ -306,6 +307,7 @@ extern int activecpu;
|
||||||
extern int activefpu;
|
extern int activefpu;
|
||||||
|
|
||||||
// Exported functions
|
// Exported functions
|
||||||
|
void strtoupper(char * s);
|
||||||
char * fext(char *, char *, int);
|
char * fext(char *, char *, int);
|
||||||
int nthpath(char *, int, char *);
|
int nthpath(char *, int, char *);
|
||||||
int ParseOptimization(char * optstring);
|
int ParseOptimization(char * optstring);
|
||||||
|
|
45
sect.c
45
sect.c
|
@ -290,7 +290,7 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr)
|
||||||
|
|
||||||
DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr);
|
DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr);
|
||||||
if (symbol != NULL)
|
if (symbol != NULL)
|
||||||
printf(" name: %s, value: $lX\n", symbol->sname, symbol->svalue);
|
printf(" name: %s, value: $%lX\n", symbol->sname, symbol->svalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -679,9 +679,8 @@ int ResolveFixups(int sno)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Fixup LONG forward references;
|
// Fixup LONG forward references; the long could be unaligned in the
|
||||||
// the long could be unaligned in the section buffer, so be careful
|
// section buffer, so be careful (again).
|
||||||
// (again).
|
|
||||||
case FU_LONG:
|
case FU_LONG:
|
||||||
flags = MLONG;
|
flags = MLONG;
|
||||||
|
|
||||||
|
@ -702,6 +701,44 @@ int ResolveFixups(int sno)
|
||||||
SETBE32(locp, 0, eval);
|
SETBE32(locp, 0, eval);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Fixup QUAD forward references
|
||||||
|
// Need to add flags for OP uses... [DONE]
|
||||||
|
case FU_QUAD:
|
||||||
|
// If the symbol is undefined, make sure to pass the symbol in
|
||||||
|
// to the MarkRelocatable() function.
|
||||||
|
/* if (!(eattr & DEFINED))
|
||||||
|
MarkRelocatable(sno, loc, 0, MQUAD, esym);
|
||||||
|
else if (tdb)
|
||||||
|
MarkRelocatable(sno, loc, tdb, MQUAD, NULL);//*/
|
||||||
|
|
||||||
|
if (w & FU_OBJLINK)
|
||||||
|
{
|
||||||
|
uint64_t quad = GETBE64(locp, 0);
|
||||||
|
uint64_t addr = eval;
|
||||||
|
|
||||||
|
if (fup->orgaddr)
|
||||||
|
addr = fup->orgaddr;
|
||||||
|
|
||||||
|
//printf("sect.c: FU_OBJLINK quad=%016lX, addr=%016lX ", quad, addr);
|
||||||
|
|
||||||
|
eval = (quad & 0xFFFFFC0000FFFFFFLL) | ((addr & 0x3FFFF8) << 21);
|
||||||
|
//printf("(%016lX)\n", eval);
|
||||||
|
}
|
||||||
|
else if (w & FU_OBJDATA)
|
||||||
|
{
|
||||||
|
uint64_t quad = GETBE64(locp, 0);
|
||||||
|
uint64_t addr = eval;
|
||||||
|
|
||||||
|
if (fup->orgaddr)
|
||||||
|
addr = fup->orgaddr;
|
||||||
|
|
||||||
|
eval = (quad & 0x000007FFFFFFFFFFLL) | ((addr & 0xFFFFF8) << 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
SETBE64(locp, 0, eval);
|
||||||
|
//printf("(%016lX)\n", eval);
|
||||||
|
break;
|
||||||
|
|
||||||
// Fixup a 3-bit "QUICK" reference in bits 9..1
|
// Fixup a 3-bit "QUICK" reference in bits 9..1
|
||||||
// (range of 1..8) in a word. [Really bits 1..3 in a byte.]
|
// (range of 1..8) in a word. [Really bits 1..3 in a byte.]
|
||||||
case FU_QUICK:
|
case FU_QUICK:
|
||||||
|
|
12
sect.h
12
sect.h
|
@ -76,6 +76,7 @@
|
||||||
#define FU_6BRA 0x0007 // Fixup 6502-format branch offset
|
#define FU_6BRA 0x0007 // Fixup 6502-format branch offset
|
||||||
#define FU_BYTEH 0x0008 // Fixup 6502 high byte of immediate word
|
#define FU_BYTEH 0x0008 // Fixup 6502 high byte of immediate word
|
||||||
#define FU_BYTEL 0x0009 // Fixup 6502 low byte of immediate word
|
#define FU_BYTEL 0x0009 // Fixup 6502 low byte of immediate word
|
||||||
|
#define FU_QUAD 0x000A // Fixup quad-word (8 bytes)
|
||||||
|
|
||||||
#define FU_SEXT 0x0010 // Ok to sign extend
|
#define FU_SEXT 0x0010 // Ok to sign extend
|
||||||
#define FU_PCREL 0x0020 // Subtract PC first
|
#define FU_PCREL 0x0020 // Subtract PC first
|
||||||
|
@ -98,9 +99,14 @@
|
||||||
#define FU_DONE 0x8000 // Fixup has been done
|
#define FU_DONE 0x8000 // Fixup has been done
|
||||||
|
|
||||||
// FPU fixups
|
// FPU fixups
|
||||||
#define FU_FLOATSING 0x000A // Fixup 32-bit float
|
#define FU_FLOATSING 0x000B // Fixup 32-bit float
|
||||||
#define FU_FLOATDOUB 0x000B // Fixup 64-bit float
|
#define FU_FLOATDOUB 0x000C // Fixup 64-bit float
|
||||||
#define FU_FLOATEXT 0x000C // Fixup 96-bit float
|
#define FU_FLOATEXT 0x000D // Fixup 96-bit float
|
||||||
|
|
||||||
|
// OP fixups
|
||||||
|
#define FU_OBJLINK 0x10000 // Fixup OL link addr (bits 24-42, drop last 3)
|
||||||
|
#define FU_OBJDATA 0x20000 // Fixup OL data addr (bits 43-63, drop last 3)
|
||||||
|
|
||||||
|
|
||||||
// Chunks are used to hold generated code and fixup records
|
// Chunks are used to hold generated code and fixup records
|
||||||
#define CHUNK struct _chunk
|
#define CHUNK struct _chunk
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
// Release Information
|
// Release Information
|
||||||
|
|
||||||
#define MAJOR 1 // Major version number
|
#define MAJOR 1 // Major version number
|
||||||
#define MINOR 12 // Minor version number
|
#define MINOR 13 // Minor version number
|
||||||
#define PATCH 5 // Patch release number
|
#define PATCH 0 // Patch release number
|
||||||
|
|
||||||
#endif // __VERSION_H__
|
#endif // __VERSION_H__
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue