Skip to content

Commit

Permalink
Start emitting vramclass start symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
AngheloAlf committed Apr 28, 2024
1 parent 170b4b1 commit ddec464
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 24 deletions.
14 changes: 14 additions & 0 deletions slinky/src/linker_symbols_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,18 @@ impl LinkerSymbolsStyle {
LinkerSymbolsStyle::Makerom => format!("_{}Offset", name),
}
}

pub fn vram_class_start(&self, name: &str) -> String {
match self {
LinkerSymbolsStyle::Splat => format!("{}_CLASS_VRAM_START", name),
LinkerSymbolsStyle::Makerom => format!("_{}ClassVramStart", name),
}
}

pub fn vram_class_end(&self, name: &str) -> String {
match self {
LinkerSymbolsStyle::Splat => format!("{}_CLASS_VRAM_END", name),
LinkerSymbolsStyle::Makerom => format!("_{}ClassVramEnd", name),
}
}
}
38 changes: 37 additions & 1 deletion slinky/src/linker_writer.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* SPDX-FileCopyrightText: © 2024 decompals */
/* SPDX-License-Identifier: MIT */

use std::collections::HashMap;
use std::path::PathBuf;
use std::{io::Write, path::Path};

use crate::{file_kind::FileKind, SlinkyError};
use crate::{utils, Document};
use crate::{utils, Document, VramClass};
use crate::{FileInfo, Segment};

use crate::script_buffer::ScriptBuffer;
Expand All @@ -18,6 +19,9 @@ pub struct LinkerWriter<'a> {

single_segment: bool,

vram_classes: HashMap<String, VramClass>,

/* Options to control stuff */
emit_sections_kind_symbols: bool,
emit_section_symbols: bool,

Expand All @@ -26,13 +30,20 @@ pub struct LinkerWriter<'a> {

impl<'a> LinkerWriter<'a> {
pub fn new(d: &'a Document) -> Self {
let mut vram_classes = HashMap::with_capacity(d.vram_classes.len());
for vram_class in &d.vram_classes {
vram_classes.insert(vram_class.name.clone(), vram_class.clone());
}

Self {
buffer: ScriptBuffer::new(),

files_paths: indexmap::IndexSet::new(),

single_segment: false,

vram_classes,

emit_sections_kind_symbols: true,
emit_section_symbols: true,

Expand Down Expand Up @@ -144,6 +155,29 @@ impl<'a> LinkerWriter<'a> {
let main_seg_sym_end: String = style.segment_vram_end(&segment.name);
let main_seg_sym_size: String = style.segment_vram_size(&segment.name);

if let Some(vram_class_name) = &segment.vram_class {
// TODO: return Err if vram class is not present instead of unwrapping
let vram_class = self.vram_classes.get_mut(vram_class_name).unwrap();

if !vram_class.emitted {
let vram_class_sym = style.vram_class_start(vram_class_name);

if let Some(fixed_vram) = vram_class.fixed_vram {
self.buffer.write_symbol(&vram_class_sym, &format!("0x{:08X}", fixed_vram));
} else {
self.buffer.write_symbol(&vram_class_sym, "0x00000000");
for other_class_name in &vram_class.follows_classes {
self.buffer.write_symbol(&vram_class_sym, &format!("MAX({}, {})", vram_class_sym, style.vram_class_end(other_class_name)));
}
}

self.buffer.write_empty_line();

// This is dumb, but Rust complains if you mut-borrow this above and call any other self.function.
vram_class.emitted = true;
}
}

if let Some(segment_start_align) = segment.segment_start_align {
self.buffer.align_symbol("__romPos", segment_start_align);
self.buffer.align_symbol(".", segment_start_align);
Expand Down Expand Up @@ -497,6 +531,8 @@ impl LinkerWriter<'_> {
line += &format!(" 0x{:08X}", fixed_vram);
} else if let Some(follows_segment) = &segment.follows_segment {
line += &format!(" {}", style.segment_vram_end(follows_segment));
} else if let Some(vram_class) = &segment.vram_class {
line += &format!(" {}", style.vram_class_start(vram_class));
}

line += &format!(" : AT({})", style.segment_rom_start(&segment.name));
Expand Down
8 changes: 7 additions & 1 deletion slinky/src/vram_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ use serde::Deserialize;

use crate::{absent_nullable::AbsentNullable, Settings, SlinkyError};

#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
pub struct VramClass {
pub name: String,

pub fixed_vram: Option<u32>,

pub follows_classes: Vec<String>,

// Settings from below do not come from the document.

pub emitted: bool,
}

#[derive(Deserialize, PartialEq, Debug)]
Expand Down Expand Up @@ -60,6 +64,8 @@ impl VramClassSerial {
name,
fixed_vram,
follows_classes,

emitted: false,
})
}
}
40 changes: 29 additions & 11 deletions tests/partial_linking/vram_classes.ld
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ SECTIONS
boot_ROM_END = __romPos;
boot_ROM_SIZE = ABSOLUTE(boot_ROM_END - boot_ROM_START);

battle_partner_CLASS_VRAM_START = 0x80238000;

battle_partner_goompa_ROM_START = __romPos;
battle_partner_goompa_VRAM = ADDR(.battle_partner_goompa);
battle_partner_goompa_alloc_VRAM = .;

.battle_partner_goompa : AT(battle_partner_goompa_ROM_START) SUBALIGN(16)
.battle_partner_goompa battle_partner_CLASS_VRAM_START : AT(battle_partner_goompa_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
battle_partner_goompa_TEXT_START = .;
Expand Down Expand Up @@ -152,7 +154,7 @@ SECTIONS
battle_partner_goombario_VRAM = ADDR(.battle_partner_goombario);
battle_partner_goombario_alloc_VRAM = .;

.battle_partner_goombario : AT(battle_partner_goombario_ROM_START) SUBALIGN(16)
.battle_partner_goombario battle_partner_CLASS_VRAM_START : AT(battle_partner_goombario_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
battle_partner_goombario_TEXT_START = .;
Expand Down Expand Up @@ -225,7 +227,7 @@ SECTIONS
battle_partner_kooper_VRAM = ADDR(.battle_partner_kooper);
battle_partner_kooper_alloc_VRAM = .;

.battle_partner_kooper : AT(battle_partner_kooper_ROM_START) SUBALIGN(16)
.battle_partner_kooper battle_partner_CLASS_VRAM_START : AT(battle_partner_kooper_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
battle_partner_kooper_TEXT_START = .;
Expand Down Expand Up @@ -294,11 +296,14 @@ SECTIONS
battle_partner_kooper_ROM_END = __romPos;
battle_partner_kooper_ROM_SIZE = ABSOLUTE(battle_partner_kooper_ROM_END - battle_partner_kooper_ROM_START);

battle_code_CLASS_VRAM_START = 0x00000000;
battle_code_CLASS_VRAM_START = MAX(battle_code_CLASS_VRAM_START, battle_partner_CLASS_VRAM_END);

battle_code_ROM_START = __romPos;
battle_code_VRAM = ADDR(.battle_code);
battle_code_alloc_VRAM = .;

.battle_code : AT(battle_code_ROM_START) SUBALIGN(16)
.battle_code battle_code_CLASS_VRAM_START : AT(battle_code_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
battle_code_TEXT_START = .;
Expand Down Expand Up @@ -367,11 +372,13 @@ SECTIONS
battle_code_ROM_END = __romPos;
battle_code_ROM_SIZE = ABSOLUTE(battle_code_ROM_END - battle_code_ROM_START);

heaps2_CLASS_VRAM_START = 0x80267FF0;

heaps2_ROM_START = __romPos;
heaps2_VRAM = ADDR(.heaps2);
heaps2_alloc_VRAM = .;

.heaps2 : AT(heaps2_ROM_START) SUBALIGN(16)
.heaps2 heaps2_CLASS_VRAM_START : AT(heaps2_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
heaps2_TEXT_START = .;
Expand Down Expand Up @@ -440,11 +447,14 @@ SECTIONS
heaps2_ROM_END = __romPos;
heaps2_ROM_SIZE = ABSOLUTE(heaps2_ROM_END - heaps2_ROM_START);

world_script_api_CLASS_VRAM_START = 0x00000000;
world_script_api_CLASS_VRAM_START = MAX(world_script_api_CLASS_VRAM_START, heaps2_CLASS_VRAM_END);

world_script_api_ROM_START = __romPos;
world_script_api_VRAM = ADDR(.world_script_api);
world_script_api_alloc_VRAM = .;

.world_script_api : AT(world_script_api_ROM_START) SUBALIGN(16)
.world_script_api world_script_api_CLASS_VRAM_START : AT(world_script_api_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
world_script_api_TEXT_START = .;
Expand Down Expand Up @@ -513,11 +523,15 @@ SECTIONS
world_script_api_ROM_END = __romPos;
world_script_api_ROM_SIZE = ABSOLUTE(world_script_api_ROM_END - world_script_api_ROM_START);

texture_memory_CLASS_VRAM_START = 0x00000000;
texture_memory_CLASS_VRAM_START = MAX(texture_memory_CLASS_VRAM_START, battle_code_CLASS_VRAM_END);
texture_memory_CLASS_VRAM_START = MAX(texture_memory_CLASS_VRAM_START, world_script_api_CLASS_VRAM_END);

texture_memory_ROM_START = __romPos;
texture_memory_VRAM = ADDR(.texture_memory);
texture_memory_alloc_VRAM = .;

.texture_memory : AT(texture_memory_ROM_START) SUBALIGN(16)
.texture_memory texture_memory_CLASS_VRAM_START : AT(texture_memory_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
texture_memory_TEXT_START = .;
Expand Down Expand Up @@ -586,11 +600,13 @@ SECTIONS
texture_memory_ROM_END = __romPos;
texture_memory_ROM_SIZE = ABSOLUTE(texture_memory_ROM_END - texture_memory_ROM_START);

segment_05_CLASS_VRAM_START = 0x05000000;

assets1_ROM_START = __romPos;
assets1_VRAM = ADDR(.assets1);
assets1_alloc_VRAM = .;

.assets1 : AT(assets1_ROM_START) SUBALIGN(16)
.assets1 segment_05_CLASS_VRAM_START : AT(assets1_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
assets1_TEXT_START = .;
Expand Down Expand Up @@ -663,7 +679,7 @@ SECTIONS
assets2_VRAM = ADDR(.assets2);
assets2_alloc_VRAM = .;

.assets2 : AT(assets2_ROM_START) SUBALIGN(16)
.assets2 segment_05_CLASS_VRAM_START : AT(assets2_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
assets2_TEXT_START = .;
Expand Down Expand Up @@ -736,7 +752,7 @@ SECTIONS
assets3_VRAM = ADDR(.assets3);
assets3_alloc_VRAM = .;

.assets3 : AT(assets3_ROM_START) SUBALIGN(16)
.assets3 segment_05_CLASS_VRAM_START : AT(assets3_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
assets3_TEXT_START = .;
Expand Down Expand Up @@ -805,11 +821,13 @@ SECTIONS
assets3_ROM_END = __romPos;
assets3_ROM_SIZE = ABSOLUTE(assets3_ROM_END - assets3_ROM_START);

segment_06_CLASS_VRAM_START = 0x06000000;

assets4_ROM_START = __romPos;
assets4_VRAM = ADDR(.assets4);
assets4_alloc_VRAM = .;

.assets4 : AT(assets4_ROM_START) SUBALIGN(16)
.assets4 segment_06_CLASS_VRAM_START : AT(assets4_ROM_START) SUBALIGN(16)
{
FILL(0x00000000);
assets4_TEXT_START = .;
Expand Down
Loading

0 comments on commit ddec464

Please sign in to comment.