From ba700f0759a59551159e90aff2bd6d547c27179b Mon Sep 17 00:00:00 2001 From: Harley Travis Date: Sat, 23 May 2026 23:55:17 -0500 Subject: TOSFloppy_2025-04-20T2103-0500.zip This was the second and final Discord release of the TempleOS floppy disk controller driver, released April 20, 2025. This release saw mainly structure changes, plus the addition of a license file (the code, at this point, is licensed under Do What The Fuck You Want To Public License, version 2.0). --- ChangeLog.TXT | 9 + Copying.TXT | 14 ++ Floppy.HH | 98 -------- KFloppy.HC | 477 +++++++++++++++++++++++++++++++++++ KFloppyA.HH | 98 ++++++++ KFloppyB.HH | 19 ++ KFloppyDMA.HC | 1 + KStart32.HC | 118 --------- Kernel.PRJ | 63 ----- KernelC.HH | 787 ---------------------------------------------------------- NewFloppy.HC | 477 ----------------------------------- ReadMe.TXT | 49 +++- 12 files changed, 656 insertions(+), 1554 deletions(-) create mode 100644 ChangeLog.TXT create mode 100644 Copying.TXT delete mode 100644 Floppy.HH create mode 100644 KFloppy.HC create mode 100644 KFloppyA.HH create mode 100644 KFloppyB.HH create mode 100644 KFloppyDMA.HC delete mode 100644 KStart32.HC delete mode 100644 Kernel.PRJ delete mode 100644 KernelC.HH delete mode 100644 NewFloppy.HC diff --git a/ChangeLog.TXT b/ChangeLog.TXT new file mode 100644 index 0000000..1059101 --- /dev/null +++ b/ChangeLog.TXT @@ -0,0 +1,9 @@ +2025-04-18: +I had a brain fart and forgot to revert the hard-coded DMA buffer address, as pointed out by TheTinkerer on the TOS Discord. +I went ahead and uncommented the stuff for splitting up the address, and fixed the base address I/O writes. +If you have installed the driver, just replace NewFloppy.HC and recompile the kernel; you should be good after that. +Whoops! + +2025-04-20 (hah! weed.): +Moved some stuff out of the system files to make things a bit less of a mess. +Also I added a copyright notice to the readme (you can still do what the fuck you want to; see Copying.TXT). \ No newline at end of file diff --git a/Copying.TXT b/Copying.TXT new file mode 100644 index 0000000..ee7d6a5 --- /dev/null +++ b/Copying.TXT @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/Floppy.HH b/Floppy.HH deleted file mode 100644 index 4e5cfdb..0000000 --- a/Floppy.HH +++ /dev/null @@ -1,98 +0,0 @@ -// FDC uses IRQ6 = int 26h -#define I_FDC 0x26 -#define IRQ_FDC 6 - -// FDC regs (primary ctrlr) -#define FDC_STAT_A 0x0 -#define FDC_STAT_B 0x1 -#define FDC_DOR 0x2 -#define FDC_TAPE 0x3 -#define FDC_MSR_DSR 0x4 -#define FDC_DATA 0x5 -#define FDC_CCR_DIR 0x7 - -// FDC cmds -#define FDC_READ_TRACK 0x02 -#define FDC_SPECIFY 0x03 -#define FDC_SENSE_STAT 0x04 -#define FDC_WRITE_DATA 0x05 -#define FDC_READ_DATA 0x06 -#define FDC_RECALIBRATE 0x07 -#define FDC_SENSE_INTR 0x08 -#define FDC_WRITE_DEL 0x09 -#define FDC_READ_ID 0x0A -#define FDC_READ_DEL 0x0C -#define FDC_FMT_TRACK 0x0D -#define FDC_DUMP_REG 0x0E -#define FDC_SEEK 0x0F -#define FDC_VERSION 0x10 -#define FDC_SCAN_EQL 0x11 -#define FDC_PERP_MODE 0x12 -#define FDC_CONFIGURE 0x13 -#define FDC_LOCK 0x14 -#define FDC_VERIFY 0x16 -#define FDC_SCAN_LO_EQL 0x19 -#define FDC_SCAN_HI_EQL 0x1D - -// Motor stuff -#define FDC_MOTOR_OFF 0 -#define FDC_MOTOR_ON 1 -#define FDC_MOTOR_WAIT 2 - -// Read/write directions -#define FDC_DIR_READ 0 -#define FDC_DIR_WRITE 1 - -// Digital Output Register (DOR) flags - -// DOR motor control flags: 1 = on, 0 = off -#define FDC_DOR_MOTD 0x80 // Drive D -#define FDC_DOR_MOTC 0x40 // Drive C -#define FDC_DOR_MOTB 0x20 // Drive B -#define FDC_DOR_MOTA 0x10 // Drive A - -// other DOR flags -#define FDC_DOR_DMA 0x08 // DMA2/IRQ6 On/Off -#define FDC_DOR_REST 0x04 // Controller Reset: this is active low; 1 = normal, 0 = reset - -// DOR drive select (DOR & 0x03): selects drive 0-3 - -// Main Status Register (MSR) flags -#define FDC_MSR_RQM 0x80 // Main Request: 1 = ready, 0 = not ready -#define FDC_MSR_DIO 0x40 // Data In/Out: 1 = FDC -> PC, 0 = PC -> FDC -#define FDC_MSR_NDMA 0x20 // Non-DMA: 1 = DMA off, 0 = DMA on -#define FDC_MSR_BUSY 0x10 // Device busy: self-explanatory - -// MSR drive seek flags: 1 = seeking, 0 = idle -#define FDC_MSR_ACTD 0x08 // Drive D -#define FDC_MSR_ACTC 0x04 // Drive C -#define FDC_MSR_ACTB 0x02 // Drive B -#define FDC_MSR_ACTA 0x01 // Drive A - -// Status Register 0 (ST0) flags - -/* ST0 interrupt code (ST0 & 0xC0): - 00 = normal termination - 01 = abnormal termination - 10 = invalid cmd - 11 = abnormal termination by poilling (drive became not ready) -*/ - -#define FDC_ST0_SEEK_END 0x20 // Seek End: seek/calibration completed -#define FDC_ST0_UNIT_CHK 0x10 // Unit Check: drive encountered a fault or recalibration failed -#define FDC_ST0_NOT_RDY 0x08 // Not Ready: self-explanatory -#define FDC_ST0_HEAD 0x04 // Active Head - -// ST0 unit select (ST0 & 0x03): same fmt as DOR drive select - -// Status Register 1 (ST1) flags -#define FDC_ST1_END_CYL 0x80 // End of Cylinder: set when sector count > sectors on track -// 0x40 is unused -#define FDC_ST1_DATA_ERR 0x20 // Data Error: set when an error is detected in a sector's data or ID fields -#define FDC_ST1_TIMEOUT 0x10 // Timeout: set when a data overrun occurs (i.e. the system is not reading data fast enough) -// 0x08 is unused -#define FDC_ST1_NO_DATA 0x04 // No Data: set when either a sector cannot be read, or an ID cannot be successfully read, or if the sector sequence cannot be determined -#define FDC_ST1_NO_WRITE 0x02 // Not Writable: set when attempting to write to a write-protected disk -#define FDC_ST1_NO_ID 0x01 // No Addr. Mark: set when an ID/(deleted) data address mark cannot be found. - -// Status Register 2 (ST2) flags \ No newline at end of file diff --git a/KFloppy.HC b/KFloppy.HC new file mode 100644 index 0000000..32f1675 --- /dev/null +++ b/KFloppy.HC @@ -0,0 +1,477 @@ +/* + New, (hopefully) Less Messy Floppy Driver + Copyright (C) 2025 Yoshi128k. + Licensed under version 2 of the Do What The Fuck You Want To Public License + See COPYING for details. +*/ + +Bool FDCIrq = FALSE; + +U0 FDCDMAInit(U16 len) +{ + U64 buf_lo, buf_hi, page, cnt_lo, cnt_hi; + + buf_lo = &FDC_DMA & 0xFF; + buf_hi = &FDC_DMA >> 8; + page = &FDC_DMA >> 16; + cnt_lo = (len - 1) & 0xFF; + cnt_hi = (len - 1) >> 8; + + OutU8(0x0A, 6); // mask ch 0 and 2 + Sleep(1); + OutU8(0x0C, -1); // reset flip flop + Sleep(1); + OutU8(0x04, buf_lo); // buf low byte + Sleep(1); + OutU8(0x04, buf_hi); // buf high byte + Sleep(1); + OutU8(0x0C, -1); // reset flip flop again + Sleep(1); + OutU8(0x05, cnt_lo); // cntr low byte + Sleep(1); + OutU8(0x05, cnt_hi); // cntr high byte + Sleep(1); + OutU8(0x81, 0); // page + Sleep(1); + OutU8(0x0A, 2); // unmask ch 0 and 2 + Sleep(1); +} + +U0 FDCDMAPrepWrite() +{ + OutU8(0x0A, 6); // mask ch 0 and 2 + Sleep(1); + OutU8(0x0B, 0x5A); // single xfer, addr inc, auto init, write, ch 2 + Sleep(1); + OutU8(0x0A, 2); // unmask ch 0 and 2 + Sleep(1); +} + +U0 FDCDMAPrepRead() +{ + OutU8(0x0A, 6); // mask ch 0 and 2 + Sleep(1); + OutU8(0x0B, 0x56); // single xfer, addr inc, auto init, read, ch 2 + Sleep(1); + OutU8(0x0A, 2); // unmask ch 0 and 2 + Sleep(1); +} + +interrupt U0 FDCIrqHandler() { + OutU8(0x20, 0x20); // EOI + FDCIrq = TRUE; +} + +U16 fdc_base = 0x03F0; + +static U8 *fd_types[8] = { + "none", + "360kB 5.25\"", + "1.2MB 5.25\"", + "720kB 3.5\"", + + "1.44MB 3.5\"", + "2.88MB 3.5\"", + "unknown type", + "unknown type" +}; + +U0 CMOSGetFloppyDrives() +{ + OutU8(0x70, 0x10); + Sleep(1); + + U64 drives = InU8(0x71); + + AdamLog("Floppy Drive 0: %s\n", fd_types[drives >> 4]); + AdamLog("Floppy Drive 1: %s\n", fd_types[drives & 0xF]); +} + +U0 FDCSendCmd(U16 base, U8 cmd) +{ + // Send a command to the floppy controller + + // 60 sec timeout + U64 i; + for (i = 0; i < 600; i++) { + Sleep(10); + if (0x80 & InU8(base + FDC_MSR_DSR)) { + OutU8(base + FDC_DATA, cmd); + Sleep(1); + return; + } + } + AdamErr("FDC Command TimeOut"); +} + +U8 FDCReadData(U16 base) +{ + // Read data from the floppy controller + + // 60 sec timeout + U64 i; + for (i=0;i<600;i++) { + Sleep(10); + if (0x80 & InU8(base + FDC_MSR_DSR)) { + return InU8(base + FDC_DATA); + } + } + AdamErr("FDC Read TimeOut"); +} + +U0 FDCCheckInt(U16 base, U8 *st0, U8 *cyl) +{ + FDCSendCmd(base, FDC_SENSE_INTR); + + *st0 = FDCReadData(base); + *cyl = FDCReadData(base); +} + +I16 fdc_mtr_ticks = 0; +U8 fdc_mtr_state = FDC_MOTOR_OFF; + +U0 FDCMotorOff(U16 base) +{ + OutU8(base + FDC_DOR, 0x0C); + fdc_mtr_state = FDC_MOTOR_OFF; +} + +U0 FDCMotorPwrOffTimer() +{ + // You're supposed to run this function as a separate CTask. It will exit when the motor + // exits the "wait" state (either because it has turned off or because something needs it to be on). + // The driver only spawns this when the motor is moved from "on" to "wait". + while (fdc_mtr_state == FDC_MOTOR_WAIT) { + // Sanity check for if something wants the motor on at the last second + if (fdc_mtr_state == FDC_MOTOR_ON) break; + + Sleep(500); + + fdc_mtr_ticks -= 50; + if (fdc_mtr_ticks <= 0) { + FDCMotorOff(fdc_base); + } + Yield; // Give control back to the scheduler + } +} + +U0 FDCMotorCtrl(U16 base, Bool onoff) +{ + U64 prev_mtr_state; + if (onoff) { + if (!fdc_mtr_state) { + // Turn on motor + OutU8(base + FDC_DOR, 0x1C); + Sleep(500); // Wait 500 ms to allow drive to spin up + } + fdc_mtr_state = FDC_MOTOR_ON; + } else { + prev_mtr_state = fdc_mtr_state; + if (fdc_mtr_state == FDC_MOTOR_WAIT) { + AdamLog("FDC: Motor PowerOff Already Pending\n"); + } + fdc_mtr_ticks = 300; // 3 sec timeout before motor turns off + fdc_mtr_state = FDC_MOTOR_WAIT; + // Only spawn the timer task of the motor is currently on; infinitely-looping tasks peg the CPU + if (prev_mtr_state != FDC_MOTOR_WAIT) Spawn(&FDCMotorPwrOffTimer,,"FDCMotorPwrOffTimer"); + } +} + +I8 FDCRecalibrate(U16 base) +{ + FDCIrq = FALSE; + + U64 i; + U8 st0, cyl; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + for (i=0;i<10;i++) { + FDCSendCmd(base, FDC_RECALIBRATE); + FDCSendCmd(base, 0); + + // Wait for an interrupt, then get the status + while (!FDCIrq) Yield; + FDCCheckInt(base, &st0, &cyl); + AdamLog("ST0: %d Cyl: %d\n",st0,cyl); + + if (st0 & 0xC0) { + static U8 * status[4] = {0, "error", "invalid", "drive"}; + AdamLog("Calibration Status: %s\n", status[st0 >> 6]); + } + + if (!cyl) { + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return 0; + } + } + + AdamErr("FDC ReCalibrate TimeOut"); + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return -1; +} + +I8 FDCReset(U16 base) +{ + FDCIrq = FALSE; + + OutU8(base + FDC_DOR, 0x00); + Sleep(1); + OutU8(base + FDC_DOR, 0x0C); + Sleep(1); + + while (!FDCIrq) Yield; + + // Ignore this + U64 i, lck; + U8 st0, cyl; + for (i=0;i<4;i++) { + FDCCheckInt(base, &st0, &cyl); + } + + // Set xfer rate to 500kbps + OutU8(base + FDC_CCR_DIR, 0x00); + Sleep(1); + + // Set the mechanical params and disable DMA (Terry didn't use it) + FDCSendCmd(base, FDC_SPECIFY); + FDCSendCmd(base, 0b10000000); // SRT = 8 (8 ms), HUT = 0 (256 ms) + FDCSendCmd(base, 0b00011110); // HLT = 15 (30 ms), NDMA = 0 (DMA enabled) + + // Configure the FIFO + FDCSendCmd(base, FDC_CONFIGURE); + FDCSendCmd(base, 0x00); // 1st param is a 0 + FDCSendCmd(base, 0b01011011); // 2nd param: Implied seek on, FIFO on, Drive polling disabled, threshold = 12 + FDCSendCmd(base, 0x00); // 3rd param: write precomp = 0 + + // Lock the configuration + FDCSendCmd(base, 0x94); + lck = FDCReadData(base); // Result: lock status + + // contingency + if (FDCRecalibrate(base)) return -1; + + return 0; +} + +I8 FDCSeek(U16 base, U8 cyli, U8 head) +{ + U64 i; + U8 st0, cyl; + FDCIrq = FALSE; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + for (i=0;i<10;i++) { + // Attempt to move to given cyl + // 1: X X X X X HD D1 D0 + // 2: Cyl No + FDCSendCmd(base, FDC_SEEK); + FDCSendCmd(base, head<<2); + FDCSendCmd(base, cyli); + + while (!FDCIrq) Yield; + FDCCheckInt(base, &st0, &cyl); + AdamLog("ST0: %d Cyl: %d\n",st0,cyl); + + if (st0 & 0xC0) { + static U8 * status[4] = {0, "error", "invalid", "drive"}; + AdamLog("Seek Status: %s\n", status[st0 >> 6]); + } + + if (cyl == cyli) { + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return 0; + } + } + + AdamErr("FDC Seek TimeOut"); + FDCMotorCtrl(base, FDC_MOTOR_OFF); + return -1; +} + +U0 FDCRead(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Read data from disk (single-track) + static U8 flags; + flags = 0x40; // Multi-track off, MFM modulation + static U64 cmd; + cmd = FDC_READ_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)); + FDCDMAPrepRead(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} + + +U0 FDCReadMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Read data from disk (multi-track) + static U8 flags; + flags = 0xC0; // Multi-track on, MFM modulation + static U64 cmd; + cmd = FDC_READ_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)*2); + FDCDMAPrepRead(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for the xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} + +U0 FDCWrite(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Write data to disk (single-track) + static U8 flags; + flags = 0x40; // Multi-track off, MFM modulation + static U64 cmd; + cmd = FDC_WRITE_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)); + FDCDMAPrepWrite(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} + + +U0 FDCWriteMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) +{ + // Write data to disk (multi-track) + static U8 flags; + flags = 0xC0; // Multi-track on, MFM modulation + static U64 cmd; + cmd = FDC_WRITE_DATA | flags; + FDCIrq = FALSE; + + U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; + + FDCMotorCtrl(base, FDC_MOTOR_ON); + + AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); + + // Prepare the DMA controller + AdamLog("Preparing DMA\n"); + FDCDMAInit(512*(trklen - sect + 1)*2); + FDCDMAPrepRead(); + + FDCSendCmd(base, cmd); + FDCSendCmd(base, head << 2); // Drive 0, specified head + FDCSendCmd(base, cyl); + FDCSendCmd(base, head); + FDCSendCmd(base, sect); + FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes + FDCSendCmd(base, trklen); // Track Length/Max Sector No. + FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") + FDCSendCmd(base, 0xFF); // Data Length (irrelevant) + + // Wait for the xfer to complete + while (!FDCIrq) Yield; + + st0 = FDCReadData(base); + st1 = FDCReadData(base); + st2 = FDCReadData(base); + rcyl = FDCReadData(base); + rhd = FDCReadData(base); + rsect = FDCReadData(base); + rsectsize = FDCReadData(base); + + AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); + + FDCMotorCtrl(base, FDC_MOTOR_OFF); +} \ No newline at end of file diff --git a/KFloppyA.HH b/KFloppyA.HH new file mode 100644 index 0000000..4e5cfdb --- /dev/null +++ b/KFloppyA.HH @@ -0,0 +1,98 @@ +// FDC uses IRQ6 = int 26h +#define I_FDC 0x26 +#define IRQ_FDC 6 + +// FDC regs (primary ctrlr) +#define FDC_STAT_A 0x0 +#define FDC_STAT_B 0x1 +#define FDC_DOR 0x2 +#define FDC_TAPE 0x3 +#define FDC_MSR_DSR 0x4 +#define FDC_DATA 0x5 +#define FDC_CCR_DIR 0x7 + +// FDC cmds +#define FDC_READ_TRACK 0x02 +#define FDC_SPECIFY 0x03 +#define FDC_SENSE_STAT 0x04 +#define FDC_WRITE_DATA 0x05 +#define FDC_READ_DATA 0x06 +#define FDC_RECALIBRATE 0x07 +#define FDC_SENSE_INTR 0x08 +#define FDC_WRITE_DEL 0x09 +#define FDC_READ_ID 0x0A +#define FDC_READ_DEL 0x0C +#define FDC_FMT_TRACK 0x0D +#define FDC_DUMP_REG 0x0E +#define FDC_SEEK 0x0F +#define FDC_VERSION 0x10 +#define FDC_SCAN_EQL 0x11 +#define FDC_PERP_MODE 0x12 +#define FDC_CONFIGURE 0x13 +#define FDC_LOCK 0x14 +#define FDC_VERIFY 0x16 +#define FDC_SCAN_LO_EQL 0x19 +#define FDC_SCAN_HI_EQL 0x1D + +// Motor stuff +#define FDC_MOTOR_OFF 0 +#define FDC_MOTOR_ON 1 +#define FDC_MOTOR_WAIT 2 + +// Read/write directions +#define FDC_DIR_READ 0 +#define FDC_DIR_WRITE 1 + +// Digital Output Register (DOR) flags + +// DOR motor control flags: 1 = on, 0 = off +#define FDC_DOR_MOTD 0x80 // Drive D +#define FDC_DOR_MOTC 0x40 // Drive C +#define FDC_DOR_MOTB 0x20 // Drive B +#define FDC_DOR_MOTA 0x10 // Drive A + +// other DOR flags +#define FDC_DOR_DMA 0x08 // DMA2/IRQ6 On/Off +#define FDC_DOR_REST 0x04 // Controller Reset: this is active low; 1 = normal, 0 = reset + +// DOR drive select (DOR & 0x03): selects drive 0-3 + +// Main Status Register (MSR) flags +#define FDC_MSR_RQM 0x80 // Main Request: 1 = ready, 0 = not ready +#define FDC_MSR_DIO 0x40 // Data In/Out: 1 = FDC -> PC, 0 = PC -> FDC +#define FDC_MSR_NDMA 0x20 // Non-DMA: 1 = DMA off, 0 = DMA on +#define FDC_MSR_BUSY 0x10 // Device busy: self-explanatory + +// MSR drive seek flags: 1 = seeking, 0 = idle +#define FDC_MSR_ACTD 0x08 // Drive D +#define FDC_MSR_ACTC 0x04 // Drive C +#define FDC_MSR_ACTB 0x02 // Drive B +#define FDC_MSR_ACTA 0x01 // Drive A + +// Status Register 0 (ST0) flags + +/* ST0 interrupt code (ST0 & 0xC0): + 00 = normal termination + 01 = abnormal termination + 10 = invalid cmd + 11 = abnormal termination by poilling (drive became not ready) +*/ + +#define FDC_ST0_SEEK_END 0x20 // Seek End: seek/calibration completed +#define FDC_ST0_UNIT_CHK 0x10 // Unit Check: drive encountered a fault or recalibration failed +#define FDC_ST0_NOT_RDY 0x08 // Not Ready: self-explanatory +#define FDC_ST0_HEAD 0x04 // Active Head + +// ST0 unit select (ST0 & 0x03): same fmt as DOR drive select + +// Status Register 1 (ST1) flags +#define FDC_ST1_END_CYL 0x80 // End of Cylinder: set when sector count > sectors on track +// 0x40 is unused +#define FDC_ST1_DATA_ERR 0x20 // Data Error: set when an error is detected in a sector's data or ID fields +#define FDC_ST1_TIMEOUT 0x10 // Timeout: set when a data overrun occurs (i.e. the system is not reading data fast enough) +// 0x08 is unused +#define FDC_ST1_NO_DATA 0x04 // No Data: set when either a sector cannot be read, or an ID cannot be successfully read, or if the sector sequence cannot be determined +#define FDC_ST1_NO_WRITE 0x02 // Not Writable: set when attempting to write to a write-protected disk +#define FDC_ST1_NO_ID 0x01 // No Addr. Mark: set when an ID/(deleted) data address mark cannot be found. + +// Status Register 2 (ST2) flags \ No newline at end of file diff --git a/KFloppyB.HH b/KFloppyB.HH new file mode 100644 index 0000000..7fb9e36 --- /dev/null +++ b/KFloppyB.HH @@ -0,0 +1,19 @@ +// headers for floppy driver +public extern Bool FDCIrq; +public extern U16 fdc_base; +public extern U0 CMOSGetFloppyDrives(); +public extern U0 FDCSendCmd(U16 base, U8 cmd); +public extern U8 FDCReadData(U16 base); +public extern U0 FDCCheckInt(U16 base, U8 *st0, U8 *cyl); +public extern I16 fdc_mtr_ticks; +public extern U8 fdc_mtr_state; +public extern U0 FDCMotorOff(U16 base); +public extern U0 FDCMotorPwrOffTimer(); +public extern U0 FDCMotorCtrl(U16 base, Bool onoff); +public extern I8 FDCRecalibrate(U16 base); +public extern I8 FDCReset(U16 base); +public extern I8 FDCSeek(U16 base, U8 cyli, U8 head); +public extern U0 FDCRead(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); +public extern U0 FDCReadMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); +public extern U0 FDCWrite(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); +public extern U0 FDCWriteMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen); diff --git a/KFloppyDMA.HC b/KFloppyDMA.HC new file mode 100644 index 0000000..bde62ff --- /dev/null +++ b/KFloppyDMA.HC @@ -0,0 +1 @@ +U8 FDC_DMA[0x4800]; // Floppy DMA buffer diff --git a/KStart32.HC b/KStart32.HC deleted file mode 100644 index ec8f67b..0000000 --- a/KStart32.HC +++ /dev/null @@ -1,118 +0,0 @@ -asm { -USE32 -//************************************ -// ASM Global vars not required for 16-bit start-up - ALIGN 8,OC_NOP -MEM_HEAP_BASE:: DU64 0; -MEM_HEAP_LIMIT:: DU64 0; -MEM_PAGE_SIZE:: DU64 0; -MEM_MAPPED_SPACE:: DU64 0; -MEM_2MEG_NUM:: DU64 0; -MEM_1GIG_NUM:: DU64 0; -MEM_512GIG_NUM:: DU64 0; -MEM_PML2:: DU64 0; -MEM_PML3:: DU64 0; -MEM_PML4:: DU64 0; - -#exe { - StreamPrint( -"SYS_MEM_INIT_FLAG:: DU8 %d;" -"SYS_MEM_INIT_VAL:: DU8 %d;" -"SYS_HEAP_INIT_FLAG:: DU8 %d;" -"SYS_HEAP_INIT_VAL:: DU8 %d;" -"SYS_VAR_INIT_FLAG:: DU8 %d;" -"SYS_VAR_INIT_VAL:: DU8 %d;" -"SYS_STAFF_MODE_FLAG:: DU8 %d;", -kernel_cfg->opts[CFG_MEM_INIT], kernel_cfg->mem_init_val, -kernel_cfg->opts[CFG_HEAP_INIT],kernel_cfg->heap_init_val, -kernel_cfg->opts[CFG_VAR_INIT], kernel_cfg->var_init_val, -kernel_cfg->opts[CFG_STAFF_MODE]); -}; -SYS_HEAP_DBG_FLAG:: DU8 _CFG_HEAP_DBG; - - ALIGN 8,0 -SYS_CTRL_ALT_FLAGS:: DU64 0; -SYS_EXTERN_TABLE:: DU64 0; - -SYS_CODE_BP:: DU64 0; -SYS_DATA_BP:: DU64 0; - -SYS_PROGRESSES:: -SYS_PROGRESS1:: DU64 0; -SYS_PROGRESS1_MAX:: DU64 0; -SYS_PROGRESS1_T0:: DU64 0; -SYS_PROGRESS1_TF:: DU64 0; -SYS_PROGRESS1_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); -SYS_PROGRESS2:: DU64 0; -SYS_PROGRESS2_MAX:: DU64 0; -SYS_PROGRESS2_T0:: DU64 0; -SYS_PROGRESS2_TF:: DU64 0; -SYS_PROGRESS2_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); -SYS_PROGRESS3:: DU64 0; -SYS_PROGRESS3_MAX:: DU64 0; -SYS_PROGRESS3_T0:: DU64 0; -SYS_PROGRESS3_TF:: DU64 0; -SYS_PROGRESS3_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); -SYS_PROGRESS4:: DU64 0; -SYS_PROGRESS4_MAX:: DU64 0; -SYS_PROGRESS4_T0:: DU64 0; -SYS_PROGRESS4_TF:: DU64 0; -SYS_PROGRESS4_DESC:: DU8 PROGRESS_DESC_LEN DUP(0); -#assert $$-SYS_PROGRESSES==sizeof(CProgress)*4 - -SYS_FOCUS_TASK:: DU64 0; -SYS_CPU_STRUCTS:: DU64 0; -SYS_MP_CNT:: DU64 1; -SYS_MP_CNT_INITIAL:: DU64 1; -SYS_MP_CNT_LOCK:: DU64 1; - - ALIGN DFT_CACHE_LINE_WIDTH,OC_NOP -SYS_CACHE_LINE_WIDTH:: DU64 DFT_CACHE_LINE_WIDTH; - DU8 DFT_CACHE_LINE_WIDTH-sizeof(CBinFile)-8 DUP(0); -SYS_SEMAS:: DU8 SEMA_SEMAS_NUM*DFT_CACHE_LINE_WIDTH DUP(0); -//************************************ - ALIGN 16,OC_NOP -CORE0_32BIT_INIT:: //Entry point for $LK,"BootRAM",A="MN:BootRAM"$. - PUSH U32 RFLAGG_START - POPFD - MOV EAX,SYS_START_CR0 - MOV_CR0_EAX - - MOV AX,CGDT.boot_ds //LOAD DS SELECTOR - MOV DS,AX - BTS U32 [SYS_RUN_LEVEL],RLf_32BIT - MOV ESI,U32 [SYS_BOOT_PATCH_TABLE_BASE] - MOV EDI,U32 [MEM_BOOT_BASE] - - MOV AX,CGDT.ds - MOV DS,AX - MOV ES,AX - MOV FS,AX - MOV GS,AX - MOV SS,AX - MOV ESP,BOOT_RAM_LIMIT //Tmp Stk - -//Patch abs addresses - MOV ECX,U32 CPatchTableAbsAddr.abs_addres_cnt[ESI] - LEA ESI,U32 CPatchTableAbsAddr.abs_addres[ESI] -@@05: LODSD - ADD EAX,EDI - ADD U32 [EAX],EDI - LOOP @@05 - - DU8 0xEA; //JMP CGDT.cs32:@@10 - DU32 @@10; - DU16 CGDT.cs32; - -@@10: BTS U32 [SYS_RUN_LEVEL],RLf_PATCHED - - CALL SYS_FIND_PCIBIOS_SERVICE_DIR - CALL SYS_FIND_PCI_SERVICES - CALL SYS_INIT_PAGE_TABLES - CALL SYS_INIT_16MEG_SYS_CODE_BP - PUSH U32 0 //Return from next call will be 64-bit - CALL SYS_ENTER_LONG_MODE - - //We fall-thou to $LK,"KStart64",A="FL:::/Kernel/KStart64.HC,1"$, next. -} -U8 FDC_DMA[0x4800]; // Floppy DMA buffer \ No newline at end of file diff --git a/Kernel.PRJ b/Kernel.PRJ deleted file mode 100644 index 158b096..0000000 --- a/Kernel.PRJ +++ /dev/null @@ -1,63 +0,0 @@ -//Compile this by calling $LK,"BootHDIns",A="MN:BootHDIns"$(). -//Don't do it directly. See $LK,"Cmp(\"/Kernel/Kernel\")",A="FF:::/Adam/Opt/Boot/BootHDIns.HC,Cmp(\"/Kernel/Kernel\""$. - -#exe { - Cd(__DIR__);; - Option(OPTf_WARN_PAREN,ON); - Option(OPTf_WARN_DUP_TYPES,ON); - #include "KCfg" - CKCfg *kernel_cfg; - kernel_cfg=KCfgNew; -}; - -#include "KernelA.HH" -#include "KStart16" -#include "KStart32" -#include "KStart64" -#include "KMathA" -#include "KUtils" -#exe {Option(OPTf_KEEP_PRIVATE,ON);}; -#include "/Compiler/CompilerA.HH" -#exe {Option(OPTf_EXTERNS_TO_IMPORTS,ON);}; -#include "/Compiler/CompilerB.HH" -#exe {Option(OPTf_EXTERNS_TO_IMPORTS,OFF);}; -#exe {Option(OPTf_KEEP_PRIVATE,OFF);}; -#include "KernelB.HH" -#include "KExts" -#include "StrA" -#include "KGlbls" -#include "KMathB" -#include "Sched" -#include "Mem/MakeMem" -#include "FontStd" -#include "FontCyrillic" -#include "StrB" -#include "KHashA" -#include "KInts" -#include "KDataTypes" -#include "Compress" -#include "KHashB" -#include "KLoad" -#include "KDate" -#include "StrPrint" -#include "StrScan" -#include "KDefine" -#include "Display" -#include "KMisc" -#include "KDbg" -#include "KeyDev" -#include "KExcept" -#include "SerialDev/MakeSerialDev" -#include "QSort" -#include "KTask" -#include "Job" -#include "PCIBIOS" -#include "MultiProc" -#include "EdLite" -#include "BlkDev/MakeBlkDev" -#include "FunSeg" -#include "KMain" -#include "Floppy.HH" -#include "NewFloppy" - -#exe {KCfgDel(kernel_cfg);}; diff --git a/KernelC.HH b/KernelC.HH deleted file mode 100644 index ffa7c8b..0000000 --- a/KernelC.HH +++ /dev/null @@ -1,787 +0,0 @@ -#help_index "AutoComplete" -#help_file "::/Doc/AutoComplete" -public extern CAutoCompleteGlbls ac; - -#help_index "AutoComplete/Dictionary" -public extern CAutoCompleteDictGlbls acd; - -#help_index "Bit" -public extern I64 BCnt(I64 d); -public extern U8 *rev_bits_table,*set_bits_table; - -#help_index "Boot" -#help_file "::/Doc/Boot" -public extern U0 Reboot(); - -#help_index "Call" -public argpop extern I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size, - /*argpop*/I64 (*fp_addr)(...),...); -//fp_addr can have any fixed number of arguments. - -#help_index "Call/FarCall32" -public _extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant -public _extern C32_EAX U32 c32_eax; -public _extern C32_EBX U32 c32_ebx; -public _extern C32_ECX U32 c32_ecx; -public _extern C32_EDI U32 c32_edi; -public _extern C32_EDX U32 c32_edx; -public _extern C32_EFLAGS U32 c32_eflags; -public _extern C32_ESI U32 c32_esi; - -#help_index "Char/BitMaps" -public extern U32 char_bmp_alpha[16],char_bmp_alpha_numeric[16], -char_bmp_alpha_numeric_no_at[16], char_bmp_word[16], -char_bmp_dec_numeric[16], char_bmp_hex_numeric[16], -char_bmp_white_space[16], char_bmp_non_eol_white_space[16], -char_bmp_zero_cr_nl_cursor[16], char_bmp_zero_tab_cr_nl_cursor[16], -char_bmp_zero_tab_cr_nl_cursor_dollar[16], -char_bmp_macro[16], char_bmp_printable[16], -char_bmp_displayable[16], char_bmp_safe_dollar[16], -char_bmp_filename[16], char_bmp_non_eol[16]; - -#help_index "Char/Conversion" -public extern U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE); -public extern I64 Char2ScanCode(I64 ch,I64 sc_flags=0); -public extern U8 ScanCode2Char(I64 sc); -public extern U8 *ScanCode2KeyName(I64 sc); -public extern F64 Str2F64(U8 *src,U8 **_end_ptr=NULL); -public extern I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL); -public extern U8 *StrScan(U8 *src,U8 *fmt,...); - -#help_index "Char/Conversion;Time/Date/CDate;Date/CDate" -public extern CDate Str2Date(U8 *src); - -#help_index "Char/Flags" -public extern U0 ScanFlags(U8 *_dst_flags,U8 *lst,U8 *src); -public extern U8 *StrPrintFlags(U8 *dst,U8 *lst,I64 flags); - -#help_index "Char/Lists" -public extern I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0); -public extern U8 *LstSub(I64 sub, U8 *lst); - -#help_index "Char/Operations" -public extern U8 *MStrPrint(U8 *fmt,...); -public extern U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0); -public extern U8 *ScaleIndent(U8 *src,F64 indent_scale_factor); -public extern I64 Spaces2Tabs(U8 *dst,U8 *src); -public _extern _STRCMP I64 StrCmp(U8 *st1,U8 *st2); -public _extern _STRCPY U0 StrCpy(U8 *dst,U8 *src); -public extern U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0); -public extern U8 *StrFirstOcc(U8 *src,U8 *marker); -public extern U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL); -public _extern _STRICMP I64 StrICmp(U8 *st1,U8 *st2); -public _extern _STRIMATCH U8 *StrIMatch(U8 *needle,U8 *haystack_str); -public extern U8 *StrLastOcc(U8 *src,U8 *marker); -public extern U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL); -public _extern _STRMATCH U8 *StrMatch(U8 *needle,U8 *haystack_str); -public _extern _STRNCMP I64 StrNCmp(U8 *st1,U8 *st2,I64 n); -public _extern _STRNICMP I64 StrNICmp(U8 *st1,U8 *st2,I64 n); -public extern I64 StrOcc(U8 *src, U8 ch); -public extern U8 *StrPrint(U8 *dst,U8 *fmt,...); -public extern U8 *StrPrintJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv); -public extern U8 *StrUtil(U8 *_src,I64 flags); -public extern U8 *Tabs2Spaces(U8 *src); -public extern Bool WildMatch(U8 *test_str,U8 *wild_str); - -#help_index "Char/Operations;Memory" -public extern U8 *CatPrint(U8 *dst,U8 *fmt,...); - -#help_index "Char/Operations;Memory/Adam Heap" -public extern U8 *AStrNew(U8 *buf); - -#help_index "Char/Operations;Memory/Heap" -public extern U8 *StrNew(U8 *buf,CTask *mem_task=NULL); - -#help_index "Char/Output;StdOut" -public extern U0 GetOutOfDollar(); -public extern Bool IsSilent(); -public extern U0 Print(U8 *fmt,...); -public extern U0 PrintErr(U8 *fmt,...); -public extern U0 PrintWarn(U8 *fmt,...); -public extern U0 PutChars(U64 ch); -extern U0 PutHex(I64 num,I64 width); -public extern U0 PutKey(I64 ch=0,I64 sc=0); -extern U0 PutS(U8 *st); //Use $LK,"Print",A="MN:Print"$() -public extern Bool Silent(Bool val=ON); -extern U8 *StrPrintHex(U8 *dst,I64 num;I64 width); - -#help_index "Char;Debugging/Raw Output;TextBase Layer/Char" -public extern CTextGlbls text; - -#help_index "Compiler/Lex" -public extern U0 HashSrcFileSet(CCmpCtrl *cc, - CHashSrcSym *h,I64 line_num_offset=0); - -#help_index "Compiler;Cmd Line (Typically)" -extern U8 *Load(U8 *filename,I64 ld_flags=0, - CBinFile *bfh_addr=INVALID_PTR); //INVALID_PTR=don't care what load addr - -#help_index "Compression" -public extern CArcCompress *CompressBuf(U8 *src,I64 size,CTask *mem_task=NULL); -public extern U8 *ExpandBuf(CArcCompress *arc,CTask *mem_task=NULL); - -#help_index "Compression/Piece by Piece" -public extern U0 ArcCompressBuf(CArcCtrl *c); -public extern U0 ArcCtrlDel(CArcCtrl *c); -public extern CArcCtrl *ArcCtrlNew(Bool expand,I64 compression_type=CT_8_BIT); -public extern U0 ArcExpandBuf(CArcCtrl *c); -public extern Bool ArcFinishCompression(CArcCtrl *c); - -#help_index "Data Types/Circular Queue" -public extern I64 QueCnt(CQue *head); -public extern CQue *QueCopy(CQue *head,CTask *mem_task=NULL); -public extern U0 QueDel(CQue *head,Bool querem=FALSE); -public extern I64 QueSize(CQue *head); - -#help_index "Data Types/Fifo" -public extern I64 FifoI64Cnt(CFifoI64 *f); -public extern U0 FifoI64Del(CFifoI64 *f); -public extern U0 FifoI64Flush(CFifoI64 *f); -public extern Bool FifoI64Ins(CFifoI64 *f,I64 q); -public extern CFifoI64 *FifoI64New(I64 size,CTask *mem_task=NULL); -public extern Bool FifoI64Peek(CFifoI64 *f,I64 *_q); -public extern Bool FifoI64Rem(CFifoI64 *f,I64 *_q); -public extern I64 FifoU8Cnt(CFifoU8 *f); -public extern U0 FifoU8Del(CFifoU8 *f); -public extern U0 FifoU8Flush(CFifoU8 *f); -public extern Bool FifoU8Ins(CFifoU8 *f,U8 b); -public extern CFifoU8 *FifoU8New(I64 size,CTask *mem_task=NULL); -public extern Bool FifoU8Peek(CFifoU8 *f,U8 *_b); -public extern Bool FifoU8Rem(CFifoU8 *f,U8 *_b); - -#help_index "Data Types/Linked List" -public extern I64 LinkedLstCnt(U8 **_lst); -public extern U8 *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL); -public extern U0 LinkedLstDel(U8 **_lst); -public extern I64 LinkedLstSize(U8 **_lst); - -#help_index "Data Types/Queue Vector" -public extern U0 QueVectU8Del(CQueVectU8 *v); -public extern I64 QueVectU8Get(CQueVectU8 *v,I64 idx); -public extern CQueVectU8 *QueVectU8New(I64 min_idx=0); -public extern U0 QueVectU8Put(CQueVectU8 *v,I64 idx,U8 ch); - -#help_index "Debugging" -public extern U8 *Caller(I64 num=1); -public extern Bool ChkCodePtr(U8 *ptr); -public extern Bool ChkOnStk(U8 *ptr,CTask *task=NULL); -public extern Bool ChkPtr(U8 *ptr); -public extern Bool IsSingleUser(); -public extern Bool IsSysDbg(); -public extern Bool SingleUser(Bool val); -public extern Bool SysDbg(Bool val); -public extern U8 *TaskCaller(CTask *task=NULL, - I64 num=0,Bool saved_context=FALSE); -public extern I64 UnusedStk(CTask *task=NULL); -public extern CDbgGlbls dbg; - -#help_index "Debugging/Debugger" -public extern Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE) //Toggle bpt. -public extern I64 B2(CTask *task=NULL,Bool live=TRUE); -extern CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE); -public extern Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE); -public extern Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE); -public extern Bool DbgMode(Bool val); -public extern Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0); -public extern Bool EdLite(U8 *filename,I64 num=1,I64 edf_dof_flags=0); -extern Bool EdLiteFileLine(U8 *fl_file_line,I64 edf_dof_flags=0); -public extern Bool Fix(I64 edf_dof_flags=0); -public extern U0 FixSet(U8 *filename,I64 line); -public extern U0 G(U8 *ms=INVALID_PTR,CTask *task=NULL); -public extern U0 G2(U8 *ms=INVALID_PTR,CTask *task=NULL); -public extern Bool IsDbgMode(); -public extern U0 S(U8 *ms=INVALID_PTR,CTask *task=NULL); - -#help_index "Debugging/Debugger;DolDoc/Cmd Line (Typically);"\ - "Cmd Line (Typically);Help System" -public extern Bool Man(U8 *st,I64 edf_dof_flags=0); - -#help_index "Debugging/Dump" -public extern U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL); -public extern U0 D(U8 *addr,I64 cnt=0x80,Bool show_offset=TRUE); -public extern U0 Da(U8 **addr,I64 cnt=0x10); -public extern U0 Dm(U8 *addr,I64 cnt=0x80); -public extern U0 Dr(CTask *task=NULL); -public extern U0 StkRep(CTask *task=NULL); -extern I64 *TaskRegAddr(CTask *task,I64 reg_num); - -#help_index "Debugging/FunSeg" -#help_file "::/Doc/DbgFunSeg" -public extern Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL); -public extern U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL); -public extern U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL); -public extern I64 SrcLineNum(U8 *addr,I64 cnt=1); - -#help_index "Debugging/FunSeg;Hash/System" -public extern CHash *FunSegFind(U8 *addr,I64 *_offset); - -#help_index "Debugging/Raw Output" -public extern Bool IsRaw(); -public extern Bool Raw(Bool val); -public extern U0 RawD(I64 mS=100,U8 *addr,I64 cnt=0x80); -public extern U0 RawDm(I64 mS=100,U8 *addr,I64 cnt=0x80); -extern U0 RawDr(CTask *task=NULL); -public extern U0 RawPrint(I64 mS=100,U8 *fmt,...); -public extern U0 RawPutChar(I64 ch); -public extern U0 VGAFlush(); - -#help_index "Debugging;Debugging/Debugger" -public extern U0 Dbg(U8 *msg=NULL,I64 msg_num=0); -public extern U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE); - -#help_index "Define;Char/Define" -#help_file "::/Doc/Define" -public extern U8 *Define(U8 *dname); -public extern CHashDefineStr *DefineLoad(U8 *dname,U8 *st); -public extern U0 DefinePrint(U8 *dname,U8 *src,...); - -#help_index "Define;Char/Define;Char/Lists" -public extern I64 DefineCnt(U8 *dname); -public extern CHashDefineStr *DefineLstLoad(U8 *dname,U8 *lst); -public extern I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0); -public extern U8 *DefineSub(I64 sub,U8 *dname); - -#help_index "Devices;Memory/Page Tables" -public extern U8 *Mem32DevAlloc(I64 size,I64 alignment); -public extern U0 Mem32DevFree(U8 *base); -public extern U8 *Mem64DevAlloc(I64 *_pages1Gig); -public extern U0 Mem64DevFree(U8 *base,I64 pages1Gig); -public extern CDevGlbls dev; - -#help_index "DolDoc/Clip" -public extern CDoc *sys_clip_doc; - -#help_index "DolDoc/Task;StdOut/Task" -#help_file "::/Doc/StdOutTask" -extern CDoc *(*fp_doc_put)(CTask *task=NULL); - -#help_index "Exceptions" -public extern U0 Break(); -public extern Bool BreakLock(CTask *task=NULL); -public extern Bool BreakUnlock(CTask *task=NULL); -public extern U0 PutExcept(Bool catch_it=TRUE); -extern U0 SysTry(U8 *start_label,U8 *skip_label); -extern U0 SysUntry(); -public extern U0 throw(I64 ch=0,Bool no_log=FALSE); - -#help_index "File/CD DVD" -public extern U0 DVDImageRead(U8 dvd_drv_let,U8 *out_name); -public extern U0 DVDImageWrite(U8 dvd_drv_let, - U8 *in_name=NULL,I64 media_type=MT_DVD); - -#help_index "File/CFile" -public extern Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1); -public extern Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1); -public extern U0 FClose(CFile *f); -public extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0); -public extern I64 FSize(CFile *f); - -#help_index "File/Cmd Line (Typically);Cmd Line (Typically)" -public extern Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE); -public extern I64 Del(U8 *files_find_mask,Bool make_mask=FALSE, - Bool del_dir=FALSE,Bool print_msg=TRUE); -public extern I64 Dir(U8 *files_find_mask="*",Bool full=FALSE); -public extern Bool DirMk(U8 *filename,I64 entry_cnt=0); -public extern Bool Drv(U8 drv_let); -public extern U0 DskChg(U8 drv_let=0); -public extern U0 HomeSet(U8 *dirname); - -#help_index "File/Cmd Line (Typically);Cmd Line (Typically);Install" -public extern Bool DrvMap(U8 drv_let,CDrv *dv); - -#help_index "File/FileNames" -extern CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name); -public extern U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL); -public extern U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL); -public extern U8 *DirNameAbs(U8 *dirname); -public extern CBlkDev *DrvIsWritable(U8 drv_let=0,Bool except=FALSE); -public extern U8 *ExtChg(U8 *filename,U8 *extension); -public extern U8 *ExtDft(U8 *filename,U8 *extension); -public extern U8 *FileExtDot(U8 *src); -public extern U8 *FileExtRem(U8 *src,U8 *dst=NULL); -public extern U8 *FileNameAbs(U8 *filename,I64 fuf_flags=0); -public extern Bool FileNameChk(U8 *filename); -public extern Bool FilesFindMatch(U8 *_test_name, - U8 *files_find_mask,I64 fuf_flags=0); -public extern Bool IsDir(U8 *dir_name); -public extern Bool IsDotC(U8 *filename); -public extern Bool IsDotZ(U8 *filename); -public extern U0 PutDirLink(U8 *dirname,U8 *full_name=NULL); -public extern U0 PutFileLink(U8 *filename,U8 *full_name=NULL, - I64 line=0,Bool plain_text=FALSE); -public extern U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum); -public extern U8 *ToggleZorNotZ(U8 *name); - -#help_index "File/FileNames;Misc" -public extern U8 *FileNameTmpTxt(); - -#help_index "File/Internal" -public extern U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE); -public extern CDirContext *DirContextNew(U8 *mask, - Bool make_mask=FALSE,Bool make_dirs=FALSE,Bool no_mask=FALSE); -public extern Bool DirNew(CDrv *dv,U8 *cur_dir, - CDirEntry *tmpde,Bool free_old_chain=TRUE); -extern I64 FileAttr(U8 *name,I64 old_attr=0); - -#help_index "File/Low Level" -#help_file "::/Doc/FileLowLevel" -public extern CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE); -public extern U0 BlkDevDel(CBlkDev *bd); -public extern Bool BlkDevLock(CBlkDev *bd); -public extern CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type); -public extern Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE); -public extern U0 BlkDevsRelease(); -public extern Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt); -public extern Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt); -public extern U0 BlkWriteZero(CDrv *dv,I64 blk,I64 cnt); -public extern I64 Clus2Blk(CDrv *dv,I64 c); -public extern I64 ClusAlloc(CDrv *dv,I64 c=0, - I64 cnt=1,Bool contiguous=FALSE); -public extern I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks); -public extern I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks); -public extern I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1); -public extern I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt); -public extern I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt); -extern Bool CopySingle(U8 *f1,U8 *f2); //Just one file -public extern U8 Drv2Let(CDrv *dv=NULL); -public extern CDrv *DrvChk(CDrv *dv,Bool except=TRUE); -public extern U0 DrvDel(CDrv *dv); -public extern Bool DrvLock(CDrv *dv); -public extern CDrv *DrvMakeFreeSlot(U8 drv_let); -public extern U8 *DrvModelNum(U8 drv_let=0); -public extern U8 DrvNextFreeLet(U8 first_drv_let='C'); -public extern U8 *DrvSerialNum(U8 drv_let=0); -public extern U8 DrvTextAttrGet(U8 drv_let=0); -public extern Bool DrvUnlock(CDrv *dv,Bool rst=FALSE); -public extern U0 DrvsRelease(); -extern U0 FAT32FreeClus(CDrv *dv,I64 c); -public extern CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE); -public extern I64 Let2BlkDevType(U8 drv_let); -public extern CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE); -public extern U8 Let2Let(U8 drv_let=0); -extern I64 Name2DirClus(CDrv *dv,U8 *dirname); -extern I64 Name2ParentDirClus(CDrv *dv,U8 *dirname); -extern U0 RedSeaFreeClus(CDrv *dv,I64 c,I64 cnt); - -#help_index "File/Program Routines" -public extern U0 DirEntryDel(CDirEntry *tmpde); -public extern U0 DirEntryDel2(CDirEntry *tmpde); -public extern U0 DirTreeDel(CDirEntry *tmpde); -public extern U0 DirTreeDel2(CDirEntry *tmpde); -public extern Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0); -public extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL); -public extern I64 FileWrite(U8 *filename, - U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0); - -#help_index "File/Program Routines;File/FileNames" -public extern CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0); - -#help_index "File/System" -public extern CATARep *ATAIDDrvs(CATARep *head,CATARep **_ata_drv, - CATARep **_atapi_drv); -extern CBlkDev *ATAMount(U8 first_drv_let, - I64 type,I64 base0,I64 base1,I64 unit); -extern Bool ATAPIStartStop(CBlkDev *bd,F64 timeout,Bool start); -extern I64 ATAProbe(I64 base0,I64 base1,I64 unit); -extern U0 ATAReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt); -extern U0 ATAWriteBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt); -extern I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN, - Bool whole_drv,Bool make_free); -extern U0 DskCacheInit(I64 size_in_U8s); -public extern U0 DskCacheInvalidate(CDrv *dv); -public extern I64 MountIDEAuto(); -public extern CBlkDevGlbls blkdev; - -#help_index "Graphics/Color" -extern U0 (*fp_set_std_palette)(); -public extern U8 *Color2Str(U8 *buf,CColorROPU32 c); -public extern CColorROPU16 Str2ColorU16(U8 *st); -public extern CColorROPU32 Str2ColorU32(U8 *st); - -#help_index "Hash" -#help_file "::/Doc/Hash" -public _extern _HASH_ADD U0 HashAdd(CHash *tmph,CHashTable *table); -public _extern _HASH_ADD_AFTER U0 HashAddAfter(CHash *tmph, - CHash *pred,CHashTable *table); //Add hash entry after entry. -public _extern _HASH_BUCKET_FIND CHash **HashBucketFind( - U8 *needle_str,CHashTable *haystack_table); -public _extern _HASH_FIND CHash *HashFind(U8 *needle_str, - CHashTable *haystack_table,I64 mask,I64 instance=1); -public _extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind( - U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1); -public _extern _HASH_STR I64 HashStr(U8 *st); -public extern CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL); - -#help_index "Hash/Frame" -#help_file "::/Doc/Frame" -public extern I64 FramePtr(U8 *name,CTask *task=NULL); -public extern CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL); -public extern I64 FramePtrDel(U8 *name,CTask *task=NULL); -public extern I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL); - -#help_index "Hash/System" -public extern U0 HashDel(CHashSrcSym *tmph); -public extern CHashGeneric *HashGenericAdd(U8 *name, - I64 type,I64 val=0,I64 u8=0,I64 u16=0,CTask *task=NULL); -public extern CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE); -public _extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table, - I64 instance=1);//instance must match tmph's -public extern U0 HashTableDel(CHashTable *table); -public extern I64 HashTablePurge(CHashTable *table); -public extern I64 HashTypeNum(CHash *tmph); -public extern I64 HashVal(CHash *tmph); -extern U0 SysSymImportsResolve(U8 *sptr,I64 ld_flags=0); - -#help_index "Hash/System;Char/Lists" -public extern I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table); - -#help_index "Hash/System;Define;Char/Define;Char/Lists" -public extern I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table); - -#help_index "Help System;Debugging/Debugger" -public extern U0 Help(); - -#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically);Install" -public extern U0 DrvRep(); - -#help_index "Install" -#help_file "::/Doc/Install" -extern CATARep *ATARepFind(CATARep *haystack_head,I64 needle_num); -public extern Bool DrvEnable(U8 drv_let,Bool val); - -#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);" -public extern U0 Fmt(U8 drv_let,Bool quick=TRUE, - Bool confirm=TRUE,I64 type=FSt_FAT32); - -#help_index "Install;Memory/BlkPool" -public extern I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024); - -#help_index "Job/Exe;Task/Job/Exe" -public extern U0 AdamErr(U8 *fmt,...); -public extern U0 AdamLog(U8 *fmt,...); -public extern I64 ExeCmdLine(CCmpCtrl *cc); -public extern U0 JobDel(CJob *tmpc); -public extern I64 JobsHndlr(I64 run_flags,CTask *task=NULL); -extern U0 SrvCmdLine(); -public extern U0 SrvTaskCont(); -public extern CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags); -public extern U0 TaskRstAwaitingMsg(CTask *task=NULL); -public extern U0 UserTaskCont(); - -#help_index "Job/Exe;Task/Job/Exe;Compiler" -public extern I64 Adam(U8 *fmt,...); -public extern I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL); -public extern I64 PopUpPrint(U8 *fmt,...); - -#help_index "Job/Exe;Task/Job/Exe;MultiCore" -public extern I64 JobResGet(CJob *rqst=NULL); -public extern Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL); - -#help_index "Job/Text & Msgs;Task/Job/Text & Msgs" -public extern CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags); - -#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;InFile;StdIn/InFile" -public extern U0 In(U8 *fmt,...); -public extern U0 InFile(U8 *filename); -public extern U0 InStr(U8 *fmt,...); -public extern U0 XTalk(CTask *task,U8 *fmt,...); -public extern U0 XTalkStr(CTask *task,U8 *fmt,...); -public extern U0 XTalkStrWait(CTask *task,U8 *fmt,...); -public extern U0 XTalkWait(CTask *task,U8 *fmt,...); - -#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;Messages" -public extern U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0); -public extern U0 PostMsg(CTask *task, - I64 msg_code,I64 arg1,I64 arg2,I64 flags=0); -public extern U0 PostMsgWait(CTask *task,I64 msg_code, - I64 arg1,I64 arg2,I64 flags=0); -public extern CJob *TaskMsg(CTask *srv,CTask *master, - I64 msg_code,I64 arg1,I64 arg2,I64 flags); - -#help_index "Job;Task/Job" -#help_file "::/Doc/Job" - -#help_index "Keyboard Devices/System;Char/System" -#help_file "::/Doc/KeyDev" -public extern U0 CtrlAltCBSet(U8 ch,U0 (*fp_hndlr)(I64 sc), - U8 *no_shift_desc=NULL,U8 *shift_desc=NULL,Bool in_irq=FALSE); -public extern U0 KeyDescSet(U8 *fmt,...); -public extern CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc), - Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE); -public extern U0 KeyDevRem(CKeyDevEntry *tmpk); -extern CKeyDevGlbls keydev; -extern CJob sys_macro_head; -extern CTask *sys_macro_task; - -#help_index "Keyboard Devices;Char/Input;StdIn" -extern U8 *(*fp_getstr2)(I64 flags=0); //GetStr $LK,"Flags",A="MN:GSF_SHIFT_ESC_EXIT"$ -public extern Bool AreYouSure(); -public extern I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE, - Bool raw_cursor=FALSE); -public extern I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE, - Bool raw_cursor=FALSE); -public extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE); -public extern U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0); -extern U0 KbdInit(); -public extern I64 KbdMsEvtTime(); -extern U0 KbdMsHndlr(Bool poll_kbd,Bool poll_ms); -extern U0 KbdMsInit(); -extern I64 KbdMsgsQue(); -public extern U0 KbdTypeMatic(U8 delay); -extern Bool MsHardDrvrInstall(); -public extern I64 PressAKey(); -public extern I64 ScanChar(); -public extern Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE); -public extern Bool YorN(); -public extern CKbdStateGlbls kbd; - -#help_index "Math" -public extern I64 CeilI64(I64 num,I64 to); -public extern U64 CeilU64(U64 num,U64 to); -public extern F64 Clamp(F64 d,F64 lo,F64 hi); -public extern I64 FloorI64(I64 num,I64 to); -public extern U64 FloorU64(U64 num,U64 to); -public extern F64 Max(F64 n1,F64 n2); -public extern F64 Min(F64 n1,F64 n2); -public extern F64 Pow10I64(I64 i); -public extern F64 Rand(); //With timestamp -public extern I16 RandI16(); -public extern I32 RandI32(); -public extern I64 RandI64(); -public extern U16 RandU16(); -public extern U32 RandU32(); -public extern U64 RandU64(); -public extern I64 RoundI64(I64 num,I64 to); -public extern I64 Seed(I64 seed=0,CTask *task=NULL); - -#help_index "Memory/Adam Heap" -public extern U8 *ACAlloc(I64 size); -public extern U8 *AMAlloc(I64 size); -public extern U8 *AMAllocIdent(U8 *src); - -#help_index "Memory/BlkPool" -public extern U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pags); -public extern U0 BlkPoolInit(CBlkPool *bp,I64 pags); -public extern U8 *MemPagAlloc(I64 pags,CBlkPool *bp=NULL); -public extern U0 MemPagFree(CMemBlk *m,CBlkPool *bp=NULL); - -#help_index "Memory/Heap" -public extern U8 *CAlloc(I64 size,CTask *mem_task=NULL); -public extern U8 *CAllocAligned(I64 size,I64 alignment, - CTask *mem_task=NULL,I64 misalignment=0); -public _extern _FREE U0 Free(U8 *addr); -public _extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL); -public extern U8 *MAllocAligned(I64 size,I64 alignment, - CTask *mem_task=NULL,I64 misalignment=0); -public extern U8 *MAllocIdent(U8 *src,CTask *mem_task=NULL); -public _extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src); -public _extern _MSIZE I64 MSize(U8 *src); //size of heap object -public _extern _MSIZE2 I64 MSize2(U8 *src); //Internal size - -#help_index "Memory/HeapCtrl" -public extern U0 HeapCtrlDel(CHeapCtrl *hc); -public extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL, - CTask *task=NULL,CBlkPool *bp); - -#help_index "Memory/Page Tables" -public extern I64 *MemPageTable(U8 *a); - -#help_index "Messages" -#help_file "::/Doc/Msgs" -public extern I64 FlushMsgs(CTask *task=NULL); -public extern I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL, - I64 mask=~1,CTask *task=NULL); -extern U0 InputFilterTask(); -public extern I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL, - I64 mask=~1,CTask *task=NULL); - -#help_index "Misc" -public extern I64 EndianI64(I64 d); -public extern U16 EndianU16(U16 d); -public extern U32 EndianU32(U32 d); -public extern U0 QSort(U8 *base,I64 num, I64 width, - I64 (*fp_compare)(U8 *e1,U8 *e2)); -public extern U0 QSortI64(I64 *base,I64 num, - I64 (*fp_compare)(I64 e1,I64 e2)); -public extern F64 sys_os_version; - -#help_index "Misc/Progress Bars" -public extern U0 ProgressBarsRst(U8 *path=NULL); - -#help_index "Mouse" -#help_file "::/Doc/Mouse" -public extern U0 GridInit(); -public extern U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX, - I64 l=I64_MAX,I64 r=I64_MAX); -public extern CMsStateGlbls ms; -public extern CGridGlbls ms_grid; -public extern CMsHardStateGlbls ms_hard; -extern CMsHardStateGlbls ms_hard_last; -extern CMsStateGlbls ms_last; - -#help_index "Mouse/Ptr" -extern U0 MsInit(); -extern U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r); - -#help_index "MultiCore" -extern U0 Core0StartMP(); -extern U0 CoreAPSethTask(); -public extern U0 MPInt(U8 num,I64 cpu_num=1); -public extern U0 MPIntAll(U8 num); -public extern U0 MPNMInt(); -extern CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL, - U8 *task_name=NULL,I64 target_cpu, - CTask *parent=NULL, //NULL means adam - I64 stk_size=0,I64 flags=1<> 8; -// page = &FDC_DMA >> 16; - cnt_lo = (len - 1) & 0xFF; - cnt_hi = (len - 1) >> 8; - - OutU8(0x0A, 6); // mask ch 0 and 2 - Sleep(1); - OutU8(0x0C, -1); // reset flip flop - Sleep(1); - OutU8(0x04, 0x75); // buf low byte - Sleep(1); - OutU8(0x04, 0x9F); // buf high byte - Sleep(1); - OutU8(0x0C, -1); // reset flip flop again - Sleep(1); - OutU8(0x05, cnt_lo); // cntr low byte - Sleep(1); - OutU8(0x05, cnt_hi); // cntr high byte - Sleep(1); - OutU8(0x81, 0); // page - Sleep(1); - OutU8(0x0A, 2); // unmask ch 0 and 2 - Sleep(1); -} - -U0 FDCDMAPrepWrite() -{ - OutU8(0x0A, 6); // mask ch 0 and 2 - Sleep(1); - OutU8(0x0B, 0x5A); // single xfer, addr inc, auto init, write, ch 2 - Sleep(1); - OutU8(0x0A, 2); // unmask ch 0 and 2 - Sleep(1); -} - -U0 FDCDMAPrepRead() -{ - OutU8(0x0A, 6); // mask ch 0 and 2 - Sleep(1); - OutU8(0x0B, 0x56); // single xfer, addr inc, auto init, read, ch 2 - Sleep(1); - OutU8(0x0A, 2); // unmask ch 0 and 2 - Sleep(1); -} - -interrupt U0 FDCIrqHandler() { - OutU8(0x20, 0x20); // EOI - FDCIrq = TRUE; -} - -U16 fdc_base = 0x03F0; - -static U8 *fd_types[8] = { - "none", - "360kB 5.25\"", - "1.2MB 5.25\"", - "720kB 3.5\"", - - "1.44MB 3.5\"", - "2.88MB 3.5\"", - "unknown type", - "unknown type" -}; - -U0 CMOSGetFloppyDrives() -{ - OutU8(0x70, 0x10); - Sleep(1); - - U64 drives = InU8(0x71); - - AdamLog("Floppy Drive 0: %s\n", fd_types[drives >> 4]); - AdamLog("Floppy Drive 1: %s\n", fd_types[drives & 0xF]); -} - -U0 FDCSendCmd(U16 base, U8 cmd) -{ - // Send a command to the floppy controller - - // 60 sec timeout - U64 i; - for (i = 0; i < 600; i++) { - Sleep(10); - if (0x80 & InU8(base + FDC_MSR_DSR)) { - OutU8(base + FDC_DATA, cmd); - Sleep(1); - return; - } - } - AdamErr("FDC Command TimeOut"); -} - -U8 FDCReadData(U16 base) -{ - // Read data from the floppy controller - - // 60 sec timeout - U64 i; - for (i=0;i<600;i++) { - Sleep(10); - if (0x80 & InU8(base + FDC_MSR_DSR)) { - return InU8(base + FDC_DATA); - } - } - AdamErr("FDC Read TimeOut"); -} - -U0 FDCCheckInt(U16 base, U8 *st0, U8 *cyl) -{ - FDCSendCmd(base, FDC_SENSE_INTR); - - *st0 = FDCReadData(base); - *cyl = FDCReadData(base); -} - -I16 fdc_mtr_ticks = 0; -U8 fdc_mtr_state = FDC_MOTOR_OFF; - -U0 FDCMotorOff(U16 base) -{ - OutU8(base + FDC_DOR, 0x0C); - fdc_mtr_state = FDC_MOTOR_OFF; -} - -U0 FDCMotorPwrOffTimer() -{ - // You're supposed to run this function as a separate CTask. It will exit when the motor - // exits the "wait" state (either because it has turned off or because something needs it to be on). - // The driver only spawns this when the motor is moved from "on" to "wait". - while (fdc_mtr_state == FDC_MOTOR_WAIT) { - // Sanity check for if something wants the motor on at the last second - if (fdc_mtr_state == FDC_MOTOR_ON) break; - - Sleep(500); - - fdc_mtr_ticks -= 50; - if (fdc_mtr_ticks <= 0) { - FDCMotorOff(fdc_base); - } - Yield; // Give control back to the scheduler - } -} - -U0 FDCMotorCtrl(U16 base, Bool onoff) -{ - U64 prev_mtr_state; - if (onoff) { - if (!fdc_mtr_state) { - // Turn on motor - OutU8(base + FDC_DOR, 0x1C); - Sleep(500); // Wait 500 ms to allow drive to spin up - } - fdc_mtr_state = FDC_MOTOR_ON; - } else { - prev_mtr_state = fdc_mtr_state; - if (fdc_mtr_state == FDC_MOTOR_WAIT) { - AdamLog("FDC: Motor PowerOff Already Pending\n"); - } - fdc_mtr_ticks = 300; // 3 sec timeout before motor turns off - fdc_mtr_state = FDC_MOTOR_WAIT; - // Only spawn the timer task of the motor is currently on; infinitely-looping tasks peg the CPU - if (prev_mtr_state != FDC_MOTOR_WAIT) Spawn(&FDCMotorPwrOffTimer,,"FDCMotorPwrOffTimer"); - } -} - -I8 FDCRecalibrate(U16 base) -{ - FDCIrq = FALSE; - - U64 i; - U8 st0, cyl; - - FDCMotorCtrl(base, FDC_MOTOR_ON); - - for (i=0;i<10;i++) { - FDCSendCmd(base, FDC_RECALIBRATE); - FDCSendCmd(base, 0); - - // Wait for an interrupt, then get the status - while (!FDCIrq) Yield; - FDCCheckInt(base, &st0, &cyl); - AdamLog("ST0: %d Cyl: %d\n",st0,cyl); - - if (st0 & 0xC0) { - static U8 * status[4] = {0, "error", "invalid", "drive"}; - AdamLog("Calibration Status: %s\n", status[st0 >> 6]); - } - - if (!cyl) { - FDCMotorCtrl(base, FDC_MOTOR_OFF); - return 0; - } - } - - AdamErr("FDC ReCalibrate TimeOut"); - FDCMotorCtrl(base, FDC_MOTOR_OFF); - return -1; -} - -I8 FDCReset(U16 base) -{ - FDCIrq = FALSE; - - OutU8(base + FDC_DOR, 0x00); - Sleep(1); - OutU8(base + FDC_DOR, 0x0C); - Sleep(1); - - while (!FDCIrq) Yield; - - // Ignore this - U64 i, lck; - U8 st0, cyl; - for (i=0;i<4;i++) { - FDCCheckInt(base, &st0, &cyl); - } - - // Set xfer rate to 500kbps - OutU8(base + FDC_CCR_DIR, 0x00); - Sleep(1); - - // Set the mechanical params and disable DMA (Terry didn't use it) - FDCSendCmd(base, FDC_SPECIFY); - FDCSendCmd(base, 0b10000000); // SRT = 8 (8 ms), HUT = 0 (256 ms) - FDCSendCmd(base, 0b00011110); // HLT = 15 (30 ms), NDMA = 0 (DMA enabled) - - // Configure the FIFO - FDCSendCmd(base, FDC_CONFIGURE); - FDCSendCmd(base, 0x00); // 1st param is a 0 - FDCSendCmd(base, 0b01011011); // 2nd param: Implied seek on, FIFO on, Drive polling disabled, threshold = 12 - FDCSendCmd(base, 0x00); // 3rd param: write precomp = 0 - - // Lock the configuration - FDCSendCmd(base, 0x94); - lck = FDCReadData(base); // Result: lock status - - // contingency - if (FDCRecalibrate(base)) return -1; - - return 0; -} - -I8 FDCSeek(U16 base, U8 cyli, U8 head) -{ - U64 i; - U8 st0, cyl; - FDCIrq = FALSE; - - FDCMotorCtrl(base, FDC_MOTOR_ON); - - for (i=0;i<10;i++) { - // Attempt to move to given cyl - // 1: X X X X X HD D1 D0 - // 2: Cyl No - FDCSendCmd(base, FDC_SEEK); - FDCSendCmd(base, head<<2); - FDCSendCmd(base, cyli); - - while (!FDCIrq) Yield; - FDCCheckInt(base, &st0, &cyl); - AdamLog("ST0: %d Cyl: %d\n",st0,cyl); - - if (st0 & 0xC0) { - static U8 * status[4] = {0, "error", "invalid", "drive"}; - AdamLog("Seek Status: %s\n", status[st0 >> 6]); - } - - if (cyl == cyli) { - FDCMotorCtrl(base, FDC_MOTOR_OFF); - return 0; - } - } - - AdamErr("FDC Seek TimeOut"); - FDCMotorCtrl(base, FDC_MOTOR_OFF); - return -1; -} - -U0 FDCRead(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) -{ - // Read data from disk (single-track) - static U8 flags; - flags = 0x40; // Multi-track off, MFM modulation - static U64 cmd; - cmd = FDC_READ_DATA | flags; - FDCIrq = FALSE; - - U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; - - FDCMotorCtrl(base, FDC_MOTOR_ON); - - AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); - - // Prepare the DMA controller - AdamLog("Preparing DMA\n"); - FDCDMAInit(512*(trklen - sect + 1)); - FDCDMAPrepRead(); - - FDCSendCmd(base, cmd); - FDCSendCmd(base, head << 2); // Drive 0, specified head - FDCSendCmd(base, cyl); - FDCSendCmd(base, head); - FDCSendCmd(base, sect); - FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes - FDCSendCmd(base, trklen); // Track Length/Max Sector No. - FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") - FDCSendCmd(base, 0xFF); // Data Length (irrelevant) - - // Wait for xfer to complete - while (!FDCIrq) Yield; - - st0 = FDCReadData(base); - st1 = FDCReadData(base); - st2 = FDCReadData(base); - rcyl = FDCReadData(base); - rhd = FDCReadData(base); - rsect = FDCReadData(base); - rsectsize = FDCReadData(base); - - AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); - - FDCMotorCtrl(base, FDC_MOTOR_OFF); -} - - -U0 FDCReadMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) -{ - // Read data from disk (multi-track) - static U8 flags; - flags = 0xC0; // Multi-track on, MFM modulation - static U64 cmd; - cmd = FDC_READ_DATA | flags; - FDCIrq = FALSE; - - U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; - - FDCMotorCtrl(base, FDC_MOTOR_ON); - - AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); - - // Prepare the DMA controller - AdamLog("Preparing DMA\n"); - FDCDMAInit(512*(trklen - sect + 1)*2); - FDCDMAPrepRead(); - - FDCSendCmd(base, cmd); - FDCSendCmd(base, head << 2); // Drive 0, specified head - FDCSendCmd(base, cyl); - FDCSendCmd(base, head); - FDCSendCmd(base, sect); - FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes - FDCSendCmd(base, trklen); // Track Length/Max Sector No. - FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") - FDCSendCmd(base, 0xFF); // Data Length (irrelevant) - - // Wait for the xfer to complete - while (!FDCIrq) Yield; - - st0 = FDCReadData(base); - st1 = FDCReadData(base); - st2 = FDCReadData(base); - rcyl = FDCReadData(base); - rhd = FDCReadData(base); - rsect = FDCReadData(base); - rsectsize = FDCReadData(base); - - AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); - - FDCMotorCtrl(base, FDC_MOTOR_OFF); -} - -U0 FDCWrite(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) -{ - // Write data to disk (single-track) - static U8 flags; - flags = 0x40; // Multi-track off, MFM modulation - static U64 cmd; - cmd = FDC_WRITE_DATA | flags; - FDCIrq = FALSE; - - U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; - - FDCMotorCtrl(base, FDC_MOTOR_ON); - - AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); - - // Prepare the DMA controller - AdamLog("Preparing DMA\n"); - FDCDMAInit(512*(trklen - sect + 1)); - FDCDMAPrepWrite(); - - FDCSendCmd(base, cmd); - FDCSendCmd(base, head << 2); // Drive 0, specified head - FDCSendCmd(base, cyl); - FDCSendCmd(base, head); - FDCSendCmd(base, sect); - FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes - FDCSendCmd(base, trklen); // Track Length/Max Sector No. - FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") - FDCSendCmd(base, 0xFF); // Data Length (irrelevant) - - // Wait for xfer to complete - while (!FDCIrq) Yield; - - st0 = FDCReadData(base); - st1 = FDCReadData(base); - st2 = FDCReadData(base); - rcyl = FDCReadData(base); - rhd = FDCReadData(base); - rsect = FDCReadData(base); - rsectsize = FDCReadData(base); - - AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); - - FDCMotorCtrl(base, FDC_MOTOR_OFF); -} - - -U0 FDCWriteMulti(U16 base, U8 cyl, U8 head, U8 sect, U8 trklen) -{ - // Write data to disk (multi-track) - static U8 flags; - flags = 0xC0; // Multi-track on, MFM modulation - static U64 cmd; - cmd = FDC_WRITE_DATA | flags; - FDCIrq = FALSE; - - U64 st0, st1, st2, rcyl, rhd, rsect, rsectsize; - - FDCMotorCtrl(base, FDC_MOTOR_ON); - - AdamLog("Cmd: %d\nParams: %d %d %d %d %d %d %d %d\n",cmd,head<<2,cyl,head,sect,2,trklen,0x1B,0xFF); - - // Prepare the DMA controller - AdamLog("Preparing DMA\n"); - FDCDMAInit(512*(trklen - sect + 1)*2); - FDCDMAPrepRead(); - - FDCSendCmd(base, cmd); - FDCSendCmd(base, head << 2); // Drive 0, specified head - FDCSendCmd(base, cyl); - FDCSendCmd(base, head); - FDCSendCmd(base, sect); - FDCSendCmd(base, 2); // Sector size = 2 = 512 bytes - FDCSendCmd(base, trklen); // Track Length/Max Sector No. - FDCSendCmd(base, 0x1B); // GAP3 Length = 27 (3.5") - FDCSendCmd(base, 0xFF); // Data Length (irrelevant) - - // Wait for the xfer to complete - while (!FDCIrq) Yield; - - st0 = FDCReadData(base); - st1 = FDCReadData(base); - st2 = FDCReadData(base); - rcyl = FDCReadData(base); - rhd = FDCReadData(base); - rsect = FDCReadData(base); - rsectsize = FDCReadData(base); - - AdamLog("Read Results:\nST0: %d\nST1: %d\nST2: %d\nCyl: %d\nHead: %d\nSect: %d\nSect Size: %d\n",st0,st1,st2,rcyl,rhd,rsect,rsectsize); - - FDCMotorCtrl(base, FDC_MOTOR_OFF); -} \ No newline at end of file diff --git a/ReadMe.TXT b/ReadMe.TXT index 9e2970a..2c84cb2 100644 --- a/ReadMe.TXT +++ b/ReadMe.TXT @@ -1,21 +1,32 @@ -These files contain the code required for the low-level floppy disk driver. -Currently, there is no block device code that implements this driver. +Copyright (c) 2025 Yoshi128k. +The source code included in this package is licensed under Version 2 +of the Do What The Fuck You Want To Public License; the exact distribution +terms are described in Copying.TXT. +The driver and all demonstration software included with this software package comes +with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. + -System source files from my system are included as a reference. + +These files contain the code required for the low-level floppy disk driver. +Currently, there is no block device code that implements this driver as I +find it a bit beyond my capabilities. To install the driver: -1. Copy Floppy.HC and Floppy.HH to the Kernel directory -2. Copy the headers at the bottom of the provided KernelC.HC into *your* KernelC. -3. Add "U8 FDC_DMA[0x4800];" to the bottom of KStart32.HC; This is the DMA buffer for the floppy disk (yeah, I know, DMA = blasphemy, but it's more reliable than PIO while being just as simple). -4. Add Floppy.HC and Floppy.HH to Kernel.PRJ so that they will be compiled into the kernel. +1. Copy KFloppy.HC, KFloppyA.HH, KFloppyB.HH, and KFloppyDMA.HC to ::/Kernel/ +2. In Kernel.PRJ(.Z), include KFloppyDMA.HC between KStart32 and KStart64; this adds a +buffer for DMA transfers to/from the floppy disk controller (see notes) +3. Then, include KFloppyA.HH and KFloppy.HC at the bottom of the above file. +4. In ::/StartOS.HC, include KFLoppyB.HH after KernelC.HH; this exports the driver +functions for use by your own programs. On startup, you will have to unmask IRQ6 and point its int to the IRQ handler, FDCIrqHandler. -To do this, write 0xB8 to port 0x21, then use IntEntrySet to set the vector for the aforementioned int. +To do this, write 0xB8 to port 0x21, then use IntEntrySet to set the vector for the aforementioned int (this may be included in the startup files). + In HolyC, that would be: -OutU8(0x21,0xB8); -IntEntrySet(0x26,&FDCIrqHandler,IDTET_IRQ); +OutU8(0x21,0xB8); // Unmask IRQ6 +IntEntrySet(0x26,&FDCIrqHandler); // IRQ mode is the default -Use FDCReset to initialize the drive (make sure a disk is inserted; it does not test for one before doing things) +Use FDCReset to initialize the drive (make sure a disk is inserted; it does not test for one before doing things). FDCSeek does what it says. @@ -25,3 +36,19 @@ Data that has been read or is to be written goes in FDC_DMA. (The FDC*Multi funs use multi-track mode; data will be read from both heads) The result of seeks, recalibrations, and data xfers will be displayed in the Adam Task. + +--A note about DMA-- +If things went to plan, I would have use PIO to do data transfers to and from the disk. +However, they didn't, and my dev system would freeze when attempting to read from tracks +beyond 0 (the drive would make a seek noise, at which point it froze). + +In Terry's demands document, he wrote: +"We don't want to do DMA." + +This is a bit ambiguous, as there are two principle forms of DMA in the PC world: + +1. ISA DMA, used by the floppy controller and ISA expansion cards. +2. PCI Busmastering, which is used by modern hardware and is very different from ISA DMA. + +TheTinkerer on the TOS Discord suggested that Terry *may* have been fine ISA DMA, but I would still +consider my usage of it to be at least a little blasphemous (though it is not mentioned in the Charter). \ No newline at end of file -- cgit v1.2.3