Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
dcd9d60271 |
15 changed files with 314 additions and 1261 deletions
84
EttinOS.svg
84
EttinOS.svg
|
@ -1,84 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="79"
|
|
||||||
height="22"
|
|
||||||
viewBox="0 0 20.902084 5.8208335"
|
|
||||||
version="1.1"
|
|
||||||
id="svg5"
|
|
||||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
|
||||||
sodipodi:docname="EttinOS.svg"
|
|
||||||
inkscape:export-filename="/home/leaf/OSes/EttinOS/EttinOS.png"
|
|
||||||
inkscape:export-xdpi="96"
|
|
||||||
inkscape:export-ydpi="96"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview7"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
showgrid="true"
|
|
||||||
units="px"
|
|
||||||
height="36px"
|
|
||||||
borderlayer="true"
|
|
||||||
inkscape:showpageshadow="false"
|
|
||||||
width="80px"
|
|
||||||
inkscape:zoom="4"
|
|
||||||
inkscape:cx="105.25"
|
|
||||||
inkscape:cy="31.875"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1200"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs2" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1">
|
|
||||||
<g
|
|
||||||
id="g4007"
|
|
||||||
transform="translate(-0.00284051)">
|
|
||||||
<g
|
|
||||||
id="g3944"
|
|
||||||
transform="translate(-2.9649416,8.6465431)">
|
|
||||||
<path
|
|
||||||
id="path19415-7"
|
|
||||||
style="color:#000000;-inkscape-font-specification:'AcPlus IBM MDA';fill:#000000;stroke:none;stroke-width:2;-inkscape-stroke:none"
|
|
||||||
d="m 12.445312,-31.673828 v 4 h 1.328126 v 11.988281 h -1.328126 v 4.001953 h 11.324219 v -8.001953 H 21.111328 V -23.6875 h 2.658203 v -7.986328 z m 15.97461,0 v 1.992187 h -1.328125 v 4.001953 h -2.658203 v 4 h 2.658203 v 8.001954 h 1.328125 v 1.99414 h 6.009766 v -1.99414 h 1.3125 v -4 h -0.988282 -3.011718 v -4.001954 h 2.6875 v -4 h -2.6875 v -5.99414 z m 11.988281,0 v 1.992187 h -1.34375 v 4.001953 H 36.40625 v 4 h 2.658203 v 8.001954 h 1.34375 v 1.99414 h 5.994141 v -1.99414 h 1.328125 v -4 h -1.003907 -2.996093 v -4.001954 h 2.671875 v -4 h -2.671875 v -5.99414 z m 11.972656,0 v 5.99414 h -1.328125 v 4 h 1.328125 v 5.994141 h -1.328125 v 4.001953 h 0.988282 6.349609 v -4.001953 h -1.34375 v -9.994141 -5.99414 z m -33.941406,4 h 0.664063 v 1.99414 h -0.664063 z m 41.929688,1.99414 v 4 h 1.003906 0.310547 v 9.996094 h 4.679687 v -9.996094 h 0.664063 v 9.996094 h 4.666015 V -12.673828 -23.6875 h -1.330078 v -1.992188 h -5.330078 -0.664062 z m -41.929688,8.001954 h 0.664063 v 1.992187 h -0.664063 z"
|
|
||||||
transform="scale(0.26458333)" />
|
|
||||||
<path
|
|
||||||
id="path14267-3-7-1"
|
|
||||||
style="font-size:4.23333px;line-height:1.25;font-family:'AcPlus IBM MDA';-inkscape-font-specification:'AcPlus IBM MDA';letter-spacing:0px;word-spacing:0px;fill:#08dd30;fill-opacity:1;stroke-width:0.529166"
|
|
||||||
d="m 3.5576229,-8.117201 v 0.5291666 h 0.3493347 v 3.7041666 H 3.5576229 v 0.5291667 h 2.4660013 v -1.5875 H 5.6742896 v 0.5291667 H 5.3197902 v 0.5291666 h -0.703834 v -1.5874999 h 0.3493347 v 0.5291666 h 0.3544993 v -1.5875 H 4.9652909 v 0.5291667 H 4.6159562 v -1.5875 h 0.703834 v 0.5291667 h 0.3544994 v 0.5291666 H 6.0236242 V -8.117201 Z m 4.2281633,0 v 0.5291666 H 7.4312869 v 1.0583333 h -0.703834 v 0.5291667 h 0.703834 v 2.1166666 h 0.3544993 v 0.5291667 h 1.0583334 v -0.5291667 h 0.3493346 v -0.5291666 h -0.703834 v 0.5291666 H 8.1351209 V -6.0005344 H 8.8441196 V -6.5297011 H 8.1351209 V -8.117201 Z m 3.1698358,0 v 0.5291666 h -0.3545 v 1.0583333 H 9.8972882 v 0.5291667 h 0.7038338 v 2.1166666 h 0.3545 v 0.5291667 h 1.058333 v -0.5291667 h 0.348297 v -0.5291666 h -0.702796 v 0.5291666 h -0.355537 v -2.1166666 h 0.710036 V -6.5297011 H 11.303919 V -8.117201 Z m 3.168798,0 v 1.0583333 h 0.703834 V -8.117201 Z m -0.3545,1.5874999 v 0.5291667 h 0.3545 v 2.1166666 h -0.3545 v 0.5291667 h 1.412833 v -0.5291667 h -0.354499 v -2.6458333 z m 2.465996,0 v 0.5291667 h 0.349335 v 2.6458333 h 0.708999 v -2.6458333 h -0.3545 v -0.5291667 z m 1.058334,0.5291667 h 0.703834 v 2.6458333 h 0.703834 V -6.0005344 H 18.352583 V -6.5297011 H 17.29425 Z" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g3982"
|
|
||||||
transform="translate(-14.717186,-10.650771)">
|
|
||||||
<path
|
|
||||||
id="path3745"
|
|
||||||
style="color:#000000;-inkscape-font-specification:'AcPlus IBM MDA';fill:#000000;stroke-width:3.77953;-inkscape-stroke:none"
|
|
||||||
transform="scale(0.26458333)"
|
|
||||||
d="m 120.74609,41.255859 v 2 h -1.34375 v 2 h -1.32226 v 11.996094 h 1.32226 v 2 h 1.34375 v 2.001953 h 2.65625 3.34375 5.33789 v -2.001953 h 1.32227 v -5.994141 h -1.32227 v -2 h -1.34375 v -2 h 2.66602 v -6.001953 h -1.32227 v -2 h -5.33789 -3.34375 z m 2,8.001953 h 0.65625 v 2 h 1.34375 v 2 h -2 z" />
|
|
||||||
<path
|
|
||||||
d="m 31.856628,14.8841 h -0.34925 v -2.645831 h 0.34925 v -0.529166 h 0.35454 v -0.529166 h 1.058334 v 0.529166 h 0.35454 v 0.529166 h 0.34925 V 14.8841 h -0.34925 v 0.529168 h -0.35454 v 0.529166 h -1.058334 v -0.529166 h -0.35454 z m 0.709082,0 v 0.529168 h 0.34925 V 14.8841 h 0.354542 V 12.238269 H 32.91496 v -0.529166 h -0.34925 v 0.529166 H 32.211168 V 14.8841 Z"
|
|
||||||
id="path14277-2-10-7-2-7-2"
|
|
||||||
style="font-size:4.23333px;line-height:1.25;font-family:'AcPlus IBM MDA';-inkscape-font-specification:'AcPlus IBM MDA';letter-spacing:0px;word-spacing:0px;fill:#e500e5;fill-opacity:1;stroke-width:0.529166" />
|
|
||||||
<path
|
|
||||||
id="path3358"
|
|
||||||
style="font-size:8.46667px;line-height:1.25;font-family:'AcPlus IBM MDA';-inkscape-font-specification:'AcPlus IBM MDA';letter-spacing:0px;word-spacing:0px;fill:#e5b800;fill-opacity:1;stroke-width:0.264583"
|
|
||||||
d="m 32.915046,11.179938 v 0.529166 h -0.349335 v 0.529167 0.529167 h 0.349335 v 0.529166 h 0.354499 v -0.529166 -0.529167 -0.529167 h 0.3545 0.703834 v 1.058334 h 0.703834 v -1.058334 h -0.349335 v -0.529166 h -1.412833 z m 1.058333,2.116666 v 0.529167 0.529167 h 0.3545 v 1.058333 h -0.703834 -0.3545 v -0.529166 -0.529167 h -0.703834 v 0.529167 0.529166 h 0.349335 v 0.529167 h 0.354499 1.412833 v -0.529167 h 0.349335 v -1.058333 h -0.349335 v -0.529167 h -0.354499 v -0.529167 z" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 6.3 KiB |
|
@ -1,7 +1,7 @@
|
||||||
MIT License
|
MIT License
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Copyright (c) 2021 CrazyEttin and contributors
|
Copyright (c) 2021 CrazyEttin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the
|
copy of this software and associated documentation files (the
|
||||||
|
|
97
README.MD
97
README.MD
|
@ -1,11 +1,9 @@
|
||||||
EttinOS
|
EttinOS
|
||||||
=======
|
=======
|
||||||
|
|
||||||
EttinOS is a minimalist 16-bit hobbyist disk operating system for the
|
EttinOS is a minimalist 16-bit DOS-like hobbyist operating system for
|
||||||
IBM Personal Computer and compatible machines. Its git repository can be
|
the IBM PC and compatible computers. Its git repository can be found at
|
||||||
found at https://ahti.space/git/crazyettin/EttinOS and that of
|
https://ahti.space/git/crazyettin/EttinOS.
|
||||||
EttinOS-extra, a collection of programs for the system, at
|
|
||||||
https://ahti.space/git/crazyettin/EttinOS-extra.
|
|
||||||
|
|
||||||
System requirements
|
System requirements
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -13,72 +11,44 @@ System requirements
|
||||||
* An Intel 8086 or compatible CPU
|
* An Intel 8086 or compatible CPU
|
||||||
* BIOS, or UEFI in legacy mode
|
* BIOS, or UEFI in legacy mode
|
||||||
* 64 KiB of RAM
|
* 64 KiB of RAM
|
||||||
* 1-4 floppy disk drives (hard disk drives are not supported)
|
* A floppy disk drive
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Build dependencies:
|
Build dependencies:
|
||||||
* A Unix-like operating system
|
* A Unix-like operating system
|
||||||
|
* bash
|
||||||
* coreutils
|
* coreutils
|
||||||
* dosfstools
|
* dosfstools
|
||||||
* mtools
|
* mtools
|
||||||
* nasm
|
* nasm
|
||||||
* rw (optional)
|
|
||||||
|
|
||||||
Running make.sh will build EttinOS and create a bootable 360 KiB 5.25"
|
Running make.sh will build EttinOS and create a bootable 360 KiB 5.25"
|
||||||
floppy disk image named EttinOS.img and a source image of the same
|
floppy disk image named EttinOS.img. To get a 1.44 MB 3.5" one instead
|
||||||
format named EttinOS-src.img. To get 1440 KiB 3.5" images instead use
|
use the argument -1440. If you want to use another floppy disk format
|
||||||
the argument -1440. If you want to use another format you will have to
|
you will have to adjust the bootloader disk description tables and
|
||||||
build the system manually.
|
install the system manually. Hard disk drives are not supported.
|
||||||
|
|
||||||
Usage
|
Input
|
||||||
-----
|
-----
|
||||||
|
|
||||||
The input system is inspired by typewriters. Typing a character
|
The EttinOS input system is inspired by typewriters. Typing a character
|
||||||
overwrites the cursor location and the erase (=tab) key erases it. The
|
overwrites the cursor location and the erase (=tab) key erases it. The
|
||||||
space and backspace keys move the cursor.
|
space and backspace keys move the cursor.
|
||||||
|
|
||||||
EttinOS assigns the drives letters from A to D and uses a version of the
|
|
||||||
MS-DOS 3.0 FAT12 file system (in actual use since 2.1) without support
|
|
||||||
for file attributes and thus disk labels and subdirectories. Drive
|
|
||||||
letters and file names are case-insensitive and the latter follow the
|
|
||||||
8.3 format. Text files use CRLF line endings.
|
|
||||||
|
|
||||||
Drives and files are specified as ([A-D]:) and ([A-D]:)FILENAME.EXT
|
|
||||||
respectively. Specifying the current drive, indicated in the prompt, is
|
|
||||||
optional.
|
|
||||||
|
|
||||||
A command can be followed by arguments separated from eachother and the
|
|
||||||
command with spaces. Extra spaces are ignored. Commands other than
|
|
||||||
changing the current drive are stored as external programs: the command
|
|
||||||
for a program is its file specification without the extension.
|
|
||||||
|
|
||||||
Commands included in EttinOS:
|
|
||||||
* [A-D]:: Change the current drive.
|
|
||||||
* ECHO: Print a message. Syntax: ECHO Message to be printed
|
|
||||||
* HELLO: Print "Hello world!".
|
|
||||||
* LIST: Print a list of the files on a drive. Syntax: LIST DRIVE
|
|
||||||
* PRINT: Print a text file. Syntax: PRINT FILE
|
|
||||||
|
|
||||||
Both LIST and PRINT page their output if all of it does not fit on the
|
|
||||||
screen at the same time. Press any key other than escape to continue
|
|
||||||
printing after each screen or escape to quit the program.
|
|
||||||
|
|
||||||
Programming
|
Programming
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
EttinOS has a flat address space of 64 KiB. The data, stack, and extra
|
EttinOS has a flat address space of 64 KiB. The data, stack, and
|
||||||
segments are set at the beginning of the RAM and the system stack at the
|
extra segments are set at the beginning of the RAM and the system stack
|
||||||
end of the address space. Programs are loaded at address 0x3000, the
|
at the end of the address space. Programs are loaded at address 0x2000.
|
||||||
number of the current drive is loaded in DL, and SI is pointed at the
|
|
||||||
command tail (a string ending in a null) when the program is executed.
|
|
||||||
The stack is reset back to the end of the address space after a program
|
The stack is reset back to the end of the address space after a program
|
||||||
has finished running.
|
has finished running.
|
||||||
|
|
||||||
System calls:
|
System calls:
|
||||||
* Interrupt 0x20: Return to the shell.
|
* Interrupt 0x20: Return to the shell.
|
||||||
* Interrupt 0x21: String operations:
|
* Interrupt 0x21: Input and output:
|
||||||
* AH = 0x0: Print a string ending in a null from SI.
|
* AH = 0x0: Print a string ending in a null from SI.
|
||||||
* AH = 0x1: Read a string ending in a null of at most AL
|
* AH = 0x1: Read a string ending in a null of at most AL
|
||||||
characters to DI until a return.
|
characters to DI until a return.
|
||||||
|
@ -86,37 +56,8 @@ System calls:
|
||||||
CRLF.
|
CRLF.
|
||||||
* AH = 0x3: Read a string ending in a null of at most AL
|
* AH = 0x3: Read a string ending in a null of at most AL
|
||||||
characters to DI until a return and print a CRLF.
|
characters to DI until a return and print a CRLF.
|
||||||
* AH = 0x4: (Under construction) Convert a decimal string ending
|
|
||||||
in a null at SI to a value in AL.
|
|
||||||
* AH = 0x5: (Under construction) Convert a value in AL to a
|
|
||||||
decimal string ending in a null at DI.
|
|
||||||
* AH = 0x6: (Under construction) Convert a hexadecimal string
|
|
||||||
ending in a null at SI to a value in AL.
|
|
||||||
* AH = 0x7: (Under construction) Convert a value in AL to a
|
|
||||||
hexadecimal string ending in a null at DI.
|
|
||||||
* Interrupt 0x22: Disk operations:
|
* Interrupt 0x22: Disk operations:
|
||||||
* AH = 0x0: (Under construction) Load the directory of a drive
|
* AH = 0x0: Load a file named in SI as a string ending in a null
|
||||||
named at SI as a string ending in a null to the offset
|
to the offset BX and set AL to 0x0 if the load was
|
||||||
BX and store the error codes in AL:
|
succesfull and 0x1 if there was an error.
|
||||||
* AL = 0x0: Succesful load
|
* AH = 0x1: Save a file (under construction).
|
||||||
* AL = 0x1: Drive not found
|
|
||||||
* AL = 0x2: Unable to read disk
|
|
||||||
* AH = 0x1: (Under construction) Store a directory at the offset
|
|
||||||
BX to a drive named at SI as a string ending in a
|
|
||||||
null.
|
|
||||||
* AH = 0x2: Load a file named at SI as a string ending in a null
|
|
||||||
to the offset BX and store the file size in CX and the
|
|
||||||
error codes in AL:
|
|
||||||
* AL = 0x0: Succesful load
|
|
||||||
* AL = 0x1: Drive not found
|
|
||||||
* AL = 0x2: Unable to read disk
|
|
||||||
* AL = 0x4: File or command not found
|
|
||||||
* AL = 0x8: Not enough memory
|
|
||||||
* AH = 0x3: (Under construction) Save a file.
|
|
||||||
|
|
||||||
Known bugs
|
|
||||||
----------
|
|
||||||
|
|
||||||
* Trying to access a disk of different format than the current one can
|
|
||||||
crash the system.
|
|
||||||
* Files beyond the ~40th one on the disk might not load properly.
|
|
||||||
|
|
41
make.sh
41
make.sh
|
@ -1,8 +1,10 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
rm -f EttinOS.img
|
rm -f EttinOS.img
|
||||||
rm -f EttinOS-src.img
|
if [ ! -d "bin" ]
|
||||||
mkdir -p bin
|
then
|
||||||
|
mkdir bin
|
||||||
|
fi
|
||||||
|
|
||||||
cd src/
|
cd src/
|
||||||
if [ "$1" = "-1440" ]
|
if [ "$1" = "-1440" ]
|
||||||
|
@ -10,42 +12,15 @@ if [ "$1" = "-1440" ]
|
||||||
else nasm BOOT.ASM -f bin -o ../bin/BOOT.BIN
|
else nasm BOOT.ASM -f bin -o ../bin/BOOT.BIN
|
||||||
fi
|
fi
|
||||||
nasm SYSTEM.ASM -f bin -o ../bin/SYSTEM.BIN
|
nasm SYSTEM.ASM -f bin -o ../bin/SYSTEM.BIN
|
||||||
nasm ECHO.ASM -f bin -o ../bin/ECHO.BIN
|
|
||||||
nasm HELLO.ASM -f bin -o ../bin/HELLO.BIN
|
nasm HELLO.ASM -f bin -o ../bin/HELLO.BIN
|
||||||
nasm LIST.ASM -f bin -o ../bin/LIST.BIN
|
|
||||||
nasm PRINT.ASM -f bin -o ../bin/PRINT.BIN
|
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
if [ "$1" = "-1440" ]
|
if [ "$1" = "-1440" ]
|
||||||
then
|
then mkfs.fat -C EttinOS.img 1440
|
||||||
mkfs.fat -C EttinOS.img 1440 1>/dev/null
|
else mkfs.fat -C EttinOS.img 360
|
||||||
mkfs.fat -C EttinOS-src.img 1440 1>/dev/null
|
|
||||||
else
|
|
||||||
mkfs.fat -C EttinOS.img 360 1>/dev/null
|
|
||||||
mkfs.fat -C EttinOS-src.img 360 1>/dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
if which rw > /dev/null 2>&1
|
|
||||||
then rw -i bin/BOOT.BIN -o EttinOS.img -b 512 -c 1x
|
|
||||||
else dd if=bin/BOOT.BIN of=EttinOS.img conv=notrunc bs=512 count=1 1>/dev/null
|
|
||||||
fi
|
fi
|
||||||
|
rw -i bin/BOOT.BIN -o EttinOS.img -b 512 -c 1x
|
||||||
mcopy -i EttinOS.img bin/SYSTEM.BIN ::
|
mcopy -i EttinOS.img bin/SYSTEM.BIN ::
|
||||||
|
mcopy -i EttinOS.img bin/HELLO.BIN ::
|
||||||
mcopy -i EttinOS.img README.MD ::
|
mcopy -i EttinOS.img README.MD ::
|
||||||
mcopy -i EttinOS.img LICENSE.MD ::
|
mcopy -i EttinOS.img LICENSE.MD ::
|
||||||
mcopy -i EttinOS.img bin/ECHO.BIN ::
|
|
||||||
mcopy -i EttinOS.img bin/HELLO.BIN ::
|
|
||||||
mcopy -i EttinOS.img bin/LIST.BIN ::
|
|
||||||
mcopy -i EttinOS.img bin/PRINT.BIN ::
|
|
||||||
|
|
||||||
mcopy -i EttinOS-src.img src/BOOT.ASM ::
|
|
||||||
mcopy -i EttinOS-src.img src/SYSTEM.ASM ::
|
|
||||||
mcopy -i EttinOS-src.img src/PRINTSTR.INC ::
|
|
||||||
mcopy -i EttinOS-src.img src/READSTR.INC ::
|
|
||||||
mcopy -i EttinOS-src.img src/PRINTLN.INC ::
|
|
||||||
mcopy -i EttinOS-src.img src/READLN.INC ::
|
|
||||||
mcopy -i EttinOS-src.img README.MD ::
|
|
||||||
mcopy -i EttinOS-src.img LICENSE.MD ::
|
|
||||||
mcopy -i EttinOS-src.img src/ECHO.ASM ::
|
|
||||||
mcopy -i EttinOS-src.img src/HELLO.ASM ::
|
|
||||||
mcopy -i EttinOS-src.img src/LIST.ASM ::
|
|
||||||
mcopy -i EttinOS-src.img src/PRINT.ASM ::
|
|
||||||
|
|
234
src/BOOT.ASM
234
src/BOOT.ASM
|
@ -1,136 +1,120 @@
|
||||||
cpu 8086
|
CPU 8086
|
||||||
org 0x7c00
|
ORG 0x7c00
|
||||||
|
|
||||||
;Jump to the code
|
|
||||||
jmp start
|
jmp start
|
||||||
|
|
||||||
;Padding
|
|
||||||
nop
|
nop
|
||||||
|
|
||||||
;OEM label
|
;Disk description tables
|
||||||
db "ETTINOS "
|
|
||||||
|
|
||||||
%ifdef F1440
|
%ifdef F1440
|
||||||
|
;1.44 MB 3.5" floppy disk (enable with the argument -d F1440 when building)
|
||||||
;1.44 MB 3.5" floppy disk BPB (enable with the argument -d F1440)
|
oemlabel db "ETTINOS "
|
||||||
sectorsize dw 0x200 ;bytes
|
sectorsize dw 0x200 ;bytes
|
||||||
clustersize db 0x1 ;sectors
|
clustersize db 0x1 ;sectors
|
||||||
reservedsectors dw 0x1
|
bootsectors dw 0x1
|
||||||
fats db 0x2
|
fats db 0x2
|
||||||
rootentries dw 0xe0
|
rootentries dw 0xe0
|
||||||
logicalsectors dw 0xb40
|
logicalsectors dw 0xb40
|
||||||
mediadescriptor db 0xf0
|
mediadescriptor db 0xf0
|
||||||
sectorsperfat dw 0x9
|
sectorsperfat dw 0x9
|
||||||
sectorspertrack dw 0x12
|
sectorspertrack dw 0x12
|
||||||
heads dw 0x2
|
sides dw 0x2
|
||||||
hiddensectors dw 0x0
|
hiddensectors dd 0x0
|
||||||
|
largesectors dd 0x0
|
||||||
|
driveid dw 0x0
|
||||||
|
drivesignature db 0x29
|
||||||
|
volumeid dd 0x0
|
||||||
|
volumelabel db "ETTINOS "
|
||||||
|
filesystem db "FAT12 "
|
||||||
|
|
||||||
%else
|
%else
|
||||||
|
;360 KiB 5.25" floppy disk (default)
|
||||||
;360 KiB 5.25" floppy disk BPB (default)
|
oemlabel db "ETTINOS "
|
||||||
sectorsize dw 0x200 ;bytes
|
sectorsize dw 0x200 ;bytes
|
||||||
clustersize db 0x2 ;sectors
|
clustersize db 0x2 ;sectors
|
||||||
reservedsectors dw 0x1
|
bootsectors dw 0x1
|
||||||
fats db 0x2
|
fats db 0x2
|
||||||
rootentries dw 0x70
|
rootentries dw 0x70
|
||||||
logicalsectors dw 0x2d0
|
logicalsectors dw 0x2d0
|
||||||
mediadescriptor db 0xfd
|
mediadescriptor db 0xfd
|
||||||
sectorsperfat dw 0x2
|
sectorsperfat dw 0x2
|
||||||
sectorspertrack dw 0x9
|
sectorspertrack dw 0x9
|
||||||
heads dw 0x2
|
sides dw 0x2
|
||||||
hiddensectors dw 0x0
|
hiddensectors dd 0x0
|
||||||
|
largesectors dd 0x0
|
||||||
|
driveid dw 0x0
|
||||||
|
drivesignature db 0x29
|
||||||
|
volumeid dd 0x0
|
||||||
|
volumelabel db "ETTINOS "
|
||||||
|
filesystem db "FAT12 "
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
;Setup
|
|
||||||
;Set the segments
|
|
||||||
start:
|
start:
|
||||||
|
|
||||||
|
;Setup
|
||||||
|
;Set up the data, stack, and extra segments
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
;Set the stack
|
;Set up the stack
|
||||||
cli
|
cli
|
||||||
mov sp, 0x0
|
mov sp, 0x0
|
||||||
sti
|
sti
|
||||||
;Store the boot drive number
|
;Store the boot drive number
|
||||||
mov [drive], dl
|
mov [bootdrive], dl
|
||||||
|
|
||||||
;Calculate and store variables not found in the BPB
|
;Load the root
|
||||||
;Start of the root
|
;Set the source
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
mov al, [fats]
|
mov al, [fats]
|
||||||
mul word [sectorsperfat]
|
mul word [sectorsperfat]
|
||||||
add ax, [reservedsectors]
|
add ax, [bootsectors]
|
||||||
mov [rootstart], ax
|
push ax
|
||||||
;Size of the root in sectors
|
call calcsource
|
||||||
|
;Set the destination
|
||||||
|
mov si, buffer
|
||||||
|
mov bx, si
|
||||||
|
;Set the size
|
||||||
|
push dx
|
||||||
mov ax, [rootentries]
|
mov ax, [rootentries]
|
||||||
mov dx, 0x20
|
mov dx, 0x20
|
||||||
mul dx
|
mul dx
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorsize]
|
div word [sectorsize]
|
||||||
mov [rootsectors], ax
|
pop dx
|
||||||
;Start of data
|
|
||||||
add ax, [rootstart]
|
|
||||||
mov [datastart], ax
|
|
||||||
|
|
||||||
;Load the root
|
|
||||||
;Set the source
|
|
||||||
mov ax, [rootstart]
|
|
||||||
;Set the destination
|
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov cx, [rootsectors]
|
|
||||||
;Store the source and the loop counter in the stack
|
|
||||||
loadrootsector:
|
|
||||||
push ax
|
push ax
|
||||||
push cx
|
;Load
|
||||||
;Set the source
|
|
||||||
call calcsource
|
|
||||||
;Set the size
|
|
||||||
mov al, 0x1
|
|
||||||
;Load a sector
|
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
;Load the loop counter and the source from the stack
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
;Set the next sector
|
|
||||||
add ax, 0x1
|
|
||||||
add bx, word [sectorsize]
|
|
||||||
;Load the next sector
|
|
||||||
loop loadrootsector
|
|
||||||
|
|
||||||
;Search the root for the system entry
|
;Search the root for the system entry
|
||||||
;Set DI to the root
|
;Set DI to the root
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
;Set the number of root entries
|
;Initialise the search loop
|
||||||
mov cx, word [rootentries]
|
mov cx, word [rootentries]
|
||||||
;Set the entry pointer
|
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
;Store the loop counter in the stack
|
|
||||||
search:
|
search:
|
||||||
|
;Store CX in the stack
|
||||||
push cx
|
push cx
|
||||||
;Check for the system entry
|
;Check for the system entry
|
||||||
mov si, file
|
mov si, sysfile
|
||||||
mov cx, 0xb
|
mov cx, 0xb
|
||||||
rep cmpsb
|
rep cmpsb
|
||||||
je loadfat
|
je loadentry
|
||||||
;Set DI at the next entry
|
;Set DI to the next entry
|
||||||
add ax, 0x20
|
add ax, 0x20
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
add di, ax
|
add di, ax
|
||||||
;Load the loop counter from the stack
|
;Load CX from the stack
|
||||||
pop cx
|
pop cx
|
||||||
;Search the next entry
|
|
||||||
loop search
|
loop search
|
||||||
|
|
||||||
;Print an error message and hang if the system is not found
|
;Print an error message if the system is not found
|
||||||
;Set SI at the file error message
|
mov si, errormsg
|
||||||
mov si, filerrormsg
|
printerror:
|
||||||
;Load a character
|
;Load a character
|
||||||
printstr:
|
|
||||||
lodsb
|
lodsb
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
|
@ -138,61 +122,53 @@ je $
|
||||||
;Print the character
|
;Print the character
|
||||||
mov ah, 0xe
|
mov ah, 0xe
|
||||||
int 0x10
|
int 0x10
|
||||||
;Print the next character
|
;Repeat
|
||||||
jmp printstr
|
jmp printerror
|
||||||
|
|
||||||
;Load the FAT
|
;Load the system entry
|
||||||
|
loadentry:
|
||||||
;Load CX from the stack
|
;Load CX from the stack
|
||||||
loadfat:
|
|
||||||
pop cx
|
pop cx
|
||||||
;Store the address of the first cluster
|
;Store the first cluster
|
||||||
mov ax, [di + 0xf]
|
mov ax, word [es:di+0xf]
|
||||||
mov [cluster], ax
|
mov word [cluster], ax
|
||||||
;Set the source
|
;Set the source
|
||||||
mov ax, [reservedsectors]
|
mov ax, 0x1
|
||||||
call calcsource
|
call calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov bx, buffer
|
mov di, buffer
|
||||||
|
mov bx, di
|
||||||
;Set the size
|
;Set the size
|
||||||
mov ax, [sectorsperfat]
|
mov ax, [sectorsperfat]
|
||||||
;Load the FAT
|
;Load
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
|
||||||
|
;Load the system file
|
||||||
|
|
||||||
;Load a cluster
|
;Load a cluster
|
||||||
loadcluster:
|
loadcluster:
|
||||||
;Set the source
|
;Set the source
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
mov ax, word [cluster]
|
mov ax, word [cluster]
|
||||||
sub ax, 0x2
|
sub ax, 0x2
|
||||||
mul byte [clustersize]
|
mul byte [clustersize]
|
||||||
add ax, [datastart]
|
add ax, bx
|
||||||
|
add ax, cx
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
call calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov bx, word [pointer]
|
mov bx, word [pointer]
|
||||||
;Set the size
|
;Set the size
|
||||||
mov ch, 0x0
|
;mov al, 0x1
|
||||||
mov cl, byte [clustersize]
|
mov al, [clustersize]
|
||||||
;Store the loop counter in the stack
|
;Load
|
||||||
loadclustersector:
|
|
||||||
push cx
|
|
||||||
;Set the source
|
|
||||||
call calcsource
|
|
||||||
;Set the size
|
|
||||||
push ax
|
|
||||||
mov al, 0x1
|
|
||||||
;Load a sector
|
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
pop ax
|
|
||||||
;Set the next sector
|
|
||||||
add ax, 0x1
|
|
||||||
add bx, [sectorsize]
|
|
||||||
;Load the loop counter from the stack
|
|
||||||
pop cx
|
|
||||||
;Load the next sector
|
|
||||||
loop loadclustersector
|
|
||||||
|
|
||||||
;Calculate the next cluster
|
;Calculate the next cluster
|
||||||
;Check if the cluster is even or odd
|
|
||||||
mov ax, [cluster]
|
mov ax, [cluster]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
mov bx, 0x3
|
mov bx, 0x3
|
||||||
|
@ -201,87 +177,65 @@ mov bx, 0x2
|
||||||
div bx
|
div bx
|
||||||
mov si, buffer
|
mov si, buffer
|
||||||
add si, ax
|
add si, ax
|
||||||
mov ax, word [si]
|
mov ax, word [ds:si]
|
||||||
or dx, dx
|
or dx, dx
|
||||||
jz even
|
jz even
|
||||||
;If the cluster is odd shift out the first four bits
|
odd:
|
||||||
times 0x4 shr ax, 0x1
|
shr ax, 1
|
||||||
|
shr ax, 1
|
||||||
|
shr ax, 1
|
||||||
|
shr ax, 1
|
||||||
jmp contcalc
|
jmp contcalc
|
||||||
;If the cluster is even mask out the final four bits
|
|
||||||
even:
|
even:
|
||||||
and ax, 0xfff
|
and ax, 0xfff
|
||||||
contcalc:
|
contcalc:
|
||||||
;Check for the file end
|
mov word [cluster], ax
|
||||||
cmp ax, 0xff8
|
cmp ax, 0xff8
|
||||||
jge boot
|
jge boot
|
||||||
;Store the address of the next cluster
|
|
||||||
mov word [cluster], ax
|
|
||||||
;Set the destination of the next cluster
|
|
||||||
mov ax, [sectorsize]
|
mov ax, [sectorsize]
|
||||||
mul word [clustersize]
|
mul word [clustersize]
|
||||||
add word [pointer], ax
|
add word [pointer], ax
|
||||||
;Load the next cluster
|
|
||||||
jmp loadcluster
|
jmp loadcluster
|
||||||
|
|
||||||
;Boot the system
|
;Clear the stack and boot the system
|
||||||
;Pass the boot drive number to the system
|
|
||||||
boot:
|
boot:
|
||||||
mov dl, byte [drive]
|
;Clear
|
||||||
;Boot the system
|
pop cx
|
||||||
|
pop bx
|
||||||
|
;Boot
|
||||||
jmp 0x0:0x500
|
jmp 0x0:0x500
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
drive db 0x0
|
bootdrive db 0x0
|
||||||
rootstart dw 0x0
|
sysfile db "SYSTEM BIN"
|
||||||
rootsectors dw 0x0
|
errormsg db "System not found", 0xd, 0xa, 0x0
|
||||||
datastart dw 0x0
|
|
||||||
file db "SYSTEM BIN"
|
|
||||||
filerrormsg db "System not found", 0xd, 0xa, 0x0
|
|
||||||
cluster dw 0x0
|
cluster dw 0x0
|
||||||
pointer dw 0x500
|
pointer dw 0x500
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Calculate the source arguments for loading data from the disk
|
;Calculate the source arguments for loading data from the disk
|
||||||
calcsource:
|
calcsource:
|
||||||
|
|
||||||
;Store AX and BX in the stack
|
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
|
||||||
;Calculate the cylinder, head, and sector
|
|
||||||
;Store the logical sector in BX
|
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
;Calculate the sector
|
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [sectorspertrack]
|
||||||
add dl, 0x1
|
add dl, 0x1
|
||||||
mov cl, dl
|
mov cl, dl
|
||||||
;Load the logical sector from BX
|
|
||||||
mov ax, bx
|
mov ax, bx
|
||||||
;Calculate the head and cylinder
|
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [sectorspertrack]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [heads]
|
div word [sides]
|
||||||
mov dh, dl ;Head
|
mov dh, dl
|
||||||
mov ch, al ;Cylinder
|
mov ch, al
|
||||||
|
|
||||||
;Load the boot drive number
|
|
||||||
mov dl, byte [drive]
|
|
||||||
|
|
||||||
;Load BX and AX from the stack
|
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
|
mov dl, byte [bootdrive]
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;***
|
;Pad the binary to a full sector and make the disk bootable
|
||||||
|
|
||||||
;Padding
|
;Padding
|
||||||
times 0x1fe-($-$$) db 0x0
|
times 0x1fe-($-$$) db 0x0
|
||||||
|
|
||||||
;Boot signature
|
;Boot signature
|
||||||
dw 0xaa55
|
dw 0xaa55
|
||||||
|
|
||||||
|
|
14
src/ECHO.ASM
14
src/ECHO.ASM
|
@ -1,14 +0,0 @@
|
||||||
cpu 8086
|
|
||||||
org 0x3000
|
|
||||||
|
|
||||||
;Check for an empty tail
|
|
||||||
cmp byte [si], 0x0
|
|
||||||
je done
|
|
||||||
|
|
||||||
;Print the message
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
|
|
||||||
;Return to the system
|
|
||||||
done:
|
|
||||||
int 0x20
|
|
|
@ -1,13 +1,11 @@
|
||||||
cpu 8086
|
CPU 8086
|
||||||
org 0x3000
|
ORG 0x2000
|
||||||
|
|
||||||
;Print a hello world.
|
;Prints a hello world.
|
||||||
mov si, hello
|
mov si, .hello
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
|
|
||||||
;Return to the system
|
|
||||||
int 0x20
|
int 0x20
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
hello db "Hello world!", 0x0
|
.hello db "Hello world!", 0x0
|
||||||
|
|
264
src/LIST.ASM
264
src/LIST.ASM
|
@ -1,264 +0,0 @@
|
||||||
cpu 8086
|
|
||||||
org 0x3000
|
|
||||||
|
|
||||||
;Store the drive number
|
|
||||||
mov [drive], dl
|
|
||||||
|
|
||||||
;Check for an empty tail
|
|
||||||
cmp byte [si], 0x0
|
|
||||||
je loadvalues
|
|
||||||
|
|
||||||
;Change the drive if needed
|
|
||||||
;Check for a drive specification
|
|
||||||
cmp byte [si + 0x1], ":"
|
|
||||||
jne driverror
|
|
||||||
cmp byte [si + 0x2], 0x0
|
|
||||||
je changedrive
|
|
||||||
cmp byte [si + 0x2], 0x20
|
|
||||||
je changedrive
|
|
||||||
;Print an error message
|
|
||||||
jmp driverror
|
|
||||||
changedrive:
|
|
||||||
;Get the BIOS equipment list
|
|
||||||
int 0x11
|
|
||||||
;Get the number of floppy drives
|
|
||||||
times 0x6 shr ax, 0x1
|
|
||||||
and ax, 0x3
|
|
||||||
inc ax
|
|
||||||
;Set the loop and drive letter counters and the drive letter and number
|
|
||||||
mov cx, ax
|
|
||||||
mov di, driveletters
|
|
||||||
mov al, [si]
|
|
||||||
mov dl, 0x0
|
|
||||||
;Check which drive to change to
|
|
||||||
checkdrive:
|
|
||||||
cmp al, [di]
|
|
||||||
je contchdrive
|
|
||||||
inc di
|
|
||||||
cmp al, [di]
|
|
||||||
je contchdrive
|
|
||||||
inc di
|
|
||||||
inc dl
|
|
||||||
loop checkdrive
|
|
||||||
;Print an error message
|
|
||||||
jmp driverror
|
|
||||||
;Change the drive
|
|
||||||
contchdrive:
|
|
||||||
mov [drive], dl
|
|
||||||
|
|
||||||
;Load the disk description table
|
|
||||||
;Set the source
|
|
||||||
loadvalues:
|
|
||||||
mov dl, [drive]
|
|
||||||
mov ch, 0x0
|
|
||||||
mov dh, 0x0
|
|
||||||
mov cl, 0x1
|
|
||||||
;Set the destination
|
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov al, 0x1
|
|
||||||
;Load the disk description table
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x13
|
|
||||||
jc diskerror
|
|
||||||
|
|
||||||
;Store the disk values used for the rest of the call
|
|
||||||
mov ax, [buffer + 0xb]
|
|
||||||
mov [sectorsize], ax
|
|
||||||
mov ax, [buffer + 0xe]
|
|
||||||
mov [reservedsectors], ax
|
|
||||||
mov al, [buffer + 0x10]
|
|
||||||
mov [fats], al
|
|
||||||
mov ax, [buffer + 0x11]
|
|
||||||
mov [rootentries], ax
|
|
||||||
mov ax, [buffer + 0x16]
|
|
||||||
mov [sectorsperfat], ax
|
|
||||||
mov ax, [buffer + 0x18]
|
|
||||||
mov [sectorspertrack], ax
|
|
||||||
mov ax, [buffer + 0x1a]
|
|
||||||
mov [heads], ax
|
|
||||||
|
|
||||||
;Calculate and store variables not found in the BPB
|
|
||||||
;Start of the root
|
|
||||||
mov ah, 0x0
|
|
||||||
mov al, [fats]
|
|
||||||
mul word [sectorsperfat]
|
|
||||||
add ax, [reservedsectors]
|
|
||||||
mov [rootstart], ax
|
|
||||||
;Size of the root in sectors
|
|
||||||
mov ax, [rootentries]
|
|
||||||
mov dx, 0x20
|
|
||||||
mul dx
|
|
||||||
mov dx, 0x0
|
|
||||||
div word [sectorsize]
|
|
||||||
mov [rootsectors], ax
|
|
||||||
|
|
||||||
;Load the root
|
|
||||||
;Set the source
|
|
||||||
mov ax, [rootstart]
|
|
||||||
;Set the destination
|
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov cx, [rootsectors]
|
|
||||||
;Store the source and the loop counter in the stack
|
|
||||||
loadrootsector:
|
|
||||||
push ax
|
|
||||||
push cx
|
|
||||||
;Set the source
|
|
||||||
call calcsource
|
|
||||||
;Set the size
|
|
||||||
mov al, 0x1
|
|
||||||
;Load a sector
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x13
|
|
||||||
;Load the loop counter and the source from the stack
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
;Set the next sector
|
|
||||||
add ax, 0x1
|
|
||||||
add bx, word [sectorsize]
|
|
||||||
loop loadrootsector
|
|
||||||
|
|
||||||
;List
|
|
||||||
;Set SI to the root
|
|
||||||
mov si, buffer
|
|
||||||
;Initialise the loop
|
|
||||||
mov cx, word [rootentries]
|
|
||||||
mov ax, 0x0
|
|
||||||
mov bl, 0x17
|
|
||||||
;Store CX in the stack
|
|
||||||
loop:
|
|
||||||
push cx
|
|
||||||
;Check for an empty entry
|
|
||||||
cmp byte [si], 0xe5
|
|
||||||
je skip
|
|
||||||
;Check for the end of entries
|
|
||||||
cmp byte [si], 0x0
|
|
||||||
je done
|
|
||||||
;store AX in the stack
|
|
||||||
push ax
|
|
||||||
;Print the main part of the name
|
|
||||||
mov cx, 0x8
|
|
||||||
push ax
|
|
||||||
printname:
|
|
||||||
mov al, [si]
|
|
||||||
mov ah, 0xe
|
|
||||||
int 0x10
|
|
||||||
inc si
|
|
||||||
loop printname
|
|
||||||
;Print a space
|
|
||||||
mov al, 0x20
|
|
||||||
mov ah, 0xe
|
|
||||||
int 0x10
|
|
||||||
;Print the extension
|
|
||||||
mov cx, 0x3
|
|
||||||
printext:
|
|
||||||
mov al, [si]
|
|
||||||
mov ah, 0xe
|
|
||||||
int 0x10
|
|
||||||
inc si
|
|
||||||
loop printext
|
|
||||||
;Print a newline
|
|
||||||
mov al, 0xd
|
|
||||||
mov ah, 0xe
|
|
||||||
int 0x10
|
|
||||||
mov al, 0xa
|
|
||||||
mov ah, 0xe
|
|
||||||
int 0x10
|
|
||||||
;Load AX from the stack
|
|
||||||
pop ax
|
|
||||||
;Check paging
|
|
||||||
cmp bl, 0x0
|
|
||||||
jz page
|
|
||||||
dec bl
|
|
||||||
;Set SI to the next entry
|
|
||||||
skip:
|
|
||||||
add ax, 0x20
|
|
||||||
mov si, buffer
|
|
||||||
add si, ax
|
|
||||||
;Load CX from the stack
|
|
||||||
pop cx
|
|
||||||
loop loop
|
|
||||||
page:
|
|
||||||
push ax
|
|
||||||
mov ah, 0x0
|
|
||||||
int 0x16
|
|
||||||
cmp al, 0x1b
|
|
||||||
je done
|
|
||||||
pop ax
|
|
||||||
mov bl, 0x17
|
|
||||||
jmp skip
|
|
||||||
|
|
||||||
done:
|
|
||||||
int 0x20
|
|
||||||
|
|
||||||
driverror:
|
|
||||||
mov si, driverrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
jmp done
|
|
||||||
|
|
||||||
diskerror:
|
|
||||||
mov si, diskerrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
jmp done
|
|
||||||
|
|
||||||
;Data
|
|
||||||
drive db 0x0
|
|
||||||
sectorsize dw 0x0 ;bytes
|
|
||||||
reservedsectors dw 0x0
|
|
||||||
fats db 0x0
|
|
||||||
rootentries dw 0x0
|
|
||||||
sectorsperfat dw 0x0
|
|
||||||
sectorspertrack dw 0x0
|
|
||||||
heads dw 0x0
|
|
||||||
rootstart dw 0x0
|
|
||||||
rootsectors dw 0x0
|
|
||||||
driveletters db "AaBbCcDd"
|
|
||||||
driverrormsg db "Drive not found", 0x0
|
|
||||||
diskerrormsg db "Unable to read disk", 0x0
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Calculate the source arguments for loading data from the disk
|
|
||||||
calcsource:
|
|
||||||
|
|
||||||
;Store AX and BX in the stack
|
|
||||||
push ax
|
|
||||||
push bx
|
|
||||||
|
|
||||||
;Calculate the cylinder, head, and sector
|
|
||||||
;Store the logical sector in BX
|
|
||||||
mov bx, ax
|
|
||||||
;Calculate the sector
|
|
||||||
mov dx, 0x0
|
|
||||||
div word [sectorspertrack]
|
|
||||||
add dl, 0x1
|
|
||||||
mov cl, dl
|
|
||||||
;Load the logical sector from BX
|
|
||||||
mov ax, bx
|
|
||||||
;Calculate the head and cylinder
|
|
||||||
mov dx, 0x0
|
|
||||||
div word [sectorspertrack]
|
|
||||||
mov dx, 0x0
|
|
||||||
div word [heads]
|
|
||||||
mov dh, dl ;Head
|
|
||||||
mov ch, al ;Cylinder
|
|
||||||
|
|
||||||
;Load the drive number
|
|
||||||
mov dl, byte [drive]
|
|
||||||
|
|
||||||
;Load BX and AX from the stack
|
|
||||||
pop bx
|
|
||||||
pop ax
|
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Buffer
|
|
||||||
buffer:
|
|
384
src/LOADF.INC
384
src/LOADF.INC
|
@ -1,91 +1,48 @@
|
||||||
;Load a file named at SI as a string ending in a null to the offset BX
|
;Load a file named in SI as a string ending in a null to the offset BX and set AL to 0x0 if the load was succesful and 0x1 if there was an error.
|
||||||
;and store the file size in CX and the error codes in AL:
|
|
||||||
; * AL = 0x0: Succesful load
|
|
||||||
; * AL = 0x1: Drive not found
|
|
||||||
; * AL = 0x2: Unable to read disk
|
|
||||||
; * AL = 0x4: File or command not found
|
|
||||||
; * AL = 0x8: Not enough memory
|
|
||||||
|
|
||||||
loadf:
|
loadf:
|
||||||
|
|
||||||
;Store BX, DX, SI, and DI in the stack
|
;Store the initial registers in the stack
|
||||||
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
push cx
|
||||||
push dx
|
push dx
|
||||||
push si
|
push si
|
||||||
push di
|
push di
|
||||||
|
|
||||||
;Store the current drive and offset
|
;Store the offset
|
||||||
mov word [.pointer], bx
|
mov word [.pointer], bx
|
||||||
mov dl, byte [curdrive]
|
|
||||||
mov byte [drive], dl
|
|
||||||
|
|
||||||
;Change the drive if needed
|
|
||||||
;Check for a drive specification
|
|
||||||
cmp byte [si + 0x1], ":"
|
|
||||||
jne .convert
|
|
||||||
;Get the BIOS equipment list
|
|
||||||
int 0x11
|
|
||||||
;Get the number of floppy drives
|
|
||||||
times 0x6 shr ax, 0x1
|
|
||||||
and ax, 0x3
|
|
||||||
inc ax
|
|
||||||
;Set the loop and drive letter counters and the drive letter and number
|
|
||||||
mov cx, ax
|
|
||||||
mov di, driveletters
|
|
||||||
mov al, [si]
|
|
||||||
mov dl, 0x0
|
|
||||||
;Check which drive to change to
|
|
||||||
.checkdrive:
|
|
||||||
cmp al, [di]
|
|
||||||
je .contchdrive
|
|
||||||
inc di
|
|
||||||
cmp al, [di]
|
|
||||||
je .contchdrive
|
|
||||||
inc di
|
|
||||||
inc dl
|
|
||||||
loop .checkdrive
|
|
||||||
;Set AL to 0x1, CX to 0x0, and print an error message
|
|
||||||
mov si, .driverrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
mov al, 0x1
|
|
||||||
mov cx, 0x0
|
|
||||||
jmp .done
|
|
||||||
;Change the drive
|
|
||||||
.contchdrive:
|
|
||||||
mov [drive], dl
|
|
||||||
;Move to the file name
|
|
||||||
add si, 0x2
|
|
||||||
|
|
||||||
;Set DI at .file and initialise it with spaces
|
;Set DI at .file and initialise it with spaces
|
||||||
.convert:
|
|
||||||
mov di, .file
|
mov di, .file
|
||||||
mov cx, 0xb
|
mov cx, 0xb
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
rep stosb
|
rep stosb
|
||||||
sub di, 0xb
|
sub di, 0xb
|
||||||
|
|
||||||
;Convert the main part of the file name into FAT format
|
;Convert .file into FAT formatting
|
||||||
;Set the length counter
|
|
||||||
|
;Initialise the length counter for the main part of the name
|
||||||
mov bl, 0x8
|
mov bl, 0x8
|
||||||
;Load a character
|
|
||||||
|
;Convert the main part of the file name
|
||||||
.nameloop:
|
.nameloop:
|
||||||
|
;Load a character
|
||||||
lodsb
|
lodsb
|
||||||
;Check for a period
|
;Check for a period
|
||||||
cmp al, 0x2e
|
cmp al, 0x2e
|
||||||
je .initext
|
je .initext
|
||||||
;Check for everything else and convert to upper case
|
;Check for everything else and convert to upper case
|
||||||
call .checkconv
|
call .checkconv
|
||||||
;Load the next character
|
|
||||||
jmp .nameloop
|
jmp .nameloop
|
||||||
|
|
||||||
;Convert the extension into FAT format
|
;Convert the extension
|
||||||
;Set DI and the length counter for the extension
|
|
||||||
.initext:
|
.initext:
|
||||||
|
;Set DI and initialise the length counter for the extension
|
||||||
mov bl, 0x3
|
mov bl, 0x3
|
||||||
mov di, .file+0x8
|
mov di, .file+0x8
|
||||||
;Load a character
|
|
||||||
.extloop:
|
.extloop:
|
||||||
|
;Load a character
|
||||||
lodsb
|
lodsb
|
||||||
;Check for a period
|
;Check for a period
|
||||||
push ax
|
push ax
|
||||||
|
@ -94,223 +51,119 @@ je .error
|
||||||
pop ax
|
pop ax
|
||||||
;Check for everything else and convert to upper case
|
;Check for everything else and convert to upper case
|
||||||
call .checkconv
|
call .checkconv
|
||||||
;Load the next character
|
|
||||||
jmp .extloop
|
jmp .extloop
|
||||||
;Set AL to 0x4, CX to 0x0, and print an error message
|
|
||||||
|
;Set the carry flag and print an error message if the file name is invalid
|
||||||
.error:
|
.error:
|
||||||
pop ax
|
pop ax
|
||||||
mov si, .filerrormsg
|
stc
|
||||||
|
mov si, .errormsg
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
mov al, 0x4
|
|
||||||
mov cx, 0x0
|
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
;Find and load the file
|
;Find and load the file
|
||||||
|
|
||||||
.load:
|
.load:
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
;Load the disk description table
|
;Load the root
|
||||||
;Set the source
|
;Set the source
|
||||||
mov dl, [drive]
|
mov ah, 0x0
|
||||||
mov ch, 0x0
|
mov al, [.fats]
|
||||||
mov dh, 0x0
|
mul word [.sectorsperfat]
|
||||||
mov cl, 0x1
|
add ax, [.bootsectors]
|
||||||
|
push ax
|
||||||
|
call .calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov si, buffer
|
mov si, buffer
|
||||||
mov bx, si
|
mov bx, si
|
||||||
;Set the size
|
;Set the size
|
||||||
mov al, 0x1
|
push dx
|
||||||
;Load the disk description table
|
mov ax, [.rootentries]
|
||||||
mov ah, 0x2
|
|
||||||
int 0x13
|
|
||||||
jnc .storevalues
|
|
||||||
;Set AL to 0x2, CX to 0x0, and print an error message
|
|
||||||
mov si, .diskerrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
mov al, 0x2
|
|
||||||
mov cx, 0x0
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
;Store the disk values used for the rest of the call
|
|
||||||
.storevalues:
|
|
||||||
mov ax, [buffer + 0xb]
|
|
||||||
mov [sectorsize], ax
|
|
||||||
mov al, [buffer + 0xd]
|
|
||||||
mov [clustersize], al
|
|
||||||
mov ax, [buffer + 0xe]
|
|
||||||
mov [reservedsectors], ax
|
|
||||||
mov al, [buffer + 0x10]
|
|
||||||
mov [fats], al
|
|
||||||
mov ax, [buffer + 0x11]
|
|
||||||
mov [rootentries], ax
|
|
||||||
mov ax, [buffer + 0x16]
|
|
||||||
mov [sectorsperfat], ax
|
|
||||||
mov ax, [buffer + 0x18]
|
|
||||||
mov [sectorspertrack], ax
|
|
||||||
mov ax, [buffer + 0x1a]
|
|
||||||
mov [heads], ax
|
|
||||||
|
|
||||||
;Calculate and store variables not found in the BPB
|
|
||||||
;Start of the root
|
|
||||||
mov ah, 0x0
|
|
||||||
mov al, [fats]
|
|
||||||
mul word [sectorsperfat]
|
|
||||||
add ax, [reservedsectors]
|
|
||||||
mov [rootstart], ax
|
|
||||||
;Size of the root in sectors
|
|
||||||
mov ax, [rootentries]
|
|
||||||
mov dx, 0x20
|
mov dx, 0x20
|
||||||
mul dx
|
mul dx
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorsize]
|
div word [.sectorsize]
|
||||||
mov [rootsectors], ax
|
pop dx
|
||||||
;Start of data
|
|
||||||
add ax, [rootstart]
|
|
||||||
mov [datastart], ax
|
|
||||||
|
|
||||||
;Load the root
|
|
||||||
;Set the source
|
|
||||||
mov ax, [rootstart]
|
|
||||||
;Set the destination
|
|
||||||
mov si, buffer
|
|
||||||
mov bx, si
|
|
||||||
;Set the size
|
|
||||||
mov cx, [rootsectors]
|
|
||||||
;Store the source and the loop counter in the stack
|
|
||||||
.loadrootsector:
|
|
||||||
push ax
|
push ax
|
||||||
push cx
|
;Load
|
||||||
;Set the source
|
|
||||||
call .calcsource
|
|
||||||
;Set the size
|
|
||||||
mov al, 0x1
|
|
||||||
;Load a sector
|
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
;Load the loop counter and the source from the stack
|
|
||||||
pop cx
|
|
||||||
pop ax
|
|
||||||
;Set the next sector
|
|
||||||
add ax, 0x1
|
|
||||||
add bx, word [sectorsize]
|
|
||||||
;Load the next sector
|
|
||||||
loop .loadrootsector
|
|
||||||
|
|
||||||
;Search the root for the file entry
|
;Search the root for the file entry
|
||||||
;Set DI to the root
|
;Set DI to the root
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
;Set the number of root entries
|
;Initialise the search loop
|
||||||
mov cx, word [rootentries]
|
mov cx, word [.rootentries]
|
||||||
;Set the entry pointer
|
|
||||||
mov ax, 0x0
|
mov ax, 0x0
|
||||||
;Store the loop counter in the stack
|
|
||||||
.search:
|
.search:
|
||||||
|
;Store CX in the stack
|
||||||
push cx
|
push cx
|
||||||
;Check for the file entry
|
;Check for the file entry
|
||||||
mov si, .file
|
mov si, .file
|
||||||
mov cx, 0xb
|
mov cx, 0xb
|
||||||
rep cmpsb
|
rep cmpsb
|
||||||
je .checksize
|
je .loadentry
|
||||||
;Set DI at the next entry
|
;Set DI to the next entry
|
||||||
add ax, 0x20
|
add ax, 0x20
|
||||||
mov di, buffer
|
mov di, buffer
|
||||||
add di, ax
|
add di, ax
|
||||||
;Load the loop counter from the stack
|
|
||||||
pop cx
|
|
||||||
;Search the next entry
|
|
||||||
loop .search
|
|
||||||
;Set AL to 0x4, CX to 0x0, and print an error message
|
|
||||||
mov si, .filerrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
mov al, 0x4
|
|
||||||
mov cx, 0x0
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
;Check and store the file size
|
|
||||||
;Load CX from the stack
|
;Load CX from the stack
|
||||||
.checksize:
|
|
||||||
pop cx
|
pop cx
|
||||||
;Check for files larger than 64 KiB
|
loop .search
|
||||||
cmp word [di + 0x13], 0x0
|
|
||||||
jne .sizerror
|
;Set the carry flag and print an error message if the file is not found
|
||||||
;Get the cluster size in bytes
|
stc
|
||||||
mov ah, 0x0
|
mov si, .errormsg
|
||||||
mov al, [clustersize]
|
|
||||||
mul word [sectorsize]
|
|
||||||
mov bx, ax
|
|
||||||
;Store the file size
|
|
||||||
mov ax, [di + 0x11]
|
|
||||||
mov word [.size], ax
|
|
||||||
;Check for files smaller than 64 KiB but too large to fit into memory
|
|
||||||
jc .sizerror
|
|
||||||
dec ax
|
|
||||||
mov dx, 0x0
|
|
||||||
div bx
|
|
||||||
mul bx
|
|
||||||
add ax, [.pointer]
|
|
||||||
jnc .loadfat
|
|
||||||
;Set AL to 0x8, CX to 0x0, and print an error message
|
|
||||||
.sizerror:
|
|
||||||
mov si, .sizerrormsg
|
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
mov al, 0x8
|
jmp .clearstack
|
||||||
mov cx, 0x0
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
;Load the FAT
|
;Load the file entry
|
||||||
.loadfat:
|
.loadentry:
|
||||||
;Store the address of the first cluster
|
;Load CX from the stack
|
||||||
mov ax, [di + 0xf]
|
pop cx
|
||||||
mov [.cluster], ax
|
;Store the first cluster
|
||||||
|
mov ax, word [es:di+0xf]
|
||||||
|
mov word [.cluster], ax
|
||||||
;Set the source
|
;Set the source
|
||||||
mov ax, [reservedsectors]
|
mov ax, 0x1
|
||||||
call .calcsource
|
call .calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov bx, buffer
|
mov di, buffer
|
||||||
|
mov bx, di
|
||||||
;Set the size
|
;Set the size
|
||||||
mov ax, [sectorsperfat]
|
mov ax, [.sectorsperfat]
|
||||||
;Load the FAT
|
;Load
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
|
|
||||||
|
;Load the file
|
||||||
|
|
||||||
;Load a cluster
|
;Load a cluster
|
||||||
.loadcluster:
|
.loadcluster:
|
||||||
;Set the source
|
;Set the source
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
mov ax, word [.cluster]
|
mov ax, word [.cluster]
|
||||||
sub ax, 0x2
|
sub ax, 0x2
|
||||||
mul byte [clustersize]
|
mul byte [.clustersize]
|
||||||
add ax, [datastart]
|
add ax, bx
|
||||||
|
add ax, cx
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
call .calcsource
|
||||||
;Set the destination
|
;Set the destination
|
||||||
mov bx, word [.pointer]
|
mov bx, word [.pointer]
|
||||||
;Set the size
|
;Set the size
|
||||||
mov ch, 0x0
|
;mov al, 0x1
|
||||||
mov cl, byte [clustersize]
|
mov al, [.clustersize]
|
||||||
;Store the loop counter in the stack
|
;Load
|
||||||
.loadsector:
|
|
||||||
push cx
|
|
||||||
;Set the source
|
|
||||||
call .calcsource
|
|
||||||
;Set the size
|
|
||||||
push ax
|
|
||||||
mov al, 0x1
|
|
||||||
;Load a sector
|
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x13
|
int 0x13
|
||||||
pop ax
|
|
||||||
;Set the next sector
|
|
||||||
add ax, 0x1
|
|
||||||
add bx, word [sectorsize]
|
|
||||||
;Load the loop counter from the stack
|
|
||||||
pop cx
|
|
||||||
;Load the next sector
|
|
||||||
loop .loadsector
|
|
||||||
|
|
||||||
;Calculate the next cluster
|
;Calculate the next cluster
|
||||||
;Check if the cluster is even or odd
|
|
||||||
mov ax, [.cluster]
|
mov ax, [.cluster]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
mov bx, 0x3
|
mov bx, 0x3
|
||||||
|
@ -319,64 +172,71 @@ mov bx, 0x2
|
||||||
div bx
|
div bx
|
||||||
mov si, buffer
|
mov si, buffer
|
||||||
add si, ax
|
add si, ax
|
||||||
mov ax, word [si]
|
mov ax, word [ds:si]
|
||||||
or dx, dx
|
or dx, dx
|
||||||
jz .even
|
jz .even
|
||||||
;If the cluster is odd shift out the first four bits
|
shr ax, 1
|
||||||
times 0x4 shr ax, 0x1
|
shr ax, 1
|
||||||
|
shr ax, 1
|
||||||
|
shr ax, 1
|
||||||
jmp .contcalc
|
jmp .contcalc
|
||||||
;If the cluster is even mask out the final four bits
|
|
||||||
.even:
|
.even:
|
||||||
and ax, 0xfff
|
and ax, 0xfff
|
||||||
.contcalc:
|
.contcalc:
|
||||||
;Check for the file end
|
|
||||||
cmp ax, 0xff8
|
|
||||||
jge .success
|
|
||||||
;Store the address of the next cluster
|
|
||||||
mov word [.cluster], ax
|
mov word [.cluster], ax
|
||||||
;Set the destination of the next cluster
|
cmp ax, 0xff8
|
||||||
mov ax, [sectorsize]
|
jge .clearcarry
|
||||||
mul word [clustersize]
|
mov ax, [.sectorsize]
|
||||||
|
mul word [.clustersize]
|
||||||
add word [.pointer], ax
|
add word [.pointer], ax
|
||||||
;Load the next cluster
|
|
||||||
jmp .loadcluster
|
jmp .loadcluster
|
||||||
|
|
||||||
;Set AL to 0x0 and load the file size to CX if the load was succesful
|
;Clear the carry flag if the load was succesful
|
||||||
.success:
|
.clearcarry:
|
||||||
mov al, 0x0
|
clc
|
||||||
mov cx, [.size]
|
|
||||||
|
|
||||||
;Clear the stack
|
;Clear the stack
|
||||||
|
.clearstack:
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
|
|
||||||
;Load DI, SI, DX, and BX from the stack
|
;Load the initial registers from the stack
|
||||||
pop di
|
pop di
|
||||||
pop si
|
pop si
|
||||||
pop dx
|
pop dx
|
||||||
|
pop cx
|
||||||
pop bx
|
pop bx
|
||||||
|
pop ax
|
||||||
|
|
||||||
;Set AH to its initial value
|
;Set AL to 0x1 if there was an error and to 0x0 otherwise and return
|
||||||
mov ah, 0x0
|
jc .setal
|
||||||
|
mov al, 0x0
|
||||||
;Return
|
iret
|
||||||
|
.setal:
|
||||||
|
mov al, 0x1
|
||||||
iret
|
iret
|
||||||
|
|
||||||
;Data
|
;Data
|
||||||
.file times 0xb db 0x20
|
.file times 0xb db 0x20
|
||||||
.size dw 0x0
|
.errormsg db "File not found", 0x0
|
||||||
.cluster dw 0x0
|
.cluster dw 0x0
|
||||||
.pointer dw 0x0
|
.pointer dw 0x0
|
||||||
.driverrormsg db "Drive not found", 0x0
|
|
||||||
.diskerrormsg db "Unable to read disk", 0x0
|
|
||||||
.filerrormsg db "File or command not found", 0x0
|
|
||||||
.sizerrormsg db "Not enough memory", 0x0
|
|
||||||
|
|
||||||
;***
|
;These are temporary until i write something to load them from the disk itself
|
||||||
|
.bootdrive db 0x0
|
||||||
|
.sectorsize dw 0x200 ;bytes
|
||||||
|
.clustersize db 0x2 ;sectors
|
||||||
|
.bootsectors dw 0x1
|
||||||
|
.fats db 0x2
|
||||||
|
.rootentries dw 0x70
|
||||||
|
.sectorsperfat dw 0x2
|
||||||
|
.sectorspertrack dw 0x9
|
||||||
|
.sides dw 0x2
|
||||||
|
|
||||||
;Check the file name and convert to upper case
|
;Check the file name and convert to upper case
|
||||||
.checkconv:
|
.checkconv:
|
||||||
|
|
||||||
;Check for the string end, length limit, and invalid characters
|
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
je .load
|
je .load
|
||||||
|
@ -408,8 +268,6 @@ jmp .error
|
||||||
.contcheck3:
|
.contcheck3:
|
||||||
cmp al, 0x7c
|
cmp al, 0x7c
|
||||||
je .error
|
je .error
|
||||||
|
|
||||||
;Check for lower case and convert it to upper case
|
|
||||||
;Check for lower case
|
;Check for lower case
|
||||||
cmp al, 0x61
|
cmp al, 0x61
|
||||||
jl .storech
|
jl .storech
|
||||||
|
@ -417,50 +275,30 @@ cmp al, 0x7a
|
||||||
jg .storech
|
jg .storech
|
||||||
;Convert lower to upper case
|
;Convert lower to upper case
|
||||||
sub al, 0x20
|
sub al, 0x20
|
||||||
|
|
||||||
;Store the character
|
|
||||||
.storech:
|
.storech:
|
||||||
|
;Store the character
|
||||||
stosb
|
stosb
|
||||||
|
;Increase the counter
|
||||||
;Decrease the counter
|
|
||||||
dec bl
|
dec bl
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Calculate the source arguments for loading data from the disk
|
;Calculate the source arguments for loading data from the disk
|
||||||
.calcsource:
|
.calcsource:
|
||||||
|
|
||||||
;Store AX and BX in the stack
|
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
|
|
||||||
;Calculate the cylinder, head, and sector
|
|
||||||
;Store the logical sector in BX
|
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
;Calculate the sector
|
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [.sectorspertrack]
|
||||||
add dl, 0x1
|
add dl, 0x1
|
||||||
mov cl, dl
|
mov cl, dl
|
||||||
;Load the logical sector from BX
|
|
||||||
mov ax, bx
|
mov ax, bx
|
||||||
;Calculate the head and cylinder
|
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [sectorspertrack]
|
div word [.sectorspertrack]
|
||||||
mov dx, 0x0
|
mov dx, 0x0
|
||||||
div word [heads]
|
div word [.sides]
|
||||||
mov dh, dl ;Head
|
mov dh, dl
|
||||||
mov ch, al ;Cylinder
|
mov ch, al
|
||||||
|
|
||||||
;Load the drive number
|
|
||||||
mov dl, byte [drive]
|
|
||||||
|
|
||||||
;Load BX and AX from the stack
|
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
|
mov dl, byte [.bootdrive]
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
101
src/PRINT.ASM
101
src/PRINT.ASM
|
@ -1,101 +0,0 @@
|
||||||
cpu 8086
|
|
||||||
org 0x3000
|
|
||||||
|
|
||||||
;Load a file and print it
|
|
||||||
|
|
||||||
;Set the stack
|
|
||||||
cli
|
|
||||||
mov sp, stack + 0x100
|
|
||||||
sti
|
|
||||||
|
|
||||||
;Check for an empty tail
|
|
||||||
;Check
|
|
||||||
cmp byte [si], 0x0
|
|
||||||
jne extract
|
|
||||||
;Print an error message and abort if the tail is empty
|
|
||||||
mov si, errormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
je done
|
|
||||||
|
|
||||||
;Find the end of the filename and add a null if needed
|
|
||||||
;Set DI at the tail
|
|
||||||
extract:
|
|
||||||
mov di, si
|
|
||||||
findend:
|
|
||||||
;Check for the string end
|
|
||||||
cmp byte [di], 0x0
|
|
||||||
je load
|
|
||||||
;Check for a space
|
|
||||||
cmp byte [di], 0x20
|
|
||||||
je addnull
|
|
||||||
inc di
|
|
||||||
jmp findend
|
|
||||||
;Add a null
|
|
||||||
addnull:
|
|
||||||
mov al, 0x0
|
|
||||||
stosb
|
|
||||||
|
|
||||||
;Load the file
|
|
||||||
;Load
|
|
||||||
load:
|
|
||||||
mov bx, stack + 0x100
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x22
|
|
||||||
;Check for errors
|
|
||||||
cmp al, 0x0
|
|
||||||
jne done
|
|
||||||
|
|
||||||
;Print the file
|
|
||||||
;Setup
|
|
||||||
mov bh, 0x0
|
|
||||||
mov bl, 0x18
|
|
||||||
mov dl, 0x50
|
|
||||||
mov si, stack + 0x100
|
|
||||||
;Decrease the character counter
|
|
||||||
print:
|
|
||||||
dec dl
|
|
||||||
;Load the current character
|
|
||||||
lodsb
|
|
||||||
;Print the character
|
|
||||||
mov ah, 0xe
|
|
||||||
int 0x10
|
|
||||||
;Check for a hard line end
|
|
||||||
cmp al, 0xa
|
|
||||||
je linecount
|
|
||||||
;Check for a soft line end
|
|
||||||
cmp dl, 0x0
|
|
||||||
je linecount
|
|
||||||
;Check paging
|
|
||||||
contprint:
|
|
||||||
cmp bl, 0x0
|
|
||||||
jz page
|
|
||||||
;Repeat for the next character
|
|
||||||
loop print
|
|
||||||
jmp done
|
|
||||||
;Decrease the line counter and reset the character one
|
|
||||||
linecount:
|
|
||||||
dec bl
|
|
||||||
mov dl, 0x50
|
|
||||||
jmp contprint
|
|
||||||
;Page
|
|
||||||
page:
|
|
||||||
push ax
|
|
||||||
mov ah, 0x0
|
|
||||||
int 0x16
|
|
||||||
cmp al, 0x1b
|
|
||||||
je done
|
|
||||||
pop ax
|
|
||||||
mov bl, 0x18
|
|
||||||
mov dl, 0x50
|
|
||||||
loop print
|
|
||||||
|
|
||||||
;Return to the system
|
|
||||||
done:
|
|
||||||
int 0x20
|
|
||||||
|
|
||||||
;Data
|
|
||||||
errormsg db "File not found", 0x0
|
|
||||||
|
|
||||||
;Stack
|
|
||||||
stack:
|
|
|
@ -1,4 +1,5 @@
|
||||||
;Print a string ending in a null from SI followed by a CRLF.
|
;Print a string ending in a null from SI followed by a CRLF.
|
||||||
|
|
||||||
println:
|
println:
|
||||||
|
|
||||||
;Print the string
|
;Print the string
|
||||||
|
@ -8,5 +9,4 @@ int 0x21
|
||||||
;Print a CRLF
|
;Print a CRLF
|
||||||
call printcrlf
|
call printcrlf
|
||||||
|
|
||||||
;Return
|
|
||||||
iret
|
iret
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
;Print a string ending in a null from SI.
|
;Print a string ending in a null from SI.
|
||||||
|
|
||||||
printstr:
|
printstr:
|
||||||
|
|
||||||
;Store AX and SI in the stack
|
;Store the initial registers in the stack
|
||||||
push ax
|
push ax
|
||||||
push si
|
push si
|
||||||
|
|
||||||
;Print the string
|
;Print the string
|
||||||
;Load the current character
|
|
||||||
.loop:
|
.loop:
|
||||||
|
;Load the current character
|
||||||
lodsb
|
lodsb
|
||||||
;Check for the string end
|
;Check for the string end
|
||||||
cmp al, 0x0
|
cmp al, 0x0
|
||||||
|
@ -15,13 +16,13 @@ je .done
|
||||||
;Print the character
|
;Print the character
|
||||||
mov ah, 0xe
|
mov ah, 0xe
|
||||||
int 0x10
|
int 0x10
|
||||||
;Print the next character
|
;Repeat for the next character
|
||||||
jmp .loop
|
jmp .loop
|
||||||
|
|
||||||
;Load the initial registers from the stack
|
|
||||||
.done:
|
.done:
|
||||||
|
|
||||||
|
;Load the initial registers from the stack
|
||||||
pop si
|
pop si
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
;Return
|
|
||||||
iret
|
iret
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;Read a string ending in a null of at most AL characters to DI until a
|
;Read a string ending in null of at most AL characters to DI until a return and print a CRLF.
|
||||||
;return and print a CRLF.
|
|
||||||
readln:
|
readln:
|
||||||
|
|
||||||
;Read the string
|
;Read the string
|
||||||
|
@ -9,5 +9,4 @@ int 0x21
|
||||||
;Print a CRLF
|
;Print a CRLF
|
||||||
call printcrlf
|
call printcrlf
|
||||||
|
|
||||||
;Return
|
|
||||||
iret
|
iret
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
;Read a string ending in a null of at most AL characters to DI until a
|
;Read a string ending in a null of at most AL characters to DI until a return.
|
||||||
;return.
|
|
||||||
readstr:
|
readstr:
|
||||||
|
|
||||||
;Store AX, BX, CX, DX, and DI in the stack
|
;Store the initial registers in the stack
|
||||||
push ax
|
push ax
|
||||||
push bx
|
push bx
|
||||||
push cx
|
push cx
|
||||||
|
@ -20,16 +20,12 @@ rep stosb
|
||||||
pop ax
|
pop ax
|
||||||
push ax
|
push ax
|
||||||
sub di, ax
|
sub di, ax
|
||||||
;Store the last column number
|
;Initialise the cursor pointer in BL and clear BH
|
||||||
mov ah, 0xf
|
|
||||||
int 0x10
|
|
||||||
dec ah
|
|
||||||
mov [.lastcolumn], ah
|
|
||||||
;Set the cursor pointer in BL and clear BH
|
|
||||||
mov bx, 0x1
|
mov bx, 0x1
|
||||||
|
|
||||||
;Read a keypress
|
|
||||||
.loop:
|
.loop:
|
||||||
|
|
||||||
|
;Read a keypress
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x16
|
int 0x16
|
||||||
|
|
||||||
|
@ -59,9 +55,9 @@ je .loop
|
||||||
|
|
||||||
;Store and print a character
|
;Store and print a character
|
||||||
.character:
|
.character:
|
||||||
;Store
|
;Store the character
|
||||||
stosb
|
stosb
|
||||||
;Print
|
;Print the character
|
||||||
mov ah, 0xe
|
mov ah, 0xe
|
||||||
int 0x10
|
int 0x10
|
||||||
;Move the cursor pointer
|
;Move the cursor pointer
|
||||||
|
@ -91,21 +87,23 @@ dec di
|
||||||
dec bl
|
dec bl
|
||||||
jmp .loop
|
jmp .loop
|
||||||
|
|
||||||
;Check for and remove trailing spaces
|
;Finish reading the string
|
||||||
;Go to the end of the input
|
|
||||||
.return:
|
.return:
|
||||||
|
|
||||||
|
;Find and remove trailing spaces
|
||||||
|
;Go to the end of the input
|
||||||
pop ax
|
pop ax
|
||||||
mov bh, 0x0
|
mov bh, 0x0
|
||||||
sub ax, bx
|
sub ax, bx
|
||||||
push di
|
push di
|
||||||
add di, ax
|
add di, ax
|
||||||
;Check for trailing spaces
|
|
||||||
.findtrailing:
|
.findtrailing:
|
||||||
|
;Check for a trailing space
|
||||||
cmp byte [di], 0x20
|
cmp byte [di], 0x20
|
||||||
je .deltrailing
|
je .deltrailing
|
||||||
jmp .end
|
jmp .end
|
||||||
;Remove trailing spaces
|
|
||||||
.deltrailing:
|
.deltrailing:
|
||||||
|
;Delete a trailing space
|
||||||
mov al, 0x0
|
mov al, 0x0
|
||||||
stosb
|
stosb
|
||||||
sub di, 0x2
|
sub di, 0x2
|
||||||
|
@ -124,102 +122,83 @@ inc di
|
||||||
inc bl
|
inc bl
|
||||||
jmp .findend
|
jmp .findend
|
||||||
|
|
||||||
;Load DI, DX, CX, BX, and AX from the stack
|
|
||||||
.done:
|
.done:
|
||||||
|
|
||||||
|
;Load the initial registers from the stack
|
||||||
pop di
|
pop di
|
||||||
pop dx
|
pop dx
|
||||||
pop cx
|
pop cx
|
||||||
pop bx
|
pop bx
|
||||||
pop ax
|
pop ax
|
||||||
|
|
||||||
;Return
|
|
||||||
iret
|
iret
|
||||||
|
|
||||||
;Data
|
|
||||||
.lastcolumn db 0x0
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Move the cursor forward
|
;Move the cursor forward
|
||||||
.nextchar:
|
|
||||||
|
|
||||||
|
;Move forward within a line
|
||||||
|
.nextchar:
|
||||||
;Get the cursor position
|
;Get the cursor position
|
||||||
mov ah, 0x3
|
mov ah, 0x3
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Check for the end of the line
|
;Check for the end of the line
|
||||||
cmp dl, [.lastcolumn]
|
cmp dl, 0x4f
|
||||||
je .nextln
|
je .nextln
|
||||||
|
;Move
|
||||||
;Move the cursor forward within a line
|
|
||||||
inc dl
|
inc dl
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Move the cursor to the beginning of the next line
|
;Move to the beginning of the next line
|
||||||
;Check if the current line is the last on screen
|
|
||||||
.nextln:
|
.nextln:
|
||||||
|
;Check if the current line is the last on screen
|
||||||
cmp dh, 0x18
|
cmp dh, 0x18
|
||||||
je .scroll
|
je .scroll
|
||||||
;Move the cursor
|
;Move
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
inc dh
|
inc dh
|
||||||
mov dl, 0x0
|
mov dl, 0x0
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Scroll the screen up by one line
|
;Scroll the screen up by one line
|
||||||
.scroll:
|
.scroll:
|
||||||
|
;Scroll
|
||||||
mov ah, 0x6
|
mov ah, 0x6
|
||||||
mov al, 0x1
|
mov al, 0x1
|
||||||
mov bh, 0x7
|
mov bh, 0x7
|
||||||
mov ch, 0x0
|
mov ch, 0x0
|
||||||
mov cl, 0x0
|
mov cl, 0x0
|
||||||
mov dh, 0x18
|
mov dh, 0x18
|
||||||
mov dl, [.lastcolumn]
|
mov dl, 0x4f
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Move to the beginning of the new line
|
;Move to the beginning of the new line
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
mov bh, 0x0
|
mov bh, 0x0
|
||||||
mov dl, 0x0
|
mov dl, 0x0
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Move the cursor backward
|
;Move the cursor backward
|
||||||
.prevchar:
|
|
||||||
|
|
||||||
|
;Move backward within a line
|
||||||
|
.prevchar:
|
||||||
;Get the cursor position
|
;Get the cursor position
|
||||||
mov ah, 0x3
|
mov ah, 0x3
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Check for the beginning of the line
|
;Check for the beginning of the line
|
||||||
cmp dl, 0x0
|
cmp dl, 0x0
|
||||||
je .prevln
|
je .prevln
|
||||||
|
;Move
|
||||||
;Move the cursor backward within a line
|
|
||||||
dec dl
|
dec dl
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Move the cursor to the end of the previous line
|
;Move to the end of the previous line
|
||||||
.prevln:
|
.prevln:
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
dec dh
|
dec dh
|
||||||
mov dl, [.lastcolumn]
|
mov dl, 0x4f
|
||||||
int 0x10
|
int 0x10
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
231
src/SYSTEM.ASM
231
src/SYSTEM.ASM
|
@ -1,7 +1,6 @@
|
||||||
cpu 8086
|
CPU 8086
|
||||||
org 0x500
|
ORG 0x500
|
||||||
|
|
||||||
;Jump to the code
|
|
||||||
jmp start
|
jmp start
|
||||||
|
|
||||||
;Interrupt handler
|
;Interrupt handler
|
||||||
|
@ -21,21 +20,22 @@ je readln
|
||||||
iret
|
iret
|
||||||
;Disk operations
|
;Disk operations
|
||||||
int0x22:
|
int0x22:
|
||||||
cmp ah, 0x2
|
cmp ah, 0x0
|
||||||
je loadf
|
je loadf
|
||||||
;To do: savef
|
;To do: savef
|
||||||
iret
|
iret
|
||||||
|
|
||||||
;System call includes
|
;System calls
|
||||||
%include "PRINTSTR.INC"
|
%include "PRINTSTR.INC"
|
||||||
%include "READSTR.INC"
|
%include "READSTR.INC"
|
||||||
%include "PRINTLN.INC"
|
%include "PRINTLN.INC"
|
||||||
%include "READLN.INC"
|
%include "READLN.INC"
|
||||||
%include "LOADF.INC"
|
%include "LOADF.INC"
|
||||||
|
|
||||||
|
start:
|
||||||
|
|
||||||
;Set up the interrupt vectors
|
;Set up the interrupt vectors
|
||||||
;Interrupt 0x20 offset
|
;Interrupt 0x20 offset
|
||||||
start:
|
|
||||||
mov ax, int0x20
|
mov ax, int0x20
|
||||||
mov [0x80], ax
|
mov [0x80], ax
|
||||||
;Interrupt 0x21 offset
|
;Interrupt 0x21 offset
|
||||||
|
@ -50,11 +50,6 @@ mov [0x82], ax
|
||||||
mov [0x86], ax
|
mov [0x86], ax
|
||||||
mov [0x8a], ax
|
mov [0x8a], ax
|
||||||
|
|
||||||
;Store the boot drive number as the current drive and set the current
|
|
||||||
;drive letter
|
|
||||||
mov [curdrive], dl
|
|
||||||
call setcurdriveletter
|
|
||||||
|
|
||||||
;Print a welcome message
|
;Print a welcome message
|
||||||
mov si, welcomemsg
|
mov si, welcomemsg
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
|
@ -68,226 +63,62 @@ mov sp, 0x0
|
||||||
sti
|
sti
|
||||||
|
|
||||||
;Prompt for and read a command
|
;Prompt for and read a command
|
||||||
;Print the current drive letter
|
|
||||||
mov si, curdriveletter
|
|
||||||
mov ah, 0x0
|
|
||||||
int 0x21
|
|
||||||
;Print a prompt
|
;Print a prompt
|
||||||
mov si, prompt
|
mov si, prompt
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x21
|
int 0x21
|
||||||
;Read
|
;Read
|
||||||
mov di, input
|
mov di, input
|
||||||
mov al, 0x4c
|
mov al, 0x4e
|
||||||
mov ah, 0x3
|
mov ah, 0x3
|
||||||
int 0x21
|
int 0x21
|
||||||
|
|
||||||
|
;Load an execute the program
|
||||||
;Check for an empty command
|
;Check for an empty command
|
||||||
cmp byte [input], 0x0
|
cmp byte [input], 0x0
|
||||||
jz shell
|
jz shell
|
||||||
|
;Load
|
||||||
;Set SI at the command
|
mov bx, 0x2000
|
||||||
;Set SI at input
|
|
||||||
mov si, input
|
mov si, input
|
||||||
;Ignore leading spaces
|
mov ah, 0x0
|
||||||
call ignoreleading
|
|
||||||
|
|
||||||
;Check for a current drive change command
|
|
||||||
cmp byte [si + 0x1], ":"
|
|
||||||
jne extract
|
|
||||||
cmp byte [si + 0x2], 0x0
|
|
||||||
je changecurdrive
|
|
||||||
cmp byte [si + 0x2], 0x20
|
|
||||||
je changecurdrive
|
|
||||||
|
|
||||||
;Extract the specification of the program file
|
|
||||||
extract:
|
|
||||||
;Set DI at program
|
|
||||||
mov di, program
|
|
||||||
;Initialise program with spaces
|
|
||||||
mov cx, 0xe
|
|
||||||
mov al, 0x20
|
|
||||||
rep stosb
|
|
||||||
sub di, 0xe
|
|
||||||
;Set the length counter
|
|
||||||
mov bl, 0xa
|
|
||||||
;Load a character
|
|
||||||
specloop:
|
|
||||||
lodsb
|
|
||||||
;Check for the string end
|
|
||||||
cmp al, 0x0
|
|
||||||
je addext
|
|
||||||
;Check for a space
|
|
||||||
cmp al, 0x20
|
|
||||||
je addext
|
|
||||||
;Check for the length limit
|
|
||||||
cmp bl, 0x0
|
|
||||||
je cmderror
|
|
||||||
;Store the character
|
|
||||||
stosb
|
|
||||||
;Decrease the counter
|
|
||||||
dec bl
|
|
||||||
;Extract the next character
|
|
||||||
jmp specloop
|
|
||||||
;Store the start of the command tail in the stack
|
|
||||||
addext:
|
|
||||||
push si
|
|
||||||
;Add extension to the specification
|
|
||||||
mov si, extension
|
|
||||||
mov cx, 0x5
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
;Load and execute the program
|
|
||||||
;Load the program
|
|
||||||
mov bx, 0x3000
|
|
||||||
mov si, program
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x22
|
int 0x22
|
||||||
;Check for errors
|
;Check for errors
|
||||||
cmp al, 0x0
|
cmp al, 0x1
|
||||||
jne shell
|
je error
|
||||||
;Pass the current drive and command tail to the program
|
;Execute
|
||||||
mov dl, [curdrive]
|
jmp 0x2000
|
||||||
pop si
|
|
||||||
call ignoreleading
|
|
||||||
;Execute the program
|
|
||||||
jmp 0x3000
|
|
||||||
|
|
||||||
;Print a command error message and return to the shell
|
;Print an error message and return to the shell
|
||||||
cmderror:
|
error:
|
||||||
mov si, cmderrormsg
|
mov bh, 0x0
|
||||||
|
mov ah, 0x3
|
||||||
|
int 0x10
|
||||||
|
dec dh
|
||||||
|
mov ah, 0x2
|
||||||
|
int 0x10
|
||||||
|
mov si, errormsg
|
||||||
mov ah, 0x2
|
mov ah, 0x2
|
||||||
int 0x21
|
int 0x21
|
||||||
jmp shell
|
jmp shell
|
||||||
|
|
||||||
;Change the current drive
|
;Data
|
||||||
;Get the BIOS equipment list
|
|
||||||
changecurdrive:
|
|
||||||
int 0x11
|
|
||||||
;Get the number of floppy drives
|
|
||||||
times 0x6 shr ax, 0x1
|
|
||||||
and ax, 0x3
|
|
||||||
inc ax
|
|
||||||
;Set the loop and drive letter counters and the drive letter and number
|
|
||||||
mov cx, ax
|
|
||||||
mov di, driveletters
|
|
||||||
mov al, [si]
|
|
||||||
mov dl, 0x0
|
|
||||||
;Check which drive to change to
|
|
||||||
checkdrive:
|
|
||||||
cmp al, [di]
|
|
||||||
je contchdrive
|
|
||||||
inc di
|
|
||||||
cmp al, [di]
|
|
||||||
je contchdrive
|
|
||||||
inc di
|
|
||||||
inc dl
|
|
||||||
loop checkdrive
|
|
||||||
;Print a drive error message and return to the shell
|
|
||||||
mov si, driverrormsg
|
|
||||||
mov ah, 0x2
|
|
||||||
int 0x21
|
|
||||||
jmp shell
|
|
||||||
;Change the drive
|
|
||||||
contchdrive:
|
|
||||||
mov [curdrive], dl
|
|
||||||
call setcurdriveletter
|
|
||||||
jmp shell
|
|
||||||
|
|
||||||
;Welcome message
|
|
||||||
welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
|
welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0
|
||||||
|
|
||||||
;Drive stuff
|
|
||||||
curdrive db 0x0
|
|
||||||
driveletters db "AaBbCcDd"
|
|
||||||
|
|
||||||
;Shell
|
|
||||||
curdriveletter db "?:", 0x0
|
|
||||||
prompt db "> ", 0x0
|
prompt db "> ", 0x0
|
||||||
input times 0x4c db 0x0
|
errormsg db "Unknown command", 0x0
|
||||||
program times 0xf db 0x0
|
input times 0x4e db 0x0
|
||||||
extension db ".BIN", 0x0
|
crlf db 0xd, 0xa, 0x0
|
||||||
cmderrormsg db "File or command not found", 0x0
|
|
||||||
driverrormsg db "Drive not found", 0x0
|
|
||||||
|
|
||||||
;Disk parameters
|
|
||||||
drive db 0x0
|
|
||||||
sectorsize dw 0x0 ;bytes
|
|
||||||
clustersize db 0x0 ;sectors
|
|
||||||
reservedsectors dw 0x0
|
|
||||||
fats db 0x0
|
|
||||||
rootentries dw 0x0
|
|
||||||
sectorsperfat dw 0x0
|
|
||||||
sectorspertrack dw 0x0
|
|
||||||
heads dw 0x0
|
|
||||||
rootstart dw 0x0
|
|
||||||
rootsectors dw 0x0
|
|
||||||
datastart dw 0x0
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Set the drive letter
|
|
||||||
setcurdriveletter:
|
|
||||||
|
|
||||||
;Set the drive number and letter counters
|
|
||||||
mov dh, 0x0
|
|
||||||
mov si, driveletters
|
|
||||||
|
|
||||||
;Check the drive number
|
|
||||||
.checkdrive:
|
|
||||||
cmp dl, dh
|
|
||||||
je .set
|
|
||||||
add si, 0x2
|
|
||||||
inc dh
|
|
||||||
jmp .checkdrive
|
|
||||||
|
|
||||||
;Set the drive letter
|
|
||||||
.set:
|
|
||||||
mov al, [si]
|
|
||||||
mov byte [curdriveletter], al
|
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Ignore leading spaces in the command and its tail
|
|
||||||
ignoreleading:
|
|
||||||
|
|
||||||
;Check for a space
|
|
||||||
lodsb
|
|
||||||
cmp al, 0x20
|
|
||||||
je ignoreleading
|
|
||||||
|
|
||||||
;Set SI to the first non-space character
|
|
||||||
dec si
|
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;Print a CRLF
|
;Print a CRLF
|
||||||
printcrlf:
|
printcrlf:
|
||||||
|
;Store the initial registers in the stack
|
||||||
;Store SI in the stack
|
|
||||||
push si
|
push si
|
||||||
|
|
||||||
;Print the CRLF
|
;Print the CRLF
|
||||||
mov si, .crlf
|
mov si, crlf
|
||||||
mov ah, 0x0
|
mov ah, 0x0
|
||||||
int 0x21
|
int 0x21
|
||||||
|
;Load the initial registers from the stack
|
||||||
;Load SI from the stack
|
|
||||||
pop si
|
pop si
|
||||||
|
|
||||||
;Return
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;Data
|
|
||||||
.crlf db 0xd, 0xa, 0x0
|
|
||||||
|
|
||||||
;***
|
|
||||||
|
|
||||||
;File system buffer
|
;File system buffer
|
||||||
buffer:
|
buffer:
|
||||||
|
|
Loading…
Reference in a new issue