]> Savannah Git Hosting - mdk.git/commitdiff

Savannah Git Hosting - mdk.git/commitdiff

git git@sv / mdk.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9ae59a9)
Support IOC commands for disk/drum devices
Tue, 9 Apr 2019 01:40:05 +0000 (02:40 +0100)
Tue, 9 Apr 2019 01:40:05 +0000 (02:40 +0100)
Thanks to Kevin Brunelle

There is a minor fix included with regards to tape devices. The test
was failing if M == 0, when it should fail when M != 0.

NOTICE: This patch changes the behavior of the VM and changes the
function parameters for the ioc_ function. Documentation changes are
included.

Permits the following:
LDX BLKNUM
IOC 0(8)
OUT ADDR(8) Write block from ADDR into disk[BLKNUM]
IOC 0(8)
IN ADDR(8) Read block from disk[BLKNUM] into ADDR
...
BLKNUM CON 45000 Example possible block on disk

I was having an issue writing a block to a drive and then reading back
the same block. Because it is impossible to move the SEEK_CUR pointer
backwards on a disk device, there was no way for a program to read
back a block that it wrote to a disk without restarting or fiddling
with ~/.mdk/disk?.dev files and symbolic links.

I have added a function parameter to the ioc_ function and used it to
pass the value of rX to ioc_. This permits us to use IOC commands to
move the read/write head on a disk/drum device. I believe that this
conforms to the potential meaning of Knuth's description of IOC for
disk/drum devices.

I have put in tests to verify that rX is positive and M = 0.

I have updated the documentation to reflect this new behavior.

This makes disks much more usable.

Note: I won't be offended if this patch is rejected because it changed
the behavior of the VM. I think it fits the spirit and enhances the
functionality in a way that some might find useful. I wanted it for
something I was working on, and I felt others might want the same. The
thing with the paper-tape should be fixed, though.


diff --git a/doc/mdk_tut.texi b/doc/mdk_tut.texi
index e2d3a1562f2c2990e13fa48bb30a7cf2e68f9928..9ff6f86fdb5e4fd60e9b9eb780a5174509318ac0 100644 (file)
--- a/doc/mdk_tut.texi
+++ b/doc/mdk_tut.texi
@@ -684,14 +684,17 @@ OPCODE = 34, MOD = I/O unit.
@noindent
In all the above instructions, the @samp{MOD} subfile must be in the
range 0-20, since it denotes the operation's target device. The
-@samp{IOC} instruction only makes sense for tape devices (@samp{MOD} =
-0-7 or 20): it shifts the read/write pointer by the number of words
-given by @samp{M} (if it equals zero, the tape is rewound)@footnote{In
-Knuth's original definition, there are other control operations
-available, but they do not make sense when implementing the block
-devices as disk files (as we do in @sc{mdk} simulator). For the same
-reason, @sc{mdk} devices are always ready, since all input-output
-operations are performed using synchronous system calls.}.
+@samp{IOC} instruction makes sense for magnetic tape devices (@samp{MOD} =
+0-7): it shifts the read/write pointer by the number of blocks
+given by @samp{M} (if it equals zero, the tape is rewound), paper tape
+devices (@samp{MOD} = 20): @samp{M} should be 0, the tape is rewound,
+and disk/drum devices (@samp{MOD} = 8-15): it moves the read/write
+pointer to the block specified in rX and @samp{M} should be 0@footnote{In
+Knuth's original definition, there are other control operations available,
+but they do not make sense when implementing the devices as disk files (as
+we do in @sc{mdk} simulator). For the same reason, @sc{mdk} devices are
+always ready, since all input-output operations are performed using
+synchronous system calls.}.
@node Conversion operators, Shift operators, Input-output operators, MIX instruction set
diff --git a/mixgtk/mixgtk_device.c b/mixgtk/mixgtk_device.c
index d3ce934ff9e9796fb3d43925400a032912c5dcbe..0cae037975683f7c06bd0c9fb14d6e1965d0379f 100644 (file)
--- a/mixgtk/mixgtk_device.c
+++ b/mixgtk/mixgtk_device.c
@@ -272,9 +272,9 @@ read_ (mix_device_t *dev, mix_word_t *block)
}
static gboolean
-ioc_ (mix_device_t *dev, mix_short_t cmd)
+ioc_ (mix_device_t *dev, mix_short_t cmd, mix_word_t val)
{
- return (DEF_DEV_VTABLE_->ioc)(dev, cmd);
+ return (DEF_DEV_VTABLE_->ioc)(dev, cmd, val);
}
static gboolean
diff --git a/mixlib/mix_device.c b/mixlib/mix_device.c
index 5d3927ca328afd2aa18bffff8e8f9f48469ea4e3..e63119b9b433c9bb86d769792f24ce1cc9db2dd2 100644 (file)
--- a/mixlib/mix_device.c
+++ b/mixlib/mix_device.c
@@ -148,11 +148,11 @@ mix_device_read (mix_device_t *dev, mix_word_t *block)
}
gboolean
-mix_device_ioc (mix_device_t *dev, mix_short_t arg)
+mix_device_ioc (mix_device_t *dev, mix_short_t arg, mix_word_t val)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_assert (dev->vtable != NULL);
- return (dev->vtable->ioc) (dev, arg);
+ return (dev->vtable->ioc) (dev, arg, val);
}
gboolean
diff --git a/mixlib/mix_device.h b/mixlib/mix_device.h
index 1273f184c4b840347bd4f4cee441ffea812e0149..c0e03ab50b0bb6d012b1732c523aa07caaaef3d8 100644 (file)
--- a/mixlib/mix_device.h
+++ b/mixlib/mix_device.h
@@ -148,7 +148,7 @@ mix_device_read (mix_device_t *dev, mix_word_t *block);
>0 - skip forward the given number of blocks
*/
extern gboolean
-mix_device_ioc (mix_device_t *dev, mix_short_t arg);
+mix_device_ioc (mix_device_t *dev, mix_short_t arg, mix_word_t val);
/*
Check if a device is busy
diff --git a/mixlib/xmix_device.c b/mixlib/xmix_device.c
index 8d4084cb030049ae69a433a23050006d8804cd45..6fb085fce4a0c178188abb577d7024d0383c1c59 100644 (file)
--- a/mixlib/xmix_device.c
+++ b/mixlib/xmix_device.c
@@ -143,14 +143,20 @@ read_ (mix_device_t *dev, mix_word_t *block)
}
static gboolean
-ioc_ (mix_device_t *dev, mix_short_t arg)
+ioc_ (mix_device_t *dev, mix_short_t arg, mix_word_t val)
{
int m;
FILE *file;
+ long diskblock;
m = mix_short_magnitude(arg);
if (mix_short_is_negative(arg)) m = -m;
m *= sizeof (mix_word_t) * SIZES_[dev->type];
+
+ diskblock = mix_word_magnitude(val);
+ if (mix_word_is_negative(val)) diskblock = -diskblock;
+ diskblock *= sizeof (mix_word_t) * SIZES_[dev->type];
+
file = mix_io_to_FILE (GET_CHANNEL_(dev));
if (dev->type >= mix_dev_TAPE_0 && dev->type <= mix_dev_TAPE_7)
@@ -160,12 +166,13 @@ ioc_ (mix_device_t *dev, mix_short_t arg)
}
if (dev->type >= mix_dev_DISK_0 && dev->type <= mix_dev_DISK_7)
{
- if (m == 0) return FALSE;
- // position disk
+ // move read/write head to block
+ if (m != 0 || diskblock < 0) return FALSE;
+ else fseek (file, diskblock, SEEK_SET);
}
if (dev->type == mix_dev_PAPER_TAPE)
{
- if (m == 0) return FALSE;
+ if (m != 0) return FALSE;
rewind (file);
}
return TRUE;
diff --git a/mixlib/xmix_device.h b/mixlib/xmix_device.h
index 13950c95d7ed37d12bea59e3c952d51cb8094c10..4de321df081e409b7ff7141183398e276f4e10b8 100644 (file)
--- a/mixlib/xmix_device.h
+++ b/mixlib/xmix_device.h
@@ -32,7 +32,7 @@ extern gchar *DEV_DIR_;
/* table of overridable device operations */
typedef gboolean (*mix_dev_write_func_t) (mix_device_t *, const mix_word_t *);
typedef gboolean (*mix_dev_read_func_t) (mix_device_t *, mix_word_t *);
-typedef gboolean (*mix_dev_ioc_func_t) (mix_device_t *, mix_short_t);
+typedef gboolean (*mix_dev_ioc_func_t) (mix_device_t *, mix_short_t, mix_word_t);
typedef gboolean (*mix_dev_busy_func_t) (const mix_device_t *);
typedef void (*mix_dev_destroy_t) (mix_device_t *);
diff --git a/mixlib/xmix_vm.c b/mixlib/xmix_vm.c
index 68a8106123cb36c5664e5ec41469621220869b04..1b8d80a24b897a7bb20e59f1c5b5897a2f55133f 100644 (file)
--- a/mixlib/xmix_vm.c
+++ b/mixlib/xmix_vm.c
@@ -303,6 +303,7 @@ ioc_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
{
mix_address_t addr;
mix_device_t *dev;
+ mix_word_t val;
g_assert (ins->opcode == mix_opIOC);
@@ -312,7 +313,8 @@ ioc_handler_ (mix_vm_t *vm, const mix_ins_t *ins)
dev = get_dev_ (vm, ins->fspec);
fail_if_not_ (vm, dev != NULL, MIX_VM_ERROR_BAD_DEVICE_NO);
- fail_if_not_ (vm, mix_device_ioc (dev, addr), MIX_VM_ERROR_DEV_CTL);
+ val = get_rX_ (vm);
+ fail_if_not_ (vm, mix_device_ioc (dev, addr, val), MIX_VM_ERROR_DEV_CTL);
inc_loc_ (vm);
return TRUE;
GNU MIX Development Kit (MDK)
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /