maple: send a 'device request' command
On an emulator, the receive buffer is filled with the correct/expected data for 'device status'. I found this experiment useful: - it revealed a bug in my register struct generator code (the maple_if-related registers were not at the correct offsets) - it validates my understanding about endianness-swapping between the maple bus and the SH4
This commit is contained in:
parent
3f30c96dcd
commit
f1a32d0719
27
Makefile
27
Makefile
@ -1 +1,28 @@
|
||||
all: main.elf
|
||||
|
||||
include common.mk
|
||||
|
||||
MAIN_OBJ = \
|
||||
start.o \
|
||||
main.o \
|
||||
load.o \
|
||||
cache.o \
|
||||
vga.o \
|
||||
rgb.o \
|
||||
holly/background.o \
|
||||
holly/region_array.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
holly/core.o \
|
||||
maple.o \
|
||||
scene.o \
|
||||
macaw.data.o \
|
||||
$(LIBGCC)
|
||||
|
||||
serial.elf: start.o serial_main.o load.o cache.o
|
||||
$(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@
|
||||
|
||||
main.elf: $(MAIN_OBJ)
|
||||
$(LD) $(LDFLAGS) -T $(LIB)/main.lds $^ -o $@
|
||||
|
||||
test.elf: $(MAIN_OBJ)
|
||||
$(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@
|
||||
|
33
common.mk
33
common.mk
@ -7,13 +7,14 @@ AARCH = --isa=sh4 --little
|
||||
AFLAGS = --fatal-warnings
|
||||
|
||||
CARCH = -m4-single-only -ml
|
||||
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib -Wno-error=narrowing
|
||||
CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable
|
||||
CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib
|
||||
CFLAGS += -Wall -Werror -Wfatal-errors
|
||||
CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable
|
||||
CFLAGS += -mfsca -funsafe-math-optimizations
|
||||
DEPFLAGS = -MMD -E
|
||||
# --print-gc-sections
|
||||
LDFLAGS = --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error
|
||||
CXXFLAGS = -std=c++20 -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics
|
||||
CXXFLAGS = -std=c++23 -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics
|
||||
|
||||
TARGET = sh4-none-elf-
|
||||
CC = $(TARGET)gcc
|
||||
@ -47,23 +48,6 @@ IP_OBJ = \
|
||||
sg/sg_ini.o \
|
||||
sg/aip.o
|
||||
|
||||
MAIN_OBJ = \
|
||||
start.o \
|
||||
main.o \
|
||||
load.o \
|
||||
cache.o \
|
||||
vga.o \
|
||||
rgb.o \
|
||||
holly/background.o \
|
||||
holly/region_array.o \
|
||||
holly/ta_fifo_polygon_converter.o \
|
||||
holly/core.o \
|
||||
scene.o \
|
||||
macaw.data.o \
|
||||
$(LIBGCC)
|
||||
|
||||
all: main.cdi
|
||||
|
||||
%.bin.o: %.bin
|
||||
$(BUILD_BINARY_O)
|
||||
|
||||
@ -87,15 +71,6 @@ all: main.cdi
|
||||
%.o: %.cpp %.cpp.d
|
||||
$(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) -c $< -o $@
|
||||
|
||||
serial.elf: start.o serial_main.o load.o cache.o
|
||||
$(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@
|
||||
|
||||
main.elf: $(MAIN_OBJ)
|
||||
$(LD) $(LDFLAGS) -T $(LIB)/main.lds $^ -o $@
|
||||
|
||||
test.elf: $(MAIN_OBJ)
|
||||
$(LD) $(LDFLAGS) -T $(LIB)/alt.lds $^ -o $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
|
31
main.cpp
31
main.cpp
@ -9,6 +9,8 @@
|
||||
#include "holly/core_bits.h"
|
||||
#include "holly/ta_fifo_polygon_converter.h"
|
||||
#include "systembus.h"
|
||||
#include "maple.h"
|
||||
#include "maple_bits.h"
|
||||
|
||||
#include "holly/texture_memory_alloc.h"
|
||||
|
||||
@ -16,6 +18,7 @@
|
||||
#include "load.h"
|
||||
#include "vga.h"
|
||||
#include "rgb.h"
|
||||
#include "string.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include "macaw.h"
|
||||
@ -64,6 +67,32 @@ uint32_t * align_32byte(uint32_t * mem)
|
||||
return reinterpret_cast<uint32_t *>(((reinterpret_cast<uint32_t>(_scene) + 31) & ~31));
|
||||
}
|
||||
|
||||
void serial_int(const uint32_t n)
|
||||
{
|
||||
char num_buf[9];
|
||||
string::hex<char>(num_buf, 8, n);
|
||||
num_buf[8] = 0;
|
||||
serial_string("0x");
|
||||
serial_string(num_buf);
|
||||
serial_string("\n");
|
||||
}
|
||||
|
||||
void maple_test()
|
||||
{
|
||||
uint32_t _command_buf[(32 + 32) / 4];
|
||||
uint32_t _receive_address[(32 + 32) / 4];
|
||||
uint32_t * command_buf = align_32byte(_command_buf);
|
||||
uint32_t * receive_address = align_32byte(_receive_address);
|
||||
|
||||
serial_int(mdstar::table_address(reinterpret_cast<uint32_t>(command_buf)));
|
||||
maple_init_host_command(command_buf, receive_address);
|
||||
maple_dma_start(command_buf);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
serial_int(receive_address[i]);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void main()
|
||||
{
|
||||
@ -82,6 +111,8 @@ void main()
|
||||
|
||||
v_sync_in();
|
||||
|
||||
maple_test();
|
||||
|
||||
volatile uint16_t * framebuffer = reinterpret_cast<volatile uint16_t *>(&texture_memory[0]);
|
||||
for (int y = 0; y < 480; y++) {
|
||||
for (int x = 0; x < 640; x++) {
|
||||
|
42
maple.cpp
42
maple.cpp
@ -1,11 +1,22 @@
|
||||
#include <cstdint>
|
||||
#include <bit>
|
||||
|
||||
#include "sh7091.h"
|
||||
#include "sh7091_bits.h"
|
||||
#include "systembus.h"
|
||||
#include "systembus_bits.h"
|
||||
#include "maple_bits.h"
|
||||
|
||||
#include "maple.h"
|
||||
|
||||
#define AP__PO__A (0b00 << 6)
|
||||
#define AP__PO__B (0b01 << 6)
|
||||
#define AP__PO__C (0b10 << 6)
|
||||
#define AP__PO__D (0b11 << 6)
|
||||
|
||||
#define AP__DE__DEVICE = (1 << 5)
|
||||
#define AP__DE__EXPANSION_DEVICE = (0 << 5)
|
||||
#define AP__DE__PORT = (0 << 5)
|
||||
#define AP__DE__DEVICE (1 << 5)
|
||||
#define AP__DE__EXPANSION_DEVICE (0 << 5)
|
||||
#define AP__DE__PORT (0 << 5)
|
||||
|
||||
#define AP__LM(reg) ((reg) & 0b11111)
|
||||
|
||||
@ -26,9 +37,9 @@ struct maple_host_command {
|
||||
uint32_t protocol_data[N];
|
||||
};
|
||||
|
||||
void maple_host_command(uint32_t * buf, uint32_t * receive_address)
|
||||
void maple_init_host_command(uint32_t * buf, uint32_t * receive_address)
|
||||
{
|
||||
auto command = reinterpet_cast<maple_host_command<1> *>(buf);
|
||||
auto command = reinterpret_cast<maple_host_command<1> *>(buf);
|
||||
|
||||
command->host_instruction = HOST_INSTRUCTION__END_FLAG
|
||||
| HOST_INSTRUCTION__PORT_SELECT__A
|
||||
@ -40,10 +51,11 @@ void maple_host_command(uint32_t * buf, uint32_t * receive_address)
|
||||
uint32_t destination_ap = AP__DE__DEVICE | AP__PO__A;
|
||||
uint32_t source_ap = AP__PO__A;
|
||||
uint32_t data_size = 0;
|
||||
command->protocol_data[0] = (command_code << 24)
|
||||
// maple bus is big endian
|
||||
command->protocol_data[0] = std::byteswap( (command_code << 24)
|
||||
| (destination_ap << 16)
|
||||
| (source_ap << 8)
|
||||
| (data_size << 0);
|
||||
| (data_size << 0));
|
||||
}
|
||||
|
||||
void maple_dma_start(uint32_t * command_buf)
|
||||
@ -56,28 +68,28 @@ void maple_dma_start(uint32_t * command_buf)
|
||||
system.ISTNRM = ISTNRM__END_OF_DMA_MAPLE_DMA;
|
||||
|
||||
// disable maple-DMA
|
||||
system.MDEN = mden::dma_enable::abort;
|
||||
maple_if.MDEN = mden::dma_enable::abort;
|
||||
|
||||
volatile uint32_t _dummy = system.MDST;
|
||||
volatile uint32_t _dummy = maple_if.MDST;
|
||||
(void)_dummy;
|
||||
|
||||
// 20nsec * 0xc350 = 1ms
|
||||
constexpr uint32_t one_msec = 0xc350;
|
||||
system.MSYS = msys::time_out_counter(one_msec)
|
||||
maple_if.MSYS = msys::time_out_counter(one_msec)
|
||||
| msys::sending_rate::_2M;
|
||||
|
||||
system.MDTSEL = mdtsel::trigger_select::software_initiation;
|
||||
maple_if.MDTSEL = mdtsel::trigger_select::software_initiation;
|
||||
|
||||
/* top address: the first/lowest address
|
||||
bottom address: the last/highest address */
|
||||
system.MDAPRO = mdapro::security_code
|
||||
maple_if.MDAPRO = mdapro::security_code
|
||||
| mdapro::top_address(0x00)
|
||||
| mdapro::bottom_address(0x7f);
|
||||
|
||||
system.MDSTAR = mdstar::table_address(command_buf);
|
||||
maple_if.MDSTAR = mdstar::table_address(reinterpret_cast<uint32_t>(command_buf));
|
||||
|
||||
system.MDEN = mden::dma_enable::enable;
|
||||
system.MDST = mdst::start_status::start;
|
||||
maple_if.MDEN = mden::dma_enable::enable;
|
||||
maple_if.MDST = mdst::start_status::start;
|
||||
|
||||
// wait for completion
|
||||
while ((system.ISTNRM & ISTNRM__END_OF_DMA_MAPLE_DMA) == 0);
|
||||
|
80
maple.h
80
maple.h
@ -1,78 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "float_uint32.h"
|
||||
|
||||
namespace mdstar {
|
||||
constexpr uint32_t table_address(uint32_t num) { return (num & 0xfffffe0) << 0; }
|
||||
}
|
||||
|
||||
namespace mdtsel {
|
||||
namespace trigger_select {
|
||||
constexpr uint32_t software_initiation = 0 << 0;
|
||||
constexpr uint32_t v_blank_initiation = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mden {
|
||||
namespace dma_enable {
|
||||
constexpr uint32_t abort = 0 << 0;
|
||||
constexpr uint32_t enable = 1 << 0;
|
||||
constexpr uint32_t status(uint32_t reg) { return (reg >> 0) & 0x1; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace mdst {
|
||||
namespace start_status {
|
||||
constexpr uint32_t status(uint32_t reg) { return (reg >> 0) & 0x1; }
|
||||
constexpr uint32_t start = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace msys {
|
||||
constexpr uint32_t time_out_counter(uint32_t num) { return (num & 0xffff) << 16; }
|
||||
constexpr uint32_t single_hard_trigger = 1 << 12;
|
||||
|
||||
namespace sending_rate {
|
||||
constexpr uint32_t _2M = 0 << 8;
|
||||
constexpr uint32_t _1M = 1 << 8;
|
||||
}
|
||||
|
||||
constexpr uint32_t delay_time(uint32_t num) { return (num & 0xf) << 0; }
|
||||
}
|
||||
|
||||
namespace mst {
|
||||
constexpr uint32_t move_status(uint32_t reg) { return (reg >> 31) & 0x1; }
|
||||
constexpr uint32_t internal_frame_monitor(uint32_t reg) { return (reg >> 24) & 0x7; }
|
||||
constexpr uint32_t internal_state_monitor(uint32_t reg) { return (reg >> 16) & 0x3f; }
|
||||
constexpr uint32_t line_monitor(uint32_t reg) { return (reg >> 0) & 0xff; }
|
||||
}
|
||||
|
||||
namespace mshtcl {
|
||||
constexpr uint32_t hard_dma_clear = 1 << 0;
|
||||
}
|
||||
|
||||
namespace mdapro {
|
||||
constexpr uint32_t security_code = 0x6155 << 16;
|
||||
constexpr uint32_t top_address(uint32_t num) { return (num & 0x7f) << 8; }
|
||||
constexpr uint32_t bottom_address(uint32_t num) { return (num & 0x7f) << 0; }
|
||||
}
|
||||
|
||||
namespace mmsel {
|
||||
namespace msb_selection {
|
||||
constexpr uint32_t bit7 = 0 << 0;
|
||||
constexpr uint32_t bit31 = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mtxdad {
|
||||
constexpr uint32_t txd_address_counter(uint32_t reg) { return (reg >> 0) & 0x1fffffff; }
|
||||
}
|
||||
|
||||
namespace mrxdad {
|
||||
constexpr uint32_t rxd_address_counter(uint32_t reg) { return (reg >> 0) & 0x1fffffff; }
|
||||
}
|
||||
|
||||
namespace mrxdbd {
|
||||
constexpr uint32_t rxd_base_address(uint32_t reg) { return (reg >> 0) & 0x1fffffff; }
|
||||
}
|
||||
|
||||
void maple_init_host_command(uint32_t * buf, uint32_t * receive_address);
|
||||
void maple_dma_start(uint32_t * command_buf);
|
||||
|
78
maple_bits.h
Normal file
78
maple_bits.h
Normal file
@ -0,0 +1,78 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "holly/float_uint32.h"
|
||||
|
||||
namespace mdstar {
|
||||
constexpr uint32_t table_address(uint32_t num) { return (num & 0xfffffe0) << 0; }
|
||||
}
|
||||
|
||||
namespace mdtsel {
|
||||
namespace trigger_select {
|
||||
constexpr uint32_t software_initiation = 0 << 0;
|
||||
constexpr uint32_t v_blank_initiation = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mden {
|
||||
namespace dma_enable {
|
||||
constexpr uint32_t abort = 0 << 0;
|
||||
constexpr uint32_t enable = 1 << 0;
|
||||
constexpr uint32_t status(uint32_t reg) { return (reg >> 0) & 0x1; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace mdst {
|
||||
namespace start_status {
|
||||
constexpr uint32_t status(uint32_t reg) { return (reg >> 0) & 0x1; }
|
||||
constexpr uint32_t start = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace msys {
|
||||
constexpr uint32_t time_out_counter(uint32_t num) { return (num & 0xffff) << 16; }
|
||||
constexpr uint32_t single_hard_trigger = 1 << 12;
|
||||
|
||||
namespace sending_rate {
|
||||
constexpr uint32_t _2M = 0 << 8;
|
||||
constexpr uint32_t _1M = 1 << 8;
|
||||
}
|
||||
|
||||
constexpr uint32_t delay_time(uint32_t num) { return (num & 0xf) << 0; }
|
||||
}
|
||||
|
||||
namespace mst {
|
||||
constexpr uint32_t move_status(uint32_t reg) { return (reg >> 31) & 0x1; }
|
||||
constexpr uint32_t internal_frame_monitor(uint32_t reg) { return (reg >> 24) & 0x7; }
|
||||
constexpr uint32_t internal_state_monitor(uint32_t reg) { return (reg >> 16) & 0x3f; }
|
||||
constexpr uint32_t line_monitor(uint32_t reg) { return (reg >> 0) & 0xff; }
|
||||
}
|
||||
|
||||
namespace mshtcl {
|
||||
constexpr uint32_t hard_dma_clear = 1 << 0;
|
||||
}
|
||||
|
||||
namespace mdapro {
|
||||
constexpr uint32_t security_code = 0x6155 << 16;
|
||||
constexpr uint32_t top_address(uint32_t num) { return (num & 0x7f) << 8; }
|
||||
constexpr uint32_t bottom_address(uint32_t num) { return (num & 0x7f) << 0; }
|
||||
}
|
||||
|
||||
namespace mmsel {
|
||||
namespace msb_selection {
|
||||
constexpr uint32_t bit7 = 0 << 0;
|
||||
constexpr uint32_t bit31 = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mtxdad {
|
||||
constexpr uint32_t txd_address_counter(uint32_t reg) { return (reg >> 0) & 0x1fffffff; }
|
||||
}
|
||||
|
||||
namespace mrxdad {
|
||||
constexpr uint32_t rxd_address_counter(uint32_t reg) { return (reg >> 0) & 0x1fffffff; }
|
||||
}
|
||||
|
||||
namespace mrxdbd {
|
||||
constexpr uint32_t rxd_base_address(uint32_t reg) { return (reg >> 0) & 0x1fffffff; }
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ def should_autonewline(line):
|
||||
return (
|
||||
"static_assert" not in line
|
||||
and "extern" not in line
|
||||
and line.split()[1] != '=' # hacky; meh
|
||||
and (len(line.split()) < 2 or line.split()[1] != '=') # hacky; meh
|
||||
)
|
||||
|
||||
def _render(out, lines):
|
||||
|
@ -51,8 +51,7 @@ def new_writer():
|
||||
if last_block is not None:
|
||||
yield "};"
|
||||
for address, name in stack:
|
||||
relative_address = address - first_address
|
||||
yield f"static_assert((offsetof (struct {last_block.lower()}_reg, {name})) == {hex(relative_address)});"
|
||||
yield f"static_assert((offsetof (struct {last_block.lower()}_reg, {name})) == {hex(address)});"
|
||||
yield ""
|
||||
stack = []
|
||||
|
||||
@ -76,8 +75,8 @@ def new_writer():
|
||||
|
||||
if block != last_block:
|
||||
yield from terminate()
|
||||
first_address = address
|
||||
last_address = address
|
||||
first_address = 0 # hmm...
|
||||
last_address = 0
|
||||
size_total = 0
|
||||
reserved_num = 0
|
||||
yield f"struct {block.lower()}_reg {{"
|
||||
|
@ -14,7 +14,7 @@ def blocks(rows):
|
||||
blocks.append(block)
|
||||
|
||||
for block in blocks:
|
||||
yield f'extern struct {block.lower()}_reg {block} __asm("{block}");'
|
||||
yield f'extern struct {block.lower()}_reg {block.lower()} __asm("{block.lower()}");'
|
||||
|
||||
input_file = sys.argv[1]
|
||||
rows = read_input(input_file)
|
||||
|
21
string.h
Normal file
21
string.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace string {
|
||||
template <typename T>
|
||||
inline void hex(T * c, uint32_t len, uint32_t n)
|
||||
{
|
||||
while (len > 0) {
|
||||
uint32_t nib = n & 0xf;
|
||||
n = n >> 4;
|
||||
if (nib > 9) {
|
||||
nib += (97 - 10);
|
||||
} else {
|
||||
nib += (48 - 0);
|
||||
}
|
||||
|
||||
c[--len] = nib;
|
||||
}
|
||||
}
|
||||
}
|
84
systembus.h
84
systembus.h
@ -88,81 +88,83 @@ static_assert((offsetof (struct system_reg, G2DTNRM)) == 0x150);
|
||||
static_assert((offsetof (struct system_reg, G2DTEXT)) == 0x154);
|
||||
|
||||
struct maple_if_reg {
|
||||
reg8 _pad0[4];
|
||||
reg32 MDSTAR; /* Maple-DMA command table address */
|
||||
reg8 _pad0[8];
|
||||
reg8 _pad1[8];
|
||||
reg32 MDTSEL; /* Maple-DMA trigger select */
|
||||
reg32 MDEN; /* Maple-DMA enable */
|
||||
reg32 MDST; /* Maple-DMA start */
|
||||
reg8 _pad1[100];
|
||||
reg8 _pad2[100];
|
||||
reg32 MSYS; /* Maple system control */
|
||||
reg32 MST; /* Maple status */
|
||||
reg32 MSHTCL; /* Maple-DMA hard trigger clear */
|
||||
reg32 MDAPRO; /* Maple-DMA address range */
|
||||
reg8 _pad2[88];
|
||||
reg8 _pad3[88];
|
||||
reg32 MMSEL; /* Maple MSP selection */
|
||||
reg8 _pad3[8];
|
||||
reg8 _pad4[8];
|
||||
reg32 MTXDAD; /* Maple TXD address counter */
|
||||
reg32 MRXDAD; /* Maple RXD address counter */
|
||||
reg32 MRXDBD; /* Maple RXD address base */
|
||||
};
|
||||
|
||||
static_assert((offsetof (struct maple_if_reg, MDSTAR)) == 0x0);
|
||||
static_assert((offsetof (struct maple_if_reg, MDTSEL)) == 0xc);
|
||||
static_assert((offsetof (struct maple_if_reg, MDEN)) == 0x10);
|
||||
static_assert((offsetof (struct maple_if_reg, MDST)) == 0x14);
|
||||
static_assert((offsetof (struct maple_if_reg, MSYS)) == 0x7c);
|
||||
static_assert((offsetof (struct maple_if_reg, MST)) == 0x80);
|
||||
static_assert((offsetof (struct maple_if_reg, MSHTCL)) == 0x84);
|
||||
static_assert((offsetof (struct maple_if_reg, MDAPRO)) == 0x88);
|
||||
static_assert((offsetof (struct maple_if_reg, MMSEL)) == 0xe4);
|
||||
static_assert((offsetof (struct maple_if_reg, MTXDAD)) == 0xf0);
|
||||
static_assert((offsetof (struct maple_if_reg, MRXDAD)) == 0xf4);
|
||||
static_assert((offsetof (struct maple_if_reg, MRXDBD)) == 0xf8);
|
||||
static_assert((offsetof (struct maple_if_reg, MDSTAR)) == 0x4);
|
||||
static_assert((offsetof (struct maple_if_reg, MDTSEL)) == 0x10);
|
||||
static_assert((offsetof (struct maple_if_reg, MDEN)) == 0x14);
|
||||
static_assert((offsetof (struct maple_if_reg, MDST)) == 0x18);
|
||||
static_assert((offsetof (struct maple_if_reg, MSYS)) == 0x80);
|
||||
static_assert((offsetof (struct maple_if_reg, MST)) == 0x84);
|
||||
static_assert((offsetof (struct maple_if_reg, MSHTCL)) == 0x88);
|
||||
static_assert((offsetof (struct maple_if_reg, MDAPRO)) == 0x8c);
|
||||
static_assert((offsetof (struct maple_if_reg, MMSEL)) == 0xe8);
|
||||
static_assert((offsetof (struct maple_if_reg, MTXDAD)) == 0xf4);
|
||||
static_assert((offsetof (struct maple_if_reg, MRXDAD)) == 0xf8);
|
||||
static_assert((offsetof (struct maple_if_reg, MRXDBD)) == 0xfc);
|
||||
|
||||
struct g1_if_reg {
|
||||
reg8 _pad0[4];
|
||||
reg32 GDSTAR; /* GD-DMA start address */
|
||||
reg32 GDLEN; /* GD-DMA length */
|
||||
reg32 GDDIR; /* GD-DMA direction */
|
||||
reg8 _pad0[4];
|
||||
reg8 _pad1[4];
|
||||
reg32 GDEN; /* GD-DMA enable */
|
||||
reg32 GDST; /* GD-DMA start */
|
||||
reg8 _pad1[100];
|
||||
reg8 _pad2[100];
|
||||
reg32 G1RRC; /* System ROM read access timing */
|
||||
reg32 G1RWC; /* System ROM write access timing */
|
||||
reg32 G1FRC; /* Flash ROM read access timing */
|
||||
reg32 G1FWC; /* Flash ROM write access timing */
|
||||
reg32 G1CRC; /* GD PIO read access timing */
|
||||
reg32 G1CWC; /* GD PIO write access timing */
|
||||
reg8 _pad2[8];
|
||||
reg8 _pad3[8];
|
||||
reg32 G1GDRC; /* GD-DMA read access timing */
|
||||
reg32 G1GDWC; /* GD-DMA write access timing */
|
||||
reg8 _pad3[8];
|
||||
reg8 _pad4[8];
|
||||
reg32 G1SYSM; /* System mode */
|
||||
reg32 G1CRDYC; /* G1IORDY signal control */
|
||||
reg32 GDAPRO; /* GD-DMA address range */
|
||||
reg8 _pad4[56];
|
||||
reg8 _pad5[56];
|
||||
reg32 GDSTARD; /* GD-DMA address count (on Root Bus) */
|
||||
reg32 GDLEND; /* GD-DMA transfer counter */
|
||||
};
|
||||
|
||||
static_assert((offsetof (struct g1_if_reg, GDSTAR)) == 0x0);
|
||||
static_assert((offsetof (struct g1_if_reg, GDLEN)) == 0x4);
|
||||
static_assert((offsetof (struct g1_if_reg, GDDIR)) == 0x8);
|
||||
static_assert((offsetof (struct g1_if_reg, GDEN)) == 0x10);
|
||||
static_assert((offsetof (struct g1_if_reg, GDST)) == 0x14);
|
||||
static_assert((offsetof (struct g1_if_reg, G1RRC)) == 0x7c);
|
||||
static_assert((offsetof (struct g1_if_reg, G1RWC)) == 0x80);
|
||||
static_assert((offsetof (struct g1_if_reg, G1FRC)) == 0x84);
|
||||
static_assert((offsetof (struct g1_if_reg, G1FWC)) == 0x88);
|
||||
static_assert((offsetof (struct g1_if_reg, G1CRC)) == 0x8c);
|
||||
static_assert((offsetof (struct g1_if_reg, G1CWC)) == 0x90);
|
||||
static_assert((offsetof (struct g1_if_reg, G1GDRC)) == 0x9c);
|
||||
static_assert((offsetof (struct g1_if_reg, G1GDWC)) == 0xa0);
|
||||
static_assert((offsetof (struct g1_if_reg, G1SYSM)) == 0xac);
|
||||
static_assert((offsetof (struct g1_if_reg, G1CRDYC)) == 0xb0);
|
||||
static_assert((offsetof (struct g1_if_reg, GDAPRO)) == 0xb4);
|
||||
static_assert((offsetof (struct g1_if_reg, GDSTARD)) == 0xf0);
|
||||
static_assert((offsetof (struct g1_if_reg, GDLEND)) == 0xf4);
|
||||
static_assert((offsetof (struct g1_if_reg, GDSTAR)) == 0x4);
|
||||
static_assert((offsetof (struct g1_if_reg, GDLEN)) == 0x8);
|
||||
static_assert((offsetof (struct g1_if_reg, GDDIR)) == 0xc);
|
||||
static_assert((offsetof (struct g1_if_reg, GDEN)) == 0x14);
|
||||
static_assert((offsetof (struct g1_if_reg, GDST)) == 0x18);
|
||||
static_assert((offsetof (struct g1_if_reg, G1RRC)) == 0x80);
|
||||
static_assert((offsetof (struct g1_if_reg, G1RWC)) == 0x84);
|
||||
static_assert((offsetof (struct g1_if_reg, G1FRC)) == 0x88);
|
||||
static_assert((offsetof (struct g1_if_reg, G1FWC)) == 0x8c);
|
||||
static_assert((offsetof (struct g1_if_reg, G1CRC)) == 0x90);
|
||||
static_assert((offsetof (struct g1_if_reg, G1CWC)) == 0x94);
|
||||
static_assert((offsetof (struct g1_if_reg, G1GDRC)) == 0xa0);
|
||||
static_assert((offsetof (struct g1_if_reg, G1GDWC)) == 0xa4);
|
||||
static_assert((offsetof (struct g1_if_reg, G1SYSM)) == 0xb0);
|
||||
static_assert((offsetof (struct g1_if_reg, G1CRDYC)) == 0xb4);
|
||||
static_assert((offsetof (struct g1_if_reg, GDAPRO)) == 0xb8);
|
||||
static_assert((offsetof (struct g1_if_reg, GDSTARD)) == 0xf4);
|
||||
static_assert((offsetof (struct g1_if_reg, GDLEND)) == 0xf8);
|
||||
|
||||
struct g2_if_reg {
|
||||
reg32 ADSTAG; /* ACIA:G2-DMA G2 start address */
|
||||
@ -302,11 +304,7 @@ static_assert((offsetof (struct pvr_if_reg, PDSTARD)) == 0xf4);
|
||||
static_assert((offsetof (struct pvr_if_reg, PDLEND)) == 0xf8);
|
||||
|
||||
extern struct system_reg system __asm("system");
|
||||
|
||||
extern struct maple_if_reg maple_if __asm("maple_if");
|
||||
|
||||
extern struct g1_if_reg g1_if __asm("g1_if");
|
||||
|
||||
extern struct g2_if_reg g2_if __asm("g2_if");
|
||||
|
||||
extern struct pvr_if_reg pvr_if __asm("pvr_if");
|
||||
|
Loading…
x
Reference in New Issue
Block a user