Files
86Box/src/floppy/fdc_magitronic.c
2025-02-08 01:28:25 -05:00

143 lines
3.6 KiB
C

/*
* 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.
*
* Implementation of the Magitronic B215 XT-FDC Controller.
*
* Authors: Tiseno100
*
* Copyright 2021 Tiseno100
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/plat_unused.h>
#define ROM_B215 "roms/floppy/magitronic/Magitronic B215 - BIOS ROM.bin"
#define ROM_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
#define DRIVE_SELECT (int) (real_drive(dev->fdc_controller, i))
typedef struct b215_t {
fdc_t *fdc_controller;
rom_t rom;
} b215_t;
static uint8_t
b215_read(UNUSED(uint16_t addr), void *priv)
{
b215_t *dev = (b215_t *) priv;
/*
Register 3F0h
Bit (3-2) for Drive B:
Bit (1-0) for Drive A:
0: 360KB
1: 1.2MB
2: 720KB
3: 1.44MB
4:
*/
int drive_spec[2];
for (uint8_t i = 0; i <= 1; i++) {
if (fdd_is_525(DRIVE_SELECT)) {
if (!fdd_is_dd(DRIVE_SELECT))
drive_spec[i] = 1;
else if (fdd_doublestep_40(DRIVE_SELECT))
drive_spec[i] = 2;
else
drive_spec[i] = 0;
} else {
if (fdd_is_dd(DRIVE_SELECT) && !fdd_is_double_sided(DRIVE_SELECT))
drive_spec[i] = 0;
else if (fdd_is_dd(DRIVE_SELECT) && fdd_is_double_sided(DRIVE_SELECT))
drive_spec[i] = 2;
else
drive_spec[i] = 3;
}
}
return ((drive_spec[1] << 2) | drive_spec[0]) & 0x0f;
}
static void
b215_close(void *priv)
{
b215_t *dev = (b215_t *) priv;
free(dev);
}
static void *
b215_init(UNUSED(const device_t *info))
{
b215_t *dev = (b215_t *) calloc(1, sizeof(b215_t));
rom_init(&dev->rom, ROM_B215, ROM_ADDR, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
dev->fdc_controller = device_add(&fdc_xt_umc_um8398_device);
io_sethandler(FDC_PRIMARY_ADDR, 1, b215_read, NULL, NULL, NULL, NULL, NULL, dev);
return dev;
}
static int
b215_available(void)
{
return rom_present(ROM_B215);
}
static const device_config_t b215_config[] = {
// clang-format off
{
.name = "bios_addr",
.description = "BIOS Address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0xca000,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "CA00H", .value = 0xca000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t fdc_b215_device = {
.name = "Magitronic B215",
.internal_name = "b215",
.flags = DEVICE_ISA,
.local = 0,
.init = b215_init,
.close = b215_close,
.reset = NULL,
.available = b215_available,
.speed_changed = NULL,
.force_redraw = NULL,
.config = b215_config
};