Skip to content

Commit

Permalink
Reorganise C structure
Browse files Browse the repository at this point in the history
This is a big C reorg to serve two main purposes:
- Be more consistent with C and GBDK patterns
- Separate modules and logic where possible. It will allow unit testing (next PR) and enable more contained enhancements (e.g. new screens, new synth concepts) and encourage small bug fixes

Changes:
- Refactors C to use .h patterns
- Splits code into modules: io, synth, screen. Consolidates global variables, easier to test and clearer which functionality owns which variables
- Converts ASM playNote* and update* for Pu1, Pu2, Wav, Noi into C functions
  - Most are pretty comparable in speed, so this shouldn't be a big perf regression (stats in comments above methods)
- Use structs for a bunch of arrays to improve readability (pointer to struct members is similar to array access (still more room for improvement)
- Use GBDK global vars for readability (e.g. rAUD3LOW, _AUDWAVERAM, rAUDENA, etc)
  • Loading branch information
tstirrat committed Jul 25, 2024
1 parent f1aa614 commit ed61a57
Show file tree
Hide file tree
Showing 40 changed files with 2,110 additions and 2,401 deletions.
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[Makefile]
indent_style = tab
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
7 changes: 4 additions & 3 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
"configurations": [
{
"name": "Mac",
"includePath": ["${workspaceFolder}/**"],
"includePath": ["${workspaceFolder}/gbdk/include"],
"defines": ["__TARGET_gb=1", "__PORT_sm83=1"],
"compilerPath": "",
"compilerPath": "${workspaceFolder}/gbdk/bin/lcc",
"cStandard": "c11",
"intelliSenseMode": "${default}"
"intelliSenseMode": "${default}",
"browse": { "limitSymbolsToIncludedHeaders": true }
}
],
"version": 4
Expand Down
9 changes: 9 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
},
"problemMatcher": []
},
{
"label": "make-clean",
"type": "shell",
"command": "make clean",
"options": {
"cwd": "Source/"
},
"problemMatcher": []
},
{
"label": "install",
"detail": "Installs the rom onto a cartridge using ems-flasher (bank 2)",
Expand Down
75 changes: 54 additions & 21 deletions Source/Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# If you move this project you can change the directory
# If you move this project you can change the directory
# to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/"
ifndef GBDK_HOME
GBDK_HOME = ../gbdk
GBDK_HOME = ../gbdk
endif

PROJECTNAME = mGB

LCC = $(GBDK_HOME)/bin/lcc
MAKEFLAGS += --no-builtin-rules

LCC = $(GBDK_HOME)/bin/lcc

LCCFLAGS += -msm83:gb # GB/GBC
# LCCFLAGS += -v # verbose
# LCCFLAGS += -autobank
# LCCFLAGS += -autobank

ifdef DEBUG
LCCFLAGS += -debug -v
Expand Down Expand Up @@ -44,28 +46,59 @@ endif
# LCCFLAGS += -Wm-yS # Convert .noi file named like input file to .sym
LCCFLAGS += -Wm-yc # GBC compatible
LCCFLAGS += -Wm-yn"$(PROJECTNAME)" # cartridge name
LCCFLAGS += -Wm-yt3 # MBC type = ROM+MBC1+RAM+BATT
LCCFLAGS += -Wm-yt3 # MBC type = ROM+MBC1+RAM+BATT
LCCFLAGS += -Wm-ya1 # number of ram banks: -ya 1

LCCFLAGS += -Wf-MMD

OBJDIR = obj
OUTDIR = out


BIN = $(OUTDIR)/$(PROJECTNAME).gb

MKDIRS = $(OUTDIR) $(OBJDIR)/io $(OBJDIR)/screen $(OBJDIR)/synth $(OBJDIR)/io/sram

C_SOURCES = $(wildcard *.c)
C_SOURCES += $(wildcard **/*.c)

SRAM_BANK0 = $(wildcard io/sram/*.b0.c)

ASM_SOURCES = $(wildcard **/*.s)


OBJS = $(C_SOURCES:%.c=$(OBJDIR)/%.o)
OBJS += $(ASM_SOURCES:%.s=$(OBJDIR)/%.o)
OBJS += $(SRAM_BANK0:%.b0.c=$(OBJDIR)/%.b0.o)


# Builds all targets sequentially
all: $(BIN)

# Dependencies - for better incremental builds
DEPS = $(OBJS:%.o=%.d)
-include $(DEPS)

# sram banks
$(OBJDIR)/%.b0.o: %.b0.c
$(LCC) $(LCCFLAGS) -Wf-ba0 -c -o $@ $<

OBJ=obj
OUT=out
# Compile .c files to .o object files
$(OBJDIR)/%.o: %.c
$(LCC) $(LCCFLAGS) -c -o $@ $<

build:
mkdir -p $(OBJ)
mkdir -p $(OUT)

# mostly so you can see the .asm
$(LCC) $(LCCFLAGS) -c -o $(OBJ)/mGB.rel mGB.c
# Compile .s assembly files to .o object files
$(OBJDIR)/%.o: %.s
$(LCC) $(LCCFLAGS) -c -o $@ $<

# SRAM bank 0
$(LCC) $(LCCFLAGS) -Wf-ba0 -c -o $(OBJ)/mgb_save.rel mgb_save.c
$(LCC) $(LCCFLAGS) -o $(OUT)/$(PROJECTNAME).gb $(OBJ)/mGB.rel $(OBJ)/mgb_save.rel *.s
# Link the compiled object files into a .gb ROM file
$(BIN): makedirs $(OBJS)
$(LCC) $(LCCFLAGS) -o $(BIN) $(OBJS)

compile.bat: Makefile
@echo "REM Automatically generated from Makefile" > compile.bat
@make -sn | sed y/\\//\\\\/ | sed s/mkdir\ \-p/mkdir/ | grep -v make >> compile.bat
.PHONY: makedirs
makedirs:
mkdir -p $(MKDIRS)

.PHONY: clean
clean:
rm -rf $(OBJ)
rm -rf $(OUT)
rm -rf $(OBJDIR) $(OUTDIR)
23 changes: 10 additions & 13 deletions Source/mGBMidiFunctions.c → Source/io/midi.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#include "mGB.h"
#include "midi.h"
#include "../mGB.h"
#include "midi_asm.h"
#include "serial.h"

#define MIDI_STATUS_BIT 0x80
#define MIDI_STATUS_NOTE_ON 0x09
#define MIDI_STATUS_NOTE_OFF 0x08
#define MIDI_STATUS_AT 0x0A
#define MIDI_STATUS_CC 0x0B
#define MIDI_STATUS_PC 0x0C
#define MIDI_STATUS_AT_MONO 0x0D
#define MIDI_STATUS_PB 0x0E

#define MIDI_STATUS_SYSTEM 0xF0
uint8_t statusByte;
uint8_t addressByte;
uint8_t valueByte;
uint8_t capturedAddress;

void updateMidiBuffer(void) {
if (serialBufferReadPosition == serialBufferPosition) {
Expand All @@ -18,7 +15,7 @@ void updateMidiBuffer(void) {

serialBufferReadPosition++; // unsigned overflow from 255 -> 0 is automatic.

UBYTE byte = serialBuffer[serialBufferReadPosition];
uint8_t byte = serialBuffer[serialBufferReadPosition];

// STATUS BYTE
if (byte & MIDI_STATUS_BIT) {
Expand Down Expand Up @@ -61,4 +58,4 @@ void updateMidiBuffer(void) {
asmEventMidiPC();
break;
}
}
}
24 changes: 24 additions & 0 deletions Source/io/midi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <gbdk/platform.h>

#define MIDI_STATUS_BIT 0x80
#define MIDI_STATUS_NOTE_ON 0x09
#define MIDI_STATUS_NOTE_OFF 0x08
#define MIDI_STATUS_AT 0x0A
#define MIDI_STATUS_CC 0x0B
#define MIDI_STATUS_PC 0x0C
#define MIDI_STATUS_AT_MONO 0x0D
#define MIDI_STATUS_PB 0x0E

#define MIDI_STATUS_SYSTEM 0xF0

// MIDI status
extern uint8_t statusByte;
// MIDI address (e.g. note/CC control)
extern uint8_t addressByte;
// MIDI value (e.g. velocity/value)
extern uint8_t valueByte;
extern uint8_t capturedAddress;

void updateMidiBuffer(void);
7 changes: 7 additions & 0 deletions Source/io/midi_asm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

extern void asmEventMidiPB(void);
extern void asmEventMidiCC(void);
extern void asmEventMidiNote(void);
extern void asmEventMidiNoteOff(void);
extern void asmEventMidiPC(void);
51 changes: 37 additions & 14 deletions Source/mGBASMMidiFunctions.s → Source/io/midi_asm.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
.module mGBASMMidiFunctions
.module midi_asm
.optsdcc -msm83

.globl _addressByte
.globl _dataSet
.globl _noiEnv
.globl _noiSus
.globl _parameterLock
.globl _pbRange
.globl _pbWheelIn
.globl _playNoteNoi
.globl _playNotePoly
.globl _playNotePu1
.globl _playNotePu2
.globl _playNoteWav
.globl _pu1State
.globl _pu2State
.globl _statusByte
.globl _valueByte
.globl _vibratoDepth
.globl _vibratoSpeed
.globl _wavDataOffset
.globl _wavSus
.globl _wavSweepSpeed

_popReturn$::
ret
Expand All @@ -13,15 +36,15 @@ _asmEventMidiNote::
ld a,(#_statusByte)
AND #0x0F
cp #0x00
jp z,_asmPlayNotePu1;
jp z,_playNotePu1
cp #0x01
jp z,_asmPlayNotePu2$;
jp z,_playNotePu2
cp #0x02
jp z,_asmPlayNoteWav$;
jp z,_playNoteWav
cp #0x03
jp z,_asmPlayNoteNoi$;
jp z,_playNoteNoi
cp #0x04
jp z,_asmPlayNotePoly$;
jp z,_playNotePoly
ret

_asmEventMidiCC::
Expand Down Expand Up @@ -232,7 +255,7 @@ _asmPu1Env$::
RRCA
AND #0x0F

ld hl,#_pu1Env
ld hl,#_pu1State + 0
ld (hl),A

ld de,#_dataSet + 2
Expand Down Expand Up @@ -369,14 +392,14 @@ _asmPu1SusOn$::
ld A,#0x01
ld de,#_dataSet + 5
ld (de),A
ld hl,#_pu1Sus
ld hl,#_pu1State + 1
ld (hl),A
ret
_asmPu1SusOff$::
ld A,#0x00
ld de,#_dataSet + 5
ld (de),A
ld hl,#_pu1Sus
ld hl,#_pu1State + 1
ld (hl),A

ld hl,#_noteStatus + 0
Expand All @@ -393,7 +416,7 @@ ret
_asmPu1Nf$::
ld A,#0x00
ld (#0xFF12),A
ld hl,#_pu1Sus
ld hl,#_pu1State + 1
ld (hl),A
ld de,#_dataSet + 5
ld (de),A
Expand Down Expand Up @@ -463,7 +486,7 @@ _asmPu2Env$::
RRCA
AND #0x0F

ld hl,#_pu2Env
ld hl,#_pu2State + 0
ld (hl),A

ld de,#_dataSet + 9
Expand Down Expand Up @@ -583,14 +606,14 @@ _asmPu2SusOn$::
ld A,#0x01
ld de,#_dataSet + 11
ld (de),A
ld hl,#_pu2Sus
ld hl,#_pu2State + 1
ld (hl),A
ret
_asmPu2SusOff$::
ld A,#0x00
ld de,#_dataSet + 11
ld (de),A
ld hl,#_pu2Sus
ld hl,#_pu2State + 1
ld (hl),A

ld hl,#_noteStatus + 5
Expand All @@ -607,7 +630,7 @@ ret
_asmPu2Nf$::
ld A,#0x00
ld (#0xFF17),A
ld hl,#_pu2Sus
ld hl,#_pu2State + 1
ld (hl),A
ld de,#_dataSet + 11
ld (de),A
Expand Down
9 changes: 7 additions & 2 deletions Source/serial.c → Source/io/serial.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "mGB.h"
#include "serial.h"
#include "../mGB.h"
#include <gb/isr.h>

uint8_t serialBuffer[256];
uint8_t serialBufferPosition;
uint8_t serialBufferReadPosition;

void serial_isr(void) CRITICAL INTERRUPT {
serialBufferPosition++; // unsigned overflow from 255 -> 0 is automatic.
serialBuffer[serialBufferPosition] = rSB;
Expand All @@ -14,4 +19,4 @@ void serial_isr(void) CRITICAL INTERRUPT {
systemIdle = 0;
}

ISR_VECTOR(VECTOR_SERIAL, serial_isr)
ISR_VECTOR(VECTOR_SERIAL, serial_isr)
7 changes: 7 additions & 0 deletions Source/io/serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <gbdk/platform.h>

extern uint8_t serialBuffer[256];
extern uint8_t serialBufferPosition;
extern uint8_t serialBufferReadPosition;
Loading

0 comments on commit ed61a57

Please sign in to comment.