From 853830f8bb6a6e50f4b8ddd8d88d19966fddeef4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 25 May 2025 19:21:33 -0400 Subject: [PATCH 01/22] Add Mindscape Music Board Ported from PCem --- src/include/86box/snd_mmb.h | 42 ++++ src/include/86box/sound.h | 3 + src/sound/CMakeLists.txt | 4 + src/sound/ayumi/CMakeLists.txt | 14 ++ src/sound/ayumi/LICENSE | 21 ++ src/sound/ayumi/ayumi.c | 338 ++++++++++++++++++++++++++++++++ src/sound/ayumi/ayumi.h | 71 +++++++ src/sound/snd_mmb.c | 339 +++++++++++++++++++++++++++++++++ src/sound/sound.c | 1 + 9 files changed, 833 insertions(+) create mode 100644 src/include/86box/snd_mmb.h create mode 100644 src/sound/ayumi/CMakeLists.txt create mode 100644 src/sound/ayumi/LICENSE create mode 100644 src/sound/ayumi/ayumi.c create mode 100644 src/sound/ayumi/ayumi.h create mode 100644 src/sound/snd_mmb.c diff --git a/src/include/86box/snd_mmb.h b/src/include/86box/snd_mmb.h new file mode 100644 index 000000000..6e5f7d3a8 --- /dev/null +++ b/src/include/86box/snd_mmb.h @@ -0,0 +1,42 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mindscape Music Board emulation. + * + * Authors: Roy Baer, + * Jasmine Iwanek, + * + * Copyright 2025 Roy Baer. + * Copyright 2025 Jasmine Iwanek. + */ +#ifndef _SOUND_SND_MMB_H_ +#define _SOUND_SND_MMB_H_ + +#define MMB_FREQ FREQ_48000 + +/* NOTE: + * The constant clock rate is a deviation from the real hardware which has + * the design flaw that the clock rate is always half the ISA bus clock. + */ +#define MMB_CLOCK 2386364 + +typedef struct ay_3_891x_s { + uint8_t index; + uint8_t regs[16]; + struct ayumi chip; +} ay_3_891x_t; + +typedef struct mmb_s { + ay_3_891x_t first; + ay_3_891x_t second; + + int16_t buffer[SOUNDBUFLEN * 2]; + int pos; +} mmb_t; + +#endif /* _SOUND_SND_MMB_H_ */ diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index a30095c66..b2e202ddb 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -205,6 +205,9 @@ extern const device_t ps1snd_device; extern const device_t ssi2001_device; extern const device_t entertainer_device; +/* Mindscape Music Board */ +extern const device_t mmb_device; + /* Pro Audio Spectrum Plus, 16, and 16D */ extern const device_t pasplus_device; extern const device_t pas16_device; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 0a04b0ff1..3aaf49bb3 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -41,6 +41,7 @@ add_library(snd OBJECT snd_sb.c snd_sb_dsp.c snd_emu8k.c + snd_mmb.c snd_mpu401.c snd_pas16.c snd_sn76489.c @@ -177,6 +178,9 @@ if(MUNT) endif() endif() +add_subdirectory(ayumi) +target_link_libraries(86Box ayumi) + add_subdirectory(ymfm) target_link_libraries(86Box ymfm) diff --git a/src/sound/ayumi/CMakeLists.txt b/src/sound/ayumi/CMakeLists.txt new file mode 100644 index 000000000..f3e4b18c7 --- /dev/null +++ b/src/sound/ayumi/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# + +add_library(ayumi STATIC + ayumi.c +) diff --git a/src/sound/ayumi/LICENSE b/src/sound/ayumi/LICENSE new file mode 100644 index 000000000..25371edc6 --- /dev/null +++ b/src/sound/ayumi/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) Peter Sovietov, http://sovietov.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/src/sound/ayumi/ayumi.c b/src/sound/ayumi/ayumi.c new file mode 100644 index 000000000..861b0fd45 --- /dev/null +++ b/src/sound/ayumi/ayumi.c @@ -0,0 +1,338 @@ +/* Author: Peter Sovietov */ + +#include +#include +#include "ayumi.h" + +static const double AY_dac_table[] = { + 0.0, 0.0, + 0.00999465934234, 0.00999465934234, + 0.0144502937362, 0.0144502937362, + 0.0210574502174, 0.0210574502174, + 0.0307011520562, 0.0307011520562, + 0.0455481803616, 0.0455481803616, + 0.0644998855573, 0.0644998855573, + 0.107362478065, 0.107362478065, + 0.126588845655, 0.126588845655, + 0.20498970016, 0.20498970016, + 0.292210269322, 0.292210269322, + 0.372838941024, 0.372838941024, + 0.492530708782, 0.492530708782, + 0.635324635691, 0.635324635691, + 0.805584802014, 0.805584802014, + 1.0, 1.0 +}; + +static const double YM_dac_table[] = { + 0.0, 0.0, + 0.00465400167849, 0.00772106507973, + 0.0109559777218, 0.0139620050355, + 0.0169985503929, 0.0200198367285, + 0.024368657969, 0.029694056611, + 0.0350652323186, 0.0403906309606, + 0.0485389486534, 0.0583352407111, + 0.0680552376593, 0.0777752346075, + 0.0925154497597, 0.111085679408, + 0.129747463188, 0.148485542077, + 0.17666895552, 0.211551079576, + 0.246387426566, 0.281101701381, + 0.333730067903, 0.400427252613, + 0.467383840696, 0.53443198291, + 0.635172045472, 0.75800717174, + 0.879926756695, 1.0 +}; + +static void reset_segment(struct ayumi* ay); + +static int update_tone(struct ayumi* ay, int index) { + struct tone_channel* ch = &ay->channels[index]; + ch->tone_counter += 1; + if (ch->tone_counter >= ch->tone_period) { + ch->tone_counter = 0; + ch->tone ^= 1; + } + return ch->tone; +} + +static int update_noise(struct ayumi* ay) { + int bit0x3; + ay->noise_counter += 1; + if (ay->noise_counter >= (ay->noise_period << 1)) { + ay->noise_counter = 0; + bit0x3 = ((ay->noise ^ (ay->noise >> 3)) & 1); + ay->noise = (ay->noise >> 1) | (bit0x3 << 16); + } + return ay->noise & 1; +} + +static void slide_up(struct ayumi* ay) { + ay->envelope += 1; + if (ay->envelope > 31) { + ay->envelope_segment ^= 1; + reset_segment(ay); + } +} + +static void slide_down(struct ayumi* ay) { + ay->envelope -= 1; + if (ay->envelope < 0) { + ay->envelope_segment ^= 1; + reset_segment(ay); + } +} + +static void hold_top(struct ayumi* ay) { + (void) ay; +} + +static void hold_bottom(struct ayumi* ay) { + (void) ay; +} + +static void (* const Envelopes[][2])(struct ayumi*) = { + {slide_down, hold_bottom}, + {slide_down, hold_bottom}, + {slide_down, hold_bottom}, + {slide_down, hold_bottom}, + {slide_up, hold_bottom}, + {slide_up, hold_bottom}, + {slide_up, hold_bottom}, + {slide_up, hold_bottom}, + {slide_down, slide_down}, + {slide_down, hold_bottom}, + {slide_down, slide_up}, + {slide_down, hold_top}, + {slide_up, slide_up}, + {slide_up, hold_top}, + {slide_up, slide_down}, + {slide_up, hold_bottom} +}; + +static void reset_segment(struct ayumi* ay) { + if (Envelopes[ay->envelope_shape][ay->envelope_segment] == slide_down + || Envelopes[ay->envelope_shape][ay->envelope_segment] == hold_top) { + ay->envelope = 31; + return; + } + ay->envelope = 0; +} + +int update_envelope(struct ayumi* ay) { + ay->envelope_counter += 1; + if (ay->envelope_counter >= ay->envelope_period) { + ay->envelope_counter = 0; + Envelopes[ay->envelope_shape][ay->envelope_segment](ay); + } + return ay->envelope; +} + +static void update_mixer(struct ayumi* ay) { + int i; + int out; + int noise = update_noise(ay); + int envelope = update_envelope(ay); + ay->left = 0; + ay->right = 0; + for (i = 0; i < TONE_CHANNELS; i += 1) { + out = (update_tone(ay, i) | ay->channels[i].t_off) & (noise | ay->channels[i].n_off); + out *= ay->channels[i].e_on ? envelope : ay->channels[i].volume * 2 + 1; + ay->left += ay->dac_table[out] * ay->channels[i].pan_left; + ay->right += ay->dac_table[out] * ay->channels[i].pan_right; + } +} + +int ayumi_configure(struct ayumi* ay, int is_ym, double clock_rate, int sr) { + int i; + memset(ay, 0, sizeof(struct ayumi)); + ay->step = clock_rate / (sr * 8 * DECIMATE_FACTOR); + ay->dac_table = is_ym ? YM_dac_table : AY_dac_table; + ay->noise = 1; + ayumi_set_envelope(ay, 1); + for (i = 0; i < TONE_CHANNELS; i += 1) { + ayumi_set_tone(ay, i, 1); + } + return ay->step < 1; +} + +void ayumi_set_pan(struct ayumi* ay, int index, double pan, int is_eqp) { + if (is_eqp) { + ay->channels[index].pan_left = sqrt(1 - pan); + ay->channels[index].pan_right = sqrt(pan); + } else { + ay->channels[index].pan_left = 1 - pan; + ay->channels[index].pan_right = pan; + } +} + +void ayumi_set_tone(struct ayumi* ay, int index, int period) { + period &= 0xfff; + ay->channels[index].tone_period = (period == 0) | period; +} + +void ayumi_set_noise(struct ayumi* ay, int period) { + period &= 0x1f; + ay->noise_period = (period == 0) | period; +} + +void ayumi_set_mixer(struct ayumi* ay, int index, int t_off, int n_off, int e_on) { + ay->channels[index].t_off = t_off & 1; + ay->channels[index].n_off = n_off & 1; + ay->channels[index].e_on = e_on; +} + +void ayumi_set_volume(struct ayumi* ay, int index, int volume) { + ay->channels[index].volume = volume & 0xf; +} + +void ayumi_set_envelope(struct ayumi* ay, int period) { + period &= 0xffff; + ay->envelope_period = (period == 0) | period; +} + +void ayumi_set_envelope_shape(struct ayumi* ay, int shape) { + ay->envelope_shape = shape & 0xf; + ay->envelope_counter = 0; + ay->envelope_segment = 0; + reset_segment(ay); +} + +static double decimate(double* x) { + double y = -0.0000046183113992051936 * (x[1] + x[191]) + + -0.00001117761640887225 * (x[2] + x[190]) + + -0.000018610264502005432 * (x[3] + x[189]) + + -0.000025134586135631012 * (x[4] + x[188]) + + -0.000028494281690666197 * (x[5] + x[187]) + + -0.000026396828793275159 * (x[6] + x[186]) + + -0.000017094212558802156 * (x[7] + x[185]) + + 0.000023798193576966866 * (x[9] + x[183]) + + 0.000051281160242202183 * (x[10] + x[182]) + + 0.00007762197826243427 * (x[11] + x[181]) + + 0.000096759426664120416 * (x[12] + x[180]) + + 0.00010240229300393402 * (x[13] + x[179]) + + 0.000089344614218077106 * (x[14] + x[178]) + + 0.000054875700118949183 * (x[15] + x[177]) + + -0.000069839082210680165 * (x[17] + x[175]) + + -0.0001447966132360757 * (x[18] + x[174]) + + -0.00021158452917708308 * (x[19] + x[173]) + + -0.00025535069106550544 * (x[20] + x[172]) + + -0.00026228714374322104 * (x[21] + x[171]) + + -0.00022258805927027799 * (x[22] + x[170]) + + -0.00013323230495695704 * (x[23] + x[169]) + + 0.00016182578767055206 * (x[25] + x[167]) + + 0.00032846175385096581 * (x[26] + x[166]) + + 0.00047045611576184863 * (x[27] + x[165]) + + 0.00055713851457530944 * (x[28] + x[164]) + + 0.00056212565121518726 * (x[29] + x[163]) + + 0.00046901918553962478 * (x[30] + x[162]) + + 0.00027624866838952986 * (x[31] + x[161]) + + -0.00032564179486838622 * (x[33] + x[159]) + + -0.00065182310286710388 * (x[34] + x[158]) + + -0.00092127787309319298 * (x[35] + x[157]) + + -0.0010772534348943575 * (x[36] + x[156]) + + -0.0010737727700273478 * (x[37] + x[155]) + + -0.00088556645390392634 * (x[38] + x[154]) + + -0.00051581896090765534 * (x[39] + x[153]) + + 0.00059548767193795277 * (x[41] + x[151]) + + 0.0011803558710661009 * (x[42] + x[150]) + + 0.0016527320270369871 * (x[43] + x[149]) + + 0.0019152679330965555 * (x[44] + x[148]) + + 0.0018927324805381538 * (x[45] + x[147]) + + 0.0015481870327877937 * (x[46] + x[146]) + + 0.00089470695834941306 * (x[47] + x[145]) + + -0.0010178225878206125 * (x[49] + x[143]) + + -0.0020037400552054292 * (x[50] + x[142]) + + -0.0027874356824117317 * (x[51] + x[141]) + + -0.003210329988021943 * (x[52] + x[140]) + + -0.0031540624117984395 * (x[53] + x[139]) + + -0.0025657163651900345 * (x[54] + x[138]) + + -0.0014750752642111449 * (x[55] + x[137]) + + 0.0016624165446378462 * (x[57] + x[135]) + + 0.0032591192839069179 * (x[58] + x[134]) + + 0.0045165685815867747 * (x[59] + x[133]) + + 0.0051838984346123896 * (x[60] + x[132]) + + 0.0050774264697459933 * (x[61] + x[131]) + + 0.0041192521414141585 * (x[62] + x[130]) + + 0.0023628575417966491 * (x[63] + x[129]) + + -0.0026543507866759182 * (x[65] + x[127]) + + -0.0051990251084333425 * (x[66] + x[126]) + + -0.0072020238234656924 * (x[67] + x[125]) + + -0.0082672928192007358 * (x[68] + x[124]) + + -0.0081033739572956287 * (x[69] + x[123]) + + -0.006583111539570221 * (x[70] + x[122]) + + -0.0037839040415292386 * (x[71] + x[121]) + + 0.0042781252851152507 * (x[73] + x[119]) + + 0.0084176358598320178 * (x[74] + x[118]) + + 0.01172566057463055 * (x[75] + x[117]) + + 0.013550476647788672 * (x[76] + x[116]) + + 0.013388189369997496 * (x[77] + x[115]) + + 0.010979501242341259 * (x[78] + x[114]) + + 0.006381274941685413 * (x[79] + x[113]) + + -0.007421229604153888 * (x[81] + x[111]) + + -0.01486456304340213 * (x[82] + x[110]) + + -0.021143584622178104 * (x[83] + x[109]) + + -0.02504275058758609 * (x[84] + x[108]) + + -0.025473530942547201 * (x[85] + x[107]) + + -0.021627310017882196 * (x[86] + x[106]) + + -0.013104323383225543 * (x[87] + x[105]) + + 0.017065133989980476 * (x[89] + x[103]) + + 0.036978919264451952 * (x[90] + x[102]) + + 0.05823318062093958 * (x[91] + x[101]) + + 0.079072012081405949 * (x[92] + x[100]) + + 0.097675998716952317 * (x[93] + x[99]) + + 0.11236045936950932 * (x[94] + x[98]) + + 0.12176343577287731 * (x[95] + x[97]) + + 0.125 * x[96]; + memcpy(&x[FIR_SIZE - DECIMATE_FACTOR], x, DECIMATE_FACTOR * sizeof(double)); + return y; +} + +void ayumi_process(struct ayumi* ay) { + int i; + double y1; + double* c_left = ay->interpolator_left.c; + double* y_left = ay->interpolator_left.y; + double* c_right = ay->interpolator_right.c; + double* y_right = ay->interpolator_right.y; + double* fir_left = &ay->fir_left[FIR_SIZE - ay->fir_index * DECIMATE_FACTOR]; + double* fir_right = &ay->fir_right[FIR_SIZE - ay->fir_index * DECIMATE_FACTOR]; + ay->fir_index = (ay->fir_index + 1) % (FIR_SIZE / DECIMATE_FACTOR - 1); + for (i = DECIMATE_FACTOR - 1; i >= 0; i -= 1) { + ay->x += ay->step; + if (ay->x >= 1) { + ay->x -= 1; + y_left[0] = y_left[1]; + y_left[1] = y_left[2]; + y_left[2] = y_left[3]; + y_right[0] = y_right[1]; + y_right[1] = y_right[2]; + y_right[2] = y_right[3]; + update_mixer(ay); + y_left[3] = ay->left; + y_right[3] = ay->right; + y1 = y_left[2] - y_left[0]; + c_left[0] = 0.5 * y_left[1] + 0.25 * (y_left[0] + y_left[2]); + c_left[1] = 0.5 * y1; + c_left[2] = 0.25 * (y_left[3] - y_left[1] - y1); + y1 = y_right[2] - y_right[0]; + c_right[0] = 0.5 * y_right[1] + 0.25 * (y_right[0] + y_right[2]); + c_right[1] = 0.5 * y1; + c_right[2] = 0.25 * (y_right[3] - y_right[1] - y1); + } + fir_left[i] = (c_left[2] * ay->x + c_left[1]) * ay->x + c_left[0]; + fir_right[i] = (c_right[2] * ay->x + c_right[1]) * ay->x + c_right[0]; + } + ay->left = decimate(fir_left); + ay->right = decimate(fir_right); +} + +static double dc_filter(struct dc_filter* dc, int index, double x) { + dc->sum += -dc->delay[index] + x; + dc->delay[index] = x; + return x - dc->sum / DC_FILTER_SIZE; +} + +void ayumi_remove_dc(struct ayumi* ay) { + ay->left = dc_filter(&ay->dc_left, ay->dc_index, ay->left); + ay->right = dc_filter(&ay->dc_right, ay->dc_index, ay->right); + ay->dc_index = (ay->dc_index + 1) & (DC_FILTER_SIZE - 1); +} diff --git a/src/sound/ayumi/ayumi.h b/src/sound/ayumi/ayumi.h new file mode 100644 index 000000000..f15939514 --- /dev/null +++ b/src/sound/ayumi/ayumi.h @@ -0,0 +1,71 @@ +/* Author: Peter Sovietov */ + +#ifndef AYUMI_H +#define AYUMI_H + +enum { + TONE_CHANNELS = 3, + DECIMATE_FACTOR = 8, + FIR_SIZE = 192, + DC_FILTER_SIZE = 1024 +}; + +struct tone_channel { + int tone_period; + int tone_counter; + int tone; + int t_off; + int n_off; + int e_on; + int volume; + double pan_left; + double pan_right; +}; + +struct interpolator { + double c[4]; + double y[4]; +}; + +struct dc_filter { + double sum; + double delay[DC_FILTER_SIZE]; +}; + +struct ayumi { + struct tone_channel channels[TONE_CHANNELS]; + int noise_period; + int noise_counter; + int noise; + int envelope_counter; + int envelope_period; + int envelope_shape; + int envelope_segment; + int envelope; + const double* dac_table; + double step; + double x; + struct interpolator interpolator_left; + struct interpolator interpolator_right; + double fir_left[FIR_SIZE * 2]; + double fir_right[FIR_SIZE * 2]; + int fir_index; + struct dc_filter dc_left; + struct dc_filter dc_right; + int dc_index; + double left; + double right; +}; + +int ayumi_configure(struct ayumi* ay, int is_ym, double clock_rate, int sr); +void ayumi_set_pan(struct ayumi* ay, int index, double pan, int is_eqp); +void ayumi_set_tone(struct ayumi* ay, int index, int period); +void ayumi_set_noise(struct ayumi* ay, int period); +void ayumi_set_mixer(struct ayumi* ay, int index, int t_off, int n_off, int e_on); +void ayumi_set_volume(struct ayumi* ay, int index, int volume); +void ayumi_set_envelope(struct ayumi* ay, int period); +void ayumi_set_envelope_shape(struct ayumi* ay, int shape); +void ayumi_process(struct ayumi* ay); +void ayumi_remove_dc(struct ayumi* ay); + +#endif diff --git a/src/sound/snd_mmb.c b/src/sound/snd_mmb.c new file mode 100644 index 000000000..35a72efbc --- /dev/null +++ b/src/sound/snd_mmb.c @@ -0,0 +1,339 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mindscape Music Board emulation. + * + * Authors: Roy Baer, + * Jasmine Iwanek, + * + * Copyright 2025 Roy Baer. + * Copyright 2025 Jasmine Iwanek. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/sound.h> +//#i nclude "cpu.h" +#include "ayumi/ayumi.h" +#include <86box/snd_mmb.h> +#include <86box/plat_unused.h> + +#ifdef ENABLE_MMB_LOG +int mmb_do_log = ENABLE_MMB_LOG; + +static void +mmb_log(const char *fmt, ...) +{ + va_list ap; + + if (mmb_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mmb_log(fmt, ...) +#endif + +void +mmb_update(mmb_t *mmb) +{ + for (; mmb->pos < sound_pos_global; mmb->pos++) { + ayumi_process(&mmb->first.chip); + ayumi_process(&mmb->second.chip); + + ayumi_remove_dc(&mmb->first.chip); + ayumi_remove_dc(&mmb->second.chip); + + mmb->buffer[mmb->pos << 1] = (mmb->first.chip.left + mmb->second.chip.left) * 16000; + mmb->buffer[(mmb->pos << 1) + 1] = (mmb->first.chip.right + mmb->second.chip.right) * 16000; + } +} + +void +mmb_get_buffer(int32_t *buffer, int len, void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + + mmb_update(mmb); + + for (int c = 0; c < len * 2; c++) + buffer[c] += mmb->buffer[c]; + + mmb->pos = 0; +} + +void +mmb_write(uint16_t addr, uint8_t val, void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + + mmb_update(mmb); + + mmb_log("mmb_write(%04X): activity now: %02X\n", addr, val); + + switch (addr & 3) { + case 0: + mmb->first.index = val; + break; + case 2: + mmb->second.index = val; + break; + case 1: + case 3: + { + ay_3_891x_t *ay = ((addr & 2) == 0) ? &mmb->first : &mmb->second; + + switch (ay->index) { + case 0: + ay->regs[0] = val; + ayumi_set_tone(&ay->chip, 0, (ay->regs[1] << 8) | ay->regs[0]); + break; + case 1: + ay->regs[1] = val & 0xf; + ayumi_set_tone(&ay->chip, 0, (ay->regs[1] << 8) | ay->regs[0]); + break; + case 2: + ay->regs[2] = val; + ayumi_set_tone(&ay->chip, 1, (ay->regs[3] << 8) | ay->regs[2]); + break; + case 3: + ay->regs[3] = val & 0xf; + ayumi_set_tone(&ay->chip, 1, (ay->regs[3] << 8) | ay->regs[2]); + break; + case 4: + ay->regs[4] = val; + ayumi_set_tone(&ay->chip, 2, (ay->regs[5] << 8) | ay->regs[4]); + break; + case 5: + ay->regs[5] = val & 0xf; + ayumi_set_tone(&ay->chip, 2, (ay->regs[5] << 8) | ay->regs[4]); + break; + case 6: + ay->regs[6] = val & 0x1f; + ayumi_set_noise(&ay->chip, ay->regs[6]); + break; + case 7: + ay->regs[7] = val; + ayumi_set_mixer(&ay->chip, 0, val & 1, (val >> 3) & 1, (ay->regs[8] >> 4) & 1); + ayumi_set_mixer(&ay->chip, 1, (val >> 1) & 1, (val >> 4) & 1, (ay->regs[9] >> 4) & 1); + ayumi_set_mixer(&ay->chip, 2, (val >> 2) & 1, (val >> 5) & 1, (ay->regs[10] >> 4) & 1); + break; + case 8: + ay->regs[8] = val; + ayumi_set_volume(&ay->chip, 0, val & 0xf); + ayumi_set_mixer(&ay->chip, 0, ay->regs[7] & 1, (ay->regs[7] >> 3) & 1, (val >> 4) & 1); + break; + case 9: + ay->regs[9] = val; + ayumi_set_volume(&ay->chip, 1, val & 0xf); + ayumi_set_mixer(&ay->chip, 1, (ay->regs[7] >> 1) & 1, (ay->regs[7] >> 4) & 1, (val >> 4) & 1); + break; + case 10: + ay->regs[10] = val; + ayumi_set_volume(&ay->chip, 2, val & 0xf); + ayumi_set_mixer(&ay->chip, 2, (ay->regs[7] >> 2) & 1, (ay->regs[7] >> 5) & 1, (val >> 4) & 1); + break; + case 11: + ay->regs[11] = val; + ayumi_set_envelope(&ay->chip, (ay->regs[12] >> 8) | ay->regs[11]); + break; + case 12: + ay->regs[12] = val; + ayumi_set_envelope(&ay->chip, (ay->regs[12] >> 8) | ay->regs[11]); + break; + case 13: + ay->regs[13] = val; + ayumi_set_envelope_shape(&ay->chip, val & 0xf); + break; + case 14: + ay->regs[14] = val; + break; + case 15: + ay->regs[15] = val; + break; + + default: + break; + } + break; + } + + default: + break; + } +} + +uint8_t +mmb_read(uint16_t addr, void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + ay_3_891x_t *ay = ((addr & 2) == 0) ? &mmb->first : &mmb->second; + uint8_t ret = 0; + + switch (ay->index) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + ret = ay->regs[ay->index]; + break; + case 14: + if (ay->regs[7] & 0x40) + ret = ay->regs[14]; + break; + case 15: + if (ay->regs[7] & 0x80) + ret = ay->regs[15]; + break; + + default: + break; + } + + mmb_log("mmb_read(%04X): activity now: %02X\n", addr, ret); + + return ret; +} + +void * +mmb_init(UNUSED(const device_t *info)) +{ + mmb_t *mmb = calloc(1, sizeof(mmb_t)); +# if 0 + uint16_t addr = (device_get_config_int("addr96") << 6) | (device_get_config_int("addr52") << 2); +#else + uint16_t addr = 0x300; + +#endif + sound_add_handler(mmb_get_buffer, mmb); + + ayumi_configure(&mmb->first.chip, 0, MMB_CLOCK, MMB_FREQ); + ayumi_configure(&mmb->second.chip, 0, MMB_CLOCK, MMB_FREQ); + + for (uint8_t i = 0; i < 3; i++) { + ayumi_set_pan(&mmb->first.chip, i, 0.5, 1); + ayumi_set_pan(&mmb->second.chip, i, 0.5, 1); + } + + io_sethandler(addr, 0x0004, + mmb_read, NULL, NULL, + mmb_write, NULL, NULL, + mmb); + + return mmb; +} + +void +mmb_close(void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + + free(mmb); +} + +// clang-format off +#if 0 +static device_config_t mmb_config[] = { + { + .name = "addr96", + .description = "Base address A9...A6", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 12, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0000", .value = 0 }, + { .description = "0001", .value = 1 }, + { .description = "0010", .value = 2 }, + { .description = "0011", .value = 3 }, + { .description = "0100", .value = 4 }, + { .description = "0101", .value = 5 }, + { .description = "0110", .value = 6 }, + { .description = "0111", .value = 7 }, + { .description = "1000", .value = 8 }, + { .description = "1001", .value = 9 }, + { .description = "1010", .value = 10 }, + { .description = "1011", .value = 11 }, + { .description = "1100", .value = 12 }, + { .description = "1101", .value = 13 }, + { .description = "1110", .value = 14 }, + { .description = "1111", .value = 15 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "addr52", + .description = "Base address A5...A2", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0000", .value = 0 }, + { .description = "0001", .value = 1 }, + { .description = "0010", .value = 2 }, + { .description = "0011", .value = 3 }, + { .description = "0100", .value = 4 }, + { .description = "0101", .value = 5 }, + { .description = "0110", .value = 6 }, + { .description = "0111", .value = 7 }, + { .description = "1000", .value = 8 }, + { .description = "1001", .value = 9 }, + { .description = "1010", .value = 10 }, + { .description = "1011", .value = 11 }, + { .description = "1100", .value = 12 }, + { .description = "1101", .value = 13 }, + { .description = "1110", .value = 14 }, + { .description = "1111", .value = 15 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .type = CONFIG_END } +}; +#endif +// clang-format on + +const device_t mmb_device = { + .name = "Mindscape Music Board", + .internal_name = "mmb", + .flags = DEVICE_ISA, + .local = 0, + .init = mmb_init, + .close = mmb_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, +#if 0 + .config = mmb_config +#else + .config = NULL +#endif +}; diff --git a/src/sound/sound.c b/src/sound/sound.c index 0c8dffe12..c3ecc8632 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -137,6 +137,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16xv_device }, { &ssi2001_device }, { &entertainer_device }, + { &mmb_device }, { &pasplus_device }, { &pas16_device }, { &pas16d_device }, From 4033f81c4888b211d06afdf38cf19c6da650e2b2 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 25 May 2025 20:15:14 -0400 Subject: [PATCH 02/22] Clean up sound/CMakeLists.txt --- src/sound/CMakeLists.txt | 9 +++++---- src/sound/esfmu/CMakeLists.txt | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 src/sound/esfmu/CMakeLists.txt diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 3aaf49bb3..fb3c9b43d 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -49,8 +49,6 @@ add_library(snd OBJECT snd_wss.c snd_ym7128.c snd_optimc.c - esfmu/esfm.c - esfmu/esfm_registers.c snd_opl_esfm.c ) @@ -181,6 +179,9 @@ endif() add_subdirectory(ayumi) target_link_libraries(86Box ayumi) +add_subdirectory(esfmu) +target_link_libraries(86Box esfmu) + add_subdirectory(ymfm) target_link_libraries(86Box ymfm) @@ -193,8 +194,8 @@ if(OPL4ML) target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) endif() -find_package(PkgConfig ) -pkg_check_modules(SERIALPORT libserialport) +find_package(PkgConfig) +pkg_check_modules(SERIALPORT libserialport) if(SERIALPORT_FOUND OR DEFINED LIBSERIALPORT_ROOT) add_compile_definitions(USE_LIBSERIALPORT=1) diff --git a/src/sound/esfmu/CMakeLists.txt b/src/sound/esfmu/CMakeLists.txt new file mode 100644 index 000000000..2505038f1 --- /dev/null +++ b/src/sound/esfmu/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# + +add_library(esfmu STATIC + esfm.c + esfm_registers.c +) From 09f63b6466450c7b22df74584ded24d71048d2de Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 27 May 2025 04:47:45 +0200 Subject: [PATCH 03/22] Assorted fixes, the Compaq Presario 7100 486 no longer crashes on CTRL+ALT+DEL. --- src/chipset/umc_hb4.c | 53 ++----------------------------------------- src/device/kbc_at.c | 4 +++- src/mem/mem.c | 12 ++++++---- src/mem/smram.c | 15 +++++++++--- 4 files changed, 24 insertions(+), 60 deletions(-) diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 889691988..55901b32e 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -270,6 +270,8 @@ hb4_smram(hb4_t *dev) } umc_smram_recalc(dev->smram_base >> 12, 1); + + flushmmucache(); } static void @@ -398,55 +400,6 @@ hb4_close(void *priv) free(dev); } -static void -ims8848_write(uint16_t addr, uint8_t val, void *priv) -{ - hb4_t *dev = (hb4_t *) priv; - - switch (addr) { - case 0x22: - dev->idx = val; - break; - case 0x23: - if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0))) - dev->access_data = 1; - break; - case 0x24: - if (dev->access_data) - dev->access_data = 0; - break; - - default: - break; - } -} - -static uint8_t -ims8848_read(uint16_t addr, void *priv) -{ - uint8_t ret = 0xff; - hb4_t *dev = (hb4_t *) priv; - - switch (addr) { - case 0x22: - ret = dev->idx; - break; - case 0x23: - ret = (dev->idx >> 4) | (dev->idx << 4); - break; - case 0x24: - if (dev->access_data) { - ret = dev->pci_conf[dev->idx]; - dev->access_data = 0; - } - break; - default: - break; - } - - return ret; -} - static void * hb4_init(UNUSED(const device_t *info)) { @@ -463,8 +416,6 @@ hb4_init(UNUSED(const device_t *info)) dev->smram_base = 0x000a0000; hb4_reset(dev); - io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev); - return dev; } diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index dc93a4fba..8840a0e4d 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -830,7 +830,9 @@ write_p2(atkbc_t *dev, uint8_t val) softresetx86(); /* Pulse reset! */ cpu_set_edx(); flushmmucache(); - if ((kbc_ven == KBC_VEN_ALI) || !strcmp(machine_get_internal_name(), "spc7700plw")) + if ((kbc_ven == KBC_VEN_ALI) || + !strcmp(machine_get_internal_name(), "spc7700plw") || + !strcmp(machine_get_internal_name(), "pl4600c")) smbase = 0x00030000; /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L diff --git a/src/mem/mem.c b/src/mem/mem.c index 07d897172..d365ecffb 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2994,10 +2994,12 @@ mem_init(void) } static void -umc_page_recalc(uint32_t c, int set) +umc_page_recalc(uint32_t c, uint32_t phys, int set) { + uint32_t target = set ? phys : c; + if (set) { - pages[c].mem = &ram[(c & 0xff) << 12]; + pages[c].mem = &ram[(target & 0xff) << 12]; pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; @@ -3010,8 +3012,8 @@ umc_page_recalc(uint32_t c, int set) #ifdef USE_NEW_DYNAREC pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64]; + pages[c].byte_dirty_mask = &byte_dirty_mask[(target & 0xff) * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[(target & 0xff) * 64]; #endif } @@ -3019,7 +3021,7 @@ void umc_smram_recalc(uint32_t start, int set) { for (uint32_t c = start; c < (start + 0x0020); c++) - umc_page_recalc(c, set); + umc_page_recalc(c, c - start + 0x000a0000, set); } static void diff --git a/src/mem/smram.c b/src/mem/smram.c index afbc5475c..928760f3a 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -59,9 +59,12 @@ smram_read(uint32_t addr, void *priv) const smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (new_addr >= (1 << 30)) return mem_read_ram_2gb(new_addr, priv); - else if (!use_separate_smram || (new_addr >= 0xa0000)) + else +#endif + if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ram(new_addr, priv); else return dev->mapping.exec[addr - dev->host_base]; @@ -73,9 +76,12 @@ smram_readw(uint32_t addr, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (new_addr >= (1 << 30)) return mem_read_ram_2gbw(new_addr, priv); - else if (!use_separate_smram || (new_addr >= 0xa0000)) + else +#endif + if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ramw(new_addr, priv); else return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]); @@ -87,9 +93,12 @@ smram_readl(uint32_t addr, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (new_addr >= (1 << 30)) return mem_read_ram_2gbl(new_addr, priv); - else if (!use_separate_smram || (new_addr >= 0xa0000)) + else +#endif + if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_raml(new_addr, priv); else return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]); From 8e895903ed2373372f2b0a2e22669e21abdfddae Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 26 May 2025 04:38:28 -0400 Subject: [PATCH 04/22] Alternate font support for MDA and Hercules --- src/include/86box/video.h | 35 +++++---- src/machine/m_amstrad.c | 2 +- src/machine/m_pcjr.c | 2 +- src/video/vid_hercules.c | 44 ++++++++++-- src/video/vid_mda.c | 45 +++++++++++- src/video/vid_table.c | 2 +- src/video/video.c | 144 ++++++++++++++++++-------------------- 7 files changed, 176 insertions(+), 98 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 085dd5f80..6a73c6462 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -36,6 +36,10 @@ using atomic_int = std::atomic_int; #define getcolg(color) (((color) >> 8) & 0xFF) #define getcolb(color) ((color) & 0xFF) +#ifdef __cplusplus +extern "C" { +#endif + enum { VID_NONE = 0, VID_INTERNAL @@ -49,10 +53,6 @@ enum { FULLSCR_SCALE_INT43 }; -#ifdef __cplusplus -extern "C" { -#endif - enum { VIDEO_ISA = 0, VIDEO_MCA, @@ -71,6 +71,11 @@ enum { #define VIDEO_FLAG_TYPE_SECONDARY VIDEO_FLAG_TYPE_SPECIAL +#define FONT_IBM_MDA_437_PATH "roms/video/mda/mda.rom" +#define FONT_IBM_MDA_437_NORDIC_PATH "roms/video/mda/4733197.bin" +#define FONT_KAM_PATH "roms/video/mda/kam.bin" +#define FONT_KAMCL16_PATH "roms/video/mda/kamcl16.bin" + typedef struct video_timings_t { int type; int write_b; @@ -189,15 +194,15 @@ extern uint32_t pal_lookup[256]; #endif extern int video_fullscreen; extern int video_fullscreen_scale; -extern uint8_t fontdat[2048][8]; -extern uint8_t fontdatm[2048][16]; -extern uint8_t fontdat2[2048][8]; -extern uint8_t fontdatm2[2048][16]; -extern uint8_t fontdatw[512][32]; -extern uint8_t fontdat8x12[256][16]; -extern uint8_t fontdat12x18[256][36]; -extern dbcs_font_t *fontdatksc5601; -extern dbcs_font_t *fontdatksc5601_user; +extern uint8_t fontdat[2048][8]; /* IBM CGA font */ +extern uint8_t fontdatm[2048][16]; /* IBM MDA font */ +extern uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */ +extern uint8_t fontdatm2[2048][16]; /* IBM MDA 2nd instance font */ +extern uint8_t fontdatw[512][32]; /* Wyse700 font */ +extern uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +extern uint8_t fontdat12x18[256][36]; /* IM1024 font */ +extern dbcs_font_t *fontdatksc5601; /* Korean KSC-5601 font */ +extern dbcs_font_t *fontdatksc5601_user; /* Korean KSC-5601 user defined font */ extern uint32_t *video_6to8; extern uint32_t *video_8togs; extern uint32_t *video_8to32; @@ -277,8 +282,8 @@ extern uint8_t video_force_resize_get_monitor(int monitor_index); extern void video_force_resize_set_monitor(uint8_t res, int monitor_index); extern void video_update_timing(void); -extern void loadfont_ex(char *s, int format, int offset); -extern void loadfont(char *s, int format); +extern void loadfont_ex(char *fn, int format, int offset); +extern void loadfont(char *fn, int format); extern int get_actual_size_x(void); extern int get_actual_size_y(void); diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 3dba578bd..814d95ffd 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2936,7 +2936,7 @@ machine_amstrad_init(const machine_t *model, int type) break; case AMS_PC1640: - loadfont("roms/video/mda/mda.rom", 0); + loadfont(FONT_IBM_MDA_437_PATH, 0); device_context(&vid_1640_device); ams->language = device_get_config_int("language"); vid_init_1640(ams); diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index d4d3b09cf..cb69bd9e5 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -1541,7 +1541,7 @@ machine_pcjr_init(UNUSED(const machine_t *model)) /* Initialize the video controller. */ video_reset(gfxcard[0]); - loadfont("roms/video/mda/mda.rom", 0); + loadfont(FONT_IBM_MDA_437_PATH, 0); device_context(&pcjr_device); pcjr_vid_init(pcjr); device_context_restore(); diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 00374d08f..af8ad08f8 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -543,14 +543,33 @@ hercules_init(UNUSED(const device_t *info)) dev->vram = (uint8_t *) malloc(0x10000); + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 2: + loadfont(FONT_KAM_PATH, 0); + break; + case 3: + loadfont(FONT_KAMCL16_PATH, 0); + break; + } + timer_add(&dev->timer, hercules_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, - hercules_read, NULL, NULL, hercules_write, NULL, NULL, - NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev); + hercules_read, NULL, NULL, + hercules_write, NULL, NULL, + NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, + dev); - io_sethandler(0x03b0, 16, - hercules_in, NULL, NULL, hercules_out, NULL, NULL, dev); + io_sethandler(0x03b0, 0x0010, + hercules_in, NULL, NULL, + hercules_out, NULL, NULL, + dev); for (uint16_t c = 0; c < 256; c++) { dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16; @@ -642,6 +661,23 @@ static const device_config_t hercules_config[] = { .selection = { { 0 } }, .bios = { { 0 } } }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Czech Kamenicky (CP 895) #1", .value = 2 }, + { .description = "Czech Kamenicky (CP 895) #2", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 66a0fbb71..7b6e54806 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -317,8 +317,32 @@ mda_standalone_init(UNUSED(const device_t *info)) mda->vram = malloc(0x1000); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); - io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + + case 2: + loadfont(FONT_KAM_PATH, 0); + break; + case 3: + loadfont(FONT_KAMCL16_PATH, 0); + break; + } + + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, + mda_read, NULL, NULL, + mda_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, + mda); + + io_sethandler(0x03b0, 0x0010, + mda_in, NULL, NULL, + mda_out, NULL, NULL, + mda); mda_init(mda); @@ -369,6 +393,23 @@ static const device_config_t mda_config[] = { }, .bios = { { 0 } } }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Czech Kamenicky (CP 895) #1", .value = 2 }, + { .description = "Czech Kamenicky (CP 895) #2", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index e0ef7ada6..33a7f30ca 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -328,7 +328,7 @@ video_reset(int card) card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); monitor_index_global = 0; - loadfont("roms/video/mda/mda.rom", 0); + loadfont(FONT_IBM_MDA_437_PATH, 0); for (uint8_t i = 1; i < GFXCARD_MAX; i ++) { if ((card != VID_NONE) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) && diff --git a/src/video/video.c b/src/video/video.c index 0773e61ce..11edbc3f4 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -1006,76 +1006,73 @@ video_force_resize_set_monitor(uint8_t res, int monitor_index) } void -loadfont_common(FILE *f, int format) +loadfont_common(FILE *fp, int format) { - int c; - int d; - switch (format) { case 0: /* MDA */ - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdatm[c][d] = fgetc(f) & 0xff; - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdatm[c][d + 8] = fgetc(f) & 0xff; - (void) fseek(f, 4096 + 2048, SEEK_SET); - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x8 cell (lines 0-7) */ + for (uint8_t d = 0; d < 8; d++) + fontdatm[c][d] = fgetc(fp) & 0xff; + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x8 cell (lines 8-13 + padding lines) */ + for (uint8_t d = 0; d < 8; d++) + fontdatm[c][d + 8] = fgetc(fp) & 0xff; + (void) fseek(fp, 4096 + 2048, SEEK_SET); + for (uint16_t c = 0; c < 256; c++) + for (uint8_t d = 0; d < 8; d++) /* 8x8 CGA (thick, primary) */ + fontdat[c][d] = fgetc(fp) & 0xff; break; case 1: /* PC200 */ - for (d = 0; d < 4; d++) { + for (uint8_t d = 0; d < 4; d++) { /* There are 4 fonts in the ROM */ - for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ - (void) !fread(&fontdatm[256 * d + c][0], 1, 16, f); - for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ - (void) !fread(&fontdat[256 * d + c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + (void) !fread(&fontdatm[256 * d + c][0], 1, 16, fp); + for (uint16_t c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + (void) !fread(&fontdat[256 * d + c][0], 1, 8, fp); + fseek(fp, 8, SEEK_CUR); } } break; default: case 2: /* CGA */ - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 256; c++) + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; case 3: /* Wyse 700 */ - for (c = 0; c < 512; c++) - for (d = 0; d < 32; d++) - fontdatw[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 512; c++) + for (uint8_t d = 0; d < 32; d++) + fontdatw[c][d] = fgetc(fp) & 0xff; break; case 4: /* MDSI Genius */ - for (c = 0; c < 256; c++) - for (d = 0; d < 16; d++) - fontdat8x12[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 256; c++) + for (uint8_t d = 0; d < 16; d++) + fontdat8x12[c][d] = fgetc(fp) & 0xff; break; - case 5: /* Toshiba 3100e */ - for (d = 0; d < 2048; d += 512) { /* Four languages... */ - for (c = d; c < d + 256; c++) { - (void) !fread(&fontdatm[c][8], 1, 8, f); + case 5: /* Toshiba 3100e */ + for (uint16_t d = 0; d < 2048; d += 512) { /* Four languages... */ + for (uint16_t c = d; c < d + 256; c++) { + (void) !fread(&fontdatm[c][8], 1, 8, fp); } - for (c = d + 256; c < d + 512; c++) { - (void) !fread(&fontdatm[c][8], 1, 8, f); + for (uint16_t c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdatm[c][8], 1, 8, fp); } - for (c = d; c < d + 256; c++) { - (void) !fread(&fontdatm[c][0], 1, 8, f); + for (uint16_t c = d; c < d + 256; c++) { + (void) !fread(&fontdatm[c][0], 1, 8, fp); } - for (c = d + 256; c < d + 512; c++) { - (void) !fread(&fontdatm[c][0], 1, 8, f); + for (uint16_t c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdatm[c][0], 1, 8, fp); } - fseek(f, 4096, SEEK_CUR); /* Skip blank section */ - for (c = d; c < d + 256; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); + fseek(fp, 4096, SEEK_CUR); /* Skip blank section */ + for (uint16_t c = d; c < d + 256; c++) { + (void) !fread(&fontdat[c][0], 1, 8, fp); } - for (c = d + 256; c < d + 512; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); + for (uint16_t c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdat[c][0], 1, 8, fp); } } break; @@ -1087,65 +1084,64 @@ loadfont_common(FILE *f, int format) if (!fontdatksc5601_user) fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); - for (c = 0; c < 16384; c++) { - for (d = 0; d < 32; d++) - fontdatksc5601[c].chr[d] = fgetc(f) & 0xff; + for (uint32_t c = 0; c < 16384; c++) { + for (uint8_t d = 0; d < 32; d++) + fontdatksc5601[c].chr[d] = fgetc(fp) & 0xff; } break; case 7: /* Sigma Color 400 */ /* The first 4k of the character ROM holds an 8x8 font */ - for (c = 0; c < 256; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); + for (uint16_t c = 0; c < 256; c++) { + (void) !fread(&fontdat[c][0], 1, 8, fp); + fseek(fp, 8, SEEK_CUR); } /* The second 4k holds an 8x16 font */ - for (c = 0; c < 256; c++) { - if (fread(&fontdatm[c][0], 1, 16, f) != 16) + for (uint16_t c = 0; c < 256; c++) { + if (fread(&fontdatm[c][0], 1, 16, fp) != 16) fatal("loadfont(): Error reading 8x16 font in Sigma Color 400 mode, c = %i\n", c); } break; - case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */ - for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */ - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */ + for (uint16_t c = 0; c < 2048; c++) /* Allow up to 2048 chars */ + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; case 9: /* Image Manager 1024 native font */ - for (c = 0; c < 256; c++) - (void) !fread(&fontdat12x18[c][0], 1, 36, f); + for (uint16_t c = 0; c < 256; c++) + (void) !fread(&fontdat12x18[c][0], 1, 36, fp); break; - case 10: /* Pravetz */ - for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */ - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + case 10: /* Pravetz */ + for (uint16_t c = 0; c < 1024; c++) /* Allow up to 1024 chars */ + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; - case 11: /* PC200 */ - for (d = 0; d < 4; d++) { + for (uint8_t d = 0; d < 4; d++) { /* There are 4 fonts in the ROM */ - for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ - (void) !fread(&fontdatm2[256 * d + c][0], 1, 16, f); - for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ - (void) !fread(&fontdat2[256 * d + c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + (void) !fread(&fontdatm2[256 * d + c][0], 1, 16, fp); + for (uint16_t c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + (void) !fread(&fontdat2[256 * d + c][0], 1, 8, fp); + fseek(fp, 8, SEEK_CUR); } } break; } - (void) fclose(f); + (void) fclose(fp); } void -loadfont_ex(char *s, int format, int offset) +loadfont_ex(char *fn, int format, int offset) { FILE *fp; - fp = rom_fopen(s, "rb"); + fp = rom_fopen(fn, "rb"); if (fp == NULL) return; @@ -1154,9 +1150,9 @@ loadfont_ex(char *s, int format, int offset) } void -loadfont(char *s, int format) +loadfont(char *fn, int format) { - loadfont_ex(s, format, 0); + loadfont_ex(fn, format, 0); } uint32_t From eac0006e7fc6923cac973dbe4c69fa478e3fd1ab Mon Sep 17 00:00:00 2001 From: rushieda <185547947+rushieda@users.noreply.github.com> Date: Tue, 27 May 2025 23:40:14 +0300 Subject: [PATCH 05/22] Add the Dell System 200 machine --- src/include/86box/machine.h | 1 + src/machine/m_at_286_386sx.c | 18 ++++++++++++++++ src/machine/machine_table.c | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 0dbbe98c5..ac26f7a50 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -475,6 +475,7 @@ extern int machine_at_spc4216p_init(const machine_t *); extern int machine_at_spc4620p_init(const machine_t *); extern int machine_at_kmxc02_init(const machine_t *); extern int machine_at_deskmaster286_init(const machine_t *); +extern int machine_at_dells200_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_3302_init(const machine_t *); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index e7aa66662..8400e4ae8 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -261,6 +261,24 @@ machine_at_px286_init(const machine_t *model) return ret; } +int +machine_at_dells200_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/dells200/dellL200256_LO_@DIP28.BIN", + "roms/machines/dells200/Dell200256_HI_@DIP28.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + device_add(&keyboard_at_device); + + return ret; +} + int machine_at_micronics386_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a3a02bfcd..d2ef357e1 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2975,6 +2975,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[ISA] Dell System 200", + .internal_name = "dells200", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_at_dells200_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 6000000, + .max_bus = 12000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has IBM AT KBC firmware. */ { .name = "[ISA] MR BIOS 286 clone", From cebf27f02d134c77877ef430a9d690795e245d12 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 04:09:47 +0200 Subject: [PATCH 06/22] Finish the Dell System 200 work. --- src/chipset/CMakeLists.txt | 1 + src/chipset/cs8220.c | 289 +++++++++++++++++++++++++++++++++++ src/include/86box/chipset.h | 1 + src/include/86box/machine.h | 1 + src/machine/m_at_286_386sx.c | 10 +- src/machine/machine_table.c | 89 +++++------ 6 files changed, 345 insertions(+), 46 deletions(-) create mode 100644 src/chipset/cs8220.c diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 7d17b9983..7a8233003 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(chipset OBJECT 82c100.c acc2168.c + cs8220.c cs8230.c ali1429.c ali1435.c diff --git a/src/chipset/cs8220.c b/src/chipset/cs8220.c new file mode 100644 index 000000000..4c08ecef5 --- /dev/null +++ b/src/chipset/cs8220.c @@ -0,0 +1,289 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of C&T CS8220 ("PC/AT") chipset. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/chipset.h> + +typedef struct { + uint32_t virt; + uint32_t phys; + + uint32_t size; + + mem_mapping_t mapping; +} ram_bank_t; + +typedef struct { + uint8_t regs[3]; + + ram_bank_t ram_banks[3]; +} cs8220_t; + +static uint8_t +cs8220_mem_read(uint32_t addr, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = ram[addr]; + + return ret; +} + +static uint16_t +cs8220_mem_readw(uint32_t addr, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + uint16_t ret = 0xffff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = *(uint16_t *) &(ram[addr]); + + return ret; +} + +static void +cs8220_mem_write(uint32_t addr, uint8_t val, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +static void +cs8220_mem_writew(uint32_t addr, uint16_t val, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + *(uint16_t *) &(ram[addr]) = val; +} + +static uint8_t +cs8220_in(uint16_t port, void *priv) { + cs8220_t *dev = (cs8220_t *) priv; + uint8_t ret = 0xff; + + switch (port) { + case 0x00a4 ... 0x00a5: + ret = dev->regs[port & 0x0001]; + break; + case 0x00ab: + ret = dev->regs[2]; + break; + } + + return ret; +} + +static void +cs8220_out(uint16_t port, uint8_t val, void *priv) { + cs8220_t *dev = (cs8220_t *) priv; + + switch (port) { + case 0x00a4: + dev->regs[0] = val; + mem_a20_alt = val & 0x40; + mem_a20_recalc(); + break; + case 0x00a5: + dev->regs[1] = val; + if (val & 0x01) { + mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, 0x000040000); + mem_mapping_disable(&dev->ram_banks[1].mapping); + mem_mapping_disable(&dev->ram_banks[2].mapping); + } else { + mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, dev->ram_banks[0].size); + mem_mapping_enable(&dev->ram_banks[1].mapping); + mem_mapping_enable(&dev->ram_banks[2].mapping); + } + break; + case 0x00ab: + dev->regs[2] = val; + break; + } +} + +static void +cs8220_close(void *priv) +{ + cs8220_t *dev = (cs8220_t *) priv; + + free(dev); +} + +static void * +cs8220_init(UNUSED(const device_t *info)) +{ + cs8220_t *dev = (cs8220_t *) calloc(1, sizeof(cs8220_t)); + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + + /* + Dell System 200: 640 kB soldered on-board, any other RAM is expansion. + */ + if (!strcmp(machine_get_internal_name(), "dells200")) switch (mem_size) { + default: + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x000a0000; + dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000; + fallthrough; + case 640: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + break; + /* + We are limited to steps of equal size, so we have to simulate some + memory expansions to work around the chipset's limits. + */ + } else switch (mem_size) { + case 256: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00020000; + dev->ram_banks[1].virt = 0x00020000; + dev->ram_banks[1].phys = 0x00020000; + dev->ram_banks[1].size = 0x00020000; + break; + case 384: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00020000; + /* Pretend there's a 128k expansion. */ + dev->ram_banks[2].virt = 0x00020000; + dev->ram_banks[2].phys = 0x00020000; + dev->ram_banks[2].size = 0x00040000; + break; + case 512: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + break; + default: + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x000a0000; + dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000; + fallthrough; + case 640: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + break; + case 768: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + /* Pretend there's a 128k expansion. */ + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x00080000; + dev->ram_banks[2].size = 0x00020000; + break; + case 896: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + /* Pretend there's a 256k expansion. */ + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x00080000; + dev->ram_banks[2].size = 0x00040000; + break; + case 1024: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00100000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00080000; + break; + } + + if (dev->ram_banks[0].size > 0x00000000) + mem_mapping_add(&dev->ram_banks[0].mapping, dev->ram_banks[0].virt, dev->ram_banks[0].size, + cs8220_mem_read, cs8220_mem_readw, NULL, + cs8220_mem_write, cs8220_mem_writew, NULL, + ram + dev->ram_banks[0].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[0])); + + if (dev->ram_banks[1].size > 0x00000000) + mem_mapping_add(&dev->ram_banks[1].mapping, dev->ram_banks[1].virt, dev->ram_banks[1].size, + cs8220_mem_read, cs8220_mem_readw, NULL, + cs8220_mem_write, cs8220_mem_writew, NULL, + ram + dev->ram_banks[1].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[1])); + + if (dev->ram_banks[2].size > 0x00000000) + mem_mapping_add(&dev->ram_banks[2].mapping, dev->ram_banks[2].virt, dev->ram_banks[2].size, + cs8220_mem_read, cs8220_mem_readw, NULL, + cs8220_mem_write, cs8220_mem_writew, NULL, + ram + dev->ram_banks[2].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[2])); + + io_sethandler(0x00a4, 0x0002, + cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev); + io_sethandler(0x00ab, 0x0001, + cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev); + + return dev; +} + +const device_t cs8220_device = { + .name = "C&T CS8220 (PC/AT)", + .internal_name = "cs8220", + .flags = 0, + .local = 0, + .init = cs8220_init, + .close = cs8220_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 688a5fecb..e11af5e4d 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -55,6 +55,7 @@ extern const device_t neat_sx_device; extern const device_t scat_device; extern const device_t scat_4_device; extern const device_t scat_sx_device; +extern const device_t cs8220_device; extern const device_t cs8230_device; extern const device_t cs4031_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ac26f7a50..137880a11 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -211,6 +211,7 @@ enum { MACHINE_CHIPSET_SCAT_SX, MACHINE_CHIPSET_NEAT, MACHINE_CHIPSET_NEAT_SX, + MACHINE_CHIPSET_CT_AT, MACHINE_CHIPSET_CT_386, MACHINE_CHIPSET_CT_CS4031, MACHINE_CHIPSET_CONTAQ_82C596, diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 8400e4ae8..2b181c499 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -273,8 +273,14 @@ machine_at_dells200_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); - device_add(&keyboard_at_device); + machine_at_common_init(model); + + device_add(&cs8220_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&keyboard_at_phoenix_device); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d2ef357e1..4b5f82f5d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -117,11 +117,12 @@ const machine_filter_t machine_chipsets[] = { { "ALi ALADDiN IV+", MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS }, { "ALi ALADDiN V", MACHINE_CHIPSET_ALI_ALADDIN_V }, { "ALi ALADDiN-PRO II", MACHINE_CHIPSET_ALI_ALADDIN_PRO_II }, + { "C&T PC/AT", MACHINE_CHIPSET_CT_AT }, + { "C&T 386/AT", MACHINE_CHIPSET_CT_386 }, { "C&T 82C235 SCAT", MACHINE_CHIPSET_SCAT }, { "C&T 82C236 SCATsx", MACHINE_CHIPSET_SCAT_SX }, { "C&T CS8221 NEAT", MACHINE_CHIPSET_NEAT }, { "C&T CS8281 NEATsx", MACHINE_CHIPSET_NEAT_SX }, - { "C&T 386", MACHINE_CHIPSET_CT_386 }, { "C&T CS4031", MACHINE_CHIPSET_CT_CS4031 }, { "Contaq 82C596", MACHINE_CHIPSET_CONTAQ_82C596 }, { "Contaq 82C597", MACHINE_CHIPSET_CONTAQ_82C597 }, @@ -2975,47 +2976,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC - firmware. */ - { - .name = "[ISA] Dell System 200", - .internal_name = "dells200", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_dells200_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 12000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 640, - .max = 16384, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has IBM AT KBC firmware. */ { .name = "[ISA] MR BIOS 286 clone", @@ -3460,6 +3420,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[C&T PC/AT] Dell System 200", + .internal_name = "dells200", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .init = machine_at_dells200_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 6000000, + .max_bus = 12000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has Quadtel KBC firmware. */ { .name = "[GC103] Quadtel 286 clone", @@ -5280,7 +5281,7 @@ const machine_t machines[] = { }, /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ { - .name = "[C&T 386] ECS 386/32", + .name = "[C&T 386/AT] ECS 386/32", .internal_name = "ecs386", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_CT_386, @@ -5320,7 +5321,7 @@ const machine_t machines[] = { }, /* Has IBM AT KBC firmware. */ { - .name = "[C&T 386] Samsung SPC-6000A", + .name = "[C&T 386/AT] Samsung SPC-6000A", .internal_name = "spc6000a", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_CT_386, From 83224dcadefa4cb3b3a99779e47c5ea35f3e27c4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 04:20:25 +0200 Subject: [PATCH 07/22] Bring the AN430TX out of the Dev branch in form of the Packard Bell PB790. --- CMakeLists.txt | 1 - src/chipset/intel_4x0.c | 13 +++-- src/machine/CMakeLists.txt | 8 --- src/machine/m_at_socket7.c | 30 +++++------- src/machine/machine_table.c | 97 +++++++++++++++++++------------------ 5 files changed, 71 insertions(+), 78 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b78295fd..3ad83fb4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,6 @@ endif() # Option Description Def. Condition Otherwise # ------ ----------- ---- ------------ --------- cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) -cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF) cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF) cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF) cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 84bd872f8..8e6ce97c3 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1013,7 +1013,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: if (!dev->smram_locked) { i4x0_smram_handler_phase0(dev); - regs[0x71] = (regs[0x71] & 0x20) | (val & 0xdf); + regs[0x71] = (regs[0x71] & 0x60) | (val & 0x9f); + regs[0x71] &= (val & 0x40); i4x0_smram_handler_phase1(dev); } break; @@ -1041,9 +1042,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x72] = (val & 0x7f); else regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78); - dev->smram_locked = (val & 0x10); - if (dev->smram_locked) - regs[0x72] &= 0xbf; + if (val & 0x08) { + dev->smram_locked = (val & 0x10); + if (dev->smram_locked) + regs[0x72] &= 0xbf; + } } } else { if (dev->smram_locked) @@ -1577,6 +1580,8 @@ i4x0_reset(void *priv) dev->regs[0x68 + i] = 0x00; } + dev->smram_locked = 0; + if (dev->type >= INTEL_430FX) { dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x02, priv); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 4098f2553..20d60c075 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -57,14 +57,6 @@ add_library(mch OBJECT m_at_misc.c ) -if(AN430TX) - target_compile_definitions(mch PRIVATE USE_AN430TX) -endif() - -if(DESKPRO386) - target_compile_definitions(mch PRIVATE USE_DESKPRO386) -endif() - if(OLIVETTI) target_compile_definitions(mch PRIVATE USE_OLIVETTI) endif() diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7d2441e18..d4b71f92f 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1007,27 +1007,17 @@ machine_at_optiplex_gn_init(const machine_t *model) return ret; } -#ifdef USE_AN430TX int machine_at_an430tx_init(const machine_t *model) { int ret; -# if 1 - ret = bios_load_linear_combined2("roms/machines/an430tx/P10-0095.BIO", - "roms/machines/an430tx/P10-0095.BI1", - "roms/machines/an430tx/P10-0095.BI2", - "roms/machines/an430tx/P10-0095.BI3", - "roms/machines/an430tx/P10-0095.RCV", + ret = bios_load_linear_combined2("roms/machines/an430tx/ANP0911A.BIO", + "roms/machines/an430tx/ANP0911A.BI1", + "roms/machines/an430tx/ANP0911A.BI2", + "roms/machines/an430tx/ANP0911A.BI3", + "roms/machines/an430tx/ANP0911A.RCV", 0x3a000, 160); -# else - ret = bios_load_linear_combined2("roms/machines/an430tx/P06-0062.BIO", - "roms/machines/an430tx/P06-0062.BI1", - "roms/machines/an430tx/P06-0062.BI2", - "roms/machines/an430tx/P06-0062.BI3", - "roms/machines/an430tx/P10-0095.RCV", - 0x3a000, 160); -# endif if (bios_only || !ret) return ret; @@ -1036,21 +1026,25 @@ machine_at_an430tx_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ - // pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); device_add(&i430tx_device); device_add(&piix4_device); +#ifdef FOLLOW_THE_SPECIFICATION device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42I | PCX7307_PC97307)); +#else + /* The technical specification says Phoenix, a real machnine HWINFO dump says AMI '5'. */ + device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC97307)); +#endif device_add(&intel_flash_bxt_ami_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } -#endif /* USE_AN430TX */ int machine_at_ym430tx_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4b5f82f5d..add0c2b7c 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -13275,49 +13275,6 @@ const machine_t machines[] = { .snd_device = &cs4236b_device, .net_device = &pcnet_am79c973_onboard_device }, -#ifdef USE_AN430TX - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i430TX] Intel AN430TX (Anchorage)", - .internal_name = "an430tx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_an430tx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#endif /* USE_AN430TX */ /* This has the AMIKey KBC firmware, which is an updated 'F' type. */ { .name = "[i430TX] Intel YM430TX (Yamamoto)", @@ -13359,9 +13316,13 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* PhoenixBIOS 4.0 Rel 6.0 for 430TX, has onboard Yamaha YMF701 which is not emulated yet. */ - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ + /* + PhoenixBIOS 4.0 Rel 6.0 for 430TX, has onboard Yamaha YMF701 which + is not emulated yet. + + Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. + */ { .name = "[i430TX] Micronics Thunderbolt", .internal_name = "thunderbolt", @@ -13383,7 +13344,8 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701-S */ + /* Machine has internal sound: Yamaha YMF701-S */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -13442,6 +13404,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i430TX] Packard Bell PB790", + .internal_name = "an430tx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_an430tx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { From 265b69c7eaef196c9a98683beb73ec2772798ca1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 04:34:00 +0200 Subject: [PATCH 08/22] And machine.h - this should fix compile. --- src/include/86box/machine.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 137880a11..320847e7b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -756,11 +756,9 @@ extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); extern int machine_at_tx97_init(const machine_t *); extern int machine_at_optiplex_gn_init(const machine_t *); -#ifdef USE_AN430TX -extern int machine_at_an430tx_init(const machine_t *); -#endif /* USE_AN430TX */ extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_thunderbolt_init(const machine_t *); +extern int machine_at_an430tx_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); From 76e9a20e12975d1cfd9bcf3b01b29b216cecf966 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 05:51:40 +0200 Subject: [PATCH 09/22] Bring the Olivetti M290 out of the Dev branch. --- CMakeLists.txt | 1 - src/chipset/CMakeLists.txt | 5 +---- src/chipset/olivetti_eva.c | 27 +++++++++------------------ src/include/86box/machine.h | 2 -- src/machine/CMakeLists.txt | 4 ---- src/machine/m_at_286_386sx.c | 10 +++++----- src/machine/machine_table.c | 2 -- 7 files changed, 15 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ad83fb4a..161394778 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,6 @@ cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF) diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 7a8233003..7817ac052 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -43,6 +43,7 @@ add_library(chipset OBJECT isa486c.c ../ioapic.c neat.c + olivetti_eva.c opti283.c opti291.c opti391.c @@ -86,7 +87,3 @@ add_library(chipset OBJECT vl82c480.c wd76c10.c ) - -if(OLIVETTI) - target_sources(chipset PRIVATE olivetti_eva.c) -endif() diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c index 7defac6ae..0dcbdd21f 100644 --- a/src/chipset/olivetti_eva.c +++ b/src/chipset/olivetti_eva.c @@ -73,26 +73,24 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv) break; case 0x069: dev->reg_069 = val; - /* - * Unfortunately, if triggered, the BIOS remapping function fails causing - * a fatal error. Therefore, this code section is currently commented. - */ -#if 0 - if (val & 1) { + mem_remap_top(0); + if (val == 0x01) { /* * Set the register to 7 or above for the BIOS to trigger the * memory remapping function if shadowing is active. */ - dev->reg_069 = 0x7; + dev->reg_069 = 0x07; } - if (val & 8) { + if (val & 0x08) { /* * Activate shadowing for region e0000-fffff */ mem_remap_top(256); - mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + mem_remap_top(384); + mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); } -#endif break; default: break; @@ -143,7 +141,7 @@ olivetti_eva_init(UNUSED(const device_t *info)) dev->reg_067 = 0x00; /* RAM enable registers */ - dev->reg_069 = 0x0; + dev->reg_069 = 0x00; io_sethandler(0x0065, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); io_sethandler(0x0067, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); @@ -152,13 +150,6 @@ olivetti_eva_init(UNUSED(const device_t *info)) /* When shadowing is not enabled in BIOS, all upper memory is available as XMS */ mem_remap_top(384); - /* - * Default settings when NVRAM is cleared activate shadowing. - * Thus, to avoid boot errors, remap only 256k from UMB to XMS. - * Remove this block once BIOS memory remapping works. - */ - mem_remap_top(256); - return dev; } diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 320847e7b..d6725ec9a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -481,9 +481,7 @@ extern int machine_at_dells200_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_3302_init(const machine_t *); -#ifdef USE_OLIVETTI extern int machine_at_m290_init(const machine_t *); -#endif /* USE_OLIVETTI */ extern int machine_at_shuttle386sx_init(const machine_t *); extern int machine_at_adi386sx_init(const machine_t *); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 20d60c075..2e3bc02bc 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -57,10 +57,6 @@ add_library(mch OBJECT m_at_misc.c ) -if(OLIVETTI) - target_compile_definitions(mch PRIVATE USE_OLIVETTI) -endif() - if(OPEN_AT) target_compile_definitions(mch PRIVATE USE_OPEN_AT) endif() diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 2b181c499..853829ccc 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -1069,7 +1069,6 @@ machine_at_pc916sx_init(const machine_t *model) return ret; } -#ifdef USE_OLIVETTI int machine_at_m290_init(const machine_t *model) { @@ -1081,15 +1080,16 @@ machine_at_m290_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 4); - device_add(&keyboard_at_olivetti_device); + machine_at_common_init_ex(model, 6); + device_add(&amstrad_megapc_nvr_device); + + device_add(&olivetti_eva_device); device_add(&port_6x_olivetti_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&olivetti_eva_device); + device_add(&keyboard_at_olivetti_device); return ret; } -#endif /* USE_OLIVETTI */ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index add0c2b7c..8cdc7444b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3096,7 +3096,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#ifdef USE_OLIVETTI /* Has Olivetti KBC firmware. */ { .name = "[ISA] Olivetti M290", @@ -3137,7 +3136,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* USE_OLIVETTI */ #ifdef USE_OPEN_AT /* Has IBM AT KBC firmware. */ { From 6426c375ee7acba5d1dc3b90f88675fe9416677d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 06:45:18 +0200 Subject: [PATCH 10/22] And chipset.h. --- src/include/86box/chipset.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index e11af5e4d..e0e775fa1 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -113,6 +113,9 @@ extern const device_t slc90e66_device; extern const device_t ioapic_device; +/* Olivetti */ +extern const device_t olivetti_eva_device; + /* OPTi */ extern const device_t opti283_device; extern const device_t opti291_device; @@ -204,8 +207,4 @@ extern const device_t nec_mate_unk_device; extern const device_t phoenix_486_jumper_device; extern const device_t phoenix_486_jumper_pci_device; - -#ifdef USE_OLIVETTI -extern const device_t olivetti_eva_device; -#endif /* USE_OLIVETTI */ #endif /*EMU_CHIPSET_H*/ From d49a71ee6e7841378b1b9a69105805e9f7b8f55d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 09:48:53 +0200 Subject: [PATCH 11/22] Remove the GUS Max from the Dev branch. --- CMakeLists.txt | 1 - src/include/86box/sound.h | 1 + src/sound/CMakeLists.txt | 4 --- src/sound/snd_gus.c | 69 ++++++++++++--------------------------- src/sound/sound.c | 1 + 5 files changed, 23 insertions(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 161394778..a632b71ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,7 +175,6 @@ endif() cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF) cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF) -cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index b2e202ddb..985abe777 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -197,6 +197,7 @@ extern const device_t ct5880_onboard_device; /* Gravis UltraSound and UltraSound Max */ extern const device_t gus_device; +extern const device_t gus_max_device; /* IBM PS/1 Audio Card */ extern const device_t ps1snd_device; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index fb3c9b43d..66a0ee4e3 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -185,10 +185,6 @@ target_link_libraries(86Box esfmu) add_subdirectory(ymfm) target_link_libraries(86Box ymfm) -if(GUSMAX) - target_compile_definitions(snd PRIVATE USE_GUSMAX) -endif() - if(OPL4ML) target_compile_definitions(snd PRIVATE USE_OPL4ML) target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 1885581a5..fff679e81 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -17,9 +17,7 @@ #include <86box/sound.h> #include "cpu.h" #include <86box/timer.h> -#ifdef USE_GUSMAX -# include <86box/snd_ad1848.h> -#endif /*USE_GUSMAX */ +#include <86box/snd_ad1848.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -145,11 +143,9 @@ typedef struct gus_t { uint8_t usrr; -#ifdef USE_GUSMAX uint8_t max_ctrl; ad1848_t ad1848; -#endif /*USE_GUSMAX */ } gus_t; static int gus_gf1_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; @@ -257,9 +253,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) int d; int old; uint16_t port; -#ifdef USE_GUSMAX uint16_t csioport; -#endif /*USE_GUSMAX */ if ((addr == 0x388) || (addr == 0x389)) port = addr; @@ -607,10 +601,9 @@ writegus(uint16_t addr, uint8_t val, void *priv) gus->irq_midi = gus->irq; } else gus->irq_midi = gus_midi_irqs[(val >> 3) & 7]; -#ifdef USE_GUSMAX + if (gus->type == GUS_MAX) ad1848_setirq(&gus->ad1848, gus->irq); -#endif /*USE_GUSMAX */ gus->sb_nmi = val & 0x80; } else { @@ -623,10 +616,9 @@ writegus(uint16_t addr, uint8_t val, void *priv) gus->dma2 = gus->dma; } else gus->dma2 = gus_dmas[(val >> 3) & 7]; -#ifdef USE_GUSMAX + if (gus->type == GUS_MAX) ad1848_setdma(&gus->ad1848, gus->dma2); -#endif /*USE_GUSMAX */ } break; case 1: @@ -684,7 +676,6 @@ writegus(uint16_t addr, uint8_t val, void *priv) break; case 0x306: case 0x706: -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) { if (gus->dma >= 4) val |= 0x10; @@ -704,7 +695,6 @@ writegus(uint16_t addr, uint8_t val, void *priv) } } } -#endif /*USE_GUSMAX */ break; default: @@ -756,11 +746,9 @@ readgus(uint16_t addr, void *priv) return val; case 0x20F: -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) val = 0x02; else -#endif /*USE_GUSMAX */ val = 0x00; break; @@ -879,11 +867,9 @@ readgus(uint16_t addr, void *priv) break; case 0x306: case 0x706: -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) val = 0x0a; /* GUS MAX */ else -#endif /*USE_GUSMAX */ val = 0xff; /*Pre 3.7 - no mixer*/ break; @@ -1183,24 +1169,20 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) { gus_t *gus = (gus_t *) priv; -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_update(&gus->ad1848); -#endif /*USE_GUSMAX */ + gus_update(gus); for (int c = 0; c < len * 2; c++) { -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); -#endif /*USE_GUSMAX */ buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; } -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) gus->ad1848.pos = 0; -#endif /*USE_GUSMAX */ + gus->pos = 0; } @@ -1333,9 +1315,7 @@ gus_reset(void *priv) gus->usrr = 0; -#ifdef USE_GUSMAX gus->max_ctrl = 0; -#endif /*USE_GUSMAX */ gus->irq_state = 0; gus->midi_irq_state = 0; @@ -1373,7 +1353,7 @@ gus_init(UNUSED(const device_t *info)) gus->uart_out = 1; - gus->type = device_get_config_int("type"); + gus->type = info->local; gus->base = device_get_config_hex16("base"); @@ -1382,7 +1362,6 @@ gus_init(UNUSED(const device_t *info)) io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); ad1848_setirq(&gus->ad1848, 5); @@ -1390,7 +1369,6 @@ gus_init(UNUSED(const device_t *info)) io_sethandler(0x10C + gus->base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848); } -#endif /*USE_GUSMAX */ timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); @@ -1423,31 +1401,12 @@ gus_speed_changed(void *priv) else gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_speed_changed(&gus->ad1848); -#endif /*USE_GUSMAX */ } static const device_config_t gus_config[] = { // clang-format off - { - .name = "type", - .description = "GUS type", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "Classic", .value = GUS_CLASSIC }, -#ifdef USE_GUSMAX - { .description = "MAX", .value = GUS_MAX }, -#endif /*USE_GUSMAX */ - { NULL } - }, - .bios = { { 0 } } - }, { .name = "base", .description = "Address", @@ -1502,7 +1461,21 @@ const device_t gus_device = { .name = "Gravis UltraSound", .internal_name = "gus", .flags = DEVICE_ISA16, - .local = 0, + .local = GUS_CLASSIC, + .init = gus_init, + .close = gus_close, + .reset = gus_reset, + .available = NULL, + .speed_changed = gus_speed_changed, + .force_redraw = NULL, + .config = gus_config +}; + +const device_t gus_max_device = { + .name = "Gravis UltraSound MAX", + .internal_name = "gus", + .flags = DEVICE_ISA16, + .local = GUS_MAX, .init = gus_init, .close = gus_close, .reset = gus_reset, diff --git a/src/sound/sound.c b/src/sound/sound.c index c3ecc8632..7bf27a136 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -115,6 +115,7 @@ static const SOUND_CARD sound_cards[] = { { &ess_ess0102_pnp_device }, { &ess_ess0968_pnp_device }, { &gus_device }, + { &gus_max_device }, { &sb_1_device }, { &sb_15_device }, { &sb_2_device }, From e9c7795c7a06ddbe2e3197685cce375d40be42d7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 09:51:08 +0200 Subject: [PATCH 12/22] Remove the OpenAT entirely - its BIOS never rearched any sort of actually usable state (and is also not actually Open, just visible source). --- CMakeLists.txt | 1 - src/include/86box/machine.h | 3 --- src/machine/CMakeLists.txt | 4 --- src/machine/m_at.c | 18 ------------- src/machine/machine_table.c | 51 ++----------------------------------- 5 files changed, 2 insertions(+), 75 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a632b71ce..777ede9ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,7 +178,6 @@ cmake_dependent_option(G100 "Matrox Productiva G100" cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d6725ec9a..98667f244 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -448,9 +448,6 @@ extern int machine_at_pb286_init(const machine_t *); extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places extern int machine_at_wellamerastar_init(const machine_t *); // Wells American A*Star with custom award BIOS -#ifdef USE_OPEN_AT -extern int machine_at_openat_init(const machine_t *); -#endif /* USE_OPEN_AT */ /* m_at_286_386sx.c */ extern int machine_at_tg286m_init(const machine_t *); diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 2e3bc02bc..8cd54edec 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -56,7 +56,3 @@ add_library(mch OBJECT m_at_socket370.c m_at_misc.c ) - -if(OPEN_AT) - target_compile_definitions(mch PRIVATE USE_OPEN_AT) -endif() diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 86fbe3776..13cd831ba 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -388,21 +388,3 @@ machine_at_wellamerastar_init(const machine_t *model) return ret; } - -#ifdef USE_OPEN_AT -int -machine_at_openat_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/openat/bios.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ibm_common_init(model); - - return ret; -} -#endif /* USE_OPEN_AT */ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8cdc7444b..408deb615 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8,17 +8,12 @@ * * Handling of the emulated machines. * - * NOTES: OpenAT wip for 286-class machine with open BIOS. - * PS2_M80-486 wip, pending receipt of TRM's for machine. - * - * - * * Authors: Miran Grca, * Fred N. van Kempen, * Jasmine Iwanek, * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2025 Miran Grca. + * Copyright 2017-2025 Fred N. van Kempen. * Copyright 2025 Jasmine Iwanek. */ #include @@ -3136,48 +3131,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#ifdef USE_OPEN_AT - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] OpenAT", - .internal_name = "openat", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_openat_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 256, - .max = 15872, - .step = 128 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#endif /* USE_OPEN_AT */ /* Has IBM AT KBC firmware. */ { .name = "[ISA] Phoenix IBM AT", From 802355e982d1995e6fa2a0a34ad3b48c98f226ca Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 12:57:07 -0300 Subject: [PATCH 13/22] Add proper on-board CS4235 to delhi3 --- src/machine/machine_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 408deb615..780f8d474 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4456,7 +4456,7 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[ALI M1409] Acer 100T", + .name = "[ALi M1409] Acer 100T", .internal_name = "acer100t", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1409, @@ -14420,7 +14420,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = &cs4235_device, + .snd_device = &cs4235_onboard_device, .net_device = NULL }, From d3cc0df2bb5f99f7f6862840aab13f3e5484fa29 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 13:20:34 -0300 Subject: [PATCH 14/22] CS423x: Remove delhi3 PnP disable command hack as it's no longer required (there's a clean nvr issue elsewhere) --- src/sound/snd_cs423x.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 17ea48dd3..74382a53b 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -650,15 +650,7 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], dev->pnp_size); /* Disable PnP key if the PKD bit is set, or if it was disabled by command 0x55. */ - /* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't - line up with real hardware (still listed in the POST summary and seen by software). - Disable the PnP key disabling mechanism until someone figures something out. */ -#if 0 isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE); -#else - if ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) - pclog("CS423x: Attempted to disable PnP key\n"); -#endif } /* Update some register bits based on the config data in RAM if requested. */ From 9ebcc443508eede6fd572379f49e2f3c627ae13b Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 May 2025 19:41:27 +0200 Subject: [PATCH 15/22] Add the Dell System 333s/L. --- src/chipset/scamp.c | 2 +- src/device/kbc_at.c | 13 +++++-- src/device/postcard.c | 8 +++-- src/include/86box/machine.h | 1 + src/include/86box/video.h | 1 + src/machine/m_at_286_386sx.c | 70 ++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 42 ++++++++++++++++++++++ src/sio/sio_detect.c | 7 ++-- src/video/vid_cl54xx.c | 19 +++++++++- 9 files changed, 152 insertions(+), 11 deletions(-) diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 8e7892c2e..855175dcd 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -1177,7 +1177,7 @@ scamp_init(UNUSED(const device_t *info)) dev->mem_flags[i] = MEM_FLAG_READ | MEM_FLAG_WRITE; scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_RW); - if (i >= 60) + if (i >= 56) scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); } } diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 8840a0e4d..dd2d5a636 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -1079,7 +1079,14 @@ write_cmd_generic(void *priv, uint8_t val) /* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */ if ((kbc_ven == KBC_VEN_AMI) && ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_GREEN)) fixed_bits |= 0x40; - if (kbc_ven == KBC_VEN_IBM_PS1) { + if (!strcmp(machine_get_internal_name(), "dells333sl")) { + /* + Dell System 333s/L: + - Bit 5: Stuck in reboot loop if clear. + */ + uint8_t p1 = 0x20 | (video_is_mda() ? 0x40 : 0x00); + kbc_delay_to_ob(dev, p1, 0, 0x00); + } else if (kbc_ven == KBC_VEN_IBM_PS1) { current_drive = fdc_get_current_drive(); /* (B0 or F0) | (fdd_is_525(current_drive) on bit 6) */ kbc_delay_to_ob(dev, dev->p1 | fixed_bits | (fdd_is_525(current_drive) ? 0x40 : 0x00), @@ -1114,7 +1121,7 @@ write_cmd_generic(void *priv, uint8_t val) Dell 466/NP: - Bit 2: Keyboard fuse (must be set); - Bit 4: Password disable jumper (must be clear); - - Bit 5: Manufacturing jumper (must be set); + - Bit 5: Manufacturing jumper (must be set). */ uint8_t p1 = 0x24; kbc_delay_to_ob(dev, p1, 0, 0x00); @@ -1123,7 +1130,7 @@ write_cmd_generic(void *priv, uint8_t val) Dell OptiPlex GXL/GXM: - Bit 3: Password disable jumper (must be clear); - Bit 4: Keyboard fuse (must be set); - - Bit 5: Manufacturing jumper (must be set); + - Bit 5: Manufacturing jumper (must be set). */ uint8_t p1 = 0x30; kbc_delay_to_ob(dev, p1, 0, 0x00); diff --git a/src/device/postcard.c b/src/device/postcard.c index 19d81b692..27f5a5aa3 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -100,7 +100,8 @@ postcard_setui(void) break; } } else if (strstr(machines[machine].name, " Dell ") && - (machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX)) { + ((machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX) || + (machine_get_chipset(machine) >= MACHINE_CHIPSET_VLSI_SCAMP))) { char dell_diags[10] = { 0 }; if (!postcard_written[1]) @@ -225,8 +226,9 @@ postcard_init(UNUSED(const device_t *info)) NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); if (strstr(machines[machine].name, " Dell ") && - (machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX)) - io_sethandler(0x00e0, 0x0001, + ((machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX) || + (machine_get_chipset(machine) >= MACHINE_CHIPSET_VLSI_SCAMP))) + io_sethandler(is486 ? 0x00e0 : 0x00e4, 0x0001, NULL, NULL, NULL, NULL, NULL, postcard_writel, NULL); return postcard_write; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 98667f244..d4d5e8618 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -485,6 +485,7 @@ extern int machine_at_adi386sx_init(const machine_t *); extern int machine_at_cmdsl386sx16_init(const machine_t *); extern int machine_at_cmdsl386sx25_init(const machine_t *); extern int machine_at_dataexpert386sx_init(const machine_t *); +extern int machine_at_dells333sl_init(const machine_t *); extern int machine_at_if386sx_init(const machine_t *); extern int machine_at_spc6033p_init(const machine_t *); extern int machine_at_wd76c10_init(const machine_t *); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 6a73c6462..bd3101d84 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -356,6 +356,7 @@ extern const device_t gd5401_isa_device; extern const device_t gd5402_isa_device; extern const device_t gd5402_onboard_device; extern const device_t gd5420_isa_device; +extern const device_t gd5420_onboard_device; extern const device_t gd5422_isa_device; extern const device_t gd5424_vlb_device; extern const device_t gd5426_isa_device; diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 853829ccc..6ac5b0195 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -37,6 +37,7 @@ #include <86box/hdc.h> #include <86box/nvr.h> #include <86box/port_6x.h> +#define USE_SIO_DETECT #include <86box/sio.h> #include <86box/serial.h> #include <86box/video.h> @@ -760,6 +761,75 @@ machine_at_cmdsl386sx25_init(const machine_t *model) return ret; } +static const device_config_t dells333sl_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "dells333sl", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "J01 (Jostens Learning Corporation OEM)", .internal_name = "dells333sl_j01", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/DELL386.BIN", "" } }, + { .name = "A02", .internal_name = "dells333sl", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/Dell_386SX_30807_UBIOS_B400_VLSI_VL82C311_Cirrus_Logic_GD5420.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t dells333sl_device = { + .name = "Dell System 333s/L", + .internal_name = "dells333sl_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dells333sl_config +}; + +int +machine_at_dells333sl_init(const machine_t *model) +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 262144, 0); + memcpy(rom, &(rom[0x00020000]), 131072); + mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); + mem_mapping_set_exec(&bios_mapping, rom); + device_context_restore(); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + machine_at_common_init_ex(model, 2); + + device_add(&ide_isa_device); + + device_add(&pc87311_device); + device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */ + + device_add(&vlsi_scamp_device); + + return ret; +} + int machine_at_dataexpert386sx_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 408deb615..e18581082 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -66,6 +66,7 @@ extern const device_t vendex_device; extern const device_t c5sbm2_device; extern const device_t sb486pv_device; extern const device_t ap5s_device; +extern const device_t dells333sl_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, @@ -4942,6 +4943,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[SCAMP] Dell System 333s/L", + .internal_name = "dells333sl", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_VLSI_SCAMP, + .init = machine_at_dells333sl_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 10000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &dells333sl_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5420_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, /* Has IBM PS/2 Type 1 KBC firmware. */ { .name = "[SCAMP] Samsung SPC-6033P", diff --git a/src/sio/sio_detect.c b/src/sio/sio_detect.c index ffa0ec9d0..d36522fe0 100644 --- a/src/sio/sio_detect.c +++ b/src/sio/sio_detect.c @@ -47,11 +47,12 @@ sio_detect_write(uint16_t port, uint8_t val, void *priv) static uint8_t sio_detect_read(uint16_t port, void *priv) { - const sio_detect_t *dev = (sio_detect_t *) priv; + /*const sio_detect_t *dev = (sio_detect_t *) priv*/; + uint8_t ret = 0xff /*dev->regs[port & 1]*/; - pclog("sio_detect_read : port=%04x = %02X\n", port, dev->regs[port & 1]); + pclog("sio_detect_read : port=%04x = %02X\n", port, ret); - return 0xff /*dev->regs[port & 1]*/; + return ret; } static void diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 13f96501c..0d02c10c3 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -4247,7 +4247,10 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5420: - romfn = BIOS_GD5420_PATH; + if (info->local & 0x200) + romfn = NULL; + else + romfn = BIOS_GD5420_PATH; break; case CIRRUS_ID_CLGD5422: @@ -4978,6 +4981,20 @@ const device_t gd5420_isa_device = { .config = gd542x_config, }; +const device_t gd5420_onboard_device = { + .name = "Cirrus Logic GD5420 (ISA)", + .internal_name = "cl_gd5420_isa", + .flags = DEVICE_ISA16, + .local = CIRRUS_ID_CLGD5420 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + .available = NULL, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config, +}; + const device_t gd5422_isa_device = { .name = "Cirrus Logic GD5422 (ISA)", .internal_name = "cl_gd5422_isa", From 30324bb859a60e76fec7cebfcb7af302674391bd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 15:13:52 -0300 Subject: [PATCH 16/22] Add internal PCI flag to STPC SBCs without PCI slots --- src/machine/machine_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 780f8d474..52c483ff5 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9422,7 +9422,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ST STPC Atlas */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -9463,7 +9463,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ .ram = { .min = 32768, .max = 163840, @@ -9504,7 +9504,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ + .flags = MACHINE_IDE | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ .ram = { .min = 32768, .max = 131072, @@ -9545,7 +9545,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, .ram = { .min = 32768, .max = 98304, @@ -9586,7 +9586,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, .ram = { .min = 32768, .max = 131072, From 81af1f8195361cf8b7bcc5a8813076dda9f9d7f0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 15:35:43 -0300 Subject: [PATCH 17/22] De-underscore the ASUS 386/33-64K --- src/include/86box/machine.h | 2 +- src/machine/m_at_386dx_486.c | 4 ++-- src/machine/machine_table.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 98667f244..53b47c4c1 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -512,7 +512,7 @@ extern int machine_at_ga486l_init(const machine_t *); extern int machine_at_cougar_init(const machine_t *); extern int machine_at_acc386_init(const machine_t *); -extern int machine_at_asus386_3364k_init(const machine_t *); +extern int machine_at_asus3863364k_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 9f7534244..b81a6bda7 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -73,11 +73,11 @@ machine_at_acc386_init(const machine_t *model) } int -machine_at_asus386_3364k_init(const machine_t *model) +machine_at_asus3863364k_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/asus386_3364k/am27c512dip28-64b53c26be3d8160533563.bin", + ret = bios_load_linear("roms/machines/asus3863364k/am27c512dip28-64b53c26be3d8160533563.bin", 0x000f0000, 65536, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 52c483ff5..63d19c8c6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5671,10 +5671,10 @@ const machine_t machines[] = { /* Has Award KBC firmware. */ { .name = "[SiS 310] ASUS 386/33-64K", - .internal_name = "asus386_3364k", + .internal_name = "asus3863364k", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_SIS_310, - .init = machine_at_asus386_3364k_init, + .init = machine_at_asus3863364k_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From 4a3eb800828e2ce176cc446be97563f84ea4556c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 15:36:53 -0300 Subject: [PATCH 18/22] De-underscore the Dell OptiPlex machines --- src/include/86box/machine.h | 6 +++--- src/machine/m_at_slot1.c | 4 ++-- src/machine/m_at_socket5.c | 4 ++-- src/machine/m_at_socket7.c | 4 ++-- src/machine/machine_table.c | 12 ++++++------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 53b47c4c1..155e6aecc 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -670,7 +670,7 @@ extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); extern int machine_at_apollo_init(const machine_t *); -extern int machine_at_optiplex_gxl_init(const machine_t *); +extern int machine_at_optiplexgxl_init(const machine_t *); extern int machine_at_zappa_init(const machine_t *); extern int machine_at_powermatev_init(const machine_t *); extern int machine_at_hawk_init(const machine_t *); @@ -750,7 +750,7 @@ extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); extern int machine_at_tx97_init(const machine_t *); -extern int machine_at_optiplex_gn_init(const machine_t *); +extern int machine_at_optiplexgn_init(const machine_t *); extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_thunderbolt_init(const machine_t *); extern int machine_at_an430tx_init(const machine_t *); @@ -819,7 +819,7 @@ extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); -extern int machine_at_optiplex_gxa_init(const machine_t *); +extern int machine_at_optiplexgxa_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); extern int machine_at_ma30d_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a147d0e13..280462858 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -151,11 +151,11 @@ machine_at_lx6_init(const machine_t *model) } int -machine_at_optiplex_gxa_init(const machine_t *model) +machine_at_optiplexgxa_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/optiplex_gxa/DELL.ROM", + ret = bios_load_linear("roms/machines/optiplexgxa/DELL.ROM", 0x000c0000, 262144, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 442281811..0d50fead8 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -238,11 +238,11 @@ machine_at_apollo_init(const machine_t *model) } int -machine_at_optiplex_gxl_init(const machine_t *model) +machine_at_optiplexgxl_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/optiplex_gxl/DELL.ROM", + ret = bios_load_linear("roms/machines/optiplexgxl/DELL.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index d4b71f92f..dbc59ef17 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -970,11 +970,11 @@ machine_at_tx97_init(const machine_t *model) } int -machine_at_optiplex_gn_init(const machine_t *model) +machine_at_optiplexgn_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/optiplex_gn/DELL.ROM", + ret = bios_load_linear("roms/machines/optiplexgn/DELL.ROM", 0x000c0000, 262144, 0); if (bios_only || !ret) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 63d19c8c6..4c6d90cea 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -10549,10 +10549,10 @@ const machine_t machines[] = { /* Has a National Semiconductor PC87332VLJ Super I/O with AMIKey 'F' KBC firmware. */ { .name = "[i430FX] Dell OptiPlex GXL/GXM", - .internal_name = "optiplex_gxl", + .internal_name = "optiplexgxl", .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_optiplex_gxl_init, + .init = machine_at_optiplexgxl_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -13147,10 +13147,10 @@ const machine_t machines[] = { */ { .name = "[i430TX] Dell OptiPlex GN+", - .internal_name = "optiplex_gn", + .internal_name = "optiplexgn", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_optiplex_gn_init, + .init = machine_at_optiplexgn_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -15210,10 +15210,10 @@ const machine_t machines[] = { firmwares: AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix MultiKey/42i 4.16. */ { .name = "[i440LX] Dell OptiPlex GXa", - .internal_name = "optiplex_gxa", + .internal_name = "optiplexgxa", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_optiplex_gxa_init, + .init = machine_at_optiplexgxa_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From 72a52318f56e274d6f66553d1a872604d07bed20 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 16:08:44 -0300 Subject: [PATCH 19/22] POST card: Streamline printing of the Dell ASCII mode --- src/device/postcard.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/device/postcard.c b/src/device/postcard.c index 27f5a5aa3..ec031c2b8 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -36,6 +36,7 @@ static uint16_t postcard_port; static uint8_t postcard_written[POSTCARDS_NUM]; static uint8_t postcard_ports_num = 1; static uint8_t postcard_prev_codes[POSTCARDS_NUM]; +static uint8_t postcard_dell_mode = 0; static char postcard_prev_diags[5] = { 0 }; #define UISTR_LEN 32 static char postcard_str[UISTR_LEN]; /* UI output string */ @@ -99,31 +100,23 @@ postcard_setui(void) ps[1][0], ps[1][1], ps[1][2], ps[1][3]); break; } - } else if (strstr(machines[machine].name, " Dell ") && - ((machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX) || - (machine_get_chipset(machine) >= MACHINE_CHIPSET_VLSI_SCAMP))) { - char dell_diags[10] = { 0 }; - - if (!postcard_written[1]) - snprintf(dell_diags, sizeof(dell_diags), "---- ----"); - else if (postcard_written[1] == 1) - snprintf(dell_diags, sizeof(dell_diags), "%s ----", postcard_diags); - else - snprintf(dell_diags, sizeof(dell_diags), "%s %s", postcard_diags, postcard_prev_diags); - - if (!postcard_written[0]) - snprintf(postcard_str, sizeof(postcard_str), "POST: -- -- %s", dell_diags); - else if (postcard_written[0] == 1) - snprintf(postcard_str, sizeof(postcard_str), "POST: %02X -- %s", postcard_codes[0], dell_diags); - else - snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X %s", postcard_codes[0], postcard_prev_codes[0], dell_diags); } else { + char dell_diags[11] = { 0 }; + if (postcard_dell_mode) { + if (!postcard_written[1]) + snprintf(dell_diags, sizeof(dell_diags), " ---- ----"); + else if (postcard_written[1] == 1) + snprintf(dell_diags, sizeof(dell_diags), " %s ----", postcard_diags); + else + snprintf(dell_diags, sizeof(dell_diags), " %s %s", postcard_diags, postcard_prev_diags); + } + if (!postcard_written[0]) - snprintf(postcard_str, sizeof(postcard_str), "POST: -- --"); + snprintf(postcard_str, sizeof(postcard_str), "POST: -- --%s", dell_diags); else if (postcard_written[0] == 1) - snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --", postcard_codes[0]); + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --%s", postcard_codes[0], dell_diags); else - snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]); + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X%s", postcard_codes[0], postcard_prev_codes[0], dell_diags); } ui_sb_bugui(postcard_str); @@ -225,9 +218,9 @@ postcard_init(UNUSED(const device_t *info)) io_sethandler(postcard_port, postcard_ports_num, NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); - if (strstr(machines[machine].name, " Dell ") && - ((machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX) || - (machine_get_chipset(machine) >= MACHINE_CHIPSET_VLSI_SCAMP))) + postcard_dell_mode = strstr(machines[machine].name, " Dell ") && + (machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX); + if (postcard_dell_mode) io_sethandler(is486 ? 0x00e0 : 0x00e4, 0x0001, NULL, NULL, NULL, NULL, NULL, postcard_writel, NULL); From 2b71002daba7a02480507f480815d01cb8c05aba Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 28 May 2025 16:35:38 -0300 Subject: [PATCH 20/22] PCI: Fix and delegate bridge initialization on Dell riser machines --- src/device/pci_bridge.c | 45 +++++++++++++++++++------------------ src/include/86box/machine.h | 2 ++ src/include/86box/pci.h | 1 + src/machine/m_at_slot1.c | 4 ++-- src/machine/m_at_socket7.c | 13 +++++++++-- src/pci.c | 4 ++-- 6 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index 8893acf69..bf49baf14 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -87,6 +87,14 @@ pci_bridge_set_ctl(void *priv, uint8_t ctl) dev->ctl = ctl; } +uint8_t +pci_bridge_get_bus_index(void *priv) +{ + pci_bridge_t *dev = (pci_bridge_t *) priv; + + return dev->bus_index; +} + static void pci_bridge_write(int func, int addr, uint8_t val, void *priv) { @@ -513,11 +521,9 @@ static void * pci_bridge_init(const device_t *info) { uint8_t interrupts[4]; - uint8_t interrupt_count; uint8_t interrupt_mask; + uint8_t add_type; uint8_t slot_count; - uint8_t dell_slots[3] = { 0x09, 0x0a, 0x0b }; - uint8_t dell_interrupts[3][4] = { { 1, 2, 3, 4 }, { 4, 2, 1, 3 }, { 1, 3, 4, 2 } }; pci_bridge_t *dev = (pci_bridge_t *) calloc(1, sizeof(pci_bridge_t)); @@ -527,40 +533,35 @@ pci_bridge_init(const device_t *info) pci_bridge_reset(dev); - if (info->local == PCI_BRIDGE_DEC_21152) - pci_add_card(PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev, &dev->slot); - else - pci_add_bridge(AGP_BRIDGE(dev->local), pci_bridge_read, pci_bridge_write, dev, &dev->slot); - - interrupt_count = sizeof(interrupts); - interrupt_mask = interrupt_count - 1; + interrupt_mask = sizeof(interrupts) - 1; if (dev->slot < 32) { - for (uint8_t i = 0; i < interrupt_count; i++) + for (uint8_t i = 0; i <= interrupt_mask; i++) interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i); } pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], interrupts[1], interrupts[2], interrupts[3]); - if (info->local == PCI_BRIDGE_DEC_21150) + if (info->local == PCI_BRIDGE_DEC_21150) { slot_count = 9; /* 9 bus masters */ - else if (info->local == PCI_BRIDGE_DEC_21152) - slot_count = 3; /* 3 bus masters */ - else + add_type = PCI_ADD_NORMAL; + } else if (info->local == PCI_BRIDGE_DEC_21152) { + slot_count = 0; /* 4 bus masters, but slots are added by the Dell machines */ + add_type = PCI_ADD_BRIDGE; + } else { slot_count = 1; /* AGP bridges always have 1 slot */ + add_type = PCI_ADD_AGPBRIDGE; + } + + pci_add_bridge(add_type, pci_bridge_read, pci_bridge_write, dev, &dev->slot); for (uint8_t i = 0; i < slot_count; i++) { - uint8_t slot = i; - if (info->local == PCI_BRIDGE_DEC_21152) { - slot = dell_slots[i]; - memcpy(interrupts, dell_interrupts[i], 4); - } /* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */ pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", - dev->bus_index, slot, interrupts[i & interrupt_mask], + dev->bus_index, i, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], interrupts[(i + 3) & interrupt_mask]); - pci_register_bus_slot(dev->bus_index, slot, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL, + pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4129cead7..3231acd80 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -722,6 +722,8 @@ extern int machine_at_vectra54_init(const machine_t *); extern int machine_at_5sbm2_init(const machine_t *); /* m_at_socket7.c */ +extern void machine_at_optiplex_21152_init(void); + extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); extern int machine_at_m7shi_init(const machine_t *); diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 462b4f821..8887f89f4 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -283,6 +283,7 @@ extern void pci_init(int flags); /* PCI bridge stuff. */ extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); +extern uint8_t pci_bridge_get_bus_index(void *priv); #ifdef EMU_DEVICE_H extern const device_t dec21150_device; diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 280462858..2ac805bee 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -170,14 +170,14 @@ machine_at_optiplexgxa_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0); pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 2, 1); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 1, 3, 4); - pci_register_slot(0x0F, PCI_CARD_BRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_BRIDGE, 0, 0, 0, 0); if (sound_card_current[0] == SOUND_INTERNAL) device_add(machine_get_snd_device(machine)); device_add(&i440lx_device); device_add(&piix4_device); - device_add(&dec21152_device); + machine_at_optiplex_21152_init(); device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index dbc59ef17..46c7b7623 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -46,6 +46,15 @@ #include <86box/network.h> #include <86box/pci.h> +void +machine_at_optiplex_21152_init(void) +{ + uint8_t bus_index = pci_bridge_get_bus_index(device_add(&dec21152_device)); + pci_register_bus_slot(bus_index, 0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_bus_slot(bus_index, 0x0a, PCI_CARD_NORMAL, 4, 2, 1, 3); + pci_register_bus_slot(bus_index, 0x0b, PCI_CARD_NORMAL, 1, 3, 4, 2); +} + int machine_at_acerv35n_init(const machine_t *model) { @@ -989,7 +998,7 @@ machine_at_optiplexgn_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Trio64V2/GX, temporarily Trio64V2/DX is given */ pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0); /* 3C905, not yet emulated */ pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); - pci_register_slot(0x0F, PCI_CARD_BRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_BRIDGE, 0, 0, 0, 0); if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); @@ -999,7 +1008,7 @@ machine_at_optiplexgn_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); - device_add(&dec21152_device); + machine_at_optiplex_21152_init(); device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); diff --git a/src/pci.c b/src/pci.c index c3020ca73..94ab9d5f2 100644 --- a/src/pci.c +++ b/src/pci.c @@ -855,10 +855,10 @@ pci_register_card(int pci_card) /* Add an instance of the PCI bridge. */ void -pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) +pci_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) { pci_card_t *card; - uint8_t bridge_slot = agp ? pci_find_slot(PCI_ADD_AGPBRIDGE, 0xff) : last_normal_pci_card_id; + uint8_t bridge_slot = (add_type == PCI_ADD_NORMAL) ? last_normal_pci_card_id : pci_find_slot(add_type, 0xff); if (bridge_slot != PCI_CARD_INVALID) { card = &pci_cards[bridge_slot]; From 25f0a26ea1f786b299ad3e8bd79ee831e322f5ba Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 29 May 2025 09:45:49 +0200 Subject: [PATCH 21/22] Vastly improve the ALi M1409 emulation (all of shadow RAM now work, as does bus speed and external cache setting), and fix the "Writing unimplemented Cyrix register FF" error as well. --- src/chipset/ali1409.c | 272 ++++++++++++++++++++++++++++++++---------- src/cpu/cpu.c | 2 +- 2 files changed, 210 insertions(+), 64 deletions(-) diff --git a/src/chipset/ali1409.c b/src/chipset/ali1409.c index 5009a6505..619843cda 100644 --- a/src/chipset/ali1409.c +++ b/src/chipset/ali1409.c @@ -61,91 +61,238 @@ ali1409_log(const char *fmt, ...) #endif typedef struct ali_1409_t { - uint8_t is_g; uint8_t index; uint8_t cfg_locked; - uint8_t reg_57h; uint8_t regs[256]; + uint8_t shadow[4]; uint8_t last_reg; } ali1409_t; +/* + This here is because from the two BIOS'es I used to reverse engineer this, + it is unclear which of the two interpretations of the shadow RAM register + operation is correct. + The 16 kB interpretation appears to work fine right now but it may be wrong, + so I left the 32 kB interpretation in as well. + */ +#ifdef INTERPRETATION_32KB +#define SHADOW_SIZE 0x00008000 +#else +#define SHADOW_SIZE 0x00004000 +#endif + +static void +ali1409_shadow_recalc(ali1409_t *dev) +{ + uint32_t base = 0x000c0000; + + for (uint8_t i = 0; i < 4; i++) { + uint8_t reg = 0x08 + i; + +#ifdef INTERPRETATION_32KB + for (uint8_t j = 0; j < 4; j += 2) { + uint8_t mask = (0x03 << j); +#else + for (uint8_t j = 0; j < 4; j++) { + uint8_t mask = (0x01 << j); +#endif + uint8_t r_on = dev->regs[reg] & 0x10; + uint8_t w_on = dev->regs[reg] & 0x20; + uint8_t val = dev->regs[reg] & mask; + uint8_t xor = (dev->shadow[i] ^ dev->regs[reg]) & (mask | 0x30); + int read = r_on ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + int write = w_on ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + + if (xor) { +#ifdef INTERPRETATION_32KB + switch (val >> j) { + case 0x00: + mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 0x01: + mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | write); + break; + case 0x02: + mem_set_mem_state_both(base, SHADOW_SIZE, read | write); + break; + case 0x03: + mem_set_mem_state_both(base, SHADOW_SIZE, read | MEM_WRITE_EXTANY); + break; + } +#else + switch (val >> j) { + case 0x00: + mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 0x01: + mem_set_mem_state_both(base, SHADOW_SIZE, read | write); + break; + } +#endif + } + + base += SHADOW_SIZE; + } + + dev->shadow[i] = dev->regs[reg]; + } + + flushmmucache_nopc(); +} static void ali1409_write(uint16_t addr, uint8_t val, void *priv) { ali1409_t *dev = (ali1409_t *) priv; - ali1409_log ("INPUT:addr %02x ,Value %02x \n" , addr , val); + ali1409_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); - if (addr & 1) { - if (dev->cfg_locked) { - if (dev->last_reg == 0x14 && val == 0x09) - dev->cfg_locked = 0; + if (addr & 0x0001) { + if (dev->cfg_locked) { + if ((dev->last_reg == 0x14) && (val == 0x09)) + dev->cfg_locked = 0; - dev->last_reg = val; - return; - } + dev->last_reg = val; + return; + } - if (dev->index == 0xff && val == 0xff) - dev->cfg_locked = 1; - else { - ali1409_log("Write reg %02x %02x %08x\n", dev->index, val, cs); - dev->regs[dev->index] = val; + /* It appears writing anything at all to register 0xFF locks it again. */ + if (dev->index == 0xff) + dev->cfg_locked = 1; + else if (dev->index < 0x44) { + ali1409_log("[%04X:%08X] [W] Register %02X = %02X\n", CS, cpu_state.pc, dev->index, val); - switch (dev->index) { - case 0xa: - switch ((val >> 4) & 3) { - case 0: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } + if (dev->index < 0x10) { + dev->regs[dev->index] = val; + + /* + There are still a lot of unknown here, but unfortunately, this is + as far as I have been able to come with two BIOS'es that are + available (the Acer 100T and an AMI Color dated 07/07/91). + */ + switch (dev->index) { + case 0x02: + /* + - Bit 7: The RAS address hold time: + - 0: 1/2 T; + - 1: 1 T. + - Bits 6-4: The RAS precharge time: + - 0, 0, 0: 1.5 T; + - 0, 0, 1: 2 T; + - 0, 1, 0: 2.5 T; + - 0, 1, 1: 3 T; + - 1, 0, 0: 3.5 T; + - 1, 0, 1: 4 T; + - 1, 1, 0: Reserved; + - 1, 1, 1: Reserved. + - Bit 3: Early miss cycle: + - 0: Disabled; + - 1: Enabled. + */ + break; + case 0x03: + /* + - Bit 6: CAS pulse for read cycle: + - 0: 1 T; + - 1: 1.5 T or 2 T. + I can not get the 2.5 T or 3 T setting to apply so + I have no idea what bit governs that. + - Bits 5, 4: CAS pulse for write cycle: + - 0, 0: 0.5 T or 1 T; + - 0, 1: 1.5 T or 2 T; + - 1, 0: 2.5 T or 3 T; + - 1, 1: Reserved. + - Bit 3: CAS active for read cycle: + - 0: Disabled; + - 1: Enabled. + - Bit 2: CAS active for write cycle: + - 0: Disabled; + - 1: Enabled. + */ + break; + case 0x06: + /* + - Bits 6-4: Clock divider: + - 0, 0, 0: / 2; + - 0, 0, 1: / 4; + - 0, 1, 0: / 8; + - 0, 1, 1: Reserved; + - 1, 0, 0: / 3; + - 1, 0, 1: / 6; + - 1, 1, 0: / 5; + - 1, 1, 1: / 10. + */ + switch ((val >> 4) & 7) { + default: + case 3: /* Reserved */ + cpu_set_isa_speed(7159091); break; - case 0xb: - switch ((val >> 4) & 3) { - case 0: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 2: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY| MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } + + case 0: + cpu_set_isa_speed(cpu_busspeed / 2); + break; + + case 1: + cpu_set_isa_speed(cpu_busspeed / 4); + break; + + case 2: + cpu_set_isa_speed(cpu_busspeed / 8); + break; + + case 4: + cpu_set_isa_speed(cpu_busspeed / 3); + break; + + case 5: + cpu_set_isa_speed(cpu_busspeed / 6); + break; + + case 6: + cpu_set_isa_speed(cpu_busspeed / 5); + break; + + case 7: + cpu_set_isa_speed(cpu_busspeed / 10); break; } + break; + case 0x08 ... 0x0b: + ali1409_shadow_recalc(dev); + break; + case 0x0c: + /* + This appears to be turbo in bit 4 (1 = on, 0 = off), + and bus speed in the rest of the bits. + */ + break; + case 0x0d: + cpu_cache_ext_enabled = !!(val & 0x08); + cpu_update_waitstates(); + break; } - } else - dev->index = val; + } + } + } else + dev->index = val; } static uint8_t ali1409_read(uint16_t addr, void *priv) { - ali1409_log ("reading at %02X\n",addr); const ali1409_t *dev = (ali1409_t *) priv; uint8_t ret = 0xff; if (dev->cfg_locked) ret = 0xff; - if (addr & 1) { - if ((dev->index >= 0xc0 || dev->index == 0x20) && cpu_iscyrix) - ret = 0xff; + else if (addr & 0x0001) { + if (dev->index < 0x44) ret = dev->regs[dev->index]; - } else - ret = dev->index; + } else + ret = dev->index; + + ali1409_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + return ret; } @@ -166,17 +313,16 @@ ali1409_init(UNUSED(const device_t *info)) dev->cfg_locked = 1; - /* M1409 Ports: - 22h Index Port - 23h Data Port - */ - - ali1409_log ("Bus speed: %i", cpu_busspeed); - + ali1409_log("Bus speed: %i\n", cpu_busspeed); io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); - io_sethandler(0x037f, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); - io_sethandler(0x03f3, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); + + dev->regs[0x0f] = 0x08; + + cpu_set_isa_speed(7159091); + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); return dev; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index d13dfe041..ec026d95e 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -4264,7 +4264,7 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) cyrix_addr = val; else if (addr < 0xf1) switch (cyrix_addr) { default: - if (cyrix_addr >= 0xc0) + if ((cyrix_addr >= 0xc0) && (cyrix_addr != 0xff)) fatal("Writing unimplemented Cyrix register %02X\n", cyrix_addr); break; From 168282875c991cc37e5c16f70e14a6d3f60aeb91 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 29 May 2025 14:09:27 +0500 Subject: [PATCH 22/22] Fix conversion to/from VHD-compatible CHS geometry not working properly --- src/qt/qt_harddiskdialog.cpp | 67 +++++++++++++++++++++--------------- src/qt/qt_harddiskdialog.hpp | 6 ++++ 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 9e5563536..ae1c60971 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -199,7 +199,7 @@ HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) * than a tenth of a percent change in size. */ static void -adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) +adjust_86box_geometry_for_vhd(_86BoxGeom *_86box_geometry, MVHDGeom *vhd_geometry) { if (_86box_geometry->cyl <= 65535) { vhd_geometry->cyl = _86box_geometry->cyl; @@ -226,10 +226,10 @@ adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) } static HarddiskDialog *callbackPtr = nullptr; -static MVHDGeom -create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt) +static _86BoxGeom +create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint32_t cyl, uint32_t heads, uint32_t spt) { - MVHDGeom _86box_geometry = { + _86BoxGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt @@ -256,10 +256,10 @@ create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, return _86box_geometry; } -static MVHDGeom -create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) +static _86BoxGeom +create_drive_vhd_dynamic(const QString &fileName, uint32_t cyl, uint32_t heads, uint32_t spt, int blocksize) { - MVHDGeom _86box_geometry = { + _86BoxGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt @@ -287,7 +287,7 @@ create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, u return _86box_geometry; } -static MVHDGeom +static _86BoxGeom create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, int blocksize) { int vhd_error = 0; @@ -299,25 +299,31 @@ create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, in options.parent_path = parentFilenameBytes.data(); options.type = MVHD_TYPE_DIFF; - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - MVHDGeom vhd_geometry; + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + MVHDGeom vhd_geometry; + _86BoxGeom _86box_geometry; if (vhd == NULL) { - vhd_geometry.cyl = 0; - vhd_geometry.heads = 0; - vhd_geometry.spt = 0; + _86box_geometry.cyl = 0; + _86box_geometry.heads = 0; + _86box_geometry.spt = 0; } else { vhd_geometry = mvhd_get_geometry(vhd); if (vhd_geometry.spt > 63) { - vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); - vhd_geometry.heads = 16; - vhd_geometry.spt = 63; + _86box_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); + _86box_geometry.heads = 16; + _86box_geometry.spt = 63; + } else { + _86box_geometry.cyl = vhd_geometry.cyl; + _86box_geometry.heads = vhd_geometry.heads; + _86box_geometry.spt = vhd_geometry.spt; } + mvhd_close(vhd); } - return vhd_geometry; + return _86box_geometry; } void @@ -409,7 +415,7 @@ HarddiskDialog::onCreateNewFile() } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ file.close(); - MVHDGeom _86box_geometry {}; + _86BoxGeom _86box_geometry {}; int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { case IMG_FMT_VHD_FIXED: @@ -493,10 +499,14 @@ HarddiskDialog::onCreateNewFile() } static void -adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) +adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry, _86BoxGeom *_86box_geometry) { - if (vhd_geometry->spt <= 63) + if (vhd_geometry->spt <= 63) { + _86box_geometry->cyl = vhd_geometry->cyl; + _86box_geometry->heads = vhd_geometry->heads; + _86box_geometry->spt = vhd_geometry->spt; return; + } int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt; if (desired_sectors > 267321600) @@ -506,9 +516,9 @@ adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) if (remainder > 0) desired_sectors -= remainder; - vhd_geometry->cyl = desired_sectors / (16 * 63); - vhd_geometry->heads = 16; - vhd_geometry->spt = 63; + _86box_geometry->cyl = desired_sectors / (16 * 63); + _86box_geometry->heads = 16; + _86box_geometry->spt = 63; } void @@ -602,11 +612,12 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) } } - MVHDGeom vhd_geom = mvhd_get_geometry(vhd); - adjust_vhd_geometry_for_86box(&vhd_geom); - cylinders = vhd_geom.cyl; - heads = vhd_geom.heads; - sectors = vhd_geom.spt; + MVHDGeom vhd_geom = mvhd_get_geometry(vhd); + _86BoxGeom _86box_geom; + adjust_vhd_geometry_for_86box(&vhd_geom, &_86box_geom); + cylinders = _86box_geom.cyl; + heads = _86box_geom.heads; + sectors = _86box_geom.spt; size = static_cast(cylinders * heads * sectors * 512); mvhd_close(vhd); } else { diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 9de61c51b..62ec6e963 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -64,4 +64,10 @@ private: void recalcSelection(); }; +typedef struct _86BoxGeom { + uint32_t cyl; + uint32_t heads; + uint32_t spt; +} _86BoxGeom; + #endif // QT_HARDDISKDIALOG_HPP