src/mess/machine/terminal.c
| r9681 | r9682 | |
| 176 | 176 | terminal_state *term = get_safe_token(device); |
| 177 | 177 | |
| 178 | 178 | memcpy(term->buffer,term->buffer+TERMINAL_WIDTH,(TERMINAL_HEIGHT-1)*TERMINAL_WIDTH); |
| 179 | | memset(term->buffer + TERMINAL_WIDTH*(TERMINAL_HEIGHT-1),0,TERMINAL_WIDTH); |
| 179 | memset(term->buffer + TERMINAL_WIDTH*(TERMINAL_HEIGHT-1),0x20,TERMINAL_WIDTH); |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | static void terminal_write_char(running_device *device,UINT8 data) { |
| r9681 | r9682 | |
| 184 | 184 | |
| 185 | 185 | term->buffer[term->y_pos*TERMINAL_WIDTH+term->x_pos] = data; |
| 186 | 186 | term->x_pos++; |
| 187 | | if (term->x_pos > TERMINAL_WIDTH) { |
| 187 | if (term->x_pos >= TERMINAL_WIDTH) |
| 188 | { |
| 188 | 189 | term->x_pos = 0; |
| 189 | 190 | term->y_pos++; |
| 190 | | if (term->y_pos==TERMINAL_HEIGHT) { |
| 191 | if (term->y_pos >= TERMINAL_HEIGHT) |
| 192 | { |
| 191 | 193 | terminal_scroll_line(device); |
| 192 | | term->y_pos = (TERMINAL_HEIGHT-1); |
| 194 | term->y_pos = TERMINAL_HEIGHT-1; |
| 193 | 195 | } |
| 194 | 196 | } |
| 195 | 197 | } |
| r9681 | r9682 | |
| 205 | 207 | WRITE8_DEVICE_HANDLER ( terminal_write ) |
| 206 | 208 | { |
| 207 | 209 | terminal_state *term = get_safe_token(device); |
| 208 | | if (data > 0x1f) { |
| 210 | if (data > 0x1f) |
| 211 | { |
| 209 | 212 | // printable char |
| 210 | 213 | if (data!=0x7f) terminal_write_char(device,data); |
| 211 | | } else { |
| 212 | | switch(data) { |
| 214 | } |
| 215 | else |
| 216 | { |
| 217 | switch(data) |
| 218 | { |
| 213 | 219 | case 0x07 : // bell |
| 214 | | break; |
| 215 | | case 0x08: if (term->x_pos!=0) { |
| 216 | | term->x_pos--; |
| 217 | | } |
| 218 | | break; |
| 219 | | case 0x09: do { |
| 220 | | term->x_pos ++; |
| 221 | | } while ((term->x_pos % 8)!=0); |
| 222 | | break; |
| 220 | break; |
| 221 | |
| 222 | case 0x08: if (term->x_pos) term->x_pos--; |
| 223 | break; |
| 224 | |
| 225 | case 0x09: term->x_pos ++; |
| 226 | term->x_pos += term->x_pos % 8; |
| 227 | if (term->x_pos >= TERMINAL_WIDTH) |
| 228 | term->x_pos = TERMINAL_WIDTH-1; |
| 229 | break; |
| 230 | |
| 223 | 231 | case 0x0a: term->y_pos++; |
| 224 | | term->x_pos = 0; |
| 225 | | if (term->y_pos==TERMINAL_HEIGHT) { |
| 226 | | terminal_scroll_line(device); |
| 227 | | term->y_pos = (TERMINAL_HEIGHT-1); |
| 228 | | }; |
| 229 | | break; |
| 230 | | case 0x0b: if (term->y_pos!=0) { |
| 231 | | term->y_pos--; |
| 232 | | } |
| 233 | | break; |
| 232 | term->x_pos = 0; |
| 233 | if (term->y_pos >= TERMINAL_HEIGHT) |
| 234 | { |
| 235 | terminal_scroll_line(device); |
| 236 | term->y_pos = TERMINAL_HEIGHT-1; |
| 237 | } |
| 238 | break; |
| 239 | |
| 240 | case 0x0b: if (term->y_pos) term->y_pos--; |
| 241 | break; |
| 242 | |
| 234 | 243 | case 0x0d: term->x_pos = 0; |
| 235 | | break; |
| 236 | | case 0x1e: term->x_pos = 0; |
| 237 | | term->y_pos = 0; |
| 238 | | break; |
| 244 | break; |
| 245 | |
| 246 | case 0x1e: term->x_pos = 0; |
| 247 | term->y_pos = 0; |
| 248 | break; |
| 239 | 249 | } |
| 240 | 250 | } |
| 241 | 251 | } |
| r9681 | r9682 | |
| 245 | 255 | ***************************************************************************/ |
| 246 | 256 | static void generic_terminal_update(running_device *device, bitmap_t *bitmap, const rectangle *cliprect) |
| 247 | 257 | { |
| 248 | | UINT8 code; |
| 249 | | int y, c, x, b; |
| 250 | 258 | terminal_state *term = get_safe_token(device); |
| 259 | UINT8 options = input_port_read(device->machine, "TERM_CONF"); |
| 260 | UINT16 cursor = term->y_pos * TERMINAL_WIDTH + term->x_pos; |
| 261 | static UINT8 framecnt=0; |
| 262 | UINT8 y,ra,chr,gfx; |
| 263 | UINT16 sy=0,ma=0,x; |
| 251 | 264 | |
| 265 | framecnt++; |
| 266 | |
| 252 | 267 | for (y = 0; y < TERMINAL_HEIGHT; y++) |
| 253 | 268 | { |
| 254 | | for (c = 0; c < 10; c++) |
| 269 | for (ra = 0; ra < 10; ra++) |
| 255 | 270 | { |
| 256 | | int horpos = 0; |
| 257 | | for (x = 0; x < TERMINAL_WIDTH; x++) |
| 271 | UINT16 *p = BITMAP_ADDR16(bitmap, sy++, 0); |
| 272 | |
| 273 | for (x = ma; x < ma + TERMINAL_WIDTH; x++) |
| 258 | 274 | { |
| 259 | | code = terminal_font[term->buffer[y*TERMINAL_WIDTH + x] *16 + c]; |
| 260 | | *BITMAP_ADDR16(bitmap, y*10 + c, horpos++) = (code >> 7) & 0x01; |
| 261 | | for (b = 6; b >= 0; b--) |
| 275 | chr = term->buffer[x]; |
| 276 | gfx = terminal_font[(chr<<4) | ra ]; |
| 277 | |
| 278 | if ((x == cursor) && (options & 1)) // at cursor position and want a cursor |
| 262 | 279 | { |
| 263 | | *BITMAP_ADDR16(bitmap, y*10 + c, horpos++) = ((code >> b) | (code >> (b+1))) & 0x01; |
| 280 | if ((options & 2) || (ra == 9)) // block, or underline & at bottom line |
| 281 | { |
| 282 | if ((options & 4) && (framecnt & 8)) // want blink & time to blink |
| 283 | { |
| 284 | } |
| 285 | else |
| 286 | { |
| 287 | if (options & 8) |
| 288 | gfx ^= 0xff; // invert |
| 289 | else |
| 290 | gfx |= 0xff; // overwrite |
| 291 | } |
| 292 | } |
| 264 | 293 | } |
| 265 | | *BITMAP_ADDR16(bitmap, y*10 + c, horpos++) = code & 0x01; |
| 266 | | *BITMAP_ADDR16(bitmap, y*10 + c, horpos++) = 0; |
| 294 | |
| 295 | /* Display a scanline of a character */ |
| 296 | *p++ = ( gfx & 0x80 ) ? 1 : 0; |
| 297 | *p++ = ( gfx & 0x40 ) ? 1 : 0; |
| 298 | *p++ = ( gfx & 0x20 ) ? 1 : 0; |
| 299 | *p++ = ( gfx & 0x10 ) ? 1 : 0; |
| 300 | *p++ = ( gfx & 0x08 ) ? 1 : 0; |
| 301 | *p++ = ( gfx & 0x04 ) ? 1 : 0; |
| 302 | *p++ = ( gfx & 0x02 ) ? 1 : 0; |
| 303 | *p++ = ( gfx & 0x01 ) ? 1 : 0; |
| 267 | 304 | } |
| 268 | 305 | } |
| 306 | ma+=TERMINAL_WIDTH; |
| 269 | 307 | } |
| 270 | 308 | } |
| 271 | 309 | |
| r9681 | r9682 | |
| 400 | 438 | |
| 401 | 439 | MACHINE_CONFIG_FRAGMENT( generic_terminal ) |
| 402 | 440 | MDRV_SCREEN_ADD(TERMINAL_SCREEN_TAG, RASTER) |
| 403 | | MDRV_SCREEN_REFRESH_RATE(50) |
| 404 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 405 | | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 406 | | MDRV_SCREEN_SIZE(TERMINAL_WIDTH*10, TERMINAL_HEIGHT*10) |
| 407 | | MDRV_SCREEN_VISIBLE_AREA(0, TERMINAL_WIDTH*10-1, 0, TERMINAL_HEIGHT*10-1) |
| 441 | MDRV_SCREEN_REFRESH_RATE(50) |
| 442 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 443 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 444 | MDRV_SCREEN_SIZE(TERMINAL_WIDTH*8, TERMINAL_HEIGHT*10) |
| 445 | MDRV_SCREEN_VISIBLE_AREA(0, TERMINAL_WIDTH*8-1, 0, TERMINAL_HEIGHT*10-1) |
| 408 | 446 | MDRV_PALETTE_LENGTH(2) |
| 409 | | MDRV_PALETTE_INIT(black_and_white) |
| 447 | MDRV_PALETTE_INIT(black_and_white) |
| 410 | 448 | |
| 411 | 449 | MDRV_VIDEO_START(terminal) |
| 412 | 450 | MDRV_VIDEO_UPDATE(terminal) |
| r9681 | r9682 | |
| 581 | 619 | PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LF") PORT_CODE(KEYCODE_RALT) PORT_CHAR(10) |
| 582 | 620 | PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) |
| 583 | 621 | PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) |
| 622 | |
| 623 | PORT_START("TERM_CONF") |
| 624 | PORT_CONFNAME( 0x01, 0x01, "Cursor") |
| 625 | PORT_CONFSETTING( 0x00, DEF_STR(No)) |
| 626 | PORT_CONFSETTING( 0x01, DEF_STR(Yes)) |
| 627 | PORT_CONFNAME( 0x02, 0x02, "Type") |
| 628 | PORT_CONFSETTING( 0x00, "Underline") |
| 629 | PORT_CONFSETTING( 0x02, "Block") |
| 630 | PORT_CONFNAME( 0x04, 0x04, "Blinking") |
| 631 | PORT_CONFSETTING( 0x00, DEF_STR(No)) |
| 632 | PORT_CONFSETTING( 0x04, DEF_STR(Yes)) |
| 633 | PORT_CONFNAME( 0x08, 0x08, "Invert") |
| 634 | PORT_CONFSETTING( 0x00, DEF_STR(No)) |
| 635 | PORT_CONFSETTING( 0x08, DEF_STR(Yes)) |
| 584 | 636 | INPUT_PORTS_END |
| 585 | 637 | |
| 586 | 638 | DEFINE_LEGACY_DEVICE(GENERIC_TERMINAL, terminal); |