Commit Diff


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