Skip to content

Commit

Permalink
fuck
Browse files Browse the repository at this point in the history
  • Loading branch information
zaydlang committed Sep 6, 2024
1 parent 5db63bc commit 269cd21
Show file tree
Hide file tree
Showing 16 changed files with 379 additions and 100 deletions.
2 changes: 1 addition & 1 deletion source/emu/hw/cpu/arm946e_s.d
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ final class ARM946E_S : ArmCPU {

if (regs[pc] == 0x201ec50 && scheduler.get_current_time_relative_to_cpu() > 0x50000000) {
log_arm7("Called: %x", regs[0]);
num_log = 30;
// num_log = 30;
}

if (instruction_set == InstructionSet.ARM) {
Expand Down
8 changes: 3 additions & 5 deletions source/emu/hw/gpu/gpu3d/geometry_engine.d
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,7 @@ final class GeometryEngine {
previous_point = point;

auto clip_matrix_point = (projection_matrix * modelview_matrix) * expand_point(point);

if (polygon_index == 4) {
if ((input.keys & DSKeyCode.DOWN) == 0) {
if (polygon_index == 7) {
log_gpu3d("Current projection matrix:");
for (int i = 0; i < 4; i++) {
log_gpu3d(" %f %f %f %f", cast(float) projection_matrix[i][0], cast(float) projection_matrix[i][1], cast(float) projection_matrix[i][2], cast(float) projection_matrix[i][3]);
Expand All @@ -257,8 +255,8 @@ final class GeometryEngine {

log_gpu3d("Current point before projection: %f %f %f %f", cast(float) point[0], cast(float) point[1], cast(float) point[2], cast(float) point[3]);
log_gpu3d("Current point after projection: %f %f %f %f", cast(float) clip_matrix_point[0], cast(float) clip_matrix_point[1], cast(float) clip_matrix_point[2], cast(float) clip_matrix_point[3]);
}
}
log_gpu3d("raw point before proj: %x %x %x %x", point[0].repr, point[1].repr, point[2].repr, point[3].repr);
log_gpu3d("raw point after proj: %x %x %x %x", clip_matrix_point[0].repr, clip_matrix_point[1].repr, clip_matrix_point[2].repr, clip_matrix_point[3].repr);}
// if (texture_transformation_mode == TextureTransformationMode.VERTEX) {
// texture_matrix[3][0] = texcoord[0];
// texture_matrix[3][1] = texcoord[1];
Expand Down
10 changes: 1 addition & 9 deletions source/emu/hw/gpu/gpu3d/gpu3d.d
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,10 @@ final class GPU3D {
void add(Pixel pixel, Coord_14_18 z, Coord_14_18 w, bool depth_buffering_mode, bool enable_alpha_blending) {
if (z > w || z < -w) return;
if (w < 0) return;
if (z < 0) return;
// pixel.r = -(cast(float) w) > 31 ? 31 : - cast(int) cast(float) w;
// pixel.g = 0;
// pixel.b = 0;
if (w < 5) return;

if (cast(float) w < 5) {
pixel.r = 31;
pixel.g = 0;
pixel.b = 0;
pixel.a = 31;
}

if (enable_alpha_blending) {
// sort by either w or z depending on depth_buffering_mode
for (int i = 0; i < count; i++) {
Expand Down
261 changes: 228 additions & 33 deletions source/emu/hw/gpu/gpu3d/rendering_engine.d

Large diffs are not rendered by default.

29 changes: 18 additions & 11 deletions source/emu/hw/gpu/gpu3d/texture.d
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ final class TextureResolver {
}

T read_slot(T)(SlotType slot_type, Word address) {
int slot = address >> 17;
int shift = slot_type == SlotType.TEXTURE ? 17 : 14;

int slot = address >> shift;
if (slot > 4) slot = 4;

static if (is (T == Word)) return mem.vram_read_slot_word(slot_type, slot, address % (1 << 17));
static if (is (T == Half)) return mem.vram_read_slot_half(slot_type, slot, address % (1 << 17));
static if (is (T == Byte)) return mem.vram_read_slot_byte(slot_type, slot, address % (1 << 17));
static if (is (T == Word)) return mem.vram_read_slot_word(slot_type, slot, address % (1 << shift));
static if (is (T == Half)) return mem.vram_read_slot_half(slot_type, slot, address % (1 << shift));
static if (is (T == Byte)) return mem.vram_read_slot_byte(slot_type, slot, address % (1 << shift));
}

float[4] get_color_from_texture(int s, int t, AnnotatedPolygon p, Word palette_base_address) {
Expand Down Expand Up @@ -122,28 +124,33 @@ final class TextureResolver {
];

case TextureFormat.TEXEL_COMPRESSED_4x4:
uint blocks_per_row = texture_s_size / 4;
uint block_x = s / 4;
uint block_y = t / 4;
uint block_fine_x = s % 4;
uint block_fine_y = t % 4;
uint blocks_per_row = texture_s_size / 4; // row_size
uint block_x = s / 4; // row_x
uint block_y = t / 4; // row_y
uint block_fine_x = s % 4; // tile_x
uint block_fine_y = t % 4; // tile_y
uint block_index = block_y * blocks_per_row + block_x;

Word compressed_block_base_address = (Word(p.orig.texture_vram_offset) << 3) + block_index * 4 + block_fine_y;
Word compressed_block_base_address = (Word(p.orig.texture_vram_offset) << 3) + block_index * 4 + block_fine_y; // data_address

Word compressed_block = read_slot!Byte(SlotType.TEXTURE, compressed_block_base_address);
int texel = (compressed_block >> (2 * block_fine_x)) & 3;

int compressed_block_slot = compressed_block_base_address >> 17;
if (compressed_block_slot != 0 && compressed_block_slot != 2) error_gpu3d("Invalid slot for compressed texture: (address: %x offset: %x, idx: %x)", compressed_block_base_address, p.orig.texture_vram_offset, texel_index);

Word palette_info_address = (1 << 17) + compressed_block_slot * 0x8000 + compressed_block_base_address / 2;
Word palette_info_address = (1 << 17) + compressed_block_slot * 0x8000 + (compressed_block_base_address & 0x1FFFF) / 2;
Half palette_info = read_slot!Half(SlotType.TEXTURE, palette_info_address);
int palette_offset = palette_info[0 ..13];
int palette_mode = palette_info[14..15];

Word color_addr = palette_base_address * 16 + palette_offset * 4;


// auto data_slot_index = data_address >> 18; // 0 or 1?
// auto data_slot_offset = data_address & 0x1FFFF;
// auto info_address = 0x20000 + (data_slot_offset >> 1) + (data_slot_index * 0x10000);

// From GBATek:

// The 2bit Texel values (0..3) are intepreted depending on the Mode (0..3),
Expand Down
2 changes: 1 addition & 1 deletion source/emu/hw/gpu/slottype.d
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module emu.hw.gpu.slottype;

enum SLOT_SIZE_BG = 1 << 13;
enum SLOT_SIZE_BG = 1 << 14;
enum SLOT_SIZE_TEX = 1 << 17;

enum SlotType {
Expand Down
5 changes: 5 additions & 0 deletions source/emu/hw/gpu/vramblock.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module emu.hw.gpu.vramblock;

import emu.hw.cpu.instructionblock;
import emu.hw.gpu.slottype;
import emu.hw.memory.mem;
import util;
Expand Down Expand Up @@ -36,4 +37,8 @@ final class VRAMBlock {
void write(T)(Word access_address, T value) {
data.write!T(access_address - address, value);
}

InstructionBlock* instruction_read(Word access_address) {
return data.instruction_read(access_address - address);
}
}
38 changes: 26 additions & 12 deletions source/emu/hw/memory/strategy/fastmem/fastmem.d
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ final class FastMem : MemStrategy {
return vmem.read!T(vram_slots[slot_type], address + (slot << 17));
}

int slot_shift_for_type(SlotType slot_type) {
final switch (slot_type) {
case SlotType.BG_PAL_A: return 17;
case SlotType.BG_PAL_B: return 17;
case SlotType.OBJ_PAL_A: return 17;
case SlotType.OBJ_PAL_B: return 17;
case SlotType.TEXTURE_PAL: return 14;
case SlotType.TEXTURE: return 17;
}
}

override {
void vram_remap_slots(VRAMBlock[10] blocks) {
for (int i = 0; i < 10; i++) {
Expand All @@ -137,18 +148,21 @@ final class FastMem : MemStrategy {
vram_c_address = blocks[2].address;
vram_d_address = blocks[3].address;

for (int i = 0; i < 10; i++) {
if (i == 7) continue;

int num_times_mapped = 0;
VRAMBlock block = blocks[i];
if (block.slot_mapped) {
for (int j = 0; j < 5; j++) {
if (block.slot.bit(j)) {
u32 offset = block.slot_ofs + num_times_mapped * SLOT_SIZE_BG;
u32 address = (j << 17);
vmem.map_with_offset(vram_slots[block.slot_type], vram_regions[i], address, offset);
num_times_mapped++;
for (int slot_type = 0; slot_type < 6; slot_type++) {
for (int i = 0; i < 10; i++) {
if (i == 7) continue;

int num_times_mapped = 0;
VRAMBlock block = blocks[i];
if (block.slot_mapped && block.slot_type == slot_type) {
for (int j = 0; j < 5; j++) {
int slot_size = 1 << slot_shift_for_type(cast(SlotType) slot_type);
if (block.slot.bit(j)) {
u32 offset = block.slot_ofs + num_times_mapped * slot_size;
u32 address = (j << 17);
vmem.map_with_offset(vram_slots[block.slot_type], vram_regions[i], address, slot_size, offset);
num_times_mapped++;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/emu/hw/memory/strategy/fastmem/virtualmemory.d
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ final class VirtualMemoryManager {
map_generic(space, memory_region, address, size, stride, 0);
}

void map_with_offset(VirtualMemorySpace* space, MemoryRegion* memory_region, u64 address, u64 offset) {
void map_with_offset(VirtualMemorySpace* space, MemoryRegion* memory_region, u64 address, u64 size, u64 offset) {
map_generic(space, memory_region, address, memory_region.size, memory_region.size, offset);
}

Expand Down
2 changes: 1 addition & 1 deletion source/emu/hw/memory/strategy/memstrategy.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import emu.hw.memory.strategy.fastmem;
import emu.hw.memory.strategy.slowmem;
import util;

alias Mem = SlowMem;
alias Mem = FastMem;

interface MemStrategy {
Word read_data_word7(Word address);
Expand Down
1 change: 1 addition & 0 deletions source/emu/hw/memory/strategy/slowmem/slowmem.d
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ import emu.hw.cpu.arm946e_s;
case 0x0: .. case 0x1: return bios7.instruction_read(address);
case 0x2: return main_memory.instruction_read(address % MAIN_MEMORY_SIZE);
case 0x3: return wram.instruction_read7(address);
case 0x6: return vram.instruction_read7(address);

default: error_unimplemented("Attempt from ARM7 to perform an instruction read from an invalid region of memory: %x", address); break;
}
Expand Down
58 changes: 44 additions & 14 deletions source/emu/hw/memory/strategy/slowmem/vram.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module emu.hw.memory.strategy.slowmem.vram;

import emu.hw.cpu.instructionblock;
import emu.hw.gpu.engines;
import emu.hw.gpu.slottype;
import emu.hw.gpu.vramblock;
Expand Down Expand Up @@ -33,21 +34,39 @@ final class SlowMemVRAM {
bool vram_c_in_ram;
bool vram_d_in_ram;

int slot_shift_for_type(SlotType slot_type) {
final switch (slot_type) {
case SlotType.BG_PAL_A: return 17;
case SlotType.BG_PAL_B: return 17;
case SlotType.OBJ_PAL_A: return 17;
case SlotType.OBJ_PAL_B: return 17;
case SlotType.TEXTURE_PAL: return 14;
case SlotType.TEXTURE: return 17;
}
}

void remap_slots(VRAMBlock[10] blocks) {
this.blocks = blocks;

for (int i = 0; i < 10; i++) {
int num_times_mapped = 0;
VRAMBlock block = blocks[i];
if (block.slot_mapped) {
for (int j = 0; j < 5; j++) {
if (block.slot.bit(j)) {
all_slots[block.slot_type][j] = cast(Slot*) (&block.data[block.slot_ofs + num_times_mapped * (SLOT_SIZE_BG)]);
num_times_mapped++;
for (int slot_type = 0; slot_type < 6; slot_type++) {
for (int i = 0; i < 10; i++) {
int num_times_mapped = 0;
VRAMBlock block = blocks[i];
log_vram("Checking block %d. Slot type: %d, slot mapped: %d (%d)", i, block.slot_type, block.slot_mapped, slot_type);
if (block.slot_mapped && block.slot_type == slot_type) {
log_vram("Block has bits: %d", block.slot);
for (int j = 0; j < 5; j++) {
int slot_size = 1 << slot_shift_for_type(cast(SlotType) slot_type);
if (block.slot.bit(j)) {
log_vram("Mapping slot %d of type %s to block %d %d %d %d", j, slot_type, i, block.slot_ofs, num_times_mapped, SLOT_SIZE_BG);
all_slots[block.slot_type][j] = cast(Slot*) (&block.data[block.slot_ofs + num_times_mapped * slot_size]);
num_times_mapped++;
}
}
}
}
}

}

T read_slot(T)(SlotType slot_type, int slot, Word address) {
Expand Down Expand Up @@ -143,23 +162,34 @@ final class SlowMemVRAM {

if (vram_c_in_ram && blocks[2].in_range(address)) result |= blocks[2].read!T(address);
if (vram_d_in_ram && blocks[3].in_range(address)) result |= blocks[3].read!T(address);
if (!vram_c_in_ram && !vram_d_in_ram) {
error_vram("Tried to read from VRAM C/D when they're not mapped to RAM!");
}
// if (!vram_c_in_ram && !vram_d_in_ram) {
// error_vram("Tried to read from VRAM C/D when they're not mapped to RAM!");
// }

return result;
}
}

InstructionBlock* instruction_read7(Word address) {
if (vram_c_in_ram && blocks[2].in_range(address)) return blocks[2].instruction_read(address);
if (vram_d_in_ram && blocks[3].in_range(address)) return blocks[3].instruction_read(address);
// if (!vram_c_in_ram && !vram_d_in_ram) {
// error_vram("Tried to read from VRAM C/D when they're not mapped to RAM!");
// }

// cope and seethe
return blocks[3].instruction_read(address);
}

void write_data7(T)(Word address, T value) {
static if (!is_memory_unit!T) {
error_vram("Tried to write to VRAM with wrong type (size: %d)", T.sizeof);
} else {
if (vram_c_in_ram && blocks[2].in_range(address)) blocks[2].write!T(address, value);
if (vram_d_in_ram && blocks[3].in_range(address)) blocks[3].write!T(address, value);
if (!vram_c_in_ram && !vram_d_in_ram) {
error_vram("Tried to read from VRAM C/D when they're not mapped to RAM!");
}
// if (!vram_c_in_ram && !vram_d_in_ram) {
// error_vram("Tried to read from VRAM C/D when they're not mapped to RAM!");
// }
}
}
}
2 changes: 1 addition & 1 deletion source/emu/hw/nds.d
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ final class NDS {

int get_backup_size() {
// lol, fix this later
return 32 * 256;
return 262144;
}

void load_save_mmfile(MmFile save_mmfile) {
Expand Down
21 changes: 16 additions & 5 deletions source/emu/hw/spi/device/eeprom.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import std.mmfile;
import util;

public class EEPROM(int page_size, int num_pages) : SPIDevice {
enum total_bytes = page_size * num_pages;
enum total_bytes = 262144;

enum State {
WAITING_FOR_COMMAND,
Expand Down Expand Up @@ -43,7 +43,7 @@ public class EEPROM(int page_size, int num_pages) : SPIDevice {
this.save_mmfile = save_mmfile;
data = cast(Byte[]) save_mmfile[];
}

int access_number = 0;
override Byte write(Byte b) {
Byte result = 0;

Expand All @@ -65,7 +65,18 @@ public class EEPROM(int page_size, int num_pages) : SPIDevice {
break;

case State.READING_JEDEC_ID:
result = 0xFF;
// result = 0xFF;
if (access_number > 3) access_number -= 3;

switch (access_number) {
case 0: return Byte(0x20);
case 1: return Byte(0x40);
case 2: return Byte(0x12);

default:
error_firmware("this is an unreachable state, something really went wrong");
return Byte(0);
}
break;

// bad code
Expand Down Expand Up @@ -131,11 +142,11 @@ public class EEPROM(int page_size, int num_pages) : SPIDevice {
case 0x05: state = State.READING_STATUS; break;
case 0x01: state = state.WRITING_STATUS; break;
case 0x03: state = State.READING_DATA; accesses_remaining = page_size + 2; break;
case 0x02: state = State.WRITING_DATA; accesses_remaining = page_size + 2; break;
case 0x0A: state = State.WRITING_DATA; accesses_remaining = page_size + 2; break;
case 0x9F: state = State.READING_JEDEC_ID; break;
case 0x06: write_enable_latch = true; break;
case 0x04: write_enable_latch = false; break;
default: log_eeprom("invalid eeprom command dummy: %x", b);
default: error_eeprom("invalid eeprom command dummy: %x", b);
}
}
}
12 changes: 6 additions & 6 deletions source/util/log.d
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static ulong get_largest_logsource_length()(){

// thanks https://github.com/dlang/phobos/blob/4239ed8ebd3525206453784908f5d37c82d338ee/std/outbuffer.d
private void log(LogSource log_source, bool fatal, Char, A...)(scope const(Char)[] fmt, A args) {
if (!fatal && log_source != LogSource.ARM7) {
if (!fatal && log_source != LogSource.VRAM) {
return;
}
import core.runtime;
Expand Down Expand Up @@ -96,12 +96,12 @@ private void log(LogSource log_source, bool fatal, Char, A...)(scope const(Char)
// nds.mem.dump();


// auto trace = defaultTraceHandler(null);
// foreach (line; trace) {
// printf("%.*s\n", cast(int) line.length, line.ptr);
// }
auto trace = defaultTraceHandler(null);
foreach (line; trace) {
printf("%.*s\n", cast(int) line.length, line.ptr);
}

// exit(-1);
exit(-1);
}
}
}
Expand Down
Loading

0 comments on commit 269cd21

Please sign in to comment.