Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kernel] Fix to allow booting 2.88M floppy on dosbox #1711

Merged
merged 2 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 49 additions & 53 deletions elks/arch/i86/drivers/block/bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,30 @@
#include <linuxmt/kdev_t.h>
#include <linuxmt/debug.h>
#include <arch/system.h>
#include "bioshd.h"

#define RESET_DISK_CHG 0 /* =1 to reset BIOS on drive change fixes QEMU retry */

/* FIXME semi-copied from bioshd.c */
#define MINOR_SHIFT 3 /* =log2(NUM_MINOR) shift to get drive num*/
#define MAX_DRIVES 8 /* <=256/NUM_MINOR*/
#define DRIVE_FD0 4 /* =MAX_DRIVES/2 first floppy drive*/
/*
* Indices for fd_types array. Note these match the value returned
* by the BIOS in BL less 1, for INT 13h AH=8 (Get Disk Parms) for IBM PC.
*/
#define FD360 0
#define FD1200 1
#define FD720 2
#define FD1440 3
#define FD2880 4 /* QEMU returns 5 */
#define FD2880_DUP 5 /* Dosbox returns 6 */
#define FD1232 6 /* PC/98 only, not returned */

struct drive_infot fd_types[] = { /* AT/PS2 BIOS reported floppy formats*/
{40, 9, 2, 512, 0},
{80, 15, 2, 512, 1},
{80, 9, 2, 512, 2},
{80, 18, 2, 512, 3},
{80, 36, 2, 512, 4},
#ifdef CONFIG_ARCH_PC98
{77, 8, 2, 1024,5},
#endif
{40, 9, 2, 512, 0}, /* 360k */
{80, 15, 2, 512, 1}, /* 1.2M */
{80, 9, 2, 512, 2}, /* 720k */
{80, 18, 2, 512, 3}, /* 1.4M */
{80, 36, 2, 512, 5}, /* 2.88M */
{80, 36, 2, 512, 6}, /* 2.88M */
{77, 8, 2, 1024,7}, /* 1.232M PC/98 only */
};

/* BIOS drive mappings */
Expand Down Expand Up @@ -218,57 +225,46 @@ int INITPROC bios_gethdinfo(struct drive_infot *drivep) {
#endif

#ifdef CONFIG_BLK_DEV_BFD_HARD
/* hard-coded floppy configuration*/
int INITPROC bios_getfdinfo(struct drive_infot *drivep)
{
/* Set this to match your system. Currently it's set to a two drive system:
/*
* Hard-coded floppy configuration
* Set below to match your system. For IBM PC, it's set to a two drive system:
*
* 720KB as /dev/fd0
* and 720KB as /dev/fd1
*
* ndrives is number of drives in your system (either 0, 1 or 2)
*/

int ndrives = MAXDRIVES;

/* drive_info[] should be set *only* for existing drives;
* comment out drive_info lines if you don't need them
* (e.g. you have less than 2 drives)
*
* Enter type 4 in fd_types' brackets for unknown drive type
* Otherwise use floppy drive type table below:
*
* Type Format
* ~~~~ ~~~~~~
* Drive Type Format
* ~~~~~ ~~~~~~
* 0 360 KB
* 1 1.2 MB
* 2 720 KB
* 3 1.44 MB
* 4 2.88 MB or Unknown
* 5 1.232 MB (PC98 1K sectors)
*
* Warning: drive will be reported as 2880 KB at bootup if you've set it
* as unknown (4). Floppy probe will detect correct floppy format at each
* change so don't bother with that
* 4 2.88 MB (QEMU)
* 5 2.88 MB (Dosbox)
* 6 1.232 MB (PC/98 1K sectors)
* ndrives is number of drives in your system (either 0, 1 or 2)
*/

int ndrives = FD_DRIVES;

#ifdef CONFIG_ARCH_PC98
#if defined(CONFIG_IMG_FD1232)
drivep[0] = fd_types[5];
drivep[1] = fd_types[5];
drivep[2] = fd_types[5];
drivep[3] = fd_types[5];
#elif defined(CONFIG_IMG_FD1440)
drivep[0] = fd_types[3];
drivep[1] = fd_types[3];
drivep[2] = fd_types[3];
drivep[3] = fd_types[3];
drivep[0] = fd_types[FD1232];
drivep[1] = fd_types[FD1232];
drivep[2] = fd_types[FD1232];
drivep[3] = fd_types[FD1232];
#else
drivep[0] = fd_types[FD1440];
drivep[1] = fd_types[FD1440];
drivep[2] = fd_types[FD1440];
drivep[3] = fd_types[FD1440];
#endif
#endif

#ifdef CONFIG_ARCH_IBMPC
drivep[0] = fd_types[2]; /* /dev/fd0 */
drivep[1] = fd_types[2]; /* /dev/fd1 */
drivep[0] = fd_types[FD720];
drivep[1] = fd_types[FD720];
#endif

return ndrives;
Expand Down Expand Up @@ -296,10 +292,10 @@ int INITPROC bios_getfdinfo(struct drive_infot *drivep)
if (peekb(0x55C,0) & (1 << drive)) {
#ifdef CONFIG_IMG_FD1232
bios_drive_map[DRIVE_FD0 + drive] = drive + 0x90;
*drivep = fd_types[5];
*drivep = fd_types[FD1232];
#else
bios_drive_map[DRIVE_FD0 + drive] = drive + 0x30;
*drivep = fd_types[3];
*drivep = fd_types[FD1440];
#endif
ndrives++; /* floppy drive count*/
drivep++;
Expand All @@ -315,7 +311,7 @@ int INITPROC bios_getfdinfo(struct drive_infot *drivep)
if (!drives && ndrives) { /* handle Toshiba T1100 BIOS returning 0 drives */
for (drive = 0; drive < ndrives; drive++) {
printk("fd%d: default 720k\n", drive);
*drivep++ = fd_types[2];
*drivep++ = fd_types[FD720];
}
return ndrives;
} else ndrives = drives;
Expand All @@ -331,10 +327,10 @@ int INITPROC bios_getfdinfo(struct drive_infot *drivep)
BD_AX = BIOSHD_DRIVE_PARMS;
BD_DX = drive;
BD_ES = BD_DI = BD_SI = 0; /* guard against BIOS bugs*/
if (!call_bios(&bdt)) /* returns drive type in BL*/
if (!call_bios(&bdt)) { /* returns drive type in BL*/
*drivep = fd_types[(BD_BX & 0xFF) - 1];
else {
int type = (sys_caps & CAP_PC_AT) ? 3 : 0;
} else {
int type = (sys_caps & CAP_PC_AT) ? FD1440 : FD360;
*drivep = fd_types[type];
printk("fd%d: default %s\n", drive, type? "1440k": "360k");
}
Expand Down Expand Up @@ -389,9 +385,9 @@ void bios_switch_device98(int target, unsigned int device, struct drive_infot *d
bios_drive_map[target + DRIVE_FD0] =
(device | (bios_drive_map[target + DRIVE_FD0] & 0x0F));
if (device == 0x30)
*drivep = fd_types[3]; /* 1.44 MB */
*drivep = fd_types[FD1440];
else if (device == 0x90)
*drivep = fd_types[5]; /* 1.232 MB */
*drivep = fd_types[FD1232];
}
#endif

Expand Down
18 changes: 2 additions & 16 deletions elks/arch/i86/drivers/block/bioshd.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include <arch/system.h>
#include <arch/irq.h>
#include <arch/ports.h>
#include "bioshd.h"

#define PER_DRIVE_INFO 1 /* =1 for per-line display of drive info at init */
#define DEBUG_PROBE 0 /* =1 to display more floppy probing information */
Expand All @@ -61,21 +62,6 @@
//#define IODELAY 5 /* times 10ms, emulated delay for floppy on QEMU */
#define MAX_ERRS 5 /* maximum sector read/write error retries */

/* the following must match with /dev minor numbering scheme*/
#define NUM_MINOR 8 /* max minor devices per drive*/
#define MINOR_SHIFT 3 /* =log2(NUM_MINOR) shift to get drive num*/
#define MAX_DRIVES 8 /* <=256/NUM_MINOR*/
#define DRIVE_HD0 0
#define DRIVE_FD0 4 /* =MAX_DRIVES/2 first floppy drive*/

#define HD_DRIVES 4 /* max hard drives */
#ifdef CONFIG_ARCH_PC98
#define FD_DRIVES 4
#else
#define FD_DRIVES 2 /* max floppy drives */
#endif
#define NUM_DRIVES (HD_DRIVES+FD_DRIVES) /* max number of drives (<=256/NUM_MINOR) */

#define MAJOR_NR BIOSHD_MAJOR
#define BIOSDISK
#include "blk.h"
Expand Down Expand Up @@ -378,7 +364,7 @@ void INITPROC bioshd_init(void)
/* FIXME perhaps remove for speed on floppy boot*/
outb_p(0x0C, FDC_DOR); /* FD motors off, enable IRQ and DMA*/

#ifdef CONFIG_BLK_DEV_BFD
#if defined(CONFIG_BLK_DEV_BFD) || defined(CONFIG_BLK_DEV_BFD_HARD)
fd_count = bios_getfdinfo(&drive_info[DRIVE_FD0]);
#endif
#ifdef CONFIG_BLK_DEV_BHD
Expand Down
19 changes: 19 additions & 0 deletions elks/arch/i86/drivers/block/bioshd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _BIOSHD_H
#define _BIOSHD_H

/* the following must match with /dev minor numbering scheme*/
#define NUM_MINOR 8 /* max minor devices per drive*/
#define MINOR_SHIFT 3 /* =log2(NUM_MINOR) shift to get drive num*/
#define MAX_DRIVES 8 /* <=256/NUM_MINOR*/
#define DRIVE_HD0 0
#define DRIVE_FD0 4 /* =MAX_DRIVES/2 first floppy drive*/

#define HD_DRIVES 4 /* max hard drives */
#ifdef CONFIG_ARCH_PC98
#define FD_DRIVES 4
#else
#define FD_DRIVES 2 /* max floppy drives */
#endif
#define NUM_DRIVES (HD_DRIVES+FD_DRIVES) /* max number of drives (<=256/NUM_MINOR) */

#endif
2 changes: 1 addition & 1 deletion elks/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void schedule(void)
prev = current;

#ifdef CHECK_SCHED
if (intr_count > 0) {
if (intr_count) {
/* Taking a timer IRQ during another IRQ or while in kernel space is
* quite legal. We just dont switch then */
panic("SCHED: schedule() called from interrupt, intr_count %d", intr_count);
Expand Down