diff --git a/arch/ps2/CONFIG.PS2 b/arch/ps2/CONFIG.PS2
new file mode 100755
index 000000000..a48a1f1d6
--- /dev/null
+++ b/arch/ps2/CONFIG.PS2
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+[[ -z $PS2DEV ]] && { echo "\$PS2DEV is unset. Aborting"; exit 1; }
+
+./config.sh --platform ps2 --prefix $PS2DEV/ps2sdk/ee --optimize-size \
+            --disable-editor --disable-helpsys --disable-utils \
+            --enable-release --enable-meter --enable-extram \
+            --enable-stdio-redirect "$@"
diff --git a/arch/ps2/Makefile.in b/arch/ps2/Makefile.in
new file mode 100644
index 000000000..7b0df2ca8
--- /dev/null
+++ b/arch/ps2/Makefile.in
@@ -0,0 +1,32 @@
+ifeq ($(strip $(PS2DEV)),)
+$(error "PS2DEV must be set in your environment.")
+endif
+
+CROSS_COMPILE = mips64r5900el-ps2-elf-
+BINEXT := .elf
+
+# Disable rules that require target code to run natively.
+SUPPRESS_HOST_TARGETS ?= 1
+
+PS2_CFLAGS = -D_EE -D__PS2__
+PS2_INCLUDES = -isystem $(PS2DEV)/ps2sdk/common/include -isystem $(PS2DEV)/ps2sdk/ports/include
+PS2_LDFLAGS = -T$(PS2DEV)/ps2sdk/ee/startup/linkfile -L$(PS2DEV)/ps2sdk/ports/lib \
+              -L$(PS2DEV)/gsKit/lib -Wl,-zmax-page-size=128 -G0 -gdwarf-2 -gz
+
+SDL_CFLAGS = -isystem $(PS2DEV)/ps2sdk/ports/include/SDL2
+SDL_LDFLAGS = -lSDL2main -lSDL2 -lpatches -lgskit -ldmakit -lps2_drivers
+
+LIBPNG_CFLAGS =
+LIBPNG_LDFLAGS = -lpng16
+
+MIKMOD_CFLAGS =
+MIKMOD_LDFLAGS = -lmikmod
+
+ARCH_CFLAGS += ${PS2_CFLAGS} ${PS2_INCLUDES}
+ARCH_CXXFLAGS += ${PS2_CFLAGS} ${PS2_INCLUDES}
+ARCH_LDFLAGS += ${PS2_LDFLAGS}
+
+build: ${build}
+	${CP} arch/ps2/pad.config ${build}
+
+include arch/zip.inc
diff --git a/arch/ps2/README.md b/arch/ps2/README.md
new file mode 100644
index 000000000..a4f8fbc79
--- /dev/null
+++ b/arch/ps2/README.md
@@ -0,0 +1,14 @@
+# Building MegaZeux for PS2
+
+NOTE: Only tested on Linux.
+
+## Preparation
+
+You need to build or install the [ps2dev](https://github.com/ps2dev/ps2dev) toolchain.
+
+The toolchain comes with all MegaZeux dependencies pre-installed.
+
+## Configuration
+
+See CONFIG.PS2 for an optimal `config.sh' configure line. You need
+to ensure PS2DEV is defined and valid.
diff --git a/arch/ps2/pad.config b/arch/ps2/pad.config
new file mode 100644
index 000000000..fabdac314
--- /dev/null
+++ b/arch/ps2/pad.config
@@ -0,0 +1,42 @@
+# 1 Select
+# 2 L3
+# 3 R3
+# 4 Start
+# 5 Up
+# 6 Right
+# 7 Down
+# 8 Left
+# 9 L2
+# 10 R2
+# 11 L1
+# 12 R1
+# 13 Triangle
+# 14 Circle
+# 15 Cross
+# 16 Square
+
+joy[1,8]axis1 = act_l_left, act_l_right
+joy[1,8]axis2 = act_l_up, act_l_down
+joy[1,8]axis3 = act_r_left, act_r_right
+joy[1,8]axis4 = act_r_up, act_r_down
+joy[1,8].axis_lx = 1
+joy[1,8].axis_ly = 2
+joy[1,8].axis_rx = 3
+joy[1,8].axis_ry = 4
+
+joy[1,8]button1 = act_select
+joy[1,8]button2 = act_lstick
+joy[1,8]button3 = act_rstick
+joy[1,8]button4 = act_start
+joy[1,8]button5 = act_up
+joy[1,8]button6 = act_right
+joy[1,8]button7 = act_down
+joy[1,8]button8 = act_left
+joy[1,8]button9 = act_ltrigger
+joy[1,8]button10 = act_rtrigger
+joy[1,8]button11 = act_lshoulder
+joy[1,8]button12 = act_rshoulder
+joy[1,8]button13 = act_x
+joy[1,8]button14 = act_a
+joy[1,8]button15 = act_b
+joy[1,8]button16 = act_y
diff --git a/config.sh b/config.sh
index a13639f60..77c27e00d 100755
--- a/config.sh
+++ b/config.sh
@@ -31,6 +31,7 @@ usage() {
 	echo "  darwin         Mac OS X Unix-like install"
 	echo "  darwin-devel   Mac OS X running from current dir"
 	echo "  darwin-dist    Mac OS X (PPC .app builds -- use Xcode for Intel)"
+	echo "  ps2            Experimental PS2 port"
 	echo "  psp            Experimental PSP port"
 	echo "  gp2x           Experimental GP2X port"
 	echo "  nds            Experimental NDS port"
@@ -940,6 +941,19 @@ if [ "$PLATFORM" = "switch" ]; then
 	GAMECONTROLLERDB="false"
 fi
 
+#
+# If the PS2 arch is enabled, some code has to be compile time
+# enabled too.
+#
+if [ "$PLATFORM" = "ps2" ]; then
+	echo "Enabling PS2-specific hacks."
+	echo "#define CONFIG_PS2" >> src/config.h
+	echo "BUILD_PS2=1" >> platform.inc
+
+	echo "Force-disabling stack protector on PS2."
+	STACK_PROTECTOR="false"
+fi
+
 #
 # If the PSP arch is enabled, some code has to be compile time
 # enabled too.
@@ -1034,9 +1048,10 @@ if [ "$PLATFORM" = "pandora" ]; then
 fi
 
 #
-# Force-disable OpenGL and overlay renderers on PSP, GP2X, 3DS, NDS and Wii
+# Force-disable OpenGL and overlay renderers on PS2, PSP, GP2X, 3DS, NDS and Wii
 #
-if [ "$PLATFORM" = "psp" ] ||
+if [ "$PLATFORM" = "ps2" ] ||
+   [ "$PLATFORM" = "psp" ] ||
    [ "$PLATFORM" = "gp2x" ] ||
    [ "$PLATFORM" = "nds" ] ||
    [ "$PLATFORM" = "nds-blocksds" ] ||
@@ -1136,6 +1151,7 @@ if [ "$PLATFORM" = "gp2x" ] ||
    [ "$PLATFORM" = "switch" ] ||
    [ "$PLATFORM" = "android" ] ||
    [ "$PLATFORM" = "emscripten" ] ||
+   [ "$PLATFORM" = "ps2" ] ||
    [ "$PLATFORM" = "psp" ] ||
    [ "$PLATFORM" = "psvita" ] ||
    [ "$PLATFORM" = "djgpp" ] ||
@@ -1416,6 +1432,7 @@ if [ "$ICON" = "true" ]; then
 	   [ "$PLATFORM" = "darwin-devel" ] ||
 	   [ "$PLATFORM" = "darwin-dist" ] ||
 	   [ "$PLATFORM" = "gp2x" ] ||
+	   [ "$PLATFORM" = "ps2" ] ||
 	   [ "$PLATFORM" = "psp" ] ||
 	   [ "$PLATFORM" = "nds" ] ||
 	   [ "$PLATFORM" = "nds-blocksds" ] ||
diff --git a/docs/platform_matrix.html b/docs/platform_matrix.html
index 497357a47..1f2663f95 100644
--- a/docs/platform_matrix.html
+++ b/docs/platform_matrix.html
@@ -408,6 +408,32 @@
     loadsave_meter:   yes,
   },
 
+  ps2:
+  {
+    platform:         "ps2",
+    description:      "PlayStation 2",
+    architecture:     "MIPS (ELF)",
+    endian:           "Little",
+    toolchain:        "gcc 11.3.0 <br> binutils 2.38",
+    packaged:         ZIP,
+    stack_protector:  _FAULTY(),
+    layer_rendering:  yes,
+    module_engine:    xmp,
+    adlib_engine:     rad,
+    ogg_vorbis:       libvorbis,
+    optimization:     size,
+    sdl:              sdl2,
+    editor:           no_low_memory,
+    helpsys:          no_low_memory,
+    audio:            yes,
+    software:         yes,
+    network:          _FAULTY(),
+    updater:          no_updater,
+    png:              yes,
+    hashtables:       yes,
+    loadsave_meter:   yes,
+  },
+
   psp:
   {
     platform:         "psp",
diff --git a/src/configure.c b/src/configure.c
index 2956c29f3..69d3692e4 100644
--- a/src/configure.c
+++ b/src/configure.c
@@ -84,6 +84,14 @@
 #define SAVE_SLOTS_DEFAULT true
 #endif
 
+#ifdef CONFIG_PS2
+#define VIDEO_OUTPUT_DEFAULT "softscale"
+#define FULLSCREEN_WIDTH_DEFAULT 640
+#define FULLSCREEN_HEIGHT_DEFAULT 448
+#define FULLSCREEN_DEFAULT 1
+#define SAVE_SLOTS_DEFAULT true
+#endif
+
 #ifdef CONFIG_WII
 #define AUDIO_SAMPLE_RATE 48000
 #define FULLSCREEN_DEFAULT 1
diff --git a/src/event_sdl.c b/src/event_sdl.c
index 16608cb5e..02e132d55 100644
--- a/src/event_sdl.c
+++ b/src/event_sdl.c
@@ -1650,10 +1650,11 @@ void __warp_mouse(int x, int y)
 
 void initialize_joysticks(void)
 {
-#if !SDL_VERSION_ATLEAST(2,0,0) || defined(CONFIG_SWITCH) || defined(CONFIG_PSVITA)
+#if !SDL_VERSION_ATLEAST(2,0,0) || defined(CONFIG_SWITCH) || defined(CONFIG_PSVITA) \
+ || defined(CONFIG_PS2)
   // SDL 1.2 doesn't have joystick added/removed events.
-  // Switch SDL doesn't seem to generate these events at all on startup. The vita
-  // appears to have the same issue.
+  // Switch SDL doesn't seem to generate these events at all on startup. The Vita
+  // and PS2 appear to have the same issue.
   int i, count;
 
   count = SDL_NumJoysticks();
diff --git a/src/io/zip.c b/src/io/zip.c
index a92bed0af..e00a23041 100644
--- a/src/io/zip.c
+++ b/src/io/zip.c
@@ -51,7 +51,7 @@
 // DJGPP may be running on exceptionally slow hardware.
 
 #if defined(CONFIG_NDS) || defined(CONFIG_3DS) || defined(CONFIG_SWITCH) || \
- defined(CONFIG_PSVITA) || defined(CONFIG_DJGPP)
+ defined(CONFIG_PSVITA) || defined(CONFIG_DJGPP) || defined(CONFIG_PS2)
 #define ZIP_WRITE_DATA_DESCRIPTOR
 #endif