// returns the amount of bytes of line that were
// consumed or -1 on error
// returns 0 when no more tokens can be read
+// writes the token to dst string buffer
int ulas_tok(struct ulas_str *dst, const char **out_line, unsigned long n);
// converts a token string to a token struct
// and literal values
struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc);
+// tokenize until a terminator char is reached
int ulas_tokuntil(struct ulas_str *dst, char c, const char **out_line,
unsigned long n);
return ulas_intexpreval(expr, rc);
}
-#define ULAS_ISINSTR(tok, name, n) (strncmp(tok, name, n) == 0)
+#define ULAS_STATICINSTR(name, n, ...) \
+ if (strncmp(ulas.tok.buf, (name), ulas.tok.maxlen) == 0) { \
+ const unsigned char t[] = {__VA_ARGS__}; \
+ memcpy(dst, t, n); \
+ return n; \
+ }
// assembles an instruction, writes bytes into dst
// returns bytes written or -1 on error
// TODO: check for symbol token here... if so add it
// and skip to the next token
- int rc = 0;
-
- if (ULAS_ISINSTR(ulas.tok.buf, "nop", ulas.tok.maxlen)) {
- dst[0] = 0x00;
- rc++;
- } else if (ULAS_ISINSTR(ulas.tok.buf, "halt", ulas.tok.maxlen)) {
- dst[0] = 0x76;
- rc++;
- } else if (ULAS_ISINSTR(ulas.tok.buf, "stop", ulas.tok.maxlen)) {
- dst[0] = 0x10;
- dst[1] = 0x00;
- rc += 2;
- } else {
- ULASERR("Invalid instruction '%s'\n", ulas.tok.buf);
- return -1;
- }
+ ULAS_STATICINSTR("nop", 1, 0x00);
+ ULAS_STATICINSTR("halt", 1, 0x76);
+ ULAS_STATICINSTR("stop", 2, 0x10, 0x00);
+ ULAS_STATICINSTR("di", 1, 0xF3);
+ ULAS_STATICINSTR("ei", 1, 0xFB);
- return rc;
+ ULASERR("Invalid instruction '%s'\n", ulas.tok.buf);
+ return -1;
}
+#undef ULAS_STATICINSTR
+
void ulas_asmlst(const char *line, char *outbuf, unsigned long n) {
if (ulaslstout) {
fprintf(ulaslstout, "%08X", ulas.address);
int outwrt = 0;
for (long i = 0; i < n; i++) {
- outwrt += fprintf(ulaslstout, "%02x ", (int)outbuf[i]);
+ outwrt += fprintf(ulaslstout, "%02x ", outbuf[i] & 0xFF);
}
for (long i = outwrt; i < pad; i++) {