summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/video/tx0.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/video/tx0.c')
-rw-r--r--src/mess/video/tx0.c484
1 files changed, 484 insertions, 0 deletions
diff --git a/src/mess/video/tx0.c b/src/mess/video/tx0.c
new file mode 100644
index 00000000000..750893aec91
--- /dev/null
+++ b/src/mess/video/tx0.c
@@ -0,0 +1,484 @@
+/*
+ TX-0
+
+ Raphael Nabet, 2004
+*/
+
+#include "emu.h"
+
+#include "cpu/pdp1/tx0.h"
+#include "includes/tx0.h"
+#include "video/crt.h"
+
+
+
+
+INLINE void tx0_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color)
+{
+ bitmap.pix16(y, x) = color;
+}
+
+
+static void tx0_draw_panel_backdrop(running_machine &machine, bitmap_ind16 &bitmap);
+static void tx0_draw_panel(running_machine &machine, bitmap_ind16 &bitmap);
+
+
+
+/*
+ video init
+*/
+VIDEO_START( tx0 )
+{
+ tx0_state *state = machine.driver_data<tx0_state>();
+ state->m_typewriter_color = color_typewriter_black;
+
+ /* alloc bitmaps for our private fun */
+ state->m_panel_bitmap.allocate(panel_window_width, panel_window_height, BITMAP_FORMAT_IND16);
+ state->m_typewriter_bitmap.allocate(typewriter_window_width, typewriter_window_height, BITMAP_FORMAT_IND16);
+
+ /* set up out bitmaps */
+ tx0_draw_panel_backdrop(machine, state->m_panel_bitmap);
+
+ const rectangle typewriter_bitmap_bounds(0, typewriter_window_width-1, 0, typewriter_window_height-1);
+ state->m_typewriter_bitmap.fill(pen_typewriter_bg, typewriter_bitmap_bounds);
+
+ state->m_crt = machine.device("crt");
+}
+
+
+SCREEN_VBLANK( tx0 )
+{
+ // rising edge
+ if (vblank_on)
+ {
+ tx0_state *state = screen.machine().driver_data<tx0_state>();
+
+ crt_eof(state->m_crt);
+ }
+}
+
+
+/*
+ schedule a pixel to be plotted
+*/
+void tx0_plot(running_machine &machine, int x, int y)
+{
+ tx0_state *state = machine.driver_data<tx0_state>();
+
+ /* compute pixel coordinates and plot */
+ x = x*crt_window_width/0777;
+ y = y*crt_window_height/0777;
+ crt_plot(state->m_crt, x, y);
+}
+
+
+/*
+ SCREEN_UPDATE_IND16( tx0 ): effectively redraw the screen
+*/
+SCREEN_UPDATE_IND16( tx0 )
+{
+ tx0_state *state = screen.machine().driver_data<tx0_state>();
+ crt_update(state->m_crt, bitmap);
+
+ tx0_draw_panel(screen.machine(), state->m_panel_bitmap);
+ copybitmap(bitmap, state->m_panel_bitmap, 0, 0, panel_window_offset_x, panel_window_offset_y, cliprect);
+
+ copybitmap(bitmap, state->m_typewriter_bitmap, 0, 0, typewriter_window_offset_x, typewriter_window_offset_y, cliprect);
+ return 0;
+}
+
+
+
+/*
+ Operator control panel code
+*/
+
+enum
+{
+ x_panel_col1a_offset = 0,
+ x_panel_col1b_offset = 24,
+ x_panel_col2_offset = x_panel_col1a_offset+184+8
+};
+
+enum
+{
+ /* column 1: registers, test accumulator, test buffer, toggle switch storage */
+ y_panel_pc_offset = 0,
+ y_panel_mar_offset = y_panel_pc_offset+2*8,
+ y_panel_mbr_offset = y_panel_mar_offset+2*8,
+ y_panel_ac_offset = y_panel_mbr_offset+2*8,
+ y_panel_lr_offset = y_panel_ac_offset+2*8,
+ y_panel_xr_offset = y_panel_lr_offset+2*8,
+ y_panel_tbr_offset = y_panel_xr_offset+2*8,
+ y_panel_tac_offset = y_panel_tbr_offset+2*8,
+ y_panel_tss_offset = y_panel_tac_offset+2*8,
+
+ /* column 2: stop c0, stop c1, cm sel, 1-bit indicators, instr, flags */
+ y_panel_stop_c0_offset = 8,
+ y_panel_stop_c1_offset = y_panel_stop_c0_offset+8,
+ y_panel_gbl_cm_sel_offset = y_panel_stop_c1_offset+8,
+ y_panel_run_offset = y_panel_gbl_cm_sel_offset+8,
+ y_panel_cycle1_offset = y_panel_run_offset+8,
+ y_panel_cycle2_offset = y_panel_cycle1_offset+8,
+ y_panel_rim_offset = y_panel_cycle2_offset+8,
+ y_panel_ioh_offset = y_panel_rim_offset+8,
+ y_panel_ios_offset = y_panel_ioh_offset+8,
+ y_panel_ir_offset = y_panel_ios_offset+8,
+ y_panel_pf_offset = y_panel_ir_offset+2*8
+};
+
+/* draw a small 8*8 LED (or is this a lamp? ) */
+static void tx0_draw_led(running_machine &machine, bitmap_ind16 &bitmap, int x, int y, int state)
+{
+ int xx, yy;
+
+ for (yy=1; yy<7; yy++)
+ for (xx=1; xx<7; xx++)
+ tx0_plot_pixel(bitmap, x+xx, y+yy, state ? pen_lit_lamp : pen_unlit_lamp);
+}
+
+/* draw nb_bits leds which represent nb_bits bits in value */
+static void tx0_draw_multipleled(running_machine &machine, bitmap_ind16 &bitmap, int x, int y, int value, int nb_bits)
+{
+ while (nb_bits)
+ {
+ nb_bits--;
+
+ tx0_draw_led(machine, bitmap, x, y, (value >> nb_bits) & 1);
+
+ x += 8;
+ }
+}
+
+
+/* draw a small 8*8 switch */
+static void tx0_draw_switch(running_machine &machine, bitmap_ind16 &bitmap, int x, int y, int state)
+{
+ int xx, yy;
+ int i;
+
+ /* erase area */
+ for (yy=0; yy<8; yy++)
+ for (xx=0; xx<8; xx++)
+ tx0_plot_pixel(bitmap, x+xx, y+yy, pen_panel_bg);
+
+
+ /* draw nut (-> circle) */
+ for (i=0; i<4;i++)
+ {
+ tx0_plot_pixel(bitmap, x+2+i, y+1, pen_switch_nut);
+ tx0_plot_pixel(bitmap, x+2+i, y+6, pen_switch_nut);
+ tx0_plot_pixel(bitmap, x+1, y+2+i, pen_switch_nut);
+ tx0_plot_pixel(bitmap, x+6, y+2+i, pen_switch_nut);
+ }
+ tx0_plot_pixel(bitmap, x+2, y+2, pen_switch_nut);
+ tx0_plot_pixel(bitmap, x+5, y+2, pen_switch_nut);
+ tx0_plot_pixel(bitmap, x+2, y+5, pen_switch_nut);
+ tx0_plot_pixel(bitmap, x+5, y+5, pen_switch_nut);
+
+ /* draw button (->disc) */
+ if (! state)
+ y += 4;
+ for (i=0; i<2;i++)
+ {
+ tx0_plot_pixel(bitmap, x+3+i, y, pen_switch_button);
+ tx0_plot_pixel(bitmap, x+3+i, y+3, pen_switch_button);
+ }
+ for (i=0; i<4;i++)
+ {
+ tx0_plot_pixel(bitmap, x+2+i, y+1, pen_switch_button);
+ tx0_plot_pixel(bitmap, x+2+i, y+2, pen_switch_button);
+ }
+}
+
+
+/* draw nb_bits switches which represent nb_bits bits in value */
+static void tx0_draw_multipleswitch(running_machine &machine, bitmap_ind16 &bitmap, int x, int y, int value, int nb_bits)
+{
+ while (nb_bits)
+ {
+ nb_bits--;
+
+ tx0_draw_switch(machine, bitmap, x, y, (value >> nb_bits) & 1);
+
+ x += 8;
+ }
+}
+
+
+/* write a single char on screen */
+static void tx0_draw_char(running_machine &machine, bitmap_ind16 &bitmap, char character, int x, int y, int color)
+{
+ drawgfx_transpen(bitmap, bitmap.cliprect(), machine.gfx[0], character-32, color, 0, 0,
+ x+1, y, 0);
+}
+
+/* write a string on screen */
+static void tx0_draw_string(running_machine &machine, bitmap_ind16 &bitmap, const char *buf, int x, int y, int color)
+{
+ while (* buf)
+ {
+ tx0_draw_char(machine, bitmap, *buf, x, y, color);
+
+ x += 8;
+ buf++;
+ }
+}
+
+
+/* draw a vertical line */
+static void tx0_draw_vline(bitmap_ind16 &bitmap, int x, int y, int height, int color)
+{
+ while (height--)
+ tx0_plot_pixel(bitmap, x, y++, color);
+}
+
+#ifdef UNUSED_FUNCTION
+/* draw a horizontal line */
+static void tx0_draw_hline(bitmap_ind16 &bitmap, int x, int y, int width, int color)
+{
+ while (width--)
+ tx0_plot_pixel(bitmap, x++, y, color);
+}
+#endif
+
+/*
+ draw the operator control panel (fixed backdrop)
+*/
+static void tx0_draw_panel_backdrop(running_machine &machine, bitmap_ind16 &bitmap)
+{
+ tx0_state *state = machine.driver_data<tx0_state>();
+ int i;
+ char buf[3];
+
+ /* fill with black */
+ const rectangle panel_bitmap_bounds(0, panel_window_width-1, 0, panel_window_height-1);
+ state->m_panel_bitmap.fill(pen_panel_bg, panel_bitmap_bounds);
+
+ /* column 1: registers, test accumulator, test buffer, toggle switch storage */
+ tx0_draw_string(machine, bitmap, "program counter", x_panel_col1b_offset, y_panel_pc_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "memory address reg.", x_panel_col1b_offset, y_panel_mar_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "memory buffer reg.", x_panel_col1b_offset, y_panel_mbr_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "accumulator", x_panel_col1b_offset, y_panel_ac_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "live register", x_panel_col1b_offset, y_panel_lr_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "index register", x_panel_col1b_offset, y_panel_xr_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "TBR", x_panel_col1b_offset, y_panel_tbr_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "TAC", x_panel_col1b_offset, y_panel_tac_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "cm", x_panel_col1a_offset+8, y_panel_tss_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "TSS", x_panel_col1a_offset+24, y_panel_tss_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "lr", x_panel_col1a_offset+168, y_panel_tss_offset, color_panel_caption);
+ for (i=0; i<16; i++)
+ {
+ sprintf(buf, "%2o", i);
+ tx0_draw_string(machine, bitmap, buf, x_panel_col1a_offset, y_panel_tss_offset+8+i*8, color_panel_caption);
+ }
+
+ /* column separator */
+ tx0_draw_vline(bitmap, x_panel_col2_offset-4, 8, 248, pen_panel_caption);
+
+ /* column 2: stop c0, stop c1, cm sel, 1-bit indicators, instr, flags */
+ tx0_draw_string(machine, bitmap, "stop c0", x_panel_col2_offset+8, y_panel_stop_c0_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "stop c1", x_panel_col2_offset+8, y_panel_stop_c1_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "cm select", x_panel_col2_offset+8, y_panel_gbl_cm_sel_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "run", x_panel_col2_offset+8, y_panel_run_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "cycle1", x_panel_col2_offset+8, y_panel_cycle1_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "cycle2", x_panel_col2_offset+8, y_panel_cycle2_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "read in", x_panel_col2_offset+8, y_panel_rim_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "i-o halt", x_panel_col2_offset+8, y_panel_ioh_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "i-o sync", x_panel_col2_offset+8, y_panel_ios_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "instr", x_panel_col2_offset+8, y_panel_ir_offset, color_panel_caption);
+ tx0_draw_string(machine, bitmap, "pgm flags", x_panel_col2_offset+8, y_panel_pf_offset, color_panel_caption);
+}
+
+
+/*
+ draw the operator control panel (dynamic elements)
+*/
+static void tx0_draw_panel(running_machine &machine, bitmap_ind16 &bitmap)
+{
+ int cm_sel, lr_sel;
+ int i;
+
+ /* column 1: registers, test accumulator, test buffer, toggle switch storage */
+ tx0_draw_multipleled(machine, bitmap, x_panel_col1b_offset+2*8, y_panel_pc_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_PC), 16);
+ tx0_draw_multipleled(machine, bitmap, x_panel_col1b_offset+2*8, y_panel_mar_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_MAR), 16);
+ tx0_draw_multipleled(machine, bitmap, x_panel_col1b_offset, y_panel_mbr_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_MBR), 18);
+ tx0_draw_multipleled(machine, bitmap, x_panel_col1b_offset, y_panel_ac_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_AC), 18);
+ tx0_draw_multipleled(machine, bitmap, x_panel_col1b_offset, y_panel_lr_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_LR), 18);
+ tx0_draw_multipleled(machine, bitmap, x_panel_col1b_offset+4*8, y_panel_xr_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_XR), 14);
+ tx0_draw_multipleswitch(machine, bitmap, x_panel_col1b_offset, y_panel_tbr_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_TBR), 18);
+ tx0_draw_multipleswitch(machine, bitmap, x_panel_col1b_offset, y_panel_tac_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_TAC), 18);
+ cm_sel = cpu_get_reg(machine.device("maincpu"), TX0_CM_SEL);
+ lr_sel = cpu_get_reg(machine.device("maincpu"), TX0_LR_SEL);
+ for (i=0; i<16; i++)
+ {
+ tx0_draw_switch(machine, bitmap, x_panel_col1a_offset+16, y_panel_tss_offset+8+i*8, (cm_sel >> i) & 1);
+ tx0_draw_multipleswitch(machine, bitmap, x_panel_col1a_offset+24, y_panel_tss_offset+8+i*8, cpu_get_reg(machine.device("maincpu"), TX0_TSS00+i), 18);
+ tx0_draw_switch(machine, bitmap, x_panel_col1a_offset+168, y_panel_tss_offset+8+i*8, (lr_sel >> i) & 1);
+ }
+
+ /* column 2: stop c0, stop c1, cm sel, 1-bit indicators, instr, flags */
+ tx0_draw_switch(machine, bitmap, x_panel_col2_offset, y_panel_stop_c0_offset, cpu_get_reg(machine.device("maincpu"), TX0_STOP_CYC0));
+ tx0_draw_switch(machine, bitmap, x_panel_col2_offset, y_panel_stop_c1_offset, cpu_get_reg(machine.device("maincpu"), TX0_STOP_CYC1));
+ tx0_draw_switch(machine, bitmap, x_panel_col2_offset, y_panel_gbl_cm_sel_offset, cpu_get_reg(machine.device("maincpu"), TX0_GBL_CM_SEL));
+ tx0_draw_led(machine, bitmap, x_panel_col2_offset, y_panel_run_offset, cpu_get_reg(machine.device("maincpu"), TX0_RUN));
+ tx0_draw_led(machine, bitmap, x_panel_col2_offset, y_panel_cycle1_offset, cpu_get_reg(machine.device("maincpu"), TX0_CYCLE) & 1);
+ tx0_draw_led(machine, bitmap, x_panel_col2_offset, y_panel_cycle2_offset, cpu_get_reg(machine.device("maincpu"), TX0_CYCLE) & 2);
+ tx0_draw_led(machine, bitmap, x_panel_col2_offset, y_panel_rim_offset, cpu_get_reg(machine.device("maincpu"), TX0_RIM));
+ tx0_draw_led(machine, bitmap, x_panel_col2_offset, y_panel_ioh_offset, cpu_get_reg(machine.device("maincpu"), TX0_IOH));
+ tx0_draw_led(machine, bitmap, x_panel_col2_offset, y_panel_ios_offset, cpu_get_reg(machine.device("maincpu"), TX0_IOS));
+ tx0_draw_multipleled(machine, bitmap, x_panel_col2_offset, y_panel_ir_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_IR), 5);
+ tx0_draw_multipleled(machine, bitmap, x_panel_col2_offset, y_panel_pf_offset+8, cpu_get_reg(machine.device("maincpu"), TX0_PF), 6);
+}
+
+
+
+/*
+ Typewriter code
+*/
+
+
+
+
+
+enum
+{
+ typewriter_line_height = 8,
+ typewriter_write_offset_y = typewriter_window_height-typewriter_line_height,
+ typewriter_scroll_step = typewriter_line_height
+};
+
+enum
+{
+ tab_step = 8
+};
+
+
+static void tx0_typewriter_linefeed(running_machine &machine)
+{
+ tx0_state *state = machine.driver_data<tx0_state>();
+ UINT8 buf[typewriter_window_width];
+ int y;
+
+ for (y=0; y<typewriter_window_height-typewriter_scroll_step; y++)
+ {
+ extract_scanline8(state->m_typewriter_bitmap, 0, y+typewriter_scroll_step, typewriter_window_width, buf);
+ draw_scanline8(state->m_typewriter_bitmap, 0, y, typewriter_window_width, buf, machine.pens);
+ }
+
+ const rectangle typewriter_scroll_clear_window(0, typewriter_window_width-1, typewriter_window_height-typewriter_scroll_step, typewriter_window_height-1);
+ state->m_typewriter_bitmap.fill(pen_typewriter_bg, typewriter_scroll_clear_window);
+}
+
+void tx0_typewriter_drawchar(running_machine &machine, int character)
+{
+ tx0_state *state = machine.driver_data<tx0_state>();
+ static const char ascii_table[2][64] =
+ {
+ { /* lower case */
+ '\0', '\0', 'e', '8',
+ '\0', '|', 'a', '3',
+ ' ', '=', 's', '4',
+ 'i', '+', 'u', '2',
+ '\0',/*color shift*/'.', 'd', '5',
+ 'r', '1', 'j', '7',
+ 'n', ',', 'f', '6',
+ 'c', '-', 'k', '\0',
+ 't', '\0', 'z', '\0',/*back space*/
+ 'l', '\0',/*tab*/ 'w', '\0',
+ 'h', '\0',/*carr. return*/'y', '\0',
+ 'p', '\0', 'q', '\0',
+ 'o', '\0',/*stop*/ 'b', '\0',
+ 'g', '\0', '9', '\0',
+ 'm', '\0',/*upper case*/ 'x', '\0',
+ 'v', '\0',/*lower case*/ '0', '\0'/*delete*/
+ },
+ { /* upper case */
+ '\0', '\0', 'E', '\210',
+ '\0', '_', 'A', '\203',
+ ' ', ':', 'S', '\204',
+ 'I', '/', 'U', '\202',
+ '\0',/*color shift*/')', 'D', '\205',
+ 'R', '\201', 'J', '\207',
+ 'N', '(', 'F', '\206',
+ 'C', '\212',/*macron*/ 'K', '\0',
+ 'T', '\0', 'Z', '\0',/*back space*/
+ 'L', '\0',/*tab*/ 'W', '\0',
+ 'H', '\0',/*carr. return*/'Y', '\0',
+ 'P', '\0', 'Q', '\0',
+ 'O', '\0',/*stop*/ 'B', '\0',
+ 'G', '\0', '\211', '\0',
+ 'M', '\0',/*upper case*/ 'X', '\0',
+ 'V', '\0',/*lower case*/ '\200', '\0'/*delete*/
+ }
+ };
+
+
+
+ character &= 0x3f;
+
+ switch (character)
+ {
+ case 020:
+#if 0
+ /* color shift */
+ state->m_typewriter_color = color_typewriter_black;
+ state->m_typewriter_color = color_typewriter_red;
+#endif
+ break;
+
+ case 043:
+ /* Backspace */
+ if (state->m_pos)
+ state->m_pos--;
+ break;
+
+ case 045:
+ /* Tab */
+ state->m_pos = state->m_pos + tab_step - (state->m_pos % tab_step);
+ break;
+
+ case 051:
+ /* Carriage Return */
+ state->m_pos = 0;
+ tx0_typewriter_linefeed( machine );
+ break;
+
+ case 061:
+ /* Stop */
+ /* ?????? */
+ break;
+
+ case 071:
+ /* Upper case */
+ state->m_case_shift = 1;
+ break;
+
+ case 075:
+ /* Lower case */
+ state->m_case_shift = 0;
+ break;
+
+ case 077:
+ /* Delete */
+ /* ?????? */
+ break;
+
+ default:
+ /* Any printable character... */
+
+ if (state->m_pos >= 80)
+ { /* if past right border, wrap around. (Right???) */
+ tx0_typewriter_linefeed( machine ); /* next line */
+ state->m_pos = 0; /* return to start of line */
+ }
+
+ /* print character (lookup ASCII equivalent in table) */
+ tx0_draw_char(machine, state->m_typewriter_bitmap, ascii_table[state->m_case_shift][character],
+ 8*state->m_pos, typewriter_write_offset_y,
+ state->m_typewriter_color); /* print char */
+
+ state->m_pos++; /* step carriage forward */
+ break;
+ }
+}