release candidate

This commit is contained in:
Andre Fachat 2023-11-18 12:00:53 +01:00
parent f1799614fc
commit e739f0ee61
29 changed files with 139 additions and 1142 deletions

View File

@ -436,5 +436,5 @@ xa-2.4.0
removed. If you need this support, you must use 2.3.x.
-- André Fachat <afachat@gmx.de> and
-- Cameron Kaiser <ckaiser@floodgap.com>, 17 November, 2023
-- Cameron Kaiser <ckaiser@floodgap.com>, 18 November, 2023

View File

@ -14,6 +14,6 @@ test2: test2.a
rom65: test.a
# ugly!
( cd .. && ../mkrom.sh -O "-G" -S "-bd 1234" -R loader/rom65 loader/test.a loader/test.a )
../hextool -cmp=rom65.ok < rom65
# don't run if this system doesn't have bash
test -f /bin/bash || exit 0 && ( cd .. && ../mkrom.sh -O "-G" -S "-bd 1234" -R loader/rom65 loader/test.a loader/test.a ) && ( ../hextool -cmp=rom65.ok < rom65 )

View File

@ -1,4 +1,4 @@
.TH FILE65 "1" "17 November 2023"
.TH FILE65 "1" "18 November 2023"
.SH NAME
file65 \- print information for o65 object files

View File

@ -1,4 +1,4 @@
.TH LDO65 "1" "17 November 2023"
.TH LDO65 "1" "18 November 2023"
.SH NAME
ldo65 \- linker for o65 object files

View File

@ -1,4 +1,4 @@
.TH RELOC65 "1" "17 November 2023"
.TH RELOC65 "1" "18 November 2023"
.SH NAME
reloc65 \- relocator for o65 object files

View File

@ -1,4 +1,4 @@
.TH UNCPK "1" "17 November 2023"
.TH UNCPK "1" "18 November 2023"
.SH NAME
uncpk \- manage c64 cpk archives

View File

@ -1,4 +1,4 @@
.TH XA "1" "17 November 2023"
.TH XA "1" "18 November 2023"
.SH NAME
xa \- 6502/R65C02/65816 cross-assembler
@ -306,9 +306,24 @@ for block instructions). A label may also be hard-specified with the
.B \-L
command line option.
.LP
Redefining a label does not change previously assembled code that used the
earlier value. Therefore, because the program counter is a special type of
label, changing the program counter to a lower value does not reorder code
assembled previously and changing it to a higher value does not issue
padding to put subsequent code at the new location. This is intentional
behaviour to facilitate generating relocatable and position-independent code,
but can differ from other assemblers which use this behaviour for
linking. However, it is possible to use pseudo-ops to simulate other
assemblers' behaviour and use
.B xa
as a linker; see
.B PSEUDO-OPS
and
.BR LINKING .
.LP
If
.B \-XCA65
is specified, "cheap" local labels may be used and/or redefined, marked by the
is specified, "cheap" local labels may be used, marked by the
.B @
prefix. Additionally, unnamed labels may be specified with
.B :
@ -352,21 +367,6 @@ documentation),
.BR
: rts ; #4
.LP
Redefining a label does not change previously assembled code that used the
earlier value. Therefore, because the program counter is a special type of
label, changing the program counter to a lower value does not reorder code
assembled previously and changing it to a higher value does not issue
padding to put subsequent code at the new location. This is intentional
behaviour to facilitate generating relocatable and position-independent code,
but can differ from other assemblers which use this behaviour for
linking. However, it is possible to use pseudo-ops to simulate other
assemblers' behaviour and use
.B xa
as a linker; see
.B PSEUDO-OPS
and
.BR LINKING .
.LP
For those instructions where the accumulator is the implied argument (such as
.B asl
and

View File

@ -151,7 +151,9 @@ int main(int argc, char *argv[]) {
int undefok=0;
int i = 1;
int tbase = 0x0400, dbase = 0x1000, bbase = 0x4000, zbase = 0x0002;
int ttlen, tdlen, tblen, tzlen;
int ttlen, tdlen, tblen, tzlen, routtlen, routdlen, tro, dro;
int lasttaddr, lastdaddr;
unsigned char *treloc, *dreloc;
char *outfile = "a.o65";
int j, jm;
file65 *file, **fp = NULL;
@ -384,8 +386,8 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
// reloc globals first, so reloc_seg has current info for resolved undef'd labels
int routtlen = 1; // end-of-table byte
int routdlen = 1; // end-of-table byte
routtlen = 1; // end-of-table byte
routdlen = 1; // end-of-table byte
for(i=0;i<j;i++) {
file = fp[i];
@ -397,19 +399,19 @@ printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n
}
// prep global reloc tables
unsigned char *treloc = malloc(routtlen);
unsigned char *dreloc = malloc(routdlen);
treloc = malloc(routtlen);
dreloc = malloc(routdlen);
#ifdef DEBUG
printf("prep'd text reloc table at %p (%d bytes)\n", treloc, routtlen);
printf("prep'd data reloc table at %p (%d bytes)\n", dreloc, routdlen);
#endif
int tro = 0;
int dro = 0;
tro = 0;
dro = 0;
// segment position of last relocation entry to compute offsets across files
int lasttaddr = tbase - 1;
int lastdaddr = dbase - 1;
lasttaddr = tbase - 1;
lastdaddr = dbase - 1;
for(i=0;i<j;i++) {
file = fp[i];
@ -597,6 +599,7 @@ int read_undef(unsigned char *buf, file65 *file) {
int resolve_undef(file65 *file, int *remains) {
int i;
undefs *current;
int nlabels = file->nundef;
#ifdef DEBUG
printf("resolved undef file %s (%d undef'd)\n", file->fname, nlabels);
@ -604,7 +607,7 @@ printf("resolved undef file %s (%d undef'd)\n", file->fname, nlabels);
if (nlabels == 0) {
return 0;
}
undefs *current = file->ud;
current = file->ud;
for (i = 0; i < nlabels; i++) {
// store pointer to global in label info
@ -1053,9 +1056,10 @@ printf("found undef'd label %s, resolved=%d, newidx=%d, (ri=%d, ro=%d)\n", u->na
obuf[ro++] = (old + diff) & 255;
ri += 3; // skip position, segment, and low byte
} else {
undefs *u;
old = buf[addr-base+pos]*256 + buf[ri+4];
// undefined
undefs *u = &fp->ud[buf[ri+2]+256*buf[ri+3]];
u = &fp->ud[buf[ri+2]+256*buf[ri+3]];
if (u->resolved == -1) {
// not resolved
diff = 0;

View File

@ -227,13 +227,16 @@ void list_setfile(FILE *fp) {
}
char *list_preamble(char *buf, int lineno, int seg, int pc) {
int i;
char c;
/* line number in file */
snprintf(buf, 10, "% 5d", lineno);
int i = strlen(buf);
i = strlen(buf);
buf += i;
buf += list_char(buf, ' ');
char c = '?';
c = '?';
/* preamble <segment>':'<address>' ' */
switch(seg) {
case SEG_ABS: c='A'; break;
@ -261,8 +264,7 @@ char *list_preamble(char *buf, int lineno, int seg, int pc) {
* Note that both lengths may be zero
*/
void do_listing(signed char *listing, int listing_len, signed char *bincode, int bincode_len) {
int i, n_hexb;
int i, n_hexb, num_last_line, tmp, overflow;
char outline[MAXLINE];
char *buf = outline;
@ -293,13 +295,13 @@ void do_listing(signed char *listing, int listing_len, signed char *bincode, int
// check if we have labels, so we can adjust the max printable number of
// bytes in the last line
int num_last_line = 11;
int tmp = listing[3] & 255;
num_last_line = 11;
tmp = listing[3] & 255;
if (tmp == (T_DEFINE & 255)) {
// we have label definition
num_last_line = 8;
}
int overflow = 0;
overflow = 0;
/* binary output (up to 8 byte. If more than 8 byte, print 7 plus "..." */
n_hexb = bincode_len;
@ -381,7 +383,7 @@ int list_tokens(char *buf, signed char *input, int len) {
char *name;
signed char c;
xalabel_t is_cll;
int tabval;
int tabval, operator;
signed char format;
if (inp >= len) return 0;
@ -448,7 +450,7 @@ int list_tokens(char *buf, signed char *input, int len) {
#endif
}
int operator = 0;
operator = 0;
while (inp < len) {
switch(input[inp]) {
@ -597,14 +599,14 @@ end:
}
int list_string(char *buf, char *string) {
int p = 0;
if (buf == NULL || string == NULL) {
fprintf(stderr, "NULL pointer: buf=%p, string=%p\n", buf, string);
fflush(stderr);
//exit(1);
return 0;
}
int p = 0;
while (string[p] != 0) {
buf[p] = string[p];
p++;

View File

@ -490,7 +490,8 @@ static int check_name(char *t, int n) {
static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int *l, int blist)
{
int er = E_OK;
int i;
int i, d;
char c;
// save mem, to restore it when we don't need the pseudo replacements anymore
// Note: in a real version, that should probably be a parameter, and not fiddling
@ -543,6 +544,10 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
// rlist.
for(i=0;i<liste[n].p_anz;i++)
{
char c;
int hkfl=0; // quote flag
int klfl=0; // brackets counter
// create new replacement entry
liste[blist+i].search=x;
liste[blist+i].s_len=(int)strlen(x);
@ -553,9 +558,7 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
// points to first char of the parameter name in the input
// copy over first char into text memory (note that the position
// is already stored in liste[].replace above)
char c=*(++mx)=*(++y);
int hkfl=0; // quote flag
int klfl=0; // brackets counter
c=*(++mx)=*(++y);
// copy over the other characters
while(c!='\0'
&& ((hkfl!=0
@ -698,7 +701,7 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
}
} // end if(liste[n].p_anz), i.e. if it has parameters
int d=(int)strlen(rs)-sl;
d=(int)strlen(rs)-sl;
if(strlen(to)+d>=MAXLINE) {
mem = saved_mem;
@ -724,7 +727,6 @@ static int pp_replace_part(char *to, char *t, int n, int sl, int recursive, int
}
i=0;
char c;
while((c=rs[i])) {
t[i++]=c;
}
@ -903,10 +905,11 @@ int pp_init(void)
int pp_open(char *name)
{
FILE *fp;
int l;
fp=xfopen(name,"r");
int l = strlen(name);
l = strlen(name);
/* we have to alloc it dynamically to make the name survive another
pp_open - it's used in the cross-reference list */
@ -959,7 +962,8 @@ int icl_close(int *c)
int icl_open(char *tt)
{
FILE *fp2;
int j,i=0;
char *namep;
int len,j,i=0;
pp_replace(s,tt,-1,rlist);
@ -982,8 +986,8 @@ int icl_open(char *tt)
fsp++;
char *namep = s+i;
int len = strlen(namep);
namep = s+i;
len = strlen(namep);
/* we have to alloc it dynamically to make the name survive another
pp_open - it's used in the cross-reference list */

View File

@ -56,7 +56,6 @@ alxl/ Various '816 width tests (includes Samuel Falvo's test)
pparity/ Tests of preprocessor macro arity (with Emil Johansson's test)
recucom/ Recursive comments test
aserror/ Tests of .assert and #error syntax/function
loader/ Old ../loader tests, moved into test suite proper
reset_segment/ Verifies conditions under which a segment is reset
expando/ Test of preprocessor expansion (thanks Tom Hargreaves)

View File

@ -12,25 +12,26 @@ OBJS=unnamed1 unnamed2 escape2
#tests: unnamed1 unnamed2 escape1 escape2 clean
tests: $(OBJS)
# BSD make won't populate $< in these and GNU make doesn't like $>
unnamed1: unnamed1.a65
#${CA65} $<; ${LD65} -t none -o unnamed1.ca65 unnamed1.o; rm unnamed1.o
${XA} -XCA65 $< -o $@
#${CA65} unnamed1.a65; ${LD65} -t none -o unnamed1.ca65 unnamed1.o; rm unnamed1.o
${XA} -XCA65 unnamed1.a65 -o $@
../hextool -cmp=unnamed1.ca65 < $@
unnamed2: unnamed2.a65
#${CA65} $<; ${LD65} -t none -o unnamed2.ca65 unnamed2.o; rm unnamed2.o
${XA} -XCA65 $< -o $@ 2>a.err || true
#${CA65} unnamed2.a65; ${LD65} -t none -o unnamed2.ca65 unnamed2.o; rm unnamed2.o
${XA} -XCA65 unnamed2.a65 -o $@ 2>a.err || true
../hextool -cmp=unnamed2.ca65 < $@
# add -XXA23 to actually test this
escape1: escape1.a65
${XA} $< -o $@
${XA} escape1.a65 -o $@
../hextool -cmp=escape1.out < $@
escape2: escape2.a65
#${CA65} $<; ${LD65} -t none -o escape2.ca65 escape2.o; rm escape2.o
${XA} -XCA65 $< -o $@ 2>a.err || true
#${CA65} escape2.a65; ${LD65} -t none -o escape2.ca65 escape2.o; rm escape2.o
${XA} -XCA65 escape2.a65 -o $@ 2>a.err || true
../hextool -cmp=escape2.ca65 < $@
clean:

View File

@ -2,10 +2,16 @@
default: all
all: t1 t2 t10 t11 t20 t21 t30 t31 t40 t41 t50 t51 t60 t61 t62
%.o65: %.s
# BSD only has suffix rules
.SUFFIXES: .o65 .hex
#%.o65: %.s
.s.o65:
../../xa -R -c -o $@ $<
%.hex: %.o65
#%.hex: %.o65
.o65.hex:
../hextool $< > $@
linked.o65: 1.o65 2.o65
@ -56,63 +62,65 @@ linked61.o65: 60.o65 61.o65
linked62.o65: 60.o65 61.o65
../../ldo65 -bd 65529 -bt 65523 -bz 255 -o $@ 61.o65 60.o65 && exit 1 || exit 0
# BSD make doesn't populate $< in these rules and GNU make doesn't like $>
t1: linked.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked.o65
../hextool -cmp=$@ < t1.ok
t2: linked2.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked2.o65
../hextool -cmp=$@ < t2.ok
t10: linked10.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked10.o65
../hextool -cmp=$@ < t10.ok
t11: linked11.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked11.o65
../hextool -cmp=$@ < t11.ok
t20: linked20.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked20.o65
../hextool -cmp=$@ < t20.ok
t21: linked21.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked21.o65
../hextool -cmp=$@ < t21.ok
t22: linked22.o65
# should fail, so no action
t30: linked30.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked30.o65
../hextool -cmp=$@ < t30.ok
t31: linked31.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked31.o65
../hextool -cmp=$@ < t31.ok
t40: linked40.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked40.o65
../hextool -cmp=$@ < t40.ok
t41: linked41.o65
../../reloc65 -bt 32768 -xt -o $@ $<
../../reloc65 -bt 32768 -xt -o $@ linked41.o65
../hextool -cmp=$@ < t41.ok
t50: linked50.o65
../../reloc65 -bt 32768 -bd 40960 -o $@ $<
../../reloc65 -bt 32768 -bd 40960 -o $@ linked50.o65
../hextool -cmp=$@ < t50.ok
t51: linked51.o65
../../reloc65 -bt 32768 -bd 40960 -o $@ $<
../../reloc65 -bt 32768 -bd 40960 -o $@ linked51.o65
../hextool -cmp=$@ < t51.ok
t60: linked60.o65
../../reloc65 -bt 32768 -bd 40960 -o $@ $<
../../reloc65 -bt 32768 -bd 40960 -o $@ linked60.o65
../hextool -cmp=$@ < t60.ok
t61: linked61.o65
../../reloc65 -bt 32768 -bd 40960 -o $@ $<
../../reloc65 -bt 32768 -bd 40960 -o $@ linked61.o65
../hextool -cmp=$@ < t61.ok
t62: linked62.o65

View File

@ -1,9 +0,0 @@
all: test1
%:%.a65
../../xa $<
clean:
rm -f a.o65

BIN
xa/tests/line/ok Normal file

Binary file not shown.

View File

@ -10,24 +10,24 @@ LD65=ld65
tests: operatorsx.out assertx.out assertx.html linebreakx.out include1x.out listblocksx.html listca65x.html listca65_2x.html
operatorsx.out: operators.a65
${XA} -P- -o operatorsx.o65 $< > $@
${XA} -P- -o operatorsx.o65 operators.a65 > $@
../hextool -cmp=operators.out < $@
assertx.out: assert.a65
${XA} -P- -o assertx.o65 $< > $@
${XA} -P- -o assertx.o65 assert.a65 > $@
../hextool -cmp=assert.out < $@
../hextool -cmp=assert.o65 < assertx.o65
assertx.html: assert.a65
${XA} -P- -Fhtml -o assertx.o65 $< > $@
${XA} -P- -Fhtml -o assertx.o65 assert.a65 > $@
../hextool -cmp=assert.html < $@
include1x.out: include1.a65
${XA} -P- $< > $@
${XA} -P- include1.a65 > $@
../hextool -cmp=include1.out < $@
linebreakx.out: linebreak.a65
${XA} -P- $< > $@
${XA} -P- linebreak.a65 > $@
../hextool -cmp=linebreak.out < $@
listblocksx.html: listblocks.a65
@ -36,13 +36,13 @@ listblocksx.html: listblocks.a65
listca65x.html: listca65.a65
${XA} -XCA65 -P- -Fhtml -o listca65x.o65 listca65.a65 > $@
#${CA65} $<; ${LD65} -t none -o listca65.ca65 listca65.o; rm listca65.o
#${CA65} $>; ${LD65} -t none -o listca65.ca65 listca65.o; rm listca65.o
../hextool -cmp=listca65.html < $@
../hextool -cmp=listca65.ca65 < listca65x.o65
listca65_2x.html: listca65_2.a65
${XA} -XCA65 -P- -Fhtml -o listca65_2x.o65 listca65_2.a65 > $@
#${CA65} $<; ${LD65} -t none -o listca65_2.ca65 listca65_2.o; rm listca65_2.o
#${CA65} $>; ${LD65} -t none -o listca65_2.ca65 listca65_2.o; rm listca65_2.o
../hextool -cmp=listca65_2.html < $@
../hextool -cmp=listca65_2.ca65 < listca65_2x.o65

View File

@ -1,8 +0,0 @@
In this directory you find two test files, i.e. test.a and test2.a for
xa. test.a is assembled into the file "example", which is loaded by the
relocator "loader", when started on a C64. Don't try to execute this
file, it's just for testing.

Binary file not shown.

Binary file not shown.

View File

@ -1,36 +0,0 @@
/* These definitions are without the two leading version/marker bytes,
* length is without options
*/
#define HDR_MAGIC 0
#define HDR_VERSION 3
#define HDR_MODE 4
#define HDR_TBASE 6
#define HDR_TLEN 8
#define HDR_DBASE 10
#define HDR_DLEN 12
#define HDR_BBASE 14
#define HDR_BLEN 16
#define HDR_ZBASE 18
#define HDR_ZLEN 20
#define HDR_STACKLEN 22
#define HDR_LEN 24
#define A_ADR $80
#define A_HIGH $40 /* or'd with the low byte */
#define A_LOW $20
#define A_MASK $e0 /* reloc type mask */
#define A_FMASK $0f /* segment type mask */
#define SEG_UNDEF 0
#define SEG_ABS 1
#define SEG_TEXT 2
#define SEG_DATA 3
#define SEG_BSS 4
#define SEG_ZERO 5
#define FM_OBJ %00010000
#define FM_SIZE %00100000
#define FM_RELOC %01000000
#define FM_CPU %10000000

View File

@ -1,909 +0,0 @@
/**************************************************************************
*
* Loader for 6502 relocatable binary format
*
* The loader supports 16 bit o65 version 1 files without undefined
* references. Also it doesn't like pagewise relocation and 65816
* code, because there are different/additional relocation entries.
*
* The support routines, that have to be changed are at the end of the
* file. The stuff in this file is in absolute format (well, you have to
* bootstrap from something :-)
* The support routines for the file handling are for the operating system
* OS/A65, as of version 1.3.10b. The first part of the file (wrapped in
* "#ifdef C64") shows how to use it with a C64, for example.
*
* The subroutine 'loader' is called with a file descriptor, that has a
* meaning for the support routines, in the X register.
* The file must already be open. Also binit must have been called before.
* The loader doesn't close the file.
*
* Support routines are:
* binit a = hi byte start address memory to handle,
* x = hi byte length of memory to handle
* balloc a/y = length of block -> x = memory descriptor
* bfree x = memory block descriptor to free
* getbadr x = memory descriptor -> a/y address of memory block
*
* zalloc a = length of needed zeropage block. returns a=address
* zfree a = address of block to free
*
* fgetc x = file descriptor, returns read byte (c=0) or error (c=1)
* The error is passed through; fgetc blocks if no data
* available
* fgetb x = filedescriptor, a/y = address of block descriptor,
* i.e. a word start address and a word length of block.
* returns (c=0) or error in accu (c=1).
*
**************************************************************************/
/**************************************************************************
* This part is a binding for a C64
* to show how it works
*/
#define C64
#ifdef C64
sysmem =$033c
syszp =$57
.word $0801
*=$801
.word nextl
.word 10
.byt $9e, "2080",0
nextl .word 0
.dsb 2080-*, 0
c64load .(
lda #>PRGEND+255
ldx #>$A000-PRGEND
jsr binit ; init memory handling
lda #7
ldx #<fname
ldy #>fname
jsr $ffbd ; setfnpar
lda #2
ldx #11
ldy #0
jsr $ffba ; setfpar
jsr $ffc0 ; open
bcs end
ldx #2
jsr $ffc6 ; chkin
bcs end
jsr loader ; don't care about x, chkin did it
php
pha
jsr $ffcc ; clrch
lda #2
jsr $ffc3 ; close
pla
plp
end rts
fname ;.asc "example",0
.byt $45, $58, $41, $4d, $50, $4c, $45, 0
.)
fgetc .(
jsr $ffcf
php
pha
bcc carry
lda #"C"
jsr $ffd2
pla
pha
carry
jsr hexout
lda #$20
jsr $ffd2
pla
plp
rts
.)
hexout .(
pha
lsr
lsr
lsr
lsr
jsr nibout
pla
nibout and #$0f
clc
adc #$30
cmp #$3a
bcc ok
adc #$41-$3a-1
ok jmp $ffd2
.)
zalloc .(
cmp #$80 ; save from $90 upward = OS, below is only basic
bcs end
lda #$10
end rts
.)
zfree .(
clc
rts
.)
#endif
/**************************************************************************
* Here is the real loader code
*/
#include "file.def"
#define E_NOMEM <-40
#define E_FVERSION <-41
loader .(
p1 =syszp
p2 =syszp+2
-syszp +=4
tmp =sysmem
file =sysmem+1
-sysmem +=2
header =sysmem
-sysmem +=HDR_LEN
textb =sysmem ; memory block ID
texta =sysmem+1 ; address of block
textl =sysmem+3 ; address of block
textd =sysmem+5 ; difference to assemble address
-sysmem +=7
datab =sysmem
dataa =sysmem+1
datal =sysmem+3
datad =sysmem+5
-sysmem +=7
bssb =sysmem
bssa =sysmem+1
bssd =sysmem+3
-sysmem +=5
zeroa =sysmem
zerod =sysmem+1
-sysmem +=3
stx file
jsr fgetc
bcs end
sta tmp
jsr fgetc
bcs end
tay
lda tmp
cpy #0
bne rt
cmp #1
beq load
rt lda #E_FVERSION ; ok, but not this version
end sec
rts
load .(
lda #<header
sta p1
lda #>header
sta p1+1
lda #<HDR_LEN
sta p1+2
lda #>HDR_LEN
sta p1+3
ldx file
lda #<p1
ldy #>p1
jsr fgetb
bcs end
; header loaded, check magic and version
lda header+HDR_MAGIC
cmp #$6f
bne end
lda header+HDR_MAGIC+1
cmp #"6"
bne end
lda header+HDR_MAGIC+2
cmp #"5"
bne end
lda header+HDR_VERSION
cmp #0
bne end
lda header+HDR_MODE+1
and #%11110000
bne end
; now allocate buffers
lda header+HDR_TLEN
ldy header+HDR_TLEN+1
sta textl
sty textl+1
jsr balloc
stx textb
bcs no_text2
jsr getbadr
sta texta
sty texta+1
sec
sbc header+HDR_TBASE
sta textd
tya
sbc header+HDR_TBASE+1
sta textd+1
lda header+HDR_DLEN
ldy header+HDR_DLEN+1
sta datal
sty datal+1
jsr balloc
stx datab
bcs no_data2
no_text2 bcs no_text1
jsr getbadr
sta dataa
sty dataa+1
sec
sbc header+HDR_DBASE
sta datad
tya
sbc header+HDR_DBASE+1
sta datad+1
lda header+HDR_BLEN
ldy header+HDR_BLEN+1
jsr balloc
stx bssb
bcs no_bss
no_text1 bcs no_text
no_data2 bcs no_data
jsr getbadr
sta bssa
sty bssa+1
sec
sbc header+HDR_BBASE
sta bssd
tya
sbc header+HDR_BBASE+1
sta bssd+1
lda header+HDR_ZLEN
jsr zalloc
bcs no_zero
sta zeroa
sec
sbc header+HDR_ZBASE
sta zerod
lda #0
sta zerod+1
jmp do_load
&no_file lda zeroa
jsr zfree
no_zero ldx bssb
jsr bfree
no_bss ldx datab
jsr bfree
no_data ldx textb
jsr bfree
no_text rts
do_load ; load options (i.e. ignore them now)
jsr fgetc
bcs no_file
cmp #0
beq load_text
tay
dey
optl jsr fgetc
bcs no_file
dey
bne optl
beq do_load
load_text ; load text segment
ldx file
lda #<texta
ldy #>texta
jsr fgetb
bcs no_file
ldx file
lda #<dataa
ldy #>dataa
jsr fgetb
bcs no_file
; check number of undefined references
ldx file
jsr fgetc
&no_file2 bcs no_file
cmp #0
bne no_file ; we have some -> not handled
ldx file
jsr fgetc
bcs no_file
cmp #0
bne no_file
; ok, text segments loaded, now relocate
lda texta
sec
sbc #1
sta p1
lda texta+1
sbc #0
sta p1+1
jsr trel
lda dataa
sec
sbc #1
sta p1
lda dataa+1
sbc #0
sta p1+1
jsr trel
lda texta ; return start of text segment
ldy texta+1
clc
rts
.)
trel .(
ldx file
jsr fgetc
no_file1 bcs no_file2
cmp #0
beq reloc_rts
cmp #255
bne t1
lda #254
clc
adc p1
sta p1
bcc trel
inc p1+1
jmp trel
t1 clc
adc p1
sta p1
bcc t1a
inc p1+1
t1a ; p1 is the relocation address
ldx file
jsr fgetc
bcs no_file1
tay
and #A_MASK
sta tmp
tya
and #A_FMASK
jsr getreldiff
ldy tmp
cpy #A_ADR
bne t2
ldy #0
clc
adc (p1),y
sta (p1),y
iny
txa
adc (p1),y
sta (p1),y
jmp trel
t2
cpy #A_LOW
bne t3
ldy #0
clc
adc (p1),y
sta (p1),y
jmp trel
t3
cpy #A_HIGH
bne trel
sta p2
stx p2+1
ldx file
jsr fgetc
clc
adc p2 ; just get the carry bit
ldy #0
lda p2+1 ; relocate high byte
adc (p1),y
sta (p1),y
jmp trel
reloc_rts
clc
rts
.)
getreldiff .( ; comparing with SEG_UNDEF would give a way
; to get label value here for undefined refs
cmp #SEG_TEXT
bne notext
lda textd
ldx textd+1
rts
notext cmp #SEG_DATA
bne nodata
lda datad
ldx datad+1
rts
nodata cmp #SEG_BSS
bne nobss
lda bssd
ldx bssd+1
rts
nobss cmp #SEG_ZERO
bne nozero
lda zerod
ldx zerod+1
nozero rts
.)
.)
/**************************************************************************
* Here come the support routines
*
* first is a simple and basic implementation of fgetb, just using fgetc
*/
fgetb .(
p =syszp
-syszp +=2
file =sysmem
l =sysmem+1
-sysmem +=3
stx file ; x=file, a=zp-adr of address, y=zp-adr of len
sta p
sty p+1
ldy #3
lda (p),y
sta l+1
dey
lda (p),y
sta l
dey
lda (p),y
pha
dey
lda (p),y
sta p
pla
sta p+1
loop ldx file
jsr fgetc ; this is a simple implementation
bcs end
ldy #0
sta (p),y
inc p
bne l0
inc p+1
l0
lda l
bne l1
dec l+1
l1 dec l
lda l
ora l+1
bne loop
clc
end
rts
.)
/**************************************************************************
* support for memory allocation
*
* These routines are taken from a preliminary SLIP implementation, as of
* OS/A65 version 1.3.10b
*/
#define MAXSLOT 8
/**********************************************************************/
/* New memory management for IP buffers */
/* exports */
/* binit */
/* balloc, bfree, btrunc, bsplit, brealloc */
/* getbadr, getblen */
#define MINBUF 8
#define MINMASK %11111000
.(
slotladr =sysmem
slothadr =sysmem+MAXSLOT
slotllen =sysmem+MAXSLOT*2
slothlen =sysmem+MAXSLOT*3
-sysmem +=MAXSLOT*4
flist =sysmem
slot =sysmem+2
-sysmem +=3
p =syszp
p2 =syszp+2
p3 =syszp+4
p4 =syszp+6
-syszp +=8
/* init memory management */
&binit .(
sta p+1 ; hi byte startadress buffer
stx p2+1 ; hi byte length of buffer
lda #0
tay
l0 sta slotladr,y
sta slothadr,y
iny
cpy #MAXSLOT
bcc l0
sta p
tay
sta (p),y
iny
sta (p),y
iny
sta (p),y
iny
lda p2+1
sta (p),y
lda p
sta flist
lda p+1
sta flist+1
clc
rts
.)
/* a/y = size of buffer to be allocated -> x buffer-ID */
&balloc .(
/* walk along freelist, and take first matching buffer
length is made a multiple of 8 (for freelist connectors */
pha
jsr getbslot
pla
bcc gotslot
lda #E_NOMEM
rts
gotslot
stx slot
adc #MINBUF-1
and #MINMASK
sta slotllen,x
tya
adc #0
sta slothlen,x
lda #0
sta p2
sta p2+1
lda flist
sta p
lda flist+1
sta p+1
l0
ldy #2
lda (p),y
sec
sbc slotllen,x
sta p3
iny
lda (p),y
sbc slothlen,x
sta p3+1
bcs found
lda p
sta p2
lda p+1
sta p2+1
ldy #1
lda (p2),y
sta p+1
dey
lda (p2),y
sta p
ora p+1
bne l0
oops lda #E_NOMEM
sec
rts
found
/* ok, we found a free buffer: p points to the buffer, p2 to the
previous one. p3 is the length of the free buffer minus the
needed size. If the buffer is longer than needed, create a
new free buffer, then link new buffer to freelist */
lda p /* save buffer address */
sta slotladr,x
lda p+1
sta slothadr,x
lda p3 /* check length */
ora p3+1
beq nocreate
lda p /* get address of new free buffer */
clc
adc slotllen,x
sta p4
lda p+1
adc slothlen,x
sta p4+1
ldy #0 /* copy next pointer */
lda (p),y
sta (p4),y
iny
lda (p),y
sta (p4),y
iny /* set new length */
lda slotllen,x
sta (p),y
lda p3
sta (p4),y
iny
lda slothlen,x
sta (p),y
lda p3+1
sta (p4),y
lda p4
sta p
lda p4+1
sta p+1
nocreate
lda p2
ora p2+1
beq freestart
ldy #0
lda p
sta (p2),y
iny
lda p+1
sta (p2),y
clc
bcc geta
freestart
lda p
sta flist
lda p+1
sta flist+1
clc
geta
lda slotladr,x
ldy slothadr,x
rts
.)
/* free buffer (ID=xr) */
&bfree .(
lda slothadr,x
sta p3+1
lda slotladr,x
sta p3
ora p3+1
beq end2
ldy #2
lda slotllen,x
sta (p3),y
iny
lda slothlen,x
sta (p3),y
lda #0
sta slothadr,x
sta slotladr,x
lda flist
ora flist+1
bne ok /* no free buffer so far? */
lda p3
sta flist
lda p3+1
sta flist+1
ldy #0
tya
sta (p3),y
iny
sta (p3),y
end2 clc
rts
ok
lda #0
sta p2
sta p2+1
lda flist
sta p
lda flist+1
sta p+1
/* we have to find the place where to put the buffer in the
ordered free list. Then we have to check if we can merge
free buffers */
loop
lda p3+1
cmp p+1
bcc found
bne next
lda p3
cmp p
bcc found
next
lda p
sta p2
lda p+1
sta p2+1
ldy #0
lda (p2),y
sta p
iny
lda (p2),y
sta p+1
ora p
bne loop
beq found
end
clc
rts
found /* p2 is the buffer before the one to be freed, p the one behind.
p3 is the buffer to be inserted */
lda p2
ora p2+1
bne fok
; insert before the first free buffer so far
ldy #0
lda flist
sta (p3),y
iny
lda flist+1
sta (p3),y
lda p3
sta flist
ldy p3+1
sty flist+1
jsr bmerge
clc
rts
fok ; insert to list
ldy #1
lda p+1 ;lda (p2),y
sta (p3),y
dey
lda p ;lda (p2),y
sta (p3),y
lda p3
sta (p2),y
iny
lda p3+1
sta (p2),y
lda p3
ldy p3+1
jsr bmerge
lda p2
ldy p2+1
jsr bmerge
clc
rts
.)
/* get adress of buffer */
&getbadr .(
lda slotladr,x
ldy slothadr,x
clc
rts
.)
/* get length of buffer */
&getblen .(
lda slotllen,x
ldy slothlen,x
clc
rts
.)
/* get free buffer-ID slot */
getbslot .(
ldx #0
l0
clc
lda slotladr,x
ora slothadr,x
beq found
inx
cpx #MAXSLOT
bcc l0
found
rts
.)
/* check if two buffers (i.e. a/y plus following) can be merged */
bmerge .(
sta p
sty p+1
ldy #2
clc
lda (p),y
adc p
sta p3
iny
lda (p),y
adc p+1
sta p3+1
ldy #0
lda (p),y
cmp p3
bne nomerge
iny
lda (p),y
cmp p3+1
bne nomerge
merge
ldy #2
clc
lda (p3),y
adc (p),y
sta (p),y
iny
lda (p3),y
adc (p),y
sta (p),y
ldy #0
lda (p3),y
sta (p),y
iny
lda (p3),y
sta (p),y
nomerge
clc
rts
.)
.)
PRGEND

Binary file not shown.

View File

@ -1,36 +0,0 @@
.fopt 1, "filename"
.(
.text
&absv = 4
lda #>test+4
bne test
*=$8000 ;*
lda <test
lo bvc lo
*=
test
lda (0),y
jmp (test)
.word *
.data
+bla
.word test
.byt <test-8, >test-8
.)
.text
nop
; .fopt 1, "filename"
lda bsslab
lda zerolab
lda #absv*2
.bss
bsslab
.dsb 20,1
.zero
zerolab
.dsb 20

View File

@ -1,28 +0,0 @@
*=$8000
.(
; .text
lda #>test+4
bne test
;*=*
lda <test
;*=
test
lda (0),y
jmp (test)
; .data
+bla
.word test
.byt <test-1, >test-1
.)
; .text
nop
lda bsslab
lda zerolab
; .bss
bsslab
.dsb 20,1
; .zero
zerolab
.dsb 20

View File

@ -1,3 +0,0 @@
lda #label
lab2

View File

@ -1,13 +1,21 @@
XA=../../xa
OBJS=test1 test2 test3 test4 test5 test6 test6a test6b test7
OBJS=test1.u test2.u test3.u test4.u test5.u test6.u test6a.u test6b.u test7.u
all: $(OBJS)
clean:
rm -f a.o65 $(OBJS)
%: %.a65 %.o65
${XA} -XC $< -o $@
../hextool -cmp=$@.o65 < $@
#%: %.a65 %.o65
# ${XA} -XC $< -o $@
# ../hextool -cmp=$@.o65 < $@
# BSD make only understands suffix rules
.SUFFIXES: .u .a65
.a65.u:
${XA} -XC $< -o $@
../hextool -cmp=$*.o65 < $@

View File

@ -9,22 +9,22 @@ tests: mixabs1 mixabs2 mix1 mix2
mixabs1: mixabsolute.a65
@echo This should fail
${XA} $< || exit 0 && exit 1
${XA} mixabsolute.a65 || exit 0 && exit 1
mixabs2: mixabsolute.a65
${XA} -R $< -o $@.tmp
${XA} -R mixabsolute.a65 -o $@.tmp
../../file65 -v $@.tmp
../../reloc65 -bt 40960 -o $@ $@.tmp
../hextool -cmp=b.ok < $@
mix1: mix1.a65
${XA} -R -o $@.o65 $<
${XA} -R -o $@.o65 mix1.a65
../../file65 -v $@.o65
../../reloc65 -X -o $@ $@.o65
../hextool -cmp=$@.ok < $@.o65
mix2: mix2.a65
${XA} -R -o $@.o65 $<
${XA} -R -o $@.o65 mix2.a65
../../file65 -v $@.o65
../../reloc65 -X -o $@ $@.o65
../hextool -cmp=$@.ok < $@.o65

View File

@ -18,46 +18,46 @@ bannerf:
undef1: undef.a65
@echo These should fail
${XA} $< || exit 0 && exit 1
${XA} -R $< || exit 0 && exit 1
${XA} -R -U -DFAIL $< || exit 0 && exit 1
${XA} -R -Ll1 -Ll3 -Ll4 -Ll5 $< || exit 0 && exit 1
${XA} undef.a65 || exit 0 && exit 1
${XA} -R undef.a65 || exit 0 && exit 1
${XA} -R -U -DFAIL undef.a65 || exit 0 && exit 1
${XA} -R -Ll1 -Ll3 -Ll4 -Ll5 undef.a65 || exit 0 && exit 1
undef2: undef.a65
${XA} -R -Ll1 -Ll3 $< -o $@.tmp
${XA} -R -Ll1 -Ll3 undef.a65 -o $@.tmp
../../reloc65 -bt 40960 -o $@ $@.tmp
../hextool -cmp=undef2.ok < $@
undef3: undef.a65
${XA} -R -U $< -o $@.tmp
${XA} -R -U undef.a65 -o $@.tmp
../../reloc65 -bt 40960 -o $@ $@.tmp
../hextool -cmp=undef2.ok < $@
undef4: undef4.a65
@echo These should fail
${XA} $< || exit 0 && exit 1
${XA} -R $< || exit 0 && exit 1
${XA} -R -Ll1 $< || exit 0 && exit 1
${XA} -R -U $< || exit 0 && exit 1
${XA} undef4.a65 || exit 0 && exit 1
${XA} -R undef4.a65 || exit 0 && exit 1
${XA} -R -Ll1 undef4.a65 || exit 0 && exit 1
${XA} -R -U undef4.a65 || exit 0 && exit 1
undef5f: undef5.a65
@echo These should fail
${XA} $< || exit 0 && exit 1
${XA} -R $< || exit 0 && exit 1
${XA} -R -Ll1 $< || exit 0 && exit 1
${XA} undef5.a65 || exit 0 && exit 1
${XA} -R undef5.a65 || exit 0 && exit 1
${XA} -R -Ll1 undef5.a65 || exit 0 && exit 1
undef5: undef5.a65
${XA} -R -U $< -o $@
${XA} -R -U undef5.a65 -o $@
../hextool -cmp=undef5.ok < $@
undef6f: undef6.a65
@echo These should fail
${XA} $< || exit 0 && exit 1
${XA} -R $< || exit 0 && exit 1
${XA} -R -Ll1 $< || exit 0 && exit 1
${XA} undef6.a65 || exit 0 && exit 1
${XA} -R undef6.a65 || exit 0 && exit 1
${XA} -R -Ll1 undef6.a65 || exit 0 && exit 1
undef6: undef6.a65
${XA} -R -U $< -o $@
${XA} -R -U undef6.a65 -o $@
../hextool -cmp=undef6.ok < $@
clean: