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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,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@v4
with:
name: arcem-nds
path: ./build/ArcEm.nds
50 changes: 48 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ set(ARCEM_MACOSX_RESOURCES
macosx/en.lproj/MainMenu.xib
macosx/en.lproj/Preferences.xib
)
set(ARCEM_NDS_SOURCES
nds/ControlPane.c
nds/ControlPane.h
nds/DispKbd.c
nds/filecalls.c
nds/KeyTable.h
nds/main.c
)
set(ARCEM_VC_SOURCES
vc/dirent.h
)
Expand All @@ -124,13 +132,15 @@ if(WIN32)
set(DEFAULT_SYSTEM "win")
elseif(APPLE)
set(DEFAULT_SYSTEM "macosx")
elseif(NINTENDO_DS)
set(DEFAULT_SYSTEM "nds")
elseif(UNIX 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 SDL3 SDL2 SDL1 macosx win")
set_property(CACHE SYSTEM PROPERTY STRINGS X SDL3 SDL2 SDL1 macosx win)
set(SYSTEM ${DEFAULT_SYSTEM} CACHE STRING "System to compile for. Options: X SDL3 SDL2 SDL1 macosx nds win")
set_property(CACHE SYSTEM PROPERTY STRINGS X SDL3 SDL2 SDL1 macosx nds win)

if(${SYSTEM} MATCHES "^(SDL[123])$")
add_executable(arcem WIN32 ${ARCEM_SOURCES} ${ARCEM_ARCH_SOURCES} ${ARCEM_SDL_SOURCES} ${ARCEM_EXTNROM_MODULES})
Expand Down Expand Up @@ -197,6 +207,22 @@ elseif(${SYSTEM} STREQUAL "macosx")

target_compile_definitions(arcem PRIVATE SOUND_SUPPORT)
endif()
elseif(${SYSTEM} STREQUAL "nds")
add_executable(arcem ${ARCEM_SOURCES} ${ARCEM_ARCH_SOURCES} ${ARCEM_NDS_SOURCES} ${ARCEM_EXTNROM_MODULES})
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")
add_executable(arcem WIN32 ${ARCEM_SOURCES} ${ARCEM_ARCH_SOURCES} ${ARCEM_WIN_SOURCES} ${ARCEM_EXTNROM_MODULES})
target_compile_definitions(arcem PRIVATE SYSTEM_win)
Expand Down Expand Up @@ -251,6 +277,25 @@ elseif(APPLE)

set(CPACK_GENERATOR "DragNDrop")
include(CPack)
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()

option(EXTNROM_SUPPORT "Build with Extension ROM support" ON)
Expand Down Expand Up @@ -292,6 +337,7 @@ source_group(src\\X FILES ${ARCEM_X_SOURCES})
source_group(src\\SDL FILES ${ARCEM_SDL_SOURCES})
source_group(src\\macosx FILES ${ARCEM_MACOSX_SOURCES})
source_group(src\\macosx FILES ${ARCEM_MACOSX_RESOURCES})
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})
Expand Down
7 changes: 6 additions & 1 deletion arch/ArcemConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ ArcemConfig_Result ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc,
{
unsigned int uValue;
int iArgument = 0;
#ifndef SYSTEM_nds
static const char sVersionString[] =
"Arcem Version " VER_STRING " (" RELEASE_DATE ")\n";
static const char sHelpString[] =
Expand Down Expand Up @@ -307,6 +308,7 @@ ArcemConfig_Result ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc,
" --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 @@ -327,6 +329,7 @@ ArcemConfig_Result ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc,
iArgument = 1;

while(iArgument < argc) {
#ifndef SYSTEM_nds
if(0 == strcmp("--version", argv[iArgument])) {
printf("%s", sVersionString);
return Result_Success;
Expand All @@ -335,7 +338,9 @@ ArcemConfig_Result ArcemConfig_ParseCommandLine(ArcemConfig *pConfig, int argc,
printf("%s", sHelpString);
return Result_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
18 changes: 18 additions & 0 deletions arch/dbugsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@
#undef DEBUG_CONFIG
#undef DEBUG_HOSTFS

#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_SOUND
#undef WARN_KEYBOARD
#undef WARN_FDC1772
#undef WARN_HDC63463
#undef WARN_CONFIG
#undef WARN_HOSTFS
#else
#define IOC_WARN
#define WARN
#define WARN_MEMC
Expand All @@ -45,6 +62,7 @@
#define WARN_HDC63463
#define WARN_CONFIG
#define WARN_HOSTFS
#endif

#define LOG_DBUG 1
#define LOG_INFO 2
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 @@ -212,7 +218,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 @@ -304,6 +311,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;
unsigned 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);
unsigned 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 @@ -431,6 +483,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;
unsigned 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)
{
unsigned 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 @@ -499,7 +590,11 @@ static void PDD_Name(FrameFunc)(ARMul_State *state,int Height,int flags)
{
updated = PDD_Name(RowFuncExpandTable)(state,hrow,flags);
}
else if(!(flags & ROWFUNC_UNALIGNED) && !(alignment & 0x7))
else if(!(flags & ROWFUNC_UNALIGNED_WORD) && !(alignment & 0x3f))
{
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 @@ -548,7 +643,11 @@ static void PDD_Name(FrameFuncNoFlags)(ARMul_State *state,int Height,int flags)
{
PDD_Name(RowFuncExpandTableNoFlags)(state,hrow);
}
else if(!(flags & ROWFUNC_UNALIGNED) && !(alignment & 0x7))
else if(!(flags & ROWFUNC_UNALIGNED_WORD) && !(alignment & 0x3f))
{
PDD_Name(RowFunc1XSameWordAlignedNoFlags)(state,hrow);
}
else if(!(flags & ROWFUNC_UNALIGNED_BYTE) && !(alignment & 0x7))
{
PDD_Name(RowFunc1XSameByteAlignedNoFlags)(state,hrow);
}
Expand Down Expand Up @@ -802,7 +901,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 & 0x3f) || ((Width*BPP)&0x3f))
flags |= ROWFUNC_UNALIGNED_WORD;

if(DisplayDev_UseUpdateFlags)
{
Expand Down
2 changes: 1 addition & 1 deletion armdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ struct ARMul_State {
#endif
};

#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 @@ -117,4 +117,22 @@ typedef unsigned char bool;
#define MSVC_PRINTF
#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