+// dc.b, dc.w / dc, dc.l, dc.i, dc.q, dc.d
+//
+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 && (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;
+
+ 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)
+ {
+ if (movei)
+ AddFixup(FU_LONG | FU_MOVEI, sloc, exprbuf);
+ else
+ AddFixup(FU_LONG, 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);
+
+ // Shamus: We only handle DC.Q type stuff, will have to add fixups
+ // and stuff later (maybe... might not be needed...)
+ // DEFINITELY NEED FIXUPS HERE!
+ if (!defined)
+ {
+ AddFixup(FU_QUAD, sloc, exprbuf);
+ D_quad(0LL);
+ }
+ else
+ {
+ D_quad(eval);
+ }
+
+ break;
+ case SIZS:
+ // 32-bit float size
+ if (m6502)
+ return error(in_6502mode);
+
+ if (!defined)
+ {
+ AddFixup(FU_FLOATSING, sloc, exprbuf);
+ D_long(0);
+ }
+ 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);
+ }
+ 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);
+ }
+ 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;
+ }
+
+ at_eol();
+ return 0;
+}
+
+