Commit 313aa567104a63fbe84d6ec2eeff5b5c81cb3524
1 parent
4cbf74b6
added VGA emulation - added PS/2 mouse and keyboard emulation - use SDL for VGA display
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@356 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
454 additions
and
120 deletions
vl.c
@@ -74,6 +74,9 @@ | @@ -74,6 +74,9 @@ | ||
74 | /* debug PC keyboard */ | 74 | /* debug PC keyboard */ |
75 | //#define DEBUG_KBD | 75 | //#define DEBUG_KBD |
76 | 76 | ||
77 | +/* debug PC keyboard : only mouse */ | ||
78 | +//#define DEBUG_MOUSE | ||
79 | + | ||
77 | #define PHYS_RAM_BASE 0xac000000 | 80 | #define PHYS_RAM_BASE 0xac000000 |
78 | #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) | 81 | #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) |
79 | 82 | ||
@@ -81,6 +84,8 @@ | @@ -81,6 +84,8 @@ | ||
81 | #define INITRD_LOAD_ADDR 0x00400000 | 84 | #define INITRD_LOAD_ADDR 0x00400000 |
82 | #define KERNEL_PARAMS_ADDR 0x00090000 | 85 | #define KERNEL_PARAMS_ADDR 0x00090000 |
83 | 86 | ||
87 | +#define GUI_REFRESH_INTERVAL 30 | ||
88 | + | ||
84 | #define MAX_DISKS 2 | 89 | #define MAX_DISKS 2 |
85 | 90 | ||
86 | /* from plex86 (BSD license) */ | 91 | /* from plex86 (BSD license) */ |
@@ -198,9 +203,6 @@ struct __attribute__ ((packed)) linux_params { | @@ -198,9 +203,6 @@ struct __attribute__ ((packed)) linux_params { | ||
198 | #define KERNEL_CS 0x10 | 203 | #define KERNEL_CS 0x10 |
199 | #define KERNEL_DS 0x18 | 204 | #define KERNEL_DS 0x18 |
200 | 205 | ||
201 | -typedef void (IOPortWriteFunc)(CPUX86State *env, uint32_t address, uint32_t data); | ||
202 | -typedef uint32_t (IOPortReadFunc)(CPUX86State *env, uint32_t address); | ||
203 | - | ||
204 | #define MAX_IOPORTS 4096 | 206 | #define MAX_IOPORTS 4096 |
205 | 207 | ||
206 | static const char *interp_prefix = CONFIG_QEMU_PREFIX; | 208 | static const char *interp_prefix = CONFIG_QEMU_PREFIX; |
@@ -212,6 +214,11 @@ int loglevel; | @@ -212,6 +214,11 @@ int loglevel; | ||
212 | IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; | 214 | IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
213 | IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; | 215 | IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
214 | BlockDriverState *bs_table[MAX_DISKS]; | 216 | BlockDriverState *bs_table[MAX_DISKS]; |
217 | +int vga_ram_size; | ||
218 | +static DisplayState display_state; | ||
219 | +int nodisp; | ||
220 | +int term_inited; | ||
221 | +int64_t ticks_per_sec; | ||
215 | 222 | ||
216 | /***********************************************************/ | 223 | /***********************************************************/ |
217 | /* x86 io ports */ | 224 | /* x86 io ports */ |
@@ -431,49 +438,6 @@ void hw_error(const char *fmt, ...) | @@ -431,49 +438,6 @@ void hw_error(const char *fmt, ...) | ||
431 | } | 438 | } |
432 | 439 | ||
433 | /***********************************************************/ | 440 | /***********************************************************/ |
434 | -/* vga emulation */ | ||
435 | -static uint8_t vga_index; | ||
436 | -static uint8_t vga_regs[256]; | ||
437 | -static int last_cursor_pos; | ||
438 | - | ||
439 | -void update_console_messages(void) | ||
440 | -{ | ||
441 | - int c, i, cursor_pos, eol; | ||
442 | - | ||
443 | - cursor_pos = vga_regs[0x0f] | (vga_regs[0x0e] << 8); | ||
444 | - eol = 0; | ||
445 | - for(i = last_cursor_pos; i < cursor_pos; i++) { | ||
446 | - c = phys_ram_base[0xb8000 + (i) * 2]; | ||
447 | - if (c >= ' ') { | ||
448 | - putchar(c); | ||
449 | - eol = 0; | ||
450 | - } else { | ||
451 | - if (!eol) | ||
452 | - putchar('\n'); | ||
453 | - eol = 1; | ||
454 | - } | ||
455 | - } | ||
456 | - fflush(stdout); | ||
457 | - last_cursor_pos = cursor_pos; | ||
458 | -} | ||
459 | - | ||
460 | -/* just to see first Linux console messages, we intercept cursor position */ | ||
461 | -void vga_ioport_write(CPUX86State *env, uint32_t addr, uint32_t data) | ||
462 | -{ | ||
463 | - switch(addr) { | ||
464 | - case 0x3d4: | ||
465 | - vga_index = data; | ||
466 | - break; | ||
467 | - case 0x3d5: | ||
468 | - vga_regs[vga_index] = data; | ||
469 | - if (vga_index == 0x0f) | ||
470 | - update_console_messages(); | ||
471 | - break; | ||
472 | - } | ||
473 | - | ||
474 | -} | ||
475 | - | ||
476 | -/***********************************************************/ | ||
477 | /* cmos emulation */ | 441 | /* cmos emulation */ |
478 | 442 | ||
479 | #define RTC_SECONDS 0 | 443 | #define RTC_SECONDS 0 |
@@ -555,6 +519,7 @@ void cmos_init(void) | @@ -555,6 +519,7 @@ void cmos_init(void) | ||
555 | /* various important CMOS locations needed by PC/Bochs bios */ | 519 | /* various important CMOS locations needed by PC/Bochs bios */ |
556 | 520 | ||
557 | cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */ | 521 | cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */ |
522 | + cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */ | ||
558 | 523 | ||
559 | /* memory size */ | 524 | /* memory size */ |
560 | val = (phys_ram_size / 1024) - 1024; | 525 | val = (phys_ram_size / 1024) - 1024; |
@@ -674,13 +639,13 @@ static void pic_update_irq(void) | @@ -674,13 +639,13 @@ static void pic_update_irq(void) | ||
674 | int64_t irq_time[16]; | 639 | int64_t irq_time[16]; |
675 | int64_t cpu_get_ticks(void); | 640 | int64_t cpu_get_ticks(void); |
676 | #endif | 641 | #endif |
677 | -#ifdef DEBUG_PIC | 642 | +#if defined(DEBUG_PIC) |
678 | int irq_level[16]; | 643 | int irq_level[16]; |
679 | #endif | 644 | #endif |
680 | 645 | ||
681 | void pic_set_irq(int irq, int level) | 646 | void pic_set_irq(int irq, int level) |
682 | { | 647 | { |
683 | -#ifdef DEBUG_PIC | 648 | +#if defined(DEBUG_PIC) |
684 | if (level != irq_level[irq]) { | 649 | if (level != irq_level[irq]) { |
685 | printf("pic_set_irq: irq=%d level=%d\n", irq, level); | 650 | printf("pic_set_irq: irq=%d level=%d\n", irq, level); |
686 | irq_level[irq] = level; | 651 | irq_level[irq] = level; |
@@ -702,7 +667,9 @@ int cpu_x86_get_pic_interrupt(CPUX86State *env) | @@ -702,7 +667,9 @@ int cpu_x86_get_pic_interrupt(CPUX86State *env) | ||
702 | /* signal the pic that the irq was acked by the CPU */ | 667 | /* signal the pic that the irq was acked by the CPU */ |
703 | irq = pic_irq_requested; | 668 | irq = pic_irq_requested; |
704 | #ifdef DEBUG_IRQ_LATENCY | 669 | #ifdef DEBUG_IRQ_LATENCY |
705 | - printf("IRQ%d latency=%Ld\n", irq, cpu_get_ticks() - irq_time[irq]); | 670 | + printf("IRQ%d latency=%0.3fus\n", |
671 | + irq, | ||
672 | + (double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec); | ||
706 | #endif | 673 | #endif |
707 | #ifdef DEBUG_PIC | 674 | #ifdef DEBUG_PIC |
708 | printf("pic_interrupt: irq=%d\n", irq); | 675 | printf("pic_interrupt: irq=%d\n", irq); |
@@ -761,18 +728,22 @@ void pic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) | @@ -761,18 +728,22 @@ void pic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) | ||
761 | } | 728 | } |
762 | if (val == 0xa0) | 729 | if (val == 0xa0) |
763 | s->priority_add = (s->priority_add + 1) & 7; | 730 | s->priority_add = (s->priority_add + 1) & 7; |
731 | + pic_update_irq(); | ||
764 | break; | 732 | break; |
765 | case 0x60 ... 0x67: | 733 | case 0x60 ... 0x67: |
766 | priority = val & 7; | 734 | priority = val & 7; |
767 | s->isr &= ~(1 << priority); | 735 | s->isr &= ~(1 << priority); |
736 | + pic_update_irq(); | ||
768 | break; | 737 | break; |
769 | case 0xc0 ... 0xc7: | 738 | case 0xc0 ... 0xc7: |
770 | s->priority_add = (val + 1) & 7; | 739 | s->priority_add = (val + 1) & 7; |
740 | + pic_update_irq(); | ||
771 | break; | 741 | break; |
772 | case 0xe0 ... 0xe7: | 742 | case 0xe0 ... 0xe7: |
773 | priority = val & 7; | 743 | priority = val & 7; |
774 | s->isr &= ~(1 << priority); | 744 | s->isr &= ~(1 << priority); |
775 | s->priority_add = (priority + 1) & 7; | 745 | s->priority_add = (priority + 1) & 7; |
746 | + pic_update_irq(); | ||
776 | break; | 747 | break; |
777 | } | 748 | } |
778 | } | 749 | } |
@@ -861,8 +832,6 @@ int speaker_data_on; | @@ -861,8 +832,6 @@ int speaker_data_on; | ||
861 | int dummy_refresh_clock; | 832 | int dummy_refresh_clock; |
862 | int pit_min_timer_count = 0; | 833 | int pit_min_timer_count = 0; |
863 | 834 | ||
864 | -int64_t ticks_per_sec; | ||
865 | - | ||
866 | int64_t get_clock(void) | 835 | int64_t get_clock(void) |
867 | { | 836 | { |
868 | struct timeval tv; | 837 | struct timeval tv; |
@@ -1354,37 +1323,6 @@ void serial_received_byte(SerialState *s, int ch) | @@ -1354,37 +1323,6 @@ void serial_received_byte(SerialState *s, int ch) | ||
1354 | } | 1323 | } |
1355 | } | 1324 | } |
1356 | 1325 | ||
1357 | -/* init terminal so that we can grab keys */ | ||
1358 | -static struct termios oldtty; | ||
1359 | - | ||
1360 | -static void term_exit(void) | ||
1361 | -{ | ||
1362 | - tcsetattr (0, TCSANOW, &oldtty); | ||
1363 | -} | ||
1364 | - | ||
1365 | -static void term_init(void) | ||
1366 | -{ | ||
1367 | - struct termios tty; | ||
1368 | - | ||
1369 | - tcgetattr (0, &tty); | ||
1370 | - oldtty = tty; | ||
1371 | - | ||
1372 | - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP | ||
1373 | - |INLCR|IGNCR|ICRNL|IXON); | ||
1374 | - tty.c_oflag |= OPOST; | ||
1375 | - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); | ||
1376 | - tty.c_cflag &= ~(CSIZE|PARENB); | ||
1377 | - tty.c_cflag |= CS8; | ||
1378 | - tty.c_cc[VMIN] = 1; | ||
1379 | - tty.c_cc[VTIME] = 0; | ||
1380 | - | ||
1381 | - tcsetattr (0, TCSANOW, &tty); | ||
1382 | - | ||
1383 | - atexit(term_exit); | ||
1384 | - | ||
1385 | - fcntl(0, F_SETFL, O_NONBLOCK); | ||
1386 | -} | ||
1387 | - | ||
1388 | void serial_init(void) | 1326 | void serial_init(void) |
1389 | { | 1327 | { |
1390 | SerialState *s = &serial_ports[0]; | 1328 | SerialState *s = &serial_ports[0]; |
@@ -1393,8 +1331,6 @@ void serial_init(void) | @@ -1393,8 +1331,6 @@ void serial_init(void) | ||
1393 | 1331 | ||
1394 | register_ioport_write(0x3f8, 8, serial_ioport_write, 1); | 1332 | register_ioport_write(0x3f8, 8, serial_ioport_write, 1); |
1395 | register_ioport_read(0x3f8, 8, serial_ioport_read, 1); | 1333 | register_ioport_read(0x3f8, 8, serial_ioport_read, 1); |
1396 | - | ||
1397 | - term_init(); | ||
1398 | } | 1334 | } |
1399 | 1335 | ||
1400 | /***********************************************************/ | 1336 | /***********************************************************/ |
@@ -2597,69 +2533,111 @@ void ide_init(void) | @@ -2597,69 +2533,111 @@ void ide_init(void) | ||
2597 | #define KBD_MODE_RFU 0x80 | 2533 | #define KBD_MODE_RFU 0x80 |
2598 | 2534 | ||
2599 | /* Mouse Commands */ | 2535 | /* Mouse Commands */ |
2600 | -#define AUX_SET_RES 0xE8 /* Set resolution */ | ||
2601 | #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ | 2536 | #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ |
2602 | #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ | 2537 | #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ |
2538 | +#define AUX_SET_RES 0xE8 /* Set resolution */ | ||
2603 | #define AUX_GET_SCALE 0xE9 /* Get scaling factor */ | 2539 | #define AUX_GET_SCALE 0xE9 /* Get scaling factor */ |
2604 | #define AUX_SET_STREAM 0xEA /* Set stream mode */ | 2540 | #define AUX_SET_STREAM 0xEA /* Set stream mode */ |
2541 | +#define AUX_POLL 0xEB /* Poll */ | ||
2542 | +#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */ | ||
2543 | +#define AUX_SET_WRAP 0xEE /* Set wrap mode */ | ||
2544 | +#define AUX_SET_REMOTE 0xF0 /* Set remote mode */ | ||
2545 | +#define AUX_GET_TYPE 0xF2 /* Get type */ | ||
2605 | #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ | 2546 | #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ |
2606 | #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ | 2547 | #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ |
2607 | #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ | 2548 | #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ |
2549 | +#define AUX_SET_DEFAULT 0xF6 | ||
2608 | #define AUX_RESET 0xFF /* Reset aux device */ | 2550 | #define AUX_RESET 0xFF /* Reset aux device */ |
2609 | #define AUX_ACK 0xFA /* Command byte ACK. */ | 2551 | #define AUX_ACK 0xFA /* Command byte ACK. */ |
2610 | 2552 | ||
2611 | -#define KBD_QUEUE_SIZE 64 | 2553 | +#define MOUSE_STATUS_REMOTE 0x40 |
2554 | +#define MOUSE_STATUS_ENABLED 0x20 | ||
2555 | +#define MOUSE_STATUS_SCALE21 0x10 | ||
2556 | + | ||
2557 | +#define KBD_QUEUE_SIZE 256 | ||
2612 | 2558 | ||
2613 | typedef struct { | 2559 | typedef struct { |
2614 | uint8_t data[KBD_QUEUE_SIZE]; | 2560 | uint8_t data[KBD_QUEUE_SIZE]; |
2615 | int rptr, wptr, count; | 2561 | int rptr, wptr, count; |
2616 | } KBDQueue; | 2562 | } KBDQueue; |
2617 | 2563 | ||
2618 | -enum KBDWriteState { | ||
2619 | - KBD_STATE_CMD = 0, | ||
2620 | - KBD_STATE_LED, | ||
2621 | -}; | ||
2622 | - | ||
2623 | typedef struct KBDState { | 2564 | typedef struct KBDState { |
2624 | KBDQueue queues[2]; | 2565 | KBDQueue queues[2]; |
2625 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ | 2566 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ |
2626 | uint8_t status; | 2567 | uint8_t status; |
2627 | uint8_t mode; | 2568 | uint8_t mode; |
2569 | + /* keyboard state */ | ||
2628 | int kbd_write_cmd; | 2570 | int kbd_write_cmd; |
2629 | int scan_enabled; | 2571 | int scan_enabled; |
2572 | + /* mouse state */ | ||
2573 | + int mouse_write_cmd; | ||
2574 | + uint8_t mouse_status; | ||
2575 | + uint8_t mouse_resolution; | ||
2576 | + uint8_t mouse_sample_rate; | ||
2577 | + uint8_t mouse_wrap; | ||
2578 | + uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ | ||
2579 | + uint8_t mouse_detect_state; | ||
2580 | + int mouse_dx; /* current values, needed for 'poll' mode */ | ||
2581 | + int mouse_dy; | ||
2582 | + int mouse_dz; | ||
2583 | + uint8_t mouse_buttons; | ||
2630 | } KBDState; | 2584 | } KBDState; |
2631 | 2585 | ||
2632 | KBDState kbd_state; | 2586 | KBDState kbd_state; |
2633 | int reset_requested; | 2587 | int reset_requested; |
2634 | int a20_enabled; | 2588 | int a20_enabled; |
2635 | 2589 | ||
2590 | +/* update irq and KBD_STAT_[MOUSE_]OBF */ | ||
2636 | static void kbd_update_irq(KBDState *s) | 2591 | static void kbd_update_irq(KBDState *s) |
2637 | { | 2592 | { |
2638 | - int level; | ||
2639 | - | ||
2640 | - level = ((s->status & KBD_STAT_OBF) && (s->mode & KBD_MODE_KBD_INT)); | ||
2641 | - pic_set_irq(1, level); | ||
2642 | - | ||
2643 | - level = ((s->status & KBD_STAT_MOUSE_OBF) && (s->mode & KBD_MODE_MOUSE_INT)); | ||
2644 | - pic_set_irq(12, level); | 2593 | + int irq12_level, irq1_level; |
2594 | + | ||
2595 | + irq1_level = 0; | ||
2596 | + irq12_level = 0; | ||
2597 | + s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); | ||
2598 | + if (s->queues[0].count != 0 || | ||
2599 | + s->queues[1].count != 0) { | ||
2600 | + s->status |= KBD_STAT_OBF; | ||
2601 | + if (s->queues[1].count != 0) { | ||
2602 | + s->status |= KBD_STAT_MOUSE_OBF; | ||
2603 | + if (s->mode & KBD_MODE_MOUSE_INT) | ||
2604 | + irq12_level = 1; | ||
2605 | + } else { | ||
2606 | + if (s->mode & KBD_MODE_KBD_INT) | ||
2607 | + irq1_level = 1; | ||
2608 | + } | ||
2609 | + } | ||
2610 | + pic_set_irq(1, irq1_level); | ||
2611 | + pic_set_irq(12, irq12_level); | ||
2645 | } | 2612 | } |
2646 | 2613 | ||
2647 | static void kbd_queue(KBDState *s, int b, int aux) | 2614 | static void kbd_queue(KBDState *s, int b, int aux) |
2648 | { | 2615 | { |
2649 | KBDQueue *q = &kbd_state.queues[aux]; | 2616 | KBDQueue *q = &kbd_state.queues[aux]; |
2650 | 2617 | ||
2618 | +#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) | ||
2619 | + if (aux) | ||
2620 | + printf("mouse event: 0x%02x\n", b); | ||
2621 | +#ifdef DEBUG_KBD | ||
2622 | + else | ||
2623 | + printf("kbd event: 0x%02x\n", b); | ||
2624 | +#endif | ||
2625 | +#endif | ||
2651 | if (q->count >= KBD_QUEUE_SIZE) | 2626 | if (q->count >= KBD_QUEUE_SIZE) |
2652 | return; | 2627 | return; |
2653 | q->data[q->wptr] = b; | 2628 | q->data[q->wptr] = b; |
2654 | if (++q->wptr == KBD_QUEUE_SIZE) | 2629 | if (++q->wptr == KBD_QUEUE_SIZE) |
2655 | q->wptr = 0; | 2630 | q->wptr = 0; |
2656 | q->count++; | 2631 | q->count++; |
2657 | - s->status |= KBD_STAT_OBF; | ||
2658 | - if (aux) | ||
2659 | - s->status |= KBD_STAT_MOUSE_OBF; | ||
2660 | kbd_update_irq(s); | 2632 | kbd_update_irq(s); |
2661 | } | 2633 | } |
2662 | 2634 | ||
2635 | +void kbd_put_keycode(int keycode) | ||
2636 | +{ | ||
2637 | + KBDState *s = &kbd_state; | ||
2638 | + kbd_queue(s, keycode, 0); | ||
2639 | +} | ||
2640 | + | ||
2663 | uint32_t kbd_read_status(CPUX86State *env, uint32_t addr) | 2641 | uint32_t kbd_read_status(CPUX86State *env, uint32_t addr) |
2664 | { | 2642 | { |
2665 | KBDState *s = &kbd_state; | 2643 | KBDState *s = &kbd_state; |
@@ -2745,9 +2723,9 @@ uint32_t kbd_read_data(CPUX86State *env, uint32_t addr) | @@ -2745,9 +2723,9 @@ uint32_t kbd_read_data(CPUX86State *env, uint32_t addr) | ||
2745 | KBDQueue *q; | 2723 | KBDQueue *q; |
2746 | int val; | 2724 | int val; |
2747 | 2725 | ||
2748 | - q = &s->queues[1]; /* first check AUX data */ | 2726 | + q = &s->queues[0]; /* first check KBD data */ |
2749 | if (q->count == 0) | 2727 | if (q->count == 0) |
2750 | - q = &s->queues[0]; /* then check KBD data */ | 2728 | + q = &s->queues[1]; /* then check AUX data */ |
2751 | if (q->count == 0) { | 2729 | if (q->count == 0) { |
2752 | /* XXX: return something else ? */ | 2730 | /* XXX: return something else ? */ |
2753 | val = 0; | 2731 | val = 0; |
@@ -2756,14 +2734,14 @@ uint32_t kbd_read_data(CPUX86State *env, uint32_t addr) | @@ -2756,14 +2734,14 @@ uint32_t kbd_read_data(CPUX86State *env, uint32_t addr) | ||
2756 | if (++q->rptr == KBD_QUEUE_SIZE) | 2734 | if (++q->rptr == KBD_QUEUE_SIZE) |
2757 | q->rptr = 0; | 2735 | q->rptr = 0; |
2758 | q->count--; | 2736 | q->count--; |
2737 | + /* reading deasserts IRQ */ | ||
2738 | + if (q == &s->queues[0]) | ||
2739 | + pic_set_irq(1, 0); | ||
2740 | + else | ||
2741 | + pic_set_irq(12, 0); | ||
2759 | } | 2742 | } |
2760 | - if (s->queues[1].count == 0) { | ||
2761 | - s->status &= ~KBD_STAT_MOUSE_OBF; | ||
2762 | - if (s->queues[0].count == 0) | ||
2763 | - s->status &= ~KBD_STAT_OBF; | ||
2764 | - kbd_update_irq(s); | ||
2765 | - } | ||
2766 | - | 2743 | + /* reassert IRQs if data left */ |
2744 | + kbd_update_irq(s); | ||
2767 | #ifdef DEBUG_KBD | 2745 | #ifdef DEBUG_KBD |
2768 | printf("kbd: read data=0x%02x\n", val); | 2746 | printf("kbd: read data=0x%02x\n", val); |
2769 | #endif | 2747 | #endif |
@@ -2820,12 +2798,212 @@ static void kbd_write_keyboard(KBDState *s, int val) | @@ -2820,12 +2798,212 @@ static void kbd_write_keyboard(KBDState *s, int val) | ||
2820 | break; | 2798 | break; |
2821 | case KBD_CMD_SET_LEDS: | 2799 | case KBD_CMD_SET_LEDS: |
2822 | kbd_queue(s, KBD_REPLY_ACK, 0); | 2800 | kbd_queue(s, KBD_REPLY_ACK, 0); |
2801 | + s->kbd_write_cmd = -1; | ||
2823 | break; | 2802 | break; |
2824 | case KBD_CMD_SET_RATE: | 2803 | case KBD_CMD_SET_RATE: |
2825 | kbd_queue(s, KBD_REPLY_ACK, 0); | 2804 | kbd_queue(s, KBD_REPLY_ACK, 0); |
2805 | + s->kbd_write_cmd = -1; | ||
2806 | + break; | ||
2807 | + } | ||
2808 | +} | ||
2809 | + | ||
2810 | +static void kbd_mouse_send_packet(KBDState *s) | ||
2811 | +{ | ||
2812 | + unsigned int b; | ||
2813 | + int dx1, dy1, dz1; | ||
2814 | + | ||
2815 | + dx1 = s->mouse_dx; | ||
2816 | + dy1 = s->mouse_dy; | ||
2817 | + dz1 = s->mouse_dz; | ||
2818 | + /* XXX: increase range to 8 bits ? */ | ||
2819 | + if (dx1 > 127) | ||
2820 | + dx1 = 127; | ||
2821 | + else if (dx1 < -127) | ||
2822 | + dx1 = -127; | ||
2823 | + if (dy1 > 127) | ||
2824 | + dy1 = 127; | ||
2825 | + else if (dy1 < -127) | ||
2826 | + dy1 = -127; | ||
2827 | + b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); | ||
2828 | + kbd_queue(s, b, 1); | ||
2829 | + kbd_queue(s, dx1 & 0xff, 1); | ||
2830 | + kbd_queue(s, dy1 & 0xff, 1); | ||
2831 | + /* extra byte for IMPS/2 or IMEX */ | ||
2832 | + switch(s->mouse_type) { | ||
2833 | + default: | ||
2834 | + break; | ||
2835 | + case 3: | ||
2836 | + if (dz1 > 127) | ||
2837 | + dz1 = 127; | ||
2838 | + else if (dz1 < -127) | ||
2839 | + dz1 = -127; | ||
2840 | + kbd_queue(s, dz1 & 0xff, 1); | ||
2841 | + break; | ||
2842 | + case 4: | ||
2843 | + if (dz1 > 7) | ||
2844 | + dz1 = 7; | ||
2845 | + else if (dz1 < -7) | ||
2846 | + dz1 = -7; | ||
2847 | + b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); | ||
2848 | + kbd_queue(s, b, 1); | ||
2849 | + break; | ||
2850 | + } | ||
2851 | + | ||
2852 | + /* update deltas */ | ||
2853 | + s->mouse_dx -= dx1; | ||
2854 | + s->mouse_dy -= dy1; | ||
2855 | + s->mouse_dz -= dz1; | ||
2856 | +} | ||
2857 | + | ||
2858 | +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) | ||
2859 | +{ | ||
2860 | + KBDState *s = &kbd_state; | ||
2861 | + | ||
2862 | + /* check if deltas are recorded when disabled */ | ||
2863 | + if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) | ||
2864 | + return; | ||
2865 | + | ||
2866 | + s->mouse_dx += dx; | ||
2867 | + s->mouse_dy -= dy; | ||
2868 | + s->mouse_dz += dz; | ||
2869 | + s->mouse_buttons = buttons_state; | ||
2870 | + | ||
2871 | + if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && | ||
2872 | + (s->queues[1].count < (KBD_QUEUE_SIZE - 16))) { | ||
2873 | + for(;;) { | ||
2874 | + /* if not remote, send event. Multiple events are sent if | ||
2875 | + too big deltas */ | ||
2876 | + kbd_mouse_send_packet(s); | ||
2877 | + if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) | ||
2878 | + break; | ||
2879 | + } | ||
2880 | + } | ||
2881 | +} | ||
2882 | + | ||
2883 | +static void kbd_write_mouse(KBDState *s, int val) | ||
2884 | +{ | ||
2885 | +#ifdef DEBUG_MOUSE | ||
2886 | + printf("kbd: write mouse 0x%02x\n", val); | ||
2887 | +#endif | ||
2888 | + switch(s->mouse_write_cmd) { | ||
2889 | + default: | ||
2890 | + case -1: | ||
2891 | + /* mouse command */ | ||
2892 | + if (s->mouse_wrap) { | ||
2893 | + if (val == AUX_RESET_WRAP) { | ||
2894 | + s->mouse_wrap = 0; | ||
2895 | + kbd_queue(s, AUX_ACK, 1); | ||
2896 | + return; | ||
2897 | + } else if (val != AUX_RESET) { | ||
2898 | + kbd_queue(s, val, 1); | ||
2899 | + return; | ||
2900 | + } | ||
2901 | + } | ||
2902 | + switch(val) { | ||
2903 | + case AUX_SET_SCALE11: | ||
2904 | + s->mouse_status &= ~MOUSE_STATUS_SCALE21; | ||
2905 | + kbd_queue(s, AUX_ACK, 1); | ||
2906 | + break; | ||
2907 | + case AUX_SET_SCALE21: | ||
2908 | + s->mouse_status |= MOUSE_STATUS_SCALE21; | ||
2909 | + kbd_queue(s, AUX_ACK, 1); | ||
2910 | + break; | ||
2911 | + case AUX_SET_STREAM: | ||
2912 | + s->mouse_status &= ~MOUSE_STATUS_REMOTE; | ||
2913 | + kbd_queue(s, AUX_ACK, 1); | ||
2914 | + break; | ||
2915 | + case AUX_SET_WRAP: | ||
2916 | + s->mouse_wrap = 1; | ||
2917 | + kbd_queue(s, AUX_ACK, 1); | ||
2918 | + break; | ||
2919 | + case AUX_SET_REMOTE: | ||
2920 | + s->mouse_status |= MOUSE_STATUS_REMOTE; | ||
2921 | + kbd_queue(s, AUX_ACK, 1); | ||
2922 | + break; | ||
2923 | + case AUX_GET_TYPE: | ||
2924 | + kbd_queue(s, AUX_ACK, 1); | ||
2925 | + kbd_queue(s, s->mouse_type, 1); | ||
2926 | + break; | ||
2927 | + case AUX_SET_RES: | ||
2928 | + case AUX_SET_SAMPLE: | ||
2929 | + s->mouse_write_cmd = val; | ||
2930 | + kbd_queue(s, AUX_ACK, 1); | ||
2931 | + break; | ||
2932 | + case AUX_GET_SCALE: | ||
2933 | + kbd_queue(s, AUX_ACK, 1); | ||
2934 | + kbd_queue(s, s->mouse_status, 1); | ||
2935 | + kbd_queue(s, s->mouse_resolution, 1); | ||
2936 | + kbd_queue(s, s->mouse_sample_rate, 1); | ||
2937 | + break; | ||
2938 | + case AUX_POLL: | ||
2939 | + kbd_queue(s, AUX_ACK, 1); | ||
2940 | + kbd_mouse_send_packet(s); | ||
2941 | + break; | ||
2942 | + case AUX_ENABLE_DEV: | ||
2943 | + s->mouse_status |= MOUSE_STATUS_ENABLED; | ||
2944 | + kbd_queue(s, AUX_ACK, 1); | ||
2945 | + break; | ||
2946 | + case AUX_DISABLE_DEV: | ||
2947 | + s->mouse_status &= ~MOUSE_STATUS_ENABLED; | ||
2948 | + kbd_queue(s, AUX_ACK, 1); | ||
2949 | + break; | ||
2950 | + case AUX_SET_DEFAULT: | ||
2951 | + s->mouse_sample_rate = 100; | ||
2952 | + s->mouse_resolution = 2; | ||
2953 | + s->mouse_status = 0; | ||
2954 | + kbd_queue(s, AUX_ACK, 1); | ||
2955 | + break; | ||
2956 | + case AUX_RESET: | ||
2957 | + s->mouse_sample_rate = 100; | ||
2958 | + s->mouse_resolution = 2; | ||
2959 | + s->mouse_status = 0; | ||
2960 | + kbd_queue(s, AUX_ACK, 1); | ||
2961 | + kbd_queue(s, 0xaa, 1); | ||
2962 | + kbd_queue(s, s->mouse_type, 1); | ||
2963 | + break; | ||
2964 | + default: | ||
2965 | + break; | ||
2966 | + } | ||
2967 | + break; | ||
2968 | + case AUX_SET_SAMPLE: | ||
2969 | + s->mouse_sample_rate = val; | ||
2970 | +#if 0 | ||
2971 | + /* detect IMPS/2 or IMEX */ | ||
2972 | + switch(s->mouse_detect_state) { | ||
2973 | + default: | ||
2974 | + case 0: | ||
2975 | + if (val == 200) | ||
2976 | + s->mouse_detect_state = 1; | ||
2977 | + break; | ||
2978 | + case 1: | ||
2979 | + if (val == 100) | ||
2980 | + s->mouse_detect_state = 2; | ||
2981 | + else if (val == 200) | ||
2982 | + s->mouse_detect_state = 3; | ||
2983 | + else | ||
2984 | + s->mouse_detect_state = 0; | ||
2985 | + break; | ||
2986 | + case 2: | ||
2987 | + if (val == 80) | ||
2988 | + s->mouse_type = 3; /* IMPS/2 */ | ||
2989 | + s->mouse_detect_state = 0; | ||
2990 | + break; | ||
2991 | + case 3: | ||
2992 | + if (val == 80) | ||
2993 | + s->mouse_type = 4; /* IMEX */ | ||
2994 | + s->mouse_detect_state = 0; | ||
2995 | + break; | ||
2996 | + } | ||
2997 | +#endif | ||
2998 | + kbd_queue(s, AUX_ACK, 1); | ||
2999 | + s->mouse_write_cmd = -1; | ||
3000 | + break; | ||
3001 | + case AUX_SET_RES: | ||
3002 | + s->mouse_resolution = val; | ||
3003 | + kbd_queue(s, AUX_ACK, 1); | ||
3004 | + s->mouse_write_cmd = -1; | ||
2826 | break; | 3005 | break; |
2827 | } | 3006 | } |
2828 | - s->kbd_write_cmd = -1; | ||
2829 | } | 3007 | } |
2830 | 3008 | ||
2831 | void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val) | 3009 | void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val) |
@@ -2857,6 +3035,9 @@ void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val) | @@ -2857,6 +3035,9 @@ void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val) | ||
2857 | cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT); | 3035 | cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT); |
2858 | } | 3036 | } |
2859 | break; | 3037 | break; |
3038 | + case KBD_CCMD_WRITE_MOUSE: | ||
3039 | + kbd_write_mouse(s, val); | ||
3040 | + break; | ||
2860 | default: | 3041 | default: |
2861 | break; | 3042 | break; |
2862 | } | 3043 | } |
@@ -2869,8 +3050,9 @@ void kbd_reset(KBDState *s) | @@ -2869,8 +3050,9 @@ void kbd_reset(KBDState *s) | ||
2869 | int i; | 3050 | int i; |
2870 | 3051 | ||
2871 | s->kbd_write_cmd = -1; | 3052 | s->kbd_write_cmd = -1; |
3053 | + s->mouse_write_cmd = -1; | ||
2872 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; | 3054 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; |
2873 | - s->status = KBD_MODE_SYS | KBD_MODE_NO_KEYLOCK; | 3055 | + s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; |
2874 | for(i = 0; i < 2; i++) { | 3056 | for(i = 0; i < 2; i++) { |
2875 | q = &s->queues[i]; | 3057 | q = &s->queues[i]; |
2876 | q->rptr = 0; | 3058 | q->rptr = 0; |
@@ -2934,6 +3116,63 @@ void bochs_bios_init(void) | @@ -2934,6 +3116,63 @@ void bochs_bios_init(void) | ||
2934 | } | 3116 | } |
2935 | 3117 | ||
2936 | /***********************************************************/ | 3118 | /***********************************************************/ |
3119 | +/* dumb display */ | ||
3120 | + | ||
3121 | +/* init terminal so that we can grab keys */ | ||
3122 | +static struct termios oldtty; | ||
3123 | + | ||
3124 | +static void term_exit(void) | ||
3125 | +{ | ||
3126 | + tcsetattr (0, TCSANOW, &oldtty); | ||
3127 | +} | ||
3128 | + | ||
3129 | +static void term_init(void) | ||
3130 | +{ | ||
3131 | + struct termios tty; | ||
3132 | + | ||
3133 | + tcgetattr (0, &tty); | ||
3134 | + oldtty = tty; | ||
3135 | + | ||
3136 | + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP | ||
3137 | + |INLCR|IGNCR|ICRNL|IXON); | ||
3138 | + tty.c_oflag |= OPOST; | ||
3139 | + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); | ||
3140 | + tty.c_cflag &= ~(CSIZE|PARENB); | ||
3141 | + tty.c_cflag |= CS8; | ||
3142 | + tty.c_cc[VMIN] = 1; | ||
3143 | + tty.c_cc[VTIME] = 0; | ||
3144 | + | ||
3145 | + tcsetattr (0, TCSANOW, &tty); | ||
3146 | + | ||
3147 | + atexit(term_exit); | ||
3148 | + | ||
3149 | + fcntl(0, F_SETFL, O_NONBLOCK); | ||
3150 | +} | ||
3151 | + | ||
3152 | +static void dumb_update(DisplayState *ds, int x, int y, int w, int h) | ||
3153 | +{ | ||
3154 | +} | ||
3155 | + | ||
3156 | +static void dumb_resize(DisplayState *ds, int w, int h) | ||
3157 | +{ | ||
3158 | +} | ||
3159 | + | ||
3160 | +static void dumb_refresh(DisplayState *ds) | ||
3161 | +{ | ||
3162 | + vga_update_display(); | ||
3163 | +} | ||
3164 | + | ||
3165 | +void dumb_display_init(DisplayState *ds) | ||
3166 | +{ | ||
3167 | + ds->data = NULL; | ||
3168 | + ds->linesize = 0; | ||
3169 | + ds->depth = 0; | ||
3170 | + ds->dpy_update = dumb_update; | ||
3171 | + ds->dpy_resize = dumb_resize; | ||
3172 | + ds->dpy_refresh = dumb_refresh; | ||
3173 | +} | ||
3174 | + | ||
3175 | +/***********************************************************/ | ||
2937 | /* cpu signal handler */ | 3176 | /* cpu signal handler */ |
2938 | static void host_segv_handler(int host_signum, siginfo_t *info, | 3177 | static void host_segv_handler(int host_signum, siginfo_t *info, |
2939 | void *puc) | 3178 | void *puc) |
@@ -2947,6 +3186,9 @@ static void host_segv_handler(int host_signum, siginfo_t *info, | @@ -2947,6 +3186,9 @@ static void host_segv_handler(int host_signum, siginfo_t *info, | ||
2947 | static int timer_irq_pending; | 3186 | static int timer_irq_pending; |
2948 | static int timer_irq_count; | 3187 | static int timer_irq_count; |
2949 | 3188 | ||
3189 | +static int timer_ms; | ||
3190 | +static int gui_refresh_pending, gui_refresh_count; | ||
3191 | + | ||
2950 | static void host_alarm_handler(int host_signum, siginfo_t *info, | 3192 | static void host_alarm_handler(int host_signum, siginfo_t *info, |
2951 | void *puc) | 3193 | void *puc) |
2952 | { | 3194 | { |
@@ -2958,9 +3200,17 @@ static void host_alarm_handler(int host_signum, siginfo_t *info, | @@ -2958,9 +3200,17 @@ static void host_alarm_handler(int host_signum, siginfo_t *info, | ||
2958 | if (timer_irq_count > 2) | 3200 | if (timer_irq_count > 2) |
2959 | timer_irq_count = 2; | 3201 | timer_irq_count = 2; |
2960 | timer_irq_count--; | 3202 | timer_irq_count--; |
3203 | + timer_irq_pending = 1; | ||
3204 | + } | ||
3205 | + gui_refresh_count += timer_ms; | ||
3206 | + if (gui_refresh_count >= GUI_REFRESH_INTERVAL) { | ||
3207 | + gui_refresh_count = 0; | ||
3208 | + gui_refresh_pending = 1; | ||
3209 | + } | ||
3210 | + | ||
3211 | + if (gui_refresh_pending || timer_irq_pending) { | ||
2961 | /* just exit from the cpu to have a chance to handle timers */ | 3212 | /* just exit from the cpu to have a chance to handle timers */ |
2962 | cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT); | 3213 | cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT); |
2963 | - timer_irq_pending = 1; | ||
2964 | } | 3214 | } |
2965 | } | 3215 | } |
2966 | 3216 | ||
@@ -2988,6 +3238,14 @@ int main_loop(void *opaque) | @@ -2988,6 +3238,14 @@ int main_loop(void *opaque) | ||
2988 | uint8_t ch; | 3238 | uint8_t ch; |
2989 | CPUState *env = global_env; | 3239 | CPUState *env = global_env; |
2990 | 3240 | ||
3241 | + if (nodisp && !term_inited) { | ||
3242 | + /* initialize terminal only there so that the user has a | ||
3243 | + chance to stop QEMU with Ctrl-C before the gdb connection | ||
3244 | + is launched */ | ||
3245 | + term_inited = 1; | ||
3246 | + term_init(); | ||
3247 | + } | ||
3248 | + | ||
2991 | for(;;) { | 3249 | for(;;) { |
2992 | 3250 | ||
2993 | ret = cpu_x86_exec(env); | 3251 | ret = cpu_x86_exec(env); |
@@ -3059,6 +3317,12 @@ int main_loop(void *opaque) | @@ -3059,6 +3317,12 @@ int main_loop(void *opaque) | ||
3059 | pic_set_irq(0, 0); | 3317 | pic_set_irq(0, 0); |
3060 | timer_irq_pending = 0; | 3318 | timer_irq_pending = 0; |
3061 | } | 3319 | } |
3320 | + | ||
3321 | + /* VGA */ | ||
3322 | + if (gui_refresh_pending) { | ||
3323 | + display_state.dpy_refresh(&display_state); | ||
3324 | + gui_refresh_pending = 0; | ||
3325 | + } | ||
3062 | } | 3326 | } |
3063 | return EXCP_INTERRUPT; | 3327 | return EXCP_INTERRUPT; |
3064 | } | 3328 | } |
@@ -3098,31 +3362,35 @@ struct option long_options[] = { | @@ -3098,31 +3362,35 @@ struct option long_options[] = { | ||
3098 | { "hdb", 1, NULL, 0, }, | 3362 | { "hdb", 1, NULL, 0, }, |
3099 | { "snapshot", 0, NULL, 0, }, | 3363 | { "snapshot", 0, NULL, 0, }, |
3100 | { "hdachs", 1, NULL, 0, }, | 3364 | { "hdachs", 1, NULL, 0, }, |
3365 | + { "nodisp", 0, NULL, 0, }, | ||
3101 | { NULL, 0, NULL, 0 }, | 3366 | { NULL, 0, NULL, 0 }, |
3102 | }; | 3367 | }; |
3103 | 3368 | ||
3104 | int main(int argc, char **argv) | 3369 | int main(int argc, char **argv) |
3105 | { | 3370 | { |
3106 | int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index; | 3371 | int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index; |
3107 | - int snapshot, linux_boot; | 3372 | + int snapshot, linux_boot, total_ram_size; |
3108 | struct linux_params *params; | 3373 | struct linux_params *params; |
3109 | struct sigaction act; | 3374 | struct sigaction act; |
3110 | struct itimerval itv; | 3375 | struct itimerval itv; |
3111 | CPUX86State *env; | 3376 | CPUX86State *env; |
3112 | const char *tmpdir, *initrd_filename; | 3377 | const char *tmpdir, *initrd_filename; |
3113 | const char *hd_filename[MAX_DISKS]; | 3378 | const char *hd_filename[MAX_DISKS]; |
3114 | - | 3379 | + DisplayState *ds = &display_state; |
3380 | + | ||
3115 | /* we never want that malloc() uses mmap() */ | 3381 | /* we never want that malloc() uses mmap() */ |
3116 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); | 3382 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
3117 | initrd_filename = NULL; | 3383 | initrd_filename = NULL; |
3118 | for(i = 0; i < MAX_DISKS; i++) | 3384 | for(i = 0; i < MAX_DISKS; i++) |
3119 | hd_filename[i] = NULL; | 3385 | hd_filename[i] = NULL; |
3120 | phys_ram_size = 32 * 1024 * 1024; | 3386 | phys_ram_size = 32 * 1024 * 1024; |
3387 | + vga_ram_size = VGA_RAM_SIZE; | ||
3121 | pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT); | 3388 | pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT); |
3122 | use_gdbstub = 0; | 3389 | use_gdbstub = 0; |
3123 | gdbstub_port = DEFAULT_GDBSTUB_PORT; | 3390 | gdbstub_port = DEFAULT_GDBSTUB_PORT; |
3124 | snapshot = 0; | 3391 | snapshot = 0; |
3125 | linux_boot = 0; | 3392 | linux_boot = 0; |
3393 | + nodisp = 0; | ||
3126 | for(;;) { | 3394 | for(;;) { |
3127 | c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index); | 3395 | c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index); |
3128 | if (c == -1) | 3396 | if (c == -1) |
@@ -3164,6 +3432,9 @@ int main(int argc, char **argv) | @@ -3164,6 +3432,9 @@ int main(int argc, char **argv) | ||
3164 | chs_fail: ; | 3432 | chs_fail: ; |
3165 | } | 3433 | } |
3166 | break; | 3434 | break; |
3435 | + case 5: | ||
3436 | + nodisp = 1; | ||
3437 | + break; | ||
3167 | } | 3438 | } |
3168 | break; | 3439 | break; |
3169 | case 'h': | 3440 | case 'h': |
@@ -3232,9 +3503,11 @@ int main(int argc, char **argv) | @@ -3232,9 +3503,11 @@ int main(int argc, char **argv) | ||
3232 | phys_ram_file); | 3503 | phys_ram_file); |
3233 | exit(1); | 3504 | exit(1); |
3234 | } | 3505 | } |
3235 | - ftruncate(phys_ram_fd, phys_ram_size); | 3506 | + total_ram_size = phys_ram_size + vga_ram_size; |
3507 | + ftruncate(phys_ram_fd, total_ram_size); | ||
3236 | unlink(phys_ram_file); | 3508 | unlink(phys_ram_file); |
3237 | - phys_ram_base = mmap(get_mmap_addr(phys_ram_size), phys_ram_size, | 3509 | + phys_ram_base = mmap(get_mmap_addr(total_ram_size), |
3510 | + total_ram_size, | ||
3238 | PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, | 3511 | PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, |
3239 | phys_ram_fd, 0); | 3512 | phys_ram_fd, 0); |
3240 | if (phys_ram_base == MAP_FAILED) { | 3513 | if (phys_ram_base == MAP_FAILED) { |
@@ -3261,6 +3534,9 @@ int main(int argc, char **argv) | @@ -3261,6 +3534,9 @@ int main(int argc, char **argv) | ||
3261 | 3534 | ||
3262 | init_ioports(); | 3535 | init_ioports(); |
3263 | 3536 | ||
3537 | + /* allocate RAM */ | ||
3538 | + cpu_register_physical_memory(0, phys_ram_size, 0); | ||
3539 | + | ||
3264 | if (linux_boot) { | 3540 | if (linux_boot) { |
3265 | /* now we can load the kernel */ | 3541 | /* now we can load the kernel */ |
3266 | ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR); | 3542 | ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR); |
@@ -3366,11 +3642,23 @@ int main(int argc, char **argv) | @@ -3366,11 +3642,23 @@ int main(int argc, char **argv) | ||
3366 | bochs_bios_init(); | 3642 | bochs_bios_init(); |
3367 | } | 3643 | } |
3368 | 3644 | ||
3645 | + /* terminal init */ | ||
3646 | + if (nodisp) { | ||
3647 | + dumb_display_init(ds); | ||
3648 | + } else { | ||
3649 | +#ifdef CONFIG_SDL | ||
3650 | + sdl_display_init(ds); | ||
3651 | + /* the pthreads modify sigaction. We don't want that. */ | ||
3652 | +#define sigaction __sigaction | ||
3653 | +#else | ||
3654 | + dumb_display_init(ds); | ||
3655 | +#endif | ||
3656 | + } | ||
3369 | /* init basic PC hardware */ | 3657 | /* init basic PC hardware */ |
3370 | register_ioport_write(0x80, 1, ioport80_write, 1); | 3658 | register_ioport_write(0x80, 1, ioport80_write, 1); |
3371 | 3659 | ||
3372 | - register_ioport_write(0x3d4, 2, vga_ioport_write, 1); | ||
3373 | - | 3660 | + vga_init(ds, phys_ram_base + phys_ram_size, phys_ram_size, |
3661 | + vga_ram_size); | ||
3374 | cmos_init(); | 3662 | cmos_init(); |
3375 | pic_init(); | 3663 | pic_init(); |
3376 | pit_init(); | 3664 | pit_init(); |
@@ -3378,7 +3666,7 @@ int main(int argc, char **argv) | @@ -3378,7 +3666,7 @@ int main(int argc, char **argv) | ||
3378 | ne2000_init(); | 3666 | ne2000_init(); |
3379 | ide_init(); | 3667 | ide_init(); |
3380 | kbd_init(); | 3668 | kbd_init(); |
3381 | - | 3669 | + |
3382 | /* setup cpu signal handlers for MMU / self modifying code handling */ | 3670 | /* setup cpu signal handlers for MMU / self modifying code handling */ |
3383 | sigfillset(&act.sa_mask); | 3671 | sigfillset(&act.sa_mask); |
3384 | act.sa_flags = SA_SIGINFO; | 3672 | act.sa_flags = SA_SIGINFO; |
@@ -3397,6 +3685,7 @@ int main(int argc, char **argv) | @@ -3397,6 +3685,7 @@ int main(int argc, char **argv) | ||
3397 | /* we probe the tick duration of the kernel to inform the user if | 3685 | /* we probe the tick duration of the kernel to inform the user if |
3398 | the emulated kernel requested a too high timer frequency */ | 3686 | the emulated kernel requested a too high timer frequency */ |
3399 | getitimer(ITIMER_REAL, &itv); | 3687 | getitimer(ITIMER_REAL, &itv); |
3688 | + timer_ms = itv.it_interval.tv_usec / 1000; | ||
3400 | pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) / | 3689 | pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) / |
3401 | 1000000; | 3690 | 1000000; |
3402 | 3691 |
vl.h
@@ -25,7 +25,22 @@ | @@ -25,7 +25,22 @@ | ||
25 | #define VL_H | 25 | #define VL_H |
26 | 26 | ||
27 | /* vl.c */ | 27 | /* vl.c */ |
28 | +struct CPUX86State; | ||
29 | +extern int reset_requested; | ||
30 | + | ||
31 | +typedef void (IOPortWriteFunc)(struct CPUX86State *env, uint32_t address, uint32_t data); | ||
32 | +typedef uint32_t (IOPortReadFunc)(struct CPUX86State *env, uint32_t address); | ||
33 | + | ||
28 | void *get_mmap_addr(unsigned long size); | 34 | void *get_mmap_addr(unsigned long size); |
35 | +int register_ioport_read(int start, int length, IOPortReadFunc *func, int size); | ||
36 | +int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size); | ||
37 | + | ||
38 | +void kbd_put_keycode(int keycode); | ||
39 | + | ||
40 | +#define MOUSE_EVENT_LBUTTON 0x01 | ||
41 | +#define MOUSE_EVENT_RBUTTON 0x02 | ||
42 | +#define MOUSE_EVENT_MBUTTON 0x04 | ||
43 | +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); | ||
29 | 44 | ||
30 | /* block.c */ | 45 | /* block.c */ |
31 | typedef struct BlockDriverState BlockDriverState; | 46 | typedef struct BlockDriverState BlockDriverState; |
@@ -52,4 +67,34 @@ struct cow_header_v2 { | @@ -52,4 +67,34 @@ struct cow_header_v2 { | ||
52 | uint32_t sectorsize; | 67 | uint32_t sectorsize; |
53 | }; | 68 | }; |
54 | 69 | ||
70 | +/* vga.c */ | ||
71 | + | ||
72 | +#define VGA_RAM_SIZE (8192 * 1024) | ||
73 | + | ||
74 | +typedef struct DisplayState { | ||
75 | + uint8_t *data; | ||
76 | + int linesize; | ||
77 | + int depth; | ||
78 | + void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h); | ||
79 | + void (*dpy_resize)(struct DisplayState *s, int w, int h); | ||
80 | + void (*dpy_refresh)(struct DisplayState *s); | ||
81 | +} DisplayState; | ||
82 | + | ||
83 | +static inline void dpy_update(DisplayState *s, int x, int y, int w, int h) | ||
84 | +{ | ||
85 | + s->dpy_update(s, x, y, w, h); | ||
86 | +} | ||
87 | + | ||
88 | +static inline void dpy_resize(DisplayState *s, int w, int h) | ||
89 | +{ | ||
90 | + s->dpy_resize(s, w, h); | ||
91 | +} | ||
92 | + | ||
93 | +int vga_init(DisplayState *ds, uint8_t *vga_ram_base, | ||
94 | + unsigned long vga_ram_offset, int vga_ram_size); | ||
95 | +void vga_update_display(void); | ||
96 | + | ||
97 | +/* sdl.c */ | ||
98 | +void sdl_display_init(DisplayState *ds); | ||
99 | + | ||
55 | #endif /* VL_H */ | 100 | #endif /* VL_H */ |