mor stuff, mostly ui
This commit is contained in:
parent
0a08fa128b
commit
1aff62163a
104
source/app.d
104
source/app.d
|
@ -21,6 +21,12 @@ struct Chip8Status {
|
|||
Disassembly
|
||||
}
|
||||
|
||||
enum DisassemblyMode {
|
||||
Linear,
|
||||
Recursive,
|
||||
Dynamic
|
||||
}
|
||||
|
||||
private {
|
||||
|
||||
Chip8* emu_;
|
||||
|
@ -29,11 +35,13 @@ struct Chip8Status {
|
|||
int range_end_;
|
||||
|
||||
// disassembly state
|
||||
DisassemblyMode ass_mode_;
|
||||
Instr[] disassembly_;
|
||||
|
||||
}
|
||||
|
||||
void initialize(Chip8* emu) {
|
||||
mode_ = ViewMode.Disassembly;
|
||||
emu_ = emu;
|
||||
} // initialize
|
||||
|
||||
|
@ -55,39 +63,54 @@ struct Chip8Status {
|
|||
default: return "%s";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // formatQual
|
||||
|
||||
void disassemble() {
|
||||
ubyte[] instrs = emu_.ram[range_start_ .. range_end_];
|
||||
disassembly_ = Assembler.disassemble(instrs);
|
||||
writefln("%s", disassembly_);
|
||||
}
|
||||
} // disassemble
|
||||
|
||||
void setRange(ushort start, ushort end) {
|
||||
range_start_ = start;
|
||||
range_end_ = end;
|
||||
}
|
||||
} // setRange
|
||||
|
||||
void reset() {
|
||||
disassembly_ = null;
|
||||
} // reset
|
||||
|
||||
void draw() {
|
||||
|
||||
import std.range : chunks;
|
||||
|
||||
if (mode_ == ViewMode.Memory) igBegin("Emulator Assembly - Memory View");
|
||||
else if (mode_ == ViewMode.Disassembly) igBegin("Emulator Assembly - Disassembly View");
|
||||
|
||||
if (igButton("Switch Mode")) {
|
||||
mode_ = cast(ViewMode)((mode_ + 1) % 2);
|
||||
}
|
||||
igBegin("Emulator Assembly");
|
||||
igRadioButton("Memory View", cast(int*)&mode_, cast(int)ViewMode.Memory); igSameLine();
|
||||
igRadioButton("Disassembly View", cast(int*)&mode_, cast(int)ViewMode.Disassembly);
|
||||
|
||||
if (mode_ == ViewMode.Memory) {
|
||||
} else if (mode_ == ViewMode.Disassembly) {
|
||||
igInputInt("Range Start: ", &range_start_);
|
||||
igInputInt("Range End: ", &range_end_);
|
||||
igInputInt("Range Start ", &range_start_);
|
||||
igInputInt("Range End ", &range_end_);
|
||||
igNewLine();
|
||||
|
||||
igText("Disassembly Mode");
|
||||
igRadioButton("Linear", cast(int*)&ass_mode_, cast(int)DisassemblyMode.Linear); igSameLine();
|
||||
igRadioButton("Recursive", cast(int*)&ass_mode_, cast(int)DisassemblyMode.Recursive); igSameLine();
|
||||
igRadioButton("Dynamic", cast(int*)&ass_mode_, cast(int)DisassemblyMode.Dynamic);
|
||||
if (igButton("Disassemble")) {
|
||||
final switch (ass_mode_) with (DisassemblyMode) {
|
||||
case Linear:
|
||||
disassemble();
|
||||
break;
|
||||
case Recursive:
|
||||
break;
|
||||
case Dynamic:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (range_start_ < 0) range_start_ = 0;
|
||||
if (range_start_ > ushort.max) range_start_ = 0;
|
||||
|
||||
|
@ -102,7 +125,20 @@ struct Chip8Status {
|
|||
}
|
||||
*/
|
||||
} else if (mode_ == ViewMode.Disassembly) {
|
||||
|
||||
int cur_offset = range_start_;
|
||||
foreach (ref instr; disassembly_) {
|
||||
|
||||
if (emu_.cpu.pc == cur_offset) {
|
||||
igTextColored(ImColor(0, 255, 0), "0x%03X |", cur_offset);
|
||||
cur_offset += 2;
|
||||
igSameLine();
|
||||
} else {
|
||||
igText("0x%03X |", cur_offset);
|
||||
cur_offset += 2;
|
||||
igSameLine();
|
||||
}
|
||||
|
||||
switch (instr.args) {
|
||||
case 3:
|
||||
|
||||
|
@ -111,12 +147,12 @@ struct Chip8Status {
|
|||
|
||||
Arg a1_arg;
|
||||
auto a1 = instr.a1(a1_arg);
|
||||
igText(formatQual(a1_arg), a1, true);
|
||||
igText(formatQual(a1_arg, true), a1);
|
||||
igSameLine();
|
||||
|
||||
Arg a2_arg;
|
||||
auto a2 = instr.a2(a2_arg);
|
||||
igText(formatQual(a2_arg), a2, true);
|
||||
igText(formatQual(a2_arg, true), a2);
|
||||
igSameLine();
|
||||
|
||||
Arg a3_arg;
|
||||
|
@ -132,7 +168,7 @@ struct Chip8Status {
|
|||
|
||||
Arg a1_arg;
|
||||
auto a1 = instr.a1(a1_arg);
|
||||
igText(formatQual(a1_arg), a1, true);
|
||||
igText(formatQual(a1_arg, true), a1);
|
||||
igSameLine();
|
||||
|
||||
Arg a2_arg;
|
||||
|
@ -221,6 +257,7 @@ struct Chip8Status {
|
|||
loaded_program = null;
|
||||
|
||||
emu_.reset();
|
||||
ass_.reset();
|
||||
|
||||
} // resetShortcut
|
||||
|
||||
|
@ -232,6 +269,7 @@ struct Chip8Status {
|
|||
auto buf = read("programs/chip8_picture.ch8");
|
||||
emu_.load(0x200, buf); // do ze load yes, will copy all the data in
|
||||
ass_.setRange(cast(ushort)0x200, cast(ushort)(0x200 + cast(ushort)buf.length));
|
||||
ass_.reset();
|
||||
|
||||
} // loadShortcut
|
||||
|
||||
|
@ -417,6 +455,25 @@ pure
|
|||
|
||||
struct Chip8 {
|
||||
|
||||
ubyte[80] chip8_fontset = [
|
||||
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
|
||||
0x20, 0x60, 0x20, 0x20, 0x70, // 1
|
||||
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
|
||||
0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
|
||||
0x90, 0x90, 0xF0, 0x10, 0x10, // 4
|
||||
0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
|
||||
0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
|
||||
0xF0, 0x10, 0x20, 0x40, 0x40, // 7
|
||||
0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
|
||||
0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
|
||||
0xF0, 0x90, 0xF0, 0x90, 0x90, // A
|
||||
0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
|
||||
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
||||
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
||||
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
||||
0xF0, 0x80, 0xF0, 0x80, 0x80 // F
|
||||
];
|
||||
|
||||
alias OpCode = ushort;
|
||||
alias ProgramCounter = ushort;
|
||||
alias Memory = ubyte[4096];
|
||||
|
@ -461,8 +518,18 @@ struct Chip8 {
|
|||
|
||||
ram[offset .. offset + data.length] = cast(ubyte[])data[];
|
||||
|
||||
loadFont(); // again
|
||||
|
||||
} // load
|
||||
|
||||
void loadFont() {
|
||||
|
||||
foreach (i, b; chip8_fontset) {
|
||||
ram[i] = b;
|
||||
}
|
||||
|
||||
} // loadFont
|
||||
|
||||
void reset() {
|
||||
|
||||
reset_flag = true;
|
||||
|
@ -655,7 +722,7 @@ struct Chip8 {
|
|||
|
||||
import std.random : uniform;
|
||||
ubyte x = cpu.opcode.x;
|
||||
cpu.v[x] = uniform(Register.min, Register.max) & (cpu.opcode & 0x00FF);
|
||||
cpu.v[x] = uniform(Register.min, Register.max) & x;
|
||||
break;
|
||||
|
||||
// 0xDXYN
|
||||
|
@ -706,6 +773,7 @@ struct Chip8 {
|
|||
|
||||
case 0x0001: // 0xEXA1 Skips the next instruction if the key stored in VX isn't pressed.
|
||||
writefln("0xEXA1: skip instruction if VX not pressed: %x", key);
|
||||
pc_target += 2;
|
||||
break;
|
||||
|
||||
default: //unhandled for some reason
|
||||
|
@ -748,8 +816,8 @@ struct Chip8 {
|
|||
case 0x0029: // 0xFX29 Sets I to the location of the sprite for the character in VX.
|
||||
|
||||
immutable ubyte vx = cpu.v[cpu.opcode.x];
|
||||
immutable ushort char_addr = 0x200 + (vx * 40); // base of char sprites + value of vx * bits per character
|
||||
// immutable ushort char_addr = vx * 0x5;
|
||||
// immutable ushort char_addr = 0x200 + (vx * 40); // base of char sprites + value of vx * bits per character
|
||||
immutable ushort char_addr = vx * 0x05;
|
||||
cpu.i = char_addr;
|
||||
break;
|
||||
|
||||
|
|
|
@ -260,6 +260,9 @@ struct Assembler {
|
|||
auto instr_output = Appender!(Instruction[])();
|
||||
|
||||
foreach (ref ubyte[] i; instructions.chunks(2)) {
|
||||
|
||||
if (i.length != 2) break;
|
||||
|
||||
ushort opcode = i[0] << 8 | i[1];
|
||||
|
||||
switch (opcode & 0xF000) {
|
||||
|
@ -273,7 +276,8 @@ struct Assembler {
|
|||
break;
|
||||
default: // 0x0NNN Calls RCA 1802 program at address NNN. Not necessary for most ROMs. | SYS addr
|
||||
//assert(0, "0x0NNN RCA 1802 program opcode not implemented!");
|
||||
instr_output ~= Instruction(opcode, OpCode.SYS, Argument.addr);
|
||||
// instr_output ~= Instruction(opcode, OpCode.SYS, Argument.addr);
|
||||
instr_output ~= Instruction(opcode, OpCode.UNK);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue