mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge branch 'master' into multimonitor-take2-ui
This commit is contained in:
@@ -86,15 +86,15 @@
|
||||
#define ESDI_IOADDR_SEC 0x3518
|
||||
#define ESDI_IRQCHAN 14
|
||||
|
||||
#define BIOS_FILE_L "roms/hdd/esdi/90x8969.bin"
|
||||
#define BIOS_FILE_H "roms/hdd/esdi/90x8970.bin"
|
||||
#define BIOS_FILE_L "roms/hdd/esdi/62-000193-036.BIN"
|
||||
#define BIOS_FILE_H "roms/hdd/esdi/62-000194-036.BIN"
|
||||
|
||||
|
||||
#define ESDI_TIME (200*TIMER_USEC)
|
||||
#define ESDI_TIME 512
|
||||
#define CMD_ADAPTER 0
|
||||
|
||||
|
||||
typedef struct esdi_drive {
|
||||
typedef struct esdi_drive_t {
|
||||
int spt, hpc;
|
||||
int tracks;
|
||||
int sectors;
|
||||
@@ -102,7 +102,7 @@ typedef struct esdi_drive {
|
||||
int hdd_num;
|
||||
} drive_t;
|
||||
|
||||
typedef struct esdi {
|
||||
typedef struct esdi_t {
|
||||
int8_t dma;
|
||||
|
||||
uint32_t bios;
|
||||
@@ -133,7 +133,7 @@ typedef struct esdi {
|
||||
int command;
|
||||
int cmd_state;
|
||||
|
||||
int in_reset;
|
||||
int in_reset, in_reset2;
|
||||
uint64_t callback;
|
||||
pc_timer_t timer;
|
||||
|
||||
@@ -240,10 +240,10 @@ esdi_mca_set_callback(esdi_t *dev, uint64_t callback)
|
||||
|
||||
if (callback) {
|
||||
dev->callback = callback;
|
||||
timer_set_delay_u64(&dev->timer, dev->callback);
|
||||
timer_on_auto(&dev->timer, dev->callback);
|
||||
} else {
|
||||
dev->callback = 0;
|
||||
timer_disable(&dev->timer);
|
||||
timer_stop(&dev->timer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,11 +824,18 @@ esdi_read(uint16_t port, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port & 7) {
|
||||
case 2: /*Basic status register*/
|
||||
case 2: /*Basic status register*/
|
||||
if (!dev->status) {
|
||||
if (((dev->command == CMD_WRITE) || dev->in_reset2) && !dev->cmd_dev) {
|
||||
dev->in_reset2 = 0;
|
||||
dev->status |= STATUS_STATUS_OUT_FULL;
|
||||
} else if (dev->command && (dev->cmd_dev == ATTN_HOST_ADAPTER))
|
||||
dev->status |= STATUS_STATUS_OUT_FULL;
|
||||
}
|
||||
ret = dev->status;
|
||||
break;
|
||||
|
||||
case 3: /*IRQ status*/
|
||||
case 3: /*IRQ status*/
|
||||
dev->status &= ~STATUS_IRQ;
|
||||
ret = dev->irq_status;
|
||||
break;
|
||||
@@ -852,6 +859,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
case 2: /*Basic control register*/
|
||||
if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) {
|
||||
dev->in_reset = 1;
|
||||
dev->in_reset2 = 1;
|
||||
esdi_mca_set_callback(dev, ESDI_TIME * 50);
|
||||
dev->status = STATUS_BUSY;
|
||||
}
|
||||
@@ -883,6 +891,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case ATTN_RESET:
|
||||
dev->in_reset = 1;
|
||||
dev->in_reset2 = 1;
|
||||
esdi_mca_set_callback(dev, ESDI_TIME * 50);
|
||||
dev->status = STATUS_BUSY;
|
||||
break;
|
||||
@@ -1143,6 +1152,7 @@ esdi_init(const device_t *info)
|
||||
|
||||
/* Mark for a reset. */
|
||||
dev->in_reset = 1;
|
||||
dev->in_reset2 = 1;
|
||||
esdi_mca_set_callback(dev, ESDI_TIME * 50);
|
||||
dev->status = STATUS_BUSY;
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ ide_get_drive(int ch)
|
||||
|
||||
|
||||
double
|
||||
ide_get_period(ide_t *ide, int size)
|
||||
ide_get_xfer_time(ide_t *ide, int size)
|
||||
{
|
||||
double period = (10.0 / 3.0);
|
||||
|
||||
@@ -313,7 +313,7 @@ ide_atapi_get_period(uint8_t channel)
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
return ide_get_period(ide, 1);
|
||||
return ide_get_xfer_time(ide, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -535,7 +535,7 @@ static void ide_hd_identify(ide_t *ide)
|
||||
ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */
|
||||
ide->buffer[0] = (1 << 6); /*Fixed drive*/
|
||||
ide->buffer[20] = 3; /*Buffer type*/
|
||||
ide->buffer[21] = 512; /*Buffer size*/
|
||||
ide->buffer[21] = hdd[ide->hdd_num].cache.num_segments * hdd[ide->hdd_num].cache.segment_size; /*Buffer size*/
|
||||
ide->buffer[50] = 0x4000; /* Capabilities */
|
||||
ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0;
|
||||
|
||||
@@ -577,12 +577,11 @@ static void ide_hd_identify(ide_t *ide)
|
||||
ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]);
|
||||
}
|
||||
|
||||
ide->buffer[47] = hdd[ide->hdd_num].max_multiple_block | 0x8000; /*Max sectors on multiple transfer command*/
|
||||
if (!ide_boards[ide->board]->force_ata3 && ide_bm[ide->board]) {
|
||||
ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/
|
||||
ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/
|
||||
ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/
|
||||
} else {
|
||||
ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/
|
||||
ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/
|
||||
}
|
||||
}
|
||||
@@ -692,13 +691,15 @@ ide_get_sector(ide_t *ide)
|
||||
uint32_t heads, sectors;
|
||||
|
||||
if (ide->lba)
|
||||
return (off64_t)ide->lba_addr + ide->skip512;
|
||||
return (off64_t)ide->lba_addr;
|
||||
else {
|
||||
heads = ide->cfg_hpc;
|
||||
sectors = ide->cfg_spt;
|
||||
|
||||
uint8_t sector = ide->sector ? ide->sector : 1;
|
||||
|
||||
return ((((off64_t) ide->cylinder * heads) + ide->head) *
|
||||
sectors) + (ide->sector - 1) + ide->skip512;
|
||||
sectors) + (sector - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,6 +734,8 @@ loadhd(ide_t *ide, int d, const char *fn)
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_preset_auto(&hdd[d]);
|
||||
|
||||
ide->spt = ide->cfg_spt = hdd[d].spt;
|
||||
ide->hpc = ide->cfg_hpc = hdd[d].hpc;
|
||||
ide->tracks = hdd[d].tracks;
|
||||
@@ -1226,31 +1229,41 @@ ide_write_data(ide_t *ide, uint32_t val, int length)
|
||||
if (ide->type == IDE_ATAPI)
|
||||
ide_atapi_packet_write(ide, val, length);
|
||||
} else {
|
||||
switch(length) {
|
||||
case 1:
|
||||
idebufferb[ide->pos] = val & 0xff;
|
||||
ide->pos++;
|
||||
break;
|
||||
case 2:
|
||||
idebufferw[ide->pos >> 1] = val & 0xffff;
|
||||
ide->pos += 2;
|
||||
break;
|
||||
case 4:
|
||||
idebufferl[ide->pos >> 2] = val;
|
||||
ide->pos += 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
switch(length) {
|
||||
case 1:
|
||||
idebufferb[ide->pos] = val & 0xff;
|
||||
ide->pos++;
|
||||
break;
|
||||
case 2:
|
||||
idebufferw[ide->pos >> 1] = val & 0xffff;
|
||||
ide->pos += 2;
|
||||
break;
|
||||
case 4:
|
||||
idebufferl[ide->pos >> 2] = val;
|
||||
ide->pos += 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (ide->pos >= 512) {
|
||||
ide->pos=0;
|
||||
ide->atastat = BSY_STAT;
|
||||
if (ide->command == WIN_WRITE_MULTIPLE)
|
||||
ide_callback(ide);
|
||||
else
|
||||
ide_set_callback(ide, ide_get_period(ide, 512));
|
||||
}
|
||||
if (ide->pos >= 512) {
|
||||
ide->pos=0;
|
||||
ide->atastat = BSY_STAT;
|
||||
double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512);
|
||||
double wait_time = seek_time + xfer_time;
|
||||
if (ide->command == WIN_WRITE_MULTIPLE) {
|
||||
if ((ide->blockcount+1) >= ide->blocksize || ide->secount == 1) {
|
||||
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
|
||||
ide->pending_delay = 0;
|
||||
} else {
|
||||
ide->pending_delay += wait_time;
|
||||
ide_callback(ide);
|
||||
}
|
||||
} else {
|
||||
ide_set_callback(ide, wait_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1601,9 +1614,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||
else
|
||||
ide->atastat = READY_STAT | BSY_STAT;
|
||||
|
||||
if (ide->type == IDE_ATAPI)
|
||||
if (ide->type == IDE_ATAPI) {
|
||||
ide->sc->callback = 100.0 * IDE_TIME;
|
||||
ide_set_callback(ide, 100.0 * IDE_TIME);
|
||||
ide_set_callback(ide, 100.0 * IDE_TIME);
|
||||
} else {
|
||||
double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], ide_get_sector(ide), HDD_OP_SEEK, 0, 0.0);
|
||||
ide_set_callback(ide, seek_time);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1641,15 +1658,26 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||
ide->atastat = BSY_STAT;
|
||||
|
||||
if (ide->type == IDE_HDD) {
|
||||
uint32_t sec_count;
|
||||
double wait_time;
|
||||
if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) {
|
||||
if (ide->secount)
|
||||
ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9));
|
||||
else
|
||||
ide_set_callback(ide, ide_get_period(ide, 131072));
|
||||
} else if (val == WIN_READ_MULTIPLE)
|
||||
ide_set_callback(ide, 200.0 * IDE_TIME);
|
||||
else
|
||||
ide_set_callback(ide, ide_get_period(ide, 512));
|
||||
// TODO make DMA timing more accurate
|
||||
sec_count = ide->secount ? ide->secount : 256;
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
||||
wait_time = seek_time > xfer_time ? seek_time : xfer_time;
|
||||
} else if (val == WIN_READ_MULTIPLE) {
|
||||
sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize;
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
||||
wait_time = seek_time + xfer_time;
|
||||
} else {
|
||||
sec_count = 1;
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
||||
wait_time = seek_time + xfer_time;
|
||||
}
|
||||
ide_set_callback(ide, wait_time);
|
||||
} else
|
||||
ide_set_callback(ide, 200.0 * IDE_TIME);
|
||||
ide->do_initial_read = 1;
|
||||
@@ -1690,14 +1718,16 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
if ((ide->type == IDE_HDD) &&
|
||||
((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) {
|
||||
if (ide->secount)
|
||||
ide_set_callback(ide, ide_get_period(ide, (int) ide->secount << 9));
|
||||
else
|
||||
ide_set_callback(ide, ide_get_period(ide, 131072));
|
||||
uint32_t sec_count = ide->secount ? ide->secount : 256;
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
||||
double wait_time = seek_time > xfer_time ? seek_time : xfer_time;
|
||||
ide_set_callback(ide, wait_time);
|
||||
} else if ((ide->type == IDE_HDD) &&
|
||||
((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE)))
|
||||
ide_set_callback(ide, ide_get_period(ide, 512));
|
||||
else if (val == WIN_IDENTIFY)
|
||||
((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) {
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), ide->secount);
|
||||
ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2));
|
||||
} else if (val == WIN_IDENTIFY)
|
||||
ide_callback(ide);
|
||||
else
|
||||
ide_set_callback(ide, 200.0 * IDE_TIME);
|
||||
@@ -1864,10 +1894,20 @@ ide_read_data(ide_t *ide, int length)
|
||||
if (ide->secount) {
|
||||
ide_next_sector(ide);
|
||||
ide->atastat = BSY_STAT | READY_STAT | DSC_STAT;
|
||||
if (ide->command == WIN_READ_MULTIPLE)
|
||||
ide_callback(ide);
|
||||
else
|
||||
ide_set_callback(ide, ide_get_period(ide, 512));
|
||||
if (ide->command == WIN_READ_MULTIPLE) {
|
||||
if (!ide->blockcount) {
|
||||
uint32_t sec_count = (ide->secount < ide->blocksize) ? ide->secount : ide->blocksize;
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
|
||||
ide_set_callback(ide, seek_time + xfer_time);
|
||||
} else {
|
||||
ide_callback(ide);
|
||||
}
|
||||
} else {
|
||||
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
|
||||
double xfer_time = ide_get_xfer_time(ide, 512);
|
||||
ide_set_callback(ide, seek_time + xfer_time);
|
||||
}
|
||||
} else if (ide->command != WIN_READ_MULTIPLE)
|
||||
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
|
||||
}
|
||||
|
||||
351
src/disk/hdd.c
351
src/disk/hdd.c
@@ -17,15 +17,19 @@
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/cdrom.h>
|
||||
|
||||
#include <86box/video.h>
|
||||
#include "cpu.h"
|
||||
|
||||
hard_disk_t hdd[HDD_NUM];
|
||||
|
||||
@@ -150,3 +154,346 @@ hdd_is_valid(int c)
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
double
|
||||
hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time)
|
||||
{
|
||||
hdd_zone_t *zone = NULL;
|
||||
for (int i = 0; i < hdd->num_zones; i++) {
|
||||
zone = &hdd->zones[i];
|
||||
if (zone->end_sector >= dst_addr)
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t new_track = zone->start_track + ((dst_addr - zone->start_sector) / zone->sectors_per_track);
|
||||
uint32_t new_cylinder = new_track / hdd->phy_heads;
|
||||
uint32_t cylinder_diff = abs((int)hdd->cur_cylinder - (int)new_cylinder);
|
||||
|
||||
bool sequential = dst_addr == hdd->cur_addr + 1;
|
||||
continuous = continuous && sequential;
|
||||
|
||||
double seek_time = 0.0;
|
||||
if (continuous) {
|
||||
if (new_track == hdd->cur_track) {
|
||||
// Same track
|
||||
seek_time = zone->sector_time_usec;
|
||||
} else if (!cylinder_diff) {
|
||||
// Same cylinder, sequential track
|
||||
seek_time = hdd->head_switch_usec;
|
||||
} else {
|
||||
// Sequential cylinder
|
||||
seek_time = hdd->cyl_switch_usec;
|
||||
}
|
||||
} else {
|
||||
if (!cylinder_diff) {
|
||||
if (operation != HDD_OP_SEEK) {
|
||||
seek_time = hdd->avg_rotation_lat_usec;
|
||||
} else {
|
||||
//seek_time = hdd->cyl_switch_usec;
|
||||
seek_time = 50.0;
|
||||
}
|
||||
} else {
|
||||
seek_time = hdd->cyl_switch_usec + (hdd->full_stroke_usec * (double)cylinder_diff / (double)hdd->phy_cyl);
|
||||
if (operation != HDD_OP_SEEK) {
|
||||
seek_time += hdd->avg_rotation_lat_usec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!max_seek_time || seek_time <= max_seek_time) {
|
||||
hdd->cur_addr = dst_addr;
|
||||
hdd->cur_track = new_track;
|
||||
hdd->cur_cylinder = new_cylinder;
|
||||
}
|
||||
|
||||
return seek_time;
|
||||
}
|
||||
|
||||
static void
|
||||
hdd_readahead_update(hard_disk_t *hdd)
|
||||
{
|
||||
hdd_cache_t *cache = &hdd->cache;
|
||||
if (cache->ra_ongoing) {
|
||||
hdd_cache_seg_t *segment = &cache->segments[cache->ra_segment];
|
||||
|
||||
uint64_t elapsed_cycles = tsc - cache->ra_start_time;
|
||||
double elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
|
||||
// Do not overwrite data not yet read by host
|
||||
uint32_t max_read_ahead = (segment->host_addr + cache->segment_size) - segment->ra_addr;
|
||||
|
||||
double seek_time = 0.0;
|
||||
|
||||
for (uint32_t i = 0; i < max_read_ahead; i++) {
|
||||
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, elapsed_us - seek_time);
|
||||
if (seek_time > elapsed_us)
|
||||
break;
|
||||
|
||||
segment->ra_addr++;
|
||||
}
|
||||
|
||||
if (segment->ra_addr > segment->lba_addr + cache->segment_size) {
|
||||
uint32_t space_needed = segment->ra_addr - (segment->lba_addr + cache->segment_size);
|
||||
segment->lba_addr += space_needed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
hdd_writecache_flush(hard_disk_t *hdd)
|
||||
{
|
||||
double seek_time = 0.0;
|
||||
while (hdd->cache.write_pending) {
|
||||
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
|
||||
hdd->cache.write_addr++;
|
||||
hdd->cache.write_pending--;
|
||||
}
|
||||
|
||||
return seek_time;
|
||||
}
|
||||
|
||||
static void
|
||||
hdd_writecache_update(hard_disk_t *hdd)
|
||||
{
|
||||
if (hdd->cache.write_pending) {
|
||||
uint64_t elapsed_cycles = tsc - hdd->cache.write_start_time;
|
||||
double elapsed_us = (double)elapsed_cycles / cpuclock * 1000000.0;
|
||||
double seek_time = 0.0;
|
||||
|
||||
while (hdd->cache.write_pending) {
|
||||
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, elapsed_us - seek_time);
|
||||
if (seek_time > elapsed_us)
|
||||
break;
|
||||
|
||||
hdd->cache.write_addr++;
|
||||
hdd->cache.write_pending--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
||||
{
|
||||
hdd_readahead_update(hdd);
|
||||
hdd_writecache_update(hdd);
|
||||
|
||||
hdd->cache.ra_ongoing = 0;
|
||||
|
||||
double seek_time = 0.0;
|
||||
|
||||
if (hdd->cache.write_pending && (addr != (hdd->cache.write_addr + hdd->cache.write_pending))) {
|
||||
// New request is not sequential to existing cache, need to flush it
|
||||
seek_time += hdd_writecache_flush(hdd);
|
||||
}
|
||||
|
||||
if (!hdd->cache.write_pending) {
|
||||
// Cache is empty
|
||||
hdd->cache.write_addr = addr;
|
||||
}
|
||||
|
||||
hdd->cache.write_pending += len;
|
||||
if (hdd->cache.write_pending > hdd->cache.write_size) {
|
||||
// If request is bigger than free cache, flush some data first
|
||||
uint32_t flush_needed = hdd->cache.write_pending - hdd->cache.write_size;
|
||||
for (uint32_t i = 0; i < flush_needed; i++) {
|
||||
seek_time += hdd_seek_get_time(hdd, hdd->cache.write_addr, HDD_OP_WRITE, 1, 0);
|
||||
hdd->cache.write_addr++;
|
||||
}
|
||||
}
|
||||
|
||||
hdd->cache.write_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
|
||||
|
||||
return seek_time;
|
||||
}
|
||||
|
||||
double
|
||||
hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len)
|
||||
{
|
||||
hdd_readahead_update(hdd);
|
||||
hdd_writecache_update(hdd);
|
||||
|
||||
double seek_time = 0.0;
|
||||
seek_time += hdd_writecache_flush(hdd);
|
||||
|
||||
hdd_cache_t *cache = &hdd->cache;
|
||||
hdd_cache_seg_t *active_seg = &cache->segments[0];
|
||||
|
||||
for (uint32_t i = 0; i < cache->num_segments; i++) {
|
||||
hdd_cache_seg_t *segment = &cache->segments[i];
|
||||
if (!segment->valid) {
|
||||
active_seg = segment;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (segment->lba_addr <= addr && (segment->lba_addr + cache->segment_size) >= addr) {
|
||||
// Cache HIT
|
||||
segment->host_addr = addr;
|
||||
active_seg = segment;
|
||||
if (addr + len > segment->ra_addr) {
|
||||
uint32_t need_read = (addr + len) - segment->ra_addr;
|
||||
for (uint32_t j = 0; j < need_read; j++) {
|
||||
seek_time += hdd_seek_get_time(hdd, segment->ra_addr, HDD_OP_READ, 1, 0.0);
|
||||
segment->ra_addr++;
|
||||
}
|
||||
}
|
||||
if (addr + len > segment->lba_addr + cache->segment_size) {
|
||||
// Need to erase some previously cached data
|
||||
uint32_t space_needed = (addr + len) - (segment->lba_addr + cache->segment_size);
|
||||
segment->lba_addr += space_needed;
|
||||
}
|
||||
goto update_lru;
|
||||
} else {
|
||||
if (segment->lru > active_seg->lru) {
|
||||
active_seg = segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache MISS
|
||||
active_seg->lba_addr = addr;
|
||||
active_seg->valid = 1;
|
||||
active_seg->host_addr = addr;
|
||||
active_seg->ra_addr = addr;
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
seek_time += hdd_seek_get_time(hdd, active_seg->ra_addr, HDD_OP_READ, i != 0, 0.0);
|
||||
active_seg->ra_addr++;
|
||||
}
|
||||
|
||||
update_lru:
|
||||
for (uint32_t i = 0; i < cache->num_segments; i++) {
|
||||
cache->segments[i].lru++;
|
||||
}
|
||||
|
||||
active_seg->lru = 0;
|
||||
|
||||
cache->ra_ongoing = 1;
|
||||
cache->ra_segment = active_seg->id;
|
||||
cache->ra_start_time = tsc + (uint32_t)(seek_time * cpuclock / 1000000.0);
|
||||
|
||||
return seek_time;
|
||||
}
|
||||
|
||||
static void
|
||||
hdd_cache_init(hard_disk_t *hdd)
|
||||
{
|
||||
hdd_cache_t *cache = &hdd->cache;
|
||||
cache->ra_segment = 0;
|
||||
cache->ra_ongoing = 0;
|
||||
cache->ra_start_time = 0;
|
||||
|
||||
for (uint32_t i = 0; i < cache->num_segments; i++) {
|
||||
cache->segments[i].valid = 0;
|
||||
cache->segments[i].lru = 0;
|
||||
cache->segments[i].id = i;
|
||||
cache->segments[i].ra_addr = 0;
|
||||
cache->segments[i].host_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hdd_zones_init(hard_disk_t *hdd)
|
||||
{
|
||||
uint32_t lba = 0;
|
||||
uint32_t track = 0;
|
||||
|
||||
double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0;
|
||||
for (uint32_t i = 0; i < hdd->num_zones; i++) {
|
||||
hdd_zone_t *zone = &hdd->zones[i];
|
||||
zone->start_sector = lba;
|
||||
zone->start_track = track;
|
||||
zone->sector_time_usec = revolution_usec / (double)zone->sectors_per_track;
|
||||
uint32_t tracks = zone->cylinders * hdd->phy_heads;
|
||||
lba += tracks * zone->sectors_per_track;
|
||||
zone->end_sector = lba - 1;
|
||||
track += tracks - 1;
|
||||
}
|
||||
}
|
||||
|
||||
hdd_preset_t hdd_presets[] = {
|
||||
{ .target_year = 1989, .match_max_mbyte = 99, .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8,
|
||||
.rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 },
|
||||
|
||||
{ .target_year = 1992, .match_max_mbyte = 249, .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3500, .full_stroke_ms = 30, .track_seek_ms = 6,
|
||||
.rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 },
|
||||
|
||||
{ .target_year = 1994, .match_max_mbyte = 999, .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5,
|
||||
.rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 },
|
||||
|
||||
{ .target_year = 1996, .match_max_mbyte = 1999, .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3,
|
||||
.rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 },
|
||||
|
||||
{ .target_year = 1997, .match_max_mbyte = 4999, .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5,
|
||||
.rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 },
|
||||
|
||||
{ .target_year = 1998, .match_max_mbyte = 9999, .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2,
|
||||
.rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 },
|
||||
|
||||
{ .target_year = 2000, .match_max_mbyte = 99999, .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2,
|
||||
.rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 },
|
||||
};
|
||||
|
||||
void
|
||||
hdd_preset_apply(hard_disk_t *hdd, hdd_preset_t *preset)
|
||||
{
|
||||
hdd->phy_heads = preset->heads;
|
||||
hdd->rpm = preset->rpm;
|
||||
|
||||
double revolution_usec = 60.0 / (double)hdd->rpm * 1000000.0;
|
||||
hdd->avg_rotation_lat_usec = revolution_usec / 2;
|
||||
hdd->full_stroke_usec = preset->full_stroke_ms * 1000;
|
||||
hdd->head_switch_usec = preset->track_seek_ms * 1000;
|
||||
hdd->cyl_switch_usec = preset->track_seek_ms * 1000;
|
||||
|
||||
hdd->cache.num_segments = preset->rcache_num_seg;
|
||||
hdd->cache.segment_size = preset->rcache_seg_size;
|
||||
hdd->max_multiple_block = preset->max_multiple;
|
||||
|
||||
hdd->cache.write_size = 64;
|
||||
|
||||
hdd->num_zones = preset->zones;
|
||||
|
||||
uint32_t disk_sectors = hdd->tracks * hdd->hpc * hdd->spt;
|
||||
uint32_t sectors_per_surface = (uint32_t)ceil((double)disk_sectors / (double)hdd->phy_heads);
|
||||
uint32_t cylinders = (uint32_t)ceil((double)sectors_per_surface / (double)preset->avg_spt);
|
||||
hdd->phy_cyl = cylinders;
|
||||
uint32_t cylinders_per_zone = cylinders / preset->zones;
|
||||
|
||||
uint32_t total_sectors = 0;
|
||||
for (uint32_t i = 0; i < preset->zones; i++) {
|
||||
uint32_t spt;
|
||||
double zone_percent = i * 100 / (double)preset->zones;
|
||||
|
||||
if (i < preset->zones - 1) {
|
||||
// Function for realistic zone sector density
|
||||
double spt_percent = -0.00341684 * pow(zone_percent, 2) - 0.175811 * zone_percent + 118.48;
|
||||
spt = (uint32_t)ceil((double)preset->avg_spt * spt_percent / 100);
|
||||
} else {
|
||||
spt = (uint32_t)ceil((double)(disk_sectors - total_sectors) / (double)(cylinders_per_zone*preset->heads));
|
||||
}
|
||||
|
||||
uint32_t zone_sectors = spt * cylinders_per_zone * preset->heads;
|
||||
total_sectors += zone_sectors;
|
||||
|
||||
hdd->zones[i].cylinders = cylinders_per_zone;
|
||||
hdd->zones[i].sectors_per_track = spt;
|
||||
}
|
||||
|
||||
hdd_zones_init(hdd);
|
||||
hdd_cache_init(hdd);
|
||||
}
|
||||
|
||||
void
|
||||
hdd_preset_auto(hard_disk_t *hdd)
|
||||
{
|
||||
uint32_t disk_sectors = hdd->tracks * hdd->hpc * hdd->spt;
|
||||
uint32_t disk_size_mb = disk_sectors * 512 / 1024 / 1024;
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(hdd_presets) / sizeof(hdd_presets[0])); i++) {
|
||||
if (hdd_presets[i].match_max_mbyte >= disk_size_mb)
|
||||
break;
|
||||
}
|
||||
|
||||
hdd_preset_t *preset = &hdd_presets[i];
|
||||
|
||||
hdd_preset_apply(hdd, preset);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ typedef struct ide_s {
|
||||
blocksize, blockcount,
|
||||
hdd_num, channel,
|
||||
pos, sector_pos,
|
||||
lba, skip512,
|
||||
lba,
|
||||
reset, mdma_mode,
|
||||
do_initial_read;
|
||||
uint32_t secount, sector,
|
||||
@@ -67,6 +67,7 @@ typedef struct ide_s {
|
||||
/* Stuff mostly used by ATAPI */
|
||||
scsi_common_t *sc;
|
||||
int interrupt_drq;
|
||||
double pending_delay;
|
||||
|
||||
int (*get_max)(int ide_has_dma, int type);
|
||||
int (*get_timings)(int ide_has_dma, int type);
|
||||
|
||||
@@ -72,6 +72,62 @@ enum {
|
||||
};
|
||||
#endif
|
||||
|
||||
enum {
|
||||
HDD_OP_SEEK = 0,
|
||||
HDD_OP_READ,
|
||||
HDD_OP_WRITE
|
||||
};
|
||||
|
||||
#define HDD_MAX_ZONES 16
|
||||
#define HDD_MAX_CACHE_SEG 16
|
||||
|
||||
typedef struct {
|
||||
uint32_t match_max_mbyte;
|
||||
uint32_t zones;
|
||||
uint32_t avg_spt;
|
||||
uint32_t heads;
|
||||
uint32_t rpm;
|
||||
uint32_t target_year;
|
||||
uint32_t rcache_num_seg;
|
||||
uint32_t rcache_seg_size;
|
||||
uint32_t max_multiple;
|
||||
double full_stroke_ms;
|
||||
double track_seek_ms;
|
||||
} hdd_preset_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint32_t lba_addr;
|
||||
uint32_t ra_addr;
|
||||
uint32_t host_addr;
|
||||
uint8_t lru;
|
||||
uint8_t valid;
|
||||
} hdd_cache_seg_t;
|
||||
|
||||
typedef struct {
|
||||
// Read cache
|
||||
hdd_cache_seg_t segments[HDD_MAX_CACHE_SEG];
|
||||
uint32_t num_segments;
|
||||
uint32_t segment_size;
|
||||
uint32_t ra_segment;
|
||||
uint8_t ra_ongoing;
|
||||
uint64_t ra_start_time;
|
||||
|
||||
// Write cache
|
||||
uint32_t write_addr;
|
||||
uint32_t write_pending;
|
||||
uint32_t write_size;
|
||||
uint64_t write_start_time;
|
||||
} hdd_cache_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cylinders;
|
||||
uint32_t sectors_per_track;
|
||||
double sector_time_usec;
|
||||
uint32_t start_sector;
|
||||
uint32_t end_sector;
|
||||
uint32_t start_track;
|
||||
} hdd_zone_t;
|
||||
|
||||
/* Define the virtual Hard Disk. */
|
||||
typedef struct {
|
||||
@@ -100,6 +156,23 @@ typedef struct {
|
||||
spt,
|
||||
hpc, /* Physical geometry parameters */
|
||||
tracks;
|
||||
|
||||
hdd_zone_t zones[HDD_MAX_ZONES];
|
||||
uint32_t num_zones;
|
||||
hdd_cache_t cache;
|
||||
uint32_t phy_cyl;
|
||||
uint32_t phy_heads;
|
||||
uint32_t rpm;
|
||||
uint8_t max_multiple_block;
|
||||
|
||||
uint32_t cur_cylinder;
|
||||
uint32_t cur_track;
|
||||
uint32_t cur_addr;
|
||||
|
||||
double avg_rotation_lat_usec;
|
||||
double full_stroke_usec;
|
||||
double head_switch_usec;
|
||||
double cyl_switch_usec;
|
||||
} hard_disk_t;
|
||||
|
||||
|
||||
@@ -131,5 +204,10 @@ extern int image_is_hdi(const char *s);
|
||||
extern int image_is_hdx(const char *s, int check_signature);
|
||||
extern int image_is_vhd(const char *s, int check_signature);
|
||||
|
||||
extern double hdd_timing_write(hard_disk_t *hdd, uint32_t addr, uint32_t len);
|
||||
extern double hdd_timing_read(hard_disk_t *hdd, uint32_t addr, uint32_t len);
|
||||
extern double hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_t continuous, double max_seek_time);
|
||||
extern void hdd_preset_apply(hard_disk_t *hdd, hdd_preset_t *preset);
|
||||
extern void hdd_preset_auto(hard_disk_t *hdd);
|
||||
|
||||
#endif /*EMU_HDD_H*/
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2018,2019 David Hrdlička.
|
||||
* Copyright 2021-2022 Jasmine Iwanek.
|
||||
*/
|
||||
|
||||
#ifndef WIN_RESOURCE_H
|
||||
@@ -184,6 +185,8 @@
|
||||
#define IDC_CHECK_VOODOO 1022
|
||||
#define IDC_BUTTON_VOODOO 1023
|
||||
#define IDC_CHECK_IBM8514 1024
|
||||
#define IDC_CHECK_XGA 1025
|
||||
#define IDC_BUTTON_XGA 1026
|
||||
|
||||
#define IDC_INPUT 1030 /* input config */
|
||||
#define IDC_COMBO_MOUSE 1031
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
extern const device_t scsi_lcs6821n_device;
|
||||
extern const device_t scsi_rt1000b_device;
|
||||
extern const device_t scsi_rt1000mc_device;
|
||||
extern const device_t scsi_t128_device;
|
||||
extern const device_t scsi_t130b_device;
|
||||
extern const device_t scsi_ls2000_device;
|
||||
|
||||
@@ -62,7 +62,7 @@ typedef struct ibm8514_t
|
||||
int x1, x2, y1, y2;
|
||||
int sys_cnt, sys_cnt2;
|
||||
int temp_cnt;
|
||||
int16_t cx, cy;
|
||||
int16_t cx, cy, oldcy;
|
||||
int16_t sx, sy;
|
||||
int16_t dx, dy;
|
||||
int16_t err;
|
||||
@@ -80,7 +80,7 @@ typedef struct ibm8514_t
|
||||
int odd_in, odd_out;
|
||||
|
||||
uint16_t scratch;
|
||||
int fill_state, fill_drop;
|
||||
int fill_state, xdir, ydir;
|
||||
} accel;
|
||||
|
||||
uint16_t test;
|
||||
|
||||
@@ -38,6 +38,7 @@ extern "C" {
|
||||
#include <86box/config.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/discord.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/machine.h>
|
||||
@@ -1524,18 +1525,25 @@ void MainWindow::refreshMediaMenu() {
|
||||
ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA));
|
||||
}
|
||||
|
||||
void MainWindow::showMessage(const QString& header, const QString& message) {
|
||||
void MainWindow::showMessage(int flags, const QString& header, const QString& message) {
|
||||
if (QThread::currentThread() == this->thread()) {
|
||||
showMessage_(header, message);
|
||||
showMessage_(flags, header, message);
|
||||
} else {
|
||||
emit showMessageForNonQtThread(header, message);
|
||||
emit showMessageForNonQtThread(flags, header, message);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::showMessage_(const QString &header, const QString &message) {
|
||||
void MainWindow::showMessage_(int flags, const QString &header, const QString &message) {
|
||||
QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this);
|
||||
if (flags & (MBX_FATAL)) {
|
||||
box.setIcon(QMessageBox::Critical);
|
||||
}
|
||||
else if (!(flags & (MBX_ERROR | MBX_WARNING))) {
|
||||
box.setIcon(QMessageBox::Warning);
|
||||
}
|
||||
box.setTextFormat(Qt::TextFormat::RichText);
|
||||
box.exec();
|
||||
if (cpu_thread_run == 0) QApplication::exit(-1);
|
||||
}
|
||||
|
||||
void MainWindow::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
void showMessage(const QString& header, const QString& message);
|
||||
void showMessage(int flags, const QString& header, const QString& message);
|
||||
void getTitle(wchar_t* title);
|
||||
void blitToWidget(int x, int y, int w, int h, int monitor_index);
|
||||
QSize getRenderWidgetSize();
|
||||
@@ -51,7 +51,7 @@ signals:
|
||||
void setFullscreen(bool state);
|
||||
void setMouseCapture(bool state);
|
||||
|
||||
void showMessageForNonQtThread(const QString& header, const QString& message);
|
||||
void showMessageForNonQtThread(int flags, const QString& header, const QString& message);
|
||||
void getTitleForNonQtThread(wchar_t* title);
|
||||
public slots:
|
||||
void showSettings();
|
||||
@@ -108,7 +108,7 @@ private slots:
|
||||
void on_actionRenderer_options_triggered();
|
||||
|
||||
void refreshMediaMenu();
|
||||
void showMessage_(const QString& header, const QString& message);
|
||||
void showMessage_(int flags, const QString& header, const QString& message);
|
||||
void getTitle_(wchar_t* title);
|
||||
|
||||
void on_actionMCA_devices_triggered();
|
||||
|
||||
@@ -326,7 +326,7 @@ void
|
||||
plat_pause(int p)
|
||||
{
|
||||
static wchar_t oldtitle[512];
|
||||
wchar_t title[512], paused_msg[64];
|
||||
wchar_t title[1024], paused_msg[512];
|
||||
|
||||
if (p == dopause) {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
|
||||
@@ -94,7 +94,7 @@ int ui_msgbox_header(int flags, void *header, void* message) {
|
||||
msgBox.exec();
|
||||
} else {
|
||||
// else scope it to main_window
|
||||
main_window->showMessage(hdr, msg);
|
||||
main_window->showMessage(flags, hdr, msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ static SCSI_CARD scsi_cards[] = {
|
||||
{ &scsi_ls2000_device, },
|
||||
{ &scsi_lcs6821n_device, },
|
||||
{ &scsi_rt1000b_device, },
|
||||
{ &scsi_rt1000mc_device, },
|
||||
{ &scsi_t128_device, },
|
||||
{ &scsi_t130b_device, },
|
||||
#ifdef WALTJE
|
||||
|
||||
@@ -156,6 +156,7 @@ typedef struct {
|
||||
double period;
|
||||
|
||||
int ncr_busy;
|
||||
uint8_t pos_regs[8];
|
||||
} ncr5380_t;
|
||||
|
||||
#define STATE_IDLE 0
|
||||
@@ -1435,6 +1436,64 @@ t128_write(uint32_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
rt1000b_mc_read(int port, void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
|
||||
return(ncr_dev->pos_regs[port & 7]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rt1000b_mc_write(int port, uint8_t val, void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
|
||||
/* MCA does not write registers below 0x0100. */
|
||||
if (port < 0x0102) return;
|
||||
|
||||
mem_mapping_disable(&ncr_dev->bios_rom.mapping);
|
||||
mem_mapping_disable(&ncr_dev->mapping);
|
||||
|
||||
/* Save the MCA register value. */
|
||||
ncr_dev->pos_regs[port & 7] = val;
|
||||
|
||||
if (ncr_dev->pos_regs[2] & 1) {
|
||||
switch (ncr_dev->pos_regs[2] & 0xe0) {
|
||||
case 0:
|
||||
ncr_dev->rom_addr = 0xd4000;
|
||||
break;
|
||||
case 0x20:
|
||||
ncr_dev->rom_addr = 0xd0000;
|
||||
break;
|
||||
case 0x40:
|
||||
ncr_dev->rom_addr = 0xcc000;
|
||||
break;
|
||||
case 0x60:
|
||||
ncr_dev->rom_addr = 0xc8000;
|
||||
break;
|
||||
case 0xc0:
|
||||
ncr_dev->rom_addr = 0xdc000;
|
||||
break;
|
||||
case 0xe0:
|
||||
ncr_dev->rom_addr = 0xd8000;
|
||||
break;
|
||||
}
|
||||
|
||||
mem_mapping_set_addr(&ncr_dev->bios_rom.mapping, ncr_dev->rom_addr, 0x4000);
|
||||
mem_mapping_set_addr(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
rt1000b_mc_feedb(void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
|
||||
return ncr_dev->pos_regs[2] & 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
ncr_init(const device_t *info)
|
||||
{
|
||||
@@ -1462,10 +1521,14 @@ ncr_init(const device_t *info)
|
||||
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
|
||||
break;
|
||||
|
||||
case 1: /* Rancho RT1000B */
|
||||
case 1: /* Rancho RT1000B/MC */
|
||||
ncr_dev->rom_addr = device_get_config_hex20("bios_addr");
|
||||
ncr_dev->irq = device_get_config_int("irq");
|
||||
ncr_dev->bios_ver = device_get_config_int("bios_ver");
|
||||
if (info->flags & DEVICE_MCA) {
|
||||
ncr_dev->rom_addr = 0xd8000;
|
||||
ncr_dev->bios_ver = 1;
|
||||
}
|
||||
|
||||
if (ncr_dev->bios_ver == 1)
|
||||
fn = RT1000B_820R_ROM;
|
||||
@@ -1475,10 +1538,20 @@ ncr_init(const device_t *info)
|
||||
rom_init(&ncr_dev->bios_rom, fn,
|
||||
ncr_dev->rom_addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000,
|
||||
memio_read, NULL, NULL,
|
||||
memio_write, NULL, NULL,
|
||||
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
|
||||
if (info->flags & DEVICE_MCA) {
|
||||
mem_mapping_add(&ncr_dev->mapping, 0, 0,
|
||||
memio_read, NULL, NULL,
|
||||
memio_write, NULL, NULL,
|
||||
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
|
||||
ncr_dev->pos_regs[0] = 0x8d;
|
||||
ncr_dev->pos_regs[1] = 0x70;
|
||||
mca_add(rt1000b_mc_read, rt1000b_mc_write, rt1000b_mc_feedb, NULL, ncr_dev);
|
||||
} else {
|
||||
mem_mapping_add(&ncr_dev->mapping, ncr_dev->rom_addr, 0x4000,
|
||||
memio_read, NULL, NULL,
|
||||
memio_write, NULL, NULL,
|
||||
ncr_dev->bios_rom.rom, MEM_MAPPING_EXTERNAL, ncr_dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Trantor T130B */
|
||||
@@ -1580,6 +1653,12 @@ rt1000b_available(void)
|
||||
return(rom_present(RT1000B_820R_ROM) && rom_present(RT1000B_810R_ROM));
|
||||
}
|
||||
|
||||
static int
|
||||
rt1000b_820_available(void)
|
||||
{
|
||||
return(rom_present(RT1000B_820R_ROM));
|
||||
}
|
||||
|
||||
static int
|
||||
t130b_available(void)
|
||||
{
|
||||
@@ -1611,6 +1690,8 @@ static const device_config_t ncr5380_mmio_config[] = {
|
||||
.selection = {
|
||||
{ .description = "C800H", .value = 0xc8000 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "D000H", .value = 0xd0000 },
|
||||
{ .description = "D400H", .value = 0xd4000 },
|
||||
{ .description = "D800H", .value = 0xd8000 },
|
||||
{ .description = "DC00H", .value = 0xdc000 },
|
||||
{ .description = "" }
|
||||
@@ -1646,6 +1727,8 @@ static const device_config_t rancho_config[] = {
|
||||
.selection = {
|
||||
{ .description = "C800H", .value = 0xc8000 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "D000H", .value = 0xd0000 },
|
||||
{ .description = "D400H", .value = 0xd4000 },
|
||||
{ .description = "D800H", .value = 0xd8000 },
|
||||
{ .description = "DC00H", .value = 0xdc000 },
|
||||
{ .description = "" }
|
||||
@@ -1683,6 +1766,25 @@ static const device_config_t rancho_config[] = {
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
};
|
||||
|
||||
static const device_config_t rancho_mc_config[] = {
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 5,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
};
|
||||
|
||||
static const device_config_t t130b_config[] = {
|
||||
{
|
||||
.name = "bios_addr",
|
||||
@@ -1747,6 +1849,8 @@ static const device_config_t t128_config[] = {
|
||||
.selection = {
|
||||
{ .description = "C800H", .value = 0xc8000 },
|
||||
{ .description = "CC00H", .value = 0xcc000 },
|
||||
{ .description = "D000H", .value = 0xd0000 },
|
||||
{ .description = "D400H", .value = 0xd4000 },
|
||||
{ .description = "D800H", .value = 0xd8000 },
|
||||
{ .description = "DC00H", .value = 0xdc000 },
|
||||
{ .description = "" }
|
||||
@@ -1806,6 +1910,20 @@ const device_t scsi_rt1000b_device = {
|
||||
.config = rancho_config
|
||||
};
|
||||
|
||||
const device_t scsi_rt1000mc_device = {
|
||||
.name = "Rancho RT1000B-MC",
|
||||
.internal_name = "rt1000mc",
|
||||
.flags = DEVICE_MCA,
|
||||
.local = 1,
|
||||
.init = ncr_init,
|
||||
.close = ncr_close,
|
||||
.reset = NULL,
|
||||
{ .available = rt1000b_820_available },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = rancho_mc_config
|
||||
};
|
||||
|
||||
const device_t scsi_t130b_device = {
|
||||
.name = "Trantor T130B",
|
||||
.internal_name = "t130b",
|
||||
|
||||
@@ -2555,18 +2555,12 @@ rect_fill:
|
||||
if (!cpu_input) {
|
||||
dev->accel.cx = dev->accel.cur_x;
|
||||
dev->accel.cy = dev->accel.cur_y;
|
||||
dev->accel.oldcy = dev->accel.cy;
|
||||
|
||||
dev->accel.sy = dev->accel.maj_axis_pcnt;
|
||||
dev->accel.xdir = (dev->accel.cmd & 0x20) ? 1 : -1;
|
||||
dev->accel.ydir = (dev->accel.cmd & 0x80) ? 1 : -1;
|
||||
|
||||
if (dev->accel.cx < dev->accel.clip_left)
|
||||
dev->accel.cx = dev->accel.clip_left;
|
||||
else if (dev->accel.cx > clip_r)
|
||||
dev->accel.cx = dev->accel.clip_left;
|
||||
|
||||
dev->accel.sx = dev->accel.sy;
|
||||
dev->accel.dx = dev->accel.destx_distp;
|
||||
dev->accel.dy = dev->accel.desty_axstp;
|
||||
dev->accel.err = dev->accel.err_term;
|
||||
dev->accel.sy = 0;
|
||||
|
||||
if (ibm8514_cpu_src(dev)) {
|
||||
dev->data_available = 0;
|
||||
@@ -2579,237 +2573,70 @@ rect_fill:
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->accel.cmd & 8) { /*Vector Line*/
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
|
||||
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
|
||||
if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) {
|
||||
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
|
||||
} else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) {
|
||||
/* Mix data = current video memory value. */
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat);
|
||||
mix_dat = ((mix_dat & rd_mask) == rd_mask);
|
||||
mix_dat = mix_dat ? mix_mask : 0;
|
||||
}
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx <= clip_r) &&
|
||||
(dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) {
|
||||
switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
|
||||
case 0: src_dat = bkgd_color; break;
|
||||
case 1: src_dat = frgd_color; break;
|
||||
case 2: src_dat = cpu_dat & 0xff; break;
|
||||
case 3: src_dat = 0; break;
|
||||
}
|
||||
|
||||
if (ibm8514_cpu_dest(dev)) {
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat);
|
||||
if (pixcntl == 3)
|
||||
src_dat = ((src_dat & rd_mask) == rd_mask);
|
||||
} else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
|
||||
case 0: src_dat = bkgd_color; break;
|
||||
case 1: src_dat = frgd_color; break;
|
||||
case 2: src_dat = cpu_dat & 0xff; break;
|
||||
case 3: src_dat = 0; break;
|
||||
}
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
|
||||
if ((compare_mode == 0) ||
|
||||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
|
||||
((compare_mode == 0x18) && (dest_dat < compare)) ||
|
||||
((compare_mode == 0x20) && (dest_dat != compare)) ||
|
||||
((compare_mode == 0x28) && (dest_dat == compare)) ||
|
||||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
|
||||
((compare_mode == 0x38) && (dest_dat > compare))) {
|
||||
old_dest_dat = dest_dat;
|
||||
MIX(mix_dat & mix_mask, dest_dat, src_dat);
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
if ((dev->accel.cmd & 4) && dev->accel.sy) {
|
||||
if ((compare_mode == 0) ||
|
||||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
|
||||
((compare_mode == 0x18) && (dest_dat < compare)) ||
|
||||
((compare_mode == 0x20) && (dest_dat != compare)) ||
|
||||
((compare_mode == 0x28) && (dest_dat == compare)) ||
|
||||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
|
||||
((compare_mode == 0x38) && (dest_dat > compare))) {
|
||||
old_dest_dat = dest_dat;
|
||||
MIX(mix_dat & mix_mask, dest_dat, src_dat);
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
if ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) {
|
||||
if (!dev->accel.sy) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
} else if (!(dev->accel.cmd & 4)) {
|
||||
} else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == dev->accel.oldcy + 1)) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
} else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
}
|
||||
}
|
||||
}
|
||||
mix_dat <<= 1;
|
||||
mix_dat |= 1;
|
||||
cpu_dat >>= 8;
|
||||
|
||||
if (dev->accel.sy == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dev->accel.cmd & 0xe0) {
|
||||
case 0x00: dev->accel.cx++; break;
|
||||
case 0x20: dev->accel.cx++; dev->accel.cy--; break;
|
||||
case 0x40: dev->accel.cy--; break;
|
||||
case 0x60: dev->accel.cx--; dev->accel.cy--; break;
|
||||
case 0x80: dev->accel.cx--; break;
|
||||
case 0xa0: dev->accel.cx--; dev->accel.cy++; break;
|
||||
case 0xc0: dev->accel.cy++; break;
|
||||
case 0xe0: dev->accel.cx++; dev->accel.cy++; break;
|
||||
}
|
||||
|
||||
dev->accel.sy--;
|
||||
}
|
||||
} else { /*Bresenham*/
|
||||
if (pixcntl == 1) {
|
||||
dev->accel.temp_cnt = 8;
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if (dev->accel.temp_cnt == 0) {
|
||||
dev->accel.temp_cnt = 8;
|
||||
mix_dat = old_mix_dat;
|
||||
}
|
||||
if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r &&
|
||||
dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) {
|
||||
if (ibm8514_cpu_dest(dev)) {
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat);
|
||||
} else switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) {
|
||||
case 0: src_dat = bkgd_color; break;
|
||||
case 1: src_dat = frgd_color; break;
|
||||
case 2: src_dat = cpu_dat & 0xff; break;
|
||||
case 3: src_dat = 0; break;
|
||||
}
|
||||
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
mix_dat <<= 1;
|
||||
mix_dat |= 1;
|
||||
cpu_dat >>= 8;
|
||||
|
||||
if ((compare_mode == 0) ||
|
||||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
|
||||
((compare_mode == 0x18) && (dest_dat < compare)) ||
|
||||
((compare_mode == 0x20) && (dest_dat != compare)) ||
|
||||
((compare_mode == 0x28) && (dest_dat == compare)) ||
|
||||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
|
||||
((compare_mode == 0x38) && (dest_dat > compare))) {
|
||||
old_dest_dat = dest_dat;
|
||||
MIX(mix_dat & 1, dest_dat, src_dat);
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
if ((dev->accel.cmd & 4) && dev->accel.sy) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
} else if (!(dev->accel.cmd & 4)) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
}
|
||||
}
|
||||
}
|
||||
dev->accel.temp_cnt--;
|
||||
mix_dat >>= 1;
|
||||
cpu_dat >>= 8;
|
||||
if (dev->accel.sy == dev->accel.maj_axis_pcnt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->accel.sy == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
/*Step minor axis*/
|
||||
switch (dev->accel.cmd & 0xe0) {
|
||||
case 0x00: dev->accel.cy--; break;
|
||||
case 0x20: dev->accel.cy--; break;
|
||||
case 0x40: dev->accel.cx--; break;
|
||||
case 0x60: dev->accel.cx++; break;
|
||||
case 0x80: dev->accel.cy++; break;
|
||||
case 0xa0: dev->accel.cy++; break;
|
||||
case 0xc0: dev->accel.cx--; break;
|
||||
case 0xe0: dev->accel.cx++; break;
|
||||
}
|
||||
} else
|
||||
dev->accel.err_term += dev->accel.desty_axstp;
|
||||
|
||||
/*Step major axis*/
|
||||
switch (dev->accel.cmd & 0xe0) {
|
||||
case 0x00: dev->accel.cx--; break;
|
||||
case 0x20: dev->accel.cx++; break;
|
||||
case 0x40: dev->accel.cy--; break;
|
||||
case 0x60: dev->accel.cy--; break;
|
||||
case 0x80: dev->accel.cx--; break;
|
||||
case 0xa0: dev->accel.cx++; break;
|
||||
case 0xc0: dev->accel.cy++; break;
|
||||
case 0xe0: dev->accel.cy++; break;
|
||||
}
|
||||
|
||||
dev->accel.sy--;
|
||||
if (dev->accel.cmd & 0x40) {
|
||||
dev->accel.oldcy = dev->accel.cy;
|
||||
dev->accel.cy += dev->accel.ydir;
|
||||
if (dev->accel.err_term >= 0) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
dev->accel.cx += dev->accel.xdir;
|
||||
} else {
|
||||
dev->accel.err_term += dev->accel.desty_axstp;
|
||||
}
|
||||
} else {
|
||||
while (count-- && (dev->accel.sy >= 0)) {
|
||||
if (dev->accel.cx < dev->accel.clip_left)
|
||||
dev->accel.cx = dev->accel.clip_left;
|
||||
else if (dev->accel.cx > clip_r)
|
||||
dev->accel.cx = dev->accel.clip_left;
|
||||
|
||||
if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx) <= clip_r &&
|
||||
(dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) {
|
||||
if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) {
|
||||
mix_dat = mix_mask; /* Mix data = forced to foreground register. */
|
||||
} else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) {
|
||||
/* Mix data = current video memory value. */
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat);
|
||||
mix_dat = ((mix_dat & rd_mask) == rd_mask);
|
||||
mix_dat = mix_dat ? mix_mask : 0;
|
||||
}
|
||||
|
||||
if (ibm8514_cpu_dest(dev)) {
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat);
|
||||
if (pixcntl == 3)
|
||||
src_dat = ((src_dat & rd_mask) == rd_mask);
|
||||
} else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) {
|
||||
case 0: src_dat = bkgd_color; break;
|
||||
case 1: src_dat = frgd_color; break;
|
||||
case 2: src_dat = cpu_dat & 0xff; break;
|
||||
case 3: src_dat = 0; break;
|
||||
}
|
||||
|
||||
READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
|
||||
if ((compare_mode == 0) ||
|
||||
((compare_mode == 0x10) && (dest_dat >= compare)) ||
|
||||
((compare_mode == 0x18) && (dest_dat < compare)) ||
|
||||
((compare_mode == 0x20) && (dest_dat != compare)) ||
|
||||
((compare_mode == 0x28) && (dest_dat == compare)) ||
|
||||
((compare_mode == 0x30) && (dest_dat <= compare)) ||
|
||||
((compare_mode == 0x38) && (dest_dat > compare))) {
|
||||
old_dest_dat = dest_dat;
|
||||
MIX(mix_dat & mix_mask, dest_dat, src_dat);
|
||||
dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask);
|
||||
if ((dev->accel.cmd & 4) && dev->accel.sy) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
} else if (!(dev->accel.cmd & 4)) {
|
||||
WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mix_dat <<= 1;
|
||||
mix_dat |= 1;
|
||||
cpu_dat >>= 8;
|
||||
|
||||
if (dev->accel.sy == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->accel.err >= dev->accel.sx) {
|
||||
dev->accel.err += dev->accel.dx;
|
||||
/*Step minor axis*/
|
||||
switch (dev->accel.cmd & 0xe0) {
|
||||
case 0x00: dev->accel.cy--; break;
|
||||
case 0x20: dev->accel.cy--; break;
|
||||
case 0x40: dev->accel.cx--; break;
|
||||
case 0x60: dev->accel.cx++; break;
|
||||
case 0x80: dev->accel.cy++; break;
|
||||
case 0xa0: dev->accel.cy++; break;
|
||||
case 0xc0: dev->accel.cx--; break;
|
||||
case 0xe0: dev->accel.cx++; break;
|
||||
}
|
||||
} else
|
||||
dev->accel.err += dev->accel.dy;
|
||||
|
||||
/*Step major axis*/
|
||||
switch (dev->accel.cmd & 0xe0) {
|
||||
case 0x00: dev->accel.cx--; break;
|
||||
case 0x20: dev->accel.cx++; break;
|
||||
case 0x40: dev->accel.cy--; break;
|
||||
case 0x60: dev->accel.cy--; break;
|
||||
case 0x80: dev->accel.cx--; break;
|
||||
case 0xa0: dev->accel.cx++; break;
|
||||
case 0xc0: dev->accel.cy++; break;
|
||||
case 0xe0: dev->accel.cy++; break;
|
||||
}
|
||||
|
||||
dev->accel.sy--;
|
||||
dev->accel.cx += dev->accel.xdir;
|
||||
if (dev->accel.err_term >= 0) {
|
||||
dev->accel.err_term += dev->accel.destx_distp;
|
||||
dev->accel.oldcy = dev->accel.cy;
|
||||
dev->accel.cy += dev->accel.ydir;
|
||||
} else {
|
||||
dev->accel.err_term += dev->accel.desty_axstp;
|
||||
}
|
||||
}
|
||||
|
||||
dev->accel.sy++;
|
||||
}
|
||||
dev->accel.cur_x = dev->accel.cx;
|
||||
dev->accel.cur_y = dev->accel.cy;
|
||||
break;
|
||||
|
||||
case 6: /*BitBlt*/
|
||||
|
||||
@@ -2363,7 +2363,12 @@ pgc_cga_text(pgc_t *dev, int w)
|
||||
val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
else
|
||||
val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer32->line[dev->displine][(x * cw) + c] = val;
|
||||
if (cw == 8) /* 80x25 CGA text screen. */
|
||||
buffer32->line[dev->displine][(x * cw) + c] = val;
|
||||
else { /* 40x25 CGA text screen. */
|
||||
buffer32->line[dev->displine][(x * cw) + (c * 2)] = val;
|
||||
buffer32->line[dev->displine][(x * cw) + (c * 2) + 1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
ma++;
|
||||
|
||||
@@ -2704,7 +2704,7 @@ static void
|
||||
xga->on = 0;
|
||||
xga->hwcursor.cur_xsize = 64;
|
||||
xga->hwcursor.cur_ysize = 64;
|
||||
xga->bios_rom.sz = 0x2000;
|
||||
xga->bios_rom.sz = 0x8000;
|
||||
|
||||
f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb");
|
||||
(void)fseek(f, 0L, SEEK_END);
|
||||
@@ -2729,7 +2729,7 @@ static void
|
||||
xga->instance = 0;
|
||||
xga->rom_addr = 0;
|
||||
mem_mapping_add(&xga->bios_rom.mapping,
|
||||
0xdc000, xga->bios_rom.sz,
|
||||
0xd8000, xga->bios_rom.sz,
|
||||
rom_read, rom_readw, rom_readl,
|
||||
NULL, NULL, NULL,
|
||||
xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, &xga->bios_rom);
|
||||
|
||||
@@ -71,7 +71,7 @@ ifeq ($(DEV_BUILD), y)
|
||||
OPEN_AT := y
|
||||
endif
|
||||
ifndef PAS16
|
||||
PAS16 := n
|
||||
PAS16 := y
|
||||
endif
|
||||
ifndef SIO_DETECT
|
||||
SIO_DETECT := y
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Grafika:"
|
||||
#define STR_VOODOO "Použít grafický akcelerátor Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Myš:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Videokarte:"
|
||||
#define STR_VOODOO "Voodoo-Grafik"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Maus:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -269,6 +269,12 @@ BEGIN
|
||||
CONTROL STR_IBM8514, IDC_CHECK_IBM8514,
|
||||
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
|
||||
7, 46, 199, CFG_CHECKBOX_HEIGHT
|
||||
|
||||
CONTROL STR_XGA, IDC_CHECK_XGA,
|
||||
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
|
||||
7, 65, 199, CFG_CHECKBOX_HEIGHT
|
||||
PUSHBUTTON STR_CONFIGURE, IDC_BUTTON_XGA,
|
||||
CFG_COMBO_BTN_LEFT, 64, CFG_BTN_WIDTH, CFG_BTN_HEIGHT
|
||||
END
|
||||
|
||||
DLG_CFG_INPUT DIALOG DISCARDABLE CFG_PANE_LEFT, CFG_PANE_TOP, CFG_PANE_WIDTH, CFG_PANE_HEIGHT
|
||||
@@ -727,7 +733,7 @@ BEGIN
|
||||
LTEXT STR_CD_SPEED, IDT_CD_SPEED,
|
||||
CFG_HMARGIN, 207, 34, CFG_PANE_LTEXT_HEIGHT
|
||||
COMBOBOX IDC_COMBO_CD_SPEED,
|
||||
43, 205, 328, 12,
|
||||
33, 205, 328, 12,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Video:"
|
||||
#define STR_VOODOO "Voodoo Graphics"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Mouse:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Video:"
|
||||
#define STR_VOODOO "Voodoo Graphics"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Mouse:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Vídeo:"
|
||||
#define STR_VOODOO "Voodoo Graphics"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Ratón:"
|
||||
#define STR_JOYSTICK "Mando:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Näytönohjain:"
|
||||
#define STR_VOODOO "Voodoo-grafiikkasuoritin"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Hiiri:"
|
||||
#define STR_JOYSTICK "Peliohjain:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Vidéo:"
|
||||
#define STR_VOODOO "Graphique Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Souris:"
|
||||
#define STR_JOYSTICK "Manette de commande:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Video:"
|
||||
#define STR_VOODOO "Voodoo grafika"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Miš:"
|
||||
#define STR_JOYSTICK "Palica za igru:"
|
||||
|
||||
@@ -277,6 +277,7 @@ END
|
||||
#define STR_VIDEO "Videokártya:"
|
||||
#define STR_VOODOO "Voodoo-gyorsítókártya"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Egér:"
|
||||
#define STR_JOYSTICK "Játékvezérlő:"
|
||||
|
||||
@@ -273,6 +273,7 @@ END
|
||||
#define STR_VIDEO "Video:"
|
||||
#define STR_VOODOO "Grafica Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Mouse:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "ビデオカード:"
|
||||
#define STR_VOODOO "Voodooグラフィック"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "マウス:"
|
||||
#define STR_JOYSTICK "ジョイスティック:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "비디오 카드:"
|
||||
#define STR_VOODOO "Voodoo 그래픽"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "마우스:"
|
||||
#define STR_JOYSTICK "조이스틱:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Wideo:"
|
||||
#define STR_VOODOO "Grafika Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Mysz:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -275,6 +275,7 @@ END
|
||||
#define STR_VIDEO "Vídeo:"
|
||||
#define STR_VOODOO "3DFX Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Mouse:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Vídeo:"
|
||||
#define STR_VOODOO "Gráficos Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Rato:"
|
||||
#define STR_JOYSTICK "Joystick:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Видеокарта:"
|
||||
#define STR_VOODOO "Ускоритель Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Мышь:"
|
||||
#define STR_JOYSTICK "Джойстик:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Video:"
|
||||
#define STR_VOODOO "Voodoo grafika"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Miška:"
|
||||
#define STR_JOYSTICK "Igralna palica:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Ekran kartı:"
|
||||
#define STR_VOODOO "Voodoo Grafikleri"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Fare:"
|
||||
#define STR_JOYSTICK "Oyun kolu:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "Відеокарта:"
|
||||
#define STR_VOODOO "Прискорювач Voodoo"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "Миша:"
|
||||
#define STR_JOYSTICK "Джойстик:"
|
||||
|
||||
@@ -272,6 +272,7 @@ END
|
||||
#define STR_VIDEO "显卡:"
|
||||
#define STR_VOODOO "Voodoo Graphics"
|
||||
#define STR_IBM8514 "IBM 8514/a Graphics"
|
||||
#define STR_XGA "XGA Graphics"
|
||||
|
||||
#define STR_MOUSE "鼠标:"
|
||||
#define STR_JOYSTICK "操纵杆:"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2018,2019 David Hrdlička.
|
||||
* Copyright 2021 Laci bá'
|
||||
* Copyright 2021-2022 Jasmine Iwanek.
|
||||
*/
|
||||
#define UNICODE
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
@@ -63,6 +64,7 @@
|
||||
#include <86box/midi.h>
|
||||
#include <86box/snd_mpu401.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_xga_device.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/win.h>
|
||||
@@ -85,7 +87,7 @@ static int temp_dynarec;
|
||||
#endif
|
||||
|
||||
/* Video category */
|
||||
static int temp_gfxcard, temp_ibm8514, temp_voodoo;
|
||||
static int temp_gfxcard, temp_ibm8514, temp_voodoo, temp_xga;
|
||||
|
||||
/* Input devices category */
|
||||
static int temp_mouse, temp_joystick;
|
||||
@@ -333,6 +335,7 @@ win_settings_init(void)
|
||||
temp_gfxcard = gfxcard;
|
||||
temp_voodoo = voodoo_enabled;
|
||||
temp_ibm8514 = ibm8514_enabled;
|
||||
temp_xga = xga_enabled;
|
||||
|
||||
/* Input devices category */
|
||||
temp_mouse = mouse_type;
|
||||
@@ -458,6 +461,7 @@ win_settings_changed(void)
|
||||
i = i || (gfxcard != temp_gfxcard);
|
||||
i = i || (voodoo_enabled != temp_voodoo);
|
||||
i = i || (ibm8514_enabled != temp_ibm8514);
|
||||
i = i || (xga_enabled != temp_xga);
|
||||
|
||||
/* Input devices category */
|
||||
i = i || (mouse_type != temp_mouse);
|
||||
@@ -549,6 +553,7 @@ win_settings_save(void)
|
||||
gfxcard = temp_gfxcard;
|
||||
voodoo_enabled = temp_voodoo;
|
||||
ibm8514_enabled = temp_ibm8514;
|
||||
xga_enabled = temp_xga;
|
||||
|
||||
/* Input devices category */
|
||||
mouse_type = temp_mouse;
|
||||
@@ -1116,6 +1121,11 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
settings_enable_window(hdlg, IDC_CHECK_IBM8514, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA));
|
||||
settings_set_check(hdlg, IDC_CHECK_IBM8514, temp_ibm8514);
|
||||
|
||||
settings_enable_window(hdlg, IDC_CHECK_XGA, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA));
|
||||
settings_set_check(hdlg, IDC_CHECK_XGA, temp_xga);
|
||||
settings_enable_window(hdlg, IDC_BUTTON_XGA, (machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)) && temp_xga);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
@@ -1134,10 +1144,23 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514);
|
||||
break;
|
||||
|
||||
case IDC_CHECK_XGA:
|
||||
temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA);
|
||||
settings_enable_window(hdlg, IDC_BUTTON_XGA, temp_xga);
|
||||
break;
|
||||
|
||||
case IDC_BUTTON_VOODOO:
|
||||
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&voodoo_device);
|
||||
break;
|
||||
|
||||
case IDC_BUTTON_XGA:
|
||||
if (machine_has_bus(temp_machine, MACHINE_BUS_MCA) > 0) {
|
||||
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&xga_device);
|
||||
} else {
|
||||
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&xga_isa_device);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_CONFIGURE_VID:
|
||||
temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
|
||||
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)video_card_getdevice(temp_gfxcard));
|
||||
@@ -1149,6 +1172,7 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
temp_gfxcard = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
|
||||
temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO);
|
||||
temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514);
|
||||
temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
Reference in New Issue
Block a user