mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-22 10:39:20 +01:00
Add dev container.
This commit is contained in:
parent
993b3f7d05
commit
44c9984758
13
.devcontainer/Dockerfile
Normal file
13
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
FROM ghcr.io/n64-tools/gcc-toolchain-mips64:latest
|
||||||
|
|
||||||
|
# Avoid warnings by switching to noninteractive
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN git clone --branch trunk https://github.com/dragonminded/libdragon.git --depth 1 ./sources/libdragon
|
||||||
|
|
||||||
|
RUN cd ./sources/libdragon && \
|
||||||
|
make -j libdragon && \
|
||||||
|
make install && \
|
||||||
|
make -j tools && \
|
||||||
|
make tools-install && \
|
||||||
|
make install-mk
|
20
.devcontainer/devcontainer.json
Normal file
20
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "N64FlashcartMenu",
|
||||||
|
// If you prefer, you can use the source files and adjust them they are located, with the same names in ./sources. This will alow you to customize them and add anything you may need on top.
|
||||||
|
"dockerFile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"mounts": [
|
||||||
|
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
|
||||||
|
// Keep command history
|
||||||
|
"source=nano-bashhistory,target=/home/vscode/commandhistory,type=volume",
|
||||||
|
],
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {
|
||||||
|
},
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": [
|
||||||
|
"ms-vsliveshare.vsliveshare-pack",
|
||||||
|
"streetsidesoftware.code-spell-checker",
|
||||||
|
"ms-vscode.makefile-tools"
|
||||||
|
]
|
||||||
|
}
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=crlf
|
@ -53,3 +53,9 @@ This will likely replace AltraOSv1
|
|||||||
# Developer documentation
|
# Developer documentation
|
||||||
**Work in progress!**
|
**Work in progress!**
|
||||||
|
|
||||||
|
You can use a dev container in VSCode.
|
||||||
|
|
||||||
|
`ms-vscode.makefile-tools` will help (installed automatically in dev container).
|
||||||
|
TODO: it does not yet work with `F5`: see https://devblogs.microsoft.com/cppblog/now-announcing-makefile-support-in-visual-studio-code/
|
||||||
|
WORKAROUND: in the terminal, use make directly `make all`
|
||||||
|
|
||||||
|
110
src/libs/pixelfx_n64digital/pfxromid.c
Normal file
110
src/libs/pixelfx_n64digital/pfxromid.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
Based on libdragon
|
||||||
|
This implementation does not disable interrupts during PIF operation!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "pfxromid.h"
|
||||||
|
#include "libdragon.h"
|
||||||
|
|
||||||
|
#define SI_STATUS_DMA_BUSY (1 << 0)
|
||||||
|
#define SI_STATUS_IO_BUSY (1 << 1)
|
||||||
|
|
||||||
|
#define MEMORY_BARRIER() asm volatile ("" : : : "memory")
|
||||||
|
|
||||||
|
#define cache_op(op, linesize) ({ \
|
||||||
|
if (length) { \
|
||||||
|
void *cur = (void*)((unsigned long)addr & ~(linesize-1)); \
|
||||||
|
int count = (int)length + (addr-cur); \
|
||||||
|
for (int i = 0; i < count; i += linesize) \
|
||||||
|
asm ("\tcache %0,(%1)\n"::"i" (op), "r" (cur+i)); \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define UncachedAddr(_addr) ((void *)(((unsigned long)(_addr))|0x20000000))
|
||||||
|
|
||||||
|
typedef struct SI_regs_s {
|
||||||
|
volatile void * DRAM_addr;
|
||||||
|
volatile void * PIF_addr_read;
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint32_t reserved2;
|
||||||
|
volatile void * PIF_addr_write;
|
||||||
|
uint32_t reserved3;
|
||||||
|
uint32_t status;
|
||||||
|
} SI_regs_t;
|
||||||
|
|
||||||
|
static volatile struct SI_regs_s * const SI_regs = (struct SI_regs_s *)0xa4800000;
|
||||||
|
static void * const PIF_RAM = (void *)0x1fc007c0;
|
||||||
|
|
||||||
|
// Uses the libdragon header function!!!
|
||||||
|
// static void data_cache_hit_writeback_invalidate(volatile void * addr, unsigned long length)
|
||||||
|
// {
|
||||||
|
// cache_op(0x15, 16);
|
||||||
|
// }
|
||||||
|
|
||||||
|
static void __SI_DMA_wait(void)
|
||||||
|
{
|
||||||
|
while (SI_regs->status & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_BUSY));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __controller_exec_PIF(void *inblock) { //TODO: this is (nearly) the same as the RTC code (duplicate) use generic function or just libdragon?!)
|
||||||
|
volatile uint64_t inblock_temp[8];
|
||||||
|
volatile uint64_t outblock_temp[8];
|
||||||
|
|
||||||
|
data_cache_hit_writeback_invalidate(inblock_temp, 64);
|
||||||
|
memcpy(UncachedAddr(inblock_temp), inblock, 64);
|
||||||
|
|
||||||
|
/* Be sure another thread doesn't get into a resource fight */
|
||||||
|
disable_interrupts();
|
||||||
|
|
||||||
|
__SI_DMA_wait();
|
||||||
|
|
||||||
|
SI_regs->DRAM_addr = inblock_temp; // only cares about 23:0
|
||||||
|
MEMORY_BARRIER();
|
||||||
|
SI_regs->PIF_addr_write = PIF_RAM; // is it really ever anything else?
|
||||||
|
MEMORY_BARRIER();
|
||||||
|
|
||||||
|
__SI_DMA_wait();
|
||||||
|
|
||||||
|
data_cache_hit_writeback_invalidate(outblock_temp, 64);
|
||||||
|
|
||||||
|
SI_regs->DRAM_addr = outblock_temp;
|
||||||
|
MEMORY_BARRIER();
|
||||||
|
SI_regs->PIF_addr_read = PIF_RAM;
|
||||||
|
MEMORY_BARRIER();
|
||||||
|
|
||||||
|
__SI_DMA_wait();
|
||||||
|
|
||||||
|
/* Now that we've copied, its safe to let other threads go */
|
||||||
|
enable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_raw_command(int controller, int command, int bytesout, unsigned char *out)
|
||||||
|
{
|
||||||
|
unsigned long long SI_read_controllers_block[8] = { 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||||
|
uint8_t *data = (uint8_t *)SI_read_controllers_block;
|
||||||
|
|
||||||
|
data[controller + 0] = bytesout + 1;
|
||||||
|
data[controller + 1] = 1;
|
||||||
|
data[controller + 2] = command;
|
||||||
|
|
||||||
|
memcpy( &data[controller + 3], out, bytesout );
|
||||||
|
data[controller + 3 + bytesout] = 0xFE;
|
||||||
|
data[controller + 3 + bytesout + 1] = 0xFF;
|
||||||
|
|
||||||
|
__controller_exec_PIF(SI_read_controllers_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pfx_send_game_id(uint8_t* crc_hi, uint8_t* crc_lo, uint8_t media_format, uint8_t country_id)
|
||||||
|
{
|
||||||
|
uint8_t out[10];
|
||||||
|
|
||||||
|
memcpy(out, crc_hi, 4);
|
||||||
|
memcpy(&out[4], crc_lo, 4);
|
||||||
|
|
||||||
|
out[8] = media_format;
|
||||||
|
out[9] = country_id;
|
||||||
|
|
||||||
|
send_raw_command(0, 0x1D, sizeof(out), out);
|
||||||
|
}
|
20
src/libs/pixelfx_n64digital/pfxromid.h
Normal file
20
src/libs/pixelfx_n64digital/pfxromid.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
** Copyright 2021 JonesAlmighty & PixelFx
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PIXELFX_ROMID_H
|
||||||
|
#define __PIXELFX_ROMID_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void pfx_send_game_id(uint8_t* crc_hi, uint8_t* crc_lo, uint8_t media_format, uint8_t country_id);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user