Skip to content

Commit 47d72c6

Browse files
committed
first release of gbatang
1 parent 64c48fb commit 47d72c6

File tree

117 files changed

+67749
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+67749
-0
lines changed

README.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
# GBATang - GBA for Sipeed Tang FPGA boards
3+
4+
<img src='doc/gbatang0.1.jpg' width=300 />
5+
6+
This is a working but early-stage Gameboy Advance FPGA core for Sipeed [Tang Mega 138K](https://wiki.sipeed.com/hardware/en/tang/tang-mega-138k/mega-138k.html), [Mega 138K Pro](https://wiki.sipeed.com/hardware/en/tang/tang-mega-138k/mega-138k-pro.html) and the upcoming portable Sipeed Tang 60K board/handheld.
7+
8+
The core outputs 720p HDMI video, accepts DS2 controller input, and supports all ROM sizes (up to 32MB). An open source BIOS is used so it can be used out of the box. ROMs are loaded from the SD card through a convenient menu system. Some games does not work yet. The following are some that are verified to work,
9+
10+
* Super Mario Advance 2 (Super Mario World)
11+
* F-ZERO Maximum Velocity
12+
* Donkey Kong Country
13+
* NES Classic Super Mario Brothers, IceClimber
14+
* and more
15+
16+
Missing things that I expect to implement include cartridge backup, SNES controller input, game compatibility fixes and ability to use original BIOS.
17+
18+
Follow [me](https://x.com/nand2mario) on X to get updates. Also check out other cores in the series: [SNESTang](https://github.com/nand2mario/snestang) and [NESTang](https://github.com/nand2mario/nestang).
19+
20+
## Instructions
21+
22+
You need the Tang Mega 138K or Tang Mega 138K Pro board. Or you can wait for the Tang retro handheld. You also need a [Tang DS2 Pmod](https://wiki.sipeed.com/hardware/en/tang/tang-PMOD/FPGA_PMOD.html), a [Tang SDRAM Pmod](https://wiki.sipeed.com/hardware/en/tang/tang-PMOD/FPGA_PMOD.html), a [DS2 controller](https://en.wikipedia.org/wiki/DualShock), and finally a MicroSD card. Then assemble the parts as shown in the picture above.
23+
24+
Then follow these steps to install the core (for detailed instructions, for now refer to [SNESTang installation](https://github.com/nand2mario/snestang/blob/main/doc/installation.md)),
25+
26+
1. Download and install [Gowin IDE 1.9.10.02](https://cdn.gowinsemi.com.cn/Gowin_V1.9.10.02_x64_win.zip).
27+
28+
2. Download a [GBATang release](https://github.com/nand2mario/gbatang/releases).
29+
30+
3. Use Gowin programmer to program `firmware.bin` to on-board flash, at starting address **0x500000**.
31+
32+
4. Again use Gowin programmer. Program `gbatang_m138k.fs` or `gbatang_m138kpro.fs` to on-board flash at starting address 0x000000.
33+
34+
5. Put GBA roms on the MicroSD card and insert it into the on-board MicroSD slot. Then power up the board.
35+
36+
## About this project
37+
38+
The project started as a port of the MiSTer GBA core to Tang FPGAs in June 2024. However, it quickly turned into a half-rewrite. By September 2024 it finally reached usable state and about half of the code is different. Here are the main differences.
39+
40+
* The overall design is a more traditional "FPGA replica" approach, as opposed to the "cycle counting" approach in the MiSTer core. Most modules work at 16Mhz, the GBA main frequency. The MiSTer main frequency is 100Mhz.
41+
* The CPU is [replaced](https://github.com/risclite/ARM9-compatible-soft-CPU-core), with missing features like 16-bit instructions added. The processor uses a similar pipelined design as the original GBA CPU.
42+
* The memory system is also completely rewritten, as required by the overall design change.
43+
* Timing accuracy could use a lot of improvements. However as a more "modern" console, GBA mostly uses interrupts and timers to keep time. So cycle-accuracy is not as important as previous consoles.
44+
* A softcore-based menu system is provided, similar to SNESTang and NESTang.
45+
46+
## Acknowledgements
47+
* [GBA_MiSTer](https://github.com/MiSTer-devel/GBA_MiSTer)
48+
* [risclite's CPU core](https://github.com/risclite/ARM9-compatible-soft-CPU-core)
49+

build.tcl

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
add_file -type verilog "src/common/dpram32_block.v"
2+
add_file -type verilog "src/common/dpram_block.v"
3+
add_file -type verilog "src/common/dual_clk_fifo.v"
4+
add_file -type verilog "src/common/eprocreg_gba.sv"
5+
add_file -type verilog "src/common/gba_bios.sv"
6+
add_file -type verilog "src/cpu/gba_cpu.v"
7+
add_file -type verilog "src/cpu/gba_cpu_thumbdecoder.v"
8+
add_file -type verilog "src/cpu/gba_interrupts.v"
9+
add_file -type verilog "src/gba2hdmi.sv"
10+
add_file -type verilog "src/gbatang_top.sv"
11+
add_file -type verilog "src/gpu/gba_drawer_merge.v"
12+
add_file -type verilog "src/gpu/gba_drawer_mode0.v"
13+
add_file -type verilog "src/gpu/gba_drawer_mode2.v"
14+
add_file -type verilog "src/gpu/gba_drawer_mode345.v"
15+
add_file -type verilog "src/gpu/gba_drawer_obj.sv"
16+
add_file -type verilog "src/gpu/gba_gpu.v"
17+
add_file -type verilog "src/gpu/gba_gpu_colorshade.sv"
18+
add_file -type verilog "src/gpu/gba_gpu_drawer.v"
19+
add_file -type verilog "src/gpu/gba_gpu_timing.v"
20+
add_file -type verilog "src/gpu/gba_timer.v"
21+
add_file -type verilog "src/gpu/gba_timer_module.v"
22+
add_file -type verilog "src/gpu/vram_hi.v"
23+
add_file -type verilog "src/gpu/vram_lo.v"
24+
add_file -type verilog "src/hdmi/audio_clock_regeneration_packet.sv"
25+
add_file -type verilog "src/hdmi/audio_info_frame.sv"
26+
add_file -type verilog "src/hdmi/audio_sample_packet.sv"
27+
add_file -type verilog "src/hdmi/auxiliary_video_information_info_frame.sv"
28+
add_file -type verilog "src/hdmi/hdmi.sv"
29+
add_file -type verilog "src/hdmi/packet_assembler.sv"
30+
add_file -type verilog "src/hdmi/packet_picker.sv"
31+
add_file -type verilog "src/hdmi/serializer.sv"
32+
add_file -type verilog "src/hdmi/source_product_description_info_frame.sv"
33+
add_file -type verilog "src/hdmi/tmds_channel.sv"
34+
add_file -type verilog "src/iosys/gowin_dpb_menu.v"
35+
add_file -type verilog "src/iosys/iosys.v"
36+
add_file -type verilog "src/iosys/picorv32.v"
37+
add_file -type verilog "src/iosys/simplespimaster.v"
38+
add_file -type verilog "src/iosys/simpleuart.v"
39+
add_file -type verilog "src/iosys/spi_master.v"
40+
add_file -type verilog "src/iosys/spiflash.v"
41+
add_file -type verilog "src/iosys/textdisp.v"
42+
add_file -type verilog "src/m138k/pll_27.v"
43+
add_file -type verilog "src/m138k/pll_33.v"
44+
add_file -type verilog "src/m138k/pll_74.v"
45+
add_file -type verilog "src/memory/gba_dma.v"
46+
add_file -type verilog "src/memory/gba_dma_module.sv"
47+
add_file -type verilog "src/memory/gba_eeprom.sv"
48+
add_file -type verilog "src/memory/gba_flash_sram.sv"
49+
add_file -type verilog "src/memory/gba_memory.sv"
50+
add_file -type verilog "src/memory/mem_eeprom.v"
51+
add_file -type verilog "src/memory/mem_iwram.v"
52+
add_file -type verilog "src/memory/rv_sdram_adapter.v"
53+
add_file -type verilog "src/memory/sdram_gba.v"
54+
add_file -type verilog "src/peripherals/controller_ds2.sv"
55+
add_file -type verilog "src/peripherals/dualshock_controller.v"
56+
add_file -type verilog "src/peripherals/gba_joypad.v"
57+
add_file -type verilog "src/sound/gba_sound.v"
58+
add_file -type verilog "src/sound/gba_sound_ch1.v"
59+
add_file -type verilog "src/sound/gba_sound_ch3.v"
60+
add_file -type verilog "src/sound/gba_sound_ch4.v"
61+
add_file -type verilog "src/sound/gba_sound_dma.v"
62+
add_file -type verilog "src/test_loader.v"
63+
64+
set_option -synthesis_tool gowinsynthesis
65+
set_option -top_module gbatang_top
66+
set_option -include_path {"src/common"}
67+
set_option -verilog_std sysv2017
68+
set_option -vhdl_std vhd2008
69+
set_option -ireg_in_iob 1
70+
set_option -oreg_in_iob 1
71+
set_option -ioreg_in_iob 1
72+
set_option -use_sspi_as_gpio 1
73+
set_option -use_mspi_as_gpio 1
74+
set_option -use_cpu_as_gpio 1
75+
76+
# use the slower but timing-optimized place algorithm
77+
set_option -place_option 2
78+
79+
run all

doc/gbatang0.1.jpg

238 KB
Loading

firmware/Makefile

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#
2+
# The xPack GNU RISC-V Embedded GCC
3+
# https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
4+
#
5+
TARGET_ELF = firmware.elf
6+
TARGET_BIN = firmware.bin
7+
#RISCV = /opt/xpack-riscv-none-elf-gcc-13.2.0-2/bin/riscv-none-elf
8+
RISCV = /usr/local/xpack-riscv-none-embed-gcc-10.1.0-1.1/bin/riscv-none-embed
9+
CC = $(RISCV)-gcc
10+
OBJCOPY = $(RISCV)-objcopy
11+
OBJDUMP = $(RISCV)-objdump
12+
CFLAGS = -Wall -O2 -g -mabi=ilp32 -march=rv32i -ffreestanding
13+
LFLAGS = -mabi=ilp32 -march=rv32i -Wl,--build-id=none,-Bstatic,-T,baremetal.ld -nostdlib
14+
LIBS = -lgcc
15+
16+
SRCS := start.S firmware.c picorv32.c spi_sd.c spiflash.c \
17+
fatfs/diskio.c fatfs/ff.c fatfs/ffunicode.c
18+
OBJS := $(SRCS:.c=.o)
19+
OBJS := $(OBJS:.S=.o)
20+
HDRS := $(wildcard *.h)
21+
22+
ifeq ($(VERBOSE),1)
23+
Q =
24+
else
25+
Q = @
26+
endif
27+
28+
default: $(TARGET_BIN)
29+
all: default
30+
31+
%.o: %.c $(HDRS)
32+
ifneq ($(VERBOSE),1)
33+
@echo CC $@
34+
endif
35+
$(Q)$(CC) $(CFLAGS) -c $< -o $@
36+
37+
%.o: %.S $(HDRS)
38+
ifneq ($(VERBOSE),1)
39+
@echo CC $@
40+
endif
41+
$(Q)$(CC) $(CFLAGS) -c $< -o $@
42+
43+
.PRECIOUS: $(TARGET_BIN) $(TARGET_ELF) $(OBJS)
44+
45+
$(TARGET_ELF): $(OBJS)
46+
ifneq ($(VERBOSE),1)
47+
@echo CC $@
48+
endif
49+
$(Q)$(CC) $(LFLAGS) $(OBJS) $(LIBS) -o $@
50+
51+
$(TARGET_BIN): $(TARGET_ELF)
52+
ifneq ($(VERBOSE),1)
53+
@echo OBJCOPY $@
54+
endif
55+
$(Q)$(OBJCOPY) $(TARGET_ELF) $(TARGET_BIN) -O binary
56+
57+
clean:
58+
$(Q)rm -f $(OBJS) $(TARGET_ELF) $(TARGET_BIN)
59+
60+
.PHONY: default all clean

firmware/baremetal.ld

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* linker control script for 'bare metal' executables.
3+
* Ensures that _start defined in start.S is put at address 0
4+
* Uses the first 2MB of RAM.
5+
*/
6+
MEMORY
7+
{
8+
FLASH (RX): ORIGIN = 0x00000, LENGTH = 100K
9+
RAM (RWX): ORIGIN = 100K, LENGTH = 0x1e7000
10+
}
11+
SECTIONS
12+
{
13+
.text :
14+
{
15+
start.o (.text)
16+
*(.text)
17+
_end = .; /* as expected by syscalls.c */
18+
} >FLASH
19+
20+
/* global and static variable with initial values */
21+
.data :
22+
{
23+
. = ALIGN(4);
24+
_sdata = .;
25+
. = ALIGN(4);
26+
*(.data) /* .data sections */
27+
*(.data*) /* .data* sections */
28+
*(.sdata) /* .sdata sections */
29+
*(.sdata*) /* .sdata* sections */
30+
. = ALIGN(4);
31+
_edata = .;
32+
}
33+
34+
/* global and static variables without initial values. initialized to 0 by start.S */
35+
.bss :
36+
{
37+
. = ALIGN(4);
38+
_sbss = .; /* start of bss, used by startup code */
39+
*(.bss)
40+
*(.bss*)
41+
*(.sbss)
42+
*(.sbss*)
43+
*(COMMON)
44+
. = ALIGN(4);
45+
_ebss = .; /* end of bss, used by startup code */
46+
}
47+
48+
.heap :
49+
{
50+
. = ALIGN(4);
51+
_heap_start = .; /* define a global symbol at heap start */
52+
}
53+
}

firmware/build.bat

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
@REM This compiles the firmware into firmware.bin in RV32I format.
3+
@REM It is to be loaded at address 0.
4+
5+
@REM Download RISC-V gcc toolchain for x64 from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/
6+
set CROSS=D:\opt\xpack-riscv-none-elf-gcc-13.2.0-2\bin\riscv-none-elf-
7+
set CFLAGS=-O -mabi=ilp32 -march=rv32i -ffreestanding
8+
9+
%CROSS%as -mabi=ilp32 -march=rv32i -c -o start.o start.S
10+
%CROSS%gcc %CFLAGS% -c -o firmware.o firmware.c
11+
%CROSS%gcc %CFLAGS% -c -o picorv32.o picorv32.c
12+
%CROSS%gcc %CFLAGS% -c -o spi_sd.o spi_sd.c
13+
%CROSS%gcc %CFLAGS% -c -o spiflash.o spiflash.c
14+
15+
@REM fatfs
16+
%CROSS%gcc %CFLAGS% -c -o fatfs\diskio.o fatfs\diskio.c
17+
%CROSS%gcc %CFLAGS% -c -o fatfs\ff.o fatfs\ff.c
18+
%CROSS%gcc %CFLAGS% -c -o fatfs\ffunicode.o fatfs\ffunicode.c
19+
20+
%CROSS%gcc %CFLAGS% -Wl,--build-id=none,-Bstatic,-T,baremetal.ld,--strip-debug ^
21+
-nostdlib -o firmware.elf start.o firmware.o picorv32.o spi_sd.o spiflash.o ^
22+
fatfs\diskio.o fatfs\ff.o fatfs\ffunicode.o -lgcc
23+
24+
%CROSS%objcopy firmware.elf firmware.bin -O binary
25+
@REM python bin2hexwords.py firmware.bin firmware.hex
26+
27+
%CROSS%objdump -Mnumeric -D firmware.elf > firmware.elf.list

firmware/clean.bat

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
del *.bin *.elf *.list *.o *.hex fatfs\*.o

0 commit comments

Comments
 (0)