Lots of general cleanup, Call to specified V86 int (from Kernel and Usermode)
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
				
			|||||||
objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o tests.o kbd.o
 | 
					objects = entry.o kernel.o task.o handler.o interrupt.o v86.o print.o tss.o dosfs/dosfs.o gdt.o usermode.o paging.o fault.o tests.o kbd.o helper.o progs.o
 | 
				
			||||||
CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
 | 
					CFLAGS = -target "i686-elf" -m32 -mgeneral-regs-only -ffreestanding -march=pentium-m -fno-stack-protector -Wno-int-conversion -nostdlib -c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%.o: %.nasm
 | 
					%.o: %.nasm
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "dosfs.h"
 | 
					#include "dosfs.h"
 | 
				
			||||||
#include "tmpstring.c"
 | 
					#include "tmpstring.c"
 | 
				
			||||||
#include "../interrupt.h"
 | 
					 | 
				
			||||||
#include "../v86defs.h"
 | 
					#include "../v86defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								fault.nasm
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								fault.nasm
									
									
									
									
									
								
							@@ -60,7 +60,7 @@ extern get_key
 | 
				
			|||||||
extern task_ptr
 | 
					extern task_ptr
 | 
				
			||||||
extern _enter_v86_internal_no_task
 | 
					extern _enter_v86_internal_no_task
 | 
				
			||||||
extern return_prev_task
 | 
					extern return_prev_task
 | 
				
			||||||
extern v86VideoInt
 | 
					extern v86Interrupt
 | 
				
			||||||
gpf_handler_32:
 | 
					gpf_handler_32:
 | 
				
			||||||
push eax
 | 
					push eax
 | 
				
			||||||
mov eax, dword [esp+8] ; EIP
 | 
					mov eax, dword [esp+8] ; EIP
 | 
				
			||||||
@@ -76,21 +76,27 @@ cmp al, 0x00 ; get key
 | 
				
			|||||||
jne .s1
 | 
					jne .s1
 | 
				
			||||||
call get_key
 | 
					call get_key
 | 
				
			||||||
jmp .return_to_offender
 | 
					jmp .return_to_offender
 | 
				
			||||||
.s1: cmp al, 0x10 ; video interrupt
 | 
					.s1: cmp al, 0x86 ; v86 interrupt call
 | 
				
			||||||
jne .return_to_offender
 | 
					jne .return_to_offender
 | 
				
			||||||
add esp, 4
 | 
					add esp, 4
 | 
				
			||||||
add dword [esp+0], 2
 | 
					add dword [esp+0], 2
 | 
				
			||||||
; add a new task
 | 
					; add a new task
 | 
				
			||||||
call _gpf_create_return_task
 | 
					call _gpf_create_return_task
 | 
				
			||||||
; now enter v86 mode
 | 
					; now enter v86 mode
 | 
				
			||||||
; get regs from return stack
 | 
					; get int & regs from return stack
 | 
				
			||||||
mov eax, [esp+12] ; return esp
 | 
					mov eax, [esp+12] ; return esp
 | 
				
			||||||
mov eax, [eax] ; regs
 | 
					mov eax, [eax] ; interrupt
 | 
				
			||||||
 | 
					and eax, 0xff ; ensure 1 byte
 | 
				
			||||||
 | 
					shl eax, 8
 | 
				
			||||||
 | 
					or eax, 0x30CD00CD ; command
 | 
				
			||||||
 | 
					mov dword [v86Interrupt], eax
 | 
				
			||||||
 | 
					mov eax, [esp+12] ; return esp
 | 
				
			||||||
 | 
					mov eax, [eax+4] ; regs
 | 
				
			||||||
push eax ; regs
 | 
					push eax ; regs
 | 
				
			||||||
mov eax, v86VideoInt
 | 
					mov eax, v86Interrupt
 | 
				
			||||||
and eax, 0xffff
 | 
					and eax, 0xffff
 | 
				
			||||||
push eax ; ip
 | 
					push eax ; ip
 | 
				
			||||||
mov eax, v86VideoInt
 | 
					mov eax, v86Interrupt
 | 
				
			||||||
shr eax, 4
 | 
					shr eax, 4
 | 
				
			||||||
and eax, 0xf000
 | 
					and eax, 0xf000
 | 
				
			||||||
push eax ; cs
 | 
					push eax ; cs
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								helper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								helper.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					#include "helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t *nextLine(uint16_t *p) {
 | 
				
			||||||
 | 
					    uintptr_t v = (uintptr_t)p;
 | 
				
			||||||
 | 
					    return (uint16_t *)(v + (160 - ((v - 0xb8000) % 160)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void V8086Int(uint8_t interrupt, union V86Regs_t *regs) {
 | 
				
			||||||
 | 
					    // Edit the v8086 code with the interrupt
 | 
				
			||||||
 | 
					    // Writing 4 bytes to ensure proper code
 | 
				
			||||||
 | 
					    *(uint32_t*)v86Interrupt = 0x30CD00CD | (interrupt << 8);
 | 
				
			||||||
 | 
					    FARPTR v86_entry = i386LinearToFp(v86Interrupt);
 | 
				
			||||||
 | 
					    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), regs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SetVideo25Lines() {
 | 
				
			||||||
 | 
					    union V86Regs_t regs;
 | 
				
			||||||
 | 
					    regs.w.ax = 0x1114; // 80x25 mode
 | 
				
			||||||
 | 
					    regs.w.bx = 0x0000;
 | 
				
			||||||
 | 
					    V8086Int(0x10, ®s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void SetVideo50Lines() {
 | 
				
			||||||
 | 
					    union V86Regs_t regs;
 | 
				
			||||||
 | 
					    regs.w.ax = 0x1112; // 80x50 mode
 | 
				
			||||||
 | 
					    regs.w.bx = 0x0000;
 | 
				
			||||||
 | 
					    V8086Int(0x10, ®s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void SetCursorDisabled() {
 | 
				
			||||||
 | 
					    union V86Regs_t regs;
 | 
				
			||||||
 | 
					    regs.w.ax = 0x0100; // set cursor
 | 
				
			||||||
 | 
					    regs.w.cx = 0x3F00; // disabled
 | 
				
			||||||
 | 
					    V8086Int(0x10, ®s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t OpenVol(VOLINFO *vi) {
 | 
				
			||||||
 | 
					    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
				
			||||||
 | 
					    uint8_t pactive, ptype;
 | 
				
			||||||
 | 
					    uint32_t pstart, psize;
 | 
				
			||||||
 | 
					    pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
 | 
				
			||||||
 | 
					    return DFS_GetVolInfo(0, diskReadBuf, pstart, vi);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					uint32_t OpenDir(uint8_t *path, VOLINFO *vi, DIRINFO *di) {
 | 
				
			||||||
 | 
					    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
				
			||||||
 | 
					    di->scratch = diskReadBuf;
 | 
				
			||||||
 | 
					    return DFS_OpenDir(vi, path, di);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void File83ToPath(char *src, char *path) {
 | 
				
			||||||
 | 
					    uint8_t tmp, trailingSpace;
 | 
				
			||||||
 | 
					    for (trailingSpace=0, tmp = 0; tmp < 8 && src[tmp]; tmp++) {
 | 
				
			||||||
 | 
					        path[tmp] = src[tmp];
 | 
				
			||||||
 | 
					        if (src[tmp] == ' ') trailingSpace++;
 | 
				
			||||||
 | 
					        else trailingSpace = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    tmp -= trailingSpace;
 | 
				
			||||||
 | 
					    path[tmp++] = '.';
 | 
				
			||||||
 | 
					    for (int i = 8; i < 11 && src[i]; i++, tmp++) {
 | 
				
			||||||
 | 
					        path[tmp] = src[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    path[tmp] = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GetFileList(DIRENT *entries, int32_t *entCount, VOLINFO *vi, DIRINFO *di) {
 | 
				
			||||||
 | 
					    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
				
			||||||
 | 
					    DIRENT de;
 | 
				
			||||||
 | 
					    int32_t fileCount = 0;
 | 
				
			||||||
 | 
					    while (!DFS_GetNext(vi, di, &de)) {
 | 
				
			||||||
 | 
					        if (de.name[0]) {
 | 
				
			||||||
 | 
					            uint8_t *d = (uint8_t*)&entries[fileCount];
 | 
				
			||||||
 | 
					            uint8_t *s = (uint8_t*)&de;
 | 
				
			||||||
 | 
					            for (int i = 0; i < sizeof(DIRENT); i++)
 | 
				
			||||||
 | 
					                d[i] = s[i];
 | 
				
			||||||
 | 
					            fileCount++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    *entCount = fileCount;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								helper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								helper.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "interrupt.h"
 | 
				
			||||||
 | 
					#include "v86defs.h"
 | 
				
			||||||
 | 
					#include "dosfs/dosfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void V8086Int(uint8_t interrupt, union V86Regs_t *regs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SetVideo25Lines();
 | 
				
			||||||
 | 
					void SetVideo50Lines();
 | 
				
			||||||
 | 
					void SetCursorDisabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t *nextLine(uint16_t *p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t OpenVol(VOLINFO *vi);
 | 
				
			||||||
 | 
					uint32_t OpenDir(uint8_t *path, VOLINFO *vi, DIRINFO *di);
 | 
				
			||||||
 | 
					void File83ToPath(char *src, char *path);
 | 
				
			||||||
 | 
					void GetFileList(DIRENT *entries, int32_t *entCount, VOLINFO *vi, DIRINFO *di);
 | 
				
			||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "interrupt.h"
 | 
					#include "interrupt.h"
 | 
				
			||||||
#include "kbd.h"
 | 
					#include "kbd.h"
 | 
				
			||||||
 | 
					#include "v86defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char int_nibbleToHex(uint8_t n) {
 | 
					char int_nibbleToHex(uint8_t n) {
 | 
				
			||||||
    return n > 9 ? (n - 10) + 'A' : n + '0';
 | 
					    return n > 9 ? (n - 10) + 'A' : n + '0';
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								interrupt.h
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								interrupt.h
									
									
									
									
									
								
							@@ -7,28 +7,6 @@ struct interrupt_frame {
 | 
				
			|||||||
    uint32_t esp, ss;
 | 
					    uint32_t esp, ss;
 | 
				
			||||||
    uint32_t es, ds, fs, gs;
 | 
					    uint32_t es, ds, fs, gs;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Real Mode helper macros */
 | 
					 | 
				
			||||||
/* segment:offset pair */
 | 
					 | 
				
			||||||
typedef uint32_t FARPTR;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Make a FARPTR from a segment and an offset */
 | 
					 | 
				
			||||||
#define MK_FP(seg, off)  ((FARPTR) (((uint32_t) (seg) << 16) | (uint16_t) (off)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Extract the segment part of a FARPTR */
 | 
					 | 
				
			||||||
#define FP_SEG(fp)        (((FARPTR) fp) >> 16)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Extract the offset part of a FARPTR */
 | 
					 | 
				
			||||||
#define FP_OFF(fp)        (((FARPTR) fp) & 0xffff)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Convert a segment:offset pair to a linear address */
 | 
					 | 
				
			||||||
#define FP_TO_LINEAR(seg, off) ((void*)(uintptr_t)((((uint32_t)seg) << 4) + ((uint32_t)off)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define EFLAG_IF ((uint32_t)1 << 9)
 | 
					 | 
				
			||||||
#define EFLAG_VM ((uint32_t)1 << 17)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FARPTR i386LinearToFp(void *ptr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
__attribute__ ((interrupt))
 | 
					__attribute__ ((interrupt))
 | 
				
			||||||
void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code);
 | 
					void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										381
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										381
									
								
								kernel.c
									
									
									
									
									
								
							@@ -8,6 +8,8 @@
 | 
				
			|||||||
#include "paging.h"
 | 
					#include "paging.h"
 | 
				
			||||||
#include "v86defs.h"
 | 
					#include "v86defs.h"
 | 
				
			||||||
#include "tests.h"
 | 
					#include "tests.h"
 | 
				
			||||||
 | 
					#include "progs.h"
 | 
				
			||||||
 | 
					#include "helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef unsigned short word;
 | 
					typedef unsigned short word;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -146,29 +148,6 @@ Protected Only (1MB+)
 | 
				
			|||||||
400000 - 700000 Usermode Code (3mB)
 | 
					400000 - 700000 Usermode Code (3mB)
 | 
				
			||||||
700000 - 800000 Usermode Stack (1mB)
 | 
					700000 - 800000 Usermode Stack (1mB)
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					 | 
				
			||||||
void SetVideo25Lines() {
 | 
					 | 
				
			||||||
    union V86Regs_t regs;
 | 
					 | 
				
			||||||
    regs.w.ax = 0x1114; // 80x25 mode
 | 
					 | 
				
			||||||
    regs.w.bx = 0x0000;
 | 
					 | 
				
			||||||
    FARPTR v86_entry = i386LinearToFp(v86VideoInt);
 | 
					 | 
				
			||||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void SetVideo50Lines() {
 | 
					 | 
				
			||||||
    union V86Regs_t regs;
 | 
					 | 
				
			||||||
    regs.w.ax = 0x1112; // 80x50 mode
 | 
					 | 
				
			||||||
    regs.w.bx = 0x0000;
 | 
					 | 
				
			||||||
    FARPTR v86_entry = i386LinearToFp(v86VideoInt);
 | 
					 | 
				
			||||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void SetCursorDisabled() {
 | 
					 | 
				
			||||||
    union V86Regs_t regs;
 | 
					 | 
				
			||||||
    regs.w.ax = 0x0100; // set cursor
 | 
					 | 
				
			||||||
    regs.w.cx = 0x3F00; // disabled
 | 
					 | 
				
			||||||
    FARPTR v86_entry = i386LinearToFp(v86VideoInt);
 | 
					 | 
				
			||||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void DrawScreen() {
 | 
					void DrawScreen() {
 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xB8000;
 | 
					    uint16_t *vga_text = (uint16_t *)0xB8000;
 | 
				
			||||||
    // clear screen
 | 
					    // clear screen
 | 
				
			||||||
@@ -204,38 +183,8 @@ void DrawScreen() {
 | 
				
			|||||||
    vga_text[80+44] = 0x1f00 | '-';
 | 
					    vga_text[80+44] = 0x1f00 | '-';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t OpenVol(VOLINFO *vi) {
 | 
					 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
    uint8_t pactive, ptype;
 | 
					 | 
				
			||||||
    uint32_t pstart, psize;
 | 
					 | 
				
			||||||
    pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
 | 
					 | 
				
			||||||
    return DFS_GetVolInfo(0, diskReadBuf, pstart, vi);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
uint32_t OpenDir(uint8_t *path, VOLINFO *vi, DIRINFO *di) {
 | 
					 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
    di->scratch = diskReadBuf;
 | 
					 | 
				
			||||||
    return DFS_OpenDir(vi, path, di);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
int32_t fileCount;
 | 
					int32_t fileCount;
 | 
				
			||||||
DIRENT *entries = (DIRENT*)0x400000;
 | 
					DIRENT *entries = (DIRENT*)0x400000;
 | 
				
			||||||
void GetFileList(VOLINFO *vi, DIRINFO *di) {
 | 
					 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
    DIRENT de;
 | 
					 | 
				
			||||||
    fileCount = 0;
 | 
					 | 
				
			||||||
    while (!DFS_GetNext(vi, di, &de)) {
 | 
					 | 
				
			||||||
        if (de.name[0]) {
 | 
					 | 
				
			||||||
            uint8_t *d = (uint8_t*)&entries[fileCount];
 | 
					 | 
				
			||||||
            uint8_t *s = (uint8_t*)&de;
 | 
					 | 
				
			||||||
            for (int i = 0; i < sizeof(DIRENT); i++)
 | 
					 | 
				
			||||||
                d[i] = s[i];
 | 
					 | 
				
			||||||
            fileCount++;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
uint16_t *nextLine(uint16_t *p) {
 | 
					 | 
				
			||||||
    uintptr_t v = (uintptr_t)p;
 | 
					 | 
				
			||||||
    return (uint16_t *)(v + (160 - ((v - 0xb8000) % 160)));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void PrintFileList() {
 | 
					void PrintFileList() {
 | 
				
			||||||
    uint16_t *vga_text = &((uint16_t *)0xb8000)[80*6+3];
 | 
					    uint16_t *vga_text = &((uint16_t *)0xb8000)[80*6+3];
 | 
				
			||||||
    for (int i = 0; i < fileCount; i++) {
 | 
					    for (int i = 0; i < fileCount; i++) {
 | 
				
			||||||
@@ -254,329 +203,6 @@ void PrintFileList() {
 | 
				
			|||||||
        vga_text = nextLine(vga_text) + 3;
 | 
					        vga_text = nextLine(vga_text) + 3;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void HexViewTest(uint8_t *path, VOLINFO *vi) {
 | 
					 | 
				
			||||||
    uint32_t err;
 | 
					 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
					 | 
				
			||||||
    uint8_t *scratch = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
    FILEINFO fi;
 | 
					 | 
				
			||||||
    err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
 | 
					 | 
				
			||||||
    if (err) {
 | 
					 | 
				
			||||||
        vga_text += printStr("Open Error: ", vga_text);
 | 
					 | 
				
			||||||
        printDword(err, vga_text);
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    uint32_t successcount;
 | 
					 | 
				
			||||||
    uint32_t readOffset = 0, lastReadOffset = -1;
 | 
					 | 
				
			||||||
    char cont = 1;
 | 
					 | 
				
			||||||
    uint32_t byteCount = 16*24, lastByteCount;
 | 
					 | 
				
			||||||
    uint32_t screenSize = 80*25;
 | 
					 | 
				
			||||||
    char reread;
 | 
					 | 
				
			||||||
    for (;cont;) {
 | 
					 | 
				
			||||||
        uint8_t diskReadBuf[byteCount];
 | 
					 | 
				
			||||||
        if (readOffset != lastReadOffset) {
 | 
					 | 
				
			||||||
            lastReadOffset = readOffset;
 | 
					 | 
				
			||||||
            reread = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (byteCount != lastByteCount) {
 | 
					 | 
				
			||||||
            lastByteCount = byteCount;
 | 
					 | 
				
			||||||
            reread = 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (reread) {
 | 
					 | 
				
			||||||
            vga_text = (uint16_t *)0xb8000;
 | 
					 | 
				
			||||||
            for (int i = 0; i < screenSize; i++)
 | 
					 | 
				
			||||||
                vga_text[i] = 0x0f00;
 | 
					 | 
				
			||||||
            vga_text += printStr((char*)path, vga_text);
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const char prnt[] = "Scroll: Up/Down PgUp/PgDown Home/End             Exit: E ";
 | 
					 | 
				
			||||||
                vga_text = &((uint16_t*)0xb8000)[80-sizeof(prnt)];
 | 
					 | 
				
			||||||
                vga_text += printStr((char*)prnt, vga_text);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            vga_text = &((uint16_t*)0xb8000)[80];
 | 
					 | 
				
			||||||
            DFS_Seek(&fi, readOffset, scratch);
 | 
					 | 
				
			||||||
            if (fi.pointer != readOffset) {
 | 
					 | 
				
			||||||
                vga_text += printStr("Seek Error", vga_text);
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            err = DFS_ReadFile(&fi, scratch, diskReadBuf, &successcount, byteCount);
 | 
					 | 
				
			||||||
            if (err && err != DFS_EOF) {
 | 
					 | 
				
			||||||
                vga_text += printStr("Read Error: ", vga_text);
 | 
					 | 
				
			||||||
                printDword(err, vga_text);
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            for (uint32_t i = 0; i < successcount && i < byteCount; i += 16) {
 | 
					 | 
				
			||||||
                vga_text += printDword(i + readOffset, vga_text);
 | 
					 | 
				
			||||||
                vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                for (uint32_t j = 0; j < 16; j++) {
 | 
					 | 
				
			||||||
                    if (i + j < successcount)
 | 
					 | 
				
			||||||
                        vga_text += printByte(diskReadBuf[i + j], vga_text);
 | 
					 | 
				
			||||||
                    else {
 | 
					 | 
				
			||||||
                        vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                        vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                    if (j == 7)
 | 
					 | 
				
			||||||
                        vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                vga_text += printChar('|', vga_text);
 | 
					 | 
				
			||||||
                for (uint32_t j = 0; j < 16; j++) {
 | 
					 | 
				
			||||||
                    if (i + j < successcount)
 | 
					 | 
				
			||||||
                        vga_text += printChar(diskReadBuf[i + j], vga_text);
 | 
					 | 
				
			||||||
                    else vga_text += printChar(' ', vga_text);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                vga_text += printChar('|', vga_text);
 | 
					 | 
				
			||||||
                vga_text = nextLine(vga_text);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            reread = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        uint16_t key = get_scancode();
 | 
					 | 
				
			||||||
        union V86Regs_t regs;
 | 
					 | 
				
			||||||
        FARPTR v86_entry;
 | 
					 | 
				
			||||||
        switch (key & 0xff) {
 | 
					 | 
				
			||||||
            case KEY_DOWN: // down
 | 
					 | 
				
			||||||
                if ((readOffset + byteCount) < fi.filelen)
 | 
					 | 
				
			||||||
                    readOffset += byteCount;
 | 
					 | 
				
			||||||
                else goto end;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_UP: // up
 | 
					 | 
				
			||||||
                if ((readOffset - byteCount) < fi.filelen)
 | 
					 | 
				
			||||||
                    readOffset -= byteCount;
 | 
					 | 
				
			||||||
                else goto home;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_PGDOWN:
 | 
					 | 
				
			||||||
                if ((readOffset + (byteCount*4)) < fi.filelen)
 | 
					 | 
				
			||||||
                    readOffset += (byteCount*4);
 | 
					 | 
				
			||||||
                else goto end;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_PGUP:
 | 
					 | 
				
			||||||
                if ((readOffset - (byteCount*4)) < fi.filelen)
 | 
					 | 
				
			||||||
                    readOffset -= (byteCount*4);
 | 
					 | 
				
			||||||
                else goto home;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_HOME: home:
 | 
					 | 
				
			||||||
                readOffset = 0;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_END: end:
 | 
					 | 
				
			||||||
                if ((fi.filelen / byteCount) * byteCount > readOffset)
 | 
					 | 
				
			||||||
                    readOffset = (fi.filelen / byteCount) * byteCount;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_E: // e
 | 
					 | 
				
			||||||
                cont = 0;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_F2:
 | 
					 | 
				
			||||||
                if (byteCount != 16*24) {
 | 
					 | 
				
			||||||
                    SetVideo25Lines();
 | 
					 | 
				
			||||||
                    SetCursorDisabled();
 | 
					 | 
				
			||||||
                    screenSize = 80*25;
 | 
					 | 
				
			||||||
                    byteCount = 16*24;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_F5:
 | 
					 | 
				
			||||||
                if (byteCount != 16*49) {
 | 
					 | 
				
			||||||
                    SetVideo50Lines();
 | 
					 | 
				
			||||||
                    SetCursorDisabled();
 | 
					 | 
				
			||||||
                    screenSize = 80*50;
 | 
					 | 
				
			||||||
                    byteCount = 16*49;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void TextViewTest(uint8_t *path, VOLINFO *vi) {
 | 
					 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
					 | 
				
			||||||
    uint32_t fileLen;
 | 
					 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x500000;
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        uint32_t err;
 | 
					 | 
				
			||||||
        uint8_t *scratch = (uint8_t *)0x20000;
 | 
					 | 
				
			||||||
        FILEINFO fi;
 | 
					 | 
				
			||||||
        err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
 | 
					 | 
				
			||||||
        if (err) {
 | 
					 | 
				
			||||||
            vga_text += printStr("Open Error: ", vga_text);
 | 
					 | 
				
			||||||
            printDword(err, vga_text);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // file too large
 | 
					 | 
				
			||||||
        if (fi.filelen > 0x300000) {
 | 
					 | 
				
			||||||
            vga_text += printStr("File too large.", vga_text);
 | 
					 | 
				
			||||||
            kbd_wait();
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        DFS_Seek(&fi, 0, scratch);
 | 
					 | 
				
			||||||
        if (fi.pointer != 0) {
 | 
					 | 
				
			||||||
            vga_text += printStr("Seek Error", vga_text);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        err = DFS_ReadFile(&fi, scratch, diskReadBuf, &fileLen, fi.filelen);
 | 
					 | 
				
			||||||
        if (err && err != DFS_EOF) {
 | 
					 | 
				
			||||||
            vga_text += printStr("Read Error: ", vga_text);
 | 
					 | 
				
			||||||
            printDword(err, vga_text);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    uint32_t *lineOffsets = (uint32_t *)0x400000;
 | 
					 | 
				
			||||||
    uint32_t lastLine;
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        char nl;
 | 
					 | 
				
			||||||
        uint8_t c = 0x0A; // start with a pretend newline
 | 
					 | 
				
			||||||
        uint32_t line = -1; // start a pretend line behind
 | 
					 | 
				
			||||||
        for (int32_t o = -1; o < (int32_t)fileLen; c = diskReadBuf[++o]) {
 | 
					 | 
				
			||||||
            // newline
 | 
					 | 
				
			||||||
            if (c == 0x0A) {
 | 
					 | 
				
			||||||
                lineOffsets[++line] = o;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            // file too large
 | 
					 | 
				
			||||||
            if ((uintptr_t)&lineOffsets[line] >= 0x4FFFFC) {
 | 
					 | 
				
			||||||
                vga_text += printStr("File too large.", vga_text);
 | 
					 | 
				
			||||||
                kbd_wait();
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        lastLine = line;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    uint32_t currLine = 0;
 | 
					 | 
				
			||||||
    char cont = 1;
 | 
					 | 
				
			||||||
    uint32_t screenSize = 80*25;
 | 
					 | 
				
			||||||
    char redraw = 1;
 | 
					 | 
				
			||||||
    uint32_t linesOnScreen = 0;
 | 
					 | 
				
			||||||
    for (;cont;) {
 | 
					 | 
				
			||||||
        if (redraw) {
 | 
					 | 
				
			||||||
            vga_text = (uint16_t *)0xb8000;
 | 
					 | 
				
			||||||
            for (int i = 0; i < screenSize; i++)
 | 
					 | 
				
			||||||
                vga_text[i] = 0x0f00;
 | 
					 | 
				
			||||||
            vga_text += printStr((char*)path, vga_text);
 | 
					 | 
				
			||||||
            vga_text += 2;
 | 
					 | 
				
			||||||
            vga_text += printStr("Line: ", vga_text);
 | 
					 | 
				
			||||||
            vga_text += printDec(currLine, vga_text);
 | 
					 | 
				
			||||||
            vga_text += printChar('/', vga_text);
 | 
					 | 
				
			||||||
            vga_text += printDec(lastLine, vga_text);
 | 
					 | 
				
			||||||
            vga_text += printStr(" Scroll: Up/Down PgUp/PgDown Home/End", vga_text);
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const char prnt[] = "Exit: E ";
 | 
					 | 
				
			||||||
                vga_text = &((uint16_t*)0xb8000)[80-sizeof(prnt)];
 | 
					 | 
				
			||||||
                vga_text += printStr((char*)prnt, vga_text);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            for (vga_text = &((uint16_t*)0xb8000)[84]; vga_text < &((uint16_t*)0xb8000)[screenSize]; vga_text += 80)
 | 
					 | 
				
			||||||
                *(uint8_t*)vga_text = '|';
 | 
					 | 
				
			||||||
            vga_text = &((uint16_t*)0xb8000)[0];
 | 
					 | 
				
			||||||
            uint32_t lineOff = 6;
 | 
					 | 
				
			||||||
            uint8_t c = 0x0A; // start with a pretend newline
 | 
					 | 
				
			||||||
            uint32_t line = currLine - 1; // start a pretend line behind
 | 
					 | 
				
			||||||
            int32_t o = lineOffsets[currLine]; // the real or fake newline on previous line
 | 
					 | 
				
			||||||
            linesOnScreen = screenSize/80;
 | 
					 | 
				
			||||||
            for (; o < (int32_t)fileLen && vga_text < &((uint16_t*)0xb8000)[screenSize]; c = diskReadBuf[++o]) {
 | 
					 | 
				
			||||||
                // newline
 | 
					 | 
				
			||||||
                if (c == 0x0A) {
 | 
					 | 
				
			||||||
                    vga_text = nextLine(vga_text);
 | 
					 | 
				
			||||||
                    line++;
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        uint16_t *vga_tmp = vga_text;
 | 
					 | 
				
			||||||
                        uint16_t decTmp[11];
 | 
					 | 
				
			||||||
                        char cnt = printDec(line, decTmp);
 | 
					 | 
				
			||||||
                        char off = cnt <= 4 ? 0 : cnt - 4;
 | 
					 | 
				
			||||||
                        vga_tmp += 4 - (cnt - off);
 | 
					 | 
				
			||||||
                        for (int i = off; i < cnt; i++, vga_tmp++)
 | 
					 | 
				
			||||||
                            *(uint8_t*)vga_tmp = (uint8_t)decTmp[i];
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    vga_text += 6;
 | 
					 | 
				
			||||||
                    lineOff = 6;
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                } 
 | 
					 | 
				
			||||||
                *(uint8_t*)vga_text = c;
 | 
					 | 
				
			||||||
                vga_text++;
 | 
					 | 
				
			||||||
                lineOff++;
 | 
					 | 
				
			||||||
                if (lineOff == 80) { // last char
 | 
					 | 
				
			||||||
                    vga_text += 6;
 | 
					 | 
				
			||||||
                    lineOff = 6;
 | 
					 | 
				
			||||||
                    linesOnScreen--;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            redraw = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        uint16_t key = get_scancode();
 | 
					 | 
				
			||||||
        union V86Regs_t regs;
 | 
					 | 
				
			||||||
        FARPTR v86_entry;
 | 
					 | 
				
			||||||
        switch (key & 0xff) {
 | 
					 | 
				
			||||||
            case KEY_DOWN: // down
 | 
					 | 
				
			||||||
                if (currLine < lastLine && lineOffsets[currLine+1] < fileLen) {
 | 
					 | 
				
			||||||
                    currLine++;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_UP: // up
 | 
					 | 
				
			||||||
                if ((currLine > 0 && lineOffsets[currLine-1] < fileLen) || currLine == 1) {
 | 
					 | 
				
			||||||
                    currLine--;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_PGDOWN:
 | 
					 | 
				
			||||||
                if (currLine+(linesOnScreen/2) <= lastLine && lineOffsets[currLine+(linesOnScreen/2)] < fileLen) {
 | 
					 | 
				
			||||||
                    currLine += (linesOnScreen/2);
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                } else goto end;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_PGUP:
 | 
					 | 
				
			||||||
                if (currLine > (linesOnScreen/2) && lineOffsets[currLine-(linesOnScreen/2)] < fileLen) {
 | 
					 | 
				
			||||||
                    currLine -= (linesOnScreen/2);
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                } else if (currLine <= (linesOnScreen/2)) {
 | 
					 | 
				
			||||||
                    currLine = 0;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_HOME: home:
 | 
					 | 
				
			||||||
                if (currLine != 0) {
 | 
					 | 
				
			||||||
                    currLine = 0;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_END: end:
 | 
					 | 
				
			||||||
                if (currLine != lastLine) {
 | 
					 | 
				
			||||||
                    currLine = lastLine;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_E: // e
 | 
					 | 
				
			||||||
                cont = 0;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_F2:
 | 
					 | 
				
			||||||
                if (screenSize != 80*25) {
 | 
					 | 
				
			||||||
                    SetVideo25Lines();
 | 
					 | 
				
			||||||
                    SetCursorDisabled();
 | 
					 | 
				
			||||||
                    screenSize = 80*25;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case KEY_F5:
 | 
					 | 
				
			||||||
                if (screenSize != 80*50) {
 | 
					 | 
				
			||||||
                    SetVideo50Lines();
 | 
					 | 
				
			||||||
                    SetCursorDisabled();
 | 
					 | 
				
			||||||
                    screenSize = 80*50;
 | 
					 | 
				
			||||||
                    redraw = 1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void File83ToPath(char *src, char *path) {
 | 
					 | 
				
			||||||
    uint8_t tmp, trailingSpace;
 | 
					 | 
				
			||||||
    for (trailingSpace=0, tmp = 0; tmp < 8 && src[tmp]; tmp++) {
 | 
					 | 
				
			||||||
        path[tmp] = src[tmp];
 | 
					 | 
				
			||||||
        if (src[tmp] == ' ') trailingSpace++;
 | 
					 | 
				
			||||||
        else trailingSpace = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    tmp -= trailingSpace;
 | 
					 | 
				
			||||||
    path[tmp++] = '.';
 | 
					 | 
				
			||||||
    for (int i = 8; i < 11 && src[i]; i++, tmp++) {
 | 
					 | 
				
			||||||
        path[tmp] = src[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    path[tmp] = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
void FileSelect() {
 | 
					void FileSelect() {
 | 
				
			||||||
    fileCount = 5;
 | 
					    fileCount = 5;
 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
@@ -588,7 +214,7 @@ void FileSelect() {
 | 
				
			|||||||
        if (reload) {
 | 
					        if (reload) {
 | 
				
			||||||
            OpenVol(&vi);
 | 
					            OpenVol(&vi);
 | 
				
			||||||
            OpenDir((uint8_t*)"", &vi, &di);
 | 
					            OpenDir((uint8_t*)"", &vi, &di);
 | 
				
			||||||
            GetFileList(&vi, &di);
 | 
					            GetFileList(entries, &fileCount, &vi, &di);
 | 
				
			||||||
            reload = 0;
 | 
					            reload = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        PrintFileList();
 | 
					        PrintFileList();
 | 
				
			||||||
@@ -610,6 +236,7 @@ void FileSelect() {
 | 
				
			|||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 0x14: // t
 | 
					            case 0x14: // t
 | 
				
			||||||
                RunTests(vga_text);
 | 
					                RunTests(vga_text);
 | 
				
			||||||
 | 
					                SetCursorDisabled();
 | 
				
			||||||
                DrawScreen();
 | 
					                DrawScreen();
 | 
				
			||||||
                reload = 1;
 | 
					                reload = 1;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										311
									
								
								progs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								progs.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,311 @@
 | 
				
			|||||||
 | 
					#include "progs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HexViewTest(uint8_t *path, VOLINFO *vi) {
 | 
				
			||||||
 | 
					    uint32_t err;
 | 
				
			||||||
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
 | 
					    uint8_t *scratch = (uint8_t *)0x20000;
 | 
				
			||||||
 | 
					    FILEINFO fi;
 | 
				
			||||||
 | 
					    err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
 | 
					        vga_text += printStr("Open Error: ", vga_text);
 | 
				
			||||||
 | 
					        printDword(err, vga_text);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    uint32_t successcount;
 | 
				
			||||||
 | 
					    uint32_t readOffset = 0, lastReadOffset = -1;
 | 
				
			||||||
 | 
					    char cont = 1;
 | 
				
			||||||
 | 
					    uint32_t byteCount = 16*24, lastByteCount;
 | 
				
			||||||
 | 
					    uint32_t screenSize = 80*25;
 | 
				
			||||||
 | 
					    char reread;
 | 
				
			||||||
 | 
					    for (;cont;) {
 | 
				
			||||||
 | 
					        uint8_t diskReadBuf[byteCount];
 | 
				
			||||||
 | 
					        if (readOffset != lastReadOffset) {
 | 
				
			||||||
 | 
					            lastReadOffset = readOffset;
 | 
				
			||||||
 | 
					            reread = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (byteCount != lastByteCount) {
 | 
				
			||||||
 | 
					            lastByteCount = byteCount;
 | 
				
			||||||
 | 
					            reread = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (reread) {
 | 
				
			||||||
 | 
					            vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
 | 
					            for (int i = 0; i < screenSize; i++)
 | 
				
			||||||
 | 
					                vga_text[i] = 0x0f00;
 | 
				
			||||||
 | 
					            vga_text += printStr((char*)path, vga_text);
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                const char prnt[] = "Scroll: Up/Down PgUp/PgDown Home/End             Exit: E ";
 | 
				
			||||||
 | 
					                vga_text = &((uint16_t*)0xb8000)[80-sizeof(prnt)];
 | 
				
			||||||
 | 
					                vga_text += printStr((char*)prnt, vga_text);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            vga_text = &((uint16_t*)0xb8000)[80];
 | 
				
			||||||
 | 
					            DFS_Seek(&fi, readOffset, scratch);
 | 
				
			||||||
 | 
					            if (fi.pointer != readOffset) {
 | 
				
			||||||
 | 
					                vga_text += printStr("Seek Error", vga_text);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            err = DFS_ReadFile(&fi, scratch, diskReadBuf, &successcount, byteCount);
 | 
				
			||||||
 | 
					            if (err && err != DFS_EOF) {
 | 
				
			||||||
 | 
					                vga_text += printStr("Read Error: ", vga_text);
 | 
				
			||||||
 | 
					                printDword(err, vga_text);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            for (uint32_t i = 0; i < successcount && i < byteCount; i += 16) {
 | 
				
			||||||
 | 
					                vga_text += printDword(i + readOffset, vga_text);
 | 
				
			||||||
 | 
					                vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                for (uint32_t j = 0; j < 16; j++) {
 | 
				
			||||||
 | 
					                    if (i + j < successcount)
 | 
				
			||||||
 | 
					                        vga_text += printByte(diskReadBuf[i + j], vga_text);
 | 
				
			||||||
 | 
					                    else {
 | 
				
			||||||
 | 
					                        vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                        vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                    if (j == 7)
 | 
				
			||||||
 | 
					                        vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                vga_text += printChar('|', vga_text);
 | 
				
			||||||
 | 
					                for (uint32_t j = 0; j < 16; j++) {
 | 
				
			||||||
 | 
					                    if (i + j < successcount)
 | 
				
			||||||
 | 
					                        vga_text += printChar(diskReadBuf[i + j], vga_text);
 | 
				
			||||||
 | 
					                    else vga_text += printChar(' ', vga_text);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                vga_text += printChar('|', vga_text);
 | 
				
			||||||
 | 
					                vga_text = nextLine(vga_text);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            reread = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        uint16_t key = get_scancode();
 | 
				
			||||||
 | 
					        union V86Regs_t regs;
 | 
				
			||||||
 | 
					        FARPTR v86_entry;
 | 
				
			||||||
 | 
					        switch (key & 0xff) {
 | 
				
			||||||
 | 
					            case KEY_DOWN: // down
 | 
				
			||||||
 | 
					                if ((readOffset + byteCount) < fi.filelen)
 | 
				
			||||||
 | 
					                    readOffset += byteCount;
 | 
				
			||||||
 | 
					                else goto end;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_UP: // up
 | 
				
			||||||
 | 
					                if ((readOffset - byteCount) < fi.filelen)
 | 
				
			||||||
 | 
					                    readOffset -= byteCount;
 | 
				
			||||||
 | 
					                else goto home;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_PGDOWN:
 | 
				
			||||||
 | 
					                if ((readOffset + (byteCount*4)) < fi.filelen)
 | 
				
			||||||
 | 
					                    readOffset += (byteCount*4);
 | 
				
			||||||
 | 
					                else goto end;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_PGUP:
 | 
				
			||||||
 | 
					                if ((readOffset - (byteCount*4)) < fi.filelen)
 | 
				
			||||||
 | 
					                    readOffset -= (byteCount*4);
 | 
				
			||||||
 | 
					                else goto home;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_HOME: home:
 | 
				
			||||||
 | 
					                readOffset = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_END: end:
 | 
				
			||||||
 | 
					                if ((fi.filelen / byteCount) * byteCount > readOffset)
 | 
				
			||||||
 | 
					                    readOffset = (fi.filelen / byteCount) * byteCount;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_E: // e
 | 
				
			||||||
 | 
					                cont = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_F2:
 | 
				
			||||||
 | 
					                if (byteCount != 16*24) {
 | 
				
			||||||
 | 
					                    SetVideo25Lines();
 | 
				
			||||||
 | 
					                    SetCursorDisabled();
 | 
				
			||||||
 | 
					                    screenSize = 80*25;
 | 
				
			||||||
 | 
					                    byteCount = 16*24;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_F5:
 | 
				
			||||||
 | 
					                if (byteCount != 16*49) {
 | 
				
			||||||
 | 
					                    SetVideo50Lines();
 | 
				
			||||||
 | 
					                    SetCursorDisabled();
 | 
				
			||||||
 | 
					                    screenSize = 80*50;
 | 
				
			||||||
 | 
					                    byteCount = 16*49;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void TextViewTest(uint8_t *path, VOLINFO *vi) {
 | 
				
			||||||
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
 | 
					    uint32_t fileLen;
 | 
				
			||||||
 | 
					    uint8_t *diskReadBuf = (uint8_t *)0x500000;
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint32_t err;
 | 
				
			||||||
 | 
					        uint8_t *scratch = (uint8_t *)0x20000;
 | 
				
			||||||
 | 
					        FILEINFO fi;
 | 
				
			||||||
 | 
					        err = DFS_OpenFile(vi, path, DFS_READ, scratch, &fi);
 | 
				
			||||||
 | 
					        if (err) {
 | 
				
			||||||
 | 
					            vga_text += printStr("Open Error: ", vga_text);
 | 
				
			||||||
 | 
					            printDword(err, vga_text);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // file too large
 | 
				
			||||||
 | 
					        if (fi.filelen > 0x300000) {
 | 
				
			||||||
 | 
					            vga_text += printStr("File too large.", vga_text);
 | 
				
			||||||
 | 
					            kbd_wait();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        DFS_Seek(&fi, 0, scratch);
 | 
				
			||||||
 | 
					        if (fi.pointer != 0) {
 | 
				
			||||||
 | 
					            vga_text += printStr("Seek Error", vga_text);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        err = DFS_ReadFile(&fi, scratch, diskReadBuf, &fileLen, fi.filelen);
 | 
				
			||||||
 | 
					        if (err && err != DFS_EOF) {
 | 
				
			||||||
 | 
					            vga_text += printStr("Read Error: ", vga_text);
 | 
				
			||||||
 | 
					            printDword(err, vga_text);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    uint32_t *lineOffsets = (uint32_t *)0x400000;
 | 
				
			||||||
 | 
					    uint32_t lastLine;
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char nl;
 | 
				
			||||||
 | 
					        uint8_t c = 0x0A; // start with a pretend newline
 | 
				
			||||||
 | 
					        uint32_t line = -1; // start a pretend line behind
 | 
				
			||||||
 | 
					        for (int32_t o = -1; o < (int32_t)fileLen; c = diskReadBuf[++o]) {
 | 
				
			||||||
 | 
					            // newline
 | 
				
			||||||
 | 
					            if (c == 0x0A) {
 | 
				
			||||||
 | 
					                lineOffsets[++line] = o;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // file too large
 | 
				
			||||||
 | 
					            if ((uintptr_t)&lineOffsets[line] >= 0x4FFFFC) {
 | 
				
			||||||
 | 
					                vga_text += printStr("File too large.", vga_text);
 | 
				
			||||||
 | 
					                kbd_wait();
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        lastLine = line;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    uint32_t currLine = 0;
 | 
				
			||||||
 | 
					    char cont = 1;
 | 
				
			||||||
 | 
					    uint32_t screenSize = 80*25;
 | 
				
			||||||
 | 
					    char redraw = 1;
 | 
				
			||||||
 | 
					    uint32_t linesOnScreen = 0;
 | 
				
			||||||
 | 
					    for (;cont;) {
 | 
				
			||||||
 | 
					        if (redraw) {
 | 
				
			||||||
 | 
					            vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
 | 
					            for (int i = 0; i < screenSize; i++)
 | 
				
			||||||
 | 
					                vga_text[i] = 0x0f00;
 | 
				
			||||||
 | 
					            vga_text += printStr((char*)path, vga_text);
 | 
				
			||||||
 | 
					            vga_text += 2;
 | 
				
			||||||
 | 
					            vga_text += printStr("Line: ", vga_text);
 | 
				
			||||||
 | 
					            vga_text += printDec(currLine, vga_text);
 | 
				
			||||||
 | 
					            vga_text += printChar('/', vga_text);
 | 
				
			||||||
 | 
					            vga_text += printDec(lastLine, vga_text);
 | 
				
			||||||
 | 
					            vga_text += printStr(" Scroll: Up/Down PgUp/PgDown Home/End", vga_text);
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                const char prnt[] = "Exit: E ";
 | 
				
			||||||
 | 
					                vga_text = &((uint16_t*)0xb8000)[80-sizeof(prnt)];
 | 
				
			||||||
 | 
					                vga_text += printStr((char*)prnt, vga_text);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            for (vga_text = &((uint16_t*)0xb8000)[84]; vga_text < &((uint16_t*)0xb8000)[screenSize]; vga_text += 80)
 | 
				
			||||||
 | 
					                *(uint8_t*)vga_text = '|';
 | 
				
			||||||
 | 
					            vga_text = &((uint16_t*)0xb8000)[0];
 | 
				
			||||||
 | 
					            uint32_t lineOff = 6;
 | 
				
			||||||
 | 
					            uint8_t c = 0x0A; // start with a pretend newline
 | 
				
			||||||
 | 
					            uint32_t line = currLine - 1; // start a pretend line behind
 | 
				
			||||||
 | 
					            int32_t o = lineOffsets[currLine]; // the real or fake newline on previous line
 | 
				
			||||||
 | 
					            linesOnScreen = screenSize/80;
 | 
				
			||||||
 | 
					            for (; o < (int32_t)fileLen && vga_text < &((uint16_t*)0xb8000)[screenSize]; c = diskReadBuf[++o]) {
 | 
				
			||||||
 | 
					                // newline
 | 
				
			||||||
 | 
					                if (c == 0x0A) {
 | 
				
			||||||
 | 
					                    vga_text = nextLine(vga_text);
 | 
				
			||||||
 | 
					                    line++;
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        uint16_t *vga_tmp = vga_text;
 | 
				
			||||||
 | 
					                        uint16_t decTmp[11];
 | 
				
			||||||
 | 
					                        char cnt = printDec(line, decTmp);
 | 
				
			||||||
 | 
					                        char off = cnt <= 4 ? 0 : cnt - 4;
 | 
				
			||||||
 | 
					                        vga_tmp += 4 - (cnt - off);
 | 
				
			||||||
 | 
					                        for (int i = off; i < cnt; i++, vga_tmp++)
 | 
				
			||||||
 | 
					                            *(uint8_t*)vga_tmp = (uint8_t)decTmp[i];
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    vga_text += 6;
 | 
				
			||||||
 | 
					                    lineOff = 6;
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                } 
 | 
				
			||||||
 | 
					                *(uint8_t*)vga_text = c;
 | 
				
			||||||
 | 
					                vga_text++;
 | 
				
			||||||
 | 
					                lineOff++;
 | 
				
			||||||
 | 
					                if (lineOff == 80) { // last char
 | 
				
			||||||
 | 
					                    vga_text += 6;
 | 
				
			||||||
 | 
					                    lineOff = 6;
 | 
				
			||||||
 | 
					                    linesOnScreen--;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            redraw = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        uint16_t key = get_scancode();
 | 
				
			||||||
 | 
					        union V86Regs_t regs;
 | 
				
			||||||
 | 
					        FARPTR v86_entry;
 | 
				
			||||||
 | 
					        switch (key & 0xff) {
 | 
				
			||||||
 | 
					            case KEY_DOWN: // down
 | 
				
			||||||
 | 
					                if (currLine < lastLine && lineOffsets[currLine+1] < fileLen) {
 | 
				
			||||||
 | 
					                    currLine++;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_UP: // up
 | 
				
			||||||
 | 
					                if ((currLine > 0 && lineOffsets[currLine-1] < fileLen) || currLine == 1) {
 | 
				
			||||||
 | 
					                    currLine--;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_PGDOWN:
 | 
				
			||||||
 | 
					                if (currLine+(linesOnScreen/2) <= lastLine && lineOffsets[currLine+(linesOnScreen/2)] < fileLen) {
 | 
				
			||||||
 | 
					                    currLine += (linesOnScreen/2);
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                } else goto end;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_PGUP:
 | 
				
			||||||
 | 
					                if (currLine > (linesOnScreen/2) && lineOffsets[currLine-(linesOnScreen/2)] < fileLen) {
 | 
				
			||||||
 | 
					                    currLine -= (linesOnScreen/2);
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                } else if (currLine <= (linesOnScreen/2)) {
 | 
				
			||||||
 | 
					                    currLine = 0;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_HOME: home:
 | 
				
			||||||
 | 
					                if (currLine != 0) {
 | 
				
			||||||
 | 
					                    currLine = 0;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_END: end:
 | 
				
			||||||
 | 
					                if (currLine != lastLine) {
 | 
				
			||||||
 | 
					                    currLine = lastLine;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_E: // e
 | 
				
			||||||
 | 
					                cont = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_F2:
 | 
				
			||||||
 | 
					                if (screenSize != 80*25) {
 | 
				
			||||||
 | 
					                    SetVideo25Lines();
 | 
				
			||||||
 | 
					                    SetCursorDisabled();
 | 
				
			||||||
 | 
					                    screenSize = 80*25;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case KEY_F5:
 | 
				
			||||||
 | 
					                if (screenSize != 80*50) {
 | 
				
			||||||
 | 
					                    SetVideo50Lines();
 | 
				
			||||||
 | 
					                    SetCursorDisabled();
 | 
				
			||||||
 | 
					                    screenSize = 80*50;
 | 
				
			||||||
 | 
					                    redraw = 1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								progs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								progs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dosfs/dosfs.h"
 | 
				
			||||||
 | 
					#include "print.h"
 | 
				
			||||||
 | 
					#include "kbd.h"
 | 
				
			||||||
 | 
					#include "v86defs.h"
 | 
				
			||||||
 | 
					#include "helper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HexViewTest(uint8_t *path, VOLINFO *vi);
 | 
				
			||||||
 | 
					void TextViewTest(uint8_t *path, VOLINFO *vi);
 | 
				
			||||||
							
								
								
									
										6
									
								
								tests.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tests.c
									
									
									
									
									
								
							@@ -1,5 +1,4 @@
 | 
				
			|||||||
#include "tests.h"
 | 
					#include "tests.h"
 | 
				
			||||||
#include "v86defs.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern char *jmp_usermode_test();
 | 
					extern char *jmp_usermode_test();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,14 +33,13 @@ void TestDiskRead() {
 | 
				
			|||||||
    uint16_t *vga_text = (uint16_t *)0xb8000 + (80*5);
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000 + (80*5);
 | 
				
			||||||
    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
					    vga_text += printStr("Setting Text Mode... ", vga_text);
 | 
				
			||||||
    regs.w.ax = 3; // text mode
 | 
					    regs.w.ax = 3; // text mode
 | 
				
			||||||
    FARPTR v86_entry = i386LinearToFp(v86VideoInt);
 | 
					    V8086Int(0x10, ®s); 
 | 
				
			||||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
					 | 
				
			||||||
    vga_text += printStr("Done. Starting Disk Read... ", vga_text);
 | 
					    vga_text += printStr("Done. Starting Disk Read... ", vga_text);
 | 
				
			||||||
    char *diskReadBuf = (char *)0x23000;
 | 
					    char *diskReadBuf = (char *)0x23000;
 | 
				
			||||||
	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);
 | 
				
			||||||
    v86_entry = i386LinearToFp(v86DiskRead);
 | 
					    FARPTR v86_entry = i386LinearToFp(v86DiskRead);
 | 
				
			||||||
    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
					    enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s);
 | 
				
			||||||
    vga_text = (uint16_t *)0xb8000;
 | 
					    vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    for (int i = 0; i < (80*25)/2; i++) {
 | 
					    for (int i = 0; i < (80*25)/2; i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tests.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tests.h
									
									
									
									
									
								
							@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
#include "dosfs/dosfs.h"
 | 
					#include "dosfs/dosfs.h"
 | 
				
			||||||
#include "print.h"
 | 
					#include "print.h"
 | 
				
			||||||
#include "interrupt.h"
 | 
					#include "interrupt.h"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ mov dword [0xb8004], 0x0f000f00 | 'e' | 'r' << 16
 | 
				
			|||||||
mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
 | 
					mov dword [0xb8008], 0x0f000f00 | 'm' | 'o' << 16
 | 
				
			||||||
mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
 | 
					mov dword [0xb800C], 0x0f000f00 | 'd' | 'e' << 16
 | 
				
			||||||
mov word [0xb8010], 0x0f00 | '!'
 | 
					mov word [0xb8010], 0x0f00 | '!'
 | 
				
			||||||
mov eax, 0 ; command = 00, get key
 | 
					mov eax, 0 ; command = 00h, get key
 | 
				
			||||||
int 0x21 ; OS call
 | 
					int 0x21 ; OS call
 | 
				
			||||||
push 0x00000013 ; eax  AH=0,AL=3 set video mode 3
 | 
					push 0x00000013 ; eax  AH=0,AL=3 set video mode 3
 | 
				
			||||||
push 0x00000000 ; ecx
 | 
					push 0x00000000 ; ecx
 | 
				
			||||||
@@ -15,7 +15,8 @@ push 0x00000000 ; ebx
 | 
				
			|||||||
push 0x00000000 ; esi
 | 
					push 0x00000000 ; esi
 | 
				
			||||||
push 0x00000000 ; edi
 | 
					push 0x00000000 ; edi
 | 
				
			||||||
push esp ; regs
 | 
					push esp ; regs
 | 
				
			||||||
mov eax, 0x10 ; command = 10
 | 
					push 0x10 ; interrupt
 | 
				
			||||||
 | 
					mov eax, 0x86 ; command = 86h, virtual 8086 call
 | 
				
			||||||
int 0x21 ; OS call
 | 
					int 0x21 ; OS call
 | 
				
			||||||
mov edi, 0xA0000
 | 
					mov edi, 0xA0000
 | 
				
			||||||
xor eax, eax
 | 
					xor eax, eax
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								v86.nasm
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								v86.nasm
									
									
									
									
									
								
							@@ -1,5 +1,12 @@
 | 
				
			|||||||
[BITS 16]
 | 
					[BITS 16]
 | 
				
			||||||
[SECTION .v86]
 | 
					[SECTION .v86]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					global v86Interrupt
 | 
				
			||||||
 | 
					v86Interrupt:
 | 
				
			||||||
 | 
					int 0x00
 | 
				
			||||||
 | 
					int 0x30
 | 
				
			||||||
 | 
					jmp $
 | 
				
			||||||
 | 
					
 | 
				
			||||||
real_hexprint:
 | 
					real_hexprint:
 | 
				
			||||||
xor cx, cx
 | 
					xor cx, cx
 | 
				
			||||||
mov bl, al
 | 
					mov bl, al
 | 
				
			||||||
@@ -70,13 +77,6 @@ int 0x30
 | 
				
			|||||||
jmp $
 | 
					jmp $
 | 
				
			||||||
.c: db `\0263>=*.\?\?\?=*.\0263>`
 | 
					.c: db `\0263>=*.\?\?\?=*.\0263>`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global v86GfxMode
 | 
					 | 
				
			||||||
v86GfxMode:
 | 
					 | 
				
			||||||
mov ax, 0x13
 | 
					 | 
				
			||||||
int 0x10
 | 
					 | 
				
			||||||
int 0x30
 | 
					 | 
				
			||||||
jmp $
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
global v86TextMode
 | 
					global v86TextMode
 | 
				
			||||||
v86TextMode:
 | 
					v86TextMode:
 | 
				
			||||||
mov ax, 0x3
 | 
					mov ax, 0x3
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								v86defs.h
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								v86defs.h
									
									
									
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Labels of v8086 programs 
 | 
				
			||||||
 | 
					// TODO Remove these and use
 | 
				
			||||||
 | 
					// a single define for location?
 | 
				
			||||||
extern void v86Test();
 | 
					extern void v86Test();
 | 
				
			||||||
extern void v86TransFlag();
 | 
					extern void v86TransFlag();
 | 
				
			||||||
extern void v86GfxMode();
 | 
					extern void v86Interrupt();
 | 
				
			||||||
extern void v86TextMode();
 | 
					extern void v86TextMode();
 | 
				
			||||||
extern void v86DiskRead();
 | 
					extern void v86DiskRead();
 | 
				
			||||||
extern void v86VideoInt();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
union __attribute((__packed__)) V86Regs_t {
 | 
					union __attribute((__packed__)) V86Regs_t {
 | 
				
			||||||
    struct dword_regs { 
 | 
					    struct dword_regs { 
 | 
				
			||||||
@@ -41,6 +43,8 @@ union __attribute((__packed__)) V86Regs_t {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs);
 | 
					extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip, union V86Regs_t *regs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void V8086Int(uint8_t interrupt, union V86Regs_t *regs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct __attribute((__packed__)) Int13DiskPacket_t {
 | 
					struct __attribute((__packed__)) Int13DiskPacket_t {
 | 
				
			||||||
    uint8_t size; // 0x10
 | 
					    uint8_t size; // 0x10
 | 
				
			||||||
    uint8_t reserved; // 0x00
 | 
					    uint8_t reserved; // 0x00
 | 
				
			||||||
@@ -50,3 +54,25 @@ struct __attribute((__packed__)) Int13DiskPacket_t {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct Int13DiskPacket_t v86disk_addr_packet;
 | 
					extern struct Int13DiskPacket_t v86disk_addr_packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Real Mode helper macros */
 | 
				
			||||||
 | 
					/* segment:offset pair */
 | 
				
			||||||
 | 
					typedef uint32_t FARPTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Make a FARPTR from a segment and an offset */
 | 
				
			||||||
 | 
					#define MK_FP(seg, off)  ((FARPTR) (((uint32_t) (seg) << 16) | (uint16_t) (off)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract the segment part of a FARPTR */
 | 
				
			||||||
 | 
					#define FP_SEG(fp)        (((FARPTR) fp) >> 16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract the offset part of a FARPTR */
 | 
				
			||||||
 | 
					#define FP_OFF(fp)        (((FARPTR) fp) & 0xffff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Convert a segment:offset pair to a linear address */
 | 
				
			||||||
 | 
					#define FP_TO_LINEAR(seg, off) ((void*)(uintptr_t)((((uint32_t)seg) << 4) + ((uint32_t)off)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EFLAG_IF ((uint32_t)1 << 9)
 | 
				
			||||||
 | 
					#define EFLAG_VM ((uint32_t)1 << 17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FARPTR i386LinearToFp(void *ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user