From: Lukas Krickl Date: Fri, 22 Dec 2023 06:38:46 +0000 (+0100) Subject: Added .chr directive to allow defining chr data X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=5da3b278bb86518541a9e51086c4b3faca26abda;p=ulas%2F.git Added .chr directive to allow defining chr data --- diff --git a/include/ulas.h b/include/ulas.h index dd48937..747ddb6 100644 --- a/include/ulas.h +++ b/include/ulas.h @@ -51,6 +51,7 @@ #define ULAS_ASMSTR_SET_ENUM_DEF ".se" #define ULAS_ASMSTR_DEFINE_ENUM ".de" #define ULAS_ASMSTR_SETCHRCODE ".scc" +#define ULAS_ASMSTR_CHR ".chr" // configurable tokens #define ULAS_TOK_COMMENT ';' @@ -400,14 +401,20 @@ enum ulas_asmdir { // .scc ''= // allows to set custom encoding for char codes // when using .str - ULAS_ASMDIR_SETCHRCODE + ULAS_ASMDIR_SETCHRCODE, + + // .chr 0, 1, 2, 3, 0, 1, 2, 3 + // allows defining + // chr (tile) data from 0-3 + // for each possible color + // it requires up to 8 integer expressions between 0 and 3 + ULAS_ASMDIR_CHR, }; // amount of registers #define ULAS_NR8 7 #define ULAS_NR16 3 - enum ulas_asmregs { // r8 ULAS_REG_B = 1, diff --git a/src/ulas.c b/src/ulas.c index 2c41378..5b48393 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -1378,7 +1378,8 @@ int ulas_tokexpr(const char **line, unsigned long n) { } // check for any expression terminators here - if (tok.type == ',' || tok.type == ']' || tok.type == '=' || ulas_istokend(&ulas.tok)) { + if (tok.type == ',' || tok.type == ']' || tok.type == '=' || + ulas_istokend(&ulas.tok)) { // on terminator we roll back line so that the terminator token // is not consumed now *line -= tokrc; @@ -2462,8 +2463,8 @@ int ulas_asmdirstr(FILE *dst, const char **line, unsigned long n, int *rc) { do { char *s = ulas_strexpr(line, n, rc); long len = strlen(s); - - // apply char code map + + // apply char code map for (int i = 0; i < len; i++) { s[i] = ulas.charcodemap[(int)s[i]]; } @@ -2529,7 +2530,7 @@ int ulas_asmdirsetcharcode(const char **line, unsigned long n) { ULASERR("Expected =\n"); return 0; } - + ULAS_EVALEXPRS(setto = ulas_intexpr(line, n, &rc)); setto = setto & 0xFF; @@ -2538,6 +2539,51 @@ int ulas_asmdirsetcharcode(const char **line, unsigned long n) { return rc; } +int ulas_asmdirchr(FILE *dst, const char **line, unsigned long n, int *rc) { + char b[2] = {0, 0}; + struct ulas_tok t; + memset(&t, 0, sizeof(t)); + int bit = 7; + ulas_tok(&ulas.tok, line, n); + + int len = strlen(ulas.tok.buf); + if (len > 8) { + *rc = -1; + ULASERR("chr input exceeds 8 pixels\n"); + return 0; + } + + for (int i = 0; i < len; i++, bit--) { + switch (ulas.tok.buf[i]) { + case '0': + // 0 sets no bit + break; + case '1': + // 1 sets 01 + b[1] |= (1 << bit); + break; + case '2': + // 2 sets 10 + b[0] |= (1 << bit); + break; + case '3': + // 3 sets 11 + b[0] |= (1 << bit); + b[1] |= (1 << bit); + break; + default: + ULASERR("Invalid chr value: '%c'. Expected 0-3.\n", ulas.tok.buf[i]); + break; + } + } + + int written = 2; + ulas_asmout(dst, b, written); + + // this always writes 2 bytes + return written; +} + int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { // this buffer is written both to dst and to verbose output char outbuf[ULAS_OUTBUFMAX]; @@ -2572,13 +2618,21 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { } if (ulas.tok.buf[0] == ULAS_TOK_ASMDIR_BEGIN) { - const char *dirstrs[] = {ULAS_ASMSTR_ORG, ULAS_ASMSTR_SET, - ULAS_ASMSTR_BYTE, ULAS_ASMSTR_STR, - ULAS_ASMSTR_FILL, ULAS_ASMSTR_PAD, - ULAS_ASMSTR_INCBIN, ULAS_ASMSTR_DEF, - ULAS_ASMSTR_CHKSM, ULAS_ASMSTR_ADV, - ULAS_ASMSTR_SET_ENUM_DEF, ULAS_ASMSTR_DEFINE_ENUM, - ULAS_ASMSTR_SETCHRCODE, NULL}; + const char *dirstrs[] = {ULAS_ASMSTR_ORG, + ULAS_ASMSTR_SET, + ULAS_ASMSTR_BYTE, + ULAS_ASMSTR_STR, + ULAS_ASMSTR_FILL, + ULAS_ASMSTR_PAD, + ULAS_ASMSTR_INCBIN, + ULAS_ASMSTR_DEF, + ULAS_ASMSTR_CHKSM, + ULAS_ASMSTR_ADV, + ULAS_ASMSTR_SET_ENUM_DEF, + ULAS_ASMSTR_DEFINE_ENUM, + ULAS_ASMSTR_SETCHRCODE, + ULAS_ASMSTR_CHR, + NULL}; enum ulas_asmdir dirs[] = { ULAS_ASMDIR_ORG, ULAS_ASMDIR_SET, ULAS_ASMDIR_BYTE, ULAS_ASMDIR_STR, @@ -2586,7 +2640,7 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { ULAS_ASMDIR_INCBIN, ULAS_ASMDIR_DEF, ULAS_ASMDIR_CHKSM, ULAS_ASMDIR_ADV, ULAS_ASMDIR_SET_ENUM_DEF, ULAS_ASMDIR_DEFINE_ENUM, - ULAS_ASMDIR_SETCHRCODE}; + ULAS_ASMDIR_SETCHRCODE, ULAS_ASMDIR_CHR}; enum ulas_asmdir dir = ULAS_ASMDIR_NONE; @@ -2644,6 +2698,9 @@ int ulas_asmline(FILE *dst, FILE *src, const char *line, unsigned long n) { case ULAS_ASMDIR_SETCHRCODE: rc = ulas_asmdirsetcharcode(&line, n); break; + case ULAS_ASMDIR_CHR: + other_writes += ulas_asmdirchr(dst, &line, n, &rc); + break; case ULAS_ASMDIR_PAD: // TODO: pad is the same as .fill n, $ - n case ULAS_ASMDIR_NONE: diff --git a/tests/t0.bin b/tests/t0.bin index 47a8d97..612d93a 100644 Binary files a/tests/t0.bin and b/tests/t0.bin differ diff --git a/tests/t0.s b/tests/t0.s index 261dc9f..93ad7b8 100644 --- a/tests/t0.s +++ b/tests/t0.s @@ -128,3 +128,5 @@ l3: .db 1 .str "abc" .scc 'a' = 'f' .str "abc" +.db 1, 2, 3 +.chr 01233213