From f252a45378164c85307d3cfe5202df42d96c1649 Mon Sep 17 00:00:00 2001 From: Rainer Buchty Date: Fri, 31 Jul 2015 15:43:33 +0200 Subject: [PATCH 1/3] resynced with HS, declobbered CONST statement --- f9dasm.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/f9dasm.c b/f9dasm.c index afe89ae..acef525 100644 --- a/f9dasm.c +++ b/f9dasm.c @@ -97,9 +97,12 @@ V1.75 2015-07-26 Only install system vector labels if they aren't defined in an info file INSERT, COMMENT, PREPCOMM without address range can be used to prepend text to the output, too PREPEND without address now works like normal PREPEND - it adds BEFORE the first line + V1.76 2015-07-31 (RB) declobbered CONST(ANT) + * CONST now works regardless of data type (formerly not possible with WORD data) + */ -#define ID "1.75" +#define ID "1.76" #if RB_VARIANT #define VERSION ID "-RB" @@ -132,6 +135,8 @@ /* RB: new vector datatypes */ #define DATATYPE_DVEC 0x0100 #define DATATYPE_CVEC 0x0200 +/* RB: const needs to be unclobbered -- can be hex, bin, word, ...) */ +#define AREATYPE_CONST 0x0400 #define AREATYPE_CLABEL 0x01 #define AREATYPE_LABEL 0x02 @@ -144,14 +149,17 @@ #define AREATYPE_DEC (AREATYPE_DATA | DATATYPE_DEC) #define AREATYPE_HEX (AREATYPE_DATA | DATATYPE_HEX) #define AREATYPE_CHAR (AREATYPE_DATA | DATATYPE_CHAR) -#define AREATYPE_CONST (AREATYPE_CODE | AREATYPE_DATA) + +/* RB: this used to be AREA_CONST, but in fact its CODA ... */ +#define AREATYPE_CODA (AREATYPE_CODE | AREATYPE_DATA) /* RB: new vector areatypes */ #define AREATYPE_DVEC (AREATYPE_WORD | DATATYPE_DVEC) #define AREATYPE_CVEC (AREATYPE_WORD | DATATYPE_CVEC) -#define IS_CODE(address) ((ATTRBYTE(address)&AREATYPE_CONST)==AREATYPE_CODE) -#define IS_DATA(address) ((ATTRBYTE(address)&AREATYPE_CONST)==AREATYPE_DATA) +/* RB: CODE/DATA now derived from CODA, not CONST anymore) */ +#define IS_CODE(address) ((ATTRBYTE(address)&AREATYPE_CODA)==AREATYPE_CODE) +#define IS_DATA(address) ((ATTRBYTE(address)&AREATYPE_CODA)==AREATYPE_DATA) #define IS_CONST(address) ((ATTRBYTE(address)&AREATYPE_CONST)==AREATYPE_CONST) #define SET_USED(address) used[(address) / 8] |= (1 << ((address) % 8)) From 8154b56f9d051da1108cd1772f7cb9a695f1f255 Mon Sep 17 00:00:00 2001 From: Rainer Buchty Date: Tue, 8 Mar 2016 11:39:15 +0100 Subject: [PATCH 2/3] init work on banking --- f9dasm.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/f9dasm.c b/f9dasm.c index acef525..4a190e8 100644 --- a/f9dasm.c +++ b/f9dasm.c @@ -35,7 +35,7 @@ */ #ifndef RB_VARIANT - #define RB_VARIANT 0 + #define RB_VARIANT 1 #endif /* History, as far as I could retrace it: @@ -99,10 +99,18 @@ PREPEND without address now works like normal PREPEND - it adds BEFORE the first line V1.76 2015-07-31 (RB) declobbered CONST(ANT) * CONST now works regardless of data type (formerly not possible with WORD data) - + V1.77 2016-02-25 (RB) added support for banked code [in work] + * new directive: bdef[ine] name phys-addr size cpu-addr + * defines a new bank named "name" of size "size" at CPU-seen address "cpu-addr" that belongs to ROM/RAM physical address "phys-address" + * new directive: bass[ign] name from[-to] name_dst + * assigns address(-region) from(-to) to bank "name_dst" and gives it a descriptive name "name" used in disassembly + * label and data-type declaration get optinal parameter "bank name" so that declarations are added to the banked labels, not the master label + * code/data disassembly checks whether current ROM address is found in bdef_t list, then uses ORG/PHASE from there + * code/data disassembly checks whether current ROM address is found in bass_t, then uses operand label name from linked bdef_t->labels + */ -#define ID "1.76" +#define ID "1.77" #if RB_VARIANT #define VERSION ID "-RB" @@ -137,6 +145,8 @@ #define DATATYPE_CVEC 0x0200 /* RB: const needs to be unclobbered -- can be hex, bin, word, ...) */ #define AREATYPE_CONST 0x0400 +/* RB: banked memory area requires own declaration */ +#define AREATYPE_BANKED 0x0800 #define AREATYPE_CLABEL 0x01 #define AREATYPE_LABEL 0x02 @@ -184,6 +194,10 @@ #define IS_DVEC(address) (ATTRBYTE(address) & DATATYPE_DVEC) #define IS_CVEC(address) (ATTRBYTE(address) & DATATYPE_CVEC) +/* RB: bank check */ +#define IS_BANK(address) (ATTRBYTE(address) & AREATYPE_BANKED)==AREATYPE_BANKED) +#define NUM_BANKS(address) (ATTRBYTE(address) & 0xff) + #ifndef TYPES #define TYPES typedef unsigned char byte; @@ -215,6 +229,31 @@ typedef struct _phasedef /* data for a phase */ unsigned short rel; } phasedef; +/* bank definition + * filled by: bdef[ine] name org_phy size org_cpu + * during INFO file parsing: *labels=calloc(sizeof(int)*size) + */ +typedef struct + { + char *name; /* bank name */ + int size; /* bank size */ + int org_cpu; /* CPU-seen base address of banked area */ + int org_phy; /* physical base address for currently disassembled ROM address */ + int *labels; /* dynamically malloc'ed labels for bank: labels = malloc(sizeof(int)*size)) */ + } bdef_t; + +/* bank assignment definition + * filled by: bass[ign] bank_name addr_start[-addr_end] + * bank_name is resolved to corresponding bdef_t *bank during INFO file parsing + */ +typedef struct + { + int addr_start; /* start address */ + int addr_end; /* end address */ + bdef_t *bank; /* referenced bank */ + } bass_t; + + /*****************************************************************************/ /* Global Data */ /*****************************************************************************/ From 67f71bfb8525ff277f65f51f047e85a2a598b31c Mon Sep 17 00:00:00 2001 From: Rainer Buchty Date: Fri, 11 Mar 2016 00:11:21 +0100 Subject: [PATCH 3/3] label parser works --- f9dasm.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 218 insertions(+), 15 deletions(-) diff --git a/f9dasm.c b/f9dasm.c index 4a190e8..b0812c4 100644 --- a/f9dasm.c +++ b/f9dasm.c @@ -107,7 +107,11 @@ * label and data-type declaration get optinal parameter "bank name" so that declarations are added to the banked labels, not the master label * code/data disassembly checks whether current ROM address is found in bdef_t list, then uses ORG/PHASE from there * code/data disassembly checks whether current ROM address is found in bass_t, then uses operand label name from linked bdef_t->labels - + * + * todo: + * 1) [x] data structures + * 2) label parser for bdef / bass + * 3) hook into disassembler */ #define ID "1.77" @@ -143,10 +147,19 @@ /* RB: new vector datatypes */ #define DATATYPE_DVEC 0x0100 #define DATATYPE_CVEC 0x0200 + /* RB: const needs to be unclobbered -- can be hex, bin, word, ...) */ #define AREATYPE_CONST 0x0400 -/* RB: banked memory area requires own declaration */ -#define AREATYPE_BANKED 0x0800 + +/* RB: banked code area requires own declaration */ +#define AREATYPE_BCODE 0x0800 + +/* RB: banked operands might appear, too, with banking independent of code bank */ +#define AREATYPE_BDATA 0x1000 + +/* RB: banked regions have a start and an end */ +#define AREATYPE_BSTART 0x2000 +#define AREATYPE_BEND 0x4000 #define AREATYPE_CLABEL 0x01 #define AREATYPE_LABEL 0x02 @@ -195,7 +208,10 @@ #define IS_CVEC(address) (ATTRBYTE(address) & DATATYPE_CVEC) /* RB: bank check */ -#define IS_BANK(address) (ATTRBYTE(address) & AREATYPE_BANKED)==AREATYPE_BANKED) +#define IS_BCODE(address) ((ATTRBYTE(address) & AREATYPE_BCODE) == AREATYPE_BCODE) +#define IS_BDATA(address) ((ATTRBYTE(address) & AREATYPE_BDATA) == AREATYPE_BDATA) +#define IS_BSTART(address) ((ATTRBYTE(address) & AREATYPE_BSTART) == AREATYPE_BSTART) +#define IS_BEND(address) ((ATTRBYTE(address) & AREATYPE_BEND) == AREATYPE_BEND) #define NUM_BANKS(address) (ATTRBYTE(address) & 0xff) #ifndef TYPES @@ -242,7 +258,14 @@ typedef struct int *labels; /* dynamically malloc'ed labels for bank: labels = malloc(sizeof(int)*size)) */ } bdef_t; -/* bank assignment definition +/* banks container */ +typedef struct + { + int max; /* number of elements stored */ + bdef_t *def; /* pointer to definitions */ + } banks_t; + +/* bank/operand assignment definition * filled by: bass[ign] bank_name addr_start[-addr_end] * bank_name is resolved to corresponding bdef_t *bank during INFO file parsing */ @@ -253,7 +276,7 @@ typedef struct bdef_t *bank; /* referenced bank */ } bass_t; - + /*****************************************************************************/ /* Global Data */ /*****************************************************************************/ @@ -299,6 +322,7 @@ unsigned begin = 0xffff, end = 0, offset = 0; int load = -1; static char *loaded[200] = {0}; char *sLoadType = ""; + /* RB: get a divider after BRA/JMP/SWIx/RTS/RTI/PULx PC */ int optdelimbar = FALSE; @@ -312,6 +336,11 @@ int noLoadLabel = FALSE; char *vec_6801[] = {"IRQ_SCI","IRQ_T0F","IRQ_OCF","IRQ_ICF","IRQ_EXT","SWI","NMI","RST"}; char *vec_6809[] = {"DIV0","SWI3","SWI2","FIRQ","IRQ","SWI","NMI","RST"}; +/* RB: banking variables */ +banks_t banks={0,NULL}; /* container for all bank definitions */ +int *label_bcode = NULL; /* like *label, but holding address-to-bank assignment */ +int *label_bdata = NULL; /* like *label, but holding operand-to-bank assignment */ + enum /* available options */ { OPTION_BEGIN, @@ -1935,7 +1964,7 @@ if ((nDigits == 2) && /* if 2-digit value */ #if RB_VARIANT sprintf(s, "'%c'", W); #else - sprintf(s, "'%c", W); + sprintf(s, "'%c", W); /* RB: shouldn't this close somewhere? check! */ #endif else sprintf(s, "$%02x", W); @@ -1980,6 +2009,8 @@ return s; /* label_string : eventually converts a word to a string */ /*****************************************************************************/ +/* RB: should respect banking -- addr is PC at time of calling */ + char *label_string(word W, int bUseLabel, word addr) { static char szOut[256]; @@ -3119,6 +3150,8 @@ wfCur = ShowMemFlags(pc) & /* get flags for current byte */ for (end = pc + 1; ; end++) /* find end of block */ { + + /* RB: respect banking here */ if(IS_LABEL(end)) /* RB: don't overrun labels ... */ { /* HS: unless they're displacements! */ char *slabel = label_string((word)end, 1, (word)end); @@ -3243,7 +3276,6 @@ printf("\n" "\tdon't apply label name to constant but treat it as a number\n" "\t\t\t CONST from[-to]\n" "\tmark auto-generated label as used\n" - "\t\t\t USED[LABEL] addr\n" "\nCommenting\n" "\tcomment: COMM[ENT] addr[-addr] text\n" "\tsuppress comments: UNCOMM[ENT] addr[-addr] text\n" @@ -3291,6 +3323,9 @@ printf("\n" "UNREL[ATIVE] addr[-addr]\n" "REMAP addr[-addr] offset\n" "PHASE addr[-addr] phase\n" + "BDEF[ine] name phys_org size cpu_org\n" + "BCODE name addr[-addr]\n" + "BDATA name addr[-addr]\n" "END\n" #endif ); @@ -4196,10 +4231,15 @@ enum infoRelative, /* RELATIVE addr[-addr] rel */ infoUnRelative, /* UNRELATIVE addr[-addr] */ infoPrepLComment, /* PREPLCOMM addr[-addr] [.]lcomment */ - infoRemap, /* REMAP addr[-addr] offs */ infoFile, /* FILE filename */ + infoRemap, /* REMAP addr[-addr] offs */ infoPhase, /* PHASE addr[-addr] phase */ + /* RB: bank define / bank assign / operand assign directives */ + infoBdef, /* BDEF[INE] name phys-addr size cpu-addr */ + infoBcode, /* BCODE name from[-to] name_dst */ + infoBdata, /* BDATA name from[-to] name_dst */ + /* RB: new vector label types */ infoCVector, /* CVEC[TOR] addr[-addr] */ infoDVector, /* DVEC[TOR] addr[-addr] */ @@ -4260,6 +4300,12 @@ static struct /* structure to convert key to type */ { "FILE", infoFile }, { "PHASE", infoPhase }, + /* RB: bank define / bank assign */ + { "BDEF", infoBdef }, + { "BDEFINE", infoBdef }, + { "BCODE", infoBcode }, + { "BDATA", infoBdata }, + /* RB: new vector label types */ { "CVECTOR", infoCVector }, { "CVEC", infoCVector }, @@ -4947,6 +4993,136 @@ while (fgets(szBuf, sizeof(szBuf), fp)) loadfile(fname, &begin, &end, &load, nFrom, outfile); } break; + + case infoBdef: /* BDEF bank_name phys_addr bank_size cpu_addr */ + { + char *bname=p; + int pbase, psize, cbase; + int found=0; + + /* get/set name end */ + for (; (*p) && (*p != ' ' ) && (*p != '\t'); p++); + if(*p) *p++='\0'; + + /* get phys base addr of bank */ + q = p; + for (; (*p) && (*p != ' ' ) && (*p != '\t'); p++); + if(*p) *p++='\0'; + sscanf(q, "%x", &pbase); + + /* get bank size */ + q = p; + for (; (*p) && (*p != ' ' ) && (*p != '\t'); p++); + if(*p) *p++='\0'; + sscanf(q, "%x", &psize); + + /* get cpu base addr of bank */ + q = p; + for (; (*p) && (*p != ' ' ) && (*p != '\t'); p++); + if(*p) *p++='\0'; + sscanf(q, "%x", &cbase); + + /* check for redefinition */ + for(i=0; i nTo) || (nTo >= 0x10000)) + break; + + /* check for presence */ + for(i=0; i=0) + { + for(i=nFrom; i<=nTo; i++) + { + /* bcode: banked code -- address shift */ + if(nType==infoBcode) + { + label[i]=AREATYPE_BCODE; + label_bcode[i]=found; + } + + /* bdata: banked data -- operand address shift */ + else + { + label[i]=AREATYPE_BDATA; + label_bdata[i]=found; + } + + /* mark start/end of region for easier parsing in disassembler */ + if(i==nFrom) label[i]|=AREATYPE_BSTART; + else if(i==nTo) label[i]|=AREATYPE_BEND; + + } + } + else fprintf(stderr,"Unable to find definition of bank \"%s\", skipping bank assignment statement.\n",bname); + } + break; + case infoPhase : /* PHASE addr[-addr] phase */ { char *laddr = p; @@ -5038,21 +5214,27 @@ for (i = 1, n = 0; i < argc; ++i) memory = (byte *)malloc(0x10000); label = (int *)malloc(0x10000 * sizeof(int)); -used = (byte *)malloc(0x10000 / 8); lblnames = (char **)malloc(0x10000 * sizeof(char *)); +used = (byte *)malloc(0x10000 / 8); commentlines = (char **)malloc(0x10000 * sizeof(char *)); lcomments = (char **)malloc(0x10000 * sizeof(char *)); rels = (unsigned short *)malloc(0x10000 * sizeof(unsigned short)); dps = (short *)malloc(0x10000 * sizeof(short)); phases = (phasedef *)malloc(MAXPHASES * sizeof(phasedef)); remaps = (int *)malloc(0x10000 * sizeof(int)); -if ((!memory) || (!label) || (!used) || - (!lblnames) || (!commentlines) || (!lcomments) || - (!rels) || (!phases) || (!dps) || (!remaps)) +label_bcode = (int *)malloc(0x10000 * sizeof(int)); +label_bdata = (int *)malloc(0x10000 * sizeof(int)); +if ( + (!memory) || (!label) || (!used) || (!lblnames) || + (!commentlines) || (!lcomments) || (!rels) || (!phases) || + (!dps) || (!remaps) || (!label_bcode) || (!label_bdata) + ) { - printf("no mem buffer\n"); + printf("No mem buffer\n"); goto exit; } +memset(label_bcode, -1, 0x10000 * sizeof(int *)); /* RB: index to bdef, -1 means unused */ +memset(label_bdata, -1, 0x10000 * sizeof(int *)); /* RB: index to bdef, -1 means unused */ memset(memory, 0x01, 0x10000); memset(label, 0x00, 0x10000 * sizeof(int)); memset(used, 0x00, 0x10000 / 8); @@ -5068,7 +5250,7 @@ if (outname) out = fopen(outname,"w"); if (!out) { - printf("can't open %s \n",outname); + printf("Can't open %s \n",outname); return 1; } fprintf(out, @@ -5407,6 +5589,13 @@ do fprintf(out, " %-7s\n\n", "DEPHASE"); } } + + /* RB: does a banked code area start? */ + if( IS_BCODE(pc) && IS_BSTART(label[pc]) ) + { + fprintf(out, " %-7s $%02X\n\n", "ORG", banks.def[label_bcode[pc]].org_cpu); + fprintf(out, " %-7s $%02X\n\n", "PHASE", banks.def[label_bcode[pc]].org_phy); + } if (commentlines[pc]) { @@ -5420,6 +5609,11 @@ do } } + /* this needs to be reworked: + * 1) unbanked -> IS_LABEL(pc) + * 2) banked code -> IS_LABEL(banks.def[label_bcode[pc]].org_cpu + pc-banks.def[label_bcode[pc]].org_phys) to shift pc to actual cpu address + */ + if (IS_LABEL(pc)) /* if any label here */ { if ((strchr(slabel, '+')) || @@ -5445,6 +5639,11 @@ do else llen = fprintf(out, "%-*s ", 7, ""); + /* RB: ShowData() and Dasm() need to respect code/data banking * + * 1) unbanked -> IS_xxxx(pc) + * 2) banked code -> IS_xxxx(banks.def[label_bcode[pc]].org_cpu + pc-banks.def[label_bcode[pc]].org_phys) to shift pc to actual cpu address + * 3) ShowData / Dasm need to know proper reference + */ if (IS_CONST(pc) || IS_DATA(pc)) { add = ShowData(out, pc, (nComment || lcomments[pc])); @@ -5510,6 +5709,10 @@ do curphase != GetPhaseDef((word)pc)) fprintf(out, "\n %-*s\n\n", 7, "DEPHASE"); + /* RB: does a banked code area end? */ + if( IS_BCODE(pc) && IS_BEND(label[pc]) ) + fprintf(out, " %-7s\n\n", "DEPHASE"); + if ((pc < 0x10000) && /* only if still in range, */ (!IS_USED(pc - 1))) /* if we DID skip something set ORG */ fprintf(out, "\n %-*s $%04X \n\n", 7, "ORG", pc);