src/mess/drivers/super80.c
| r1808 | r1809 | |
| 1 | | /* |
| 2 | | super80.c |
| 1 | /* Super80.c written by Robbbert, 2005-2008. See super80.txt for documentation. */ |
| 3 | 2 | |
| 4 | | Super-80 computer sold by Dick Smith Electronics in 1981 as a kit. |
| 5 | | |
| 6 | | Several variants of video hardware: |
| 7 | | * 32*16 monochrome display |
| 8 | | * 32*16 color display |
| 9 | | * 80*24 monochrome display |
| 10 | | * 80*24 color display |
| 11 | | |
| 12 | | We only emulate the first variant for now. |
| 13 | | |
| 14 | | architecture: |
| 15 | | * z80 @ 2MHz |
| 16 | | * 16k, 32k or 48k RAM (>0000->bfff), plus 4k of optional extra RAM in |
| 17 | | >f000->ffff |
| 18 | | * 12k ROM (>c000->efff range) |
| 19 | | */ |
| 20 | | |
| 21 | | #include <math.h> |
| 22 | 3 | #include "driver.h" |
| 23 | | #include "deprecat.h" |
| 24 | | #include "mslegacy.h" |
| 25 | | #include "machine/z80ctc.h" |
| 26 | 4 | #include "machine/z80pio.h" |
| 27 | | #include "machine/z80sio.h" |
| 28 | 5 | #include "cpu/z80/z80daisy.h" |
| 6 | #include "devices/snapquik.h" |
| 7 | #include "devices/cartslot.h" |
| 8 | #include "devices/cassette.h" |
| 9 | #include "devices/z80bin.h" |
| 10 | #include "inputx.h" |
| 29 | 11 | #include "sound/speaker.h" |
| 12 | #include "deprecat.h" /* "Machine" needed for z80pio interrupt */ |
| 30 | 13 | |
| 31 | | static void pio_interrupt(int state); |
| 14 | static UINT8 super80_mhz=2; /* state of bit 2 of port F0 */ |
| 15 | static UINT16 vidpg=0xfe00; /* Home position of video page being displayed */ |
| 16 | static UINT8 int_sw; /* internal 1 mhz flipflop */ |
| 32 | 17 | |
| 33 | | static int vidpg; |
| 34 | | static int charset; |
| 18 | static UINT8 current_palette; /* for super80m and super80v */ |
| 19 | static UINT8 current_charset; /* for super80m */ |
| 35 | 20 | |
| 36 | | static const z80pio_interface z80pio_intf = |
| 21 | /* the rest are for super80v */ |
| 22 | static UINT8 *pcgram; |
| 23 | static int off_x = 0; |
| 24 | static int off_y = 0; |
| 25 | static UINT8 framecnt = 0; |
| 26 | static UINT8 super80v_vid_col=1; // 0 = color ram ; 1 = video ram |
| 27 | static UINT8 super80v_rom_pcg=1; // 0 = prom ; 1 = pcg |
| 28 | static UINT8 mc6845_cursor[15]; // cursor shape |
| 29 | static UINT8 mc6845[20]; /* registers */ |
| 30 | static UINT8 mc6845_reg; /* register index */ |
| 31 | static UINT8 mc6845_mask[]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0}; |
| 32 | |
| 33 | #define SUPER80V_SCREEN_WIDTH (560) |
| 34 | #define SUPER80V_SCREEN_HEIGHT (300) |
| 35 | |
| 36 | /**************************** PALETTES for super80m and super80v ******************************************/ |
| 37 | |
| 38 | static const UINT8 super80_rgb_palette[16*3] = |
| 37 | 39 | { |
| 38 | | pio_interrupt, |
| 39 | | NULL, |
| 40 | | NULL |
| 40 | 0x00, 0x00, 0x00, /* 0 Black */ |
| 41 | 0x00, 0x00, 0x00, /* 1 Black */ |
| 42 | 0x00, 0x00, 0x7f, /* 2 Blue */ |
| 43 | 0x00, 0x00, 0xff, /* 3 Light Blue */ |
| 44 | 0x00, 0x7f, 0x00, /* 4 Green */ |
| 45 | 0x00, 0xff, 0x00, /* 5 Bright Green */ |
| 46 | 0x00, 0x7f, 0x7f, /* 6 Cyan */ |
| 47 | 0x00, 0xff, 0xff, /* 7 Turquoise */ |
| 48 | 0x7f, 0x00, 0x00, /* 8 Dark Red */ |
| 49 | 0xff, 0x00, 0x00, /* 9 Red */ |
| 50 | 0x7f, 0x00, 0x7f, /* 10 Purple */ |
| 51 | 0xff, 0x00, 0xff, /* 11 Magenta */ |
| 52 | 0x7f, 0x7f, 0x00, /* 12 Lime */ |
| 53 | 0xff, 0xff, 0x00, /* 13 Yellow */ |
| 54 | 0xbf, 0xbf, 0xbf, /* 14 Off White */ |
| 55 | 0xff, 0xff, 0xff, /* 15 White */ |
| 41 | 56 | }; |
| 42 | 57 | |
| 43 | | static void pio_interrupt(int state) |
| 58 | static const UINT8 super80_comp_palette[16*3] = |
| 44 | 59 | { |
| 45 | | cpunum_set_input_line(Machine, 0, 0, state); |
| 60 | 0x00, 0x00, 0x00, /* 0 Black */ |
| 61 | 0x80, 0x80, 0x80, /* 1 Grey */ |
| 62 | 0x00, 0x00, 0xff, /* 2 Blue */ |
| 63 | 0xff, 0xff, 0x80, /* 3 Light Yellow */ |
| 64 | 0x00, 0xff, 0x00, /* 4 Green */ |
| 65 | 0xff, 0x80, 0xff, /* 5 Light Magenta */ |
| 66 | 0x00, 0xff, 0xff, /* 6 Cyan */ |
| 67 | 0xff, 0x40, 0x40, /* 7 Light Red */ |
| 68 | 0xff, 0x00, 0x00, /* 8 Red */ |
| 69 | 0x00, 0x80, 0x80, /* 9 Dark Cyan */ |
| 70 | 0xff, 0x00, 0xff, /* 10 Magenta */ |
| 71 | 0x80, 0xff, 0x80, /* 11 Light Green */ |
| 72 | 0xff, 0xff, 0x00, /* 12 Yellow */ |
| 73 | 0x00, 0x00, 0x80, /* 13 Dark Blue */ |
| 74 | 0xff, 0xff, 0xff, /* 14 White */ |
| 75 | 0x00, 0x00, 0x00, /* 15 Black */ |
| 76 | }; |
| 77 | |
| 78 | static void palette_set_colors_rgb(running_machine *machine, const UINT8 *colors) |
| 79 | { |
| 80 | UINT8 r, b, g, color_count = 16; |
| 81 | |
| 82 | while (color_count--) |
| 83 | { |
| 84 | r = *colors++; g = *colors++; b = *colors++; |
| 85 | colortable_palette_set_color(machine->colortable, 15 - color_count, MAKE_RGB(r, g, b)); |
| 86 | } |
| 46 | 87 | } |
| 47 | 88 | |
| 48 | | static void keyboard_scan(void) |
| 89 | static PALETTE_INIT( super80m ) |
| 49 | 90 | { |
| 50 | | UINT8 sel; |
| 51 | 91 | int i; |
| 52 | | UINT8 state = 0xff; |
| 92 | machine->colortable = colortable_alloc(machine, 16); |
| 93 | palette_set_colors_rgb(machine, super80_rgb_palette); |
| 94 | |
| 95 | for( i = 0; i < 256; i++ ) |
| 96 | { |
| 97 | colortable_entry_set_value(machine->colortable, i*2, i>>4); |
| 98 | colortable_entry_set_value(machine->colortable, i*2+1, i&15); |
| 99 | } |
| 100 | } |
| 53 | 101 | |
| 54 | | sel = z80pio_p_r(0, 0); |
| 55 | | for (i=0; i<8; i++) |
| 102 | |
| 103 | /**************************** VIDEO *****************************************************************/ |
| 104 | /* the following are for super80v */ |
| 105 | static READ8_HANDLER( super80v_low_r ) |
| 106 | { |
| 107 | if (!super80v_vid_col) |
| 108 | return colorram[offset]; |
| 109 | else |
| 110 | return videoram[offset]; |
| 111 | } |
| 112 | |
| 113 | static WRITE8_HANDLER( super80v_low_w ) |
| 114 | { |
| 115 | if (!super80v_vid_col) |
| 116 | colorram[offset] = data; |
| 117 | else |
| 118 | videoram[offset] = data; |
| 119 | } |
| 120 | |
| 121 | static READ8_HANDLER( super80v_high_r ) |
| 122 | { |
| 123 | if (!super80v_vid_col) |
| 124 | return colorram[0x800+offset]; |
| 125 | |
| 126 | if (!super80v_rom_pcg) |
| 127 | return pcgram[offset]; |
| 128 | else |
| 129 | return pcgram[0x800+offset]; |
| 130 | } |
| 131 | |
| 132 | static WRITE8_HANDLER( super80v_high_w ) |
| 133 | { |
| 134 | if (!super80v_vid_col) |
| 135 | colorram[offset+0x800] = data; |
| 136 | else |
| 56 | 137 | { |
| 57 | | if (! (sel & (1 << i))) |
| 58 | | state &= readinputport(i); |
| 138 | videoram[offset+0x800] = data; |
| 139 | |
| 140 | if (super80v_rom_pcg) |
| 141 | { |
| 142 | int chr = 0x80 + (offset>>4); |
| 143 | pcgram[0x800+offset] = data; |
| 144 | |
| 145 | /* decode character graphics again */ |
| 146 | decodechar(Machine->gfx[0], chr, pcgram); |
| 147 | } |
| 59 | 148 | } |
| 60 | | z80pio_p_w(0, 1, state); |
| 61 | 149 | } |
| 62 | 150 | |
| 63 | | static TIMER_CALLBACK( reset_timer_callback ) |
| 151 | /* The 6845 can produce a variety of cursor shapes - all are emulated here */ |
| 152 | static void mc6845_cursor_configure(void) |
| 64 | 153 | { |
| 65 | | memory_set_bankptr(1, memory_region(REGION_CPU1) + 0x0000); |
| 154 | UINT8 i,curs_type=0,r9,r10,r11; |
| 155 | |
| 156 | /* curs_type holds the general cursor shape to be created |
| 157 | 0 = no cursor |
| 158 | 1 = partial cursor (only shows on a block of scan lines) |
| 159 | 2 = full cursor |
| 160 | 3 = two-part cursor (has a part at the top and bottom with the middle blank) */ |
| 161 | |
| 162 | for ( i = 0; i < 16; i++) mc6845_cursor[i] = 0; // prepare cursor by erasing old one |
| 163 | |
| 164 | r9 = mc6845[9]; // number of scan lines - 1 |
| 165 | r10 = mc6845[10] & 0x1f; // cursor start line = last 5 bits |
| 166 | r11 = mc6845[11]+1; // cursor end line incremented to suit for-loops below |
| 167 | |
| 168 | /* decide the curs_type by examining the registers */ |
| 169 | if (r10 < r11) curs_type=1; // start less than end, show start to end |
| 170 | else |
| 171 | if (r10 == r11) curs_type=2; // if equal, show full cursor |
| 172 | else curs_type=3; // if start greater than end, it's a two-part cursor |
| 173 | |
| 174 | if ((r11 - 1) > r9) curs_type=2; // if end greater than scan-lines, show full cursor |
| 175 | if (r10 > r9) curs_type=0; // if start greater than scan-lines, then no cursor |
| 176 | if (r11 > 16) r11=16; // truncate 5-bit register to fit our 4-bit hardware |
| 177 | |
| 178 | /* create the new cursor */ |
| 179 | if (curs_type > 1) for (i = 0;i < 16;i++) mc6845_cursor[i]=0xff; // turn on full cursor |
| 180 | |
| 181 | if (curs_type == 1) for (i = r10;i < r11;i++) mc6845_cursor[i]=0xff; // for each line that should show, turn on that scan line |
| 182 | |
| 183 | if (curs_type == 3) for (i = r11; i < r10;i++) mc6845_cursor[i]=0; // now take a bite out of the middle |
| 66 | 184 | } |
| 67 | 185 | |
| 68 | | static MACHINE_RESET( super80 ) |
| 186 | /* Resize the screen within the limits of the hardware. |
| 187 | If we are using dynamic screen resizing, expand the image to fill the screen area */ |
| 188 | static void mc6845_screen_configure(void) |
| 69 | 189 | { |
| 70 | | /* reset PIO */ |
| 71 | | z80pio_init(0, &z80pio_intf); |
| 72 | | z80pio_reset(0); |
| 73 | | keyboard_scan(); |
| 74 | | /* enable ROM in base >0000, and re-enable RAM shortly thereafter */ |
| 75 | | memory_set_bankptr(1, memory_region(REGION_CPU1) + 0xC000); |
| 76 | | timer_set(ATTOTIME_IN_USEC(10), NULL, 0, reset_timer_callback); |
| 190 | screen_state *state = &Machine->screen[0]; |
| 191 | rectangle visarea; |
| 192 | UINT16 width, height, bytes; |
| 193 | UINT8 dyn = readinputport(9) & 0x10; // read dipswitch |
| 194 | visarea.min_x = 0; |
| 195 | visarea.max_x = SUPER80V_SCREEN_WIDTH-1; |
| 196 | visarea.min_y = 0; |
| 197 | visarea.max_y = SUPER80V_SCREEN_HEIGHT-1; |
| 198 | |
| 199 | /* dynamic screen sizing - we must override some user settings */ |
| 200 | if (dyn) |
| 201 | { |
| 202 | mc6845[4] = mc6845[6]; // no band at top or bottom |
| 203 | mc6845[7] = mc6845[6]; // screen starts at the top line |
| 204 | mc6845[5] = 0; // exactly at the top |
| 205 | } |
| 206 | |
| 207 | /* calculate the effect of sync and vertical adjustments */ |
| 208 | if ( mc6845[2] ) off_x = mc6845[0] - mc6845[2] - 23; else off_x = -24; |
| 209 | |
| 210 | off_y = (mc6845[4] - mc6845[7]) * (mc6845[9] + 1) + mc6845[5]; |
| 211 | |
| 212 | if( off_y < 0 ) off_y = 0; |
| 213 | |
| 214 | if( off_y > 128 ) off_y = 128; |
| 215 | |
| 216 | width = mc6845[1]*7-1; // width in pixels |
| 217 | height = mc6845[6]*(mc6845[9]+1)-1; // height in pixels |
| 218 | bytes = mc6845[1]*mc6845[6]-1; // video ram needed -1 |
| 219 | |
| 220 | /* Physically resize the screen now */ |
| 221 | if (dyn) |
| 222 | { |
| 223 | visarea.min_x = 0; |
| 224 | visarea.max_x = width; |
| 225 | visarea.min_y = 0; |
| 226 | visarea.max_y = height; |
| 227 | if ((width < 610) |
| 228 | && (height < 460) /* bounds checking to prevent an assert or violation */ |
| 229 | && (bytes < 0x1000)) |
| 230 | video_screen_configure(0, width+1, height+1, &visarea, state->refresh); |
| 231 | } |
| 232 | else |
| 233 | video_screen_configure(0, SUPER80V_SCREEN_WIDTH, SUPER80V_SCREEN_HEIGHT, &visarea, state->refresh); // in case dipswitch was just turned to NO |
| 77 | 234 | } |
| 78 | 235 | |
| 79 | | static VIDEO_START( super80 ) |
| 236 | static VIDEO_EOF( super80 ) |
| 80 | 237 | { |
| 238 | UINT8 go_fast = 0; |
| 239 | if ((super80_mhz == 2) || (!(readinputport(9) & 2))) /* bit 2 of port F0 is low, OR user turned on config switch */ |
| 240 | go_fast++; |
| 241 | |
| 242 | /* code to slow down computer to 1mhz by halting cpu on every second frame */ |
| 243 | if (!go_fast) |
| 244 | { |
| 245 | if (!int_sw) |
| 246 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it |
| 247 | |
| 248 | int_sw++; |
| 249 | if (int_sw > 1) |
| 250 | { |
| 251 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it |
| 252 | int_sw = 0; |
| 253 | } |
| 254 | } |
| 255 | else |
| 256 | { |
| 257 | if (int_sw < 8) // @2mhz, reset just once |
| 258 | { |
| 259 | cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, CLEAR_LINE); |
| 260 | int_sw = 8; // ...not every time |
| 261 | } |
| 262 | } |
| 81 | 263 | } |
| 82 | 264 | |
| 265 | static VIDEO_EOF( super80v ) |
| 266 | { |
| 267 | /* if we chose another palette or colour mode, enable it */ |
| 268 | UINT8 chosen_palette = (readinputport(9) & 0x60)>>5; // read colour dipswitches |
| 269 | |
| 270 | if (chosen_palette != current_palette) // any changes? |
| 271 | { |
| 272 | current_palette = chosen_palette; // save new palette |
| 273 | if (!current_palette) |
| 274 | palette_set_colors_rgb(machine, super80_comp_palette); // composite colour |
| 275 | else |
| 276 | palette_set_colors_rgb(machine, super80_rgb_palette); // rgb and b&w |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | static VIDEO_EOF( super80m ) |
| 281 | { |
| 282 | VIDEO_EOF_CALL( super80v ); |
| 283 | VIDEO_EOF_CALL( super80 ); |
| 284 | } |
| 285 | |
| 83 | 286 | static VIDEO_UPDATE( super80 ) |
| 84 | 287 | { |
| 85 | | int x, y, chr, col; |
| 86 | | UINT8 *RAM = memory_region(REGION_CPU1) + vidpg; |
| 288 | UINT8 x, y, code=32, screen_on=0; |
| 289 | UINT8 mask = machine->gfx[0]->total_elements - 1; /* 0x3F for super80; 0xFF for super80d & super80e */ |
| 87 | 290 | |
| 291 | if ((super80_mhz == 1) || (!(readinputport(9) & 4))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 292 | screen_on++; |
| 293 | |
| 294 | /* display the picture */ |
| 88 | 295 | for (y=0; y<16; y++) |
| 296 | { |
| 89 | 297 | for (x=0; x<32; x++) |
| 90 | 298 | { |
| 91 | | chr = *RAM++; |
| 92 | | if (charset) |
| 299 | if (screen_on) |
| 300 | code = program_read_byte(vidpg + x + (y<<5)); |
| 301 | |
| 302 | drawgfx(bitmap, machine->gfx[0], code & mask, 0, 0, 0, x*8, y*10, |
| 303 | &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | return 0; |
| 308 | } |
| 309 | |
| 310 | static VIDEO_UPDATE( super80m ) |
| 311 | { |
| 312 | UINT8 x, y, code=32, col=0, screen_on=0, options=readinputport(9); |
| 313 | |
| 314 | /* get selected character generator */ |
| 315 | UINT8 cgen = current_charset ^ ((options & 0x10)>>4); /* bit 0 of port F1 and cgen config switch */ |
| 316 | |
| 317 | if ((super80_mhz == 1) || (!(options & 4))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 318 | screen_on++; |
| 319 | |
| 320 | if (screen_on) |
| 321 | { |
| 322 | if ((options & 0x60) == 0x60) |
| 323 | col = 15; /* b&w */ |
| 324 | else |
| 325 | col = 5; /* green */ |
| 326 | } |
| 327 | |
| 328 | /* display the picture */ |
| 329 | for (y=0; y<16; y++) |
| 330 | { |
| 331 | for (x=0; x<32; x++) |
| 332 | { |
| 333 | if (screen_on) |
| 93 | 334 | { |
| 94 | | col = (chr & 0x80) ? 1 : 0; |
| 95 | | chr &= 0x7f; |
| 335 | code = program_read_byte(vidpg + x + (y<<5)); /* get character to display */ |
| 336 | |
| 337 | if (!(options & 0x40)) col = program_read_byte(0xfe00 + x + (y<<5)); /* byte of colour to display */ |
| 96 | 338 | } |
| 97 | | else |
| 98 | | col = 0; |
| 99 | | drawgfx(bitmap, machine->gfx[charset], chr, col, 0, 0, x*8, y*10, |
| 100 | | &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); |
| 339 | |
| 340 | drawgfx(bitmap, machine->gfx[cgen], code, col, 0, 0, x*8, y*10, |
| 341 | &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); |
| 101 | 342 | } |
| 343 | } |
| 344 | |
| 102 | 345 | return 0; |
| 103 | 346 | } |
| 104 | 347 | |
| 105 | | /* |
| 106 | | port $F0: General Purpose output port |
| 107 | | Bit 0 - cassette output |
| 108 | | Bit 1 - cassette relay control; 0=relay on |
| 109 | | Bit 2 - turns screen on and off;0=screen off |
| 110 | | Bit 3 - Available for user projects [We will use it for sound] |
| 111 | | Bit 4 - Available for user projects [We will use it for video switching] |
| 112 | | Bit 5 - cassette LED; 0=LED on |
| 113 | | Bit 6/7 - not decoded |
| 114 | | */ |
| 115 | | static WRITE8_HANDLER (super80_gpo_w) |
| 348 | static VIDEO_UPDATE( super80v ) |
| 116 | 349 | { |
| 117 | | speaker_level_w(0, (data & 0x08) ? 1 : 0); |
| 118 | | charset = (data & 0x10) ? 1 : 0; |
| 350 | UINT16 i, bytes = mc6845[1]*mc6845[6]; |
| 351 | UINT8 speed = mc6845[10]&0x20, flash = mc6845[10]&0x40; // cursor modes |
| 352 | UINT16 cursor = (mc6845[14]<<8) | mc6845[15]; // get cursor position |
| 353 | UINT16 screen_home = (mc6845[12]<<8) | mc6845[13]; // screen home offset (usually zero) |
| 354 | UINT8 options=readinputport(9); |
| 355 | framecnt++; |
| 356 | |
| 357 | /* Get the graphics of the character under the cursor, xor with the visible cursor scan lines, |
| 358 | and store as character number 256. If inverse mode, drop bit 7 of character before xoring */ |
| 359 | if (!super80v_rom_pcg) |
| 360 | for ( i = 0; i < 16; i++) |
| 361 | pcgram[0x1000+i] = pcgram[(videoram[cursor]&0x7f)*16+i] ^ mc6845_cursor[i]; |
| 362 | else |
| 363 | for ( i = 0; i < 16; i++) |
| 364 | pcgram[0x1000+i] = pcgram[(videoram[cursor])*16 + i] ^ mc6845_cursor[i]; |
| 365 | |
| 366 | decodechar(machine->gfx[0],256, pcgram); // and into machine graphics |
| 367 | |
| 368 | for( i = screen_home; (i < (bytes + screen_home)) & (i < 0x1000); i++ ) |
| 369 | { |
| 370 | int sx, sy, chr, col; |
| 371 | sy = off_y + ((i - screen_home) / mc6845[1]) * (mc6845[9] + 1); |
| 372 | sx = (off_x + ((i - screen_home) % mc6845[1])) * 7; |
| 373 | chr = videoram[i]; |
| 374 | |
| 375 | /* get colour or b&w */ |
| 376 | if ((options & 0x60) == 0x60) col = 15; /* b&w */ |
| 377 | else col = 5; /* green */ |
| 378 | if (!(options & 0x40)) col = colorram[i]; // read a byte of colour |
| 379 | |
| 380 | if ((!super80v_rom_pcg) && (chr > 0x7f)) // is it a high chr in inverse mode |
| 381 | { |
| 382 | col = BITSWAP8(col,3,2,1,0,7,6,5,4); // swap nibbles |
| 383 | chr &= 0x7f; // and drop bit 7 |
| 384 | } |
| 385 | |
| 386 | /* if cursor is on and we are at cursor position, show it */ |
| 387 | /* NOTE: flash rates obtained from real hardware */ |
| 388 | |
| 389 | if ((((!flash) && (!speed)) || // (5,6)=(0,0) = cursor on always |
| 390 | ((flash) && (speed) && (framecnt & 0x10)) || // (5,6)=(1,1) = cycle per 32 frames |
| 391 | ((flash) && (!speed) && (framecnt & 8))) && // (5,6)=(0,1) = cycle per 16 frames |
| 392 | (i == cursor)) // displaying at cursor position? |
| 393 | chr = 256; // 256 = cursor character |
| 394 | |
| 395 | drawgfx( bitmap,Machine->gfx[0],chr,col,0,0,sx,sy, |
| 396 | &Machine->screen[0].visarea,TRANSPARENCY_NONE,0); // put character on the screen |
| 397 | |
| 398 | } |
| 399 | |
| 400 | return 0; |
| 119 | 401 | } |
| 120 | 402 | |
| 121 | | /* |
| 122 | | port $F1: Video page output port |
| 123 | | Bit 0 - not decoded |
| 124 | | Bits 1 to 7 - choose video page to display |
| 125 | | Bit 1 controls A9, bit 2 does A10, etc |
| 126 | | */ |
| 127 | | static WRITE8_HANDLER (super80_vidpg_w) |
| 403 | /**************************** PIO ******************************************************************************/ |
| 404 | |
| 405 | static void pio_interrupt(int state) |
| 128 | 406 | { |
| 129 | | vidpg = (data & ~1) << 8; |
| 407 | cpunum_set_input_line( Machine, 0, 0, state ? ASSERT_LINE : CLEAR_LINE ); |
| 130 | 408 | } |
| 131 | 409 | |
| 132 | | /* |
| 133 | | port $F2: General purpose input port |
| 134 | | Bit 0 - cassette input |
| 135 | | Bit 1 - Available for user projects |
| 136 | | Bit 2 - Available for user projects |
| 137 | | Bit 3 - not decoded |
| 138 | | Bit 4 - Switch A [These switches are actual DIP switches on the motherboard] |
| 139 | | Bit 5 - Switch B |
| 140 | | Bit 6 - Switch C |
| 141 | | Bit 7 - Switch D |
| 142 | | */ |
| 143 | | static READ8_HANDLER (super80_gpi_r) |
| 410 | static const z80pio_interface pio_intf = |
| 144 | 411 | { |
| 145 | | return 0; |
| 412 | pio_interrupt, /* callback when change interrupt status */ |
| 413 | NULL, /* portA ready active callback (not used in super80) */ |
| 414 | NULL /* portB ready active callback (not used in super80) */ |
| 415 | }; |
| 416 | |
| 417 | |
| 418 | static const struct z80_irq_daisy_chain super80_daisy_chain[] = |
| 419 | { |
| 420 | { z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 0 }, |
| 421 | { 0, 0, 0, 0, -1} /* end mark */ |
| 422 | }; |
| 423 | |
| 424 | /**************************** CASSETTE ROUTINES *****************************************************************/ |
| 425 | |
| 426 | static mess_image *cassette_device_image(void) |
| 427 | { |
| 428 | return image_from_devtype_and_index(IO_CASSETTE, 0); |
| 146 | 429 | } |
| 147 | 430 | |
| 148 | | static WRITE8_HANDLER (super80_z80pio_w) |
| 431 | static void cassette_motor( UINT8 data ) |
| 149 | 432 | { |
| 150 | | //z80pio_0_w(offset, data); |
| 151 | | if (offset == 0) |
| 152 | | /* port A write: scan keyboard */ |
| 153 | | keyboard_scan(); |
| 433 | if (data) |
| 434 | cassette_change_state(image_from_devtype_and_index(IO_CASSETTE, 0), CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); |
| 435 | else |
| 436 | cassette_change_state(image_from_devtype_and_index(IO_CASSETTE, 0), CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); |
| 437 | |
| 438 | /* does user want to hear the sound? */ |
| 439 | if (readinputport(9) & 8) |
| 440 | cassette_change_state(image_from_devtype_and_index(IO_CASSETTE, 0), CASSETTE_SPEAKER_ENABLED, CASSETTE_MASK_SPEAKER); |
| 441 | else |
| 442 | cassette_change_state(image_from_devtype_and_index(IO_CASSETTE, 0), CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER); |
| 154 | 443 | } |
| 155 | 444 | |
| 156 | | static ADDRESS_MAP_START(super80_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 157 | | AM_RANGE(0x0000, 0x0fff) AM_READWRITE(MRA8_BANK1, MWA8_RAM) |
| 158 | | AM_RANGE(0x1000, 0xbfff) AM_RAM |
| 445 | /********************************************* TIMER ************************************************/ |
| 446 | |
| 447 | static UINT8 wave_length, last_wave_state=0, cass_out; |
| 448 | |
| 449 | /* this timer runs at 200khz and does 2 jobs: |
| 450 | 1. Scan the keyboard and present the results to the pio |
| 451 | 2. Emulate the 2 chips in the cassette input circuit |
| 452 | |
| 453 | Reasons why it is necessary: |
| 454 | 1. The real z80pio is driven by the cpu clock and is capable of independent actions. |
| 455 | MAME does not support this at all. If the interrupt key sequence is entered, the |
| 456 | computer can be reset out of a hung state by the operator. |
| 457 | 2. This "emulates" U79 CD4046BCN PLL chip and U1 LM311P op-amp. U79 converts a frequency to a voltage, |
| 458 | and U1 amplifies that voltage to digital levels. U1 has a trimpot connected, to set the midpoint. */ |
| 459 | |
| 460 | static TIMER_CALLBACK( super80_timer ) |
| 461 | { |
| 462 | UINT8 wave_state=0, i, mask=1, out_f8=z80pio_p_r(0,0), in_fa=255; |
| 463 | |
| 464 | for ( i=1; i < 9;i++) |
| 465 | { |
| 466 | if (!(out_f8 & mask)) in_fa &= readinputport(i); |
| 467 | mask<<=1; |
| 468 | } |
| 469 | |
| 470 | z80pio_p_w(0,1,in_fa); |
| 471 | |
| 472 | if (cassette_input(cassette_device_image()) > +0.03) wave_state+=2; |
| 473 | |
| 474 | if (wave_state == last_wave_state) |
| 475 | wave_length++; |
| 476 | else |
| 477 | { |
| 478 | last_wave_state = wave_state; |
| 479 | cass_out = wave_state; |
| 480 | if (wave_length < 0x40) cass_out++; |
| 481 | wave_length = 0; |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | /**************************** I/O PORTS *****************************************************************/ |
| 486 | |
| 487 | static READ8_HANDLER( super80v_11_r ) |
| 488 | { |
| 489 | if ((mc6845_reg > 13) && (mc6845_reg < 18)) /* determine readable registers */ |
| 490 | return mc6845[mc6845_reg]; |
| 491 | else |
| 492 | return 0; |
| 493 | } |
| 494 | |
| 495 | static READ8_HANDLER( super80_f2_r ) |
| 496 | { |
| 497 | UINT8 data = readinputport(0) & 0xf0; // dip switches on pcb |
| 498 | data |= cass_out; // bit 0 = output of U1, bit 1 = current wave_state |
| 499 | data |= 0x0c; // bits 2,3 - not used |
| 500 | return data; |
| 501 | } |
| 502 | |
| 503 | static WRITE8_HANDLER( super80v_10_w ) |
| 504 | { |
| 505 | if (data < 18) mc6845_reg = data; else mc6845_reg = 19; /* make sure if you try using an invalid register your write will go nowhere */ |
| 506 | } |
| 507 | |
| 508 | static WRITE8_HANDLER( super80v_11_w ) |
| 509 | { |
| 510 | if (mc6845_reg < 16) mc6845[mc6845_reg] = data & mc6845_mask[mc6845_reg]; /* save data in register */ |
| 511 | if (mc6845_reg < 10) mc6845_screen_configure(); /* adjust screen size */ |
| 512 | if ((mc6845_reg > 8) && (mc6845_reg < 12)) mc6845_cursor_configure(); /* adjust cursor shape */ |
| 513 | } |
| 514 | |
| 515 | static UINT8 last_data; |
| 516 | |
| 517 | static WRITE8_HANDLER( super80_f0_w ) |
| 518 | { |
| 519 | UINT8 bits = data ^ last_data; |
| 520 | |
| 521 | if (bits & 0x20) set_led_status(2,(data & 32) ? 0 : 1); /* bit 5 - LED - scroll lock led is used */ |
| 522 | speaker_level_w(0, (data & 8) ? 0 : 1); /* bit 3 - speaker */ |
| 523 | super80_mhz = (data & 4) ? 1 : 2; /* bit 2 - video on/off */ |
| 524 | if (bits & 0x02) cassette_motor( data & 2 ? 1 : 0); /* bit 1 - cassette motor */ |
| 525 | if (bits & 0x01) cassette_output(cassette_device_image(), (data & 1) ? -1.0 : +1.0); /* bit 0 - cass out */ |
| 526 | |
| 527 | last_data = data; |
| 528 | } |
| 529 | |
| 530 | static WRITE8_HANDLER( super80v_f0_w ) |
| 531 | { |
| 532 | UINT8 bits = data ^ last_data; |
| 533 | |
| 534 | if (bits & 0x20) set_led_status(2,(data & 32) ? 0 : 1); /* bit 5 - LED - scroll lock led is used */ |
| 535 | super80v_rom_pcg = data & 0x10; /* bit 4 - bankswitch gfx rom or pcg */ |
| 536 | speaker_level_w(0, (data & 8) ? 0 : 1); /* bit 3 - speaker */ |
| 537 | super80v_vid_col = data & 4; /* bit 2 - bankswitch video or colour ram */ |
| 538 | if (bits & 0x02) cassette_motor( data & 2 ? 1 : 0); /* bit 1 - cassette motor */ |
| 539 | if (bits & 0x01) cassette_output(cassette_device_image(), (data & 1) ? -1.0 : +1.0); /* bit 0 - cass out */ |
| 540 | |
| 541 | last_data = data; |
| 542 | } |
| 543 | |
| 544 | static WRITE8_HANDLER( super80_f1_w ) |
| 545 | { |
| 546 | vidpg = (data & 0xfe) << 8; |
| 547 | current_charset = data & 1; |
| 548 | } |
| 549 | |
| 550 | static READ8_HANDLER( super80_f8_r ) { return z80pio_d_r (0,0); } |
| 551 | static READ8_HANDLER( super80_f9_r ) { return z80pio_c_r (0,0); } |
| 552 | static READ8_HANDLER( super80_fa_r ) { return z80pio_d_r (0,1); } |
| 553 | static READ8_HANDLER( super80_fb_r ) { return z80pio_c_r (0,1); } |
| 554 | static WRITE8_HANDLER( super80_f8_w ) { z80pio_d_w(0,0, data); } |
| 555 | static WRITE8_HANDLER( super80_f9_w ) { z80pio_c_w(0,0, data); } |
| 556 | static WRITE8_HANDLER( super80_fa_w ) { z80pio_d_w(0,1, data); } |
| 557 | static WRITE8_HANDLER( super80_fb_w ) { z80pio_c_w(0,1, data); } |
| 558 | |
| 559 | /**************************** MEMORY AND I/O MAPPINGS *****************************************************************/ |
| 560 | |
| 561 | static READ8_HANDLER( super80_read_ff ) { return 0xff; } /* returns the true state of unmapped memory */ |
| 562 | |
| 563 | static ADDRESS_MAP_START( super80_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 564 | AM_RANGE(0x0000, 0x3fff) AM_RAMBANK(1) |
| 565 | AM_RANGE(0x4000, 0xbfff) AM_RAM |
| 159 | 566 | AM_RANGE(0xc000, 0xefff) AM_ROM |
| 567 | AM_RANGE(0xf000, 0xffff) AM_READWRITE(super80_read_ff, MWA8_NOP) |
| 568 | ADDRESS_MAP_END |
| 569 | |
| 570 | static ADDRESS_MAP_START( super80m_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 571 | AM_RANGE(0x0000, 0x3fff) AM_RAMBANK(1) |
| 572 | AM_RANGE(0x4000, 0xbfff) AM_RAM |
| 573 | AM_RANGE(0xc000, 0xefff) AM_ROM |
| 160 | 574 | AM_RANGE(0xf000, 0xffff) AM_RAM |
| 161 | 575 | ADDRESS_MAP_END |
| 162 | 576 | |
| 163 | | static READ8_HANDLER( pio_0_r ) |
| 164 | | { |
| 165 | | return (offset & 2) ? z80pio_c_r(0, offset & 1) : z80pio_d_r(0, offset & 1); |
| 166 | | } |
| 577 | static ADDRESS_MAP_START( super80v_map, ADDRESS_SPACE_PROGRAM, 8) |
| 578 | AM_RANGE(0x0000, 0x3fff) AM_RAMBANK(1) |
| 579 | AM_RANGE(0x4000, 0xbfff) AM_RAM |
| 580 | AM_RANGE(0xc000, 0xefff) AM_ROM |
| 581 | AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(super80v_low_r, super80v_low_w) AM_BASE(&pcgram) |
| 582 | AM_RANGE(0xf800, 0xffff) AM_READWRITE(super80v_high_r, super80v_high_w) |
| 583 | ADDRESS_MAP_END |
| 167 | 584 | |
| 168 | | static ADDRESS_MAP_START(super80_ports, ADDRESS_SPACE_IO, 8) |
| 169 | | //AM_RANGE(0xdc, 0xdc) AM_READWRITE(super80_parallel_r, super80_parallel_w) |
| 170 | | //AM_RANGE(0xdd, 0xdd) AM_READWRITE(super80_serial0_r, super80_serial0_w) |
| 171 | | //AM_RANGE(0xde, 0xde) AM_READWRITE(super80_serial1_r, super80_serial1_w) |
| 172 | | AM_RANGE(0xf0, 0xf0) AM_WRITE(super80_gpo_w) |
| 173 | | AM_RANGE(0xf1, 0xf1) AM_WRITE(super80_vidpg_w) |
| 174 | | AM_RANGE(0xf2, 0xf2) AM_READ(super80_gpi_r) |
| 175 | | AM_RANGE(0xf8, 0xfb) AM_READWRITE(pio_0_r, super80_z80pio_w) |
| 585 | static ADDRESS_MAP_START( super80_io, ADDRESS_SPACE_IO, 8 ) |
| 586 | ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) |
| 587 | AM_RANGE(0x00, 0xdf) AM_READWRITE(super80_read_ff, MWA8_NOP) |
| 588 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x14) AM_READWRITE(super80_read_ff, super80_f0_w) |
| 589 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x14) AM_READWRITE(super80_read_ff, super80_f1_w) |
| 590 | AM_RANGE(0xe2, 0xe2) AM_MIRROR(0x14) AM_READWRITE(super80_f2_r, MWA8_NOP) |
| 591 | AM_RANGE(0xe3, 0xe3) AM_MIRROR(0x14) AM_READWRITE(super80_read_ff, MWA8_NOP) /* decoded but not connected to anything */ |
| 592 | AM_RANGE(0xe8, 0xef) AM_READWRITE(super80_read_ff, MWA8_NOP) |
| 593 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x04) AM_READWRITE(super80_f8_r,super80_f8_w) |
| 594 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x04) AM_READWRITE(super80_f9_r,super80_f9_w) |
| 595 | AM_RANGE(0xfa, 0xfa) AM_MIRROR(0x04) AM_READWRITE(super80_fa_r,super80_fa_w) |
| 596 | AM_RANGE(0xfb, 0xfb) AM_MIRROR(0x04) AM_READWRITE(super80_fb_r,super80_fb_w) |
| 176 | 597 | ADDRESS_MAP_END |
| 177 | 598 | |
| 599 | static ADDRESS_MAP_START( super80v_io, ADDRESS_SPACE_IO, 8 ) |
| 600 | ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) |
| 601 | AM_RANGE(0x00, 0x0f) AM_READWRITE(super80_read_ff, MWA8_NOP) |
| 602 | AM_RANGE(0x10, 0x10) AM_READWRITE(super80_read_ff, super80v_10_w) |
| 603 | AM_RANGE(0x11, 0x11) AM_READWRITE(super80v_11_r, super80v_11_w) |
| 604 | AM_RANGE(0x12, 0xdf) AM_READWRITE(super80_read_ff, MWA8_NOP) |
| 605 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x14) AM_READWRITE(super80_read_ff, super80v_f0_w) |
| 606 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x14) AM_READWRITE(super80_read_ff, MWA8_NOP) /* decoded but not connected to anything */ |
| 607 | AM_RANGE(0xe2, 0xe2) AM_MIRROR(0x14) AM_READWRITE(super80_f2_r, MWA8_NOP) |
| 608 | AM_RANGE(0xe3, 0xe3) AM_MIRROR(0x14) AM_READWRITE(super80_read_ff, MWA8_NOP) /* decoded but not connected to anything */ |
| 609 | AM_RANGE(0xe8, 0xef) AM_READWRITE(super80_read_ff, MWA8_NOP) |
| 610 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x04) AM_READWRITE(super80_f8_r,super80_f8_w) |
| 611 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x04) AM_READWRITE(super80_f9_r,super80_f9_w) |
| 612 | AM_RANGE(0xfa, 0xfa) AM_MIRROR(0x04) AM_READWRITE(super80_fa_r,super80_fa_w) |
| 613 | AM_RANGE(0xfb, 0xfb) AM_MIRROR(0x04) AM_READWRITE(super80_fb_r,super80_fb_w) |
| 614 | ADDRESS_MAP_END |
| 615 | |
| 616 | /**************************** DIPSWITCHES, KEYBOARD, HARDWARE CONFIGURATION ****************************************/ |
| 617 | |
| 178 | 618 | static INPUT_PORTS_START( super80 ) |
| 619 | PORT_START |
| 620 | PORT_BIT( 0xf, 0xf, IPT_UNUSED ) |
| 621 | PORT_DIPNAME( 0x10, 0x00, "Switch A") PORT_DIPLOCATION("SW1:1") |
| 622 | PORT_DIPSETTING( 0x10, DEF_STR(Off)) |
| 623 | PORT_DIPSETTING( 0x00, DEF_STR(On)) |
| 624 | PORT_DIPNAME( 0x20, 0x20, "Switch B") PORT_DIPLOCATION("SW1:2") |
| 625 | PORT_DIPSETTING( 0x20, DEF_STR(Off)) |
| 626 | PORT_DIPSETTING( 0x00, DEF_STR(On)) |
| 627 | PORT_DIPNAME( 0x40, 0x40, "Switch C") PORT_DIPLOCATION("SW1:3") |
| 628 | PORT_DIPSETTING( 0x40, DEF_STR(Off)) |
| 629 | PORT_DIPSETTING( 0x00, DEF_STR(On)) |
| 630 | PORT_DIPNAME( 0x80, 0x00, "Switch D") PORT_DIPLOCATION("SW1:4") |
| 631 | PORT_DIPSETTING( 0x80, DEF_STR(Off)) |
| 632 | PORT_DIPSETTING( 0x00, DEF_STR(On)) |
| 633 | |
| 179 | 634 | PORT_START /* line 0 */ |
| 180 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_TILDE) |
| 181 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) |
| 182 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) |
| 183 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) |
| 184 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) |
| 185 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) |
| 186 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) |
| 187 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_LALT) |
| 635 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('@') PORT_CHAR('`') |
| 636 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') |
| 637 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') |
| 638 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') |
| 639 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') |
| 640 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') |
| 641 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| 642 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_LALT) |
| 188 | 643 | PORT_START /* line 1 */ |
| 189 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) |
| 190 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) |
| 191 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) |
| 192 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) |
| 193 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) |
| 194 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_QUOTE) |
| 195 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) |
| 196 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) |
| 644 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') |
| 645 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') |
| 646 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') |
| 647 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') |
| 648 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') |
| 649 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') |
| 650 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 651 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) |
| 197 | 652 | PORT_START /* line 2 */ |
| 198 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) |
| 199 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) |
| 200 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) |
| 201 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) |
| 202 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) |
| 203 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) |
| 204 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) |
| 205 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 653 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') |
| 654 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') |
| 655 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') |
| 656 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') |
| 657 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') |
| 658 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') |
| 659 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) |
| 660 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Fire)") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) |
| 206 | 661 | PORT_START /* line 3 */ |
| 207 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) |
| 208 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) |
| 209 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) |
| 210 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) |
| 211 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) |
| 212 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) |
| 213 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINEFEED") PORT_CODE(KEYCODE_ENTER_PAD) |
| 214 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) |
| 662 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') |
| 663 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') |
| 664 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') |
| 665 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') |
| 666 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') |
| 667 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') |
| 668 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINEFEED") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(10) |
| 669 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) |
| 215 | 670 | PORT_START /* line 4 */ |
| 216 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) |
| 217 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) |
| 218 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) |
| 219 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\")PORT_CODE(KEYCODE_BACKSLASH) |
| 220 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) |
| 221 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_NUMLOCK) |
| 222 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) |
| 223 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 671 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') |
| 672 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') |
| 673 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') |
| 674 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |")PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') |
| 675 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') |
| 676 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(3) |
| 677 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 678 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Right)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) |
| 224 | 679 | PORT_START /* line 5 */ |
| 225 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) |
| 226 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) |
| 227 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) |
| 228 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) |
| 229 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) |
| 230 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) |
| 231 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) |
| 232 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 680 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') |
| 681 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') |
| 682 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') |
| 683 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') |
| 684 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') |
| 685 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') |
| 686 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) |
| 687 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Left)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) |
| 233 | 688 | PORT_START /* line 6 */ |
| 234 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) |
| 235 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) |
| 236 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) |
| 237 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^") PORT_CODE(KEYCODE_EQUALS) |
| 238 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) |
| 239 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) |
| 240 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) |
| 241 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 689 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') |
| 690 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') |
| 691 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') |
| 692 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('~') |
| 693 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \'") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') |
| 694 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') |
| 695 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) |
| 696 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Down)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) |
| 242 | 697 | PORT_START /* line 7 */ |
| 243 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) |
| 244 | | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) |
| 245 | | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) |
| 246 | | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) |
| 247 | | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) |
| 248 | | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) |
| 249 | | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) |
| 250 | | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) |
| 698 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') |
| 699 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') |
| 700 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') |
| 701 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') |
| 702 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') |
| 703 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(' ') |
| 704 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) |
| 705 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Up)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) |
| 706 | |
| 707 | /* Enhanced options not available on real hardware */ |
| 708 | PORT_START_TAG("CONFIG") |
| 709 | PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") |
| 710 | PORT_CONFSETTING( 0x00, DEF_STR(No)) |
| 711 | PORT_CONFSETTING( 0x01, DEF_STR(Yes)) |
| 712 | PORT_CONFNAME( 0x02, 0x02, "2 Mhz always") |
| 713 | PORT_CONFSETTING( 0x02, DEF_STR(No)) |
| 714 | PORT_CONFSETTING( 0x00, DEF_STR(Yes)) |
| 715 | PORT_CONFNAME( 0x04, 0x04, "Screen on always") |
| 716 | PORT_CONFSETTING( 0x04, DEF_STR(No)) |
| 717 | PORT_CONFSETTING( 0x00, DEF_STR(Yes)) |
| 718 | PORT_CONFNAME( 0x08, 0x08, "Cassette Speaker") |
| 719 | PORT_CONFSETTING( 0x08, DEF_STR(On)) |
| 720 | PORT_CONFSETTING( 0x00, DEF_STR(Off)) |
| 251 | 721 | INPUT_PORTS_END |
| 252 | 722 | |
| 253 | | static const gfx_layout super80_elg4_charlayout = |
| 723 | static INPUT_PORTS_START( super80m ) |
| 724 | PORT_INCLUDE( super80 ) |
| 725 | |
| 726 | PORT_MODIFY("CONFIG") |
| 727 | |
| 728 | /* Enhanced options not available on real hardware */ |
| 729 | PORT_CONFNAME( 0x10, 0x10, "Swap CharGens") |
| 730 | PORT_CONFSETTING( 0x10, DEF_STR(No)) |
| 731 | PORT_CONFSETTING( 0x00, DEF_STR(Yes)) |
| 732 | PORT_CONFNAME( 0x60, 0x40, "Colour") |
| 733 | PORT_CONFSETTING( 0x60, "MonoChrome") |
| 734 | PORT_CONFSETTING( 0x40, "Green") |
| 735 | PORT_CONFSETTING( 0x00, "Composite") |
| 736 | PORT_CONFSETTING( 0x20, "RGB") |
| 737 | INPUT_PORTS_END |
| 738 | |
| 739 | static INPUT_PORTS_START( super80v ) |
| 740 | PORT_INCLUDE( super80m ) |
| 741 | |
| 742 | PORT_MODIFY("CONFIG") |
| 743 | |
| 744 | /* Enhanced options not available on real hardware */ |
| 745 | PORT_BIT( 0x6, 0x6, IPT_UNUSED ) |
| 746 | PORT_CONFNAME( 0x10, 0x10, "Auto-Resize?") |
| 747 | PORT_CONFSETTING( 0x00, DEF_STR(No)) |
| 748 | PORT_CONFSETTING( 0x10, DEF_STR(Yes)) |
| 749 | INPUT_PORTS_END |
| 750 | |
| 751 | /**************************** GRAPHICS DECODE *****************************************************************/ |
| 752 | |
| 753 | static const gfx_layout super80_charlayout = |
| 254 | 754 | { |
| 255 | 755 | 8,10, /* 8 x 10 characters */ |
| 256 | | 256, /* 256 characters */ |
| 756 | 64, /* 64 characters */ |
| 257 | 757 | 1, /* 1 bits per pixel */ |
| 258 | 758 | { 0 }, /* no bitplanes; 1 bit per pixel */ |
| 259 | 759 | /* x offsets */ |
| r1808 | r1809 | |
| 264 | 764 | 8*16 /* every char takes 16 bytes */ |
| 265 | 765 | }; |
| 266 | 766 | |
| 267 | | static const gfx_layout super80_dslc_charlayout = |
| 767 | static const gfx_layout super80d_charlayout = |
| 268 | 768 | { |
| 269 | 769 | 8,10, /* 8 x 10 characters */ |
| 270 | | 128, /* 128 characters */ |
| 770 | 256, /* 256 characters */ |
| 271 | 771 | 1, /* 1 bits per pixel */ |
| 272 | 772 | { 0 }, /* no bitplanes; 1 bit per pixel */ |
| 273 | 773 | /* x offsets */ |
| r1808 | r1809 | |
| 278 | 778 | 8*16 /* every char takes 16 bytes */ |
| 279 | 779 | }; |
| 280 | 780 | |
| 781 | static const gfx_layout super80v_charlayout = |
| 782 | { |
| 783 | 8,16, /* 8 x 16 characters */ |
| 784 | 257, /* 256 characters + cursor character */ |
| 785 | 1, /* 1 bits per pixel */ |
| 786 | { 0 }, /* no bitplanes; 1 bit per pixel */ |
| 787 | /* x offsets */ |
| 788 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 789 | /* y offsets triple height: use each line three times */ |
| 790 | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, |
| 791 | 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, |
| 792 | 8*16 /* every char takes 16 bytes */ |
| 793 | }; |
| 794 | |
| 281 | 795 | static GFXDECODE_START( super80 ) |
| 282 | | GFXDECODE_ENTRY( REGION_GFX1, 0x0000, super80_elg4_charlayout, 0, 2 ) |
| 283 | | GFXDECODE_ENTRY( REGION_GFX1, 0x1000, super80_dslc_charlayout, 0, 2 ) |
| 796 | GFXDECODE_ENTRY( REGION_GFX1, 0x0000, super80_charlayout, 0, 1 ) |
| 284 | 797 | GFXDECODE_END |
| 285 | 798 | |
| 286 | | static const UINT8 bw_palette[] = |
| 287 | | { |
| 288 | | 0x00,0x00,0x00, /* black */ |
| 289 | | 0xff,0xff,0xff /* white */ |
| 290 | | }; |
| 799 | static GFXDECODE_START( super80d ) |
| 800 | GFXDECODE_ENTRY( REGION_GFX1, 0x0000, super80d_charlayout, 0, 1 ) |
| 801 | GFXDECODE_END |
| 291 | 802 | |
| 292 | | static PALETTE_INIT( super80_bw ) |
| 803 | static GFXDECODE_START( super80m ) |
| 804 | GFXDECODE_ENTRY( REGION_GFX1, 0x0000, super80d_charlayout, 0, 256 ) |
| 805 | GFXDECODE_ENTRY( REGION_GFX2, 0x0000, super80d_charlayout, 0, 256 ) |
| 806 | GFXDECODE_END |
| 807 | |
| 808 | static GFXDECODE_START( super80v ) |
| 809 | GFXDECODE_ENTRY( REGION_CPU1, 0xf000, super80v_charlayout, 0, 256 ) |
| 810 | GFXDECODE_END |
| 811 | |
| 812 | /**************************** BASIC MACHINE CONSTRUCTION ***********************************************************/ |
| 813 | |
| 814 | /* after the first 4 bytes have been read from ROM, switch the ram back in */ |
| 815 | static TIMER_CALLBACK( super80_reset ) |
| 293 | 816 | { |
| 294 | | palette_set_colors_rgb(machine, 0, bw_palette, sizeof(bw_palette) / 3); |
| 817 | memory_set_bank(1, 0); |
| 295 | 818 | } |
| 296 | 819 | |
| 297 | | static const struct z80_irq_daisy_chain super80_daisy_chain[] = |
| 820 | MACHINE_RESET( super80 ) |
| 298 | 821 | { |
| 299 | | {z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 0}, |
| 300 | | {0,0,0,0,-1} |
| 301 | | }; |
| 822 | z80pio_init(0, &pio_intf); |
| 823 | timer_set(ATTOTIME_IN_USEC(10), NULL, 0, super80_reset); |
| 824 | memory_set_bank(1, 1); |
| 825 | } |
| 302 | 826 | |
| 303 | | |
| 304 | | |
| 305 | 827 | static MACHINE_DRIVER_START( super80 ) |
| 306 | 828 | /* basic machine hardware */ |
| 307 | | MDRV_CPU_ADD_TAG("main", Z80, 2000000) /* 2 Mhz */ |
| 308 | | MDRV_CPU_PROGRAM_MAP(super80_mem, 0) |
| 309 | | MDRV_CPU_IO_MAP(super80_ports, 0) |
| 829 | MDRV_CPU_ADD_TAG("main", Z80, 12000000/6) /* 2 Mhz */ |
| 830 | MDRV_CPU_PROGRAM_MAP(super80_map, 0) |
| 831 | MDRV_CPU_IO_MAP(super80_io, 0) |
| 310 | 832 | MDRV_CPU_CONFIG(super80_daisy_chain) |
| 311 | | //MDRV_CPU_VBLANK_INT(super80_interrupt,1) |
| 312 | | MDRV_INTERLEAVE(1) |
| 313 | 833 | |
| 314 | 834 | MDRV_MACHINE_RESET( super80 ) |
| 315 | 835 | |
| 316 | 836 | MDRV_GFXDECODE(super80) |
| 317 | 837 | MDRV_SCREEN_ADD("main", RASTER) |
| 318 | | MDRV_SCREEN_REFRESH_RATE(50) |
| 319 | | // MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 838 | MDRV_SCREEN_REFRESH_RATE(48.8) |
| 839 | // MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(200)) |
| 320 | 840 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 321 | 841 | MDRV_SCREEN_SIZE(32*8, 16*10) |
| 322 | | MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0, 16*10-1) |
| 323 | | MDRV_PALETTE_LENGTH(sizeof(bw_palette)/sizeof(bw_palette[0])/3) |
| 324 | | MDRV_PALETTE_INIT(super80_bw) |
| 842 | MDRV_SCREEN_VISIBLE_AREA(0, 32*8-1, 0, 16*10-1) |
| 843 | MDRV_PALETTE_LENGTH(2) |
| 844 | MDRV_PALETTE_INIT(black_and_white) |
| 325 | 845 | |
| 326 | | MDRV_VIDEO_START(super80) |
| 846 | MDRV_VIDEO_EOF(super80) |
| 327 | 847 | MDRV_VIDEO_UPDATE(super80) |
| 328 | 848 | |
| 329 | 849 | /* sound hardware */ |
| r1808 | r1809 | |
| 331 | 851 | MDRV_SOUND_ADD(WAVE, 0) |
| 332 | 852 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 333 | 853 | MDRV_SOUND_ADD(SPEAKER, 0) |
| 334 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75) |
| 854 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 335 | 855 | MACHINE_DRIVER_END |
| 336 | 856 | |
| 857 | static MACHINE_DRIVER_START( super80d ) |
| 858 | MDRV_IMPORT_FROM(super80) |
| 859 | MDRV_GFXDECODE(super80d) |
| 860 | MACHINE_DRIVER_END |
| 337 | 861 | |
| 862 | static MACHINE_DRIVER_START( super80m ) |
| 863 | MDRV_IMPORT_FROM(super80) |
| 864 | MDRV_CPU_MODIFY("main") |
| 865 | MDRV_CPU_PROGRAM_MAP(super80m_map, 0) |
| 866 | |
| 867 | MDRV_GFXDECODE(super80m) |
| 868 | MDRV_PALETTE_LENGTH(256*2) |
| 869 | MDRV_PALETTE_INIT(super80m) |
| 870 | MDRV_VIDEO_EOF(super80m) |
| 871 | MDRV_VIDEO_UPDATE(super80m) |
| 872 | MACHINE_DRIVER_END |
| 873 | |
| 874 | static MACHINE_DRIVER_START( super80v ) |
| 875 | MDRV_IMPORT_FROM(super80m) |
| 876 | MDRV_CPU_MODIFY("main") |
| 877 | MDRV_CPU_PROGRAM_MAP(super80v_map, 0) |
| 878 | MDRV_CPU_IO_MAP(super80v_io, 0) |
| 879 | |
| 880 | // MDRV_SCREEN_REFRESH_RATE(50) |
| 881 | MDRV_GFXDECODE(super80v) |
| 882 | // MDRV_SCREEN_SIZE(SUPER80V_SCREEN_WIDTH, SUPER80V_SCREEN_HEIGHT) |
| 883 | // MDRV_SCREEN_VISIBLE_AREA(0, SUPER80V_SCREEN_WIDTH-1, 0, SUPER80V_SCREEN_HEIGHT-1) |
| 884 | MDRV_VIDEO_EOF(super80v) |
| 885 | MDRV_VIDEO_UPDATE(super80v) |
| 886 | MACHINE_DRIVER_END |
| 887 | |
| 888 | |
| 889 | static DRIVER_INIT( super80 ) |
| 890 | { |
| 891 | UINT8 *RAM = memory_region(REGION_CPU1); |
| 892 | memory_configure_bank(1, 0, 2, &RAM[0x0000], 0xc000); |
| 893 | timer_pulse(ATTOTIME_IN_HZ(200000),NULL,0,super80_timer); /* timer for keyboard and cassette */ |
| 894 | } |
| 895 | |
| 896 | static DRIVER_INIT( super80d ) |
| 897 | { |
| 898 | UINT8 *RAM = memory_region(REGION_GFX1); |
| 899 | UINT16 i; /* create inverse characters */ |
| 900 | for (i = 0x0800; i < 0x1000; i++) RAM[i] = ~RAM[i]; |
| 901 | DRIVER_INIT_CALL( super80 ); |
| 902 | } |
| 903 | |
| 904 | static DRIVER_INIT( super80v ) |
| 905 | { |
| 906 | pcgram = memory_region(REGION_CPU1)+0xf000; |
| 907 | videoram = memory_region(REGION_CPU1)+0x18000; |
| 908 | colorram = memory_region(REGION_CPU1)+0x1C000; |
| 909 | DRIVER_INIT_CALL( super80 ); |
| 910 | } |
| 911 | |
| 912 | |
| 913 | /**************************** ROMS *****************************************************************/ |
| 914 | |
| 338 | 915 | ROM_START( super80 ) |
| 339 | | ROM_REGION(0x10000,REGION_CPU1,0) |
| 340 | | ROM_LOAD("s80c8r5.007", 0xc000, 0x1000, CRC(294f217c)) |
| 341 | | ROM_LOAD("s80d8r5.007", 0xd000, 0x1000, CRC(9765793e)) |
| 342 | | ROM_LOAD("s80e8r5.007", 0xe000, 0x1000, CRC(5f65d94b)) |
| 916 | ROM_REGION(0x10000, REGION_CPU1, 0) |
| 917 | ROM_LOAD("super80.u26", 0xc000, 0x1000, CRC(6a6a9664) SHA1(2c4fcd943aa9bf7419d58fbc0e28ffb89ef22e0b) ) |
| 918 | ROM_LOAD("super80.u33", 0xd000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) |
| 919 | ROM_LOAD("super80.u42", 0xe000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) |
| 343 | 920 | |
| 344 | | ROM_REGION(0x1800,REGION_GFX1,0) |
| 345 | | ROM_LOAD("s80helg4", 0x0000, 0x1000, CRC(ebe763a7)) |
| 346 | | ROM_LOAD("s80hdslc", 0x1000, 0x0800, CRC(cb4c81e2)) |
| 921 | ROM_REGION(0x0400, REGION_GFX1, ROMREGION_DISPOSE) |
| 922 | ROM_LOAD("super80.u27", 0x0000, 0x0400, CRC(d1e4b3c6) SHA1(3667b97c6136da4761937958f281609690af4081) ) |
| 347 | 923 | ROM_END |
| 348 | 924 | |
| 349 | | /*************************************************************************** |
| 925 | ROM_START( super80d ) |
| 926 | ROM_REGION(0x10000, REGION_CPU1, 0) |
| 927 | ROM_LOAD("super80d.u26", 0xc000, 0x1000, CRC(cebd2613) SHA1(87b94cc101a5948ce590211c68272e27f4cbe95a) ) |
| 928 | ROM_LOAD("super80.u33", 0xd000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) |
| 929 | ROM_LOAD("super80.u42", 0xe000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) |
| 350 | 930 | |
| 351 | | Game driver(s) |
| 931 | ROM_REGION(0x1000, REGION_GFX1, ROMREGION_DISPOSE) |
| 932 | ROM_LOAD("super80d.u27", 0x0000, 0x0800, CRC(cb4c81e2) SHA1(8096f21c914fa76df5d23f74b1f7f83bd8645783) ) |
| 933 | ROM_RELOAD( 0x0800, 0x0800 ) |
| 934 | ROM_END |
| 352 | 935 | |
| 353 | | ***************************************************************************/ |
| 936 | ROM_START( super80e ) |
| 937 | ROM_REGION(0x10000, REGION_CPU1, 0) |
| 938 | ROM_LOAD("super80e.u26", 0xc000, 0x1000, CRC(bdc668f8) SHA1(3ae30b3cab599fca77d5e461f3ec1acf404caf07) ) |
| 939 | ROM_LOAD("super80.u33", 0xd000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) |
| 940 | ROM_LOAD("super80.u42", 0xe000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) |
| 354 | 941 | |
| 942 | ROM_REGION(0x1000, REGION_GFX1, ROMREGION_DISPOSE) |
| 943 | ROM_LOAD("super80e.u27", 0x0000, 0x1000, CRC(ebe763a7) SHA1(ffaa6d6a2c5dacc5a6651514e6707175a32e83e8) ) |
| 944 | ROM_END |
| 945 | |
| 946 | ROM_START( super80m ) |
| 947 | ROM_REGION(0x10000, REGION_CPU1, 0) |
| 948 | ROM_LOAD("s80-8r0.u26", 0xc000, 0x1000, CRC(48d410d8) SHA1(750d984abc013a3344628300288f6d1ba140a95f) ) |
| 949 | ROM_LOAD("s80-8r5.u33", 0xd000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c) ) |
| 950 | ROM_LOAD("s80-8r5.u42", 0xe000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691) ) |
| 951 | |
| 952 | ROM_REGION(0x1000, REGION_GFX1, ROMREGION_DISPOSE) |
| 953 | ROM_LOAD("super80d.u27", 0x0000, 0x0800, CRC(cb4c81e2) SHA1(8096f21c914fa76df5d23f74b1f7f83bd8645783) ) |
| 954 | ROM_RELOAD( 0x0800, 0x0800 ) |
| 955 | |
| 956 | ROM_REGION(0x1000, REGION_GFX2, ROMREGION_DISPOSE) |
| 957 | ROM_LOAD("super80e.u27", 0x0000, 0x1000, CRC(ebe763a7) SHA1(ffaa6d6a2c5dacc5a6651514e6707175a32e83e8) ) |
| 958 | ROM_END |
| 959 | |
| 960 | ROM_START( super80v ) |
| 961 | ROM_REGION( 0x20000, REGION_CPU1, 0 ) |
| 962 | ROM_LOAD("s80-v37v.u26", 0xc000, 0x1000, CRC(01e0c0dd) SHA1(ef66af9c44c651c65a21d5bda939ffa100078c08) ) |
| 963 | ROM_LOAD("s80-v37.u33", 0xd000, 0x1000, CRC(812ad777) SHA1(04f355bea3470a7d9ea23bb2811f6af7d81dc400) ) |
| 964 | ROM_LOAD("s80-v37.u42", 0xe000, 0x1000, CRC(e02e736e) SHA1(57b0264c805da99234ab5e8e028fca456851a4f9) ) |
| 965 | ROM_LOAD("s80hmce.ic12", 0xf000, 0x0800, CRC(a6488a1e) SHA1(7ba613d70a37a6b738dcd80c2bb9988ff1f011ef) ) |
| 966 | ROM_END |
| 967 | |
| 968 | /**************************** DEVICES *****************************************************************/ |
| 969 | |
| 970 | static QUICKLOAD_LOAD( super80 ) |
| 971 | { |
| 972 | int ch; |
| 973 | UINT16 args[3]; |
| 974 | UINT16 start_addr, end_addr, exec_addr, i=0, j, size; |
| 975 | UINT8 data, sw=1; |
| 976 | char * pgmname; |
| 977 | pgmname = (char *) malloc(256); |
| 978 | |
| 979 | image_fseek(image, 7, SEEK_SET); |
| 980 | |
| 981 | while((ch = image_fgetc(image)) != 0x1A) |
| 982 | { |
| 983 | if (ch == EOF) return INIT_FAIL; |
| 984 | |
| 985 | if (ch) |
| 986 | { |
| 987 | pgmname[i] = ch; /* build program name */ |
| 988 | i++; |
| 989 | } |
| 990 | } |
| 991 | |
| 992 | pgmname[i]=0; /* terminate string with a null */ |
| 993 | |
| 994 | if (image_fread(image, args, sizeof(args)) != sizeof(args)) |
| 995 | { |
| 996 | free(pgmname); |
| 997 | return INIT_FAIL; |
| 998 | } |
| 999 | |
| 1000 | exec_addr = LITTLE_ENDIANIZE_INT16(args[0]); |
| 1001 | start_addr = LITTLE_ENDIANIZE_INT16(args[1]); |
| 1002 | end_addr = LITTLE_ENDIANIZE_INT16(args[2]); |
| 1003 | |
| 1004 | size = (end_addr - start_addr + 1) & 0xffff; |
| 1005 | |
| 1006 | popmessage("%s\nsize=%04X : start=%04X : end=%04X : exec=%04X",pgmname,size,start_addr,end_addr,exec_addr); |
| 1007 | |
| 1008 | for (i = 0; i < size; i++) |
| 1009 | { |
| 1010 | j = (start_addr + i) & 0xffff; |
| 1011 | if (image_fread(image, &data, 1) != 1) |
| 1012 | { |
| 1013 | printf("\nQUICKLOAD: %s : unexpected EOF while writing byte to %X\n",pgmname,j); |
| 1014 | free(pgmname); |
| 1015 | return INIT_FAIL; |
| 1016 | } |
| 1017 | program_write_byte(j, data); |
| 1018 | } |
| 1019 | |
| 1020 | free(pgmname); |
| 1021 | |
| 1022 | /* reading the dipswitch: 1 = autorun */ |
| 1023 | sw = readinputport(9) & 1; |
| 1024 | |
| 1025 | /* exec_addr of 0xffff indicates a non-executable file */ |
| 1026 | if ((exec_addr != 0xffff) && (sw)) |
| 1027 | cpunum_set_reg(0, REG_PC, exec_addr); |
| 1028 | |
| 1029 | return INIT_PASS; |
| 1030 | } |
| 1031 | |
| 1032 | static void super80_quickload_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) |
| 1033 | { |
| 1034 | /* quickload */ |
| 1035 | switch(state) |
| 1036 | { |
| 1037 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 1038 | case MESS_DEVINFO_STR_DEV_FILE: strcpy(info->s = device_temp_str(), __FILE__); break; |
| 1039 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "bin"); break; |
| 1040 | |
| 1041 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 1042 | case MESS_DEVINFO_PTR_QUICKLOAD_LOAD: info->f = (genf *) quickload_load_super80; break; |
| 1043 | |
| 1044 | default: quickload_device_getinfo(devclass, state, info); break; |
| 1045 | } |
| 1046 | } |
| 1047 | |
| 1048 | static DEVICE_LOAD( super80_cart ) |
| 1049 | { |
| 1050 | /* int size = mame_fsize(fp); |
| 1051 | UINT8 *mem = malloc(size); |
| 1052 | if( mem ) |
| 1053 | { |
| 1054 | if( mame_fread(fp, mem, size) == size ) |
| 1055 | { |
| 1056 | memcpy(memory_region(REGION_CPU1)+0xc000, mem, size); |
| 1057 | } |
| 1058 | free(mem); |
| 1059 | } */ |
| 1060 | |
| 1061 | image_fread(image, memory_region(REGION_CPU1) + 0xc000, 0x3000); |
| 1062 | |
| 1063 | return INIT_PASS; |
| 1064 | } |
| 1065 | |
| 1066 | static void super80_cartslot_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) |
| 1067 | { |
| 1068 | /* cartslot */ |
| 1069 | switch(state) |
| 1070 | { |
| 1071 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 1072 | case MESS_DEVINFO_INT_COUNT: info->i = 1; break; |
| 1073 | |
| 1074 | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 1075 | case MESS_DEVINFO_PTR_LOAD: info->load = device_load_super80_cart; break; |
| 1076 | |
| 1077 | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 1078 | case MESS_DEVINFO_STR_FILE_EXTENSIONS: strcpy(info->s = device_temp_str(), "rom"); break; |
| 1079 | |
| 1080 | default: cartslot_device_getinfo(devclass, state, info); break; |
| 1081 | } |
| 1082 | } |
| 1083 | |
| 1084 | static void super80_cassette_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) |
| 1085 | { |
| 1086 | /* cassette */ |
| 1087 | switch(state) |
| 1088 | { |
| 1089 | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 1090 | case MESS_DEVINFO_INT_COUNT: info->i = 1; break; |
| 1091 | case MESS_DEVINFO_INT_CASSETTE_DEFAULT_STATE:info->i = CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED; break; |
| 1092 | |
| 1093 | default: cassette_device_getinfo(devclass, state, info); break; |
| 1094 | } |
| 1095 | } |
| 1096 | INPUT_PORTS_START(0) |
| 1097 | INPUT_PORTS_END |
| 1098 | |
| 355 | 1099 | SYSTEM_CONFIG_START(super80) |
| 356 | | //CONFIG_DEVICE_CASSETTE (1, NULL) |
| 1100 | CONFIG_DEVICE(super80_cassette_getinfo) |
| 1101 | CONFIG_DEVICE(super80_cartslot_getinfo) |
| 1102 | CONFIG_DEVICE(super80_quickload_getinfo) |
| 357 | 1103 | SYSTEM_CONFIG_END |
| 358 | 1104 | |
| 359 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT CONFIG COMPANY FULLNAME */ |
| 360 | | COMP( 1981, super80, 0, 0, super80, super80, 0, super80, "Dick Smith", "Super-80" , 0) |
| 1105 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT CONFIG COMPANY FULLNAME */ |
| 1106 | COMP( 1981, super80, 0, 0, super80, super80, super80, super80, "Dick Smith","Super-80 (V1.2)" , 0) |
| 1107 | COMP( 1981, super80d, super80, 0, super80d, super80, super80d, super80, "Dick Smith","Super-80 (V2.2)" , 0) |
| 1108 | COMP( 1981, super80e, super80, 0, super80d, super80, super80, super80, "Dick Smith","Super-80 (El Graphix 4)" , 0) |
| 1109 | COMP( 1981, super80m, super80, 0, super80m, super80m, super80d, super80, "Dick Smith","Super-80 (8R0)" , 0) |
| 1110 | COMP( 1981, super80v, super80, 0, super80v, super80v, super80v, super80, "Dick Smith","Super-80 (with VDUEB)" , 0) |
| 1111 | |