From a4e2c238ea47badea198132fc5d9311d1f40ca13 Mon Sep 17 00:00:00 2001 From: Justin Wind Date: Mon, 23 Apr 2012 14:24:51 -0700 Subject: [PATCH] minor cleanups to display and callback routines changed some names/structs/typedefs around, mostly aesthetical --- dcpu16.c | 4 ++- dcpu16.h | 18 ++++++++------ display.c | 72 +++++++++++++++++++++++++++-------------------------- display.h | 4 +-- vm-dcpu16.c | 14 +++++------ 5 files changed, 59 insertions(+), 53 deletions(-) diff --git a/dcpu16.c b/dcpu16.c index 165b589..51d755d 100644 --- a/dcpu16.c +++ b/dcpu16.c @@ -26,6 +26,8 @@ * TODO * change api to print into buffers rather than stdio * refactor opcode functiontables into switch statements + * let callbacks determine whether to override events, or just observe + * sort init callbacks by base addr, to call in-order */ static const char * const src_id_ = "$Id$"; @@ -763,7 +765,7 @@ void dcpu16_dump_ram(struct dcpu16 *d, DCPU16_WORD start, DCPU16_WORD end) { * Register callback fn to be triggered whenever event matching any events * in bitwise mask occur. */ -int dcpu16_acct_add(struct dcpu16 *vm, dcpu16_acct_event mask, void (*fn)(struct dcpu16 *, dcpu16_acct_event, DCPU16_WORD, void *), void *data) { +int dcpu16_acct_add(struct dcpu16 *vm, dcpu16_acct_event mask, dcpu16_ev_cb_t *fn, void *data) { struct dcpu16_acct_cb cb; cb.mask = mask; diff --git a/dcpu16.h b/dcpu16.h index 73592d9..7741c93 100644 --- a/dcpu16.h +++ b/dcpu16.h @@ -11,27 +11,29 @@ typedef unsigned short DCPU16_WORD; /* a self-contained dcpu16 core */ struct dcpu16 { + struct dcpu16_acct_cb *cb_table_; /* list of callbacks to invoke for certain events */ + size_t cb_table_entries_; /* callback list maintenance */ + size_t cb_table_allocated_; /* callback list maintenance */ + unsigned int skip_ : 1; /* skip execution of next instruction */ + DCPU16_WORD reg_work_[2]; /* work registers for holding literal values while decoding instructions */ + unsigned long long cycle; /* number of cycles this core has executed */ DCPU16_WORD reg[8]; /* system registers, a b c x y z i j */ DCPU16_WORD pc; /* program counter */ DCPU16_WORD sp; /* stack pointer */ DCPU16_WORD o; /* overflow */ - unsigned int skip_ : 1; /* skip execution of next instruction */ DCPU16_WORD ram[DCPU16_RAM]; /* memory */ - DCPU16_WORD reg_work_[2]; /* (private) work registers for holding literal values while decoding instructions */ - struct dcpu16_acct_cb *cb_table_; /* list of callbacks to invoke for certain events */ - size_t cb_table_entries_; /* callback list maintenance */ - size_t cb_table_allocated_; /* callback list maintenance */ }; -/* these are used for accounting/watchpointing/&c */ +/* these are used for accounting/watchpointing/modules/&c */ typedef unsigned int dcpu16_acct_event; +typedef void (dcpu16_ev_cb_t)(struct dcpu16 *, dcpu16_acct_event, DCPU16_WORD, void *); #define DCPU16_ACCT_EV_READ (1<<1) #define DCPU16_ACCT_EV_WRITE (1<<2) #define DCPU16_ACCT_EV_NOP (1<<3) #define DCPU16_ACCT_EV_RESET (1<<4) struct dcpu16_acct_cb { - void (*fn)(struct dcpu16 *, dcpu16_acct_event e, DCPU16_WORD addr, void *); + dcpu16_ev_cb_t *fn; void *data; dcpu16_acct_event mask; }; @@ -52,7 +54,7 @@ void dcpu16_dump_ram(struct dcpu16 *, DCPU16_WORD, DCPU16_WORD); DCPU16_WORD dcpu16_disassemble_print(struct dcpu16 *, DCPU16_WORD); /* register a callback for an accounting event */ -int dcpu16_acct_add(struct dcpu16 *, dcpu16_acct_event mask, void (*fn)(struct dcpu16 *, dcpu16_acct_event, DCPU16_WORD, void *), void *data); +int dcpu16_acct_add(struct dcpu16 *, dcpu16_acct_event mask, dcpu16_ev_cb_t *fn, void *data); /* execute the next instruction */ void dcpu16_step(struct dcpu16 *); diff --git a/display.c b/display.c index c1e6c20..2c8485a 100644 --- a/display.c +++ b/display.c @@ -36,9 +36,14 @@ struct pixel_ { char b; }; +struct dcpu16_display_ { + char *outfile; + struct pixel_ *pixbuf; +}; + static inline -DPIX pcolor_(unsigned int c) { - DPIX p = { 0, 0, 0 }; +struct pixel_ pcolor_(unsigned int c) { + struct pixel_ p = { 0, 0, 0 }; switch (c) { case 0x1: p.r=0x00, p.g=0x00, p.b=0xaa; break; /* dark blue */ @@ -64,7 +69,7 @@ DPIX pcolor_(unsigned int c) { /* should this just flood-fill entire display? */ static inline -void display_draw_border(DPIX *pixbuf, DPIX color) { +void display_draw_border(struct pixel_ *pixbuf, struct pixel_ color) { size_t x, y; size_t i; @@ -90,8 +95,8 @@ void display_draw_border(DPIX *pixbuf, DPIX color) { /* render a character cell to the display */ static inline -void display_draw_cell(DPIX *pixbuf, DCPU16_WORD *cell_map, DCPU16_WORD index, int cell_x, int cell_y, DPIX fg, DPIX bg) { - DPIX *cellstart = pixbuf; /* start of display */ +void display_draw_cell(struct pixel_ *pixbuf, DCPU16_WORD *cell_map, DCPU16_WORD index, int cell_x, int cell_y, struct pixel_ fg, struct pixel_ bg) { + struct pixel_ *cellstart = pixbuf; /* start of display */ unsigned int pix_x, pix_y; unsigned char *cell_bitmap = (unsigned char *)(cell_map + (index * sizeof index)); @@ -117,7 +122,7 @@ void display_draw_cell(DPIX *pixbuf, DCPU16_WORD *cell_map, DCPU16_WORD index, i } /* write pnm file */ -void display_pnm_write(DPIX *pixbuf, const char *filename) { +void display_pnm_write(struct pixel_ *pixbuf, const char *filename) { size_t i; FILE *f; @@ -148,34 +153,21 @@ void display_pnm_write(DPIX *pixbuf, const char *filename) { /* currently this populates the chargen map 'from rom'.. */ /* and clears the display buffers */ void display_reset_fn(struct dcpu16 *vm, dcpu16_acct_event e, DCPU16_WORD addr, void *data) { - DPIX *pixbuf = (DPIX *)data; + struct dcpu16_display_ *d = (struct dcpu16_display_ *)data; (void)e, (void)addr; - fprintf(stderr, "DEBUG: event:%u\n", e); - - fprintf(stderr, "DEBUG: loading chargen map from 0x%04x to 0x%04x (%zuo)\n", - DISPLAY_CELL_MAP, - DISPLAY_CELL_MAP + (unsigned short)(sizeof chargen_4x8_glyphs / sizeof addr), - sizeof chargen_4x8_glyphs); memcpy(vm->ram + DISPLAY_CELL_MAP, chargen_4x8_glyphs, sizeof chargen_4x8_glyphs); - fprintf(stderr, "DEBUG: clearing display buffer from 0x%04x to 0x%04x (%zuo)\n", - DISPLAY_BASE, - DISPLAY_END, - (DISPLAY_END - DISPLAY_BASE) * sizeof *(vm->ram)); memset(vm->ram + DISPLAY_BASE, 0, (DISPLAY_END - DISPLAY_BASE) * sizeof *(vm->ram)); - fprintf(stderr, "DEBUG: clearing pixel buffer (%zuo)\n", - PIX_X * PIX_Y * sizeof *pixbuf); - memset(pixbuf, 0, PIX_X * PIX_Y * sizeof *pixbuf); + memset(d->pixbuf, 0, PIX_X * PIX_Y * sizeof *(d->pixbuf)); } /* the callback to register with the cpu for watching memory updates */ /* user data is an allocated display buffer */ void display_fn(struct dcpu16 *vm, dcpu16_acct_event e, DCPU16_WORD addr, void *data) { - const char * const outfile = "dcpu16-display.pnm"; - DPIX *pixbuf = (DPIX *)data; + DCPU16_DISPLAY *d = (DCPU16_DISPLAY *)data; unsigned char index, blink, bg, fg; unsigned int cell_x, cell_y; @@ -196,21 +188,20 @@ void display_fn(struct dcpu16 *vm, dcpu16_acct_event e, DCPU16_WORD addr, void * blink = (vm->ram[addr] >> 7) & 0x01; bg = (vm->ram[addr] >> 8) & 0x0f; fg = (vm->ram[addr] >> 12) & 0x0f; - display_draw_cell(pixbuf, vm->ram + DISPLAY_CELL_MAP, index, cell_x, cell_y, pcolor_(fg), pcolor_(bg)); + display_draw_cell(d->pixbuf, vm->ram + DISPLAY_CELL_MAP, index, cell_x, cell_y, pcolor_(fg), pcolor_(bg)); } } - display_pnm_write(pixbuf, outfile); + display_pnm_write(d->pixbuf, d->outfile); return; } if (addr == DISPLAY_MISC) { /* new border color */ char border = vm->ram[addr] & 0x0f; - fprintf(stderr, "display event: new border\n"); - display_draw_border(pixbuf, pcolor_(border)); + display_draw_border(d->pixbuf, pcolor_(border)); - display_pnm_write(pixbuf, outfile); + display_pnm_write(d->pixbuf, d->outfile); return; } @@ -222,17 +213,28 @@ void display_fn(struct dcpu16 *vm, dcpu16_acct_event e, DCPU16_WORD addr, void * bg = (vm->ram[addr] >> 8) & 0x0f; fg = (vm->ram[addr] >> 12) & 0x0f; - fprintf(stderr, "display event: cell %ux%u:%u '%c'\n", cell_x, cell_y, index, index); - - display_draw_cell(pixbuf, vm->ram + DISPLAY_CELL_MAP, index, cell_x, cell_y, pcolor_(fg), pcolor_(bg)); - display_pnm_write(pixbuf, outfile); + display_draw_cell(d->pixbuf, vm->ram + DISPLAY_CELL_MAP, index, cell_x, cell_y, pcolor_(fg), pcolor_(bg)); + display_pnm_write(d->pixbuf, d->outfile); } /* init the pixel buffer */ -DPIX *display_init_pixbuf(void) { - DPIX *pixbuf; +DCPU16_DISPLAY *display_new(const char *filename) { + DCPU16_DISPLAY *d = calloc(1, sizeof *d); + if (d == NULL) + return NULL; + + d->pixbuf = calloc(PIX_X * PIX_Y, sizeof *(d->pixbuf)); + if (d->pixbuf == NULL) { + free(d); + return NULL; + } - pixbuf = calloc(PIX_X * PIX_Y, sizeof *pixbuf); + d->outfile = strdup(filename); + if (d->outfile == NULL) { + free(d->pixbuf); + free(d); + return NULL; + } - return pixbuf; + return d; } diff --git a/display.h b/display.h index f6e4461..bc5651d 100644 --- a/display.h +++ b/display.h @@ -3,10 +3,10 @@ #include "dcpu16.h" -typedef struct pixel_ DPIX; +typedef struct dcpu16_display_ DCPU16_DISPLAY; void display_reset_fn(struct dcpu16 *, dcpu16_acct_event, DCPU16_WORD, void *); void display_fn(struct dcpu16 *, dcpu16_acct_event, DCPU16_WORD, void *); -DPIX *display_init_pixbuf(void); +DCPU16_DISPLAY *display_new(const char *filename); #endif /* DISPLAY_H_MJYI1IAV */ diff --git a/vm-dcpu16.c b/vm-dcpu16.c index 1e3a496..5f65273 100644 --- a/vm-dcpu16.c +++ b/vm-dcpu16.c @@ -368,31 +368,31 @@ COMMAND_HELP(run) { COMMAND_IMPL(display) { (void)arg_count, (void)arg_vector; - static DPIX *pixbuf = NULL; + static DCPU16_DISPLAY *display = NULL; - if (pixbuf) { + if (display) { printf("display already enabled..\n"); return 0; } - pixbuf = display_init_pixbuf(); - if (pixbuf == NULL) { + display = display_new("dcpu16-display.pnm"); + if (display == NULL) { fprintf(stderr, "failed to initialize display buffer\n"); return 0; } - if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_WRITE, display_fn, pixbuf)) { + if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_WRITE, display_fn, display)) { fprintf(stderr, "failed to register display update callback\n"); return 0; } - if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_RESET, display_reset_fn, pixbuf)) { + if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_RESET, display_reset_fn, display)) { fprintf(stderr, "failed to register display reset callback\n"); return 0; } /* init display as if reset occurred */ - display_reset_fn(vm, DCPU16_ACCT_EV_RESET, 0, pixbuf); + display_reset_fn(vm, DCPU16_ACCT_EV_RESET, 0, display); return 0; } -- 2.43.2