summaryrefslogtreecommitdiffhomepage
path: root/mixlib
diff options
context:
space:
mode:
Diffstat (limited to 'mixlib')
-rw-r--r--mixlib/Makefile.am2
-rw-r--r--mixlib/mix_device.c168
-rw-r--r--mixlib/mix_device.h28
-rw-r--r--mixlib/mix_vm.c19
-rw-r--r--mixlib/mix_vm.h5
-rw-r--r--mixlib/xmix_device.h77
-rw-r--r--mixlib/xmix_device.obin0 -> 30132 bytes
7 files changed, 181 insertions, 118 deletions
diff --git a/mixlib/Makefile.am b/mixlib/Makefile.am
index 38c475a..5091e88 100644
--- a/mixlib/Makefile.am
+++ b/mixlib/Makefile.am
@@ -24,7 +24,7 @@ libmix_a_SOURCES = mix.h mix.c \
mix_file.h mix_file.c \
mix_code_file.h mix_code_file.c \
mix_parser.h xmix_parser.h mix_parser.c mix_scanner.l \
- mix_device.h mix_device.c \
+ mix_device.h mix_device.c xmix_device.h xmix_device.c \
mix_eval.h mix_eval.c xmix_eval.h mix_eval_scanner.l \
mix_src_file.c mix_src_file.h \
mix_vm_clock.c mix_vm_clock.h \
diff --git a/mixlib/mix_device.c b/mixlib/mix_device.c
index 624702b..13e7150 100644
--- a/mixlib/mix_device.c
+++ b/mixlib/mix_device.c
@@ -1,7 +1,7 @@
/* -*-c-*- -------------- mix_device.c :
* Implementation of the functions declared in mix_device.h
* ------------------------------------------------------------------
- * Copyright (C) 2000 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,56 +21,14 @@
#include "mix_file.h"
-#include "mix_device.h"
-
-/*
- Actual definition of a mix device, which can be cast to
- a mix file.
-*/
-struct mix_device_t
-{
- mix_iochannel_t *file;
- mix_device_type_t type;
-};
-
-
-static const char *DEV_EXT_ = ".dev";
-
-static const char *DEF_NAMES_[] = {
- "tape0", "tape1", "tape2", "tape3", "tape4", "tape5", "tape6", "tape7",
- "disk0", "disk1", "disk2", "disk3", "disk4", "disk5", "disk6", "disk7",
- "cardrd", "cardwr", "printer", "console", "paper"
-};
-
-static const size_t SIZES_[] = {
- 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 100, 100,
- 16, 16, 24, 14, 14
-};
-
-static const mix_device_mode_t MODES_[] = {
- mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
- mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
- mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN, mix_dev_BIN,
- mix_dev_BIN, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR, mix_dev_CHAR,
- mix_dev_CHAR
-};
-
-static const mix_fmode_t FMODES_[] = {
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT, mix_io_RDWRT,
- mix_io_READ, mix_io_WRITE, mix_io_WRITE, mix_io_RDWRT, mix_io_WRITE
-};
-
-#define GET_CHANNEL_(dev) (dev->file)
-#define GET_FILE_(dev) ((mix_file_t *)(dev->file))
+#include "xmix_device.h"
mix_device_t *
mix_device_new (mix_device_type_t type)
{
- mix_device_t *result = g_new (mix_device_t, 1);
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
result->type = type;
if (type != mix_dev_CONSOLE) {
result->file = MIX_IOCHANNEL(mix_file_new_with_def_ext (DEF_NAMES_[type],
@@ -78,26 +36,18 @@ mix_device_new (mix_device_type_t type)
DEV_EXT_));
} else
result->file = mix_io_new (stdout);
-
+ result->vtable = DEF_DEV_VTABLE_;
return result;
}
-void
-mix_device_delete (mix_device_t *dev)
-{
- if (dev != NULL)
- {
- if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL)
- mix_file_delete (GET_FILE_(dev));
- g_free (dev);
- }
-}
+
mix_device_t *
mix_device_new_with_name (mix_device_type_t type, const gchar *name)
{
mix_device_t *result = NULL;
- g_return_val_if_fail (name != NULL, result);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
result = g_new (mix_device_t, 1);
result->type = type;
if (type != mix_dev_CONSOLE)
@@ -110,11 +60,46 @@ mix_device_new_with_name (mix_device_type_t type, const gchar *name)
{
result->file = mix_io_new (stdout);
}
+ result->vtable = DEF_DEV_VTABLE_;
return result;
}
+/*
+ Create a new device with a given type and stream
+*/
+mix_device_t *
+mix_device_new_with_file (mix_device_type_t type, FILE *file)
+{
+ mix_device_t *result = NULL;
+ g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (type < mix_dev_INVALID, NULL);
+ result = g_new (mix_device_t, 1);
+ result->type = type;
+ result->file = mix_io_new (file);
+ result->vtable = DEF_DEV_VTABLE_;
+ return result;
+}
+
+void
+mix_device_delete (mix_device_t *dev)
+{
+ if (dev != NULL)
+ {
+ if (dev->type != mix_dev_CONSOLE && GET_FILE_(dev) != NULL)
+ mix_file_delete (GET_FILE_(dev));
+ g_free (dev);
+ }
+}
+
+mix_device_type_t
+mix_device_type (const mix_device_t *dev)
+{
+ g_return_val_if_fail (dev != NULL, mix_dev_INVALID);
+ return dev->type;
+}
+
const char *
-mix_device_get_name (mix_device_t *dev)
+mix_device_get_name (const mix_device_t *dev)
{
g_return_val_if_fail (dev != NULL, NULL);
return mix_file_base_name(GET_FILE_(dev));
@@ -124,7 +109,7 @@ mix_device_get_name (mix_device_t *dev)
Get the device block size
*/
size_t
-mix_device_block_size (mix_device_t *dev)
+mix_device_block_size (const mix_device_t *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return SIZES_[dev->type];
@@ -134,7 +119,7 @@ mix_device_block_size (mix_device_t *dev)
Get the device io mode
*/
mix_device_mode_t
-mix_device_mode (mix_device_t *dev)
+mix_device_mode (const mix_device_t *dev)
{
g_return_val_if_fail (dev != NULL, 0);
return MODES_[dev->type];
@@ -146,23 +131,10 @@ mix_device_mode (mix_device_t *dev)
gboolean
mix_device_write (mix_device_t *dev, const mix_word_t *block)
{
- gboolean result;
-
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (block != NULL, FALSE);
- if (FMODES_[dev->type] == mix_io_READ) return FALSE;
- if (MODES_[dev->type] == mix_dev_CHAR)
- result = mix_io_write_word_array_as_char (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
- else
- result = mix_io_write_word_array (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
- if (result && mix_device_mode(dev) == mix_dev_CHAR)
- putc ('\n', mix_io_to_FILE (GET_CHANNEL_ (dev)));
-
- fflush (mix_io_to_FILE (GET_CHANNEL_ (dev)));
-
- return result;
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->write) (dev, block);
}
gboolean
@@ -170,48 +142,22 @@ mix_device_read (mix_device_t *dev, mix_word_t *block)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (block != NULL, FALSE);
- if (FMODES_[dev->type] == mix_io_WRITE) return FALSE;
- if (MODES_[dev->type] == mix_dev_CHAR)
- return mix_io_read_word_array_as_char (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
- else
- return mix_io_read_word_array (GET_CHANNEL_ (dev),
- block, SIZES_[dev->type]);
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->read) (dev, block);
}
gboolean
mix_device_ioc (mix_device_t *dev, mix_short_t arg)
{
- int m;
- FILE *file;
-
g_return_val_if_fail (dev != NULL, FALSE);
-
- m = mix_short_magnitude(arg);
- if (mix_short_is_negative(arg)) m = -m;
- m *= 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)
- {
- if (m == 0) rewind (file);
- else fseek (file, m, SEEK_CUR);
- }
- if (dev->type >= mix_dev_DISK_0 && dev->type <= mix_dev_DISK_7)
- {
- g_return_val_if_fail (m == 0, FALSE);
- // position disk
- }
- if (dev->type == mix_dev_PAPER_TAPE)
- {
- g_return_val_if_fail (m == 0, FALSE);
- rewind (file);
- }
- return TRUE;
+ g_assert (dev->vtable != NULL);
+ return (dev->vtable->ioc) (dev, arg);
}
gboolean
-mix_device_busy (mix_device_t *dev)
+mix_device_busy (const mix_device_t *dev)
{
- return (dev != NULL && !mix_io_is_ready(GET_CHANNEL_(dev)));
+ g_return_val_if_fail (dev != NULL, FALSE);
+ return (dev->vtable->busy) (dev);
+
}
diff --git a/mixlib/mix_device.h b/mixlib/mix_device.h
index 73f16af..7248d72 100644
--- a/mixlib/mix_device.h
+++ b/mixlib/mix_device.h
@@ -1,7 +1,7 @@
/* -*-c-*- ---------------- mix_device.h :
* Declaration of mix_device_t and associated methods.
* ------------------------------------------------------------------
- * Copyright (C) 2000 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
#define MIX_DEVICE_H
#include <stddef.h>
+#include <stdio.h>
#include "mix.h"
#include "mix_types.h"
@@ -56,7 +57,8 @@ typedef enum {
mix_dev_CARD_WR,
mix_dev_PRINTER,
mix_dev_CONSOLE,
- mix_dev_PAPER_TAPE
+ mix_dev_PAPER_TAPE,
+ mix_dev_INVALID
} mix_device_type_t;
/*
@@ -80,28 +82,42 @@ extern mix_device_t *
mix_device_new_with_name (mix_device_type_t type, const gchar *name);
/*
+ Create a new device with a given type and stream
+*/
+extern mix_device_t *
+mix_device_new_with_file (mix_device_type_t type, FILE *file);
+
+/*
Delete a device.
*/
extern void
mix_device_delete(mix_device_t *dev);
+
+/*
+ Get a device type
+*/
+extern mix_device_type_t
+mix_device_type (const mix_device_t *dev);
+
+
/*
Get a device name
*/
extern const char *
-mix_device_get_name (mix_device_t *dev);
+mix_device_get_name (const mix_device_t *dev);
/*
Get the device block size
*/
extern size_t
-mix_device_block_size (mix_device_t *dev);
+mix_device_block_size (const mix_device_t *dev);
/*
Get the device io mode
*/
extern mix_device_mode_t
-mix_device_mode (mix_device_t *dev);
+mix_device_mode (const mix_device_t *dev);
/*
Write a block to the device.
@@ -129,7 +145,7 @@ mix_device_ioc (mix_device_t *dev, mix_short_t arg);
Check if a device is busy
*/
extern gboolean
-mix_device_busy (mix_device_t *dev);
+mix_device_busy (const mix_device_t *dev);
#endif /* MIX_DEVICE_H */
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c
index 979d558..6da21e2 100644
--- a/mixlib/mix_vm.c
+++ b/mixlib/mix_vm.c
@@ -87,6 +87,8 @@ mix_vm_delete (mix_vm_t * vm)
{
int i;
+ g_return_if_fail (vm != NULL);
+
if (vm->line_table != NULL) g_tree_destroy (vm->line_table);
if (vm->address_table != NULL) g_tree_destroy (vm->address_table);
if (vm->symbol_table != NULL) mix_symbol_table_delete (vm->symbol_table);
@@ -97,6 +99,23 @@ mix_vm_delete (mix_vm_t * vm)
g_free (vm);
}
+/* connect devices to a virtual machine */
+mix_device_t *
+mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device)
+{
+ mix_device_t *old;
+ mix_device_type_t type;
+
+ g_return_val_if_fail (vm != NULL, NULL);
+ g_return_val_if_fail (device != NULL, NULL);
+
+ type = mix_device_type (device);
+ old = vm->devices[type];
+ vm->devices[type] = device;
+
+ return old;
+}
+
/* Reset a vm (set state as of a newly created one) */
void
mix_vm_reset (mix_vm_t * vm)
diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h
index ac734d7..b4b408c 100644
--- a/mixlib/mix_vm.h
+++ b/mixlib/mix_vm.h
@@ -25,6 +25,7 @@
#include "mix_types.h"
#include "mix_ins.h"
+#include "mix_device.h"
#include "mix_code_file.h"
#include "mix_src_file.h"
#include "mix_symbol_table.h"
@@ -46,6 +47,10 @@ mix_vm_new(void);
extern void
mix_vm_delete(mix_vm_t * vm);
+/* connect devices to a virtual machine */
+extern mix_device_t * /* previously connected device */
+mix_vm_connect_device (mix_vm_t *vm, mix_device_t *device);
+
/* Reset a vm (set state as of a newly created one) */
extern void
mix_vm_reset(mix_vm_t * vm);
diff --git a/mixlib/xmix_device.h b/mixlib/xmix_device.h
new file mode 100644
index 0000000..c3e8a88
--- /dev/null
+++ b/mixlib/xmix_device.h
@@ -0,0 +1,77 @@
+/* -*-c-*- ---------------- xmix_device.h :
+ * Protected declarations for mix_device_t
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/03/02 00:30:56 jose>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef XMIX_DEVICE_H
+#define XMIX_DEVICE_H
+
+#include "mix_file.h"
+#include "mix_device.h"
+
+/* 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_busy_func_t) (const mix_device_t *);
+
+typedef struct mix_device_vtable_t
+{
+ mix_dev_write_func_t write;
+ mix_dev_read_func_t read;
+ mix_dev_ioc_func_t ioc;
+ mix_dev_busy_func_t busy;
+} mix_device_vtable_t;
+
+/* default vtable */
+extern const mix_device_vtable_t *DEF_DEV_VTABLE_;
+
+/*
+ Actual definition of a mix device, which can be cast to
+ a mix file.
+*/
+struct mix_device_t
+{
+ mix_iochannel_t *file;
+ mix_device_type_t type;
+ const mix_device_vtable_t *vtable;
+};
+
+#define GET_CHANNEL_(dev) (dev->file)
+#define GET_FILE_(dev) ((mix_file_t *)(dev->file))
+
+/* default extension for device files */
+extern const char *DEV_EXT_;
+/* default names for device files */
+extern const char *DEF_NAMES_[];
+/* block sizes for devices */
+extern const size_t SIZES_[];
+/* modes for devices */
+extern const mix_device_mode_t MODES_[];
+/* files modes for devices */
+extern const mix_fmode_t FMODES_[];
+
+
+
+
+#endif /* XMIX_DEVICE_H */
+
diff --git a/mixlib/xmix_device.o b/mixlib/xmix_device.o
new file mode 100644
index 0000000..7a5526f
--- /dev/null
+++ b/mixlib/xmix_device.o
Binary files differ