commit 9990f831c9f7692866d7dc6608ac48ed0b817f47 from: Benjamin Stürz date: Sat Oct 05 22:06:30 2024 UTC sys: add initial floppy driver code Floppy drives are such a massive pain in the ass. commit - b6729e0b95ada1c7074add2ca93ce6c01dca8a9c commit + 9990f831c9f7692866d7dc6608ac48ed0b817f47 blob - 722893b531ef4abd9d897099a15cd772593b7b42 blob + 0392e0db74d8749bc01305b5fd88746df0606704 --- sys/Makefile +++ sys/Makefile @@ -1,7 +1,7 @@ .SUFFIXES: .asm .o LDFLAGS = -s --no-pie -OBJ = loader.o kernel.o +OBJ = loader.o kernel.o floppy.o IMG = sys.img blob - 0c67881007e3e0152772558c01203f1f4e03aebd blob + 884330b6194faf72eaf12a1617d8742be1236b92 --- sys/kernel.asm +++ sys/kernel.asm @@ -4,7 +4,13 @@ %include "macros.inc" section .text +extern floppy_init global _entry +global putchar +global puts +global puthexb +global puthexw +global panic _entry: pop dx mov byte [bootdrv], dl @@ -125,6 +131,8 @@ _entry: lea bp, [kbmsg] call puts + call floppy_init + sti jmp $ blob - /dev/null blob + 898c63b83194e4a1572e736bb32054468aa279b1 (mode 644) --- /dev/null +++ sys/floppy.asm @@ -0,0 +1,205 @@ +[bits 16] +[cpu 286] + +%include "macros.inc" + +; Floppy Registers +SRA equ 0x3f0 ; Status Register A RO +SRB equ 0x3f1 ; Status Register B RO +DOR equ 0x3f2 ; Digital Output Register RW +TDR equ 0x3f3 ; Tape Drive Register RW +MSR equ 0x3f4 ; Main Status Register RO +DSR equ 0x3f4 ; Datarate Select Register WO +DFF equ 0x3f5 ; Data FIFO RW +DIR equ 0x3f7 ; Digital Input Register RO +CCR equ 0x3f7 ; Configuration Control Register WO + +DOR_MOTD equ 0x80 ; Drive Motor 3 ON +DOR_MOTC equ 0x40 ; Drive Motor 2 ON +DOR_MOTB equ 0x20 ; Drive Motor 1 ON +DOR_MOTA equ 0x10 ; Drive Motor 0 ON +DOR_IRQ equ 0x08 ; Enable IRQs and DMA +DOR_NRESET equ 0x04 ; 0=enter reset mode, 1=normal operation +DOR_DSEL equ 0x03 ; Select drive number mask + +MSR_RQM equ 0x80 ; It's OK (or mandatory) to exchange bytes with the FIFO IO port +MSR_DIO equ 0x40 ; FIFO expects an IN opcode +MSR_NDMA equ 0x20 ; Set while executing PIO mode read/write commands +MSR_BSY equ 0x10 ; Command Busy +MSR_ACTD equ 0x08 ; Drive 3 is seeking +MSR_ACTC equ 0x04 ; Drive 2 is seeking +MSR_ACTB equ 0x02 ; Drive 1 is seeking +MSR_ACTA equ 0x01 ; Drive 0 is seeking + +DSR_288M equ 0x03 ; 2.88M floppy (1Mbps) +DSR_144M equ 0x00 ; 1.44M floppy (500Kbps) + +; Floppy drive commands +CMD_READ_TRACK equ 2 ; IRQ6 +CMD_SPECIFY equ 3 ; set drive parameters +CMD_SENSE_DRIVE_STATUS equ 4 +CMD_WRITE_DATA equ 5 ; write to disk +CMD_READ_DATA equ 6 ; read from disk +CMD_RECALIBRATE equ 7 ; seek to cylinder 0 +CMD_SENSE_INTERRUPT equ 8 ; ack IRQ6, get status of last command +CMD_WRITE_DELETED_DATA equ 9 +CMD_READ_ID equ 10 ; IRQ6 +CMD_READ_DELETED_DATA equ 12 +CMD_FORMAT_TRACK equ 13 +CMD_DUMPREG equ 14 +CMD_SEEK equ 15 ; seek both heads to cylinder X +CMD_VERSION equ 16 ; used during initialization, once +CMD_SCAN_EQUAL equ 17 +CMD_PERPENDICULAR_MODE equ 18 ; used during initialization, once, maybe +CMD_CONFIGURE equ 19 ; set controller parameters +CMD_LOCK equ 20 ; protect controller parameters from reset +CMD_VERIFY equ 22 +CMD_SCAN_LOW_OR_EQUAL equ 25 +CMD_SCAN_HIGH_OR_EQUAL equ 29 + +CMD_MT equ 0x80 ; multitrack mode +CMD_MF equ 0x40 ; "MFM" magnetic encoding mode. Always set for read/write/format/verify +CMD_SK equ 0x20 ; Skip mode. Skips "deleted sectors" + + +section .text +extern puthexb +extern putchar +extern puts +extern panic +global floppy_init +floppy_init: + lea bp, [fimsg] + call puts + + ; read what types of floppy drives we have + outb_slow 0x70, 0x90 + in al, 0x71 + mov byte [floppy_type], al + call puthexb + + mov al, 10 + call putchar + + lea bp, [vermsg] + call puts + + call version + call puthexb + + mov al, 10 + call putchar + + ret + +wait_rqm: + push cx + mov cx, 128 + +.again: + dec cx + jz error + + mov dx, MSR + in al, dx + test al, MSR_RQM + jz .again + + pop cx + ret + +version: + mov cx, 3 + +.begin: + dec cx + jz error + + ; wait for the controller + mov dx, MSR + in al, dx + and al, (MSR_RQM | MSR_DIO) + cmp al, MSR_RQM + jne .reset + + ; send version command + mov al, CMD_VERSION + mov dx, DFF + out dx, al + + ; wait for version byte + call wait_rqm + test al, MSR_DIO + jz error + + ; read version byte + mov dx, DFF + in al, dx + mov bl, al + + ; wait for completion + call wait_rqm + + ; verify result + mov dx, MSR + in al, dx + and al, (MSR_RQM | MSR_BSY | MSR_DIO) + cmp al, MSR_RQM + jne .retry + mov al, bl + ret + +.retry: + push cx + lea bp, [rtmsg] + call puts + pop cx + jmp .begin + +.reset: + push cx + call reset + pop cx + jmp .begin + +reset: + lea bp, [rsmsg] + jmp puts + +error: + lea bp, [errstr] + jmp panic + +; ax LBA +; return: +; - bx cyl +; - cx head +; - dx sector +lba_to_cha: + xor dx, dx + mov cx, 36 + div cx + mov bx, ax ; cyl + mov ax, dx + xor dx, dx + mov cx, 18 + div cx + mov cx, ax ; head + inc dx ; sector + ret + +section .rodata +errstr: + db "An error occured in the floppy driver", 10, 0 +fimsg: + db "Floppy drive type: 0x", 0 +vermsg: + db "Floppy drive version: 0x", 0 +rsmsg: + db "Resetting floppy drive...", 10, 0 +rtmsg: + db "Retrying last operating", 10, 0 + +section .bss +floppy_type: + resb 1