- VALUE address;
-
- if (!rgpu && !rdsp && !m6502)
- return error(".org permitted only in gpu/dsp and 6502 sections");
-
- if (rgpu | rdsp)
- {
- orgaddr = 0;
-
- if (abs_expr(&address) == ERROR)
- {
- error("cannot determine org'd address");
- return ERROR;
- }
-
- orgaddr = address;
- orgactive = 1;
- //printf("ORG: address = $%08X...\n", orgaddr);
-
- return 0;
- }
- else
- {
- // 6502
- // We also kludge `lsloc' so the listing generator doesn't
- // try to spew out megabytes.
- VALUE eval;
-
- //if (m6502 == 0) return error(".org permitted only in .6502 section");
- if (abs_expr(&eval) < 0) return 0;
- if (eval >= 0x10000L) return error(range_error);
-
- if (sloc != currentorg[0])
- {
- currentorg[1] = sloc;
- currentorg += 2;
- }
-
- currentorg[0] = eval;
- ch_size = 0;
- lsloc = sloc = eval;
- chptr = scode->chptr + eval;
- orgactive = 1;
- orgaddr = eval;
- at_eol();
- return 0;
- }
+ uint64_t address;
+
+ if (!rgpu && !rdsp && !robjproc && !m6502 && !dsp56001)
+ return error(".org permitted only in GPU/DSP/OP, 56001 and 6502 sections");
+
+ // M56K can leave the expression off the org for some reason :-/
+ // (It's because the expression is non-standard, and so we have to look at
+ // it in isolation)
+ if (!dsp56001 && (abs_expr(&address) == ERROR))
+ {
+ error("cannot determine org'd address");
+ return ERROR;
+ }
+
+ if (rgpu | rdsp | robjproc)
+ {
+ orgaddr = address;
+ orgactive = 1;
+ }
+ else if (m6502)
+ {
+ // 6502. We also kludge 'lsloc' so the listing generator doesn't try
+ // to spew out megabytes.
+ if (address > 0xFFFF)
+ return error(range_error);
+
+ if (sloc != currentorg[0])
+ {
+ currentorg[1] = sloc;
+ currentorg += 2;
+ }
+
+ currentorg[0] = address;
+ ch_size = 0;
+ lsloc = sloc = address;
+ chptr = scode->chptr + address;
+ orgaddr = address;
+ orgactive = 1;
+ }
+ else if (dsp56001)
+ {
+ // Only mark segments we actually wrote something
+ if (chptr != dsp_currentorg->start && dsp_written_data_in_current_org)
+ {
+ dsp_currentorg->end = chptr;
+ dsp_currentorg++;
+ }
+
+ // Maybe we switched from a non-DSP section (TEXT, DATA, etc) and
+ // scode isn't initialised yet. Not that it's going to be a valid
+ // scenario, but if we try it anyhow it's going to lead to a crash. So
+ // let's fudge a value of 0 and get on with it.
+ orgaddr = (scode != NULL ? sloc : 0);
+ SaveSection();
+
+ if (tok[1] != ':')
+ return error(syntax_error);
+
+ int sectionToSwitch = 0;
+
+ switch (tok[0])
+ {
+ case KW_X:
+ dsp_currentorg->memtype = ORG_X;
+ sectionToSwitch = M56001X;
+ break;
+
+ case KW_Y:
+ dsp_currentorg->memtype = ORG_Y;
+ sectionToSwitch = M56001Y;
+ break;
+
+ case KW_P:
+ dsp_currentorg->memtype = ORG_P;
+ sectionToSwitch = M56001P;
+ break;
+
+ case KW_L:
+ dsp_currentorg->memtype = ORG_L;
+ sectionToSwitch = M56001L;
+ break;
+
+ default:
+ return error("unknown type in ORG");
+ }
+
+ if ((obj_format == LOD) || (obj_format == P56))
+ SwitchSection(sectionToSwitch);
+
+ tok += 2;
+ chcheck(3); // Ensure we got a valid address to write
+ dsp_currentorg->chunk = scode; // Mark down which chunk this org starts from (will be needed when outputting)
+
+ if (*tok == EOL)
+ {
+ // Well, the user didn't specify an address at all so we'll have to
+ // use the last used address of that section (or 0 if there wasn't one)
+ address = orgaddr;
+ dsp_currentorg->start = chptr;
+ dsp_currentorg->orgadr = orgaddr;
+ }
+ else
+ {
+ if (abs_expr(&address) == ERROR)
+ {
+ error("cannot determine org'd address");
+ return ERROR;
+ }
+
+ dsp_currentorg->start = chptr;
+ dsp_currentorg->orgadr = (uint32_t)address;
+ sect[cursect].orgaddr = (uint32_t)address;
+ }
+
+ if (address > DSP_MAX_RAM)
+ {
+ return error(range_error);
+ }
+
+ dsp_written_data_in_current_org = 0;
+
+ // Copied from 6502 above: kludge `lsloc' so the listing generator
+ // doesn't try to spew out megabytes.
+ lsloc = sloc = (int32_t)address;
+// N.B.: It seems that by enabling this, even though it works elsewhere, will cause symbols to royally fuck up. Will have to do some digging to figure out why.
+// orgactive = 1;
+ }
+
+ ErrorIfNotAtEOL();
+ return 0;