Index: pdp11_rx.c
===================================================================
--- pdp11_rx.c	(revision 1994)
+++ pdp11_rx.c	(working copy)
@@ -25,6 +25,7 @@
 
    rx           RX11/RX01 floppy disk
 
+   07-Jul-08    HMH     Add ImageDisk (IMD) support.
    07-Jul-05    RMS     Removed extraneous externs
    12-Oct-02    RMS     Added autoconfigure support
    08-Oct-02    RMS     Added variable address support to bootstrap
@@ -49,6 +50,12 @@
 
 #include "pdp11_defs.h"
 
+#define USE_IMD
+
+#ifdef USE_IMD
+#include "sim_imd.h"
+#endif /* USE_IMD */
+
 #define RX_NUMTR        77                              /* tracks/disk */
 #define RX_M_TRACK      0377
 #define RX_NUMSC        26                              /* sectors/track */
@@ -131,7 +138,15 @@
 t_stat rx_reset (DEVICE *dptr);
 t_stat rx_boot (int32 unitno, DEVICE *dptr);
 void rx_done (int esr_flags, int new_ecode);
+#ifdef USE_IMD
+t_stat rx_attach(UNIT *uptr, char *cptr);
+t_stat rx_detach(UNIT *uptr);
 
+#define UNIT_TYPE_DSK	(UNIT_BUFABLE|UNIT_MUSTBUF)
+#define UNIT_IS_IMD(uptr)	((uptr->flags & UNIT_TYPE_DSK) == 0)
+
+#endif /* USE_IMD */
+
 /* RX11 data structures
 
    rx_dev       RX device descriptor
@@ -147,9 +162,9 @@
 
 UNIT rx_unit[] = {
     { UDATA (&rx_svc,
-             UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, RX_SIZE) },
+             UNIT_FIX|UNIT_ATTABLE|UNIT_BUFABLE|UNIT_MUSTBUF, RX_SIZE) },
     { UDATA (&rx_svc,
-             UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF, RX_SIZE) }
+             UNIT_FIX|UNIT_ATTABLE|UNIT_BUFABLE|UNIT_MUSTBUF, RX_SIZE) }
     };
 
 REG rx_reg[] = {
@@ -179,7 +194,11 @@
 MTAB rx_mod[] = {
     { UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
     { UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
-    { MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
+#ifdef USE_IMD
+	{ UNIT_TYPE_DSK, 0, "ImageDisk", "IMD", NULL },
+    { UNIT_TYPE_DSK, UNIT_TYPE_DSK, "Raw DSK", "DSK", NULL },
+#endif /* USE_IMD */
+	{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
       &set_addr, &show_addr, NULL },
     { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
       &set_vec, &show_vec, NULL },
@@ -192,7 +211,12 @@
     "RX", rx_unit, rx_reg, rx_mod,
     RX_NUMDR, 8, 20, 1, 8, 8,
     NULL, NULL, &rx_reset,
-    &rx_boot, NULL, NULL,
+    &rx_boot,
+#ifdef USE_IMD
+	&rx_attach, &rx_detach,
+#else
+	NULL, NULL,
+#endif /* USE_IMD */
     &rx_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS
     };
 
@@ -360,7 +384,9 @@
         return SCPE_OK;
 
     case RWXFR:
-        if ((uptr->flags & UNIT_BUF) == 0) {            /* not buffered? */
+		printf("RX: RWXFR\n");
+        if (((uptr->flags & UNIT_BUF) == 0) &&
+			(!UNIT_IS_IMD(uptr))) {                     /* not buffered? */
             rx_done (0, 0110);                          /* done, error */
             return IORETURN (rx_stopioe, SCPE_UNATT);
             }
@@ -376,19 +402,57 @@
         da = CALC_DA (rx_track, rx_sector);             /* get disk address */
         if (func == RXCS_WRDEL) rx_esr = rx_esr | RXES_DD; /* del data? */
         if (func == RXCS_READ) {                        /* read? */
-            for (i = 0; i < RX_NUMBY; i++)
-                rx_buf[i] = fbuf[da + i];
-            }
+#ifdef USE_IMD
+			if(!UNIT_IS_IMD(uptr)) {
+#endif /* USE_IMD */
+				for (i = 0; i < RX_NUMBY; i++) {
+					rx_buf[i] = fbuf[da + i];
+				}
+#ifdef USE_IMD
+			} else {
+				unsigned int flags = 0;
+				unsigned int readlen;
+
+				printf("RX: Read T%d/N:%d\n", rx_track, rx_sector);
+				sectRead(uptr->filebuf,
+					rx_track,
+					0,
+					rx_sector,
+					rx_buf,
+					RX_NUMBY,
+					&flags,
+					&readlen);
+			}
+#endif /* USE_IMD */
+		}
         else {
             if (uptr->flags & UNIT_WPRT) {              /* write and locked? */
                 rx_done (RXES_WLK, 0100);               /* done, error */
                 break;
                 }
-            for (i = 0; i < RX_NUMBY; i++)              /* write */
-                fbuf[da + i] = rx_buf[i];
-            da = da + RX_NUMBY;
-            if (da > uptr->hwmark) uptr->hwmark = da;
-            }
+#ifdef USE_IMD
+			if(!UNIT_IS_IMD(uptr)) {
+#endif /* USE_IMD */
+				for (i = 0; i < RX_NUMBY; i++)              /* write */
+					fbuf[da + i] = rx_buf[i];
+				da = da + RX_NUMBY;
+				if (da > uptr->hwmark) uptr->hwmark = da;
+#ifdef USE_IMD
+			} else {
+				unsigned int flags = (rx_esr & RXES_DD) ? IMD_DISK_IO_DELETED_ADDR_MARK : 0;
+				unsigned int writelen;
+
+				sectWrite(uptr->filebuf,
+					rx_track,
+					0,
+					rx_sector,
+					rx_buf,
+					RX_NUMBY,
+					&flags,
+					&writelen);
+			}
+#endif /* USE_IMD */
+        }
         rx_done (0, 0);                                 /* done */
         break;
 
@@ -403,13 +467,34 @@
     case INIT_COMPLETE:                                 /* init complete */
         rx_unit[0].TRACK = 1;                           /* drive 0 to trk 1 */
         rx_unit[1].TRACK = 0;                           /* drive 1 to trk 0 */
-        if ((rx_unit[0].flags & UNIT_BUF) == 0) {       /* not buffered? */
+        if (((rx_unit[0].flags & UNIT_BUF) == 0) &&
+			(!UNIT_IS_IMD((&rx_unit[0])))) {              /* not buffered? */
             rx_done (RXES_ID, 0010);                    /* init done, error */
             break;
             }
         da = CALC_DA (1, 1);                            /* track 1, sector 1 */
-        for (i = 0; i < RX_NUMBY; i++)                  /* read sector */
-            rx_buf[i] = fbuf[da + i];
+#ifdef USE_IMD
+		if(!UNIT_IS_IMD(uptr)) {
+#endif /* USE_IMD */
+			for (i = 0; i < RX_NUMBY; i++) {
+				rx_buf[i] = fbuf[da + i];
+			}
+#ifdef USE_IMD
+		} else {
+			unsigned int flags = 0;
+			unsigned int readlen;
+
+			printf("RX: Init T%d/N:%d\n", rx_track, rx_sector);
+			sectRead(uptr->filebuf,
+				1,
+				0,
+				1,
+				rx_buf,
+				RX_NUMBY,
+				&flags,
+				&readlen);
+		}
+#endif /* USE_IMD */
         rx_done (RXES_ID, 0);                           /* set done */
         if ((rx_unit[1].flags & UNIT_ATT) == 0) rx_ecode = 0020;
         break;
@@ -452,10 +537,15 @@
 CLR_INT (RX);                                           /* clear int req */
 sim_cancel (&rx_unit[1]);                               /* cancel drive 1 */
 if (dptr->flags & DEV_DIS) sim_cancel (&rx_unit[0]);    /* disabled? */
-else if (rx_unit[0].flags & UNIT_BUF)  {                /* attached? */
+else if ((rx_unit[0].flags & UNIT_BUF) &&
+		 (!UNIT_IS_IMD((&rx_unit[0])))) {               /* attached? (DSK) */
     rx_state = INIT_COMPLETE;                           /* yes, sched init */
     sim_activate (&rx_unit[0], rx_swait * abs (1 - rx_unit[0].TRACK));
     }
+else if(rx_unit[0].filebuf != NULL) {					/* attached? (IMD) */
+    rx_state = INIT_COMPLETE;                           /* yes, sched init */
+    sim_activate (&rx_unit[0], rx_swait * abs (1 - rx_unit[0].TRACK));
+}
 else rx_done (0, 0010);                                 /* no, error */
 return auto_config (0, 0);                              /* run autoconfig */
 }
@@ -516,3 +606,91 @@
 saved_PC = BOOT_ENTRY;
 return SCPE_OK;
 }
+
+#ifdef USE_IMD
+/* Attach routine */
+t_stat rx_attach(UNIT *uptr, char *cptr)
+{
+    char header[4];
+    t_stat r;
+
+    r = attach_unit(uptr, cptr);    /* attach unit  */
+    if ( r != SCPE_OK)              /* error?       */
+        return r;
+
+    /* Determine length of this disk */
+    uptr->capac = sim_fsize(uptr->fileref);
+
+    /* rewind to the beginning of the file. */
+	fseek(uptr->fileref, 0, SEEK_SET);
+
+    if(uptr->capac > 0) {
+        fgets(header, 4, uptr->fileref);
+        if(strncmp(header, "IMD", 3)) {	/* DSK Image */
+			if(UNIT_IS_IMD(uptr)) {
+				r = detach_unit(uptr);
+				if ( r != SCPE_OK)              /* error?       */
+					return r;
+
+				uptr->flags |= UNIT_TYPE_DSK;
+				r = attach_unit(uptr, cptr);    /* attach unit  */
+				if ( r != SCPE_OK)              /* error?       */
+					return r;
+
+				printf("RX: changed type to DSK image\n");
+			} else;
+		} else {	/* IMD Image */
+			if(UNIT_IS_IMD(uptr)) {
+			} else {
+				uptr->flags &= ~UNIT_TYPE_DSK;
+				r = detach_unit(uptr);
+				if ( r != SCPE_OK)              /* error?       */
+					return r;
+
+				r = attach_unit(uptr, cptr);    /* attach unit  */
+				if ( r != SCPE_OK)              /* error?       */
+					return r;
+
+				printf("RX: changed type to IMD image\n");
+			}
+			uptr->capac = RX_SIZE;
+		}
+    } else {
+		if(UNIT_IS_IMD(uptr)) {
+			/* create a disk image file in IMD format. */
+			diskCreate(uptr->fileref, "$Id$");
+			uptr->capac = RX_SIZE; //sim_fsize(uptr->fileref);
+		} else;
+    }
+
+    if(UNIT_IS_IMD(uptr)) {
+        uptr->filebuf = diskOpen((uptr->fileref), 1);
+        printf("\n");
+
+		/* Write-protect the unit if IMD think's it's writelocked. */
+		if(imdIsWriteLocked(uptr->filebuf)) {
+			uptr->flags |= UNIT_WLK;
+		}
+    }
+
+    return SCPE_OK;
+}
+
+
+/* Detach routine */
+t_stat rx_detach(UNIT *uptr)
+{
+    t_stat r;
+
+	if(UNIT_IS_IMD(uptr)) {
+		diskClose(uptr->filebuf);
+	}
+
+    r = detach_unit(uptr);  /* detach unit */
+    if ( r != SCPE_OK)
+        return r;
+
+    return SCPE_OK;
+}
+
+#endif /* USE_IMD */

Property changes on: pdp11_rx.c
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
