private void Step4_GetDefine() { dicDefine = new Dictionary <string, MmlDatum2>(); for (int i = 0; i < asm.Count; i++) { MmlDatum2 md = asm[i]; if (md == null || md.args == null || md.args.Count < 2 || !(md.args[0] is int) || (int)md.args[0] != -5) { continue; } if (!(md.args[1] is string)) { continue; } string[] wd = ((string)md.args[1]).Trim().ToLower().Replace("\t", " ").Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); if (wd[1] != "equ") { continue; } string defineLabel = wd[0]; md = new MmlDatum2(wd[2], -5, ""); dicDefine.Add(defineLabel, md); } }
private void asmDbRefDefine(MmlDatum2 asm, ref int ptr) { if (assembleBlockLatest) { ptr += 2; return; } List <object> args = asm.args; if (args[ptr + 1] is string) { string define = ((string)args[ptr + 1]).ToLower(); bool byteFlg = false; if (define.IndexOf("b:") >= 0) { byteFlg = true; define = define.Substring(2); } int n = GetInt(dicDefine[define].code); ptr += 2; Poke(currentBank, currentAddress++, (byte)n, asm); if (!byteFlg) { Poke(currentBank, currentAddress++, (byte)(n >> 8), asm); } } else { Log.WriteLine(LogLevel.ERROR, "Db ref degine error."); ptr++; } }
private void asmLabel(MmlDatum2 asm, ref int ptr) { if (assembleBlockLatest) { ptr += 2; return; } List <object> args = asm.args; if (args[ptr + 1] is string) { string label = ((string)args[ptr + 1]).ToLower(); if (dicLabel.ContainsKey(label)) { MmlDatum2 md = dicLabel[label]; ; md.args.Add(currentBank); md.args.Add(currentAddress); ptr += 2; } ptr += 2; } else { Log.WriteLine(LogLevel.ERROR, "Db Label error."); ptr++; } }
private void Step2_GetMacro() { dicMacroBlock = new Dictionary <string, List <MmlDatum2> >(); for (int i = 0; i < asm.Count; i++) { MmlDatum2 md = asm[i]; if (md == null || md.args == null || md.args.Count < 2 || !(md.args[0] is int) || (int)md.args[0] != -4) { continue; } if (!(md.args[1] is string)) { continue; } string wd = ((string)md.args[1]).Trim().ToLower(); if (wd.IndexOf(".macro") < 0) { continue; } string macroLabel = wd.Substring(0, wd.IndexOf('.')).Trim(); asm.RemoveAt(i); List <MmlDatum2> mb = new List <MmlDatum2>(); while (i < asm.Count) { md = asm[i]; if (md == null || md.args == null || md.args.Count < 2 || !(md.args[0] is int) || (int)md.args[0] != -4) { mb.Add(md); asm.RemoveAt(i); continue; } if (!(md.args[1] is string)) { mb.Add(md); asm.RemoveAt(i); continue; } wd = ((string)md.args[1]).Trim().ToLower(); if (wd.IndexOf(".endm") < 0) { mb.Add(md); asm.RemoveAt(i); continue; } asm.RemoveAt(i); dicMacroBlock.Add(macroLabel, mb); i--; break; } } }
private void asmMacro(MmlDatum2 asm, ref int ptr) { string tmp = ((string)asm.args[ptr + 1]).Replace("\t", " "); string[] macros = tmp.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); int n; switch (macros[ptr]) { case ".bank": if (assembleBlockLatest) { break; } n = AnaFormula(asm.args); currentBank = n; ptr = asm.args.Count; return; case ".org": if (assembleBlockLatest) { break; } n = GetInt(macros[ptr + 1]); currentAddress = n; break; case ".code": //無視 break; case ".if": assembleBlockStack.Push(!anaCondition(macros)); //ブロックするかどうかのフラグなので判定結果を反転させたものがセットされる UpdateAssembleBlockLatest(); break; case ".else": bool flg = assembleBlockStack.Pop(); assembleBlockStack.Push(!flg); UpdateAssembleBlockLatest(); break; case ".endif": assembleBlockStack.Pop(); UpdateAssembleBlockLatest(); break; default: Log.WriteLine(LogLevel.ERROR, "macro error."); ptr++; return; } ptr += 2; }
private void asmDbRefLabel(MmlDatum2 asm, ref int ptr) { if (assembleBlockLatest) { ptr += 2; return; } List <object> args = asm.args; if (args[ptr + 1] is string) { string label = ((string)args[ptr + 1]).ToLower(); object byteFlg = false; if (label.IndexOf("b:") >= 0) { byteFlg = true; label = label.Substring(2); } if (label.IndexOf("bank(") >= 0) { byteFlg = -1; label = label.Substring(label.IndexOf("bank(") + 5, label.LastIndexOf(")") - label.IndexOf("bank(") - 5); } if (!dicRefLabel.ContainsKey(label)) { dicRefLabel.Add(label, new List <Tuple <int, int, object> >());// currentBank, currentAddress, byteFlg } dicRefLabel[label].Add(new Tuple <int, int, object>(currentBank, currentAddress, byteFlg)); Poke(currentBank, currentAddress++, 0, asm); if (byteFlg is bool && !(bool)byteFlg) { Poke(currentBank, currentAddress++, 0, asm); } ptr += 2; } else { Log.WriteLine(LogLevel.ERROR, "Db ref Label error."); ptr++; } }
private void SetLabel() { foreach (string refkey in dicRefLabel.Keys) { string key = refkey + ":"; if (!dicLabel.ContainsKey(key)) { continue; } MmlDatum2 md = dicLabel[key]; byte bank = (byte)(int)md.args[2]; int adr = (int)md.args[3]; List <Tuple <int, int, object> > trgs = dicRefLabel[refkey]; foreach (Tuple <int, int, object> trg in trgs) { byte trgBank = (byte)trg.Item1; int trgAdr = trg.Item2; object trgByteFlg = trg.Item3; MmlDatum2 m; if (trgByteFlg is bool) { m = new MmlDatum2(); m.dat = (byte)adr; dest[trgBank][trgAdr] = m; if (!(bool)trgByteFlg) { m = new MmlDatum2(); m.dat = (byte)(adr >> 8); dest[trgBank][trgAdr + 1] = m; } } else { m = new MmlDatum2(); m.dat = bank; dest[trgBank][trgAdr] = m; } } } }
private void Step5_GetLabel() { dicLabel = new Dictionary <string, MmlDatum2>(); for (int i = 0; i < asm.Count; i++) { MmlDatum2 md = asm[i]; if (md == null || md.args == null || md.args.Count < 2 || !(md.args[0] is int) || (int)md.args[0] != -2) { continue; } if (!(md.args[1] is string)) { continue; } md.dat = i;//行数を入れてみる dicLabel.Add((string)md.args[1], md); } }
private void Step3_ReplaceMacro() { bool f; do { f = false; for (int i = 0; i < asm.Count; i++) { MmlDatum2 md = asm[i]; if (md == null || md.args == null || md.args.Count < 2 || !(md.args[0] is int) || (int)md.args[0] != -6) { continue; } if (!(md.args[1] is string)) { continue; } string wd = ((string)md.args[1]).Trim().ToLower(); foreach (string key in dicMacroBlock.Keys) { if (wd != key) { continue; } f = true; asm.RemoveAt(i); foreach (MmlDatum2 val in dicMacroBlock[key]) { asm.Insert(i++, val); } } } } while (f); }
private void Poke(int bank, int adr, byte dat, MmlDatum2 src) { while (dest.Count < bank + 1) { dest.Add(new List <MmlDatum2>()); } while (dest[bank].Count < adr + 1) { dest[bank].Add(null); } dest[bank][adr] = new MmlDatum2(); dest[bank][adr].dat = dat; dest[bank][adr].args = null; dest[bank][adr].code = ""; dest[bank][adr].linePos = src.linePos; dest[bank][adr].type = src.type; if (adr > 0x9b84) { ; } Log.WriteLine(LogLevel.TRACE, string.Format("{0:X02}:{1:X04}:{2:X02}", bank, adr, dat)); }
private void asmDb(MmlDatum2 asm, ref int ptr) { if (assembleBlockLatest) { ptr += 2; return; } List <object> args = asm.args; if (args[ptr + 1] is byte) { byte n = (byte)args[ptr + 1]; ptr += 2; Poke(currentBank, currentAddress++, n, asm); } else if (args[ptr + 1] is int) { byte n = (byte)(int)args[ptr + 1]; ptr += 2; Poke(currentBank, currentAddress++, n, asm);//int であってもbyte扱いです } else if (args[ptr + 1] is char) { byte n = (byte)(char)args[ptr + 1]; ptr += 2; Poke(currentBank, currentAddress++, n, asm); } else if (args[ptr + 1] is string) { //複合型 string sen = (string)args[ptr + 1]; List <byte> wd = new List <byte>(); for (int i = 0; i < sen.Length; i++) { if (sen[i] == ' ' || sen[i] == '\t') { continue; } if (sen[i] == ',') { continue; } int j; string x = ""; if (sen[i] == '"') { x = ""; j = i + 1; for (; j < sen.Length; j++) { if (sen[j] == '"') { break; } x += sen[j]; } i = j; Common.myEncoding enc = new Common.myEncoding(); byte[] ary = enc.GetSjisArrayFromString(x); foreach (byte b in ary) { wd.Add(b); } continue; } x = ""; j = i; for (; j < sen.Length; j++) { if (sen[i] == ' ' || sen[i] == '\t' || sen[i] == ',') { break; } x += sen[j]; } i = j; int n = GetInt(x); wd.Add((byte)n); } ptr += 2; foreach (byte b in wd) { Poke(currentBank, currentAddress++, b, asm); } } else { Log.WriteLine(LogLevel.ERROR, "Db error."); ptr++; } }
// MDRファイル読み出し private List <MmlDatum2> packPCMintoMDR(List <MmlDatum2> destBuf, string file, string pcm, ref _mdr m) { if (string.IsNullOrEmpty(file)) { return(destBuf); } if (string.IsNullOrEmpty(pcm)) { return(destBuf); } byte[] bank = new byte[BANK_SIZE]; Log.WriteLine(LogLevel.INFO, "packing..."); int start_pos = m.size; // パックされている場合はPCM先頭バングから計算する if (m.pcm_packed != 0) { start_pos = m.pcm_startbank * BANK_SIZE; } byte[] pcmBuf; try { if (File.Exists(pcm)) { pcmBuf = File.ReadAllBytes(pcm); } else { pcm = Path.Combine(Path.GetDirectoryName(file), pcm); pcmBuf = File.ReadAllBytes(pcm); } } catch { Log.WriteLine(LogLevel.ERROR, string.Format("File open error!:{0}", pcm)); return(null); } // PCMデータ出力位置 Log.WriteLine(LogLevel.INFO, string.Format("PCM Start:{0:X08}h", start_pos)); m.fp = start_pos; int block_len = 0; int pcm_blocks = 1; int i = 0; while (i < pcmBuf.Length) { MmlDatum2 md = new MmlDatum2("", pcmBuf[i]); destBuf.Insert(m.fp + i, md); i++; block_len++; if ((i % BANK_SIZE) == 0) { pcm_blocks++; block_len = 0; } } if (pcmBuf.Length > 0 && block_len == 0) { pcm_blocks--; } m.pcm_packed = 1; m.pcm_startadrs = 0x20; // SRAM開始アドレス m.pcm_startbank = (int)(start_pos / BANK_SIZE); // 開始バンク m.pcm_banks = pcm_blocks - 1; // ブロック数 m.pcm_lastsize = (block_len + 0xff) / 0x100; // 最後のブロックサイズ Log.WriteLine(LogLevel.INFO, string.Format("PCM StartAdrs:{0:x02}h", m.pcm_startadrs)); Log.WriteLine(LogLevel.INFO, string.Format("PCM StartBank:{0:x02}h", m.pcm_startbank)); Log.WriteLine(LogLevel.INFO, string.Format("PCM Banks:{0:x02}h", m.pcm_banks)); Log.WriteLine(LogLevel.INFO, string.Format("PCM LastSize:{0:x02}h", m.pcm_lastsize)); writeMDRHeader(destBuf, m); Log.WriteLine(LogLevel.INFO, "ok!"); return(destBuf); }