Preliminary support for CHS disks.
This commit is contained in:
parent
d1f1bfa974
commit
6a4c1908bb
2
bochsrc
2
bochsrc
@ -11,7 +11,7 @@ floppy_bootsig_check: disabled=0
|
|||||||
floppya: type=none
|
floppya: type=none
|
||||||
# no floppyb
|
# no floppyb
|
||||||
ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
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
|
ata0-slave: type=none
|
||||||
ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15
|
||||||
ata1-master: type=none
|
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
|
add word [addr_packet_start_block], secreadcnt
|
||||||
loop read_loop
|
loop read_loop
|
||||||
entry:
|
entry:
|
||||||
mov ax,0x2403 ; A20 BIOS Support
|
;mov ax,0x2403 ; A20 BIOS Support
|
||||||
int 0x15
|
;int 0x15
|
||||||
jb .no_a20
|
;jb .no_a20
|
||||||
cmp ah,0
|
;cmp ah,0
|
||||||
jnz .no_a20
|
;jnz .no_a20
|
||||||
mov ax,0x2401 ; A20 BIOS Activate
|
;mov ax,0x2401 ; A20 BIOS Activate
|
||||||
int 0x15
|
;int 0x15
|
||||||
.no_a20:
|
;.no_a20:
|
||||||
cli ; no interrupts
|
cli ; no interrupts
|
||||||
xor ax,ax
|
xor ax,ax
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
@ -39,15 +39,41 @@ mov eax, cr0 ; set pmode bit
|
|||||||
or al, 1
|
or al, 1
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
jmp 08h:Pmode
|
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:
|
err:
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
mov si, string
|
mov si, string
|
||||||
mov cx, string_end - 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:
|
print:
|
||||||
push 0xb800
|
push 0xb800
|
||||||
pop es
|
pop es
|
||||||
@ -57,9 +83,9 @@ err_print:
|
|||||||
lodsb
|
lodsb
|
||||||
stosw
|
stosw
|
||||||
loop err_print
|
loop err_print
|
||||||
add di, 2
|
;add di, 2
|
||||||
mov ax, bx
|
;mov ax, bx
|
||||||
call hexprint
|
;call hexprint
|
||||||
hlt_loop:
|
hlt_loop:
|
||||||
hlt
|
hlt
|
||||||
jmp hlt_loop
|
jmp hlt_loop
|
||||||
@ -100,20 +126,57 @@ mov [esi], esi
|
|||||||
mov [edi], edi
|
mov [edi], edi
|
||||||
cmpsd
|
cmpsd
|
||||||
jne .kernel
|
jne .kernel
|
||||||
in al, 0x92 ; fast A20
|
call enable_A20
|
||||||
test al, 2
|
;in al, 0x92 ; fast A20
|
||||||
jnz .fa20_end
|
;test al, 2
|
||||||
or al, 2
|
;jnz .fa20_end
|
||||||
and al, 0xFE
|
;or al, 2
|
||||||
out 0x92, al
|
;and al, 0xFE
|
||||||
.fa20_end:
|
;out 0x92, al
|
||||||
|
;.fa20_end:
|
||||||
jmp .a20
|
jmp .a20
|
||||||
.kernel:
|
.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 edi, 0x100000
|
||||||
mov ecx, 0x10000
|
mov ecx, 0x10000
|
||||||
rep movsb
|
rep movsb
|
||||||
jmp 08h:0x100000
|
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:
|
gdt_desc:
|
||||||
dw gdt_end - gdt
|
dw gdt_end - gdt
|
||||||
@ -134,12 +197,12 @@ gdt_end:
|
|||||||
|
|
||||||
string: db 'DISK ERROR'
|
string: db 'DISK ERROR'
|
||||||
string_end:
|
string_end:
|
||||||
no_exten_str: db 'NO INT13 EXTEN'
|
;no_exten_str: db 'NO INT13 EXTEN'
|
||||||
no_exten_str_end:
|
;no_exten_str_end:
|
||||||
|
|
||||||
addr_packet:
|
addr_packet:
|
||||||
db 0x10, 0x00 ; size, reserved
|
db 0x10, 0x00 ; size, reserved
|
||||||
dw secreadcnt ; blocks
|
dw secreadcnt ; blocks
|
||||||
addr_packet_transfer_buff_off: dw 0x0000 ; transfer buffer offset
|
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
|
addr_packet_start_block: dq 1 ; start block
|
||||||
|
@ -11,7 +11,17 @@
|
|||||||
#include "dosfs.h"
|
#include "dosfs.h"
|
||||||
#include "tmpstring.c"
|
#include "tmpstring.c"
|
||||||
#include "../v86defs.h"
|
#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) {
|
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,
|
// NOTE If the buffer provided is outside the 0x20000-0x2FE00 range,
|
||||||
// the function will use that buffer for the Virtual 8086 process
|
// 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;
|
uint8_t *v86buf = buffer;
|
||||||
if ((uintptr_t)v86buf < 0x20000 || (uintptr_t)v86buf > 0x2FE00)
|
if ((uintptr_t)v86buf < 0x20000 || (uintptr_t)v86buf > 0x2FE00)
|
||||||
v86buf = (uint8_t *)0x20000;
|
v86buf = (uint8_t *)0x20000;
|
||||||
v86disk_addr_packet.start_block = sector;
|
|
||||||
v86disk_addr_packet.blocks = count;
|
// TODO This check should probably happen at the kernel level
|
||||||
v86disk_addr_packet.transfer_buffer =
|
if (useCHS == -1) {
|
||||||
(uintptr_t)v86buf & 0x000F |
|
union V86Regs_t regs;
|
||||||
(((uintptr_t)v86buf & 0xFFFF0) << 12);
|
// Check for INT 13 Extensions support
|
||||||
union V86Regs_t regs;
|
regs.h.ah = 0x41;
|
||||||
FARPTR v86_entry = i386LinearToFp(v86DiskRead);
|
regs.w.bx = 0x55AA;
|
||||||
enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
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)
|
if (v86buf != buffer)
|
||||||
memcpy(buffer, v86buf, count * SECTOR_SIZE);
|
memcpy(buffer, v86buf, count * SECTOR_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
|
13
entry.nasm
13
entry.nasm
@ -1,5 +1,8 @@
|
|||||||
global entry
|
global entry
|
||||||
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
|
lgdt [gdt_desc] ; load gdt register
|
||||||
jmp 08h:Pmodecode
|
jmp 08h:Pmodecode
|
||||||
|
|
||||||
@ -19,9 +22,19 @@ mov eax, 0x1f001f00
|
|||||||
mov ecx, (80*25)/2
|
mov ecx, (80*25)/2
|
||||||
mov edi, 0xb8000
|
mov edi, 0xb8000
|
||||||
rep stosd ; clear screen
|
rep stosd ; clear screen
|
||||||
|
mov eax, dword [kernel_check]
|
||||||
|
cmp eax, 0x12345678
|
||||||
|
jne err
|
||||||
call start
|
call start
|
||||||
hlt_loop:
|
hlt_loop:
|
||||||
hlt
|
hlt
|
||||||
jmp hlt_loop
|
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 start
|
||||||
|
extern kernel_check
|
||||||
|
@ -24,6 +24,8 @@ jmp .hlt
|
|||||||
|
|
||||||
global _gpf_eax_save
|
global _gpf_eax_save
|
||||||
_gpf_eax_save: dd 0
|
_gpf_eax_save: dd 0
|
||||||
|
global _gpf_eflags_save
|
||||||
|
_gpf_eflags_save: dd 0
|
||||||
extern gpf_handler_v86
|
extern gpf_handler_v86
|
||||||
global gpfHandler
|
global gpfHandler
|
||||||
gpfHandler:
|
gpfHandler:
|
||||||
@ -52,6 +54,7 @@ pop ecx
|
|||||||
pop ebx
|
pop ebx
|
||||||
sti ; we shouldn't crash now?
|
sti ; we shouldn't crash now?
|
||||||
mov eax, dword [esp+16] ; EFLAGS
|
mov eax, dword [esp+16] ; EFLAGS
|
||||||
|
mov dword [_gpf_eflags_save], eax ; save
|
||||||
and eax, 1 << 17 ; VM flag
|
and eax, 1 << 17 ; VM flag
|
||||||
test eax, eax
|
test eax, eax
|
||||||
pop eax
|
pop eax
|
||||||
|
1
kernel.c
1
kernel.c
@ -297,6 +297,7 @@ void FileSelect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t kernel_check= 0x12345678;
|
||||||
void start() {
|
void start() {
|
||||||
word *vga_text = (word *)0xb8000;
|
word *vga_text = (word *)0xb8000;
|
||||||
char h[] = "LuciaOS";
|
char h[] = "LuciaOS";
|
||||||
|
4
link.ld
4
link.ld
@ -4,11 +4,11 @@ ENTRY(entry)
|
|||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x100000;
|
. = 0x100000;
|
||||||
|
|
||||||
.text : ALIGN(0x1000) {
|
.text : {
|
||||||
*(.text);
|
*(.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : ALIGN(0x1000) {
|
.data : {
|
||||||
*(.data);
|
*(.data);
|
||||||
*(.rodata);
|
*(.rodata);
|
||||||
*(.rodata*);
|
*(.rodata*);
|
||||||
|
70
tests.c
70
tests.c
@ -34,23 +34,74 @@ char TestUser() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void TestDiskRead() {
|
void TestDiskRead() {
|
||||||
|
//vga_text += printStr("Starting Disk Read... ", vga_text);
|
||||||
union V86Regs_t regs;
|
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;
|
char *diskReadBuf = (char *)0x20000;
|
||||||
v86disk_addr_packet.transfer_buffer =
|
v86disk_addr_packet.transfer_buffer =
|
||||||
(uintptr_t)diskReadBuf & 0x000F |
|
(uintptr_t)diskReadBuf & 0x000F |
|
||||||
(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
|
(((uintptr_t)diskReadBuf & 0xFFFF0) << 12);
|
||||||
FARPTR v86_entry = i386LinearToFp(v86DiskRead);
|
FARPTR v86_entry = i386LinearToFp(v86DiskRead);
|
||||||
enter_v86(0x0000, 0x8000, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
|
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++) {
|
for (int i = 0; i < (80*25)/2; i++) {
|
||||||
printByte(diskReadBuf[i], &vga_text[i*2]);
|
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() {
|
void TestFAT() {
|
||||||
uint16_t *vga_text = (uint16_t *)0xb8000;
|
uint16_t *vga_text = (uint16_t *)0xb8000;
|
||||||
uint8_t *diskReadBuf = (uint8_t *)0x22400;
|
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);
|
vga_text += printStr("Usermode test failed! Press any key to continue.", vga_text);
|
||||||
}
|
}
|
||||||
kbd_wait();
|
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();
|
TestDiskRead();
|
||||||
kbd_wait();
|
kbd_wait();
|
||||||
TestFAT();
|
TestFAT();
|
||||||
|
20
v86.nasm
20
v86.nasm
@ -108,3 +108,23 @@ db 0x10, 0x00 ; size, reserved
|
|||||||
dw 0x1 ; blocks
|
dw 0x1 ; blocks
|
||||||
dd 0x23000000 ; transfer buffer 0x23000
|
dd 0x23000000 ; transfer buffer 0x23000
|
||||||
dq 0x1 ; start block
|
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
|
||||||
|
@ -9,6 +9,8 @@ extern void v86TransFlag();
|
|||||||
extern void v86Interrupt();
|
extern void v86Interrupt();
|
||||||
extern void v86TextMode();
|
extern void v86TextMode();
|
||||||
extern void v86DiskRead();
|
extern void v86DiskRead();
|
||||||
|
extern void v86DiskGetGeometry();
|
||||||
|
extern void v86DiskReadCHS();
|
||||||
|
|
||||||
union __attribute((__packed__)) V86Regs_t {
|
union __attribute((__packed__)) V86Regs_t {
|
||||||
struct dword_regs {
|
struct dword_regs {
|
||||||
|
Loading…
Reference in New Issue
Block a user