Tuesday, 12 October 2021

[Rpcemu] [PATCH 3/4] Add disc format abstraction layer

diff -r 592604520b7e -r ca4be2ca9a9a src/ArmDynarec.c
--- a/src/ArmDynarec.c    Sat Oct 09 14:01:30 2021 +0100
+++ b/src/ArmDynarec.c    Sat Oct 09 17:23:31 2021 +0100
@@ -48,7 +48,7 @@
 #include "arm.h"
 #include "cp15.h"
 #include "fdc.h"
-#include "disc_adf.h"
+#include "disc.h"
 
 #if defined __amd64__
 #    include "codegen_amd64.h"
diff -r 592604520b7e -r ca4be2ca9a9a src/arm.c
--- a/src/arm.c    Sat Oct 09 14:01:30 2021 +0100
+++ b/src/arm.c    Sat Oct 09 17:23:31 2021 +0100
@@ -54,7 +54,7 @@
 #include "keyboard.h"
 #include "fdc.h"
 #include "ide.h"
-#include "disc_adf.h"
+#include "disc.h"
 
 ARMState arm;
 
diff -r 592604520b7e -r ca4be2ca9a9a src/disc.c
--- /dev/null    Thu Jan 01 00:00:00 1970 +0000
+++ b/src/disc.c    Sat Oct 09 17:23:31 2021 +0100
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <string.h>
+#include "rpcemu.h"
+#include "disc.h"
+#include "disc_adf.h"
+#include "fdc.h"
+
+disc_funcs *drive_funcs[2];
+
+static int disc_drivesel = 0;
+static int disc_notfound = 0;
+static int current_track[2] = {0, 0};
+
+void
+disc_set_drivesel(int drive)
+{
+    disc_drivesel = drive;
+}
+
+int
+disc_empty(int drive)
+{
+    return !drive_funcs[drive];
+}
+
+void
+disc_poll(void)
+{
+        if (!disc_empty(disc_drivesel)) {
+                if (drive_funcs[disc_drivesel] && drive_funcs[disc_drivesel]->poll)
+                        drive_funcs[disc_drivesel]->poll();
+                if (disc_notfound) {
+                        disc_notfound--;
+                        if (!disc_notfound)
+                                fdc_notfound();
+                }
+        }
+}
+
+int disc_get_current_track(int drive)
+{
+        return current_track[drive];
+}
+
+void disc_seek(int drive, int track)
+{
+        if (drive_funcs[drive] && drive_funcs[drive]->seek)
+                drive_funcs[drive]->seek(drive, track);
+//        if (track != oldtrack[drive] && !disc_empty(drive))
+//                ioc_discchange_clear(drive);
+
+        current_track[drive] = track;
+}
+
+void
+disc_readsector(int drive, int sector, int track, int side, int density)
+{
+        if (drive_funcs[drive] && drive_funcs[drive]->readsector)
+        drive_funcs[drive]->readsector(drive, sector, track, side, density);
+        else
+        disc_notfound = 10000;
+}
+
+void
+disc_writesector(int drive, int sector, int track, int side, int density)
+{
+        if (drive_funcs[drive] && drive_funcs[drive]->writesector)
+        drive_funcs[drive]->writesector(drive, sector, track, side, density);
+        else
+        disc_notfound = 10000;
+}
+
+void
+disc_readaddress(int drive, int track, int side, int density)
+{
+        if (drive_funcs[drive] && drive_funcs[drive]->readaddress)
+        drive_funcs[drive]->readaddress(drive, track, side, density);
+        else
+        disc_notfound = 10000;
+}
+
+void
+disc_format(int drive, int track, int side, int density)
+{
+        if (drive_funcs[drive] && drive_funcs[drive]->format)
+        drive_funcs[drive]->format(drive, track, side, density);
+        else
+        disc_notfound = 10000;
+}
+
+void
+disc_stop(int drive)
+{
+        if (drive_funcs[drive] && drive_funcs[drive]->stop)
+        drive_funcs[drive]->stop();
+}
diff -r 592604520b7e -r ca4be2ca9a9a src/disc.h
--- /dev/null    Thu Jan 01 00:00:00 1970 +0000
+++ b/src/disc.h    Sat Oct 09 17:23:31 2021 +0100
@@ -0,0 +1,22 @@
+typedef struct {
+        void (*seek)(int drive, int track);
+        void (*readsector)(int drive, int sector, int track, int side, int density);
+        void (*writesector)(int drive, int sector, int track, int side, int density);
+        void (*readaddress)(int drive, int track, int side, int density);
+        void (*format)(int drive, int track, int side, int density);
+        void (*stop)();
+        void (*poll)();
+        void (*close)(int drive);
+} disc_funcs;
+
+extern disc_funcs *drive_funcs[2];
+
+extern void disc_set_drivesel(int drive);
+extern void disc_poll(void);
+extern int disc_get_current_track(int drive);
+extern void disc_seek(int drive, int track);
+extern void disc_readsector(int drive, int sector, int track, int side, int density);
+extern void disc_writesector(int drive, int sector, int track, int side, int density);
+extern void disc_readaddress(int drive, int track, int side, int density);
+extern void disc_format(int drive, int track, int side, int density);
+extern void disc_stop(int drive);
diff -r 592604520b7e -r ca4be2ca9a9a src/disc_adf.c
--- a/src/disc_adf.c    Sat Oct 09 14:01:30 2021 +0100
+++ b/src/disc_adf.c    Sat Oct 09 17:23:31 2021 +0100
@@ -2,9 +2,12 @@
 #include <string.h>
 #include <stdint.h>
 #include "rpcemu.h"
+#include "disc.h"
 #include "disc_adf.h"
 #include "fdc.h"
 
+static disc_funcs adf_disc_funcs;
+
 static struct {
         FILE *f;
         uint8_t track_data[2][20*1024];
@@ -67,18 +70,19 @@
         adf[drive].maxsector = (ftell(adf[drive].f)+1 ) / size;
         adf[drive].skew = skew;
 
-        adf_seek(drive, 0);
+        drive_funcs[drive] = &adf_disc_funcs;
+        drive_funcs[drive]->seek(drive, disc_get_current_track(drive));
 }
 
 
-void adf_close(int drive)
+static void adf_close(int drive)
 {
         if (adf[drive].f)
             fclose(adf[drive].f);
         adf[drive].f = NULL;
 }
 
-void adf_seek(int drive, int track)
+static void adf_seek(int drive, int track)
 {
         if (!adf[drive].f)
                 return;
@@ -95,7 +99,7 @@
                 fread(adf[drive].track_data[0], adf[drive].sectors * adf[drive].size, 1, adf[drive].f);
         }
 }
-void adf_writeback(int drive, int track)
+static void adf_writeback(int drive, int track)
 {
         if (!adf[drive].f)
                 return;
@@ -113,7 +117,7 @@
         }
 }
 
-void adf_readsector(int drive, int sector, int track, int side, int density)
+static void adf_readsector(int drive, int sector, int track, int side, int density)
 {
         int sector_nr = (sector - adf[drive].skew) + adf[drive].sectors * (track * (adf[drive].dblside ? 2 : 1) + (side ? 1 : 0));
 
@@ -134,7 +138,7 @@
         adf_state.readpos = 0;
 }
 
-void adf_writesector(int drive, int sector, int track, int side, int density)
+static void adf_writesector(int drive, int sector, int track, int side, int density)
 {
         int sector_nr = (sector - adf[drive].skew) + adf[drive].sectors * (track * (adf[drive].dblside ? 2 : 1) + (side ? 1 : 0));
 
@@ -154,7 +158,7 @@
         adf_state.readpos = 0;
 }
 
-void adf_readaddress(int drive, int track, int side, int density)
+static void adf_readaddress(int drive, int track, int side, int density)
 {
         if (adf[drive].dblstep)
                 track /= 2;
@@ -174,7 +178,7 @@
         adf_state.pause = 100;//500;
 }
 
-void adf_format(int drive, int track, int side, int density)
+static void adf_format(int drive, int track, int side, int density)
 {
         if (adf[drive].dblstep)
                 track /= 2;
@@ -193,7 +197,7 @@
         adf_state.informat  = 1;
 }
 
-void adf_stop(void)
+static void adf_stop(void)
 {
 //    rpclog("adf_stop\n");
 
@@ -205,7 +209,7 @@
         adf_state.informat = 0;
 }
 
-void adf_poll(void)
+static void adf_poll(void)
 {
         int c;
 
@@ -277,3 +281,14 @@
                 }
         }
 }
+
+static disc_funcs adf_disc_funcs = {
+    .seek        = adf_seek,
+        .readsector  = adf_readsector,
+        .writesector = adf_writesector,
+        .readaddress = adf_readaddress,
+        .poll        = adf_poll,
+        .format      = adf_format,
+        .stop        = adf_stop,
+        .close       = adf_close
+};
\ No newline at end of file
diff -r 592604520b7e -r ca4be2ca9a9a src/disc_adf.h
--- a/src/disc_adf.h    Sat Oct 09 14:01:30 2021 +0100
+++ b/src/disc_adf.h    Sat Oct 09 17:23:31 2021 +0100
@@ -1,20 +1,3 @@
 extern void adf_init(void);
 
-extern void adf_load(int drive, const char *fn, int sectors, int size, int dblside, int dblstep, int density, int skew);
-
-extern void adf_close(int drive);
-extern void adf_seek(int drive, int track);
-extern void adf_readsector(int drive, int sector, int track, int side, int density);
-extern void adf_writesector(int drive, int sector, int track, int side, int density);
-extern void adf_readaddress(int drive, int sector, int side, int density);
-extern void adf_format(int drive, int sector, int side, int density);
-extern void adf_stop(void);
-extern void adf_poll(void);
-
-#define disc_seek        adf_seek
-#define disc_readsector  adf_readsector
-#define disc_writesector adf_writesector
-#define disc_readaddress adf_readaddress
-#define disc_format      adf_format
-#define disc_stop        adf_stop
-#define disc_poll        adf_poll
\ No newline at end of file
+extern void adf_load(int drive, const char *fn, int sectors, int size, int dblside, int dblstep, int density, int skew);
\ No newline at end of file
diff -r 592604520b7e -r ca4be2ca9a9a src/fdc.c
--- a/src/fdc.c    Sat Oct 09 14:01:30 2021 +0100
+++ b/src/fdc.c    Sat Oct 09 17:23:31 2021 +0100
@@ -32,6 +32,7 @@
 #include "iomd.h"
 #include "ide.h"
 #include "arm.h"
+#include "disc.h"
 #include "disc_adf.h"
 
 /* FDC commands */
@@ -223,6 +224,11 @@
     }
     fclose(f);
 
+    if (drive_funcs[drive]) {
+        drive_funcs[drive]->close(drive);
+        drive_funcs[drive] = NULL;
+    }
+
     rpclog("fdc_image_load: %s (%ld) loaded as '%s'\n", fn, len, format->name);
     adf_load(drive, fn, format->sectors, format->sectorsize, format->sides, format->tracks == 40,
             format->density ? 1 : 2, format->sectorskew);
@@ -232,7 +238,10 @@
 fdc_image_save(const char *fn, int drive)
 {
     (void)fn;
-    adf_close(drive);
+    if (drive_funcs[drive]) {
+        drive_funcs[drive]->close(drive);
+        drive_funcs[drive] = NULL;
+    }
 }
 
 void
@@ -248,6 +257,10 @@
             fdc.status = 0x80;
         }
         motoron = val & 0x30;
+        if (val & 0x10)
+            disc_set_drivesel(0);
+        else if (val & 0x20)
+            disc_set_drivesel(1);
         break;
 
     case 0x3f4: /* Data Rate Select Register (DSR) */
@@ -672,7 +685,7 @@
 
 static void fdc_overrun(void)
 {
-        disc_stop();
+        disc_stop(fdc.drive);
 
         fdcsend(0x40 | (fdc.side ? 4 : 0) | fdc.drive);
         fdcsend(0x10); /*Overrun*/
diff -r 592604520b7e -r ca4be2ca9a9a src/qt5/rpcemu.pro
--- a/src/qt5/rpcemu.pro    Sat Oct 09 14:01:30 2021 +0100
+++ b/src/qt5/rpcemu.pro    Sat Oct 09 17:23:31 2021 +0100
@@ -26,6 +26,7 @@
         ../vidc20.h \
         ../arm_common.h \
         ../arm.h \
+        ../disc.h \
         ../disc_adf.h \
         main_window.h \
         configure_dialog.h \
@@ -54,6 +55,7 @@
         ../rpc-machdep.c \
         ../arm_common.c \
         ../i8042.c \
+        ../disc.c \
         ../disc_adf.c \
         settings.cpp \
         rpc-qt5.cpp \


_______________________________________________
RPCEmu mailing list
RPCEmu@riscos.info
http://www.riscos.info/cgi-bin/mailman/listinfo/rpcemu

No comments:

Post a Comment