Compare commits

...

4 Commits

Author SHA1 Message Date
c8e84be5d2 common.lds: define vbr alignment
This also creates an example of a VBR+0x100 function in interrupt.cpp
2024-04-15 18:22:28 +08:00
c1e3e9d074 start.s: rename p1ram_end_ptr to stack_end_ptr 2024-04-15 18:20:25 +08:00
5e54666822 runtime_init: call cache::init before copying
It is unclear why this reordering is useful--it should be the case
that the previous content of the cache is invalidated on write
regardless of when cache::init is called.
2024-04-15 18:17:32 +08:00
bd33fbf2e4 example/font_bitmap: remove unintentional padding between characters
At 4bpp, each 8×8px character only requires (8 * 8 / 2) bytes of
texture ram.
2024-04-15 18:16:13 +08:00
9 changed files with 140 additions and 14 deletions

View File

@ -41,6 +41,15 @@ SECTIONS
*(COMMON)
} > p1ram
.text.vbr ALIGN(4) : SUBALIGN(4)
{
KEEP(*(.vbr.100))
. = ALIGN(0x300);
KEEP(*(.vbr.400))
. = ALIGN(0x200);
KEEP(*(.vbr.600))
} > p1ram
INCLUDE "debug.lds"
}

View File

@ -329,6 +329,7 @@ example/serial_transfer.elf: $(START_OBJ) $(SERIAL_TRANSFER_OBJ)
INTERRUPT_OBJ = \
example/interrupt.o \
example/illslot.o \
sh7091/serial.o
example/interrupt.elf: LDSCRIPT = $(LIB)/alt.lds

View File

@ -110,10 +110,11 @@ uint32_t transform(uint32_t * ta_parameter_buf, const char * s, const uint32_t l
| tsp_instruction_word::texture_u_size::from_int(8)
| tsp_instruction_word::texture_v_size::from_int(8);
const uint32_t character_offset = ((8 * 8) / 2) * (s[string_ix] - ' ');
const uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture));
const uint32_t texture_control_word = texture_control_word::pixel_format::_4bpp_palette
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address((texture_address + 8 * 8 * (s[string_ix] - ' ')) / 8);
| texture_control_word::texture_address((texture_address + character_offset) / 8);
parameter.append<ta_global_parameter::polygon_type_0>() =
ta_global_parameter::polygon_type_0(parameter_control_word,
@ -131,9 +132,9 @@ uint32_t transform(uint32_t * ta_parameter_buf, const char * s, const uint32_t l
float y = strip_vertices[i].y;
float z = strip_vertices[i].z;
x *= 32.f;
y *= 32.f;
x += 64.f + 32 * string_ix;
x *= 8.f;
y *= 8.f;
x += 64.f + 8 * string_ix;
y += 240.f;
z = 1.f / (z + 10.f);
@ -189,7 +190,7 @@ inline void inflate_character(const uint8_t * src, const uint8_t c)
auto mem = reinterpret_cast<volatile texture_memory_alloc *>(texture_memory64);
auto texture = reinterpret_cast<volatile uint32_t *>(mem->texture);
uint32_t offset = 8 * 8 * character_index;
uint32_t offset = ((8 * 8) / 2) * character_index;
/*
union {

6
example/illslot.s Normal file
View File

@ -0,0 +1,6 @@
.global _illslot
_illslot:
rts
mova test,r0
test: .long 0x12345678

View File

@ -4,14 +4,103 @@
#include "sh7091/sh7091.hpp"
#include "sh7091/sh7091_bits.hpp"
#include "sh7091/vbr.hpp"
#include "systembus.hpp"
void vbr100()
{
serial::string("vbr100\n");
serial::string("expevt ");
serial::integer(sh7091.CCN.EXPEVT);
serial::string("intevt ");
serial::integer(sh7091.CCN.INTEVT);
uint32_t spc;
uint32_t ssr;
asm volatile ("stc spc,%0"
: "=r" (spc)
);
asm volatile ("stc ssr,%0"
: "=r" (ssr)
);
serial::string("spc ");
serial::integer(spc);
serial::string("ssr ");
serial::integer(ssr);
while (1);
}
void vbr400()
{
serial::string("vbr400");
while (1);
}
void vbr600()
{
serial::string("vbr600");
while (1);
}
extern "C" uint32_t * illslot(void);
void main()
{
uint32_t vbr;
uint32_t vbr = reinterpret_cast<uint32_t>(&__vbr_link_start) - 0x100;
asm ("stc vbr,%0" : "=r" (vbr));
system.IML2NRM = 0;
system.IML2ERR = 0;
system.IML2EXT = 0;
system.IML4NRM = 0;
system.IML4ERR = 0;
system.IML4EXT = 0;
system.IML6NRM = 0;
system.IML6ERR = 0;
system.IML6EXT = 0;
sh7091.CCN.INTEVT = 0;
sh7091.CCN.EXPEVT = 0;
uint32_t zero = 0;
asm volatile ("ldc %0,spc"
:
: "r" (zero));
asm volatile ("ldc %0,ssr"
:
: "r" (zero));
asm volatile ("ldc %0,vbr"
:
: "r" (vbr));
uint32_t sr;
asm volatile ("stc sr,%0"
: "=r" (sr));
serial::string("sr ");
serial::integer<uint32_t>(sr);
sr = sr & (~(1 << 28)); // BL
asm volatile ("ldc %0, sr"
:
: "r" (sr));
/*
uint32_t vbr2;
asm volatile ("stc vbr,%0"
: "=r" (vbr2));
*/
serial::integer<uint32_t>(vbr);
//serial::integer<uint32_t>(vbr2);
serial::integer<uint32_t>(reinterpret_cast<uint32_t>(&vbr100));
uint32_t * test = illslot();
serial::integer<uint32_t>(*test);
while (1);
}

View File

@ -46,6 +46,8 @@ void copy(uint32_t * start, const uint32_t * end, uint32_t * load)
extern "C"
void runtime_init()
{
cache::init();
// relocate text (if necessary)
copy(&__text_link_start, &__text_link_end, &__text_load_start);
@ -71,6 +73,4 @@ void runtime_init()
while (start < end) {
((init_t*)(*start++))();
}
cache::init();
}

17
sh7091/vbr.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
__attribute__((section(".vbr.100")))
__attribute__((interrupt_handler))
void vbr100();
__attribute__((section(".vbr.400")))
__attribute__((interrupt_handler))
void vbr400();
__attribute__((section(".vbr.600")))
__attribute__((interrupt_handler))
void vbr600();
extern uint32_t __vbr_link_start __asm("__vbr_link_start");

View File

@ -2,7 +2,7 @@
.global _start
_start:
/* set stack pointer */
mov.l p1ram_end_ptr,r15
mov.l stack_end_ptr,r15
/* mask all interrupts */
mov.l imask_all,r0
@ -27,8 +27,8 @@ _start:
nop
.align 4
p1ram_end_ptr:
.long __p1ram_end
stack_end_ptr:
.long __stack_end
imask_all:
.long 0xf0
runtime_init_ptr:

View File

@ -1,6 +1,5 @@
__p1ram_start = ORIGIN(p1ram);
/* reserve bytes for serial program loader */
__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram) - __stack_reservation;
__stack_end = ORIGIN(p1ram) + LENGTH(p1ram) - __stack_reservation;
__text_link_start = ADDR(.text);
__text_link_end = ADDR(.text) + SIZEOF(.text);
@ -19,3 +18,7 @@ __ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors);
__bss_link_start = ADDR(.bss);
__bss_link_end = ADDR(.bss) + SIZEOF(.bss);
__vbr_link_start = ADDR(.text.vbr);
__vbr_link_end = ADDR(.text.vbr) + SIZEOF(.text.vbr);
__vbr_load_end = LOADADDR(.text.vbr);