From cfb5b332f008770b323fbb708a17c2547a4b5d4c Mon Sep 17 00:00:00 2001
From: Cacodemon345 <wahil1976@outlook.com>
Date: Thu, 30 May 2024 15:33:01 +0600
Subject: [PATCH] Mem recalcs and IO

---
 src/include/86box/pcmcia.h        |   6 ++
 src/pcmcia/pcmcia_socket_pd6710.c | 172 ++++++++++++++++++++++++++++++
 2 files changed, 178 insertions(+)

diff --git a/src/include/86box/pcmcia.h b/src/include/86box/pcmcia.h
index 7030438952..87331f9294 100644
--- a/src/include/86box/pcmcia.h
+++ b/src/include/86box/pcmcia.h
@@ -28,6 +28,12 @@ struct pcmcia_socket_t {
     /* Signals card insertion/removal to the socket. */
     void (*card_inserted)(bool inserted, pcmcia_socket_t* socket);
 
+    /* Signals STSCHG to the socket. */
+    void (*status_changed)(bool status, pcmcia_socket_t* socket);
+
+    /* Signals READY to the socket. */
+    void (*ready_changed)(bool ready, pcmcia_socket_t* socket);
+
     /* Opaque pointer to card-specific information. */
     void *card_priv;
 
diff --git a/src/pcmcia/pcmcia_socket_pd6710.c b/src/pcmcia/pcmcia_socket_pd6710.c
index 1d5ec96a67..4d87cdd500 100644
--- a/src/pcmcia/pcmcia_socket_pd6710.c
+++ b/src/pcmcia/pcmcia_socket_pd6710.c
@@ -1,4 +1,5 @@
 
+/* TODO: Dual-socket PD6722. */
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdbool.h>
@@ -40,7 +41,21 @@ typedef struct pd67xx_memory_map
 
 typedef struct pcmcia_socket_pd67xx
 {
+    uint8_t index;
+
     uint8_t chip_rev;
+    union
+    {
+        uint8_t interface_status;
+        struct {
+            uint8_t bvd : 2;
+            uint8_t cd : 2;
+            uint8_t wp : 1;
+            uint8_t ready : 1;
+            uint8_t power_on : 1;
+            uint8_t vpp_valid : 1;
+        };
+    };
     uint8_t power_control;
     uint8_t interrupt_general_control;
     uint8_t card_status;
@@ -56,6 +71,24 @@ typedef struct pcmcia_socket_pd67xx
     pcmcia_socket_t socket;
 } pcmcia_socket_pd67xx;
 
+void pd67xx_mem_recalc(pd67xx_memory_map* mem_map)
+{
+    mem_mapping_disable(&mem_map->mapping);
+    if (mem_map->main_ptr->mapping_enable & (1 << mem_map->map_num)) {
+        uint32_t start = mem_map->start.addr << 12;
+        uint32_t end = (mem_map->end.addr & 0x3fff) << 12;
+
+        if (start < (16 << 12)) {
+            start = (16 << 12);
+        }
+
+        if (end < start)
+            return;
+        
+        mem_mapping_set_addr(&mem_map->mapping, start, (end - start) + 4096);
+    }
+}
+
 uint8_t pd67xx_mem_read(uint32_t addr, void* priv)
 {
     pd67xx_memory_map* pd67xx_mem_map = (pd67xx_memory_map*)priv;
@@ -125,3 +158,142 @@ void pd67xx_mem_writew(uint32_t addr, uint16_t val, void* priv)
     addr &= 0x3FFFFFF;
     return pd67xx->socket.mem_writew(addr, val, !(pd67xx_mem_map->offset.addr & (1 << 14)), pd67xx->socket.card_priv);
 }
+
+uint8_t pd67xx_io_read_1(uint16_t port, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return 0xFF;
+
+    if (!pd67xx->socket.io_read)
+        return 0xFF;
+
+    port += pd67xx->io_offsets[0];
+    return pd67xx->socket.io_read(port, pd67xx->socket.card_priv);
+}
+
+uint16_t pd67xx_io_readw_1(uint16_t port, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return 0xFF;
+
+    if (!pd67xx->socket.io_read)
+        return 0xFF;
+
+    port += pd67xx->io_offsets[0];
+    return pd67xx->socket.io_readw(port, pd67xx->socket.card_priv);
+}
+
+void pd67xx_io_write_1(uint16_t port, uint8_t val, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return;
+
+    if (!pd67xx->socket.io_write)
+        return;
+
+    port += pd67xx->io_offsets[0];
+    return pd67xx->socket.io_write(port, val, pd67xx->socket.card_priv);
+}
+
+void pd67xx_io_writew_1(uint16_t port, uint16_t val, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return;
+
+    if (!pd67xx->socket.io_writew)
+        return;
+
+    port += pd67xx->io_offsets[0];
+    return pd67xx->socket.io_write(port, val, pd67xx->socket.card_priv);
+}
+
+uint8_t pd67xx_io_read_2(uint16_t port, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return 0xFF;
+
+    if (!pd67xx->socket.io_read)
+        return 0xFF;
+
+    port += pd67xx->io_offsets[1];
+    return pd67xx->socket.io_read(port, pd67xx->socket.card_priv);
+}
+
+uint16_t pd67xx_io_readw_2(uint16_t port, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return 0xFF;
+
+    if (!pd67xx->socket.io_read)
+        return 0xFF;
+
+    port += pd67xx->io_offsets[1];
+    return pd67xx->socket.io_readw(port, pd67xx->socket.card_priv);
+}
+
+void pd67xx_io_write_2(uint16_t port, uint8_t val, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return;
+
+    if (!pd67xx->socket.io_write)
+        return;
+
+    port += pd67xx->io_offsets[1];
+    return pd67xx->socket.io_write(port, val, pd67xx->socket.card_priv);
+}
+
+void pd67xx_io_writew_2(uint16_t port, uint16_t val, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!pd67xx->socket.card_priv)
+        return;
+
+    if (!pd67xx->socket.io_writew)
+        return;
+
+    port += pd67xx->io_offsets[1];
+    return pd67xx->socket.io_write(port, val, pd67xx->socket.card_priv);
+}
+
+void pd67xx_port_write(uint16_t port, uint8_t val, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!(port & 1))
+        pd67xx->index = val;
+    else {
+
+    }
+}
+
+uint8_t pd67xx_port_read(uint16_t port, void* priv)
+{
+    pcmcia_socket_pd67xx* pd67xx = priv;
+
+    if (!(port & 1))
+        return pd67xx->index;
+    else {
+        switch (pd67xx->index) {
+            case 0x00:
+                return 0b10000010;
+            default:
+                return 0xFF;
+        }
+    }
+}