Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Nintendo DS port #4

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,19 @@ jobs:
with:
name: arcem-${{ matrix.amiga.host }}
path: ./arcem

build-nds:
name: Nintendo DS
runs-on: ubuntu-latest
container: devkitpro/devkitarm:20241104

steps:
- uses: actions/checkout@v3
- name: Configure
run: $DEVKITPRO/portlibs/nds/bin/arm-none-eabi-cmake -B build/ -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} .
- name: Build
run: cmake --build build/ --config ${{env.BUILD_TYPE}} --parallel
- uses: actions/upload-artifact@v3
with:
name: arcem-nds
path: ./build/ArcEm.nds
59 changes: 57 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ set(ARCEM_X_SOURCES
X/pseudo.c
X/true.c
)
set(ARCEM_NDS_SOURCES
nds/ControlPane.c
nds/ControlPane.h
nds/DispKbd.c
nds/filecalls.c
nds/filecalls_internal.h
nds/KeyTable.h
nds/main.c
)
set(ARCEM_VC_SOURCES
vc/dirent.h
)
Expand All @@ -83,16 +92,25 @@ set(ARCEM_WIN_SOURCES
win/win.c
win/win.h
)
set(ARCEM_EXTNROM_MODULES
support_modules/hostfs/hostfs,ffa
support_modules/hostfs/hostfsfiler,ffa
support_modules/modes/ArcemModes,ffa
support_modules/scrollwheel/scrollwheel,ffa
support_modules/support/support,ffa
)

if(WIN32)
set(DEFAULT_SYSTEM "win")
elseif(NINTENDO_DS)
set(DEFAULT_SYSTEM "nds")
elseif(UNIX AND NOT APPLE AND NOT HAIKU)
set(DEFAULT_SYSTEM "X")
else()
set(DEFAULT_SYSTEM "SDL2")
endif()
set(SYSTEM ${DEFAULT_SYSTEM} CACHE STRING "System to compile for. Options: X SDL2 SDL1 win")
set_property(CACHE SYSTEM PROPERTY STRINGS X SDL2 SDL1 win)
set(SYSTEM ${DEFAULT_SYSTEM} CACHE STRING "System to compile for. Options: X SDL2 SDL1 nds win")
set_property(CACHE SYSTEM PROPERTY STRINGS X SDL2 SDL1 nds win)

option(EXTNROM_SUPPORT "Build with Extension ROM support" ON)
if(EXTNROM_SUPPORT)
Expand Down Expand Up @@ -146,6 +164,23 @@ elseif(${SYSTEM} STREQUAL "X")
find_package(Threads REQUIRED)
target_link_libraries(Threads::Threads)
endif()
elseif(${SYSTEM} STREQUAL "nds")
add_executable(arcem ${ARCEM_SOURCES} ${ARCEM_ARCH_SOURCES} ${ARCEM_INIH_SOURCES} ${ARCEM_NDS_SOURCES})
target_include_directories(arcem PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/nds)
target_compile_definitions(arcem PRIVATE SYSTEM_nds USE_FAKEMAIN NO_OPEN64)

target_compile_options(arcem PRIVATE -mthumb -mthumb-interwork)
target_link_options(arcem PRIVATE -Wl,--gc-sections -mthumb -mthumb-interwork)

grit_add_binary_target(bg nds/img/bg.png)
grit_add_binary_target(font nds/img/font.png NO_MAP)
grit_add_binary_target(keys nds/img/keys.png NO_MAP)
dkp_add_embedded_binary_library(grit_data bg font keys)
target_link_libraries(arcem PRIVATE grit_data filesystem fat)

if(CALICO_ROOT)
target_compile_definitions(arcem PRIVATE -D__CALICO__)
endif()
elseif(${SYSTEM} STREQUAL "win")
option(SOUND_SUPPORT "Build with sound support" ON)
if(SOUND_SUPPORT)
Expand All @@ -169,6 +204,25 @@ elseif(APPLE)
OUTPUT_NAME "ArcEm"
MACOSX_BUNDLE TRUE
)
elseif(NINTENDO_DS)
file(COPY ${ARCEM_EXTNROM_MODULES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/nitrofs/extnrom)
set_target_properties(arcem PROPERTIES OUTPUT_NAME "ArcEm")
if(CALICO_ROOT)
nds_create_rom(arcem
ARM7 lykoi
SUBTITLE1 "Archimedes Emulator"
SUBTITLE2 "WIP using Calico"
ICON nds/arc.bmp
NITROFS ${CMAKE_CURRENT_BINARY_DIR}/nitrofs
)
else()
nds_create_rom(arcem
SUBTITLE1 "Archimedes Emulator"
SUBTITLE2 "WIP"
ICON nds/arc.bmp
NITROFS ${CMAKE_CURRENT_BINARY_DIR}/nitrofs
)
endif()
endif()

target_include_directories(arcem PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/arch)
Expand All @@ -194,6 +248,7 @@ source_group(src FILES ${ARCEM_SOURCES})
source_group(src\\arch FILES ${ARCEM_ARCH_SOURCES})
source_group(src\\X FILES ${ARCEM_X_SOURCES})
source_group(src\\SDL FILES ${ARCEM_SDL_SOURCES})
source_group(src\\nds FILES ${ARCEM_NDS_SOURCES})
source_group(src\\vc FILES ${ARCEM_VC_SOURCES})
source_group(src\\win FILES ${ARCEM_WIN_SOURCES})
source_group(libs\\inih FILES ${ARCEM_INIH_SOURCES})
11 changes: 10 additions & 1 deletion arch/ArcemConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ void ArcemConfig_SetupDefaults(ArcemConfig *pConfig)

#if defined(EXTNROM_SUPPORT)
/* The default directory is extnrom in the current working directory */
#ifdef SYSTEM_nds
pConfig->sEXTNDirectory = arcemconfig_StringDuplicate("nitro:/extnrom");
#else
pConfig->sEXTNDirectory = arcemconfig_StringDuplicate("extnrom");
#endif
/* If we've run out of memory this early, something is very wrong */
if(NULL == pConfig->sEXTNDirectory) {
ControlPane_Error(EXIT_FAILURE,"Failed to allocate memory for initial configuration. Please free up more memory.\n");
Expand Down Expand Up @@ -239,6 +243,7 @@ void ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc, char *argv[])
{
unsigned int uValue;
int iArgument = 0;
#ifndef SYSTEM_nds
char sHelpString[] =
"Arcem <Options>\n"
" Where options are one or more of the following\n"
Expand Down Expand Up @@ -270,6 +275,7 @@ void ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc, char *argv[])
" --menukeys <a> <b> - Specify which key numbers open the tweak menu\n"
#endif /* SYSTEM_riscos_single */
;
#endif

/* No commandline arguments? */
if(0 == argc) {
Expand All @@ -290,6 +296,7 @@ void ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc, char *argv[])
iArgument = 1;

while(iArgument < argc) {
#ifndef SYSTEM_nds
if(0 == strcmp("--version", argv[iArgument])) {
printf("Arcem %s\n", Version);

Expand All @@ -300,7 +307,9 @@ void ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc, char *argv[])

exit(EXIT_SUCCESS);
}
else if(0 == strcmp("--config", argv[iArgument])) {
else
#endif
if(0 == strcmp("--config", argv[iArgument])) {
if(iArgument+1 < argc) { /* Is there a following argument? */
ini_parse(argv[iArgument + 1], ArcemConfig_Handler, pConfig);
iArgument += 2;
Expand Down
17 changes: 17 additions & 0 deletions arch/dbugsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef _DBUGSYS_H_
#define _DBUGSYS_H_

#include "c99.h"
#include <stdio.h>
#include <stdarg.h>

Expand All @@ -26,6 +27,21 @@
#undef DEBUG_HDC63463
#undef DEBUG_CONFIG

#if defined(SYSTEM_nds) && defined(NDEBUG)
#undef IOC_WARN
#undef WARN
#undef WARN_MEMC
#undef WARN_I2C
#undef WARN_DATA
#undef WARN_DMAWRITE
#undef WARN_DMAREAD
#undef WARN_INTS
#undef WARN_VIDC
#undef WARN_KEYBOARD
#undef WARN_FDC1772
#undef WARN_HDC63463
#undef WARN_CONFIG
#else
#define IOC_WARN
#define WARN
#define WARN_MEMC
Expand All @@ -39,6 +55,7 @@
#define WARN_FDC1772
#define WARN_HDC63463
#define WARN_CONFIG
#endif

#define dbug_stdout printf

Expand Down
109 changes: 105 additions & 4 deletions arch/paldisplaydev.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@
void PDD_Name(Host_EndUpdate)(ARMul_State *state,PDD_Row *row)
- End updating the region of the row

ARMword *PDD_Name(Host_TransferUpdate)(ARMul_State *state,PDD_Row *row,
unsigned int count,const ARMword *src)
- Write 'count' bits of the row to the screen.
- 'count' will always be a multiple of 32.
- This is only used in DS builds at the moment.

void PDD_Name(Host_AdvanceRow)(ARMul_State *state,PDD_Row *row,
unsigned int count)
- Advance the row pointer by 'count' bits
Expand Down Expand Up @@ -211,7 +217,8 @@ struct PDD_Name(DisplayInfo) {

#define ROWFUNC_FORCE 0x1 /* Force row to be fully redrawn */
#define ROWFUNC_UPDATED 0x2 /* Flag used to indicate whether anything was done */
#define ROWFUNC_UNALIGNED 0x4 /* Flag that gets set if we know we can't use the byte-aligned rowfuncs */
#define ROWFUNC_UNALIGNED_BYTE 0x4 /* Flag that gets set if we know we can't use the byte-aligned rowfuncs */
#define ROWFUNC_UNALIGNED_WORD 0x8 /* Flag that gets set if we know we can't use the word-aligned rowfuncs */

/*

Expand Down Expand Up @@ -303,6 +310,51 @@ static inline int PDD_Name(RowFunc1XSameByteAligned)(ARMul_State *state,PDD_Row
return (flags & ROWFUNC_UPDATED);
}

static inline int PDD_Name(RowFunc1XSameWordAligned)(ARMul_State *state,PDD_Row drow,int flags)
{
uint32_t Vptr = DC.Vptr>>5;
uint32_t Vstart = MEMC.Vstart<<2;
uint32_t Vend = (MEMC.Vend+1)<<2; /* Point to pixel after end */
const ARMword *RAM = MEMC.PhysRam;
int Remaining = DC.BitWidth>>5;

/* Sanity checks to avoid looping forever */
if((Vptr >= Vend) || (Vstart >= Vend))
return 0;
if(Vptr >= Vend)
Vptr = Vstart;

/* Process the row */
while(Remaining > 0)
{
uint32_t FlagsOffset = Vptr/(UPDATEBLOCKSIZE/4);
int Available = MIN(Remaining,MIN(((FlagsOffset+1)*(UPDATEBLOCKSIZE/4))-Vptr,Vend-Vptr));

if((flags & ROWFUNC_FORCE) || (HD.UpdateFlags[FlagsOffset] != MEMC.UpdateFlags[FlagsOffset]))
{
/* Process the pixels in this region, stopping at end of row/update block/Vend */
#ifndef SYSTEM_nds
int outoffset;
ARMword *out = PDD_Name(Host_BeginUpdate)(state,&drow,Available<<5,&outoffset);
EndianWordCpy(out+(outoffset>>5),RAM+Vptr,Available);
PDD_Name(Host_EndUpdate)(state,&drow);
#else
PDD_Name(Host_TransferUpdate)(state,&drow,Available<<5,RAM+Vptr);
#endif
flags |= ROWFUNC_UPDATED;
}
PDD_Name(Host_AdvanceRow)(state,&drow,Available<<5);
Vptr += Available;
Remaining -= Available;
if(Vptr >= Vend)
Vptr = Vstart;
}

DC.Vptr = Vptr<<5;

return (flags & ROWFUNC_UPDATED);
}

/*

Row output via ExpandTable
Expand Down Expand Up @@ -430,6 +482,45 @@ static inline void PDD_Name(RowFunc1XSameByteAlignedNoFlags)(ARMul_State *state,
DC.Vptr = Vptr<<3;
}

static inline void PDD_Name(RowFunc1XSameWordAlignedNoFlags)(ARMul_State *state,PDD_Row drow)
{
uint32_t Vptr = DC.Vptr>>5;
uint32_t Vstart = MEMC.Vstart<<2;
uint32_t Vend = (MEMC.Vend+1)<<2; /* Point to pixel after end */
const ARMword *RAM = MEMC.PhysRam;
int Remaining = DC.BitWidth>>5;

/* Sanity checks to avoid looping forever */
if((Vptr >= Vend) || (Vstart >= Vend))
return;
if(Vptr >= Vend)
Vptr = Vstart;

/* Process the row */
while(Remaining > 0)
{
int Available = MIN(Remaining,Vend-Vptr);

/* Process the pixels in this region, stopping at end of row/update block/Vend */
#ifndef SYSTEM_nds
int outoffset;
ARMword *out = PDD_Name(Host_BeginUpdate)(state,&drow,Available<<5,&outoffset);
EndianWordCpy(out+(outoffset>>5),RAM+Vptr,Available);
PDD_Name(Host_EndUpdate)(state,&drow);
#else
PDD_Name(Host_TransferUpdate)(state,&drow,Available<<5,RAM+Vptr);
#endif

PDD_Name(Host_AdvanceRow)(state,&drow,Available<<5);
Vptr += Available;
Remaining -= Available;
if(Vptr >= Vend)
Vptr = Vstart;
}

DC.Vptr = Vptr<<5;
}

/*

Row output via ExpandTable
Expand Down Expand Up @@ -708,7 +799,9 @@ static void PDD_Name(EventFunc)(ARMul_State *state,CycleCount nowtime)
/* We can test these values once here, so that it's only output alignment
that we need to worry about during the loop */
if((DC.Vptr & 0x7) || ((Width*BPP)&0x7))
flags |= ROWFUNC_UNALIGNED;
flags |= ROWFUNC_UNALIGNED_WORD | ROWFUNC_UNALIGNED_BYTE;
else if((DC.Vptr & 0x31) || ((Width*BPP)&0x31))
flags |= ROWFUNC_UNALIGNED_WORD;

if(DisplayDev_UseUpdateFlags)
{
Expand All @@ -732,7 +825,11 @@ static void PDD_Name(EventFunc)(ARMul_State *state,CycleCount nowtime)
{
updated = PDD_Name(RowFuncExpandTable)(state,hrow,flags);
}
else if(!(flags & ROWFUNC_UNALIGNED) && !(alignment & 0x7))
else if(!(flags & ROWFUNC_UNALIGNED_WORD) && !(alignment & 0x31))
{
updated = PDD_Name(RowFunc1XSameWordAligned)(state,hrow,flags);
}
else if(!(flags & ROWFUNC_UNALIGNED_BYTE) && !(alignment & 0x7))
{
updated = PDD_Name(RowFunc1XSameByteAligned)(state,hrow,flags);
}
Expand Down Expand Up @@ -783,7 +880,11 @@ static void PDD_Name(EventFunc)(ARMul_State *state,CycleCount nowtime)
{
PDD_Name(RowFuncExpandTableNoFlags)(state,hrow);
}
else if(!(flags & ROWFUNC_UNALIGNED) && !(alignment & 0x7))
else if(!(flags & ROWFUNC_UNALIGNED_WORD) && !(alignment & 0x31))
{
PDD_Name(RowFunc1XSameWordAlignedNoFlags)(state,hrow);
}
else if(!(flags & ROWFUNC_UNALIGNED_BYTE) && !(alignment & 0x7))
{
PDD_Name(RowFunc1XSameByteAlignedNoFlags)(state,hrow);
}
Expand Down
2 changes: 1 addition & 1 deletion armdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ struct ARMul_State {

};

#ifdef AMIGA
#if defined(AMIGA) || defined(SYSTEM_nds)
extern void *state_alloc(int s);
extern void state_free(void *p);
#else
Expand Down
18 changes: 18 additions & 0 deletions c99.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,22 @@ typedef unsigned char bool;
#define inline __inline
#endif

#ifdef SYSTEM_nds
/* Use integer only versions of printf and scanf to reduce the executable size */
#include <stdio.h>

#define printf iprintf
#define fprintf fiprintf
#define sprintf siprintf
#define snprintf sniprintf

#define vprintf viprintf
#define vfprintf vfiprintf
#define vsprintf vsiprintf
#define vsnprintf vsniprintf

#define sscanf siscanf
#define fscanf fiscanf
#endif

#endif
Loading
Loading