From 33bb7119411747e6e3972624c385a3728190253c Mon Sep 17 00:00:00 2001 From: FlameCyclone <1490868135@qq.com> Date: Mon, 7 Aug 2023 12:56:54 +0800 Subject: add new command: .str --- source/command.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- source/defs.h | 1 + source/inst.h | 3 +- source/protos.h | 1 + 4 files changed, 179 insertions(+), 2 deletions(-) diff --git a/source/command.c b/source/command.c index 9b3784f..b4f811e 100644 --- a/source/command.c +++ b/source/command.c @@ -15,7 +15,7 @@ char pseudo_flag[] = { 0x0F, 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0F, 0x0F, 0x0F, // 30 - 39 0x0F, 0x0F, 0x0C, 0x0C, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x04, // 40 - 49 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, // P_INESPRGRAM - 50, P_INESPRGNVRAM - 51, P_INESCHRRAM - 52, P_INESCHRNVRAM - 53, P_INESSUBMAP - 54, P_INESBAT - 55, P_INESTIM - 56 - 0x0F // P_SEQU 57 + 0x0C, 0x0F // P_SEQU 58 }; @@ -337,6 +337,180 @@ do_dw(int *ip) println(); } +/* ---- + * do_str() + * ---- + * .str pseudo + */ + +void +do_str(int *ip) +{ + unsigned char c; + unsigned char str_len = 0; + int ip_tmp = 0; + + /* define label */ + labldef(loccnt, 1); + + /* output infos */ + data_loccnt = loccnt; + data_level = 2; + + /* skip spaces */ + while (isspace((int)prlnbuf[++(*ip)])); + + ip_tmp = *ip; + /* get length */ + for (;;) { + /* ASCII string */ + if (prlnbuf[*ip] == '\"') { + for (;;) { + c = prlnbuf[++(ip_tmp)]; + if (c == '\"') + break; + if (c == '\0') { + error("Unterminated ASCII string!"); + return; + } + if (c == '\\') { + c = prlnbuf[++(ip_tmp)]; + switch(c) { + case 'r': + c = '\r'; + break; + case 'n': + c = '\n'; + break; + case 't': + c = '\t'; + break; + } + } + + /* update location counter */ + str_len++; + } + ip_tmp++; + } + /* bytes */ + else { + /* get a byte */ + if (!evaluate(&ip_tmp, 0)) + return; + + /* update location counter */ + str_len++; + + /* store byte on last pass */ + if (pass == LAST_PASS) { + /* check for overflow */ + if ((value > 0xFF) && (value < 0xFFFFFF80)) { + error("Overflow error!"); + return; + } + } + } + + /* check if there's another byte */ + c = prlnbuf[ip_tmp++]; + + if (c != ',') + break; + } + + if (str_len > 0) { + printf("pos: %d length: %d\n", loccnt, str_len); + putbyte(loccnt, str_len); + loccnt++; + } + + /* get bytes */ + for (;;) { + /* ASCII string */ + if (prlnbuf[*ip] == '\"') { + for (;;) { + c = prlnbuf[++(*ip)]; + if (c == '\"') + break; + if (c == '\0') { + error("Unterminated ASCII string!"); + return; + } + if (c == '\\') { + c = prlnbuf[++(*ip)]; + switch(c) { + case 'r': + c = '\r'; + break; + case 'n': + c = '\n'; + break; + case 't': + c = '\t'; + break; + } + } + /* store char on last pass */ + if (pass == LAST_PASS) + putbyte(loccnt, c); + + /* update location counter */ + loccnt++; + } + (*ip)++; + } + /* bytes */ + else { + /* get a byte */ + if (!evaluate(ip, 0)) + return; + + /* update location counter */ + loccnt++; + + /* store byte on last pass */ + if (pass == LAST_PASS) { + /* check for overflow */ + if ((value > 0xFF) && (value < 0xFFFFFF80)) { + error("Overflow error!"); + return; + } + + /* store byte */ + putbyte(loccnt - 1, value); + } + } + + /* check if there's another byte */ + c = prlnbuf[(*ip)++]; + + if (c != ',') + break; + } + + /* check error */ + if (c != ';' && c != '\0') { + error("Syntax error!"); + return; + } + + /* size */ + if (lablptr) { + lablptr->data_type = P_DB; + lablptr->data_size = loccnt - data_loccnt; + } + else { + if (lastlabl) { + if (lastlabl->data_type == P_DB) + lastlabl->data_size += loccnt - data_loccnt; + } + } + + /* output line */ + if (pass == LAST_PASS) + println(); +} /* ---- * do_equ() diff --git a/source/defs.h b/source/defs.h index 385b288..aa61aa3 100644 --- a/source/defs.h +++ b/source/defs.h @@ -107,6 +107,7 @@ #define P_INESBAT 55 // .inesbat #define P_INESTIM 56 // .inestim #define P_SEQU 57 // .sequ +#define P_STR 58 // .str /* symbol flags */ #define MDEF 3 /* multiply defined */ diff --git a/source/inst.h b/source/inst.h index 42076e6..4d502e0 100644 --- a/source/inst.h +++ b/source/inst.h @@ -61,7 +61,7 @@ struct t_opcode base_inst[57] = { }; /* pseudo instruction table */ -struct t_opcode base_pseudo[77] = { +struct t_opcode base_pseudo[78] = { {NULL, "=", do_equ, PSEUDO, P_EQU, 0}, {NULL, "BANK", do_bank, PSEUDO, P_BANK, 0}, @@ -140,6 +140,7 @@ struct t_opcode base_pseudo[77] = { {NULL, ".RS", do_rs, PSEUDO, P_RS, 0}, {NULL, ".WORD", do_dw, PSEUDO, P_DW, 0}, {NULL, ".ZP", do_section, PSEUDO, P_ZP, S_ZP}, + {NULL, ".STR", do_str, PSEUDO, P_STR, 0}, {NULL, NULL, NULL, 0, 0, 0} }; diff --git a/source/protos.h b/source/protos.h index c6f8277..f5179ba 100644 --- a/source/protos.h +++ b/source/protos.h @@ -30,6 +30,7 @@ void do_mlist(int *ip); void do_nolist(int *ip); void do_nomlist(int *ip); void do_db(int *ip); +void do_str(int *ip); void do_dw(int *ip); void do_equ(int *ip); void do_sequ(int *ip); -- cgit v1.2.3