void CParser::NextSym() { // sets the global variable sym to the next symbol, and // if it is an operator // sets the global variable opkind to the kind of operator // if it is a constant // sets the global variable constkind to the kind of operator // if it is a reference to a cell // sets the global variable cellcoord to the kind of operator errmsg = NULL; while (ch == ' ' || ch == 0x9) NextCh(); switch (ch) { case '(': sym = lbracksym; NextCh(); break; case ')': sym = rbracksym; NextCh(); break; case ',': sym = commasym; NextCh(); break; case '%' : sym = opsym; opkind = OPmodulus; NextCh(); break; case '+' : sym = opsym; opkind = OPplus; NextCh(); break; case '-' : sym = opsym; opkind = OPminus; NextCh(); break; case '*' : sym = opsym; opkind = OPtimes; NextCh(); break; case '/' : sym = opsym; opkind = OPdivide; NextCh(); break; case '&' : sym = opsym; opkind = OPand; NextCh(); TermChar('&'); break; case '|' : sym = opsym; opkind = OPor; NextCh(); TermChar('|'); break; case '=' : sym = opsym; opkind = OPequal; NextCh(); TermChar('='); break; case '!' : sym = opsym; NextCh(); if (ch == '=') { opkind = OPunequal; NextCh(); } else { opkind = OPnot; } break; case '>': sym = opsym; NextCh(); if (ch == '=') { opkind = OPgreaterequal; NextCh(); } else { opkind = OPgreater; } break; case '<': sym = opsym; NextCh(); if (ch == '=') { opkind = OPlessequal; NextCh(); } else { opkind = OPless; } break; case '\"' : { int start; sym = constsym; constkind = stringtype; NextCh(); start = chcount; while ((ch != '\"') && (ch != 0x0)) NextCh(); GrabRealString(start); TermChar('\"'); // check for eol before '\"' break; } case 0x0: sym = eolsym; break; default: { int start; start = chcount; DigRep(); if ((start != chcount) || (ch == '.')) { // number sym = constsym; if (ch == '.') { constkind = floattype; NextCh(); DigRep(); } else constkind = inttype; if ((ch == 'e') || (ch == 'E')) { int mark; constkind = floattype; NextCh(); if ((ch == '+') || (ch == '-')) NextCh(); mark = chcount; DigRep(); if (mark == chcount) { ScanError("Number expected after 'E'"); return; } } GrabString(start); } else if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) { // reserved word? start = chcount; CharRep(); GrabString(start); if (!strcasecmp(const_as_string, "SUM")) { sym = sumsym; } else if (!strcasecmp(const_as_string, "NOT")) { sym = opsym; opkind = OPnot; } else if (!strcasecmp(const_as_string, "AND")) { sym = opsym; opkind = OPand; } else if (!strcasecmp(const_as_string, "OR")) { sym = opsym; opkind = OPor; } else if (!strcasecmp(const_as_string, "IF")) sym = ifsym; else if (!strcasecmp(const_as_string, "WHOMADE")) sym = whocodedsym; else if (!strcasecmp(const_as_string, "FALSE")) { sym = constsym; constkind = booltype; boolvalue = false; } else if (!strcasecmp(const_as_string, "TRUE")) { sym = constsym; constkind = booltype; boolvalue = true; } else { sym = idsym; //STR_String str; //str.Format("'%s' makes no sense here", (const char*)funstr); //ScanError(str); } } else { // unknown symbol STR_String str; str.Format("Unexpected character '%c'", ch); NextCh(); ScanError(str); return; } } } }
SPCReader::SPCReader(Stream* fp) { #if 0 reg_pc = 0x430; reg_a = 0; reg_x = 0; reg_y = 0; reg_psw = 0; reg_sp = 0xFF; memset(apuram, 0x00, sizeof(apuram)); memset(dspregs, 0x00, sizeof(dspregs)); dspregs[0x6C] = 0xE0; fp->read(&apuram[0x400], 0x1000); return; #endif if(!TestMagic(fp)) throw MDFN_Error(0, _("Not a valid SPC file!")); uint8 header[0x100]; fp->rewind(); fp->read(header, sizeof(header)); reg_pc = MDFN_de16lsb(&header[0x25]); reg_a = header[0x27]; reg_x = header[0x28]; reg_y = header[0x29]; reg_psw = header[0x2A]; reg_sp = header[0x2B]; fp->read(apuram, 65536); fp->read(dspregs, 0x80); fp->seek(0x101C0, SEEK_SET); fp->read(apuram + 0xFFC0, 0x40); if(header[0x23] == 0x1A) { bool binary_tags = true; if(header[0xA0] == '/' && header[0xA3] == '/') binary_tags = false; if(header[0xD2] >= '0' && header[0xD2] <= '9' && header[0xD3] == 0x00) binary_tags = false; fp->seek(0x2E, SEEK_SET); song_name = GrabString(fp, 32); game_name = GrabString(fp, 32); fp->seek(binary_tags ? 0xB0 : 0xB1, SEEK_SET); artist_name = GrabString(fp, 32); } // // // #if 0 fp->seek(0x10200, SEEK_SET); uint8 xid_header[8]; if(fp->read(xid_header, sizeof(xid_header), false) == sizeof(xid_header) && !memcmp(xid_header, "xid6", 4)) { uint8 sub_header[4]; while(fp->read(sub_header, sizeof(sub_header), false) == sizeof(sub_header)) { const uint8 id = sub_header[0]; const uint8 type = sub_header[1]; uint16 len = MDFN_de16lsb(&sub_header[2]); printf("ID: 0x%02x, Type: 0x%02x, Len: 0x%04x\n", id, type, len); if(type == 1 && len > 4) len = (len + 3) &~ 3; switch(id) { default: if(type) fp->seek(len, SEEK_CUR); break; case 0x01: song_name = GrabString(fp, len); break; case 0x02: game_name = GrabString(fp, len); break; case 0x03: artist_name = GrabString(fp, len); break; } } } #endif }