Preliminary support for CHS disks.
This commit is contained in:
		
							
								
								
									
										2
									
								
								bochsrc
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								bochsrc
									
									
									
									
									
								
							@@ -11,7 +11,7 @@ floppy_bootsig_check: disabled=0
 | 
			
		||||
floppya: type=none
 | 
			
		||||
# no floppyb
 | 
			
		||||
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
 | 
			
		||||
ata0-master: type=disk, path="virtdisk.bin", mode=flat, cylinders=2, heads=16, spt=63, sect_size=512, model="Generic 1234", biosdetect=auto, translation=auto
 | 
			
		||||
ata0-master: type=disk, path="virtdisk.bin", mode=flat, cylinders=8, heads=16, spt=63, sect_size=512, model="Generic 1234", biosdetect=auto, translation=auto
 | 
			
		||||
ata0-slave: type=none
 | 
			
		||||
ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15
 | 
			
		||||
ata1-master: type=none
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										117
									
								
								boot.nasm
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								boot.nasm
									
									
									
									
									
								
							@@ -23,14 +23,14 @@ add word [addr_packet_transfer_buff_seg], (secreadcnt*512)/16
 | 
			
		||||
add word [addr_packet_start_block], secreadcnt
 | 
			
		||||
loop read_loop
 | 
			
		||||
entry:
 | 
			
		||||
mov ax,0x2403 ; A20 BIOS Support
 | 
			
		||||
int 0x15
 | 
			
		||||
jb .no_a20
 | 
			
		||||
cmp ah,0
 | 
			
		||||
jnz .no_a20
 | 
			
		||||
mov ax,0x2401 ; A20 BIOS Activate
 | 
			
		||||
int 0x15
 | 
			
		||||
.no_a20:
 | 
			
		||||
;mov ax,0x2403 ; A20 BIOS Support
 | 
			
		||||
;int 0x15
 | 
			
		||||
;jb .no_a20
 | 
			
		||||
;cmp ah,0
 | 
			
		||||
;jnz .no_a20
 | 
			
		||||
;mov ax,0x2401 ; A20 BIOS Activate
 | 
			
		||||
;int 0x15
 | 
			
		||||
;.no_a20:
 | 
			
		||||
cli             ; no interrupts
 | 
			
		||||
xor ax,ax
 | 
			
		||||
mov ds, ax
 | 
			
		||||
@@ -39,15 +39,41 @@ mov eax, cr0    ; set pmode bit
 | 
			
		||||
or al, 1
 | 
			
		||||
mov cr0, eax
 | 
			
		||||
jmp 08h:Pmode
 | 
			
		||||
no_exten:
 | 
			
		||||
; read with CHS
 | 
			
		||||
; FIXME This only reads up to sector count
 | 
			
		||||
mov ah,8
 | 
			
		||||
int 0x13 ; geometry
 | 
			
		||||
and cx, 0x3f
 | 
			
		||||
push cx
 | 
			
		||||
push 0x0080 ; DH=head,DL=disk
 | 
			
		||||
push 0x2000 ; buffer seg
 | 
			
		||||
push 2 ; sector
 | 
			
		||||
.loop:
 | 
			
		||||
mov ax, [esp]
 | 
			
		||||
push 0xb800
 | 
			
		||||
pop es
 | 
			
		||||
xor di,di
 | 
			
		||||
call hexprint
 | 
			
		||||
mov ax, [esp+2]
 | 
			
		||||
mov es, ax
 | 
			
		||||
mov ax, 0x0201
 | 
			
		||||
mov cx, [esp]
 | 
			
		||||
xor bx,bx
 | 
			
		||||
mov dx, [esp+4]
 | 
			
		||||
int 0x13
 | 
			
		||||
jc err
 | 
			
		||||
add word [esp+2], 0x20
 | 
			
		||||
mov cx, [esp]
 | 
			
		||||
inc cl
 | 
			
		||||
mov [esp], cx
 | 
			
		||||
cmp cl, [esp+6]
 | 
			
		||||
jg entry
 | 
			
		||||
jmp .loop
 | 
			
		||||
err:
 | 
			
		||||
mov bx, ax
 | 
			
		||||
mov si, string
 | 
			
		||||
mov cx, string_end - string
 | 
			
		||||
jmp print
 | 
			
		||||
no_exten:
 | 
			
		||||
mov bx, ax
 | 
			
		||||
mov si, no_exten_str
 | 
			
		||||
mov cx, no_exten_str_end - no_exten_str
 | 
			
		||||
print:
 | 
			
		||||
push 0xb800
 | 
			
		||||
pop es
 | 
			
		||||
@@ -57,9 +83,9 @@ err_print:
 | 
			
		||||
lodsb
 | 
			
		||||
stosw
 | 
			
		||||
loop err_print
 | 
			
		||||
add di, 2
 | 
			
		||||
mov ax, bx
 | 
			
		||||
call hexprint
 | 
			
		||||
;add di, 2
 | 
			
		||||
;mov ax, bx
 | 
			
		||||
;call hexprint
 | 
			
		||||
hlt_loop:
 | 
			
		||||
hlt
 | 
			
		||||
jmp hlt_loop
 | 
			
		||||
@@ -100,20 +126,57 @@ mov [esi], esi
 | 
			
		||||
mov [edi], edi
 | 
			
		||||
cmpsd
 | 
			
		||||
jne .kernel
 | 
			
		||||
in al, 0x92 ; fast A20
 | 
			
		||||
test al, 2
 | 
			
		||||
jnz .fa20_end
 | 
			
		||||
or al, 2
 | 
			
		||||
and al, 0xFE
 | 
			
		||||
out 0x92, al
 | 
			
		||||
.fa20_end:
 | 
			
		||||
call enable_A20
 | 
			
		||||
;in al, 0x92 ; fast A20
 | 
			
		||||
;test al, 2
 | 
			
		||||
;jnz .fa20_end
 | 
			
		||||
;or al, 2
 | 
			
		||||
;and al, 0xFE
 | 
			
		||||
;out 0x92, al
 | 
			
		||||
;.fa20_end:
 | 
			
		||||
jmp .a20
 | 
			
		||||
.kernel:
 | 
			
		||||
mov esi, 0x8000
 | 
			
		||||
;mov dword [0xb8000], 0x07000700 | 'P' | 'M' << 16
 | 
			
		||||
;mov dword [0xb8004], 0x07000700 | 'O' | 'D' << 16
 | 
			
		||||
;mov dword [0xb8008], 0x07000700 | 'E' | ' ' << 16
 | 
			
		||||
mov esi, 0x20000
 | 
			
		||||
mov edi, 0x100000
 | 
			
		||||
mov ecx, 0x10000
 | 
			
		||||
rep movsb
 | 
			
		||||
jmp 08h:0x100000
 | 
			
		||||
enable_A20:
 | 
			
		||||
        cli
 | 
			
		||||
        call    a20wait
 | 
			
		||||
        mov     al,0xAD
 | 
			
		||||
        out     0x64,al
 | 
			
		||||
        call    a20wait
 | 
			
		||||
        mov     al,0xD0
 | 
			
		||||
        out     0x64,al
 | 
			
		||||
        call    a20wait2
 | 
			
		||||
        in      al,0x60
 | 
			
		||||
        push    eax
 | 
			
		||||
        call    a20wait
 | 
			
		||||
        mov     al,0xD1
 | 
			
		||||
        out     0x64,al
 | 
			
		||||
        call    a20wait
 | 
			
		||||
        pop     eax
 | 
			
		||||
        or      al,2
 | 
			
		||||
        out     0x60,al
 | 
			
		||||
        call    a20wait
 | 
			
		||||
        mov     al,0xAE
 | 
			
		||||
        out     0x64,al
 | 
			
		||||
        call    a20wait
 | 
			
		||||
        ret
 | 
			
		||||
a20wait:
 | 
			
		||||
        in      al,0x64
 | 
			
		||||
        test    al,2
 | 
			
		||||
        jnz     a20wait
 | 
			
		||||
        ret
 | 
			
		||||
a20wait2:
 | 
			
		||||
        in      al,0x64
 | 
			
		||||
        test    al,1
 | 
			
		||||
        jz      a20wait2
 | 
			
		||||
        ret
 | 
			
		||||
 | 
			
		||||
gdt_desc:
 | 
			
		||||
    dw gdt_end - gdt
 | 
			
		||||
@@ -134,12 +197,12 @@ gdt_end:
 | 
			
		||||
 | 
			
		||||
string: db 'DISK ERROR'
 | 
			
		||||
string_end:
 | 
			
		||||
no_exten_str: db 'NO INT13 EXTEN'
 | 
			
		||||
no_exten_str_end:
 | 
			
		||||
;no_exten_str: db 'NO INT13 EXTEN'
 | 
			
		||||
;no_exten_str_end:
 | 
			
		||||
 | 
			
		||||
addr_packet:
 | 
			
		||||
db 0x10, 0x00 ; size, reserved
 | 
			
		||||
dw secreadcnt ; blocks
 | 
			
		||||
addr_packet_transfer_buff_off: dw 0x0000 ; transfer buffer offset
 | 
			
		||||
addr_packet_transfer_buff_seg: dw 0x0800 ; transfer buffer segment
 | 
			
		||||
addr_packet_transfer_buff_seg: dw 0x2000 ; transfer buffer segment
 | 
			
		||||
addr_packet_start_block: dq 1 ; start block
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,17 @@
 | 
			
		||||
#include "dosfs.h"
 | 
			
		||||
#include "tmpstring.c"
 | 
			
		||||
#include "../v86defs.h"
 | 
			
		||||
#include "../print.h"
 | 
			
		||||
 | 
			
		||||
extern uint32_t _gpf_eax_save;
 | 
			
		||||
extern uint32_t _gpf_eflags_save;
 | 
			
		||||
extern uint16_t error_screen[80*50]; // defined in kernel.c
 | 
			
		||||
__attribute((__no_caller_saved_registers__))
 | 
			
		||||
extern void error_environment(); // defined in kernel.c
 | 
			
		||||
uint32_t numHead;
 | 
			
		||||
uint32_t secPerTrack;
 | 
			
		||||
uint32_t maxCylinder;
 | 
			
		||||
char useCHS = -1;
 | 
			
		||||
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count) {
 | 
			
		||||
	// NOTE If the buffer provided is outside the 0x20000-0x2FE00 range,
 | 
			
		||||
	// the function will use that buffer for the Virtual 8086 process
 | 
			
		||||
@@ -19,14 +29,61 @@ uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t
 | 
			
		||||
	uint8_t *v86buf = buffer;
 | 
			
		||||
	if ((uintptr_t)v86buf < 0x20000 || (uintptr_t)v86buf > 0x2FE00)
 | 
			
		||||
		v86buf = (uint8_t *)0x20000;
 | 
			
		||||
	v86disk_addr_packet.start_block = sector;
 | 
			
		||||
	v86disk_addr_packet.blocks = count;
 | 
			
		||||
	v86disk_addr_packet.transfer_buffer =
 | 
			
		||||
		(uintptr_t)v86buf & 0x000F |
 | 
			
		||||
		(((uintptr_t)v86buf & 0xFFFF0) << 12);
 | 
			
		||||
	union V86Regs_t regs;
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
 | 
			
		||||
	// TODO This check should probably happen at the kernel level
 | 
			
		||||
	if (useCHS == -1) {
 | 
			
		||||
		union V86Regs_t regs;
 | 
			
		||||
		// Check for INT 13 Extensions support
 | 
			
		||||
		regs.h.ah = 0x41;
 | 
			
		||||
		regs.w.bx = 0x55AA;
 | 
			
		||||
		regs.h.dl = 0x80;
 | 
			
		||||
		V8086Int(0x13, ®s);
 | 
			
		||||
		// LBA supported if CF clear
 | 
			
		||||
		if (!(_gpf_eflags_save & 0x1)) {
 | 
			
		||||
			useCHS = 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			FARPTR v86_entry = i386LinearToFp(v86DiskGetGeometry);
 | 
			
		||||
			enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
			// check CF for error
 | 
			
		||||
			if (_gpf_eflags_save & 0x1) {
 | 
			
		||||
				uint16_t *vga = error_screen;
 | 
			
		||||
				vga += printStr("Could not get Disk Geometry.", vga);
 | 
			
		||||
				error_environment();
 | 
			
		||||
				for(;;);
 | 
			
		||||
			}
 | 
			
		||||
			numHead = ((_gpf_eax_save & 0xff00) >> 8) + 1;
 | 
			
		||||
			secPerTrack = _gpf_eax_save & 0x3f;
 | 
			
		||||
			maxCylinder = ((_gpf_eax_save & 0xff0000) >> 16) | ((_gpf_eax_save & 0xc0) << 2);
 | 
			
		||||
			useCHS = 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO Do error handling
 | 
			
		||||
	if (!useCHS) {
 | 
			
		||||
		// LBA Read
 | 
			
		||||
		v86disk_addr_packet.start_block = sector;
 | 
			
		||||
		v86disk_addr_packet.blocks = count;
 | 
			
		||||
		v86disk_addr_packet.transfer_buffer =
 | 
			
		||||
			(uintptr_t)v86buf & 0x000F |
 | 
			
		||||
			(((uintptr_t)v86buf & 0xFFFF0) << 12);
 | 
			
		||||
		union V86Regs_t regs;
 | 
			
		||||
		FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
			
		||||
		enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
	} else {
 | 
			
		||||
        uint32_t tmp = sector / secPerTrack;
 | 
			
		||||
        uint32_t sec = (sector % (secPerTrack)) + 1;
 | 
			
		||||
        uint32_t head = tmp % numHead;
 | 
			
		||||
        uint32_t cyl = tmp / numHead;
 | 
			
		||||
		union V86Regs_t regs;
 | 
			
		||||
        regs.w.ax = 0x0201;
 | 
			
		||||
        regs.h.ch = cyl & 0xff;
 | 
			
		||||
        regs.h.cl = sec | ((cyl >> 2) & 0xc0);
 | 
			
		||||
        regs.h.dh = head;
 | 
			
		||||
        regs.h.dl = 0x80;
 | 
			
		||||
        regs.w.bx = (uintptr_t)v86buf & 0xFFFF;
 | 
			
		||||
        FARPTR v86_entry = i386LinearToFp(v86DiskReadCHS);
 | 
			
		||||
        enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
	}
 | 
			
		||||
	if (v86buf != buffer)
 | 
			
		||||
		memcpy(buffer, v86buf, count * SECTOR_SIZE);
 | 
			
		||||
	return 0;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								entry.nasm
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								entry.nasm
									
									
									
									
									
								
							@@ -1,5 +1,8 @@
 | 
			
		||||
global entry
 | 
			
		||||
entry:
 | 
			
		||||
mov dword [0xb8000], 0x07000700 | 'E' | 'N' << 16
 | 
			
		||||
mov dword [0xb8004], 0x07000700 | 'T' | 'R' << 16
 | 
			
		||||
mov dword [0xb8008], 0x07000700 | 'Y' | ' ' << 16
 | 
			
		||||
lgdt [gdt_desc]  ; load gdt register
 | 
			
		||||
jmp 08h:Pmodecode
 | 
			
		||||
 | 
			
		||||
@@ -19,9 +22,19 @@ mov eax, 0x1f001f00
 | 
			
		||||
mov ecx, (80*25)/2
 | 
			
		||||
mov edi, 0xb8000
 | 
			
		||||
rep stosd ; clear screen
 | 
			
		||||
mov eax, dword [kernel_check]
 | 
			
		||||
cmp eax, 0x12345678
 | 
			
		||||
jne err
 | 
			
		||||
call start
 | 
			
		||||
hlt_loop:
 | 
			
		||||
hlt
 | 
			
		||||
jmp hlt_loop
 | 
			
		||||
err:
 | 
			
		||||
mov dword [0xb8000], 0x07000700 | 'L' | 'O' << 16
 | 
			
		||||
mov dword [0xb8004], 0x07000700 | 'A' | 'D' << 16
 | 
			
		||||
mov dword [0xb8008], 0x07000700 | 'F' | 'A' << 16
 | 
			
		||||
mov dword [0xb800C], 0x07000700 | 'I' | 'L' << 16
 | 
			
		||||
jmp hlt_loop
 | 
			
		||||
 | 
			
		||||
extern start
 | 
			
		||||
extern kernel_check
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,8 @@ jmp .hlt
 | 
			
		||||
 | 
			
		||||
global _gpf_eax_save
 | 
			
		||||
_gpf_eax_save: dd 0
 | 
			
		||||
global _gpf_eflags_save
 | 
			
		||||
_gpf_eflags_save: dd 0
 | 
			
		||||
extern gpf_handler_v86
 | 
			
		||||
global gpfHandler
 | 
			
		||||
gpfHandler:
 | 
			
		||||
@@ -52,6 +54,7 @@ pop ecx
 | 
			
		||||
pop ebx
 | 
			
		||||
sti ; we shouldn't crash now?
 | 
			
		||||
mov eax, dword [esp+16] ; EFLAGS
 | 
			
		||||
mov dword [_gpf_eflags_save], eax ; save
 | 
			
		||||
and eax, 1 << 17 ; VM flag
 | 
			
		||||
test eax, eax
 | 
			
		||||
pop eax
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								kernel.c
									
									
									
									
									
								
							@@ -297,6 +297,7 @@ void FileSelect() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t kernel_check= 0x12345678;
 | 
			
		||||
void start() {
 | 
			
		||||
    word *vga_text = (word *)0xb8000;
 | 
			
		||||
    char h[] = "LuciaOS";
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								link.ld
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								link.ld
									
									
									
									
									
								
							@@ -4,11 +4,11 @@ ENTRY(entry)
 | 
			
		||||
SECTIONS {
 | 
			
		||||
    . = 0x100000;
 | 
			
		||||
 | 
			
		||||
    .text : ALIGN(0x1000) {
 | 
			
		||||
    .text : {
 | 
			
		||||
        *(.text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .data : ALIGN(0x1000) {
 | 
			
		||||
    .data : {
 | 
			
		||||
        *(.data);
 | 
			
		||||
        *(.rodata);
 | 
			
		||||
        *(.rodata*);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								tests.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								tests.c
									
									
									
									
									
								
							@@ -34,23 +34,74 @@ char TestUser() {
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
void TestDiskRead() {
 | 
			
		||||
    //vga_text += printStr("Starting Disk Read... ", vga_text);
 | 
			
		||||
    union V86Regs_t regs;
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000 + (80*5);
 | 
			
		||||
    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
			
		||||
    regs.w.ax = 3; // text mode
 | 
			
		||||
    V8086Int(0x10, ®s); 
 | 
			
		||||
    //vga_text += printStr("Done. Starting Disk Read... ", vga_text);
 | 
			
		||||
    char *diskReadBuf = (char *)0x20000;
 | 
			
		||||
	v86disk_addr_packet.transfer_buffer =
 | 
			
		||||
		(uintptr_t)diskReadBuf & 0x000F |
 | 
			
		||||
		(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
			
		||||
    enter_v86(0x0000, 0x8000, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
    vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    for (int i = 0; i < (80*25)/2; i++) {
 | 
			
		||||
        printByte(diskReadBuf[i], &vga_text[i*2]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
extern uint32_t _gpf_eax_save;
 | 
			
		||||
extern uint32_t _gpf_eflags_save;
 | 
			
		||||
void TestCHS() {
 | 
			
		||||
    uint16_t *vga_text = (uint16_t*)0xb8000;
 | 
			
		||||
    printStr("CHS Test ", vga_text);
 | 
			
		||||
    // CHS Read
 | 
			
		||||
    union V86Regs_t regs;
 | 
			
		||||
    FARPTR v86_entry = i386LinearToFp(v86DiskGetGeometry);
 | 
			
		||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
    // check CF for error
 | 
			
		||||
    if (_gpf_eflags_save & 0x1) {
 | 
			
		||||
        uint16_t *vga = &((uint16_t*)0xb8000)[80];
 | 
			
		||||
        vga += printStr("Could not get Disk Geometry.", vga);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    uint32_t numHead = ((_gpf_eax_save & 0xff00) >> 8) + 1;
 | 
			
		||||
    uint32_t secPerTrack = _gpf_eax_save & 0x3f;
 | 
			
		||||
    uint32_t maxCyl = ((_gpf_eax_save & 0xff0000) >> 16) | ((_gpf_eax_save & 0xc0) << 2);
 | 
			
		||||
    uint32_t maxLBA = numHead * secPerTrack * (maxCyl + 1);
 | 
			
		||||
    for (uint32_t sector = 0; sector < maxLBA && sector < 0x8000 /* don't bother reading huge disks */; sector += (sector + secPerTrack < maxLBA) ? secPerTrack : 1) {
 | 
			
		||||
        uint16_t *vga = &((uint16_t*)0xb8000)[9];
 | 
			
		||||
        vga += printWord(sector, vga); vga++;
 | 
			
		||||
        // LBA -> CHS
 | 
			
		||||
        uint32_t tmp = sector / secPerTrack;
 | 
			
		||||
        uint32_t sec = (sector % (secPerTrack)) + 1;
 | 
			
		||||
        uint32_t head = tmp % numHead;
 | 
			
		||||
        uint32_t cyl = tmp / numHead;
 | 
			
		||||
        vga += printWord(cyl, vga); vga += printChar(':', vga);
 | 
			
		||||
        vga += printByte(head, vga); vga += printChar(':', vga);
 | 
			
		||||
        vga += printByte(sec, vga); vga += printChar(' ', vga);
 | 
			
		||||
        vga += printStr("/ ", vga);
 | 
			
		||||
        vga += printWord(maxCyl, vga); vga += printChar(':', vga);
 | 
			
		||||
        vga += printByte(numHead - 1, vga); vga += printChar(':', vga);
 | 
			
		||||
        vga += printByte(secPerTrack, vga); vga += printChar(' ', vga);
 | 
			
		||||
        regs.w.ax = 0x0201;
 | 
			
		||||
        regs.h.ch = cyl & 0xff;
 | 
			
		||||
        regs.h.cl = sec | ((cyl >> 2) & 0xc0);
 | 
			
		||||
        regs.h.dh = head;
 | 
			
		||||
        regs.h.dl = 0x80;
 | 
			
		||||
        regs.w.bx = 0x0000;
 | 
			
		||||
        v86_entry = i386LinearToFp(v86DiskReadCHS);
 | 
			
		||||
        enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
			
		||||
        // if CF was set, we have error
 | 
			
		||||
        if (_gpf_eflags_save & 0x1) {
 | 
			
		||||
            uint16_t *vga = &((uint16_t*)0xb8000)[80];
 | 
			
		||||
            vga += printStr("Disk Error: ", vga);
 | 
			
		||||
            vga += printByte(_gpf_eax_save & 0xff, vga);
 | 
			
		||||
            vga += printStr(" CHS=", vga);
 | 
			
		||||
            vga += printWord(cyl, vga); vga += printChar(':', vga);
 | 
			
		||||
            vga += printByte(head, vga); vga += printChar(':', vga);
 | 
			
		||||
            vga += printByte(sec, vga);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void TestFAT() {
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x22400;
 | 
			
		||||
@@ -144,6 +195,13 @@ void RunTests() {
 | 
			
		||||
        vga_text += printStr("Usermode test failed! Press any key to continue.", vga_text);
 | 
			
		||||
    }
 | 
			
		||||
    kbd_wait();
 | 
			
		||||
    union V86Regs_t regs;
 | 
			
		||||
    vga_text = (uint16_t *)0xb8000 + (80*5);
 | 
			
		||||
    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
			
		||||
    regs.w.ax = 3; // text mode
 | 
			
		||||
    V8086Int(0x10, ®s); 
 | 
			
		||||
    TestCHS();
 | 
			
		||||
    kbd_wait();
 | 
			
		||||
    TestDiskRead();
 | 
			
		||||
    kbd_wait();
 | 
			
		||||
    TestFAT();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								v86.nasm
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								v86.nasm
									
									
									
									
									
								
							@@ -108,3 +108,23 @@ db 0x10, 0x00 ; size, reserved
 | 
			
		||||
dw 0x1 ; blocks
 | 
			
		||||
dd 0x23000000 ; transfer buffer 0x23000
 | 
			
		||||
dq 0x1 ; start block
 | 
			
		||||
 | 
			
		||||
global v86DiskGetGeometry
 | 
			
		||||
v86DiskGetGeometry:
 | 
			
		||||
mov ah, 8
 | 
			
		||||
mov dl, 0x80
 | 
			
		||||
int 0x13
 | 
			
		||||
movzx eax, ch
 | 
			
		||||
shl eax, 16
 | 
			
		||||
mov al, cl
 | 
			
		||||
mov ah, dh
 | 
			
		||||
int 0x30
 | 
			
		||||
ud2
 | 
			
		||||
 | 
			
		||||
global v86DiskReadCHS
 | 
			
		||||
v86DiskReadCHS:
 | 
			
		||||
push 0x2000
 | 
			
		||||
pop es
 | 
			
		||||
int 0x13
 | 
			
		||||
int 0x30
 | 
			
		||||
ud2
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user