From 750b5028a18de8a958db63849b5bae84180dad84 Mon Sep 17 00:00:00 2001 From: jaortega Date: Wed, 1 Nov 2000 22:53:21 +0000 Subject: --- mixlib/mix_vm_dump.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 mixlib/mix_vm_dump.c (limited to 'mixlib/mix_vm_dump.c') diff --git a/mixlib/mix_vm_dump.c b/mixlib/mix_vm_dump.c new file mode 100644 index 0000000..33b5c38 --- /dev/null +++ b/mixlib/mix_vm_dump.c @@ -0,0 +1,194 @@ +/* ---------------------- mix_vm_dump.c : + * Implementation of the functions declared in mix_vm_dump.h + * ------------------------------------------------------------------ +** Copyright (C) 2000 jose antonio ortega ruiz +** +** 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. +** +*/ + +#include "mix.h" +#include +#include "xmix_vm.h" +#include "mix_vm_dump.h" + +/* Create/destroy a dump context */ +mix_dump_context_t * +mix_dump_context_new(gint fd, mix_address_t begin, mix_address_t end, + guint32 options) +{ + mix_dump_context_t *result = NULL; + GIOChannel *channel = NULL; + + if ( fd == MIX_DUMP_DEF_CHANNEL ) fd = STDIN_FILENO; + channel = g_io_channel_unix_new (fd); + g_return_val_if_fail (channel != NULL, NULL); + + if ( begin > end ) begin = end; + if ( end >= MEM_CELLS_NO_ ) end = MEM_CELLS_NO_; + + result = g_new (mix_dump_context_t,1); + g_return_val_if_fail (result != NULL, NULL); + + result->options = options; + result->begin = begin; + result->end = end; + result->channel = channel; + + return result; +} + +void +mix_dump_context_delete (mix_dump_context_t *dc) +{ + g_return_if_fail (dc != NULL); + g_io_channel_close (dc->channel); + g_free (dc); +} + +gboolean /* TRUE if success */ +mix_dump_context_set_channel (mix_dump_context_t *dc, gint fd) +{ + g_return_val_if_fail (dc != NULL, FALSE); + g_io_channel_close (dc->channel); + dc->channel = g_io_channel_unix_new (fd == MIX_DUMP_DEF_CHANNEL? + STDERR_FILENO : fd); + return ( dc->channel != NULL ); +} + +/* Use the dump context */ +#define WORD_FMT_ "%s %02d %02d %02d %02d %02d (%010ld)" +#define SHORT_FMT_ "%s %02d %02d (%04d)" +#define WORD_SIGN_(w) mix_word_is_negative (w)? "-":"+" +#define SHORT_SIGN_(s) mix_short_is_negative (s)? "-":"+" +#define WORD_ABS_(w) mix_word_magnitude (w) +#define SHORT_ABS_(s) mix_short_magnitude (s) +#define WORD_BYTE_(w,i) mix_byte_new (mix_word_magnitude (w)>>(6*(5-i))) +#define SHORT_BYTE_(s,i) mix_byte_new (mix_short_magnitude (s)>>(6*(2-i))) +#define WORD_ARGS_(w) WORD_SIGN_ (w), WORD_BYTE_ (w,1), WORD_BYTE_ (w,2), \ + WORD_BYTE_ (w,3), WORD_BYTE_ (w,4), WORD_BYTE_ (w,5), WORD_ABS_ (w) +#define SHORT_ARGS_(s) SHORT_SIGN_ (s), SHORT_BYTE_ (s,1), SHORT_BYTE_ (s,2), \ + SHORT_ABS_ (s) + +static gboolean +write_buffer_ (const gchar *buf, guint len, GIOChannel *io) +{ + guint k, err; + + while ( len > 0 ) { + err = g_io_channel_write (io, (gchar *) buf, len, &k); + g_return_val_if_fail (err == G_IO_ERROR_NONE || + err == G_IO_ERROR_AGAIN, FALSE); + len -= k; + } + return TRUE; +} + + + +void +mix_vm_dump (const mix_vm_t *vm, const mix_dump_context_t *dc) +{ + static const guint BUF_LEN = 40; + gchar buf[BUF_LEN]; + guint j, i; + + g_return_if_fail (vm != NULL); + g_return_if_fail (dc != NULL); + + + if ( (dc->options & MIX_DUMP_rA) == MIX_DUMP_rA ) + { + mix_word_t rA = get_rA_ (vm); + guint k = g_snprintf (buf, BUF_LEN, "rA: " WORD_FMT_ "\n", + WORD_ARGS_ (rA)); + g_return_if_fail (write_buffer_ (buf, k, dc->channel)); + } + + if ( (dc->options & MIX_DUMP_rX) == MIX_DUMP_rX ) + { + mix_word_t rX = get_rX_ (vm); + guint k = g_snprintf (buf, BUF_LEN, "rX: " WORD_FMT_ "\n", + WORD_ARGS_ (rX)); + g_return_if_fail (write_buffer_ (buf, k, dc->channel)); + } + + if ( (dc->options & MIX_DUMP_rJ) == MIX_DUMP_rJ ) + { + mix_short_t rJ = get_rJ_ (vm); + guint k = g_snprintf (buf, BUF_LEN, "rJ: " SHORT_FMT_ "\n", + SHORT_ARGS_ (rJ)); + g_return_if_fail (write_buffer_ (buf, k, dc->channel)); + } + + for (j = 0, i = 0; j < IREG_NO_; ++j) + { + if ( (dc->options & (MIX_DUMP_rI1<channel)); + i++; + } + if ( i%2 == 0 && i != 0 ) + g_return_if_fail (write_buffer_ ("\n", 1, dc->channel)); + } + + if ( i%2 == 1 ) + g_return_if_fail (write_buffer_ ("\n", 1, dc->channel)); + + if ( (dc->options & MIX_DUMP_OVER) == MIX_DUMP_OVER ) + { + guint k = g_snprintf (buf, BUF_LEN, _("Overflow: %s\n"), + get_over_ (vm)? "T":"F"); + g_return_if_fail (write_buffer_ (buf, k, dc->channel)); + } + + if ( (dc->options & MIX_DUMP_CMP) == MIX_DUMP_CMP ) + { + guint k; + const gchar *val = "?"; + switch (get_cmp_ (vm)) + { + case mix_LESS: + val = "L"; + break; + case mix_GREAT: + val = "G"; + break; + case mix_EQ: + val = "E"; + break; + default: + g_assert_not_reached (); + break; + } + k = g_snprintf (buf, BUF_LEN, _("Cmp: %s\n"), val); + g_return_if_fail (write_buffer_ (buf, k, dc->channel)); + } + + if ( (dc->options & MIX_DUMP_CELLS) == MIX_DUMP_CELLS ) + { + for (j = dc->begin; j < dc->end; ++j) + { + mix_word_t cell = get_cell_ (vm,j); + guint k = g_snprintf (buf, BUF_LEN, "%04d: " WORD_FMT_ "\n", j, + WORD_ARGS_ (cell)); + g_return_if_fail (write_buffer_ (buf, k, dc->channel)); + } + } +} + -- cgit v1.2.3