mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-22 05:48:37 +00:00
Some smaller refactorings and misc changes
This commit is contained in:
parent
ab7807cdb0
commit
ec5eebdeed
24 changed files with 545 additions and 210 deletions
|
|
@ -92,8 +92,6 @@ namespace Indy.IL2CPU.Assembler {
|
|||
}
|
||||
}
|
||||
|
||||
private Func<string, string> mGetFileNameForGroup;
|
||||
|
||||
private uint mDataMemberCounter = 0;
|
||||
|
||||
public string GetIdentifier(string aPrefix) {
|
||||
|
|
@ -101,29 +99,11 @@ namespace Indy.IL2CPU.Assembler {
|
|||
return aPrefix + mDataMemberCounter.ToString("X8").ToUpper();
|
||||
}
|
||||
|
||||
public Assembler(Func<string, string> aGetFileNameForGroup) {
|
||||
mGetFileNameForGroup = aGetFileNameForGroup;
|
||||
public Assembler() {
|
||||
CurrentInstance.Push(this);
|
||||
//mInstructions.AddComplexIndexDefinition(
|
||||
}
|
||||
|
||||
public List<KeyValuePair<string, Instruction>> GetInstructions() {
|
||||
//using (mInstructionsLocker.AcquireReaderLock()) {
|
||||
// if(mInstructions.ContainsKey(Thread.CurrentThread.ManagedThreadId)) {
|
||||
// return mInstructions[Thread.CurrentThread.ManagedThreadId];
|
||||
// }
|
||||
//}
|
||||
// using(mInstructionsLocker.AcquireWriterLock()) {
|
||||
// // do this check again, between the two locks, the situation might have changed.
|
||||
// if (mInstructions.ContainsKey(Thread.CurrentThread.ManagedThreadId))
|
||||
// {
|
||||
// return mInstructions[Thread.CurrentThread.ManagedThreadId];
|
||||
// }
|
||||
// var xResult = new
|
||||
// }
|
||||
throw new NotImplementedException("After multi-threaded refactorings, this hasn't been implemented again, yet");
|
||||
}
|
||||
|
||||
public List<DataMember> DataMembers {
|
||||
get { return mDataMembers; }
|
||||
}
|
||||
|
|
@ -294,7 +274,9 @@ namespace Indy.IL2CPU.Assembler {
|
|||
}
|
||||
if (mInstructions.Count > 0) {
|
||||
string xMainLabel="";
|
||||
foreach (Instruction x in mInstructions) {
|
||||
for(int i = 0; i < mInstructions.Count;i++){
|
||||
//foreach (Instruction x in mInstructions) {
|
||||
var x = mInstructions[i];
|
||||
string prefix = "\t\t\t";
|
||||
Label xLabel = x as Label;
|
||||
if (xLabel != null) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,35 @@ namespace Indy.IL2CPU.Assembler {
|
|||
}
|
||||
}
|
||||
|
||||
private ulong? mActualAddress;
|
||||
|
||||
public bool Resolve(Assembler aAssembler, out ulong aAddress) {
|
||||
if (mActualAddress != null) {
|
||||
aAddress = mActualAddress.Value;
|
||||
return true;
|
||||
}
|
||||
BaseAssemblerElement xElement = (from item in aAssembler.Instructions
|
||||
let xLabel = item as Label
|
||||
where xLabel != null && xLabel.QualifiedName.Equals(Name, StringComparison.InvariantCultureIgnoreCase)
|
||||
select item).SingleOrDefault();
|
||||
if (xElement == null) {
|
||||
xElement = (from item in aAssembler.DataMembers
|
||||
where item.Name.Equals(Name, StringComparison.InvariantCultureIgnoreCase)
|
||||
select item).SingleOrDefault();
|
||||
}
|
||||
|
||||
if (xElement != null) {
|
||||
if (xElement.ActualAddress.HasValue) {
|
||||
mActualAddress = xElement.ActualAddress.Value + (uint)Offset;
|
||||
aAddress = mActualAddress.Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
aAddress = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
get;
|
||||
set;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@ using System.IO;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler {
|
||||
public class RawAssembler : Assembler {
|
||||
public RawAssembler() : base(null) { }
|
||||
public RawAssembler() : base() { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,155 +6,9 @@ using System.Text;
|
|||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
public class Assembler : Indy.IL2CPU.Assembler.Assembler {
|
||||
//TODO: COM Port info - should be in assembler? Assembler should not know about comports...
|
||||
protected byte mComNumber = 0;
|
||||
protected UInt16[] mComPortAddresses = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
|
||||
|
||||
public Assembler(Func<string, string> aGetStreamForGroup, byte aComNumber)
|
||||
: base(aGetStreamForGroup) {
|
||||
mComNumber = aComNumber;
|
||||
}
|
||||
|
||||
public Assembler(Func<string, string> aGetStreamForGroup) : base(aGetStreamForGroup) {
|
||||
}
|
||||
|
||||
private static string GetValidGroupName(string aGroup) {
|
||||
return aGroup.Replace('-','_').Replace('.', '_');
|
||||
}
|
||||
|
||||
public override void Initialize() {
|
||||
base.Initialize();
|
||||
if (mComNumber > 0) {
|
||||
new Define("DEBUGSTUB");
|
||||
}
|
||||
new Label("Kernel_Start");
|
||||
new Comment("MultiBoot-compliant loader (e.g. GRUB or X.exe) provides info in registers: ");
|
||||
new Comment("EBX=multiboot_info ");
|
||||
new Comment("EAX=0x2BADB002 - check if it's really Multiboot loader ");
|
||||
new Comment(" ;- copy mb info - some stuff for you ");
|
||||
new Add { DestinationReg = Registers.EBX, SourceValue = 4 };
|
||||
new Move {
|
||||
DestinationReg = Registers.EAX,
|
||||
SourceReg = Registers.EBX,
|
||||
SourceIsIndirect = true
|
||||
};
|
||||
new Move { DestinationRef = new ElementReference("MultiBootInfo_Memory_Low"), DestinationIsIndirect = true, SourceReg = Registers.EAX };
|
||||
new Add { DestinationReg = Registers.EBX, SourceValue = 4 };
|
||||
new Move {
|
||||
DestinationReg = Registers.EAX,
|
||||
SourceReg = Registers.EBX,
|
||||
SourceIsIndirect = true
|
||||
};
|
||||
new Move { DestinationRef = new ElementReference("MultiBootInfo_Memory_High"), DestinationIsIndirect = true, SourceReg = Registers.EAX };
|
||||
new Move {
|
||||
DestinationReg = Registers.ESP,
|
||||
SourceRef = new ElementReference("Kernel_Stack")
|
||||
};
|
||||
new Comment("some more startups todo");
|
||||
new ClrInterruptFlag();
|
||||
if (mComNumber > 0) {
|
||||
UInt16 xComAddr = mComPortAddresses[mComNumber - 1];
|
||||
// 9600 baud, 8 databits, no parity, 1 stopbit
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 1 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0 };
|
||||
new Out { Size = 8 }; // disable interrupts for serial stuff
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 3 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x80 };
|
||||
new Out { Size = 8 }; // Enable DLAB (set baud rate divisor)
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0xC };
|
||||
new Out { Size = 8 }; // Set divisor (lo byte)
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 1 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x0 };
|
||||
new Out { Size = 8 }; // (hi byte)
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 3 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x3 };
|
||||
new Out { Size = 8 }; // 8 bits, no parity, one stop bit
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 2 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0xC7 };
|
||||
new Out { Size = 8 }; // Enable FIFO, clear them, with 14-byte threshold
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 4 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x3 };
|
||||
new Out { Size = 8 }; // IRQ-s enabled, RTS/DSR set
|
||||
}
|
||||
|
||||
// SSE init
|
||||
// CR4[bit 9]=1, CR4[bit 10]=1, CR0[bit 2]=0, CR0[bit 1]=1
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR4 };
|
||||
new Or { DestinationReg = Registers.EAX, SourceValue = 0x100 };
|
||||
new Move { DestinationReg = Registers.CR4, SourceReg = Registers.EAX };
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR4 };
|
||||
new Or { DestinationReg = Registers.EAX, SourceValue = 0x200 };
|
||||
new Move { DestinationReg = Registers.CR4, SourceReg = Registers.EAX };
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR0 };
|
||||
|
||||
new And { DestinationReg = Registers.EAX, SourceValue = 0xfffffffd };
|
||||
new Move { DestinationReg = Registers.CR0, SourceReg = Registers.EAX };
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR0 };
|
||||
|
||||
new And { DestinationReg = Registers.EAX, SourceValue = 1 };
|
||||
new Move { DestinationReg = Registers.CR0, SourceReg = Registers.EAX };
|
||||
|
||||
// END SSE INIT
|
||||
|
||||
new Call { DestinationLabel = EntryPointName };
|
||||
new Label(".loop");
|
||||
new ClrInterruptFlag();
|
||||
new Halt();
|
||||
new Jump { DestinationLabel = ".loop" };
|
||||
new Label("DEBUG_STUB_");
|
||||
new Return();
|
||||
if (mComNumber > 0) {
|
||||
var xStub = new DebugStub();
|
||||
xStub.Main(mComPortAddresses[mComNumber - 1]);
|
||||
}
|
||||
//aOutputWriter.WriteLine("section .data");
|
||||
DataMembers.Add(new DataIfNotDefined("NASM_COMPILATION"));
|
||||
uint xFlags = 0x10003;
|
||||
DataMembers.Add(new DataMember("MultibootSignature",
|
||||
new uint[] { 0x1BADB002 }));
|
||||
DataMembers.Add(new DataMember("MultibootFlags",
|
||||
xFlags));
|
||||
DataMembers.Add(new DataMember("MultibootChecksum",
|
||||
(int)(0 - (xFlags + 0x1BADB002))));
|
||||
DataMembers.Add(new DataMember("MultibootHeaderAddr", new ElementReference("MultibootSignature")));
|
||||
DataMembers.Add(new DataMember("MultibootLoadAddr", new ElementReference("MultibootSignature")));
|
||||
DataMembers.Add(new DataMember("MultibootLoadEndAddr", 0));
|
||||
DataMembers.Add(new DataMember("MultibootBSSEndAddr", 0));
|
||||
DataMembers.Add(new DataMember("MultibootEntryAddr", new ElementReference("Kernel_Start")));
|
||||
DataMembers.Add(new DataEndIfDefined());
|
||||
DataMembers.Add(new DataIfDefined("NASM_COMPILATION"));
|
||||
xFlags = 0x00003;
|
||||
DataMembers.Add(new DataMember("MultibootSignature",
|
||||
new uint[] { 0x1BADB002 }));
|
||||
DataMembers.Add(new DataMember("MultibootFlags",
|
||||
xFlags));
|
||||
DataMembers.Add(new DataMember("MultibootChecksum",
|
||||
(int)(0 - (xFlags + 0x1BADB002))));
|
||||
DataMembers.Add(new DataEndIfDefined());
|
||||
DataMembers.Add(new DataMember("MultiBootInfo_Memory_High", 0));
|
||||
DataMembers.Add(new DataMember("MultiBootInfo_Memory_Low", 0));
|
||||
DataMembers.Add(new DataMember("Before_Kernel_Stack",
|
||||
new byte[0x50000]));
|
||||
DataMembers.Add(new DataMember("Kernel_Stack",
|
||||
new byte[0]));
|
||||
DebugStub.EmitDataSection();
|
||||
}
|
||||
|
||||
protected override void OnBeforeFlush() {
|
||||
base.OnBeforeFlush();
|
||||
DataMembers.AddRange(new DataMember[]{
|
||||
new DataMember("_end_data",
|
||||
new byte[0])});
|
||||
new Label("_end_code");
|
||||
}
|
||||
|
||||
public override void FlushText(TextWriter aOutput) {
|
||||
aOutput.WriteLine("use32");
|
||||
//aOutput.WriteLine("%define NASM_COMPILATION 1");
|
||||
//aOutput.WriteLine("global Kernel_Start");
|
||||
aOutput.WriteLine("[map all main.map]");
|
||||
//aOutput.WriteLine("org 0x500000");
|
||||
aOutput.WriteLine("org 0x200000");
|
||||
base.FlushText(aOutput);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
157
source/Indy.IL2CPU/Assembler/x86/CosmosAssembler.cs
Normal file
157
source/Indy.IL2CPU/Assembler/x86/CosmosAssembler.cs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
public class CosmosAssembler: Assembler {
|
||||
//TODO: COM Port info - should be in assembler? Assembler should not know about comports...
|
||||
protected byte mComNumber = 0;
|
||||
protected UInt16[] mComPortAddresses = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
|
||||
|
||||
public CosmosAssembler(byte aComNumber) {
|
||||
mComNumber = aComNumber;
|
||||
}
|
||||
|
||||
private static string GetValidGroupName(string aGroup) {
|
||||
return aGroup.Replace('-','_').Replace('.', '_');
|
||||
}
|
||||
|
||||
public override void Initialize() {
|
||||
base.Initialize();
|
||||
if (mComNumber > 0) {
|
||||
new Define("DEBUGSTUB");
|
||||
}
|
||||
new Label("Kernel_Start");
|
||||
new Comment("MultiBoot-compliant loader (e.g. GRUB or X.exe) provides info in registers: ");
|
||||
new Comment("EBX=multiboot_info ");
|
||||
new Comment("EAX=0x2BADB002 - check if it's really Multiboot loader ");
|
||||
new Comment(" ;- copy mb info - some stuff for you ");
|
||||
new Add { DestinationReg = Registers.EBX, SourceValue = 4 };
|
||||
new Move {
|
||||
DestinationReg = Registers.EAX,
|
||||
SourceReg = Registers.EBX,
|
||||
SourceIsIndirect = true
|
||||
};
|
||||
new Move { DestinationRef = new ElementReference("MultiBootInfo_Memory_Low"), DestinationIsIndirect = true, SourceReg = Registers.EAX };
|
||||
new Add { DestinationReg = Registers.EBX, SourceValue = 4 };
|
||||
new Move {
|
||||
DestinationReg = Registers.EAX,
|
||||
SourceReg = Registers.EBX,
|
||||
SourceIsIndirect = true
|
||||
};
|
||||
new Move { DestinationRef = new ElementReference("MultiBootInfo_Memory_High"), DestinationIsIndirect = true, SourceReg = Registers.EAX };
|
||||
new Move {
|
||||
DestinationReg = Registers.ESP,
|
||||
SourceRef = new ElementReference("Kernel_Stack")
|
||||
};
|
||||
new Comment("some more startups todo");
|
||||
new ClrInterruptFlag();
|
||||
if (mComNumber > 0) {
|
||||
UInt16 xComAddr = mComPortAddresses[mComNumber - 1];
|
||||
// 9600 baud, 8 databits, no parity, 1 stopbit
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 1 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0 };
|
||||
new Out { Size = 8 }; // disable interrupts for serial stuff
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 3 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x80 };
|
||||
new Out { Size = 8 }; // Enable DLAB (set baud rate divisor)
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0xC };
|
||||
new Out { Size = 8 }; // Set divisor (lo byte)
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 1 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x0 };
|
||||
new Out { Size = 8 }; // (hi byte)
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 3 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x3 };
|
||||
new Out { Size = 8 }; // 8 bits, no parity, one stop bit
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 2 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0xC7 };
|
||||
new Out { Size = 8 }; // Enable FIFO, clear them, with 14-byte threshold
|
||||
new Move { DestinationReg = Registers.DX, SourceValue = (uint)xComAddr + 4 };
|
||||
new Move { DestinationReg = Registers.AL, SourceValue = 0x3 };
|
||||
new Out { Size = 8 }; // IRQ-s enabled, RTS/DSR set
|
||||
}
|
||||
|
||||
// SSE init
|
||||
// CR4[bit 9]=1, CR4[bit 10]=1, CR0[bit 2]=0, CR0[bit 1]=1
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR4 };
|
||||
new Or { DestinationReg = Registers.EAX, SourceValue = 0x100 };
|
||||
new Move { DestinationReg = Registers.CR4, SourceReg = Registers.EAX };
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR4 };
|
||||
new Or { DestinationReg = Registers.EAX, SourceValue = 0x200 };
|
||||
new Move { DestinationReg = Registers.CR4, SourceReg = Registers.EAX };
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR0 };
|
||||
|
||||
new And { DestinationReg = Registers.EAX, SourceValue = 0xfffffffd };
|
||||
new Move { DestinationReg = Registers.CR0, SourceReg = Registers.EAX };
|
||||
new Move { DestinationReg = Registers.EAX, SourceReg = Registers.CR0 };
|
||||
|
||||
new And { DestinationReg = Registers.EAX, SourceValue = 1 };
|
||||
new Move { DestinationReg = Registers.CR0, SourceReg = Registers.EAX };
|
||||
|
||||
// END SSE INIT
|
||||
|
||||
new Call { DestinationLabel = EntryPointName };
|
||||
new Label(".loop");
|
||||
new ClrInterruptFlag();
|
||||
new Halt();
|
||||
new Jump { DestinationLabel = ".loop" };
|
||||
new Label("DEBUG_STUB_");
|
||||
new Return();
|
||||
if (mComNumber > 0) {
|
||||
var xStub = new DebugStub();
|
||||
xStub.Main(mComPortAddresses[mComNumber - 1]);
|
||||
}
|
||||
//aOutputWriter.WriteLine("section .data");
|
||||
DataMembers.Add(new DataIfNotDefined("NASM_COMPILATION"));
|
||||
uint xFlags = 0x10003;
|
||||
DataMembers.Add(new DataMember("MultibootSignature",
|
||||
new uint[] { 0x1BADB002 }));
|
||||
DataMembers.Add(new DataMember("MultibootFlags",
|
||||
xFlags));
|
||||
DataMembers.Add(new DataMember("MultibootChecksum",
|
||||
(int)(0 - (xFlags + 0x1BADB002))));
|
||||
DataMembers.Add(new DataMember("MultibootHeaderAddr", new ElementReference("MultibootSignature")));
|
||||
DataMembers.Add(new DataMember("MultibootLoadAddr", new ElementReference("MultibootSignature")));
|
||||
DataMembers.Add(new DataMember("MultibootLoadEndAddr", 0));
|
||||
DataMembers.Add(new DataMember("MultibootBSSEndAddr", 0));
|
||||
DataMembers.Add(new DataMember("MultibootEntryAddr", new ElementReference("Kernel_Start")));
|
||||
DataMembers.Add(new DataEndIfDefined());
|
||||
DataMembers.Add(new DataIfDefined("NASM_COMPILATION"));
|
||||
xFlags = 0x00003;
|
||||
DataMembers.Add(new DataMember("MultibootSignature",
|
||||
new uint[] { 0x1BADB002 }));
|
||||
DataMembers.Add(new DataMember("MultibootFlags",
|
||||
xFlags));
|
||||
DataMembers.Add(new DataMember("MultibootChecksum",
|
||||
(int)(0 - (xFlags + 0x1BADB002))));
|
||||
DataMembers.Add(new DataEndIfDefined());
|
||||
DataMembers.Add(new DataMember("MultiBootInfo_Memory_High", 0));
|
||||
DataMembers.Add(new DataMember("MultiBootInfo_Memory_Low", 0));
|
||||
DataMembers.Add(new DataMember("Before_Kernel_Stack",
|
||||
new byte[0x50000]));
|
||||
DataMembers.Add(new DataMember("Kernel_Stack",
|
||||
new byte[0]));
|
||||
DebugStub.EmitDataSection();
|
||||
}
|
||||
|
||||
protected override void OnBeforeFlush() {
|
||||
base.OnBeforeFlush();
|
||||
DataMembers.AddRange(new DataMember[]{
|
||||
new DataMember("_end_data",
|
||||
new byte[0])});
|
||||
new Label("_end_code");
|
||||
}
|
||||
|
||||
public override void FlushText(TextWriter aOutput) {
|
||||
//aOutput.WriteLine("use32");
|
||||
//aOutput.WriteLine("%define NASM_COMPILATION 1");
|
||||
//aOutput.WriteLine("global Kernel_Start");
|
||||
aOutput.WriteLine("[map all main.map]");
|
||||
//aOutput.WriteLine("org 0x500000");
|
||||
base.FlushText(aOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ namespace Indy.IL2CPU.Assembler.X86
|
|||
{
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode= new byte[0xF4]
|
||||
OpCode= new byte[]{0xF4}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,5 +16,15 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
DestinationRef = new ElementReference(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
var xResult = base.ToString();
|
||||
if (!xResult.StartsWith(Mnemonic + " near", StringComparison.InvariantCultureIgnoreCase)) {
|
||||
if (xResult.StartsWith(Mnemonic)) {
|
||||
return Mnemonic + " near " + xResult.Substring(Mnemonic.Length + 1);
|
||||
}
|
||||
}
|
||||
return xResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,14 +7,23 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
[OpCode("mov")]
|
||||
public class Move: InstructionWithDestinationAndSourceAndSize {
|
||||
public static void InitializeEncodingData(Instruction.InstructionData aData){
|
||||
aData.DefaultSize = false;
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xB0 },
|
||||
//NeedsModRMByte=true,
|
||||
OperandSizeByte=0,
|
||||
OperandSizeBitShiftLeft = 3,
|
||||
DestinationReg=Guid.Empty,
|
||||
DestinationRegByte=0,
|
||||
SourceImmediate=true
|
||||
}); // immediate to register
|
||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||
OpCode = new byte[] { 0xC6 },
|
||||
NeedsModRMByte=true,
|
||||
OperandSizeByte=0,
|
||||
DestinationReg=Guid.Empty,
|
||||
DestinationRegByte=1,
|
||||
SourceImmediate=true
|
||||
});
|
||||
//NeedsModRMByte=true,
|
||||
OperandSizeByte = 0,
|
||||
OperandSizeBitShiftLeft = 0,
|
||||
SourceImmediate = true
|
||||
}); // immediate to memory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,8 @@ using System.Text;
|
|||
namespace Indy.IL2CPU.Assembler.X86 {
|
||||
[OpCode("push")]
|
||||
public class Push : InstructionWithDestinationAndSize {
|
||||
public Push() {
|
||||
Size = 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
source/Indy.IL2CPU/Assembler/x86/X/RegisterEBX.cs
Normal file
35
source/Indy.IL2CPU/Assembler/x86/X/RegisterEBX.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Indy.IL2CPU.Assembler.X86.X {
|
||||
public class RegisterEBX : Register32 {
|
||||
public const string Name = "EBX";
|
||||
public static readonly RegisterEBX Instance = new RegisterEBX();
|
||||
|
||||
public override string ToString() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterEBX(ElementReference aReference) {
|
||||
Instance.Move(aReference);
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterEBX(MemoryAction aAction) {
|
||||
Instance.Move(aAction);
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterEBX(UInt32 aValue) {
|
||||
Instance.Move(aValue);
|
||||
return Instance;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterEBX(RegisterECX aValue) {
|
||||
Instance.Move(aValue.GetId());
|
||||
return Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,8 @@ namespace Indy.IL2CPU.Assembler.X86.X {
|
|||
//TODO: Add registers as needed, not all are here yet
|
||||
public RegisterEAX EAX = RegisterEAX.Instance;
|
||||
public RegisterAL AL = RegisterAL.Instance;
|
||||
|
||||
|
||||
public RegisterEBX EBX = RegisterEBX.Instance;
|
||||
public RegisterECX ECX = RegisterECX.Instance;
|
||||
|
||||
public RegisterEDX EDX = RegisterEDX.Instance;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
if (aThis.DestinationReg != Guid.Empty) {
|
||||
xDest = Registers.GetRegisterName(aThis.DestinationReg);
|
||||
} else {
|
||||
xDest = "0x" + aThis.DestinationValue.ToString("X").ToUpperInvariant();
|
||||
xDest = "0x" + aThis.DestinationValue.GetValueOrDefault().ToString("X").ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
if (aThis.DestinationDisplacement != 0) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
set;
|
||||
}
|
||||
|
||||
uint DestinationValue {
|
||||
uint? DestinationValue {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
set;
|
||||
}
|
||||
|
||||
uint SourceValue {
|
||||
uint? SourceValue {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
public bool HasDestinationOperand;
|
||||
public bool HasSourceOperand;
|
||||
|
||||
/// <summary>
|
||||
/// True if by default large (32bit), false if small (16bit)
|
||||
/// </summary>
|
||||
public bool? DefaultSize;
|
||||
public List<InstructionEncodingOption> EncodingOptions = new List<InstructionEncodingOption>();
|
||||
}
|
||||
|
||||
|
|
@ -131,8 +135,261 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
case 64:
|
||||
return "qword";
|
||||
default:
|
||||
return "non-existing size!!";
|
||||
throw new Exception("Invalid size: " + aSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DetermineSize(Indy.IL2CPU.Assembler.Assembler aAssembler, out ulong aSize) {
|
||||
InstructionData xInstructionData = null;
|
||||
using (mInstructionDatasLocker.AcquireReaderLock()) {
|
||||
mInstructionDatas.TryGetValue(this.GetType(), out xInstructionData);
|
||||
}
|
||||
if (xInstructionData == null) {
|
||||
return base.DetermineSize(aAssembler, out aSize);
|
||||
}
|
||||
var xWithDestAndSourceAndSize = this as InstructionWithDestinationAndSourceAndSize;
|
||||
if (xWithDestAndSourceAndSize != null) {
|
||||
return DetermineSize(xWithDestAndSourceAndSize, xInstructionData, out aSize);
|
||||
}
|
||||
var xWithDestAndSource = this as InstructionWithDestinationAndSource;
|
||||
if (xWithDestAndSource != null) {
|
||||
return base.DetermineSize(aAssembler, out aSize);
|
||||
}
|
||||
var xWithDestAndSize = this as InstructionWithDestinationAndSize;
|
||||
if (xWithDestAndSize != null) {
|
||||
return base.DetermineSize(aAssembler, out aSize);
|
||||
}
|
||||
var xWithDest = this as InstructionWithDestination;
|
||||
if (xWithDest != null) {
|
||||
return base.DetermineSize(aAssembler, out aSize);
|
||||
}
|
||||
if (xInstructionData.EncodingOptions.Count > 0) {
|
||||
// todo: improve
|
||||
aSize = (ulong)xInstructionData.EncodingOptions[0].OpCode.Length;
|
||||
return true;
|
||||
}
|
||||
aSize = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool DetermineSize(InstructionWithDestinationAndSourceAndSize aInstruction, InstructionData aInstructionData, out ulong aSize) {
|
||||
var xTheEncodingOption = GetInstructionEncodingOption(aInstruction, aInstructionData);
|
||||
aSize = (ulong)xTheEncodingOption.OpCode.Length;
|
||||
if (xTheEncodingOption.NeedsModRMByte) {
|
||||
aSize += 1;
|
||||
}
|
||||
if (aInstruction.DestinationValue.HasValue || aInstruction.DestinationRef != null) {
|
||||
aSize += 4;
|
||||
}
|
||||
if (aInstruction.SourceValue.HasValue || aInstruction.SourceRef != null) {
|
||||
aSize += 4;
|
||||
}
|
||||
if (aInstructionData.DefaultSize.HasValue && aInstructionData.DefaultSize.Value) {
|
||||
if (aInstruction.Size < 16) {
|
||||
aSize += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static InstructionData.InstructionEncodingOption GetInstructionEncodingOption(InstructionWithDestinationAndSourceAndSize aInstruction, InstructionData aInstructionData) {
|
||||
InstructionData.InstructionEncodingOption xTheEncodingOption = null;
|
||||
for (int i = 0; i < aInstructionData.EncodingOptions.Count; i++) {
|
||||
var xEncodingOption = aInstructionData.EncodingOptions[i];
|
||||
if (!((xEncodingOption.DestinationReg.HasValue && aInstruction.DestinationReg != Guid.Empty) ||
|
||||
(!xEncodingOption.DestinationReg.HasValue && aInstruction.DestinationReg == Guid.Empty))) {
|
||||
// mismatch
|
||||
continue;
|
||||
}
|
||||
if (!((xEncodingOption.DestinationMemory && (aInstruction.DestinationValue != null && aInstruction.DestinationIsIndirect)) ||
|
||||
(!xEncodingOption.DestinationMemory && (aInstruction.DestinationValue == null && !aInstruction.DestinationIsIndirect))) && aInstruction.DestinationIsIndirect) {
|
||||
continue;
|
||||
}
|
||||
if (!((xEncodingOption.DestinationImmediate && aInstruction.DestinationValue != null) ||
|
||||
(!xEncodingOption.DestinationImmediate && aInstruction.DestinationValue == null))) {
|
||||
continue;
|
||||
}
|
||||
if (!((xEncodingOption.SourceReg.HasValue && aInstruction.SourceReg != Guid.Empty) ||
|
||||
(!xEncodingOption.SourceReg.HasValue && aInstruction.SourceReg == Guid.Empty))) {
|
||||
// mismatch
|
||||
continue;
|
||||
}
|
||||
if (!((xEncodingOption.SourceMemory && (aInstruction.SourceValue != null && aInstruction.SourceIsIndirect)) ||
|
||||
(!xEncodingOption.SourceMemory && (aInstruction.SourceValue == null && !aInstruction.SourceIsIndirect))) && aInstruction.SourceIsIndirect) {
|
||||
continue;
|
||||
}
|
||||
if (!((xEncodingOption.SourceImmediate && aInstruction.SourceValue != null) ||
|
||||
(!xEncodingOption.SourceImmediate && aInstruction.SourceValue == null))) {
|
||||
continue;
|
||||
}
|
||||
xTheEncodingOption = xEncodingOption;
|
||||
break;
|
||||
}
|
||||
if (xTheEncodingOption == null) {
|
||||
throw new Exception("No valid EncodingOption found!");
|
||||
}
|
||||
return xTheEncodingOption;
|
||||
}
|
||||
|
||||
public override byte[] GetData(Indy.IL2CPU.Assembler.Assembler aAssembler) {
|
||||
InstructionData xInstructionData = null;
|
||||
using (mInstructionDatasLocker.AcquireReaderLock()) {
|
||||
mInstructionDatas.TryGetValue(this.GetType(), out xInstructionData);
|
||||
}
|
||||
if (xInstructionData == null) {
|
||||
return base.GetData(aAssembler);
|
||||
}
|
||||
var xWithDestAndSourceAndSize = this as InstructionWithDestinationAndSourceAndSize;
|
||||
if (xWithDestAndSourceAndSize != null) {
|
||||
return GetData(aAssembler, xWithDestAndSourceAndSize, xInstructionData);
|
||||
}
|
||||
var xWithDestAndSource = this as InstructionWithDestinationAndSource;
|
||||
if (xWithDestAndSource != null) {
|
||||
return base.GetData(aAssembler);
|
||||
}
|
||||
var xWithDestAndSize = this as InstructionWithDestinationAndSize;
|
||||
if (xWithDestAndSize != null) {
|
||||
return base.GetData(aAssembler);
|
||||
}
|
||||
var xWithDest = this as InstructionWithDestination;
|
||||
if (xWithDest != null) {
|
||||
return base.GetData(aAssembler);
|
||||
}
|
||||
if (xInstructionData.EncodingOptions.Count > 0) {
|
||||
// todo: improve
|
||||
return xInstructionData.EncodingOptions[0].OpCode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static byte[] GetData(Indy.IL2CPU.Assembler.Assembler aAssembler, InstructionWithDestinationAndSourceAndSize aInstruction, InstructionData aInstructionData) {
|
||||
var xEncodingOption = GetInstructionEncodingOption(aInstruction, aInstructionData);
|
||||
var xSize = xEncodingOption.OpCode.Length;
|
||||
if (xEncodingOption.NeedsModRMByte) {
|
||||
xSize += 1;
|
||||
}
|
||||
if (aInstruction.DestinationValue.HasValue || aInstruction.DestinationRef != null) {
|
||||
xSize += 4;
|
||||
}
|
||||
if (aInstruction.SourceValue.HasValue || aInstruction.SourceRef != null) {
|
||||
xSize += 4;
|
||||
}
|
||||
int xExtraOffset = 0;
|
||||
if (aInstructionData.DefaultSize.HasValue && aInstructionData.DefaultSize.Value) {
|
||||
if (aInstruction.Size < 16) {
|
||||
xSize += 1;
|
||||
xExtraOffset = 1;
|
||||
}
|
||||
}
|
||||
var xBuffer = new byte[xSize];
|
||||
Array.Copy(xEncodingOption.OpCode, 0, xBuffer, xExtraOffset, xEncodingOption.OpCode.Length);
|
||||
if (xExtraOffset == 1) {
|
||||
throw new Exception("OperandSize prefix needed!");
|
||||
}
|
||||
if (xEncodingOption.NeedsModRMByte) {
|
||||
if(aInstruction.DestinationReg != Guid.Empty && !aInstruction.DestinationIsIndirect) {
|
||||
xBuffer[xEncodingOption.OpCode.Length] |= 0xC0;
|
||||
}
|
||||
if(aInstruction.DestinationReg != Guid.Empty && aInstruction.DestinationIsIndirect) {
|
||||
//
|
||||
}
|
||||
// todo: add more ModRM stuff
|
||||
}
|
||||
if (aInstruction.DestinationReg != Guid.Empty) {
|
||||
xBuffer[xEncodingOption.DestinationRegByte] |= (byte)(EncodeRegister(aInstruction.DestinationReg) << xEncodingOption.DestinationRegBitShiftLeft);
|
||||
}
|
||||
// todo: add more options
|
||||
if (aInstruction.SourceValue.HasValue) {
|
||||
int xOffset = xEncodingOption.OpCode.Length + xExtraOffset;
|
||||
if(xEncodingOption.NeedsModRMByte) {
|
||||
xOffset++;
|
||||
}
|
||||
Array.Copy(BitConverter.GetBytes(aInstruction.SourceValue.Value), 0, xBuffer, xOffset, 4);
|
||||
}
|
||||
if(aInstructionData.DefaultSize.HasValue) {
|
||||
if(!aInstructionData.DefaultSize.Value && aInstruction.Size > 16) {
|
||||
xBuffer[xEncodingOption.OperandSizeByte] |= (byte)(1 << xEncodingOption.OperandSizeBitShiftLeft);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
return xBuffer;
|
||||
}
|
||||
|
||||
private static byte EncodeRegister(Guid aRegister) {
|
||||
// todo: implement support for other registers
|
||||
if (!Registers.Is32Bit(aRegister)) {
|
||||
throw new Exception("Register not supported!");
|
||||
}
|
||||
if (aRegister == Registers.EAX) return 0x0;
|
||||
if (aRegister == Registers.ECX) return 0x1;
|
||||
if (aRegister == Registers.EDX) return 0x2;
|
||||
if (aRegister == Registers.EBX) return 0x3;
|
||||
if (aRegister == Registers.ESP) return 0x4;
|
||||
if (aRegister == Registers.EBP) return 0x5;
|
||||
if (aRegister == Registers.ESI) return 0x6;
|
||||
if (aRegister == Registers.EDI) return 0x7;
|
||||
throw new Exception("Register not supported!");
|
||||
}
|
||||
|
||||
private ulong? mDataSize;
|
||||
|
||||
public override bool IsComplete(Indy.IL2CPU.Assembler.Assembler aAssembler) {
|
||||
var xWithDestAndSourceAndSize = this as InstructionWithDestinationAndSourceAndSize;
|
||||
if (xWithDestAndSourceAndSize != null) {
|
||||
ulong xAddress;
|
||||
if (xWithDestAndSourceAndSize.DestinationRef != null && !xWithDestAndSourceAndSize.DestinationRef.Resolve(aAssembler, out xAddress)) {
|
||||
return false;
|
||||
}
|
||||
if (xWithDestAndSourceAndSize.DestinationRef != null && !xWithDestAndSourceAndSize.SourceRef.Resolve(aAssembler, out xAddress)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var xWithDestAndSource = this as InstructionWithDestinationAndSource;
|
||||
if (xWithDestAndSource != null) {
|
||||
ulong xAddress;
|
||||
if (xWithDestAndSource.DestinationRef != null && !xWithDestAndSource.DestinationRef.Resolve(aAssembler, out xAddress)) {
|
||||
return false;
|
||||
}
|
||||
if (xWithDestAndSource.DestinationRef != null && !xWithDestAndSource.SourceRef.Resolve(aAssembler, out xAddress)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var xWithDestAndSize = this as InstructionWithDestinationAndSize;
|
||||
if (xWithDestAndSize != null) {
|
||||
ulong xAddress;
|
||||
if (xWithDestAndSize.DestinationRef != null && !xWithDestAndSize.DestinationRef.Resolve(aAssembler, out xAddress)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var xWithDest = this as InstructionWithDestination;
|
||||
if (xWithDest != null) {
|
||||
ulong xAddress;
|
||||
if (xWithDest.DestinationRef!=null && !xWithDest.DestinationRef.Resolve(aAssembler, out xAddress)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override ulong? ActualAddress {
|
||||
get {
|
||||
if (!StartAddress.HasValue) {
|
||||
return null;
|
||||
}
|
||||
if(!mDataSize.HasValue){
|
||||
return null;
|
||||
}
|
||||
return StartAddress.Value + mDataSize.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsLargeRegister(Guid aRegister) {
|
||||
return Registers.Is32Bit(aRegister);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
set;
|
||||
}
|
||||
|
||||
public uint DestinationValue {
|
||||
public uint? DestinationValue {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
set;
|
||||
}
|
||||
|
||||
public uint SourceValue {
|
||||
public uint? SourceValue {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
|||
if (SourceReg != Guid.Empty) {
|
||||
xDest = Registers.GetRegisterName(SourceReg);
|
||||
} else {
|
||||
xDest = "0x" + SourceValue.ToString("X").ToUpperInvariant();
|
||||
xDest = "0x" + SourceValue.GetValueOrDefault().ToString("X").ToUpperInvariant();
|
||||
}
|
||||
}
|
||||
if (SourceDisplacement != 0) {
|
||||
|
|
|
|||
|
|
@ -167,10 +167,9 @@ namespace Indy.IL2CPU {
|
|||
switch (aTargetPlatform) {
|
||||
case TargetPlatformEnum.X86: {
|
||||
mMap = new Indy.IL2CPU.IL.X86.X86OpCodeMap();
|
||||
mAssembler = new Assembler.X86.Assembler(aGetFileNameForGroup,
|
||||
((aDebugMode != DebugMode.None) && (aDebugMode != DebugMode.MLUsingGDB))
|
||||
? aDebugComNumber
|
||||
: (byte)0);
|
||||
mAssembler = new Assembler.X86.CosmosAssembler(((aDebugMode != DebugMode.None) && (aDebugMode != DebugMode.MLUsingGDB))
|
||||
? aDebugComNumber
|
||||
: (byte)0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.ESI};
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESI };
|
||||
//Assembler.StackSizes.Push(xElementCountSize);
|
||||
new CPUx86.Push { DestinationValue = mElementSize };
|
||||
new CPUx86.Push { Size=32,DestinationValue = mElementSize };
|
||||
Assembler.StackContents.Push(new StackContent(4, typeof(uint)));
|
||||
Multiply(Assembler);
|
||||
// the total items size is now on the stack
|
||||
new CPUx86.Push { DestinationValue = (ObjectImpl.FieldDataOffset + 4) };
|
||||
new CPUx86.Push { Size=32,DestinationValue = (ObjectImpl.FieldDataOffset + 4) };
|
||||
Assembler.StackContents.Push(new StackContent(4, typeof(uint)));
|
||||
Add(Assembler);
|
||||
// the total array size is now on the stack.
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
throw new Exception("Remainder size " + (aField.Size) + " not supported!");
|
||||
}
|
||||
if (aAddGCCode && aField.NeedsGC) {
|
||||
new CPUx86.Push { DestinationReg = Registers.ESP, DestinationIsIndirect = true };
|
||||
new CPUx86.Push {Size=32, DestinationReg = Registers.ESP, DestinationIsIndirect = true };
|
||||
Engine.QueueMethod(GCImplementationRefs.IncRefCountRef);
|
||||
new CPUx86.Call { DestinationLabel = Label.GenerateLabelName(GCImplementationRefs.IncRefCountRef) };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
|
||||
public override void Push(uint aValue) {
|
||||
new CPUx86.Push { DestinationValue = aValue };
|
||||
new CPUx86.Push {Size=32, DestinationValue = aValue };
|
||||
}
|
||||
|
||||
private int xLabelId = 0;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
foreach (var xLocal in aLocals) {
|
||||
aAssembler.StackContents.Push(new StackContent(xLocal.Size, xLocal.VariableType));
|
||||
for (int i = 0; i < (xLocal.Size / 4); i++) {
|
||||
new CPUx86.Push{DestinationValue=0};
|
||||
new CPUx86.Push{Size=32,DestinationValue=0};
|
||||
}
|
||||
}
|
||||
if(aDebugMode&& aIsNonDebuggable) {
|
||||
|
|
|
|||
|
|
@ -90,11 +90,13 @@
|
|||
<Compile Include="Assembler\EndIfDefined.cs" />
|
||||
<Compile Include="Assembler\IfDefined.cs" />
|
||||
<Compile Include="Assembler\IfNotDefined.cs" />
|
||||
<Compile Include="Assembler\x86\CosmosAssembler.cs" />
|
||||
<Compile Include="Assembler\x86\In.cs" />
|
||||
<Compile Include="Assembler\x86\JumpToSegment.cs" />
|
||||
<Compile Include="Assembler\x86\MoveIfBelow.cs" />
|
||||
<Compile Include="Assembler\x86\MoveIfLess.cs" />
|
||||
<Compile Include="Assembler\x86\Registers_Old.cs" />
|
||||
<Compile Include="Assembler\x86\X\RegisterEBX.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\Extensions.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\IInstructionWithDestination.cs" />
|
||||
<Compile Include="Assembler\x86\_Infra\IInstructionWithSize.cs" />
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ namespace TestApp {
|
|||
class Renderer : Y86 {
|
||||
public void DoRender() {
|
||||
Label = "Kernel_Start";
|
||||
EAX = 0xB8000;
|
||||
EBX = 0xB8000;
|
||||
Memory[EBX, 8] = 65;
|
||||
//IfDefined("DefinedSymbol");
|
||||
//Memory[0xB8002, 8] = 66;
|
||||
//Memory[0xB8003, 8] = 15;
|
||||
|
|
@ -26,11 +27,7 @@ namespace TestApp {
|
|||
}
|
||||
static void Main(string[] args) {
|
||||
try {
|
||||
var xAsm = new Assembler(delegate(string aGroup) {
|
||||
return Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
"Output"),
|
||||
aGroup + ".out");
|
||||
});
|
||||
var xAsm = new Assembler();
|
||||
xAsm.Initialize();
|
||||
xAsm.DataMembers.Add(new Indy.IL2CPU.Assembler.DataMember("TestData", new byte[]{65, 66, 67, 68,69,70, 71, 72, 73, 74}));
|
||||
xAsm.Instructions.Clear();
|
||||
|
|
@ -42,17 +39,17 @@ namespace TestApp {
|
|||
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
"Output"));
|
||||
}
|
||||
//using (Stream xOutput = new FileStream(Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
// "Output"),
|
||||
// "TheOutput.out"), FileMode.Create)) {
|
||||
// xAsm.FlushBinary(xOutput, 0x500000);
|
||||
//}
|
||||
|
||||
using (StreamWriter xOutput = new StreamWriter(Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
using (Stream xOutput = new FileStream(Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
"Output"),
|
||||
"TheOutput.out"))) {
|
||||
xAsm.FlushText(xOutput);
|
||||
}
|
||||
"TheOutput.bin"), FileMode.Create)) {
|
||||
xAsm.FlushBinary(xOutput, 0x500000);
|
||||
}
|
||||
|
||||
//using (StreamWriter xOutput = new StreamWriter(Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
|
||||
// "Output"),
|
||||
// "TheOutput.asm"))) {
|
||||
// xAsm.FlushText(xOutput);
|
||||
//}
|
||||
|
||||
// now the file should have been written
|
||||
} catch (Exception E) { Console.WriteLine(E.ToString()); }
|
||||
|
|
|
|||
Loading…
Reference in a new issue