Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ The LLVM-MOS compiler toolchain and platform libraries.
- [PC Engine / TurboGrafx-16](https://en.wikipedia.org/wiki/TurboGrafx-16)
- [PC Engine CD](https://en.wikipedia.org/wiki/TurboGrafx-16#TurboGrafx-CD/CD-ROM%C2%B2)
- [RPC/8e](http://www.eloraam.com/blog/2012/04/22/rp-control-internals/) (RedPower 2)
- [SNES [(Nintendo Entertainment System)] (https://en.wikipedia.org/wiki/Super_Nintendo_Entertainment_System)
- 6502 simulator (included)

## Notable features
Expand Down Expand Up @@ -182,6 +183,7 @@ executables and libraries for that target.
| PC Engine | Standard | `mos-pce-clang` |
| PC Engine | CD | `mos-pce-cd-clang` |
| RPC/8e (RedPower 2) | - | `mos-rpc8e-clang` |
| SNES | - | `mos-snes-clang` |
| Watara Supervision | - | `mos-supervision-clang` |
| 6502 simulator | - | `mos-sim-clang` |

Expand Down
3 changes: 3 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ endif()
if(PLATFORM MATCHES ^nes-)
add_subdirectory(nes)
endif()
if(PLATFORM MATCHES ^snes-)
add_subdirectory(snes)
endif()
if(PLATFORM STREQUAL pce)
add_subdirectory(pce)
endif()
Expand Down
2 changes: 2 additions & 0 deletions examples/snes/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_executable(cgramtest cgramtest.c.c)
install_example(cgramtest)
32 changes: 32 additions & 0 deletions examples/snes/cgramtest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <stdint.h>
#include <stddef.h>
#include <snes_regs_xc.h>

int main(void) {
int8_t regRead1 = 0;
uint8_t lastInputLo = 0;
uint8_t lastInputHi = 0;
REG_NMITIMEN = 0x01; //Joypad autoread enable
REG_INIDISP = 0x0F; // Set brightness to 15, screen enabled
for (;;) {
do{ //Wait for Vblank
regRead1 = REG_RDNMI;
} while( (regRead1 > 0));
do{ //Wait for joypad read ready
regRead1 = REG_HVBJOY;
} while( (regRead1 & 0x01) != 0);

lastInputLo = REG_JOY1L;
lastInputHi = REG_JOY1H;
if (lastInputLo | lastInputHi) {
REG_CGDATA = 0x1F;
REG_CGDATA = 0x00;
REG_CGADD = 0x00;
}
else {
REG_CGDATA = 0x00;
REG_CGDATA = 0x1F;
REG_CGADD = 0x00;
}
}
}
1 change: 1 addition & 0 deletions mos-platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ add_subdirectory(nes-mmc1)
add_subdirectory(nes-mmc3)
add_subdirectory(nes-unrom)
add_subdirectory(nes-unrom-512)
add_subdirectory(snes)
add_subdirectory(osi-c1p)
add_subdirectory(dodo)
add_subdirectory(pet)
Expand Down
24 changes: 24 additions & 0 deletions mos-platform/snes/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
platform(snes COMPLETE PARENT common)

if(NOT CMAKE_CROSSCOMPILING)
return()
endif()

include_directories(BEFORE SYSTEM .)

add_platform_library(snes-crt0)
merge_libraries(snes-crt0
common-init-stack
common-copy-zp-data
common-copy-data
common-zero-bss
)

add_platform_library(snes-c
putchar_stub.c
startup.s
vectors.s
)

add_subdirectory(snesxc)
target_include_directories(snes-c SYSTEM BEFORE PUBLIC .)
2 changes: 2 additions & 0 deletions mos-platform/snes/clang.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-mlto-zp=224
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-mcpu=mosw65816 will enable some 65816-specific optimizations.

-D__SNES__
123 changes: 123 additions & 0 deletions mos-platform/snes/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* SNES LoROM linker script for LLVM-MOS
*
* Multi-bank ROM for SNES LoROM mapping.
* Target CPU: 65816 (use -mcpu=mosw65816 compiler flag)
*/

/* Provide imaginary (zero page) registers. */
__rc0 = 0x00;
INCLUDE imag-regs.ld
ASSERT(__rc31 == 0x001f, "Inconsistent zero page map.")

MEMORY {
zp : ORIGIN = __rc31 + 1, LENGTH = 0x100 - (__rc31 + 1)
ram (rw) : ORIGIN = 0x0200, LENGTH = 0x1C00
rom_bank_0 (rx) : ORIGIN = 0x008000, LENGTH = 0x7E00
rom_bank_1 (rx) : ORIGIN = 0x018000, LENGTH = 0x7E00
rom_bank_2 (rx) : ORIGIN = 0x028000, LENGTH = 0x7E00
rom_bank_3 (rx) : ORIGIN = 0x038000, LENGTH = 0x7E00
rom_bank_4 (rx) : ORIGIN = 0x048000, LENGTH = 0x7E00
rom_bank_5 (rx) : ORIGIN = 0x058000, LENGTH = 0x7E00
rom_bank_6 (rx) : ORIGIN = 0x068000, LENGTH = 0x7E00
rom_bank_7 (rx) : ORIGIN = 0x078000, LENGTH = 0x7E00
rom_bank_0_fixed : ORIGIN = 0x00FE00, LENGTH = 0x0200
}

REGION_ALIAS("c_writeable", ram)
/* Define c_readonly for backwards compatibility, though we use classes for placement */
REGION_ALIAS("c_readonly", rom_bank_0)

/* Set initial soft stack address to just above zero page */
__stack = 0x0200;

/* Set entry point to startup code */
ENTRY(_start)

SECTIONS {
INCLUDE c.ld

/* Custom sections for ROM bank placement - these come AFTER c.ld sections */

/* Code section for rom_bank_0_fixed - placed before vectors */
.text.rom_bank_0_fixed : { *(.text.rom_bank_0_fixed .text.rom_bank_0_fixed.*) } >rom_bank_0_fixed

/* Read-only data section for rom_bank_0_fixed */
.rodata.rom_bank_0_fixed : { *(.rodata.rom_bank_0_fixed .rodata.rom_bank_0_fixed.*) } >rom_bank_0_fixed

/* Generic section for rom_bank_0_fixed (allows __attribute__((section("rom_bank_0_fixed")))) */
rom_bank_0_fixed : { *(rom_bank_0_fixed rom_bank_0_fixed.*) } >rom_bank_0_fixed

/* SNES Interrupt Vectors - Native Mode */
.vectors_native 0xFFE4 : {
SHORT(COP) /* COP vector */
SHORT(BRK) /* BRK vector */
SHORT(ABORT) /* ABORT vector */
SHORT(NMI) /* NMI vector */
SHORT(DIRQ) /* Reserved vector */
SHORT(IRQ) /* IRQ vector */
/* 4 bytes reserved */
LONG(0x00000000)
} >rom_bank_0_fixed

/* SNES Interrupt Vectors - Emulation Mode */
.vectors_emulation 0xFFF4 : {
SHORT(COP) /* COP vector */
SHORT(DIRQ) /* Reserved vector */
SHORT(ABORT) /* ABORT vector */
SHORT(NMI) /* NMI vector */
SHORT(_start) /* RESET vector - points to program entry point */
SHORT(IRQ) /* IRQ vector */
} >rom_bank_0_fixed

/* Custom sections for ROM bank placement */
/* Code sections for specific banks */
.text.rom_bank_0 : { *(.text.rom_bank_0 .text.rom_bank_0.*) } >rom_bank_0
.text.rom_bank_1 : { *(.text.rom_bank_1 .text.rom_bank_1.*) } >rom_bank_1
.text.rom_bank_2 : { *(.text.rom_bank_2 .text.rom_bank_2.*) } >rom_bank_2
.text.rom_bank_3 : { *(.text.rom_bank_3 .text.rom_bank_3.*) } >rom_bank_3
.text.rom_bank_4 : { *(.text.rom_bank_4 .text.rom_bank_4.*) } >rom_bank_4
.text.rom_bank_5 : { *(.text.rom_bank_5 .text.rom_bank_5.*) } >rom_bank_5
.text.rom_bank_6 : { *(.text.rom_bank_6 .text.rom_bank_6.*) } >rom_bank_6
.text.rom_bank_7 : { *(.text.rom_bank_7 .text.rom_bank_7.*) } >rom_bank_7

/* Constant/read-only data sections for specific banks */
.rodata.rom_bank_0 : { *(.rodata.rom_bank_0 .rodata.rom_bank_0.*) } >rom_bank_0
.rodata.rom_bank_1 : { *(.rodata.rom_bank_1 .rodata.rom_bank_1.*) } >rom_bank_1
.rodata.rom_bank_2 : { *(.rodata.rom_bank_2 .rodata.rom_bank_2.*) } >rom_bank_2
.rodata.rom_bank_3 : { *(.rodata.rom_bank_3 .rodata.rom_bank_3.*) } >rom_bank_3
.rodata.rom_bank_4 : { *(.rodata.rom_bank_4 .rodata.rom_bank_4.*) } >rom_bank_4
.rodata.rom_bank_5 : { *(.rodata.rom_bank_5 .rodata.rom_bank_5.*) } >rom_bank_5
.rodata.rom_bank_6 : { *(.rodata.rom_bank_6 .rodata.rom_bank_6.*) } >rom_bank_6
.rodata.rom_bank_7 : { *(.rodata.rom_bank_7 .rodata.rom_bank_7.*) } >rom_bank_7

/* Generic sections that can be used directly with rom_bank_X names */
/* These allow using __attribute__((section("rom_bank_0"))) directly */
rom_bank_0 : { *(rom_bank_0 rom_bank_0.*) } >rom_bank_0
rom_bank_1 : { *(rom_bank_1 rom_bank_1.*) } >rom_bank_1
rom_bank_2 : { *(rom_bank_2 rom_bank_2.*) } >rom_bank_2
rom_bank_3 : { *(rom_bank_3 rom_bank_3.*) } >rom_bank_3
rom_bank_4 : { *(rom_bank_4 rom_bank_4.*) } >rom_bank_4
rom_bank_5 : { *(rom_bank_5 rom_bank_5.*) } >rom_bank_5
rom_bank_6 : { *(rom_bank_6 rom_bank_6.*) } >rom_bank_6
rom_bank_7 : { *(rom_bank_7 rom_bank_7.*) } >rom_bank_7
}

OUTPUT_FORMAT {
FULL(rom_bank_0)
FULL(rom_bank_0_fixed)
FULL(rom_bank_1)
FULL(rom_bank_0_fixed)
FULL(rom_bank_2)
FULL(rom_bank_0_fixed)
FULL(rom_bank_3)
FULL(rom_bank_0_fixed)
FULL(rom_bank_4)
FULL(rom_bank_0_fixed)
FULL(rom_bank_5)
FULL(rom_bank_0_fixed)
FULL(rom_bank_6)
FULL(rom_bank_0_fixed)
FULL(rom_bank_7)
FULL(rom_bank_0_fixed)
}

7 changes: 7 additions & 0 deletions mos-platform/snes/putchar_stub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Minimal putchar stub for LLVM-Mos
// This provides the __putchar function that sprintf requires internally
int __putchar(int c) {
// Do nothing - this is just a stub to satisfy the linker
// Potentially write to no$snes debug port and use a lua script for mesen
return c;
}
11 changes: 11 additions & 0 deletions mos-platform/snes/snesxc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
install(FILES
int_snes_xc.h
snes_regs_xc.h
snesxc.h
TYPE INCLUDE)

add_platform_library(snes-snesxc
snesxc.c
)
target_include_directories(snes-snesxc BEFORE PUBLIC ..)
target_link_libraries(snes-snesxc PRIVATE common-asminc)
24 changes: 24 additions & 0 deletions mos-platform/snes/snesxc/int_snes_xc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

#ifndef __INT_SNES_XC_H
#define __INT_SNES_XC_H

typedef __INT8_TYPE__ int8_t;
typedef __INT16_TYPE__ int16_t;
typedef __INT32_TYPE__ int32_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __SIZE_TYPE__ size_t;

#ifndef NULL
#define NULL 0
#endif

typedef volatile int8_t *volatile vs8;
typedef volatile int16_t *volatile vs16;
typedef volatile int32_t *volatile vs32;
typedef volatile uint8_t *volatile vu8;
typedef volatile uint16_t *volatile vu16;
typedef volatile uint32_t *volatile vu32;

#endif // __INT_SNES_XC_H
Loading