diff --git a/rtl/msx/msx_slots/mappers.sv b/rtl/msx/msx_slots/mappers.sv
index 92e7cbe..a227a33 100644
--- a/rtl/msx/msx_slots/mappers.sv
+++ b/rtl/msx/msx_slots/mappers.sv
@@ -213,6 +213,13 @@ module mappers (
.ocm_slot2_mode(ocm_slot2_mode)
);
+ mapper_out superSwangi_out();
+ mapper_superSwangi mapper_superSwangi (
+ .cpu_bus(cpu_bus),
+ .block_info(block_info),
+ .out(superSwangi_out)
+ );
+
assign data = fm_pac_out.data
& national_out.data
& mfrsd_out.data
@@ -237,7 +244,8 @@ module mappers (
& zemina90_out.addr
& mfrsd_out.addr
& ese_ram_out.addr
- & mega_ram_out.addr;
+ & mega_ram_out.addr
+ & superSwangi_out.addr;
assign memory_bus.rnw = offset_out.rnw
& mirror_out.rnw
@@ -271,7 +279,8 @@ module mappers (
| zemina90_out.ram_cs
| mfrsd_out.ram_cs
| ese_ram_out.ram_cs
- | mega_ram_out.ram_cs;
+ | mega_ram_out.ram_cs
+ | superSwangi_out.ram_cs;
assign memory_bus.sram_cs = ascii8_out.sram_cs
| ascii16_out.sram_cs
diff --git a/rtl/msx/msx_slots/mappers/files.qip b/rtl/msx/msx_slots/mappers/files.qip
index 847926e..f0398f6 100644
--- a/rtl/msx/msx_slots/mappers/files.qip
+++ b/rtl/msx/msx_slots/mappers/files.qip
@@ -18,3 +18,4 @@ set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) n
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) eseRam.sv ]
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) megaram.sv ]
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mirror.sv ]
+set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) superSwangi.sv ]
\ No newline at end of file
diff --git a/rtl/msx/msx_slots/mappers/superSwangi.sv b/rtl/msx/msx_slots/mappers/superSwangi.sv
new file mode 100644
index 0000000..1e91696
--- /dev/null
+++ b/rtl/msx/msx_slots/mappers/superSwangi.sv
@@ -0,0 +1,90 @@
+// Super Swangi mapper
+//
+// Copyright (c) 2025 Molekula
+//
+// All rights reserved
+//
+// Redistribution and use in source and synthezised forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in synthesized form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// * Neither the name of the author nor the names of other contributors may
+// be used to endorse or promote products derived from this software without
+// specific prior written agreement from the author.
+//
+// * License is granted for non-commercial use only. A fee may not be charged
+// for redistributions as source code or in synthesized/hardware form without
+// specific prior written agreement from the author.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+module mapper_superSwangi (
+ cpu_bus_if.device_mp cpu_bus, // Interface for CPU communication
+ mapper_out out, // Interface for mapper output
+ block_info block_info // Struct containing mapper configuration and parameters
+);
+
+ // Control signals for memory mapping
+ wire cs, we;
+
+ // Mapped if address is not in the lower or upper 16KB
+ wire mapped = ^cpu_bus.addr[15:14]; //0000-3fff & c000-ffff unmaped
+
+ assign cs = block_info.typ == MAPPER_SUPERSWANGI && cpu_bus.mreq && mapped;
+
+ // Bank registers for memory banking
+ logic [8:0] bank[0:1][2];
+ logic [7:0] block, nrBlocks, blockMask, blockRequest;
+ logic [8:0] blockCompute;
+
+ assign nrBlocks = block_info.rom_size[21:14];
+ assign blockMask = nrBlocks - 1'b1;
+
+ assign block = {1'b0,cpu_bus.data[7:1]} < nrBlocks ? {1'b0,cpu_bus.data[7:1]} : {1'b0,cpu_bus.data[7:1]} & blockMask;
+ assign blockCompute = block < nrBlocks ? {1'b0,block} : 9'h100;
+
+ // Bank switching logic
+ always @(posedge cpu_bus.clk) begin
+ if (cpu_bus.reset) begin
+ // Initialize bank values on reset
+ bank[0] <= '{9'h00, 9'h00};
+ bank[1] <= '{9'h00, 9'h00};
+ end else begin
+ if (cs && cpu_bus.wr && cpu_bus.req && cpu_bus.addr == 16'h8000) begin
+ bank[block_info.id][1] <= blockCompute;
+ end
+ end
+ end
+
+ // Calculate bank base and address mapping
+ wire [7:0] bank_base;
+ wire bank_unmaped;
+ wire [26:0] ram_addr;
+ assign {bank_unmaped, bank_base} = bank[block_info.id][cpu_bus.addr[15]];
+
+ assign ram_addr = {5'b0, bank_base, cpu_bus.addr[13:0]};
+
+ wire ram_valid = cs && ~bank_unmaped && cpu_bus.rd;
+
+ // Assign the final outputs for the mapper
+ assign out.ram_cs = ram_valid;
+ assign out.addr = ram_valid ? ram_addr : {27{1'b1}};
+
+endmodule
diff --git a/rtl/package.sv b/rtl/package.sv
index 8dc924e..44df609 100644
--- a/rtl/package.sv
+++ b/rtl/package.sv
@@ -12,6 +12,7 @@ typedef enum logic [5:0] {MAPPER_NONE, MAPPER_OFFSET, MAPPER_ASCII16, MAPPER_RTY
MAPPER_MEGARAM, MAPPER_MEGASCC, MAPPER_MEGAASCII8, MAPPER_MEGAASCII16,
MAPPER_TURBO_R_FDC,
MAPPER_YAMAHA_SFG,MAPPER_MIRROR,
+ MAPPER_SUPERSWANGI,
MAPPER_UNUSED} mapper_typ_t;
typedef enum logic [3:0] {BLOCK_RAM, BLOCK_ROM, BLOCK_SRAM, BLOCK_DEVICE, BLOCK_MAPPER, BLOCK_CART, BLOCK_REF_MEM, BLOCK_REF_DEV, BLOCK_IO_DEVICE, BLOCK_EXPANDER, BLOCK_REF_SHARED_MEM} block_t;
typedef enum logic [2:0] {CONF_BLOCK, CONF_DEVICE, CONF_LAYOUT, CONF_CARTRIGE, CONF_BLOCK_FW, CONF_UNUSED5, CONF_UNUSED6, CONF_END} conf_t;
diff --git a/tools/CreateMSXpack/Extension/CART_FW_EN.xml b/tools/CreateMSXpack/Extension/CART_FW_EN.xml
index 405cc5b..9ac4d15 100644
--- a/tools/CreateMSXpack/Extension/CART_FW_EN.xml
+++ b/tools/CreateMSXpack/Extension/CART_FW_EN.xml
@@ -136,6 +136,11 @@
LATCH_PORT
+
+
+ SUPERSWANGI
+
+
FM_PAC_EN.ROM
diff --git a/tools/CreateMSXpack/Extension/CART_FW_JP.xml b/tools/CreateMSXpack/Extension/CART_FW_JP.xml
index 8d37380..b2cb457 100644
--- a/tools/CreateMSXpack/Extension/CART_FW_JP.xml
+++ b/tools/CreateMSXpack/Extension/CART_FW_JP.xml
@@ -134,6 +134,11 @@
ZEMINA90
LATCH_PORT
+
+
+
+ SUPERSWANGI
+
diff --git a/tools/CreateMSXpack/cart_device.json b/tools/CreateMSXpack/cart_device.json
index e9de27d..ba90c2a 100644
--- a/tools/CreateMSXpack/cart_device.json
+++ b/tools/CreateMSXpack/cart_device.json
@@ -26,6 +26,7 @@
"ASCII16SRAM8": 34,
"ASCII8SRAM2": 35,
"ASCII8SRAM8": 36,
+ "SuperSwangi": 40,
"RTYPE": 49,
"ASCII8": 50,
"ASCII16": 51,
diff --git a/tools/CreateMSXpack/mapper.json b/tools/CreateMSXpack/mapper.json
index 60820ea..feaefeb 100644
--- a/tools/CreateMSXpack/mapper.json
+++ b/tools/CreateMSXpack/mapper.json
@@ -31,5 +31,6 @@
"MEGAASCII16" : 29,
"TURBO_R_FDC" : 30,
"YAMAHA_SFG" : 31,
- "MIRROR" : 32
+ "MIRROR" : 32,
+ "SUPERSWANGI" : 33
}