Lots of general cleanup, Call to specified V86 int (from Kernel and Usermode)
This commit is contained in:
parent
d63430bb4d
commit
b41d65bfce
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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user