+//
+// dc.b, dc.w / dc, dc.l, dc.i, dc.q, dc.d, dc.s, dc.x
+//
+int d_dc(WORD siz)
+{
+ WORD eattr;
+ uint64_t eval;
+ uint8_t * p;
+
+ if ((scattr & SBSS) != 0)
+ return error("illegal initialization of section");
+
+ // Do an auto_even if it's not BYTE sized (hmm, should we be doing this???)
+ if ((cursect != M6502) && (cursect != M56001P) && (cursect != M56001X)
+ && (cursect != M56001Y) && (cursect != M56001L)
+ && (siz != SIZB) && (sloc & 1))
+ auto_even();
+
+ // Check to see if we're trying to set LONGS on a non 32-bit aligned
+ // address in a GPU or DSP section, in their local RAM
+ if ((siz == SIZL) && (orgaddr & 0x03)
+ && ((rgpu && (orgaddr >= 0xF03000) && (orgaddr <= 0xF03FFFF))
+ || (rdsp && (orgaddr >= 0xF1B000) && (orgaddr <= 0xF1CFFFF))))
+ warn("depositing LONGs on a non-long address in local RAM");
+
+ for(;; tok++)
+ {
+ // dc.b 'string' [,] ...
+ if (siz == SIZB && (*tok == STRING || *tok == STRINGA8) && (tok[2] == ',' || tok[2] == EOL))
+ {
+ uint32_t i = strlen(string[tok[1]]);
+
+ if ((challoc - ch_size) < i)
+ chcheck(i);
+
+ if (*tok == STRING)
+ {
+ for(p=string[tok[1]]; *p!=EOS; p++)
+ D_byte(*p);
+ }
+ else if (*tok == STRINGA8)
+ {
+ for(p=string[tok[1]]; *p!=EOS; p++)
+ D_byte(strtoa8[*p]);
+ }
+ else
+ {
+ error("String format not supported... yet");
+ }
+
+ tok += 2;
+ goto comma;
+ }
+
+ int movei = 0; // MOVEI flag for dc.i
+
+ if (*tok == DOTI)
+ {
+ movei = 1;
+ tok++;
+ siz = SIZL;
+ }
+
+ // dc.x <expression>
+ SYM * esym = 0;
+
+ if (expr(exprbuf, &eval, &eattr, &esym) != OK)
+ return 0;
+
+ uint16_t tdb = eattr & TDB;
+ uint16_t defined = eattr & DEFINED;
+
+// N.B.: This is awful. This needs better handling, rather than just bodging something in that, while works, is basically an ugly wart on the assembler. !!! FIX !!!
+ if (dsp56001)
+ {
+ if (cursect != M56001L)
+ {
+ if (!defined)
+ {
+ AddFixup(FU_DSPIMM24 | FU_SEXT, sloc, exprbuf);
+ D_dsp(0);
+ }
+ else
+ {
+ if (eattr & FLOAT)
+ {
+ double fval = *(double *)&eval;
+ eval = DoubleToDSPFloat(fval);
+ }
+ else
+ {
+ if ((uint32_t)eval + 0x1000000 >= 0x2000000)
+ return error(range_error);
+ }
+
+ // Deposit DSP word (24-bit)
+ D_dsp(eval);
+ }
+ }
+ else
+ {
+ // In L: we deposit stuff to both X: and Y: instead
+ // We will be a bit lazy and require that there is a 2nd value
+ // in the same source line. (Motorola's assembler can parse
+ // 12-digit hex values, which we can't do at the moment) This
+ // of course requires to parse 2 values in one pass. If there
+ // isn't another value in this line, assume X: value is 0.
+ int secondword = 0;
+ uint32_t evaly;
+l_parse_loop:
+
+ if (!defined)
+ {
+ AddFixup(FU_DSPIMM24 | FU_SEXT, sloc, exprbuf);
+ D_dsp(0);
+ }
+ else
+ {
+ if (eattr & FLOAT)
+ {
+ float fval = *(float *)&eval;
+ eval = DoubleToDSPFloat(fval);
+ }
+ else
+ {
+ if (eval + 0x1000000 >= 0x2000000)
+ return error(range_error);
+ }
+
+ // Parse 2nd value if we didn't do this yet
+ if (secondword == 0)
+ {
+ evaly = (uint32_t)eval;
+ secondword = 1;
+
+ if (*tok != ':')
+ {
+ // If we don't have a : then we're probably at EOL,
+ // which means the X: value will be 0
+ eval = 0;
+ ErrorIfNotAtEOL();
+ }
+ else
+ {
+ tok++; // Eat the comma;
+
+ if (expr(exprbuf, &eval, &eattr, NULL) != OK)
+ return 0;
+
+ defined = (WORD)(eattr & DEFINED);
+ goto l_parse_loop;
+ }
+ }
+
+ // Deposit DSP words (24-bit)
+ D_dsp(eval);
+ D_dsp(evaly);
+ sloc--; // We do write 2 DSP words but as far as L: space is concerned we actually advance our counter by one
+ }
+
+ }
+
+ goto comma;
+ }
+
+ switch (siz)
+ {
+ case SIZB:
+ if (!defined)
+ {
+ AddFixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
+ D_byte(0);
+ }
+ else
+ {
+ if (tdb)
+ return error("non-absolute byte value");
+
+ if (eval + 0x100 >= 0x200)
+ return error("%s (value = $%X)", range_error, eval);
+
+ D_byte(eval);
+ }
+
+ break;
+
+ case SIZW:
+ case SIZN:
+ if (!defined)
+ {
+ AddFixup(FU_WORD | FU_SEXT, sloc, exprbuf);
+ D_word(0);
+ }
+ else
+ {
+ if (eval + 0x10000 >= 0x20000)
+ return error(range_error);
+
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
+
+ // Deposit 68000 or 6502 (byte-reversed) word
+ if (cursect != M6502)
+ D_word(eval)
+ else
+ D_rword(eval)
+ }
+
+ break;
+
+ case SIZL:
+ // Shamus: Why can't we do longs in 6502 mode?
+ if (m6502)
+ return error(in_6502mode);
+
+ if (!defined)
+ {
+ AddFixup(FU_LONG | (movei ? FU_MOVEI : 0), sloc, exprbuf);
+ D_long(0);
+ }
+ else
+ {
+ if (tdb)
+ MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
+
+ if (movei)
+ eval = WORDSWAP32(eval);
+
+ D_long(eval);
+ }
+
+ break;
+
+ case SIZQ:
+ // 64-bit size
+ if (m6502)
+ return error(in_6502mode);
+
+ // DEFINITELY NEED FIXUPS HERE!
+ if (!defined)
+ {
+ AddFixup(FU_QUAD, sloc, exprbuf);
+ eval = 0;
+ }
+
+ D_quad(eval);
+ break;
+
+ case SIZS:
+ // 32-bit float size
+ if (m6502)
+ return error(in_6502mode);
+
+/* Seems to me that if something is undefined here, then that should be an error. Likewise for the D & X variants. */
+ if (!defined)
+ {
+// AddFixup(FU_FLOATSING, sloc, exprbuf);
+// D_long(0);
+ return error("labels not allowed in floating point expressions");
+ }
+ else
+ {
+//Would this *ever* happen?
+// if (tdb)
+// MarkRelocatable(cursect, sloc, tdb, MSINGLE, NULL);
+
+ PTR ptr;
+ ptr.u64 = &eval;
+ uint32_t ieee754 = FloatToIEEE754((float)*ptr.dp);
+ D_long(ieee754);
+ }
+
+ break;
+
+ case SIZD:
+ // 64-bit double size
+ if (m6502)
+ return error(in_6502mode);
+
+ if (!defined)
+ {
+// AddFixup(FU_FLOATDOUB, sloc, exprbuf);
+// D_quad(0LL);
+ return error("labels not allowed in floating point expressions");
+ }
+ else
+ {
+//Would this *ever* happen?
+// if (tdb)
+// MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
+
+ PTR ptr;
+ ptr.u64 = &eval;
+ uint64_t ieee754 = DoubleToIEEE754(*ptr.dp);
+ D_quad(ieee754);
+ }
+
+ break;
+
+ case SIZX:
+ if (m6502)
+ return error(in_6502mode);
+
+ uint8_t extDbl[12];
+ memset(extDbl, 0, 12);
+
+ if (!defined)
+ {
+// AddFixup(FU_FLOATEXT, sloc, exprbuf);
+// D_extend(extDbl);
+ return error("labels not allowed in floating point expressions");
+ }
+ else
+ {
+//Would this *ever* happen?
+// if (tdb)
+// MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
+
+ PTR ptr;
+ ptr.u64 = &eval;
+ DoubleToExtended(*ptr.dp, extDbl);
+ D_extend(extDbl);
+ }
+
+ break;
+ }
+
+comma:
+ if (*tok != ',')
+ break;
+ }
+
+ ErrorIfNotAtEOL();
+ return 0;