diff --git a/qemu-pc9821/qemu/hw/fdc.c b/qemu-pc9821/qemu/hw/fdc.c index fe7fb53b..297d2e8e 100644 --- a/qemu-pc9821/qemu/hw/fdc.c +++ b/qemu-pc9821/qemu/hw/fdc.c @@ -220,7 +220,7 @@ static const fd_format_t fd_formats[] = { /* 1.23 MB 5"1/4 floppy disks */ { FDRIVE_DRV_120, FDRIVE_DISK_288, 1024, 8, 77, 1, "1.23 MB 5\"1/4", }, /* 1.2 MB 5"1/4 floppy disks */ - { FDRIVE_DRV_120, FDRIVE_DISK_288, 512, 15, 80, 1, "1.2 kB 5\"1/4", }, + { FDRIVE_DRV_120, FDRIVE_DISK_288, 512, 15, 80, 1, "1.2 MB 5\"1/4", }, { FDRIVE_DRV_120, FDRIVE_DISK_288, 512, 18, 80, 1, "1.44 MB 5\"1/4", }, { FDRIVE_DRV_120, FDRIVE_DISK_288, 512, 18, 82, 1, "1.48 MB 5\"1/4", }, { FDRIVE_DRV_120, FDRIVE_DISK_288, 512, 18, 83, 1, "1.49 MB 5\"1/4", }, diff --git a/qemu-pc9821/qemu/hw/fmopna.cpp b/qemu-pc9821/qemu/hw/fmopna.cpp index cc314036..a9d032e0 100644 --- a/qemu-pc9821/qemu/hw/fmopna.cpp +++ b/qemu-pc9821/qemu/hw/fmopna.cpp @@ -83,7 +83,7 @@ static inline uint16_t limit_sample(Sample sample) return highlow; } -void *opna_init(int frequency, int sample_rate) +void *opna_init(int frequency, int sample_rate, const char* path) { OPNAState *s = (OPNAState *)malloc(sizeof(OPNAState)); @@ -92,7 +92,7 @@ void *opna_init(int frequency, int sample_rate) s->fifo_l = (Sample *)malloc(sizeof(Sample) * BUFLEN); s->fifo_r = (Sample *)malloc(sizeof(Sample) * BUFLEN); - s->opna->Init(frequency, sample_rate, false, NULL); + s->opna->Init(frequency, sample_rate, false, path); s->opna->Reset(); s->opna->SetReg(0x27, 0); diff --git a/qemu-pc9821/qemu/hw/fmopna.h b/qemu-pc9821/qemu/hw/fmopna.h index eb4a86c1..2fd7ea4e 100644 --- a/qemu-pc9821/qemu/hw/fmopna.h +++ b/qemu-pc9821/qemu/hw/fmopna.h @@ -31,7 +31,7 @@ extern "C" { #endif -void *opna_init(int frequency, int sample_rate); +void *opna_init(int frequency, int sample_rate, const char* path); void opna_reset(void *opaque); void opna_update_buffer(void *opaque, int16_t *buffer, int samples, int stereo); void opna_advance_time(void *opaque, int usec); diff --git a/qemu-pc9821/qemu/hw/pc.c b/qemu-pc9821/qemu/hw/pc.c index d9f9c4cf..fb9ca94c 100644 --- a/qemu-pc9821/qemu/hw/pc.c +++ b/qemu-pc9821/qemu/hw/pc.c @@ -1199,12 +1199,8 @@ QEMUMachine isapc_machine = { /* NEC PC-9821 */ +#ifdef HAS_AUDIO #define SUPPORT_PC98_FMSOUND - -#ifdef SUPPORT_PC98_FMSOUND -#define PC98_NE2000_NB_MAX 1 -#else -#define PC98_NE2000_NB_MAX 2 #endif static void *pc98_sys; @@ -1254,12 +1250,16 @@ static uint32_t pc98_ioport_9894_read(void *opaque, uint32_t addr) return 0x90; /* cpu wait */ } -#ifndef SUPPORT_PC98_FMSOUND +#ifdef HAS_AUDIO +#ifdef SUPPORT_PC98_FMSOUND + /* This port is assigned in pc98fmsound.c */ +#else static uint32_t pc98_ioport_a460_read(void *opaque, uint32_t addr) { return 0x7f; /* Mate-X PCM */ } #endif +#endif void pc98_cpu_shutdown(void) { @@ -1276,8 +1276,10 @@ void pc98_select_ems(uint32_t value) } /* LGY-98 */ +#define PC98_NE2000_NB_MAX 2 + static const int pc98_ne2000_io[2] = { 0xd0, 0x10d0 }; -static const int pc98_ne2000_irq[2] = { 6, 3 }; +static const int pc98_ne2000_irq[2] = { 6, 5 }; static void pc98_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) { @@ -1375,9 +1377,8 @@ static void pc98_init1(ram_addr_t ram_size, 1 KEYBOARD 2 CRTV 3 PC-9801-86 - LGY-98 #2 (I/O=10D0h) 4 RS-232C - 5 (SCSI) + 5 LGY-98 #2 (I/O=10D0h) 6 LGY-98 #1 (I/O=00D0h) 7 SLAVE PIC 8 FPU @@ -1401,10 +1402,12 @@ static void pc98_init1(ram_addr_t ram_size, register_ioport_write(0x534, 1, 1, pc98_ioport_534_write, NULL); register_ioport_read(0x534, 1, 1, pc98_ioport_534_read, NULL); register_ioport_read(0x9894, 1, 1, pc98_ioport_9894_read, NULL); +#ifdef HAS_AUDIO #ifdef SUPPORT_PC98_FMSOUND /* This port is assigned in pc98fmsound.c */ #else register_ioport_read(0xa460, 1, 1, pc98_ioport_a460_read, NULL); +#endif #endif cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1); diff --git a/qemu-pc9821/qemu/hw/pc98kbd.c b/qemu-pc9821/qemu/hw/pc98kbd.c index 9719caee..34c86432 100644 --- a/qemu-pc9821/qemu/hw/pc98kbd.c +++ b/qemu-pc9821/qemu/hw/pc98kbd.c @@ -58,34 +58,44 @@ enum { }; /* - END -> HELP - F11 -> STOP - F12 -> COPY + F11 -> STOP + F12 -> COPY + Home -> HOME/CR + End -> HELP + PageUp -> ROLL UP + Page Down -> ROLL DOWN + L-Alt -> GRAPH + R-Alt -> KANA + Henkan -> XFER + Muhenkan -> NFER */ static const uint8_t kbd_table[128] = { - 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x74, 0x1d, 0x1e, - 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0xff, 0x70, 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x70, 0xff, - 0x70, 0x34, 0xff, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6a, 0x6b, 0xff, 0xff, 0x3e, - 0x3a, 0x36, 0xff, 0x3b, 0xff, 0x3c, 0xff, 0x3f, - 0x3d, 0x37, 0x38, 0x39, 0xff, 0xff, 0xff, 0x60, - 0x61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x33, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x35, 0xff, 0x51, 0xff, 0x0d, 0xff, 0xff, + 0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x74,0x1d,0x1e, + 0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0xff,0x70,0x28,0x29,0x2a,0x2b,0x2c, + 0x2d,0x2e,0x2f,0x30,0x31,0x32,0x70,0x45,0x73,0x34,0x71,0x62,0x63,0x64,0x65,0x66, + 0x67,0x68,0x69,0x6a,0x6b,0xff,0xff,0x42,0x43,0x44,0x40,0x46,0x47,0x48,0x49,0x4a, + 0x4b,0x4c,0x4e,0x50,0xff,0xff,0xff,0x60,0x61,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0x33,0xff,0xff,0xff,0xff,0xff,0x35,0xff,0x51,0xff,0x0d,0xff,0xff, +}; +static const uint8_t kbd_table_e0[128] = { + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1c,0x74,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0x41,0xff,0xff,0x72,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0x3a,0x36,0xff,0x3b,0xff,0x3c,0xff,0x3f, + 0x3d,0x37,0x38,0x39,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, }; struct KeyBoardState { /* keyboard */ uint8_t lock; uint8_t pressed[128]; + uint8_t recv_e0; /* sio */ uint8_t mode; @@ -112,7 +122,9 @@ typedef struct KeyBoardState KeyBoardState; static void kbd_reset(KeyBoardState *s) { +/* printf("pc98kbd: reset\n"); +*/ } static void kbd_recv(KeyBoardState *s, uint8_t value) @@ -177,10 +189,22 @@ static void kbd_send(KeyBoardState *s, uint8_t value) static void kbd_event_handler(void *opaque, int keycode) { KeyBoardState *s = opaque; + const uint8_t *table; + + if (s->recv_e0 != 0) { + s->recv_e0 = 0; + table = kbd_table_e0; + } else { + if (keycode == 0xe0) { + s->recv_e0 = 1; + return; + } + table = kbd_table; + } if (keycode & 0x80) { /* key released */ - if ((keycode = kbd_table[keycode & 0x7f]) != 0xff) { + if ((keycode = table[keycode & 0x7f]) != 0xff) { if (s->pressed[keycode]) { kbd_recv(s, keycode | 0x80); } @@ -188,26 +212,29 @@ static void kbd_event_handler(void *opaque, int keycode) } } else { /* key pressed */ - if (keycode == 0x3a) { - s->lock ^= KBD_LOCK_CAPS; - if (s->lock & KBD_LOCK_CAPS) { - kbd_recv(s, 0x71); + if ((keycode = table[keycode]) != 0xff) { + if (keycode == 0x71) { + s->lock ^= KBD_LOCK_CAPS; + if (s->lock & KBD_LOCK_CAPS) { + kbd_recv(s, 0x71); + } else { + kbd_recv(s, 0x71 | 0x80); + } + } else if (keycode == 0x72) { + s->lock ^= KBD_LOCK_KANA; + if (s->lock & KBD_LOCK_KANA) { + kbd_recv(s, 0x72); + } else { + kbd_recv(s, 0x72 | 0x80); + } } else { - kbd_recv(s, 0x71 | 0x80); + if (s->pressed[keycode]) { + kbd_recv(s, keycode | 0x80); + } + kbd_recv(s, keycode); + s->pressed[keycode] = 1; } - } else if (keycode == 0x70) { - s->lock ^= KBD_LOCK_KANA; - if (s->lock & KBD_LOCK_KANA) { - kbd_recv(s, 0x72); - } else { - kbd_recv(s, 0x72 | 0x80); - } - } else if ((keycode = kbd_table[keycode]) != 0xff) { - if (s->pressed[keycode]) { - kbd_recv(s, keycode | 0x80); - } - kbd_recv(s, keycode); - s->pressed[keycode] = 1; + } } } diff --git a/qemu-pc9821/qemu/hw/pc98sound.c b/qemu-pc9821/qemu/hw/pc98sound.c index 07726a28..2b42dee8 100644 --- a/qemu-pc9821/qemu/hw/pc98sound.c +++ b/qemu-pc9821/qemu/hw/pc98sound.c @@ -270,18 +270,17 @@ static void sound_regnum_ex_write(void *opaque, uint32_t addr, uint32_t value) SoundState *s = opaque; if(!(s->mask & 1)) { -// return; + return; } s->regnum_ex = value; } static uint32_t sound_status_ex_read(void *opaque, uint32_t addr) { - /* 0x18C */ SoundState *s = opaque; if(!(s->mask & 1)) { -// return 0xff; + return 0xff; } /* run fmgen to update status */ @@ -296,7 +295,7 @@ static void sound_reg_ex_write(void *opaque, uint32_t addr, uint32_t value) SoundState *s = opaque; if(!(s->mask & 1)) { -// return; + return; } opna_write_reg_ex(s->opna, s->regnum_ex, value); update_interrupt(s); @@ -317,7 +316,7 @@ static uint32_t sound_reg_ex_read(void *opaque, uint32_t addr) SoundState *s = opaque; if(!(s->mask & 1)) { -// return 0xff; + return 0xff; } return opna_read_reg_ex(s->opna, s->regnum_ex); } @@ -368,6 +367,7 @@ void pc98_sound_init(AudioState *audio, qemu_irq *pic, int irq) { SoundState *s; struct audsettings as; + char temp_dir[MAX_PATH]; s = qemu_mallocz(sizeof(SoundState)); @@ -393,7 +393,9 @@ void pc98_sound_init(AudioState *audio, qemu_irq *pic, int irq) AUD_remove_card(&s->card); } - s->opna = opna_init(3993552 << 1, SAMPLE_RATE); + /* fmgen requires '/' at the end of wave file dir */ + sprintf(temp_dir, "%s/", bios_dir); + s->opna = opna_init(7987200, SAMPLE_RATE, temp_dir); register_ioport_write(0x188, 1, 1, sound_regnum_write, s); register_ioport_read(0x188, 1, 1, sound_status_read, s); diff --git a/qemu-pc9821/qemu/hw/pc98vga.c b/qemu-pc9821/qemu/hw/pc98vga.c index 337a9256..6c5044e7 100644 --- a/qemu-pc9821/qemu/hw/pc98vga.c +++ b/qemu-pc9821/qemu/hw/pc98vga.c @@ -152,10 +152,10 @@ struct EGCState { struct VGAState { DisplayState *ds; - uint8_t tvram_buffer[480 * 640]; + uint8_t tvram_buffer[400 * 641]; uint8_t vram0_buffer[480 * 640]; uint8_t vram1_buffer[480 * 640]; - uint8_t null_buffer[480 * 640]; + uint8_t null_buffer[480 * 641]; int width; int height; int last_width; @@ -163,7 +163,9 @@ struct VGAState { uint8_t dirty; uint8_t blink; uint32_t palette_chr[8]; - uint32_t palette_gfx[256]; + uint32_t palette_gfx8[8]; + uint32_t palette_gfx16[16]; + uint32_t palette_gfx256[256]; uint8_t font[0x84000]; uint8_t tvram[TVRAM_SIZE]; @@ -242,6 +244,7 @@ enum { MODE2_EGC = 0x02, MODE2_WRITE_MASK = 0x03, MODE2_256COLOR = 0x10, + MODE2_TXTSHIFT = 0x20, MODE2_480LINE = 0x34, }; @@ -2902,13 +2905,13 @@ static void grcg_mem_writeb(VGAState *s, uint32_t addr1, uint8_t value) s->vram16_draw_b[addr] = s->grcg_tile_b[0]; } if (!(s->grcg_mode & GRCG_PLANE_1)) { - s->vram16_draw_r[addr] = s->grcg_tile_b[0]; + s->vram16_draw_r[addr] = s->grcg_tile_b[1]; } if (!(s->grcg_mode & GRCG_PLANE_2)) { - s->vram16_draw_g[addr] = s->grcg_tile_b[0]; + s->vram16_draw_g[addr] = s->grcg_tile_b[2]; } if (!(s->grcg_mode & GRCG_PLANE_3)) { - s->vram16_draw_e[addr] = s->grcg_tile_b[0]; + s->vram16_draw_e[addr] = s->grcg_tile_b[3]; } } } @@ -4165,14 +4168,14 @@ static void update_palette(VGAState *s) r = s->anapal[PALETTE_R][i]; g = s->anapal[PALETTE_G][i]; b = s->anapal[PALETTE_B][i]; - s->palette_gfx[i] = rgb_to_pixel(depth, r, g, b); + s->palette_gfx256[i] = rgb_to_pixel(depth, r, g, b); } } else if (s->mode2[MODE2_16COLOR]) { for (i = 0; i < 16; i++) { r = s->anapal[PALETTE_R][i] << 4; g = s->anapal[PALETTE_G][i] << 4; b = s->anapal[PALETTE_B][i] << 4; - s->palette_gfx[i] = rgb_to_pixel(depth, r, g, b); + s->palette_gfx16[i] = rgb_to_pixel(depth, r, g, b); } } else { for (i = 0; i < 4; i++) { @@ -4181,11 +4184,11 @@ static void update_palette(VGAState *s) r = (s->digipal[i] & 0x02) ? 0xff : 0; g = (s->digipal[i] & 0x04) ? 0xff : 0; b = (s->digipal[i] & 0x01) ? 0xff : 0; - s->palette_gfx[lo[i]] = rgb_to_pixel(depth, r, g, b); + s->palette_gfx8[lo[i]] = rgb_to_pixel(depth, r, g, b); r = (s->digipal[i] & 0x20) ? 0xff : 0; g = (s->digipal[i] & 0x40) ? 0xff : 0; b = (s->digipal[i] & 0x10) ? 0xff : 0; - s->palette_gfx[hi[i]] = rgb_to_pixel(depth, r, g, b); + s->palette_gfx8[hi[i]] = rgb_to_pixel(depth, r, g, b); } } } @@ -4228,7 +4231,7 @@ static void render_chr_screen(VGAState *s) xofs = 8; addrofs = 1; } - memset(s->tvram_buffer, 0, 640 * 480); + memset(s->tvram_buffer, 0, sizeof(s->tvram_buffer)); for (y = 0; y < 400; y += bl) { uint32_t gaiji1st = 0, last = 0, offset; @@ -4267,19 +4270,21 @@ static void render_chr_screen(VGAState *s) gaiji1st = 0; } } else { - uint16_t lo = code & 0xff; - if (s->mode1[MODE1_FONTSEL]) { - offset = 0x80000 | (lo << 4); - } else { - offset = 0x82000 | (lo << 4); + offset = 0x80000 | ((code & 0xff) << 4); + if((attr & ATTR_VL) && s->mode1[MODE1_ATRSEL]) { + offset |= 0x1000; + } + if(!s->mode1[MODE1_FONTSEL]) { + offset |= 0x2000; } gaiji1st = 0; } last = offset; + for (l = 0; l < cl && l < 16; l++) { int yy = y + l + pl; - if (yy >= ytop && yy < 480) { - uint8_t *dest = s->tvram_buffer + yy * 640 + x; + if (yy >= ytop && yy < 400) { + uint8_t *dest = s->tvram_buffer + yy * 641 + x; uint8_t pattern = s->font[offset + l]; if (!(attr & ATTR_ST)) { pattern = 0; @@ -4290,7 +4295,7 @@ static void render_chr_screen(VGAState *s) if ((attr & ATTR_UL) && l == 15) { pattern = 0xff; } - if (attr & ATTR_VL) { + if ((attr & ATTR_VL) && !s->mode1[MODE1_ATRSEL]) { pattern |= 0x08; } if (cursor && l >= cursor_top && l < cursor_bottom) { @@ -4363,11 +4368,11 @@ static void render_gfx_screen(VGAState *s) } for (y = 0; y < 400; y++) { for (x = 0; x < 640; x += 8) { - b = s->vram16_draw_b[*addr]; - r = s->vram16_draw_r[*addr]; - g = s->vram16_draw_g[*addr]; + b = s->vram16_disp_b[*addr]; + r = s->vram16_disp_r[*addr]; + g = s->vram16_disp_g[*addr]; if (s->mode2[MODE2_16COLOR]) { - e = s->vram16_draw_e[*addr]; + e = s->vram16_disp_e[*addr]; } addr++; *dest++ = ((b & 0x80) >> 7) | ((r & 0x80) >> 6) | ((g & 0x80) >> 5) | ((e & 0x80) >> 4); @@ -4379,8 +4384,12 @@ static void render_gfx_screen(VGAState *s) *dest++ = ((b & 0x02) >> 1) | ((r & 0x02) >> 0) | ((g & 0x02) << 1) | ((e & 0x02) << 2); *dest++ = ((b & 0x01) >> 0) | ((r & 0x01) << 1) | ((g & 0x01) << 2) | ((e & 0x01) << 3); } - if (s->mode1[MODE1_200LINE]) { - memset(dest, 0, 640); + if ((s->gdc_gfx.cs[0] & 0x1f) == 1) { + if (s->mode1[MODE1_200LINE]) { + memset(dest, 0, 640); + } else { + memcpy(dest, dest - 640, 640); + } dest += 640; y++; } @@ -4406,10 +4415,12 @@ static void render_gfx_screen(VGAState *s) static void update_display(void *opaque) { VGAState *s = opaque; + uint8_t chr_start = s->gdc_chr.start; /* render screen */ if (s->mode2[MODE2_256COLOR] && s->mode2[MODE2_480LINE]) { s->height = 480; + chr_start = 0; } else { s->height = 400; } @@ -4424,7 +4435,7 @@ static void update_display(void *opaque) s->gdc_chr.dirty &= ~GDC_DIRTY_START; s->dirty |= DIRTY_DISPLAY; } - if (s->gdc_chr.start) { + if (chr_start) { if ((s->gdc_chr.dirty & GDC_DIRTY_CHR) || (s->dirty & DIRTY_TVRAM)) { /* update text screen */ render_chr_screen(s); @@ -4469,14 +4480,19 @@ static void update_display(void *opaque) int size = ds_get_linesize(s->ds); uint8_t *dest1 = ds_get_data(s->ds); - if (s->mode1[MODE1_DISP]) { + if (s->mode1[MODE1_DISP] && (chr_start || s->gdc_gfx.start)) { /* output screen */ uint8_t *src_chr; uint8_t *src_gfx; - if (!s->gdc_chr.start || s->mode2[MODE2_256COLOR]) { + uint32_t *palette_gfx; + + if (!chr_start) { src_chr = s->null_buffer; } else { src_chr = s->tvram_buffer; + if (!s->mode2[MODE2_TXTSHIFT]) { + src_chr++; + } } if (!s->gdc_gfx.start) { src_gfx = s->null_buffer; @@ -4487,6 +4503,13 @@ static void update_display(void *opaque) } else { src_gfx = s->vram1_buffer; } + if (s->mode2[MODE2_256COLOR]) { + palette_gfx = s->palette_gfx256; + } else if (s->mode2[MODE2_16COLOR]) { + palette_gfx = s->palette_gfx16; + } else { + palette_gfx = s->palette_gfx8; + } for (y = 0; y < s->height; y++) { uint8_t *dest = dest1; switch(depth) { @@ -4495,7 +4518,7 @@ static void update_display(void *opaque) if (*src_chr) { *((uint8_t *)dest) = s->palette_chr[*src_chr & 0x07]; } else { - *((uint8_t *)dest) = s->palette_gfx[*src_gfx]; + *((uint8_t *)dest) = palette_gfx[*src_gfx]; } src_chr++; src_gfx++; @@ -4508,7 +4531,7 @@ static void update_display(void *opaque) if (*src_chr) { *((uint16_t *)dest) = s->palette_chr[*src_chr & 0x07]; } else { - *((uint16_t *)dest) = s->palette_gfx[*src_gfx]; + *((uint16_t *)dest) = palette_gfx[*src_gfx]; } src_chr++; src_gfx++; @@ -4520,7 +4543,7 @@ static void update_display(void *opaque) if (*src_chr) { *((uint32_t *)dest) = s->palette_chr[*src_chr & 0x07]; } else { - *((uint32_t *)dest) = s->palette_gfx[*src_gfx]; + *((uint32_t *)dest) = palette_gfx[*src_gfx]; } src_chr++; src_gfx++; @@ -4528,6 +4551,7 @@ static void update_display(void *opaque) } break; } + src_chr++; // width=641 dest1 += size; } } else { @@ -4587,20 +4611,22 @@ static void font_init(VGAState *s) int i, j; p = s->font + 0x81000; - q = s->font + 0x82000; + q = s->font + 0x83000; for (i = 0; i < 256; i++) { - q += 8; for (j = 0; j < 4; j++) { uint32_t bit = 0; - if (i & (1 << j)) + if (i & (1 << j)) { bit |= 0xf0f0f0f0; - if (i & (0x10 << j)) + } + if (i & (0x10 << j)) { bit |= 0x0f0f0f0f; + } *(uint32_t *)p = bit; p += 4; *(uint16_t *)q = (uint16_t)bit; q += 2; } + q += 8; } for (i = 0; i < 0x80; i++) { q = s->font + (i << 12); diff --git a/qemu-pc9821/qemu/target-i386/op_helper.c b/qemu-pc9821/qemu/target-i386/op_helper.c index 85c14b1e..37195cdb 100644 --- a/qemu-pc9821/qemu/target-i386/op_helper.c +++ b/qemu-pc9821/qemu/target-i386/op_helper.c @@ -1788,20 +1788,20 @@ void helper_aas(void) void helper_daa(void) { - int al, af, cf; + int old_al, al, af, cf; int eflags; eflags = helper_cc_compute_all(CC_OP); cf = eflags & CC_C; af = eflags & CC_A; - al = EAX & 0xff; + old_al = al = EAX & 0xff; eflags = 0; if (((al & 0x0f) > 9 ) || af) { al = (al + 6) & 0xff; eflags |= CC_A; } - if ((al > 0x9f) || cf) { + if ((old_al > 0x99) || cf) { al = (al + 0x60) & 0xff; eflags |= CC_C; } diff --git a/qemu-pc9821/qemu/target-i386/ops_sse.h b/qemu-pc9821/qemu/target-i386/ops_sse.h index 99d483a2..b037147c 100644 --- a/qemu-pc9821/qemu/target-i386/ops_sse.h +++ b/qemu-pc9821/qemu/target-i386/ops_sse.h @@ -806,51 +806,51 @@ void helper_rcpss(XMMReg *d, XMMReg *s) void helper_haddps(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_S(0) = d->XMM_S(0) + d->XMM_S(1); - r.XMM_S(1) = d->XMM_S(2) + d->XMM_S(3); - r.XMM_S(2) = s->XMM_S(0) + s->XMM_S(1); - r.XMM_S(3) = s->XMM_S(2) + s->XMM_S(3); + r.XMM_S(0) = float32_add(d->XMM_S(0), d->XMM_S(1), &env->sse_status); + r.XMM_S(1) = float32_add(d->XMM_S(2), d->XMM_S(3), &env->sse_status); + r.XMM_S(2) = float32_add(s->XMM_S(0), s->XMM_S(1), &env->sse_status); + r.XMM_S(3) = float32_add(s->XMM_S(2), s->XMM_S(3), &env->sse_status); *d = r; } void helper_haddpd(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_D(0) = d->XMM_D(0) + d->XMM_D(1); - r.XMM_D(1) = s->XMM_D(0) + s->XMM_D(1); + r.XMM_D(0) = float64_add(d->XMM_D(0), d->XMM_D(1), &env->sse_status); + r.XMM_D(1) = float64_add(s->XMM_D(0), s->XMM_D(1), &env->sse_status); *d = r; } void helper_hsubps(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_S(0) = d->XMM_S(0) - d->XMM_S(1); - r.XMM_S(1) = d->XMM_S(2) - d->XMM_S(3); - r.XMM_S(2) = s->XMM_S(0) - s->XMM_S(1); - r.XMM_S(3) = s->XMM_S(2) - s->XMM_S(3); + r.XMM_S(0) = float32_sub(d->XMM_S(0), d->XMM_S(1), &env->sse_status); + r.XMM_S(1) = float32_sub(d->XMM_S(2), d->XMM_S(3), &env->sse_status); + r.XMM_S(2) = float32_sub(s->XMM_S(0), s->XMM_S(1), &env->sse_status); + r.XMM_S(3) = float32_sub(s->XMM_S(2), s->XMM_S(3), &env->sse_status); *d = r; } void helper_hsubpd(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_D(0) = d->XMM_D(0) - d->XMM_D(1); - r.XMM_D(1) = s->XMM_D(0) - s->XMM_D(1); + r.XMM_D(0) = float64_sub(d->XMM_D(0), d->XMM_D(1), &env->sse_status); + r.XMM_D(1) = float64_sub(s->XMM_D(0), s->XMM_D(1), &env->sse_status); *d = r; } void helper_addsubps(XMMReg *d, XMMReg *s) { - d->XMM_S(0) = d->XMM_S(0) - s->XMM_S(0); - d->XMM_S(1) = d->XMM_S(1) + s->XMM_S(1); - d->XMM_S(2) = d->XMM_S(2) - s->XMM_S(2); - d->XMM_S(3) = d->XMM_S(3) + s->XMM_S(3); + d->XMM_S(0) = float32_sub(d->XMM_S(0), s->XMM_S(0), &env->sse_status); + d->XMM_S(1) = float32_add(d->XMM_S(1), s->XMM_S(1), &env->sse_status); + d->XMM_S(2) = float32_sub(d->XMM_S(2), s->XMM_S(2), &env->sse_status); + d->XMM_S(3) = float32_add(d->XMM_S(3), s->XMM_S(3), &env->sse_status); } void helper_addsubpd(XMMReg *d, XMMReg *s) { - d->XMM_D(0) = d->XMM_D(0) - s->XMM_D(0); - d->XMM_D(1) = d->XMM_D(1) + s->XMM_D(1); + d->XMM_D(0) = float64_sub(d->XMM_D(0), s->XMM_D(0), &env->sse_status); + d->XMM_D(1) = float64_add(d->XMM_D(1), s->XMM_D(1), &env->sse_status); } /* XXX: unordered */ diff --git a/qemu-pc9821/qemu/target-i386/translate.c b/qemu-pc9821/qemu/target-i386/translate.c index 05db89f3..f1b9474e 100644 --- a/qemu-pc9821/qemu/target-i386/translate.c +++ b/qemu-pc9821/qemu/target-i386/translate.c @@ -1426,70 +1426,84 @@ static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, { target_ulong mask; int shift_label; - TCGv t0, t1; + TCGv t0, t1, t2; - if (ot == OT_QUAD) + if (ot == OT_QUAD) { mask = 0x3f; - else + } else { mask = 0x1f; + } /* load */ - if (op1 == OR_TMP0) + if (op1 == OR_TMP0) { gen_op_ld_T0_A0(ot + s->mem_index); - else + } else { gen_op_mov_TN_reg(ot, 0, op1); + } - tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask); + t0 = tcg_temp_local_new(); + t1 = tcg_temp_local_new(); + t2 = tcg_temp_local_new(); - tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1); + tcg_gen_andi_tl(t2, cpu_T[1], mask); if (is_right) { if (is_arith) { gen_exts(ot, cpu_T[0]); - tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5); - tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, cpu_T[0]); + tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2); } else { gen_extu(ot, cpu_T[0]); - tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5); - tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, cpu_T[0]); + tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2); } } else { - tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5); - tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, cpu_T[0]); + tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2); } /* store */ - if (op1 == OR_TMP0) + if (op1 == OR_TMP0) { gen_op_st_T0_A0(ot + s->mem_index); - else + } else { gen_op_mov_reg_T0(ot, op1); - + } + /* update eflags if non zero shift */ - if (s->cc_op != CC_OP_DYNAMIC) + if (s->cc_op != CC_OP_DYNAMIC) { gen_op_set_cc_op(s->cc_op); + } - /* XXX: inefficient */ - t0 = tcg_temp_local_new(); - t1 = tcg_temp_local_new(); - - tcg_gen_mov_tl(t0, cpu_T[0]); - tcg_gen_mov_tl(t1, cpu_T3); + tcg_gen_mov_tl(t1, cpu_T[0]); shift_label = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label); + tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label); - tcg_gen_mov_tl(cpu_cc_src, t1); - tcg_gen_mov_tl(cpu_cc_dst, t0); - if (is_right) + tcg_gen_addi_tl(t2, t2, -1); + tcg_gen_mov_tl(cpu_cc_dst, t1); + + if (is_right) { + if (is_arith) { + tcg_gen_sar_tl(cpu_cc_src, t0, t2); + } else { + tcg_gen_shr_tl(cpu_cc_src, t0, t2); + } + } else { + tcg_gen_shl_tl(cpu_cc_src, t0, t2); + } + + if (is_right) { tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot); - else + } else { tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot); - + } + gen_set_label(shift_label); s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ tcg_temp_free(t0); tcg_temp_free(t1); + tcg_temp_free(t2); } static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2, @@ -4827,20 +4841,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) tcg_gen_sub_tl(t2, t2, t0); gen_extu(ot, t2); tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1); + label2 = gen_new_label(); if (mod == 3) { - label2 = gen_new_label(); gen_op_mov_reg_v(ot, R_EAX, t0); tcg_gen_br(label2); gen_set_label(label1); gen_op_mov_reg_v(ot, rm, t1); - gen_set_label(label2); } else { - tcg_gen_mov_tl(t1, t0); + /* perform no-op store cycle like physical cpu; must be + before changing accumulator to ensure idempotency if + the store faults and the instruction is restarted */ + gen_op_st_v(ot + s->mem_index, t0, a0); gen_op_mov_reg_v(ot, R_EAX, t0); + tcg_gen_br(label2); gen_set_label(label1); - /* always store */ gen_op_st_v(ot + s->mem_index, t1, a0); } + gen_set_label(label2); tcg_gen_mov_tl(cpu_cc_src, t0); tcg_gen_mov_tl(cpu_cc_dst, t2); s->cc_op = CC_OP_SUBB + ot; @@ -7477,7 +7494,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; case 5: /* lfence */ case 6: /* mfence */ - if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE)) + if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2)) goto illegal_op; break; case 7: /* sfence / clflush */