public void AppendTable(ASMTable table) { AppendLabel(table.Name); foreach (var entry in table) { AppendCode(entry.ToString()); } }
/// <summary> /// Generates the code for the desired effect /// </summary> /// <param name="channel"></param> /// <param name="table"></param> /// <param name="sa1"></param> /// <returns></returns> public override string Code(int channel, HDMATable table, bool sa1) { int Base = 0x4300 + (channel * 0x10); int Register = (int)Layers; int BaseAddress = RAM.Layer1X[sa1] + ((int)Layers - (int)LayerRegister.Layer1_X) * 2; int RegMode = ((Register & 0xFF) << 8) + 0x02; int LSRs = (int)((1.0 / _speed) / 2.0); int Tablesize = (Scanlines / _width) >= 15 ? 15 : (Scanlines / _width); int TableInRAM = CountRAMBytes(); string tableString = "The Table takes up " + TableInRAM + " bytes of the free RAM\n" + "It ranges from $" + FreeRAM.ToString("X6") + " - $" + (FreeRAM + TableInRAM - 1).ToString("X6") + " (both addresses included)"; ASMTable codeTable = new ASMTable(".WaveTable"); for (int i = 0; i <= Tablesize; i++) { codeTable.Add(new ASMTableEntry((byte)_IArr[i])); } char xy = (((int)Layers & 0x01) == 0 ? 'Y' : 'X'); ASMCodeBuilder CodeBuilder = new ASMCodeBuilder(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendLabel(INITLabel, "This section is to be used in the INIT code of levelASM"); CodeBuilder.AppendCode("REP #$20"); CodeBuilder.AppendCode("LDA #$" + RegMode.ToASMString(), "Use Mode 02 on register " + Register.ToASMString()); CodeBuilder.AppendCode("STA $" + Base.ToASMString(), "43" + Channel + "0 = Mode, 43" + Channel + "1 = Register"); CodeBuilder.AppendCode("LDA #$" + (FreeRAM & 0xFFFF).ToASMString(), "Address of HDMA table"); CodeBuilder.AppendCode("STA $" + (Base + 2).ToASMString(), "43" + Channel + "2 = Low-Byte of table, 43" + Channel + "3 = High-Byte of table"); CodeBuilder.AppendCode("SEP #$20"); CodeBuilder.AppendCode("LDA.b #$" + (FreeRAM >> 16).ToASMString(), "Address of HDMA table, get bank byte"); CodeBuilder.AppendCode("STA $" + (Base + 4).ToASMString(), "43" + Channel + "4 = Bank-Byte of table"); CodeBuilder.AppendCode("LDA #$" + (0x01 << Channel).ToASMString()); CodeBuilder.AppendCode("TSB $" + RAM.HDMAEnable[sa1].ToASMString(), "Enable HDMA channel " + Channel); CodeBuilder.AppendCode("RTS", "End HDMA setup" + MAINSeperator); CodeBuilder.CloseBlock(); CodeBuilder.AppendCommentLine(tableString); CodeBuilder.AppendEmptyLine(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendLabel(MAINLabel, "This section is to be used in the MAIN code of levelASM"); CodeBuilder.AppendCode("LDY #$00", "Y will be the loop counter."); CodeBuilder.AppendCode("LDX #$00", "X the index for writing the table to the RAM"); CodeBuilder.AppendCode("LDA $" + RAM.FrameCounter[sa1].ToASMString(), "Speed of waves"); CodeBuilder.AppendCode("LSR #" + LSRs, "Slowing down A"); CodeBuilder.AppendCode("STA $00", "Save for later use."); CodeBuilder.CloseBlock(); CodeBuilder.AppendEmptyLine(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendCode("PHB : PHK : PLB", "Preservev bank"); CodeBuilder.AppendLabel(".Loop", "Jump back if not finished writing table"); CodeBuilder.AppendCode("LDA #$" + _width.ToASMString(), "Set scanline height"); CodeBuilder.AppendCode("STA $" + FreeRAM.ToASMString() + ",x", "for each wave"); CodeBuilder.AppendCode("TYA", "Transfer Y to A, to calculate next index"); CodeBuilder.AppendCode("ADC $00", "Add frame counter"); CodeBuilder.AppendCode("AND #$" + Tablesize.ToASMString()); CodeBuilder.AppendCode("PHY", "Preserve loop counter"); CodeBuilder.AppendCode("TAY", "Get the index in Y"); CodeBuilder.CloseBlock(); CodeBuilder.AppendEmptyLine(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendCode("LDA.w " + codeTable.Name + ",y", "Load in wave value"); CodeBuilder.AppendCode("LSR", "Half only"); CodeBuilder.AppendCode("CLC", "Clear Carry for addition"); CodeBuilder.AppendCode("ADC $" + (BaseAddress).ToASMString(), "Add value to layer " + xy + " position (low byte)"); CodeBuilder.AppendCode("STA $" + (FreeRAM + 1).ToASMString() + ",x", "store to HDMA table (low byte)"); CodeBuilder.AppendCode("LDA $" + (BaseAddress + 1).ToASMString(), "Get high byte of X position"); CodeBuilder.AppendCode("ADC #$00", "Add value to layer X position (low byte)"); CodeBuilder.AppendCode("STA $" + (FreeRAM + 2).ToASMString() + ",x", "store to HDMA table (high byte)"); CodeBuilder.CloseBlock(); CodeBuilder.AppendEmptyLine(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendCode("PLY", "Pull original loop counter"); CodeBuilder.AppendCode("CPY #$" + (Scanlines / _width).ToASMString(), "Compare if we have written enough HDMA entries."); CodeBuilder.AppendCode("BPL .End", "If bigger, end HDMA"); CodeBuilder.AppendCode("INX", "Increase X, so that in the next loop, it writes the new table data..."); CodeBuilder.AppendCode("INX", "... at the end of the old one instead of overwritting it."); CodeBuilder.AppendCode("INX"); CodeBuilder.AppendCode("INY", "Increase loop counter"); CodeBuilder.AppendCode("BRA .Loop", "Repeat loop"); CodeBuilder.CloseBlock(); CodeBuilder.AppendEmptyLine(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendLabel(".End", "Jump here when at the end of HDMA"); CodeBuilder.AppendCode("PLB", "Pull back data bank."); CodeBuilder.AppendCode("LDA #$00", "End HDMA by writting 00..."); CodeBuilder.AppendCode("STA $" + (FreeRAM + 3).ToASMString() + ",x", "...at the end of the table."); CodeBuilder.AppendCode("RTS"); CodeBuilder.CloseBlock(); CodeBuilder.AppendEmptyLine(); CodeBuilder.OpenNewBlock(); CodeBuilder.AppendTable(codeTable); CodeBuilder.CloseBlock(); return(CodeBuilder.ToString()); // +"\n\n" + tableString; }