Merge branch 'master' into gh-pages

This commit is contained in:
Jeff Parsons 2017-09-21 17:28:47 -07:00
commit 65da4c1d45
47 changed files with 12504 additions and 74 deletions

View file

@ -11,7 +11,7 @@ are simple XML files that describe a piece of software (an application, an opera
link to a PCjs machine configuration capable of running the software, along with a "ready-to-run" machine state file.
Conversely, a PCjs machine XML file can refer back to the manifest, to obtain a list of disk images.
Here are some [Demos](/apps/pc/) of "ready-to-run" apps on [PCjs](/docs/about/).
Here are some [Demos](/apps/pcx86/) of "ready-to-run" apps on [PCjs](/docs/about/).
There have been lots of server-side changes recently, including API improvements that make it easy (well, *easier*)
to dynamically create diskette images from a list of files, or even an entire folder (including all subfolders),

View file

@ -135,7 +135,7 @@ modes commonly used on the IBM VGA. Here's that table:
ATC[0x12]: PLANES 0x0F 0x0F 0x0F 0x0F 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F
ATC[0x13]: HPAN 0x08 0x08 0x08 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
In addition, I've created a [VGA Tests](/tests/pc/vga/) directory to hold VGA test and sample code that PCjs can
In addition, I've created a [VGA Tests](/tests/pcx86/vga/) directory to hold VGA test and sample code that PCjs can
now successfully run (for the most part). See that directory for more details.
*[@jeffpar](http://twitter.com/jeffpar)*

View file

@ -13,7 +13,7 @@ It turned out that that archive was a rabbit hole I could not *not* go down.
First, I collected all the other PC Tech Journal ZIP archives there (from December 1985 through January 1989),
recreated them as a set of [PC Tech Journal Disks](/disks/pcx86/shareware/pctj/), and added them to the
[PCjs Disk Library](/disks/pcx86/), so now you can "Load" and "Save" them in any [PCjs Machine](devices/pcx86/machine/).
[PCjs Disk Library](/disks/pcx86/), so now you can "Load" and "Save" them in any [PCjs Machine](/devices/pcx86/machine/).
Next, since I was also a fan of PC Magazine back in the day, I decided to do the same for all the PC Magazine ZIP
archives. So now there's a set of [PC Magazine Disks](/disks/pcx86/shareware/pcmag/) you can play with as well.

View file

@ -86,7 +86,7 @@ starts reading from the top of video memory after it reaches the bottom. So all
new lines at the top of the video memory again. If IBM had thought of that trick 5 years earlier, back in 1981,
think of all the years of shared flicker-grief that could have been avoided!
Today, in honor of all that flickering, I'm pleased to announce that [PCx86](devices/pcx86/machine/), one of the
Today, in honor of all that flickering, I'm pleased to announce that [PCx86](/devices/pcx86/machine/), one of the
PCjs emulators I'm always trying to improve, now offers **FLICKERING** on all IBM PC Color Graphics configurations.
If you feel the need to override it, you can add *flicker=0* to the URL of your favorite machine; e.g.:

View file

@ -0,0 +1,332 @@
---
layout: post
title: Puzzled Programmers
date: 2017-09-21 10:00:00
permalink: /blog/2017/09/21/
machines:
- id: ibm5160-msdos320
type: pcx86
resume: 1
config: /devices/pcx86/machine/5160/ega/640kb/machine.xml
drives: '[{name:"10Mb Hard Disk",type:3,path:"/disks/pcx86/fixed/10mb/MSDOS320-C400.json"}]'
autoMount:
A:
name: None
B:
name: None
---
One of books I used to have a copy of (and perhaps still do, in the bowels of my storage unit) was "Puzzled Programmers"
by Michael Wiesenberg. It was published by Microsoft Press in 1987, and I recently rediscovered an online copy in the
[Internet Archive's](https://archive.org) [Open Library](https://openlibrary.org):
> [Puzzled Programmers: 15 mind-boggling story puzzles to test your programming prowess, solutions in BASIC, Pascal, and C](https://openlibrary.org/books/OL2379315M/Puzzled_programmers)
Someone else was currently "borrowing" it, so I added myself to the wait-list, and a few days ago, the Internet Archive
notified me that it was available for reading. I started skimming it, and noticed that for each of the puzzles, it
included complete solutions in all the aforementioned languages: BASIC, Pascal, and C. I also noticed this portion of
the Introduction:
> **Timing the Programs on Your Computer**
> Run times are specified for each puzzle, but you should look at these times only as guidelines or, in the vernacular,
as ballpark figures. The figures given are for a Hewlett-Packard Vectra (IBM PC AT compatible) running at a clock speed
of 8 MHz. Obviously, the times will differ with other interpreters and on other computers. The following table gives you
some idea of how long a program ought to take on your particular system. This table shows timings on various systems
of the programs presented in the solution to Puzzle 5.
Computer BASIC Turbo Pascal Microsoft C
-------------------------------------------------------------------------------
Tandy 1000 (4.77 MHz) 2 minutes 11 seconds 1.3 seconds 2.4 seconds
IBM PC XT clone (4.77 MHz) 1 minute 58.5 seconds 1.3 seconds 2.3 seconds
IBM PC A T (6 MHz) 50 seconds 0.5 seconds 0.9 seconds
HP Vectra (8 MHz) 35 seconds 0.5 seconds 0.4 seconds
Macintosh Plus 8 seconds < 1 second < 1 second
Apple II C 2 minutes 20 seconds 23.6 seconds* n/a
-------------------------------------------------------------------------------
*Apple Pascal
This almost seemed like an invitation to try my hand at Puzzle #5, and to see how a PCjs "machine" fared.
### A Pleasant Fourthsum
I skipped ahead to page 27, "Puzzle 5: A Pleasant Fourthsum", and started reading. I have to admit that the story
completely failed to interest me. There were lots of irrelevant details about a delicious breakfast that this imaginary
bunch of successful twenty-somethings were enjoying, when suddenly one of them says:
"Before we get into the future of languages at I-Q, I've got a great computer puzzle for everyone."
which he then states in one sentence:
"Find a four-digit number that is the sum of the fourth powers of its digits."
and then the conversation returns to other random topics, like whether anyone should be worried that FORTRAN might
become a weapons guidance language, and whether they need to make lunch reservations -- when they've barely finished
breakfast!
Skipping ahead to the "Solutions" section, it turned out that the challenge was to actually find *all* four-digit
numbers, not just *a* number. Also, only numbers 1000 through 9999 are considered (no numbers with leading zeros).
Just for fun, I created [my own solution](/tests/node/puzzled/puzzle5.js) in JavaScript first:
```javascript
let p = new Array(10);
/**
* test(n)
*
* Returns true IFF the number matches the criteria.
*
* @param {number} n
* @returns {boolean}
*/
function test(n) {
let total = 0;
let value = n;
while (n) {
total += p[n % 10];
n = (n / 10)|0;
}
return total == value;
}
function run() {
let n = 1000;
for (let d = 0; d < 10; d++) {
p[d] = Math.pow(d, 4);
}
while (true) {
if (test(n)) console.log(n);
if (++n > 9999) break;
}
}
run();
```
then I looked at the solutions in "Puzzled Programmers". Here's the BASIC solution:
```basic
5 REM BASIC Solution to Puzzle #5 in "Puzzled Programmers" (c) 1987
10 DIM PWR(9)
20 FOR I = 0 TO 9
30 PWR(I) = I^4
40 NEXT I
50 H000 = 1000
60 FOR H = 1 TO 9
70 I00 = 0
80 FOR I = 0 TO 9
90 J0 = 0
100 FOR J = 0 TO 9
110 PARTSUM = H000 + I00 + J0
120 PART4THS = PWR(H) + PWR(I) + PWR(J)
130 FOR K = 0 TO 9
140 SUM = PARTSUM + K
150 IF PART4THS + PWR(K) <> SUM THEN 190
160 PRINT SUM; "= ";
170 PRINT USING "#^4 + "; H, I, J;
180 PRINT USING "#^4"; K
190 NEXT K
200 J0 = J0 + 10
210 NEXT J
220 I00 = I00 + 100
230 NEXT I
240 H000 = H000 + 1000
250 NEXT H
```
and the C solution (which I modified to loop 100 times, to make timing with a stopwatch easier):
```c
/* C solution to puzzle #5 in "Puzzled Programmers" (c) 1987 */
main()
{
int pwr[10], /* the fourth power of each digit */
h, /* the digit in the thousands position */
h000, /* h * 1000, that is, the value of the number
in the thousands position */
i, /* the digit in the hundreds position */
i00, /* i * 100, that is, the value of the number
in the hundreds position */
j, /* the digit in the tens position */
j0, /* i * 10, that is, the value of the number
in the tens position */
part4ths, /* h^4 + i^4 + j^4 */
partsum, /* h000 + i00 + j0 */
k, /* the digit in the ones position */
sum, l;
for (i = 0; i < 10; i++) pwr[i] = i * i * i * i;
for (l = 100; l-- > 0;) {
for (h000 = 1000, h = 1; h <= 9; h++, h000 += 1000) {
/* thousands digit */
for (i00 = i = 0; i <= 9; i++, i00 += 100) {
/* hundreds digit */
for ( j0 = j = 0; j <= 9; j++, j0 += 10) {
/* tens digit */
partsum = h000 + i00 + j0;
part4ths = pwr[h] + pwr[i] + pwr[j];
for ( k = 0; k <= 9; k++) { /* ones digit */
sum = partsum + k; /* this produces the four-digit
number */
if (part4ths + pwr[k] == sum) {
if (!l) printf("%d = %d^4 + %d^4 + %d^4 + %d^4\n",
sum, h, i, j, k);
}
}
}
}
}
}
}
```
Here's my own C solution, which is slightly smaller and faster than the book's solution:
```c
/* @jeffpar's optimized C solution to puzzle #5 */
main()
{
int p[10];
int d, l, n, s;
for (d = 0; d < 10; d++) p[d] = d * d * d * d;
for (l = 100; l-- > 0;) { /* loop 100 times for timing purposes */
for (n = 100; n < 1000; n++) {
/* I originally used a "do...while (t /= 10)" loop here
to create the power summation (where t was a copy of n),
but since we know n is a 3-digit number, we can inline
all three power references and minimize the number of
divisions; we also bias the sum by -(n*10) so that we
don't have to add (n*10) to d for the final comparison. */
s = p[n/100] + p[(n/10)%10] + p[n%10] - (n*10);
for (d = 0; d < 10; d++) {
if (s + p[d] == d) {
if (!l) printf("%d = %d^4 + %d^4 + %d^4 + %d^4\n",
n * 10 + d, n/100, (n/10)%10, n%10, d);
}
}
}
}
}
```
And finally, here's the book's Pascal solution:
```pascal
program sum4ths(input, output);
var
pwr: { the fourth power of each number, 0 to 9 }
array[0..9] of integer;
h, { the digit in the thousands position }
h000, { h * 1000, that is, the value of the number
in the thousands position }
i, { the digit in the hundreds position }
i00, { i * 100, that is, the value of the number in
the hundreds position }
j, { the digits in the tens position }
j0, { j * 10, that is, the value of the number in
the tens position }
part4ths, { h^4 + i^4 + j^4 }
partsum, { h000 + i00 + j0 }
k, { the digit in the ones position }
sum: integer;
begin
for i := 0 to 9 do pwr[i] := i * i * i * i;
h000 := 1000;
for h := 1 to 9 do begin { thousands digit }
i00 := 0;
for i := 0 to 9 do begin { hundreds digit }
j0 := 0;
for j := 0 to 9 do begin { tens digits }
partsum := h000 + i00 + j0;
part4ths := pwr[h] + pwr[i] + pwr[j];
for k := 0 to 9 do begin { ones digit }
sum := partsum + k; { this produces the four-digit number }
if part4ths + pwr[k] = sum then
writeln(sum, ' = ', h, '^4 + ', i, '^4 + ', j, '^4 + ', k, '^4')
end;
j0 := j0 + 10;
end;
i00 := i00 + 100;
end;
h000 := h000 + 1000;
end
end.
```
You can play with all these solutions in the 4.77Mhz IBM PC XT machine below. Use `CD \PUZZLED\PUZZLE5` to switch
to the directory for Puzzle #5.
To run the BASIC version, use `GWBASIC`, since the machine boots MS-DOS 3.20:
C:\PUZZLED\PUZZLE5>GWBASIC PUZZLE5.BAS
To compile and run the C version, you can use the pre-installed copy of Microsoft C 4.00:
C:\PUZZLED\PUZZLE5>cl puzzle5.c
Microsoft (R) C Compiler Version 4.00
Copyright (C) Microsoft Corp 1984, 1985, 1986. All rights reserved.
puzzle5.c
Microsoft (R) Overlay Linker Version 3.51
Copyright (C) Microsoft Corp 1983, 1984, 1985, 1986. All rights reserved.
Object Modules [.OBJ]: PUZZLE5.OBJ
Run File [PUZZLE5.EXE]: PUZZLE5.EXE/NOI
List File [NUL.MAP]: NUL
Libraries [.LIB]: ;
C:\PUZZLED\PUZZLE5>puzzle5
1634 = 1^4 + 6^4 + 3^4 + 4^4
8208 = 8^4 + 2^4 + 0^4 + 8^4
9474 = 9^4 + 4^4 + 7^4 + 4^4
To compile and run the Pascal version, load diskette "IBM Pascal 1.00 (Combined)" in drive A, and then type the
commands shown below:
C:\PUZZLED\PUZZLE5>a:pas1
IBM Personal Computer Pascal Compiler
Version 1.00 (C)Copyright IBM Corp 1981
Source filename [.PAS]: puzzle5p
Object filename [PUZZLE5P.OBJ]:
Source listing [NUL.LST]:
Object listing [NUL.COD]: puzzle5p
Pass One No Errors Detected.
C:\PUZZLED\PUZZLE5>a:pas2
Code Area Size = #0296 (662)
Cons Area Size = #004C (76)
Data Area Size = #002A (42)
Pass Two No Errors Detected.
C:\PUZZLED\PUZZLE5>a:link
IBM Personal Computer Linker
Version 1.00 (C) Copyright IBM Corp 1981
Object Modules: puzzle5p
Run File: puzzle5p
List File [PUZZLE5P.MAP] :
Libraries [ ] :
Publics [No]:
Line Numbers [No]:
Stack size [Object file stack]:
Load Low [Yes]:
DSAllocation [No]:
C:\PUZZLED\PUZZLE5>puzzle5p
1634 = 1^4 + 6^4 + 3^4 + 4^4
8208 = 8^4 + 2^4 + 0^4 + 8^4
9474 = 9^4 + 4^4 + 7^4 + 4^4
It appears that PCjs is somewhat faster than a real machine. For example, the author's BASIC solution ran
for almost two minutes on a PC XT clone, but it finishes in about one and a half minutes on the 4.77Mhz PC XT
configuration below.
Clearly, I still have some work to do if I want PCjs to faithfully simulate how *slow* these systems used to be.
{% include machine.html id="ibm5160-msdos320" %}
*[@jeffpar](http://twitter.com/jeffpar)*
*Sep 21, 2017*

View file

@ -15,11 +15,11 @@ scripts: # the following list of scripts should mirror what /modules/diskdump/li
---
PCjs DiskDump and FileDump API
===
------------------------------
The PCjs [DiskDump](/modules/diskdump/) and [FileDump](/modules/filedump/) API are not fully supported
by the current PCjs web server. When [pcjs.org](http://www.pcjs.org/) switched from a Node-based web server running on
[Amazon Web Services](https://aws.amazon.com/elasticbeanstalk/) to [GitHub Pages](https://pages.github.com/),
The PCjs [DiskDump](/modules/diskdump/) and [FileDump](/modules/filedump/) API are not fully supported by the
current PCjs web server. When [pcjs.org](http://www.pcjs.org/) switched from a Node-based web server running
on [Amazon Web Services](https://aws.amazon.com/elasticbeanstalk/) to [GitHub Pages](https://pages.github.com/),
the original server-side API had to be abandoned.
However, we're working on a client-side replacement of the API that will run

View file

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<keyboard id="keyboard" model="us84" pos="left" padLeft="8px" padBottom="8px">
<control type="button" binding="esc">ESC</control>
<control type="button" binding="ctrl-c">CTRL-C</control>
<control type="button" binding="ctrl-alt-del">CTRL-ALT-DEL</control>
<control type="button" binding="num-ins">Ins</control>
<control type="button" binding="ctrl-break">Ctrl-Break</control>
<control type="button" binding="ctrl-c">Ctrl-C</control>
<control type="button" binding="ctrl-alt-del">Ctrl-Alt-Del</control>
<control type="button" binding="f1">F1</control>
<control type="button" binding="f2">F2</control>
<control type="button" binding="f3">F3</control>

View file

@ -11,4 +11,4 @@ PDP-10 Device Configurations
* [Control Panels](panel/)
Test machines include a [PDP-10 (Model KA10) with Debugger](/devices/pdp11/machine/ka10/panel/debugger/).
Test machines include a [PDP-10 (Model KA10) with Debugger](/devices/pdp10/machine/ka10/test/debugger/).

View file

@ -9,7 +9,7 @@ permalink: /disks/
Disk Libraries
--------------
Browse these PCjs Disk Libraries:
Browse the following PCjs Disk Libraries.
* [IBM PC](pcx86/)
* [Challenger 1P](c1p/)
@ -19,7 +19,8 @@ Additional software is available in the [Application Archives](/apps/).
---
### PCx86 Disk Image Formats
PCx86 Disk Image Formats
------------------------
PCx86 works best with disk images in a **JSON** format, so that's the only disk format you'll
find in the [PCjs Project](https://github.com/jeffpar/pcjs).
@ -27,7 +28,8 @@ find in the [PCjs Project](https://github.com/jeffpar/pcjs).
There are several ways you can convert a PCjs **JSON** disk image back into a binary **IMG** file:
- Load the disk into a PCjs machine and click the **Save** button
- Use the [DiskDump API](/api/v1/dump) (available only in the [PCjs Node Web Server](/server.js))
- Use the [DiskDump API](/api/v1/dump) (available only with the
[PCjs Node Web Server](https://github.com/jeffpar/pcjs/blob/master/server.js))
Note that whenever you **Save** a disk inside a PCjs machine, it is saved exactly as it exists
at that point in time. So, if you made any changes to the disk, those changes will be preserved
@ -38,7 +40,8 @@ For example:
{{ site.url }}/api/v1/dump?disk=/disks/pcx86/dos/ibm/2.00/PCDOS200-DISK1.json&format=img
The [PCjs Node Web Server](/server.js) also generates "onclick" handlers for links to **JSON** disk
The [HTMLOut Component](https://github.com/jeffpar/pcjs/blob/master/modules/htmlout/lib/htmlout.js)
of the PCjs Node Web Server also generates "onclick" handlers for links to **JSON** disk
images that automatically invoke the API for you.
See [Creating PCx86-Compatible Disk Images](/docs/pcx86/#creating-pcx86-compatible-disk-images)

View file

@ -7,7 +7,7 @@ permalink: /disks/pcx86/apps/ibm/topview/
TopView
---
Information is available for these versions of TopView:
Information is available for the following versions of TopView.
* [TopView 1.01](1.01/)
* [TopView 1.10](1.10/)

View file

@ -418,6 +418,10 @@
<disk path="/disks/pcx86/tools/borland/pascal/3.01a/TURBO-PASCAL-301A.json">Borland Turbo Pascal 3.01A</disk>
<disk path="/disks/pcx86/tools/ibm/bascom/1.00/BASCOM100-DISK1.json">IBM BASIC Compiler 1.00 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/ibm/bascom/1.00/BASCOM100-DISK2.json">IBM BASIC Compiler 1.00 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK1.json">IBM Pascal 1.00 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK2.json">IBM Pascal 1.00 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK3.json">IBM Pascal 1.00 (Disk 3)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISKS.json">IBM Pascal 1.00 (Combined)</disk>
<disk path="/disks/pcx86/tools/logitech/modula2/1.00/LOGITECH-MODULA2-DISK1-SYSTEM.json">Modula-2/86 1.00 (1-System)</disk>
<disk path="/disks/pcx86/tools/logitech/modula2/1.00/LOGITECH-MODULA2-DISK2-LINKER.json">Modula-2/86 1.00 (2-Linker)</disk>
<disk path="/disks/pcx86/tools/logitech/modula2/1.00/LOGITECH-MODULA2-DISK3-COMPILER.json">Modula-2/86 1.00 (3-Compiler)</disk>

View file

@ -350,6 +350,10 @@
<disk path="/disks/pcx86/apps/lotus/123/1as/123-DISK3-GRAPH.json">Lotus 1-2-3 1A* (3-Graph)</disk>
<disk path="/disks/pcx86/apps/lotus/123/1as/123-DISK4-TUTORIAL.json">Lotus 1-2-3 1A* (4-Tutorial)</disk>
<disk path="/disks/pcx86/apps/microsoft/chart/2.02/CHART202.json">MS Chart 2.02 (Modified)</disk>
<disk path="/disks/pcx86/apps/microsoft/multiplan/1.06/MULTIPLAN106.json">MS Multiplan 1.06 (Modified)</disk>
<disk path="/disks/pcx86/apps/microsoft/multiplan/2.00/MULTIPLAN200.json">MS Multiplan 2.00 (Modified)</disk>
<disk path="/disks/pcx86/apps/microsoft/multiplan/2.01/MULTIPLAN201-INSTALL.json">MS Multiplan 2.01 (INSTALL)</disk>
<disk path="/disks/pcx86/apps/microsoft/multiplan/2.01/MULTIPLAN201-PROGRAM.json">MS Multiplan 2.01 (PROGRAM)</disk>
<disk path="/disks/pcx86/apps/microsoft/word/3.0/WORD30-DISK1-PROGRAM.json">MS Word 3.0 (Disk 1)</disk>
<disk path="/disks/pcx86/apps/microsoft/word/3.0/WORD30-DISK2-SPELL.json">MS Word 3.0 (Disk 2)</disk>
<disk path="/disks/pcx86/apps/microsoft/word/3.0/WORD30-DISK3-UTILITIES.json">MS Word 3.0 (Disk 3)</disk>
@ -414,6 +418,10 @@
<disk path="/disks/pcx86/tools/borland/pascal/3.01a/TURBO-PASCAL-301A.json">Borland Turbo Pascal 3.01A</disk>
<disk path="/disks/pcx86/tools/ibm/bascom/1.00/BASCOM100-DISK1.json">IBM BASIC Compiler 1.00 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/ibm/bascom/1.00/BASCOM100-DISK2.json">IBM BASIC Compiler 1.00 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK1.json">IBM Pascal 1.00 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK2.json">IBM Pascal 1.00 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK3.json">IBM Pascal 1.00 (Disk 3)</disk>
<disk path="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISKS.json">IBM Pascal 1.00 (Combined)</disk>
<disk path="/disks/pcx86/tools/logitech/modula2/1.00/LOGITECH-MODULA2-DISK1-SYSTEM.json">Modula-2/86 1.00 (1-System)</disk>
<disk path="/disks/pcx86/tools/logitech/modula2/1.00/LOGITECH-MODULA2-DISK2-LINKER.json">Modula-2/86 1.00 (2-Linker)</disk>
<disk path="/disks/pcx86/tools/logitech/modula2/1.00/LOGITECH-MODULA2-DISK3-COMPILER.json">Modula-2/86 1.00 (3-Compiler)</disk>
@ -509,6 +517,17 @@
<disk path="/disks/pcx86/tools/microsoft/os2/sdk/1.02/MSOS2-SDK102-DISK13.json">MS OS/2 SDK 1.02 (EXAMPLE1)</disk>
<disk path="/disks/pcx86/tools/microsoft/os2/sdk/1.02/MSOS2-SDK102-DISK14.json">MS OS/2 SDK 1.02 (EXAMPLE2)</disk>
<disk path="/disks/pcx86/tools/microsoft/os2/sdk/1.02/MSOS2-SDK102-DISK15.json">MS OS/2 SDK 1.02 (NETWORK)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/3.31/PASCAL331-DISK1.json">MS Pascal 3.31 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/3.31/PASCAL331-DISK2.json">MS Pascal 3.31 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK1.json">MS Pascal 4.00 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK2.json">MS Pascal 4.00 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK3.json">MS Pascal 4.00 (Disk 3)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK4.json">MS Pascal 4.00 (Disk 4)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK5.json">MS Pascal 4.00 (Disk 5)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK6.json">MS Pascal 4.00 (Disk 6)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK7.json">MS Pascal 4.00 (Disk 7)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK8.json">MS Pascal 4.00 (Disk 8)</disk>
<disk path="/disks/pcx86/tools/microsoft/pascal/4.00/PASCAL400-DISK9.json">MS Pascal 4.00 (Disk 9)</disk>
<disk path="/disks/pcx86/tools/microsoft/windows/sdk/1.01/WINSDK101-DISK1-UTILITIES.json">Windows SDK 1.01 (Disk 1)</disk>
<disk path="/disks/pcx86/tools/microsoft/windows/sdk/1.01/WINSDK101-DISK2-LIBSMALL.json">Windows SDK 1.01 (Disk 2)</disk>
<disk path="/disks/pcx86/tools/microsoft/windows/sdk/1.01/WINSDK101-DISK3-LIBMEDIUM.json">Windows SDK 1.01 (Disk 3)</disk>

File diff suppressed because one or more lines are too long

View file

@ -51,54 +51,55 @@ will load the following PC AT controller configuration and disk image:
### Notes Regarding 10Mb Disks
The [PC-DOS 2.00 Formatted Disk (Empty)](pcdos200-empty.xml) is *completely* empty. It was partitioned with the PC-DOS 2.00
**FDISK** utility, allocating the entire disk to a single DOS partition, and then it was formatted with the PC-DOS 2.00
**FORMAT** utility. Neither the **FORMAT** "/S" option nor the **SYS** command were used, so no system files were
transferred, leaving the disk completely empty and non-bootable.
The [PC-DOS 2.00 Formatted Disk (Empty)](pcdos200-empty.xml) is *completely* empty. It was partitioned with the PC-DOS
2.00 **FDISK** utility, allocating the entire disk to a single DOS partition, and then it was formatted with the PC-DOS
2.00 **FORMAT** utility. Neither the **FORMAT** "/S" option nor the **SYS** command were used, so no system files were
transferred, leaving the disk completely empty and unbootable.
After formatting, PC-DOS 2.00 reports:
10592256 bytes total disk space
10592256 bytes available on disk
As explained in the [DiskDump source code](/modules/diskdump/lib/diskdump.js), in its description of the 10Mb
As explained in our [DiskDump source code](/modules/diskdump/lib/diskdump.js), in its description of the 10Mb
BPB, a 10Mb "Type 3" PC XT fixed disk contains:
306 cylinders
4 heads
17 sectors/track
for a total of 20808 sectors or 10,653,696 bytes. However, as p.1-179 of the PC XT Technical Reference Manual
for a total of 20808 sectors or 10,653,696 bytes. However, as page 1-179 of the PC XT Technical Reference Manual
(April 1983) notes:
WARNING: The last cylinder on the fixed disk drive is reserved for diagnostic use.
Diagnostic write tests will destroy any data on this cylinder.
And this is confirmed by the PC XT BIOS, p.A-94, in the code for the "GET PARAMETERS (AH = 8)" function:
And this is confirmed by the PC XT BIOS, page A-94, in the code for the "GET PARAMETERS (AH = 8)" function:
C800:03B2 268B07 MOV AX,ES:[BX] ; MAX NUMBER OF CYLINDERS
C800:03B5 2D0200 SUB AX,2 ; ADJUST FOR 0-N AND RESERVE LAST TRACK
By "RESERVE LAST TRACK", they really meant "RESERVE LAST CYLINDER", because 68 (not 17) sectors are reserved at
the end of the disk. In addition, the first sector of the disk is reserved for the Master Boot Record (MBR), so there
are a total of 69 reserved sectors. (20808 - 69) = 20739 or 0x5103, which is exactly what's stored in the "total
sectors" field of the disk's BPB, yielding a total partition size of 10,618,368 bytes.
are a total of 69 reserved sectors. 20808 - 69 = 20739 sectors (0x5103), which is exactly what's stored in the
"total sectors" field of the disk's BPB, yielding a total partition size of 10,618,368 bytes.
However, that 69-sector overhead is not the end of the story. There is also overhead incurred by the FAT file system,
which, in this case, consists of:
- Boot sector (1)
- DOS Boot sector (1)
- FAT sectors (2 * 8 = 16)
- Root directory sectors (32)
for a total of 49 sectors, leaving (20739 - 49) = 20690 sectors. Moreover, free space is measured in clusters,
for a total of 49 sectors, leaving 20739 - 49 = 20690 sectors. Moreover, free space is measured in clusters,
not sectors, and the partition uses 8 sectors/cluster, leaving room for 2586.25 clusters. Since a fractional cluster
is not allowed, another 2 sectors are lost, bringing the total FAT file system overhead to 51 sectors.
Thus, actual free space is (20739 - 51) * 512, or 10,592,256 bytes, which is exactly what DOS reports as the available
space.
Some sources on the internet (eg,[http://www.wikiwand.com/en/Timeline_of_DOS_operating_systems](http://www.wikiwand.com/en/Timeline_of_DOS_operating_systems))
Some sources on the internet (eg,
[http://www.wikiwand.com/en/Timeline_of_DOS_operating_systems](http://www.wikiwand.com/en/Timeline_of_DOS_operating_systems))
claim that the FAT file system overhead for the XT's 10Mb disk is "50 sectors". As they explain:
"The fixed disk has 10,618,880 bytes of raw space: 305 cylinders (the equivalent of tracks) × 2 platters

View file

@ -84,6 +84,7 @@
<manifest ref="/disks/pcx86/tools/borland/pascal/3.00b/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/borland/pascal/3.01a/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/ibm/bascom/1.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/ibm/pascal/1.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/logitech/modula2/1.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/logitech/modula2/1.10/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/basic/manifest.xml"/>

View file

@ -67,6 +67,9 @@
<manifest ref="/disks/pcx86/apps/lotus/123/1a/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/lotus/123/1as/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/chart/2.02/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/multiplan/1.06/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/multiplan/2.00/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/multiplan/2.01/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/word/3.0/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/word/3.1/manifest.xml"/>
<manifest ref="/disks/pcx86/apps/microsoft/word/5.0/manifest.xml"/>
@ -81,6 +84,7 @@
<manifest ref="/disks/pcx86/tools/borland/pascal/3.00b/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/borland/pascal/3.01a/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/ibm/bascom/1.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/ibm/pascal/1.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/logitech/modula2/1.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/logitech/modula2/1.10/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/basic/manifest.xml"/>
@ -103,6 +107,8 @@
<manifest ref="/disks/pcx86/tools/microsoft/mouse/5.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/mouse/6.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/os2/sdk/1.02/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/pascal/3.31/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/pascal/4.00/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/windows/sdk/1.01/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/windows/sdk/1.03/manifest.xml"/>
<manifest ref="/disks/pcx86/tools/microsoft/windows/sdk/1.04/manifest.xml"/>

View file

@ -8,3 +8,4 @@ IBM Languages and Utilities
---------------------------
* [IBM BASIC Compilers](/disks/pcx86/tools/ibm/bascom/)
* [IBM Pascal Compilers](/disks/pcx86/tools/ibm/pascal/)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,76 @@
---
layout: page
title: IBM Pascal Compiler 1.00
permalink: /disks/pcx86/tools/ibm/pascal/1.00/
---
IBM Pascal Compiler 1.00
------------------------
When the IBM Pascal Compiler 1.00 was originally released in August 1981, the standard IBM PC contained at most
two diskette drives (no hard drive), so compiling Pascal programs required using a "scratch disk" in drive B:
and then inserting each of the three 160Kb Pascal Compiler disks into drive A: to complete the compilation and
linking process. Moreover, the user was required to copy LINK.EXE from their PC-DOS 1.00 diskette (the only version
of PC-DOS available at the time) to the third disk.
To make life a bit simpler (but only a bit), we've combined the contents of all three diskettes onto a 360Kb "Combined"
diskette, along with LINK.EXE from PC-DOS 1.00. Here's the [DiskDump](/modules/diskdump/) command used to produce the
diskette image:
diskdump --path="archive/PAS1/PAS1.EXE;PASKEY;ENTX6S.ASM;FILKQQ.INC;FILUQQ.INC;archive/PAS2/PAS2.EXE;
archive/PAS3/PASCAL;PASCAL.LIB;../../../../dos/ibm/1.00/archive/PCDOS100/LINK.EXE" --format=json --label=PASCAL100
--output=PASCAL100-DISKS.json --manifest
It's important to use the original PC-DOS linker, because not all linkers will process IBM Pascal 1.00 object files
properly. Given this dependency, it's odd that IBM didn't simply distribute the PC-DOS 1.00 linker on the third IBM
Pascal disk; there was certainly room for it, so it wouldn't have cost anything, and it would have reduced the risk
of using a newer and potentially incompatible linker.
NOTE: We do not have copies of the three original distribution disks. However, based on information in IBM's Pascal
Compiler documentation, we were able to recreate the contents of the disks. The file dates were arbitrarily selected
from the August 1981 time frame.
### Directory of IBM Pascal 1.00 (Disk 1)
Volume in drive A is PAS1
Directory of A:\
ENTX6S ASM 8320 8-31-81 12:00p
FILKQQ INC 5347 8-31-81 12:00p
FILUQQ INC 1513 8-31-81 12:00p
PAS1 EXE 81408 8-31-81 12:00p
PASKEY 2816 8-31-81 12:00p
5 File(s) 59904 bytes free
### Directory of IBM Pascal 1.00 (Disk 2)
Volume in drive A is PAS2
Directory of A:\
PAS2 EXE 99200 8-31-81 12:00p
1 File(s) 60928 bytes free
### Directory of IBM Pascal 1.00 (Disk 3)
Volume in drive A is PAS3
Directory of A:\
PASCAL 50 8-31-81 12:00p
PASCAL LIB 83456 8-31-81 12:00p
2 File(s) 76288 bytes free
### Directory of IBM Pascal 1.00 (Combined)
Volume in drive A is PASCAL100
Directory of A:\
PAS1 EXE 81408 8-31-81 12:00p
PASKEY 2816 8-31-81 12:00p
ENTX6S ASM 8320 8-31-81 12:00p
FILKQQ INC 5347 8-31-81 12:00p
FILUQQ INC 1513 8-31-81 12:00p
PAS2 EXE 99200 8-31-81 12:00p
PASCAL 50 8-31-81 12:00p
PASCAL LIB 83456 8-31-81 12:00p
LINK EXE 43264 8-04-81
9 File(s) 31744 bytes free

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/versions/pcx86/1.37.0/manifest.xsl"?>
<manifest type="software">
<title>IBM Pascal Compiler</title>
<version>1.00</version>
<type>Utility</type>
<category>Compiler</category>
<language>Pascal</language>
<author>IBM/Microsoft</author>
<releaseDate>1981-08</releaseDate>
<disk id="disk01" size="163840" chs="40:1:8" dir="archive/PAS1" href="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK1.json" md5="0928b1d381346edb65389035fdadf576" md5json="47444406efdc43fa0016af7e7b930a30">
<name>IBM Pascal 1.00 (Disk 1)</name>
<file size="8320" time="1981-08-31 12:00:00" attr="0x20" md5="948612930287deb5fd53edd701ea0c11">ENTX6S.ASM</file>
<file size="5347" time="1981-08-31 12:00:00" attr="0x20" md5="7dfc79d20d272dafe89050d496a964cf">FILKQQ.INC</file>
<file size="1513" time="1981-08-31 12:00:00" attr="0x20" md5="f2ccf10239ff715e0185f4fd6773f6bf">FILUQQ.INC</file>
<file size="81408" time="1981-08-31 12:00:00" attr="0x20" md5="2f5b2a5abb1ddc47b8878c4ddc85d659">PAS1.EXE</file>
<file size="2816" time="1981-08-31 12:00:00" attr="0x20" md5="158742abe72baea5f1c4de6e3541e578">PASKEY</file>
</disk>
<disk id="disk02" size="163840" chs="40:1:8" dir="archive/PAS2" href="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK2.json" md5="54c895c983236726d880a5c54fb6b76c" md5json="c8bf7b25a980110c2fd04e7a64cddf5c">
<name>IBM Pascal 1.00 (Disk 2)</name>
<file size="99200" time="1981-08-31 12:00:00" attr="0x20" md5="6fa0cf28313f5fd6672a87ab7734dec7">PAS2.EXE</file>
</disk>
<disk id="disk03" size="163840" chs="40:1:8" dir="archive/PAS3" href="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISK3.json" md5="f9724e602d895e8ada7e4c7788130007" md5json="5d652b98c5ee4e3fb08aa4bc67b92354">
<name>IBM Pascal 1.00 (Disk 3)</name>
<file size="50" time="1981-08-31 12:00:00" attr="0x20" md5="0d20462b4a56654c357fd5b332b45f08">PASCAL</file>
<file size="83456" time="1981-08-31 12:00:00" attr="0x20" md5="fcb8631a5fba5c4b146cf253ca27773e">PASCAL.LIB</file>
</disk>
<disk id="disk04" size="368640" chs="40:2:9" href="/disks/pcx86/tools/ibm/pascal/1.00/PASCAL100-DISKS.json" md5="01cb202e441cc2d6fe4cad0b2771df0d" md5json="a2f35b82f2263007feba98c5682d9ee3">
<name>IBM Pascal 1.00 (Combined)</name>
<file size="81408" time="1981-08-31 12:00:00" attr="0x20" md5="2f5b2a5abb1ddc47b8878c4ddc85d659">PAS1.EXE</file>
<file size="2816" time="1981-08-31 12:00:00" attr="0x20" md5="158742abe72baea5f1c4de6e3541e578">PASKEY</file>
<file size="8320" time="1981-08-31 12:00:00" attr="0x20" md5="948612930287deb5fd53edd701ea0c11">ENTX6S.ASM</file>
<file size="5347" time="1981-08-31 12:00:00" attr="0x20" md5="7dfc79d20d272dafe89050d496a964cf">FILKQQ.INC</file>
<file size="1513" time="1981-08-31 12:00:00" attr="0x20" md5="f2ccf10239ff715e0185f4fd6773f6bf">FILUQQ.INC</file>
<file size="99200" time="1981-08-31 12:00:00" attr="0x20" md5="6fa0cf28313f5fd6672a87ab7734dec7">PAS2.EXE</file>
<file size="50" time="1981-08-31 12:00:00" attr="0x20" md5="0d20462b4a56654c357fd5b332b45f08">PASCAL</file>
<file size="83456" time="1981-08-31 12:00:00" attr="0x20" md5="fcb8631a5fba5c4b146cf253ca27773e">PASCAL.LIB</file>
<file size="43264" time="1981-08-04 00:00:00" attr="0x20" md5="2f11573f12d0bf5a60a62a50eef7e577">LINK.EXE</file>
</disk>
</manifest>

View file

@ -0,0 +1,10 @@
---
layout: page
title: IBM Pascal Compilers
permalink: /disks/pcx86/tools/ibm/pascal/
---
IBM Pascal Compilers
--------------------
* [IBM Pascal Compiler 1.00](1.00/)

View file

@ -5,13 +5,13 @@ permalink: /modules/diskdump/
---
DiskDump Module
===
---------------
**DiskDump** is a Node module with both a command-line interface and a web server API for converting disk images
to/from various formats (eg, JSON files, JSON files with comments, IMG disk images, etc).
DiskDump is a Node [module](lib/diskdump.js) with both a command-line [utility](bin/diskdump) and a web server API
for converting disk images to/from various formats (eg, JSON files, JSON files with comments, IMG disk images, etc).
### Building Disk Images from Folders/Files
Building Disk Images from Folders/Files
---
In addition to converting disk images to/from JSON, DiskDump can also create disk images from the contents of local
files/folders.
@ -28,7 +28,8 @@ into that folder as well, so that you could then run:
node modules/diskdump/bin/diskdump --path="apps/pcx86/1981/visicalc/vc.com;README.md" --format=img --output=disk.img
to produce a `disk.img` containing both "VC.COM" and "README.md". In fact, this is exactly how the
[disk.json](/apps/pcx86/1981/visicalc/disk.json) stored in the [VisiCalc](/apps/pcx86/1981/visicalc/) folder was generated.
[VisiCalc Disk](/apps/pcx86/1981/visicalc/VISICALC1981.json) stored in the [VisiCalc](/apps/pcx86/1981/visicalc/)
folder was generated.
The equivalent web server API request would look like:

View file

@ -331,7 +331,7 @@ function DiskDump(sDiskPath, asExclude, sFormat, fComments, sSize, sServerRoot,
*/
this.sServerRoot = sServerRoot;
this.sDiskPath = sDiskPath;
if (this.sServerRoot && !net.isRemote(sDiskPath)) {
if (this.sServerRoot && !net.isRemote(sDiskPath) && sDiskPath.indexOf(';') < 0) {
this.sDiskPath = path.join(this.sServerRoot, sDiskPath);
}
this.asExclude = asExclude || DiskDump.asExclusions;
@ -1786,25 +1786,24 @@ DiskDump.prototype.readPath = function(sPath, done)
var sFileName = asFiles[iFile];
var i = sFileName.lastIndexOf(path.sep);
if (i >= 0) {
if (sFileName.indexOf("..") < 0) {
sDefaultPath = sFileName.substr(0, i);
/*
* The DiskDump constructor joins the beginning of sPath with sServerRoot,
* but if there are any intermediate paths, we have to join them ourselves.
*/
if (iFile > 0 && !net.isRemote(sDefaultPath)) {
sDefaultPath = path.join(this.sServerRoot, sDefaultPath);
}
sFileName = sFileName.substr(i+1);
} else {
/*
* TODO: We need to permit ".." without compromising the server...
*
var err = new Error('invalid file "' + sFileName + '"');
done(err, null);
return;
*/
//
// We used to prevent paths with "..", to protect the web server from malicious requests,
// but we need to allow them for unfettered command-line support of the --path option.
//
// if (sFileName.indexOf("..") >= 0) {
// var err = new Error('invalid file "' + sFileName + '"');
// done(err, null);
// return;
// }
sDefaultPath = sFileName.substr(0, i);
/*
* The DiskDump constructor joins the beginning of sPath with sServerRoot,
* but if there are any intermediate paths, we have to join them ourselves.
*/
if (iFile > 0 && !net.isRemote(sDefaultPath)) {
sDefaultPath = path.join(this.sServerRoot, sDefaultPath);
}
sFileName = sFileName.substr(i+1);
}
/*
* Ordinarily, sFileName will already be the basename, except when it has a path element like "../"

View file

@ -5,6 +5,7 @@ permalink: /modules/filedump/
---
FileDump Module
===
---------------
This module (and command-line utility) is used to convert the contents of binary files to JSON.
FileDump is a Node [module](lib/filedump.js) with both a command-line [utility](bin/filedump) and a web server API
for converting the contents of binary files to JSON.

View file

@ -21,13 +21,13 @@ If you want to read as little as possible, then just paste the following code on
```html
<div id="myC1P"/></div><div style="clear:both"></div>
<script type="text/javascript"
src="http://www.pcjs.org/versions/c1pjs/1.34.0/c1p.js">
src="http://www.pcjs.org/versions/c1pjs/1.37.0/c1p.js">
</script>
<script type="text/javascript">
window.embedC1P(
"myC1P",
"http://www.pcjs.org/devices/c1p/machine/8kb/embed/machine.xml",
"http://www.pcjs.org/versions/c1pjs/1.34.0/components.xsl"
"http://www.pcjs.org/versions/c1pjs/1.37.0/components.xsl"
);
</script>
```
@ -45,7 +45,7 @@ The order of the XML elements also determines the layout of the associated HTML
**&lt;keyboard&gt;** element appears before the **&lt;video&gt;** element, then the keyboard controls will be
displayed *above* the video display instead of *below*. There's an extensive set of attributes that you can add
to any of the elements below to style and position them, including the usual *style* attribute, but at present,
there's no documentation beyond the sample XML files and the default [XML stylesheet](/versions/c1pjs/1.34.0/components.xsl).
there's no documentation beyond the sample XML files and the default [XML stylesheet](/versions/c1pjs/1.37.0/components.xsl).
The example at the top of this page uses an [XML file](/devices/c1p/machine/8kb/embed/machine.xml) that looks like:
@ -82,7 +82,7 @@ Machine configuration files can also be "self-starting" if they contain the foll
top of the file:
```xml
<?xml-stylesheet type="text/xsl" href="http://www.pcjs.org/versions/c1pjs/1.34.0/machine.xsl"?>
<?xml-stylesheet type="text/xsl" href="http://www.pcjs.org/versions/c1pjs/1.37.0/machine.xsl"?>
```
For example, here's a self-starting [machine.xml](/devices/c1p/machine/8kb/large/machine.xml) configuration.
@ -133,11 +133,11 @@ Step 3: Add the C1Pjs Simulator to your web page
Somewhere on your page, you need to add the following **&lt;script&gt;** element:
```html
<script type="text/javascript" src="http://www.pcjs.org/versions/c1pjs/1.34.0/c1p.js"></script>
<script type="text/javascript" src="http://www.pcjs.org/versions/c1pjs/1.37.0/c1p.js"></script>
```
To include the C1Pjs Debugger, use [c1p-dbg.js](/versions/c1pjs/1.34.0/c1p-dbg.js) instead of
[c1p.js](/versions/c1pjs/1.34.0/c1p.js), and include some additional definitions in your machine
To include the C1Pjs Debugger, use [c1p-dbg.js](/versions/c1pjs/1.37.0/c1p-dbg.js) instead of
[c1p.js](/versions/c1pjs/1.37.0/c1p.js), and include some additional definitions in your machine
definition XML file:
```xml
@ -175,7 +175,7 @@ The **embedC1P()** function accepts three parameters:
- the *id* attribute of the HTML element that will contain the simulator (eg, 'myC1P');
- the URL of your machine definition XML file (eg, 'embed.xml', since it's on the same server);
- the URL of an XML stylesheet; unless you've created your own stylesheet, it's recommended you omit this
parameter and use the default [XML stylesheet](/versions/c1pjs/1.34.0/components.xsl).
parameter and use the default [XML stylesheet](/versions/c1pjs/1.37.0/components.xsl).
Step 5: Enjoy!
--------------
@ -184,7 +184,7 @@ All I ask is that any page that embeds the simulator also includes attribution,
> [PCjs](http://pcjs.org) © 2012-2017 by [Jeff Parsons](mailto:Jeff@pcjs.org) ([@jeffpar](http://twitter.com/jeffpar))
If you use the default [XML stylesheet](/versions/c1pjs/1.34.0/components.xsl), attribution is automatically inserted,
If you use the default [XML stylesheet](/versions/c1pjs/1.37.0/components.xsl), attribution is automatically inserted,
which relieves you from including it yourself.
Feel free to copy any or all of the files listed above to your own server (it's probably better to share the server

View file

@ -0,0 +1,244 @@
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
I N T R O D U C T I O N
This manual is intended to replace the various (expensive) references needed to
program for the DOS environment, that stack of magazines threatening to take
over your work area, and those odd tables and charts you can never find when you
need them.
The various Microsoft and IBM publications and references don't always have the
same information. This has caused some consternation about the "undocumented"
features to be found in DOS. In general use, if a call doesn't appear in the IBM
DOS Technical Reference it is considered "undocumented" although it may be in
common use.
Microsoft's offical policy toward DOS has been to put the burden of documenting
and supporting their product to their vendors. Microsoft will not answer any
questions concerning DOS directly since they don't officially support it. This
leaves what information IBM and other OEMs (DEC, Zenith, et al) have chosen to
publish, and the information obtained from programmers who've poked around
inside it.
Now that Microsoft is selling MSDOS 3.2 and 3.3 as Microsoft products they seem
to be dragging their feet over whether they will have to support the generic
version since it doesn't have an OEM name on it anymore. In view of their push
to OS/2 (OS/2! Just Say No!) further support of DOS seems unlikely.
The information here is valid for DOS 2.x and 3.x. Where there are differences
between the two versions there are notes in the text. No effort was expended
on DOS 1.x or networking features.
As I write this there is still considerable furor over incompatibilities with
DOS 4.0. Since a Technical Reference for 4.0 isn't availible yet, I don't have
a whole lot of info on it.
When I started writing this book, it was originally for my own personal use.
Then I began expanding it with the idea of getting it published, since at that
time there was *nothing* in print like it. If I had managed to send it off to
the publishers early enough, I would have had it made. As it was I lost six
months having a nice steel rod put in my leg, and half a dozen similar books
were published by then, and nobody was interested in mine. Six months is a
long time in the PC world.
That's why I'm uploading this file as "user-supported." It gives me a chance
to recoup a few bucks for the year or so I've been working on this thing, and
it gives some advantages that a printed book can't - first, you can load it on
your hard disk and use Vern Buerg's LIST or SideKick to scan through text. You
can grab a peice of something and paste it into a document, etc. If you help
support the PC Programmer's Reference you will always have the latest version
availible; you can't "upgrade" printed books.
A project this size takes a LOT of time and effort. I've tried to verify all
the information I've received, but there's just too much for absolute certainty.
If you find any typos, incorrect information, or want to see something else,
let me know. If you have any more detailed information on something, PLEASE let
me know!
Dave Williams
D I S C L A I M E R
The information presented here was gathered from megabytes of files found on
BBS systems, conversations on a dozen different BBS systems, correspondence,
and every reference book I could get my hands on. On occaision, a number of
prestigious references didn't agree with each other. Where this has happened, I
have used the latest references. There is too much information here for me to
verify every fact personally. I have used my own judgement as to the
reliability of the sources.
This entire project was originally begun as a reference for myself, where I
put all the little bits of information I culled from various sources into a
whole and (hopefully) organized format so I could find them again when
nescessary. If you find anything that is incorrect, I would greatly appreciate
a card or letter telling me.
As is common these days, I have to make a "Notice of Disclaimer". I take no
responsibility for anything, and if anything you do with this book ruins you
for life or makes your dog bite you, or anything else, that's just tough.
I hope you find much use for this reference. It was a trip to write, too.
Dave Williams
(C) Copyright 1988
References used in preparing this book:
IBM Technical Reference
Personal Computer
p/n 6322507 IBM Publications
IBM Technical Reference
Personal Computer - PCjr
p/n 1502293 IBM Publications
IBM Technical Reference
Options and Adapters - Enhanced Graphics Adapter
p/n 6280131 IBM Publications Aug 1984
IBM DOS Operations Manual Version 2.00
MS-DOS Programmer's Reference
by Microsoft
p/n 135555-001 Intel Corp. 1984
Lotus-Intel-Microsoft Expanded Memory Specification 4.0
Intel Corp. 1987
Microsoft Extended Memory Specification v2.00
Microsoft Corporation, 1988
X3.4-1977: American National Standard Code for Information Interchange
by American National Standards Institute (ANSI)
New York, NY 1977
Microcomputer Products - 1987 Data Book
NEC Electronics, Inc.
p/n 500105 Aug 1987
FastCard IV User Manual
Peripheral Marketing Inc
p/n 0527 Jan 1987
Hercules Graphics Card User's Manual
Programmer's Guide to the IBM PC
Peter Norton
Microsoft Press 1985
Inside the IBM PC
Peter Norton
Exploring the IBM PCjr
Peter Norton
Microsoft Press 1984
Advanced MSDOS
Ray Duncan
Microsoft Press 1986
The IBM Personal Computer from the Inside Out
Murray Sargent III and Richard L. Shoemaker
Addison-Wesley 1984
DOS:The Complete Reference
Kris Jamsa
Osborne/McGraw-Hill 1987
Mapping the IBM PC
Russ Davies/Compute! Magazine
Compute! Books 1986
Tricks of the MS-DOS Masters
Waite Group
Supercharging MS-DOS
Van Volverton
Microsoft Press 1986
DOS Power Tools
Paul Somerson
Bantam Books 1988
Running MS-DOS
Van Wolverton
Microsoft Press
Microcomputer Interfacing
Bruce A. Artwick
Prentice Hall 1980
The 8080a Bugbook
Tony-Larsen-Titus
Howard W. Sams 1977
S-286 User Manual, version 2
Link Computer, 1988
MPC Operations Guide, Manual #1023
Columbia Data Products, Inc.
CDP 1983
Assembly Language Subroutines for MSDOS Computers
Leo J. Scanlon
TAB Books 1986
The Serious Assembler
Charles A. Crayne and Dian Gerard
Baen Books 1985
Assembly Language Programming for the IBM Personal Computer
David J. Bradley
Prentice-Hall 1984
The 8086 Book
Russell Rector and George Alexy
Osborne/McGraw-Hill 1980
Compute!'s Guide to Assembly Language Programming on the IBM PC
Dr. Dobb's Journal
PC Magazine
PC Resource
PC Tech Journal
Computer Language
Programmer's Journal
Byte Magazine
various computer bulletin board systems, including
Byte Information Exchange (BIX)
Compuserve IBM SIG
GEnie IBM RT
GT Net international network
FIDO Net international network
PCanada BBS system (Toronto, Canada)
Pecan Pi RBBS, (404) 454-8756 (Atlanta, Georgia)
Night Modulator, (408) 728-5598 (San Jose, California)
various text files downloaded from BBS systems - INTERRUP.ARC, BIOSDOS.ZOO,
DOSINFO.ARC, DOSERROR.DOC, DOSTIPS.TXT, etc.
and all the people who have been good enough to furnish information

View file

@ -0,0 +1,241 @@
CHAPTER 1.
DOS TECHNICAL INFORMATION
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
SOME HISTORY
Development of MSDOS/PCDOS began in October 1980, when IBM began searching
the market for an operating system for the yet-to-be-introduced IBM PC.
Microsoft had no real operating system to sell, but after some research licensed
Seattle Computer Products' 86-DOS, which had been written by a man named Tim
Paterson for use on the company's line of 8086, S100 bus micros. This was
hurriedly polished up and presented to IBM for evaluation. IBM had originally
intended to use Digital Research's CP/M operating system, which was the industry
standard at the time. Folklore reports everything from obscure legal
entanglements to outright snubbing of the IBM representatives by Digital,
irregardless, IBM found itself left with Microsoft's offering of "Microsoft Disk
Operating System 1.0". An agreement was reached between the two, and "IBM PC-DOS
1.0" was ready for the introduction of the IBM PC in October 1981. IBM subjected
the operating system to an extensive quality-assurance program, found well over
300 bugs, and decided to rewrite the programs. This is why PC-DOS is copyrighted
by both IBM and Microsoft.
It is sometimes amusing to reflect on the fact that the IBM PC was not
originally intended to run MSDOS. The target operating system at the end of the
development was for a (not yet in existence) 8086 version of CP/M. On the other
hand, when DOS was originally written the IBM PC did not yet exist! Although
PC-DOS was bundled with the computer, Digital Research's CP/M-86 would probably
have been the main operating system for the PC except for two things - Digital
Research wanted $495 for CP/M-86 (considering PC-DOS was essentially free) and
many software developers found it easier to port existing CP/M software to DOS
than to the new version of CP/M.
MSDOS and PC-DOS have been run on more than just the IBM-PC and clones. There
was an expansion board for the Apple ][ that allowed one to run (some) well -
behaved DOS programs. There are expansion boards for the Commodore Amiga 2000,
the Apple MacIntosh II, and the IBM RT PC allowing them to run DOS, and the IBM
3270 PC, which ran DOS on a 68000 microprocessor. The Atari STs can run an
emulator program and boot MSDOS.
Specific Versions of MS/PC-DOS:
DOS version nomenclature: major.minor.minor. The digit to the left of the
decimal point indicates a major DOS version change. 1.0 was the first version.
2.0 added subdirectories, etc. 3.0 added file handles and network support.
The first minor version indicates customization for a major application. For
example, 2.1 for the PCjr, 3.3 for the PS/2s. The second minor version does not
seem to have any particular meaning.
The main versions of DOS are:
PC-DOS 1.0 October 1981 original release
PC-DOS 1.1 June 1982 bugfix, double sided drive support
MS-DOS 1.25 June 1982 for early compatibles
PC-DOS 2.0 March 1983 for PC/XT, many UNIX-like functions
PC-DOS 2.1 October 1983 for PCjr, bugfixes for 2.0
MS-DOS 2.11 October 1983 compatible equivalent to 2.1
PC-DOS 3.0 August 1984 for PC/AT, network support
PC-DOS 3.1 November 1984 bugfix for 3.0
MS-DOS 2.25 October 1985 compatible; extended foreign language support
PC-DOS 3.2 July 1986 3.5 inch drive support for Convertible
PC-DOS 3.3 April 1987 for PS/2 series
Some versions of MS-DOS varied from PC-DOS in the availible external commands.
Some OEMs only licensed the basic operating system code (the xxxDOS and xxxBIO
programs, and COMMAND.COM) from Microsoft, and either wrote the rest themselves
or contracted them from outside software houses like Phoenix. Most of the
external programs for DOS 3.x are written in "C" while the 1.x and 2.x utilities
were written in assembly language. Other OEMs required customized versions of
DOS for their specific hardware configurations, such as Sanyo 55x and early
Tandy computers, which were unable to exchange their DOS with the IBM version.
At least two versions of DOS have been modified to be run entirely out of ROM.
The Sharp PC5000 had MSDOS 1.25 in ROM, and the Toshiba 1100 and some Tandy
models have MSDOS 2.11 in ROM.
THE OPERATING SYSTEM HIERARCHY
The Disk Operating System (DOS) and the ROM BIOS serve as an insulating layer
between the application program and the machine, and as a source of services
to the application program.
The system heirarchy may be thought of as a tree, with the lowest level being
the actual hardware. The 8088 or V20 processor sees the computer's address
space as a ladder two bytes wide and one million bytes long. Parts of this
ladder are in ROM, parts in RAM, and parts are not assigned. There are also
256 "ports" that the processor can use to control devices.
The hardware is normally addressed by the ROM BIOS, which will always know
where everything is in its particular system. The chips may usually also be
written to directly, by telling the processor to write to a specific address or
port. This sometimes does not work as the chips may not always be at the same
addresses or have the same functions from machine to machine.
DOS STRUCTURE
DOS consists of four components:
* The boot record
* The ROM BIOS interface (IBMBIO.COM or IO.SYS)
* The DOS program file (IBMDOS.COM or MSDOS.SYS)
* The command processor (COMMAND.COM or aftermarket replacement)
* The Boot Record
The boot record begins on track 0, sector 1, side 0 of every diskette formatted
by the DOS FORMAT command. The boot record is placed on diskettes to produce an
error message if you try to start up the system with a nonsystem diskette in
drive A. For hard disks, the boot record resides on the first sector of the DOS
partition. All media supported by DOS use one sector for the boot record.
* Read Only Memory (ROM) BIOS Interface
The file IBMBIO.COM or IO.SYS is the interface module to the ROM BIOS.
This file provides a low-level interface to the ROM BIOS device routines and
may contain extensions or changes to the system board ROMs. Some compatibles do
not have a ROM BIOS to extend, and load the entire BIOS from disk. (Sanyo 55x,
Viasyn)
* The DOS Program File
The actual DOS program is file IBMDOS.COM or MSDOS.SYS. It provides a high-
level interface for user (application) programs. This program consists of file
management routines, data blocking/deblocking for the disk routines, and a
variety of built-in functions easily accessible by user programs.
When a user program calls these function routines, they accept high-level
information by way of register and control block contents. For device
operations, the functions translate the requirement into one or more calls to
IBMBIO.COM or MSDOS.SYS to complete the request.
* The Command Interpreter
The Command interpreter, COMMAND.COM, consists of these parts:
Resident Portion:
The resident portion resides in memory immediately following IBMDOS.COM and its
data area. This portion contains routines to process interrupts 22h (Terminate
Address), 23h (Ctrl-Break Handler), and 24h (Critical Error Handler), as well as
a routine to reload the transient portion if needed. For DOS 3.x, this portion
also contains a routine to load and execute external commands, such as files
with exensions of COM or EXE.
When a program terminates, a checksum is used to determine if the application
program overlaid the transient portion of COMMAND.COM. If so, the resident
portion will reload the transient portion from the area designated by COMSPEC=
in the DOS environment. If COMMAND.COM cannot be found, the system will halt.
NOTE: DOS 3.3 checks for the presence of a hard disk, and will default to
COMSPEC=C:\. Previous versions default to COMSPEC=A:\. Under some DOS
versions, if COMMAND.COM is not immediately availible for reloading
(i.e., swapping to a floppy with COMMAND.COM on it) DOS may crash.
All standard DOS error handling is done within the resident portion of
COMMAND.COM. This includes displaying error messages and interpreting the
replies of Abort, Retry, Ignore, Fail.
An initialization routine is included in the resident portion and assumes
control during startup. This routine contains the AUTOEXEC.BAT file handler and
determines the segment address where user application programs may be loaded.
The initialization routine is then no longer needed and is overlaid by the first
program COMMAND.COM loads.
NOTE: AUTOEXEC.BAT may be a hidden file.
A transient portion is loaded at the high end of memory. This is the command
processor itself, containing all of the internal command processors and the
batch file processor. For DOS 2.x, this portion also contains a routine to load
and execute external commands, such as files with extensions of COM or EXE.
This portion of COMMAND.COM also produces the DOS prompt (such as "A>"), reads
the command from the standard input device (usually the keyboard or a batch
file), and executes the command. For external commands, it builds a command line
and issues an EXEC function call to load and transfer control to the program.
NOTE: COMMAND.COM may be a hidden file.
NOTE: For Dos 2.x, the transient portion of the command processor contains the
EXEC routine that loads and executes external commands. For DOS 3.x, the
resident portion of the command processor contains the EXEC routine.
DOS Initialization
The system is initialized by a software reset (Ctrl-Alt-Del), a hardware reset
(reset button), or by turning the computer on. The Intel 80x8x series processors
always look for their first instruction at the end of their address space
(0FFFF0h) when powered up or reset. This address contains a jump to the first
instruction for the ROM BIOS.
Built-in ROM programs (Power-On Self-Test, or POST, in the IBM) check machine
status and run inspection programs of various sorts. Some machines set up a
reserved RAM area with bytes indicating installed equipment (AT and PCjr).
The ROM routine looks for a disk drive at A: or an option ROM (usually a hard
disk) at absolute address C:800h. If no floppy drive or option ROM is found, the
BIOS calls int 19h (ROM BASIC if it is an IBM) or displays error message.
If a bootable disk is found, the ROM BIOS loads the first sector of information
from the disk and then jumps into the RAM location holding that code. This code
normally is a routine to load the rest of the code off the disk, or to "boot"
the system.
The following actions occur after a system initialization:
1. The boot record is read into memory and given control.
2. The boot record then checks the root directory to assure that the first
two files are IBMBIO.COM and IBMDOS.COM. These two files must be the
first two files, and they must be in that order (IBMBIO.COM first, with
its sectors in contiguous order).
NOTE: IBMDOS.COM need not be contiguous in version 3.x.
3. The boot record loads IBMBIO.COM into memory.
4. The initialization code in IBMBIO.COM loads IBMDOS.COM, determines
equipment status, resets the disk system, initializes the attached
devices, sets the system parameters and loads any installable device
drivers according to the CONFIG.SYS file in the root directory (if
present), sets the low-numbered interrupt vectors, relocates IBMDOS.COM
downward, and calls the first byte of DOS.
NOTE: CONFIG.SYS may be a hidden file.
5. DOS initializes its internal working tables, initializes the interrupt
vectors for interrupts 20h through 27h, and builds a Program Segment
Prefix for COMMAND.COM at the lowest available segment. For DOS versions
3.10 up, DOS initializes interrupt vectors for interrupts 0Fh through 3Fh.
6. IBMBIO.COM uses the EXEC function call to load and start the top-level
command processor. The default command processor is COMMAND.COM.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,230 @@
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
These scan codes are generated by pressing a key on the PC's keyboard. This
is the 'make' code. A 'break' code is generated when the key is released. The
break scancode is 128 higher than the make code, and is generated by setting
bit 7 of the scan code byte to 1.
IBM PC KEYBOARD EXTENDED CODES
Normal Shift Control Alt
ESC 1
1 2 0;120
2 3 0;121
3 4 0;122
4 5 0;123
5 6 0;124
6 7 0;125
7 8 0;126
8 9 0;127
9 10 0;128
0 11 0;129
- 12 0;130
= 13 0;131
TAB 15 0;15(backtab)
backtab none 0;15
RETURN 28
Normal Shift Control Alt NumLock
Home 0;71 0;119 none 7
UpArrow 0;72 none none 8
PgUp 0;73 0;132 none 9
gray - 0;74 0;74
LArrow 0;75 0;115 none 4
keypad 5 none none none 5
RArrow 0;77 0;116 6
gray + 0;78 0;78
End 0;79 0;117 none 1
DnArrow 0;80 2
PgDn 0;81 0;118 none 3
Ins 0;82 none 11
Del 0;83 0;128 none 52
PrtSc 55 0;114
L shift 42
R shift 54
alt key 56
capslock 58
spacebar 57
control key 29
numlock 69
scrollock 70
; 39
[ 26
] 27
" 40
\ 43
/ 53
, 51
. 52
Normal Shift Control Alt
a = 30 0;30
b = 48 0;48
c = 46 0;46
d = 32 0;32
e = 18 0;18
f = 33 0;33
g = 34 0;34
h = 35 0;35
i = 23 0;23
j = 36 0;36
k = 37 0;37
l = 38 0;38
m = 50 0;50
n = 49 0;49
o = 24 0;24
p = 25 0;25
q = 16 0;16
r = 19 0;19
s = 31 0;31
t = 20 0;20
u = 22 0;22
v = 47 0;47
w = 17 0;17
x = 45 0;45
y = 21 0;21
z = 44 0;44
Normal Shift Control Alt
F1 = 0;59 0;84 0;94 0;104
F2 = 0;60 0;85 0;95 0;105
F3 = 0;61 0;86 0;96 0;106
F4 = 0;62 0;87 0;97 0;107
F5 = 0;63 0;88 0;98 0;108
F6 = 0;64 0;89 0;99 0;109
F7 = 0;65 0;90 0;100 0;110
F8 = 0;66 0;91 0;101 0;111
F9 = 0;67 0;92 0;102 0;112
F10 = 0;68 0;93 0;103 0;113
"Enhanced" 101/102 key keyboard scancodes
Normal Shift Control Alt
F11 = 0;152 0;162 0;172 0;182 |
F12 = 0;153 0;163 0;173 0;183 | Tandy?
F11 = 0;133 0;135 0;137 0;139
F12 = 0;134 0;136 0;138 0;140
alt-home 0;151
UpArr 0;141 0;152
Ctrl - 0;142
Ctrl 5 0;143
Ctrl + 0;144
DnArr 0;145 0;160
Ins 0;146 0;162
Del 0;147 0;163
Tab 0;148 0;165
/ 0;149 0;164
Ctrl-* 0;150
alt-Enter 0;166
alt-PgUp 0;153
alt-LArr 0;154
alt-RArr 0;155
alt-End 0;156
alt-PgDn 0;161
BIOS keystroke codes, hexadecimal
Key Normal Shift Control Alt
Esc 011B 011B 011B --
1! 0231 '1' 0221 '!' -- 7800
2@ 0332 '2' 0340 '@' 0300 7900
3# 0433 '3' 0423 '#' -- 7A00
4$ 0534 '4' 0524 '$' -- 7B00
5% 0635 '5' 0625 '%' -- 7C00
6^ 0736 '6' 075E '^' 071E 7D00
7& 0837 '7' 0826 '&' -- 7E00
8* 0938 '8' 092A '*' -- 7F00
9( 0A39 '9' 0A28 '(' -- 8000
0) 0B30 '0' 0B29 ')' -- 8100
-_ 0C2D '-' 0C5F '_' 0C1F 8200
=+ 0D3D '=' 0D2B '+' -- 8300
BkSpc 0E08 0E08 0E7F --
tab 0F09 0F00 -- --
q 1071 'q' 1051 'Q' 1011 1000
w 1177 'w' 1157 'W' 1117 1100
e 1265 'e' 1245 'E' 1205 1200
r 1372 'r' 1352 'R' 1312 1300
t 1474 't' 1454 'T' 1414 1400
y 1579 'y' 1559 'Y' 1519 1500
u 1675 'u' 1655 'U' 1615 1600
i 1769 'i' 1749 'I' 1709 1700
o 186F 'o' 184F 'O' 180F 1800
p 1970 'p' 1950 'P' 1910 1900
[{ 1A5B '[' 1A7B '{' 1A1B --
]} 1B5D ']' 1B7D '}' 1B1D --
enter 1C0D 1C0D 1C0A --
Ctrl -- -- -- --
a 1E61 'a' 1E41 'A' 1E01 1E00
s 1F73 's' 1F53 'S' 1F13 1F00
d 2064 'd' 2044 'D' 2004 2000
f 2166 'f' 2146 'F' 2106 2100
g 2267 'g' 2247 'G' 2207 2200
h 2368 'h' 2348 'H' 2308 2300
j 246A 'j' 244A 'J' 240A 2400
k 256B 'k' 254B 'K' 250B 2500
l 266C 'l' 264C 'L' 260C 2600
;: 273B ';' 273A ':' -- --
'" 2827 ''' 2822 '"' -- --
`~ 2960 '`' 297E '~' -- --
l shift -- -- -- --
\| 2B5C '\' 2B7C '|' 2B1C --
z 2C7A 'z' 2C5A 'Z' 2C1A 2C00
x 2D78 'x' 2D58 'X' 2D18 2D00
c 2E63 'c' 2E43 'C' 2E03 2E00
v 2F76 'v' 2F56 'V' 2F16 2F00
b 3062 'b' 3042 'B' 3002 3000
n 316E 'n' 314E 'N' 310E 3100
m 326D 'm' 324D 'M' 320D 3200
,< 332C ',' 333C '<' -- --
.> 342E '.' 343E '>' -- --
/? 352F '/' 353F '?' -- --
r shift -- -- -- --
PrtSc 372A '*' -- 7200 --
Alt -- -- -- --
spacebar 3920 ' ' 3920 ' ' 3920 ' ' 3920 ' '
CapsLock -- -- -- --
F1 3B00 5400 5E00 6800
F2 3C00 5500 5F00 6900
F3 3D00 5600 6000 6A00
F4 3E00 5700 6100 6B00
F5 3F00 5800 6200 6C00
F6 4000 5900 6300 6D00
F7 4100 5A00 6400 6E00
F8 4200 5B00 6500 6F00
F9 4300 5C00 6600 7000
F10 4400 5D00 6700 7100
NumLock -- -- -- --
Scroll -- -- -- --
7 Home 4700 4737 '7' 7700 --
8 up 4800 4838 '8' -- --
9 PgUp 4900 4939 '9' 8400 --
grey - 4A2D '-' 4A2D '-' -- --
4 left 4B00 4B34 '4' 7300 --
5 -- 4C35 '5' -- --
6 right 4D00 4D36 '6' 7400 --
grey + 4E2B '+' 4E2B '+' -- --
1 End 4F00 4F31 '1' 7500 --
2 down 5000 5032 '2' -- --
3 PgDn 5100 5133 '3' 7600 --
Ins 5200 5230 '0' -- --
Del 5300 532E '.' -- --
A table entry of "--" means you can't get that combination out of BIOS.

View file

@ -0,0 +1,18 @@
This is a user-supported technical reference. If you find this information
to be of use, please mail your check or money order for $15 to:
Dave Williams
PO Box 181
Jacksonville, AR 72087-0181
USA
In return for your support you will receive the very latest edition of this
manual on a disk, plus one disk of appendixes and references and a third
disk with source code. That's about two megabytes of raw data when
uncompressed, or the equivalent of ten manuals the size of the technical
reference manuals from IBM or Microsoft.
In addition, supporting users may obtain updates by merely mailing a disk and
return postage whenever they feel like it.

View file

@ -0,0 +1,713 @@
CHAPTER 2
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
CPU Port Assignments, System Memory Map, BIOS Data Area, Interrupts 00h to 09h
SYSTEM MEMORY MAP - OVERALL
The IBM PC handles its address space in 64k segments, divided into 16k
fractions and then further as nescessary.
start start end
addr. addr. addr. usage
(dec) (hex)
00000 **** 640k *************** system data, drivers....
0000:0000 hardware interrupt vectors
0000:0040 BIOS interrupt vectors
0k start of RAM | 0000:0080 DOS interrupt vector table
16k 00000-03FFF | 0000:0300 Stack area during POST and bootstrap routine
32k 04000-07FFF | 0000:0400 BIOS Data Area
48k 08000-0BFFF | 0000:04F0 Intra-Application Communications Area
|
64k 10000-13FFF | 0000:0500 DOS reserved communication area
80k 14000-17FFF | xxxx:0000 IO.SYS - DOS interface to ROM I/O routines
96k 18000-1BFFF | xxxx:0000 MSDOS.SYS - DOS interrupt handlers, service
112k 1C000-1FFFF | routines (int 21 functions)
|
128k 20000-23FFF | xxxx:xxxx DOS buffers, control areas, and installed
144k 24000-27FFF | device drivers.
160k 28000-2BFFF | xxxx:0000 resident portion of COMMAND.COM, interrupt
176k 2C000-2FFFF | handlers for int 22h, 23h,24h, and code to
| reload the transient portion
192k 30000-33FFF | xxxx:0000 master environment block, default 64 bytes
208k 34000-37FFF | xxxx:0000 environment for next program
224k 38000-3BFFF | xxxx:0000 external commands or utilities (COM or EXE
240k 3C000-3FFFF | files)
|
256k 40000-43FFF | ----:---- application programs
272k 44000-47FFF | xxxx:0000 user stack for COM files (256 bytes)
288k 48000-4BFFF | xxxx:0000 transient portion of COMMAND.COM
304k 4C000-4FFFF |
|
320k 50000-53FFF |
336k 54000-57FFF |
352k 58000-5BFFF |
368k 5C000-5FFFF |
|
384k 60000-63FFF |
400k 64000-67FFF |
416k 68000-6BFFF |
432k 6C000-6FFFF |
|
448k 70000-73FFF |
464k 74000-77FFF |
480k 78000-7BFFF |
496k 7C000-7FFFF |
|
512k 80000-83FFF |
528k 84000-87FFF |
544k 88000-8BFFF | original IBM PC-1 BIOS limited memory to 544k
560k 8C000-8FFFF |
|
576k 90000-93FFF |
592k 94000-97FFF |
609k 98000-9BFFF |
624k 9C000-9FFFF | to 640k (top of RAM address space)
A0000 ***** 64k *************** EGA address
640k A0000-A95B0 MCGA 320x200 256 color video buffer
AF8C0 MCGA 640x480 2 color video buffer
-A3FFF
656k A4000-A7FFF
672k A8000-ABFFF
688k AC000-AFFFF
B0000 ***** 64k *************** mono and CGA address
704k B0000-B3FFF mono uses only 4k | The PCjr and early Tandy 1000
720k B4000-B7FFF | BIOSs revector direct writes to
736k B8000-BBFFF CGA uses entire 16k | the B8 area to the Video Gate
756k BC000-BFFFF | Array and reserved system RAM
C0000 ***** 64k *************** expansion ROM
768k C0000-C3FFF 16k EGA BIOS C000:001E EGA BIOS signature (the letters IBM)
784k C4000-C5FFF
C6000-C63FF 256 bytes Professional Graphics Display communication area
C6400-C7FFF
800k C8000-CBFFF 16k hard disk controller BIOS, drive 0 default
816k CC000-CDFFF 8k IBM PC Network NETBIOS
CE000-CFFFF
D0000 ***** 64k *************** expansion ROM | PCjr first ROM cartridge
832k D0000-D7FFF 32k IBM Cluster Adapter | address area.
DA000 voice communications |
848k D4000-D7FFF | Common expanded memory board
864k D8000-DBFFF | paging area.
880k DC000-DFFFF |
E0000 ***** 64k *************** expansion ROM | PCjr second ROM
896k E0000-E3FFF | cartridge address
912k E4000-E7FFF | area
928k E8000-EBFFF |
944k EC000-EFFFF |
F0000 ***** 64k *************** system | PCjr optional ROM
960k F0000-F3FFF reserved by IBM | cartridge address
976k F4000- | area (cartridge
F6000 ROM BASIC Begins | BASIC)
992k F8000-FB000 |
1008k FC000-FFFFF ROM BASIC and original |
BIOS (Compatibility BIOS |
in PS/2) |
1024k FFFFF end of memory (1024k) for 8088 machines
F000:FFF5 BIOS release date
F000:FFFE PC model identification
384k 100000-15FFFF 80286/AT extended memory area, 1Mb motherboard
15Mb 100000-FFFFFF 80286/AT extended memory address space
15Mb 160000-FDFFFF Micro Channel RAM expansion (15Mb extended memory)
128k FE0000-FFFFFF system board ROM (PS/2 Advanced BIOS)
PC Port Assignment, Intel 8088, 80C88, 8086, 80286, 80386 CPUs
hex addr. Function
0000-000F 8237 DMA controller
0010-001F 8237 DMA controller (AT, PS/2)
0020-0027 8259A interrupt controller
0020-003F 8259A interrupt controller (AT)
0040-005F 8253-5 programmable timers
(note: 0041 was memory refresh in PCs. Not used in PS/2)
0060-0067 8255 peripheral interface
0060-006F 8042 keyboard controller (AT)
0200-020F game-control adapter
0210-0217 expansion box (PC, XT)
0278-027F LPT3
02F8-02FF COM2
0300-031F prototype card
0320-032F hard disk controller
0378-037F LPT2
03BC-03BF LPT1
03D0-03DF CGA, MCGA, VGA adapter control
03F0-03F7 floppy disk controller
03F8-03FF COM1
note: These are functions common across the IBM range. The PCjr, PC
Convertible and PS/2 (both buses) have enhancements. In some cases, the
AT and PS/2 series ignore, duplicate, or reassign ports arbitrarily. If
your code incorporates specific port addresses for video or system board
control it would be wise to have your application determine the machine
type and video adapter and address the ports as required.
Reserved Memory Locations in the IBM PC
addr. size description
000h-3FFh DOS interrupt vector table
30:00h- used as a stack area during POST and bootstrap routines. This
3F:FFh stack area may be revectored by an application program.
The BIOS Data Area addr. from 400h to 4FFh
40:00 word COM1 port address | These addresses are zeroed out in the
40:02 word COM2 port address | OS/2 DOS Compatibility Box if any of
40:04 word COM3 port address | the OS/2 COM??.SYS drivers are loaded.
40:06 word COM4 port address |
40:08 word LPT1 port address
40:0A word LPT2 port address
40:0C word LPT3 port address
40:0E word LPT4 port address (not valid in PS/2 machines)
40:0E word PS/2 pointer to 1k extended BIOS Data Area at top of RAM
40:10 word equipment flag (see int 11h)
bits:
0 1 if floppy drive present (see bits 6&7) 0 if not
1 1 if 80x87 installed (not valid in PCjr)
2,3 system board RAM (not used on AT or PS/2)
00 16k
01 32k
10 48k
11 64k
4,5 initial video mode
00 no video adapter
01 40 column color (PCjr)
10 80 column color
11 MDA
6,7 number of diskette drives
00 1 drive
01 2 drives
10 3 drives
11 4 drives
8 0 DMA present
1 DMA not present (PCjr)
9,A,B number of RS232 serial ports
C game adapter (joystick)
0 no game adapter
1 if game adapter
D serial printer (PCjr only)
0 no printer
1 serial printer present
E,F number of parallel printers installed
note 1) The IBM PC and AT store the settings of the system board
switches or CMOS RAM setup information (as obtained by the BIOS
in the Power-On Self Test (POST)) at addresses 40:10h and
40:13h. 00000001b indicates "on", 00000000b is "off".
2) CMOS RAM map, PC/AT:
offset contents
00h Seconds
01h Second Alarm
02h Minutes
03h Minute Alarm
04h Hours
05h Hour Alarm
06h Day of the Week
07h Day of the Month
08h Month
09h Year
0Ah Status Register A
0Bh Status Register B
0Ch Status Register C
0Dh Status Register D
0Eh Diagnostic Status Byte
0Fh Shutdown Status Byte
10h Disk Drive Type for Drives A: and B:
The drive-type bytes use bits 0:3 for the first
drive and 4:7 for the other
Disk drive types:
00h no drive present
01h double sided 360k
02h high capacity (1.2 meg)
03h-0Fh reserved
11h (AT):Reserved (PS/2):drive type for hard disk C:
12h (PS/2):drive type for hard disk D:
(AT, XT/286):hard disk type for drives C: and D:
Format of drive-type entry for AT, XT/286:
0 number of cyls in drive (0-1023 allowed)
2 number of heads per drive (0-15 allowed)
3 starting reduced write compensation (not
used on AT)
5 starting cylinder for write compensation
7 max. ECC data burst length, XT only
8 control byte
Bit
7 disable disk-access retries
6 disable ECC retries
5-4 reserved, set to zero
3 more than 8 heads
2-0 drive option on XT (not used by AT)
9 timeout value for XT (not used by AT)
12 landing zone cylinder number
14 number of sectors per track (default 17,
0-17 allowed)
13h Reserved
14h Equipment Byte (corresponds to sw. 1 on PC and XT)
15h-16h Base Memory Size (low,high)
17h-18h Expansion Memory Size (low,high)
19h-20h Reserved
(PS/2) POS information Model 50 (60 and 80 use a 2k
CMOS RAM that is not accessible through software)
21h-2Dh Reserved (not checksumed)
2Eh-2Fh Checksum of Bytes 10 Through 20 (low,high)
30h-31h Exp. Memory Size as Det. by POST (low,high)
32h Date Century Byte
33h Information Flags (set during power-on)
34h-3Fh Reserved
3) The alarm function is used to drive the BIOS wait function (int
15h function 90h).
4) To access the configuration RAM write the byte address (00-3Fh)
you need to access to I/O port 70h, then access the data via I/O
port 71h.
5) CMOS RAM chip is a Motorola 146818
6) The equipment byte is used to determine the configuration for the
power-on diagnostics.
7) Bytes 00-0Dh are defined by the chip for timing functions, bytes
0Eh-3Fh are defined by IBM.
40:12 byte number of errors detected by infrared keyboard link (PCjr only)
40:13 word availible memory size in Kbytes (less display RAM in PCjr)
this is the value returned by int 12h
40:17 byte keyboard flag byte 0 (see int 9h)
bit 7 insert mode on 3 alt pressed
6 capslock on 2 ctrl pressed
5 numlock on 1 left shift pressed
4 scrollock on 0 right shift pressed
40:18 byte keyboard flag byte 1 (see int 9h)
bit 7 insert pressed 3 ctrl-numlock (pause) toggled
6 capslock pressed 2 PCjr keyboard click active
5 numlock pressed 1 PCjr ctrl-alt-capslock held
4 scrollock pressed 0
40:19 byte storage for alternate keypad entry (not normally used)
40:1A word pointer to keyboard buffer head character
40:1C word pointer to keyboard buffer tail character
40:1E 32bytes 16 2-byte entries for keyboard circular buffer, read by int 16h
40:3E byte drive seek status - if bit=0, next seek will recalibrate by
repositioning to Track 0.
bit 3 drive D bit 2 drive C
1 drive B 0 drive A
40:3F byte diskette motor status
bit 7 1, write in progress 3 1, D: motor on (floppy 3)
6 2 1, C: motor on (floppy 2)
5 1 1, B: motor on
4 0 1, A: motor on
40:40 byte motor off counter
starts at 37 and is decremented 1 by each system clock tick.
motor is shut off when count = 0.
40:41 byte status of last diskette operation where:
bit 7 timeout failure bit 3 DMA overrun
6 seek failure 2 sector not found
5 controller failure 1 address not found
4 CRC failure 0 bad command
40:42 7 bytes NEC status
40:49 byte current CRT mode (hex value)
00h 40x25 BW (CGA) 01h 40x25 color (CGA)
02h 80x25 BW (CGA) 03h 80x25 color (CGA)
04h 320x200 color (CGA) 05h 320x200 BW (CGA)
06h 640x200 BW (CGA) 07h monochrome (MDA)
extended video modes (EGA/MCGA/VGA or other)
08h lores,16 color 09h med res,16 color
0Ah hires,4 color 0Bh n/a
0Ch med res,16 color 0Dh hires,16 color
0Eh hires,4 color 0Fh hires,64 color
40:4A word number of columns on screen, coded as hex number of columns
20 col = 14h (video mode 8, low resolution 160x200 CGA graphics)
40 col = 28h
80 col = 46h
40:4C word screen buffer length in bytes
(number of bytes used per screen page, varies with video mode)
40:4E word current screen buffer starting offset (active page)
40:50 8 words cursor position pages 1-8
the first byte of each word gives the column (0-19, 39, or 79)
the second byte gives the row (0-24)
40:60 byte end line for cursor (normally 1)
40:61 byte start line for cursor (normally 0)
40:62 byte current video page being displayed (0-7)
40:63 word base port address of 6845 CRT controller or equivalent
for active display 3B4h=mono, 3D4h=color
40:65 byte current setting of the CRT mode register
40:66 byte current palette mask setting (CGA)
40:67 5 bytes temporary storage for SS:SP during shutdown (cassette interface)
40:6C word timer counter low word
40:6E word timer counter high word
40:69 byte HD_INSTALL (Columbia PCs) (not valid on most clone computers)
bit 0 = 0 8 inch external floppy drives
1 5-1/4 external floppy drives
1,2 = highest drive address which int 13 will accept
(since the floppy drives are assigned 0-3, subtract
3 to obtain the number of hard disks installed)
4,5 = # of hard disks connected to expansion controller
6,7 = # of hard disks on motherboard controller
(if bit 6 or 7 = 1, no A: floppy is present and
the maximum number of floppies from int 11 is 3)
40:70 byte 24 hour timer overflow 1 if timer went past midnight
it is reset to 0 each time it is read by int 1Ah
40:71 byte BIOS break flag (bit 7 = 1 means break key hit)
40:72 word reset flag (1234 = soft reset, memory check will be bypassed)
PCjr keeps 1234h here for softboot when a cartridge is installed
40:74 byte status of last hard disk operation; PCjr special diskette control
40:75 byte # of hard disks attached (0-2) ; PCjr special diskette control
40:76 byte hd control byte; temporary holding area for 6th param table entry
40:77 byte port offset to current hd adapter ; PCjr special diskette control
40:78 4 bytes timeout value for LPT1,LPT2,LPT3,LPT4
40:7C 4 bytes timeout value for COM1,COM2,COM3,COM4 (0-FFh seconds, default 1)
40:80 word pointer to start of circular keyboard buffer, default 03:1E
40:82 word pointer to end of circular keyboard buffer, default 03:3E
40:84 byte rows on the screen (EGA only)
40:84 byte PCjr interrupt flag; timer channel 0 (used by POST)
40:85 word bytes per character (EGA only)
40:85 2 bytes (PCjr only) typamatic char to repeat
40:86 2 bytes (PCjr only) typamatic initial delay
40:87 byte mode options (EGA only)
Bit 1 0 = EGA is connected to a color display
1 = EGA is monochrome.
Bit 3 0 = EGA is the active display,
1 = "other" display is active.
Mode combinations:
Bit3 Bit1 Meaning
0 0 EGA is active display and is color
0 1 EGA is active display and is monochrome
1 0 EGA is not active, a mono card is active
1 1 EGA is not active, a CGA is active
40:87 byte (PCjr only) current Fn key code
40:88 byte feature bit switches (EGA only) 0=on, 1=off
bit 3 = switch 4
bit 2 = switch 3
bit 1 = switch 2
bit 0 = switch 1
40:88 byte (PCjr only) special keyboard status byte
bit 7 function flag 3 typamatic (0=enable,1=disable)
6 Fn-B break 2 typamatic speed (0=slow,1=fast)
5 Fn pressed 1 extra delay bef.typamatic (0=enable)
4 Fn lock 0 write char, typamatic delay elapsed
40:89 byte PCjr, current value of 6845 reg 2 (horiz.synch) used by
ctrl-alt-cursor screen positioning routine in ROM
40:8A byte PCjrCRT/CPU Page Register Image, default 3Fh
40:8B byte last diskette data rate selected
40:8C byte hard disk status returned by controller
40:8D byte hard disk error returned by controller
40:8E byte hard disk interrupt (bit 7=working int)
40:90 4 bytes media state drive 0, 1, 2, 3
40:94 2 bytes track currently seeked to drive 0, 1
40:96 byte keyboard flag byte 3 (see int 9h)
40:97 byte keyboard flag byte 2 (see int 9h)
40:98 dword pointer to users wait flag
40:9C dword users timeout value in microseconds
40:A0 byte real time clock wait function in use
40:A1 byte LAN A DMA channel flags
40:A2 2 bytes status LAN A 0,1
40:A4 dword saved hard disk interrupt vector
40:A8 dword EGA pointer to parameter table
40:B4 byte keyboard NMI control flags (Convertible)
40:B5 dword keyboard break pending flags (Convertible)
40:B9 byte port 60 single byte queue (Convertible)
40:BA byte scan code of last key (Convertible)
40:BB byte pointer to NMI buffer head (Convertible)
40:BC byte pointer to NMI buffer tail (Convertible)
40:BD 16bytes NMI scan code buffer (Convertible)
40:CE word day counter (Convertible and after)
to -04:8F end of BIOS Data Area
40:90-40:EF reserved by IBM
04:F0 16 bytes Intra-Application Communications Area (for use by applications
04:FF to transfer data or parameters to each other)
05:00 byte DOS print screen status flag
00h not active or successful completion
01h print screen in progress
0FFh error during print screen operation
05:01 Used by BASIC
05:02-03 PCjr POST and diagnostics work area
05:04 byte Single drive mode status byte
00 logical drive A
01 logical drive B
05:05-0E PCjr POST and diagnostics work area
05:0F BASIC: SHELL flag (set to 02h if there is a current SHELL)
05:10 word BASIC: segment address storage (set with DEF SEG)
05:12 4 bytes BASIC: int 1Ch clock interrupt vector segment:offset storage
05:16 4 bytes BASIC: int 23h ctrl-break interrupt segment:offset storage
05:1A 4 bytes BASIC: int 24h disk error interrupt vector segment:offset storage
05:1B-1F Used by BASIC for dynamic storage
05:20-21 Used by DOS for dynamic storage
05:22-2C Used by DOS for diskette parameter table. See int 1Eh for values
05:30-33 Used by MODE command
05:34-FF Unknown - Reserved for DOS
At Absolute Addresses:
0008:0047 IO.SYS or IBMBIO.COM IRET instruction. This is the dummy routine that
interrupts 01h, 03h, and 0Fh are initialized to during POST.
C000:001E EGA BIOS signature (the letters IBM)
F000:FFF5 BIOS release date
F000:FFFE PC model identification
date model byte submodel byte revision
04/24/81 FF = PC-0 (16k) -- --
10/19/81 FF = PC-1 (64k) -- --
08/16/82 FF = PC, XT, XT/370 -- --
(256k motherboard)
10/27/82 FF = PC, XT, XT/370 -- --
(256k motherboard)
11/08/82 FE = XT, Portable PC -- --
XT/370, 3270PC
01/10/86 FB = XT 00 01
01/10/86 FB = XT-2 (early)
05/09/86 FB = XT-2 (640k) 00 02
06/01/83 FD = PCjr -- --
01/10/84 FC = AT -- --
06/10/85 FC = AT 00 01
11/15/85 FC = AT 01 00
04/21/86 FC = XT/286 02 00
09/13/85 F9 = Convertible 00 00
09/02/86 FA = PS/2 Model 30 00 00
11/15/86 FC = AT, Enhanced 8mHz
02/13/87 FC = PS/2 Model 50 04 00
02/13/87 FC = PS/2 Model 60 05 00
1987 F8 = PS/2 Model 80 00 00
2D = Compaq PC (4.77) -- --
9A = Compaq Plus (XT) -- --
00FC 7531/2 Industrial AT
06FC 7552 Gearbox
The IBM PC System Interrupts (Overview)
The interrupt table is stored in the very lowest location in memory, starting
at 0000:0000h. The locations are offset from segment 0, ie location 0000h has
the address for int 0, etc. Each address is four bytes long and its location in
memory can be found by multiplying the interrupt number by 4. For example, int
7 could be found by (7x4=28) or 1Bh (0000:001Bh).
These interrupt vectors normally point to ROM tables or are taken over by DOS
when an application is run. Some applications revector these interrupts to
their own code to change the way the system responds to the user.
Interrupt Address Function
Number (Hex)
0 00-03 CPU Divide by Zero
1 04-07 CPU Single Step
2 08-0B CPU Nonmaskable
3 0C-0F CPU Breakpoint
4 10-13 CPU Overflow
5 14-17 BIOS Print Screen
6 18-1B hdw Reserved
7 1C-1F hdw Reserved
8 20-23 hdw Time of Day
9 24-27 hdw Keyboard
A 28-2B hdw Reserved
B 2C-2F hdw Communications [8259]
C 30-33 hdw Communications
D 34-37 hdw Disk
E 38-3B hdw Diskette
F 3C-3F hdw Printer
10 40-43 BIOS Video
11 44-47 BIOS Equipment Check
12 48-4B BIOS Memory
13 4C-4F BIOS Diskette/Disk
14 50-53 BIOS Serial Communications
15 54-57 BIOS Cassette, System Services
16 58-5B BIOS Keyboard
17 5C-5F BIOS Parallel Printer
18 60-63 BIOS Resident BASIC
19 64-67 BIOS Bootstrap Loader
1A 68-6B BIOS Time of Day
1B 6C-6F BIOS Keyboard Break
1C 70-73 BIOS Timer Tick
1D 74-77 BIOS Video Initialization
1E 78-7B BIOS Diskette Parameters
1F 7C-7F BIOS Video Graphics Characters, second set
20 80-83 DOS General Program Termination
21 84-87 DOS DOS Services Function Request
22 88-8B DOS Called Program Termination Address
23 8C-8F DOS Control Break Termination Address
24 90-93 DOS Critical Error Handler
25 94-97 DOS Absolute Disk Read
26 98-9B DOS Absolute Disk Write
27 9C-9F DOS Terminate and Stay Resident
28-3F A0-FF DOS Reserved for DOS
40-43 100-115 BIOS Reserved for BIOS
44 116-119 BIOS First 128 Graphics Characters
45-47 120-131 BIOS Reserved for BIOS
48 132-135 BIOS PCjr Cordless Keyboard Translation
49 136-139 BIOS PCjr Non-Keyboard Scancode Translation Table
50-5F 140-17F BIOS Reserved for BIOS
60-67 180-19F Reserved for User Software Interrupts
68-7F 1A0-1FF Reserved by IBM
80-85 200-217 ROM BASIC
86-F0 218-3C3 Used by BASIC Interpreter When BASIC is Running
F1-FF 3C4-3FF Reserved by IBM
For consistency in this volume, all locations and offsets are in hexadecimal
unless otherwise specified. All hex numbers are prefaced with a leading zero
if they begin with an alphabetic character, and are terminated with a
lowercase H (h). The formats vary according to common usage.
The IBM-PC System Interrupts (in detail)
Interrupt 00h Divide by Zero (processor error). Automatically called at end
(0:0000h) of DIV or IDIV operation that results in error. Normally set by
DOS to display an error message and abort the program.
Interrupt 01h Single step - Taken after every instruction when CPU Trap Flag
(0:0004h) indicates single-step mode (bit 8 of FLAGS is 1). This is what
makes the T command of DEBUG work for single stepping. Is not
generated after MOV to segment register or POP of segment
register. (unless you have a very early 8088 with the microcode
bug).
Interrupt 02h Non-maskable interrupt - Vector not disabled via CLI. Used by
(0:0008h) parity check routine in POST, 8087 coprocessor, PCjr infrared
keyboard link.
Interrupt 03h Breakpoint - Taken when CPU executes the 1-byte int 3 (0CCh).
(0:000Ch) Generated by opcode 0CCh. Similar to 8080's RST instruction.
Generally used to set breakpoints for DEBUG.
Interrupt 04h Divide overflow - Generated by INTO instruction if OF flag is
(0:0010h) set. If flag is not set, INTO is effectively a NOP. Used to trap
any arithmetic errors when program is ready to handle them rather
than immediately when they occur.
Interrupt 05h Print Screen - service dumps the screen to the printer. Invoked
(0:0014h) by int 9 for shifted key 55 (PrtSc). Automatically called by
keyboard scan when PrtSc key is pressed. Normally executes
routine to print the screen, but may call any routine that can
safely be executed from inside the keyboard scanner. Status and
result byte are at address 0050:0000.
entry AH 05h
return absolute address 50:0
00h print screen has not been called, or upon return from a call
there were no errors.
01h print screen is already in progress.
0FFh error encountered during printing.
note 1) Uses BIOS services to read the screen
2) Output is directed to LPT1
3) Revectored into GRAPHICS.COM if GRAPHICS.COM is loaded
Interrupt 06h Reserved by IBM
(0:0018h)
Interrupt 07h Reserved by IBM
(0:00C0h)
Interrupt 08h Timer - 55ms timer "tick" taken 18.2 times per second. Updates
(0:0020h) (IRQ0) BIOS clock and turns off diskette drive motors after 2
seconds of inactivity.
entry AH 08h
return absolute addresses:
40:6C number of interrupts since power on (4 bytes)
40:70 number of days since power on (1 byte)
40:67 day counter on all products after AT
40:40 motor control count - gets decremented and shuts off diskette
motor if zero
note Int 1Ch invoked as a user interrupt.
Interrupt 09h Keyboard - taken whenever a key is pressed or released.
(0:0024h) (IRQ1) Stores characters/scan-codes in status at [0040:0017,18]
entry AH 09h
return at absolute memory addresses:
40:17 bit
0 right shift key depressed
1 left shift key depressed
2 control key depressed
3 alt key depressed
4 ScrollLock state has been toggled
5 NumLock state has been toggled
6 CapsLock state has been toggled
7 insert state is active
40:18 bit
0 left control key depressed
1 left alt key depressed
2 SysReq key depressed
3 Pause key has been toggled
4 ScrollLock key is depressed
5 NumLock key is depressed
6 CapsLock key is depressed
7 Insert key is depressed
40:96 bit
0 last code was the E1h hidden code
1 last code was the E0h hidden code
2 right control key down
3 right alt key down
4 101 key Enhanced keyboard installed
5 force NumLock if rd ID & kbx
6 last character was first ID character
7 doing a read ID (must be bit 0)
40:97 bit
0 ScrollLock indicator
1 NumLock indicator
2 CapsLock indicator
3 circus system indicator
4 ACK received
5 resend received flag
6 mode indicator update
7 keyboard transmit error flag
40:1E keyboard buffer (20h bytes)
40:1C buffer tail pointer
40:72 1234h if ctrl-alt-del pressed on keyboard
AL scan code
note 1) Int 05h invoked if PrtSc key pressed
2) Int 1Bh invoked if Ctrl-Break key sequence pressed
3) Int 15h, AH=85h invoked on AT and after if SysReq key is pressed
4) Int 15h, AH=4Fh invoked on machines after AT
Interrupt 0Ah EGA Vertical Retrace
(0:0028h) (IRQ2) used by EGA vertical retrace, hard disk
Interrupt 0Bh Communications Controller (serial port) hdw. entry
(0:002Ch) (IRQ3) Serial Port 2 (com2)
note IRQ 3 may be used by SDLC (synchronous data-link control) or
bisynchronous communications cards instead of a serial port.
Interrupt 0Ch Communications Controller (serial port) hdw. entry
(0:0030h) (IRQ4) Serial Port 1 (com1)
note IRQ 4 may be used by SDLC (synchronous data-link control) or
bisynchronous communications cards instead of a serial port.
Interrupt 0Dh Alternate Printer, PC/AT 80287
(0:0034h) (IRQ5) used by hard disk, 60 Hz RAM refresh, LPT2 on AT, XT/286,
and PS/2, dummy CRT vertical retrace on PCjr
Interrupt 0Eh Diskette - indicates that a seek is in progress
(0:0038h) (IRQ6) (sets bit 8 of 40:3E)
Interrupt 0Fh Reserved by IBM
(0:003Ch) (IRQ7) IRQ7 used by PPI interrupt (LPT1, LPT2)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,539 @@
CHAPTER 6
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
DOS CONTROL BLOCKS AND WORK AREAS
When DOS loads a program, it first sets aside a section of memory for the
program called the program segment, or code segment. Then it constructs a
control block called the program segment prefix, or PSP, in the first 256
(100h) bytes. Usually, the program is loaded directly after the PSP at
100h.
The PSP contains various information used by DOS to help run the program.
The PSP is always located at offset 0 within the code segment. When a program
recieves control certain registers are set to point to the PSP. For a COM
file, all registers are set to point to the beginning of the PSP and the
program begins at 100h. For the more complex EXE file structures, only DS and
ES registers are set to point to the PSP. The linker passes the settings for
the DS, IP, SS, and SP registers and may set the starting location in CS:IP to
a location other than 100h.
IBMBIO provides an IRET instruction at absolute address 847h for use as a
dummy routine for interrupts that are not used by DOS. This lets the
interrupts do nothing until their vectors are rerouted to ttheir appropriate
handlers.
A storage block is used by DOS to record the amount and location of allocated
memory withion the machine's address spacd.
A storage block, a Program Segment Prefix, and an environment area are built
by FDOS for each program currently resident in the address space. The storage
block is used by DOS to record the address range of memory allocated to a
program. IOt us used by DOs to find th enext availible area to load a program
and to determine if there is a\enough memory to run that porogram. When a
memory area is in use, it is said to be allocated. Then the program ends, or
releases memory, it is said to bne deallocated.
A storage block contains a pointer ro rhe Program Segment Prefix assoiciated
with each program. This control block is constructed by IBMDOS for the purpose
opf providing stanfdardized areas for DOS/program communication., Within ghr
PSP are arsas which are used to save interrupt vectors, pass parameters to
the program, record disk directory information, and to buffer disk reads and
writes. This control block is 100h bytes in lengrth and is followed by the
program mopdule loaded by DOS.
The PSP contains a pointer to the environment area for that program. This
area contains a copy of the current DOS SET, PROMPT, COMSPEC, and PATH values
as well as any user-set variables. The program may examine and modify this
information as desired.
Each storage block is 10h bytes long, although only 5 bytes are currently
used by DOS. The first byte contains 4Dh (a capital M) to indicate that it
contains a pointer to the next storage block. A 5Ah (a capital Z) in the
first byte of a storage block indicatres there are no more storage blocks
following this one (it is the end of the chain). The identifier byte is
followeed by a 2 byte segment number for the associated PSP for that program.
The next 2 bytes contain the number of segments what are allocated to the
program. If this is not the last storage block, then another storage block
follows the allocated memory area.
When thge storage block contains zero for the nuymber of allocated segments,
then no storage is allocated to thius block and the next storage block
immediately follows this one. This can ha-p[en whjen memory is allocated and
then deallocated repeatedly.
IBMDOS constructs a storage block and PSP before loading the command
interpreter (default is COMMAND.COM).
If the copy of COMMAND.COM is a secondary copy, it will lack an environment
address as PSP+2Ch.
The Disk Transfer Area (DTA)
DOS uses an area in memory to contain the data for all file reads and writes
that are performed with FCB function calls. This are is known as the disk
transfer area. This disk transfer area (DTA) is sometimes called a buffer.
It can be located anywhere in the data area of your application program and
should be set by your program.
Only one DTA can be in effect at a time, so your program must tell DOS what
memory location to use before using any disk read or write functions. Use
function call 1Ah (Set Disk Transfer Address) to set the disk transfer address.
Use function call 2Fh (Get Disk Transfer Address) to get the disk transfer
address. Once set, DOS continues to use that area for all disk operations until
another function call 1Ah is issued to define a new DTA. When a program is given
control by COMMAND.COM, a default DTA large enough to hold 128 bytes is
established at 80h into the program's Program Segment Prefix.
For file reads and writes that are performed with the extended function calls,
there is no need to set a DTA address. Instead, specify a buffer address when
you issue the read or write call.
DOS Program Segment
When you enter an external command or call a program through the EXEC function
call, DOS determines the lowest availible address space to use as the start of
available memory for the program being started. This area is called the Program
Segment.
At offset 0 within the program segment, DOS builds the Program Segment Prefix
control block. EXEC loads the program after the Program Segment Prefix (at
offset 100h) and gives it control.
The program returns from EXEC by a jump to offset 0 in the Program Segment
Prefix, by issuing an int 20h, or by issuing an int 21h with register AH=00h or
4Ch, or by calling location 50h in the PSP with AH=00h or 4Ch.
It is the responsibility of all programs to ensure that the CS register
contains the segment address of the Program Segment Prefix when terminating by
any of these methods except call 4Ch.
All of these methods result in returning to the program that issued the EXEC.
During this returning process, interrupt vectors 22h, 23h, and 24h (Terminate,
Ctrl-Break, and Critical Error Exit addresses) are restored from the values
saved in the PSP of the terminating program. Control is then given to the
terminate address.
When a program receives control, the following conditions are in effect:
For all programs:
1) The segment address of the passed environment is contained at offset 2Ch in
the Program Segment Prefix.
2) The environment is a series of ASCII strings totalling less than 32k bytes
in the form: NAME=parameter The default environment is 160 bytes.
Each string is terminated by a byte of zeroes, and the entire set of strings
is terminated by abother byte of zeroes. Following the byte of zeroes that
terminates the set of environment string is a set of initial arguments passed
to a program that contains a word count followed by an ASCIIZ string. The
ASCIIZ string contains the drive, path, and filename.ext of the executable
program. Programs may use this area to determine where the program was loaded
from. The environment built by the command processor (and passed to all
programs it invokes) contains a COMSPEC=string at a minimum (the parameter on
COMSPEC is the path used by DOS to locate COMMAND.COM on disk). The last PATH
and PROMPT commands issued will also be in the environment, along with any
environment strings entered through the SET command.
The environment that you are passed is actually a copy of the invoking
process's environment. If your application terminates and stays resident
through int 27h, you should be aware that the copy of the environment passed
to you is static. That is, it will not change even if subsequent PATH,
PROMPT, or SET commands are issued.
The environment can be used to transfer information between processes or to
store strings for later use by application programs. The environment is
always located on a paragraph boundary. This is its format:
byte ASCIIZ string 1
byte ASCIIZ string 2
....
byte ASCIIZ string n
byte of zeros (0)
Typically the environment strings have the form:
parameter = value
Following the byte of zeros in the environment, a WORD indicates the number
of other strings following.
If the environment is part of an EXECed command interpreter, it is followed
by a copy of the DS:DX filename passed to the child process. A zero value
causes the newly created process to inherit the parent's environment.
3) Offset 80h in the PSP contains code to invoke the DOS function dispatcher.
Thus, by placing the desired function number in AH, a program can issue a
long call to PSP+50h to invoke a DOS function rather than issuing an int 21h.
4) The disk transfer address (DTA) is set to 80h (default DTA in PSP).
5) File Control Blocks 5Ch and 6Ch are formatted from the first two parameters
entered when the command was invoked. Note that if either parameter contained
a path name, then the corresponding FCB will contain only a valid drive
number. The filename field will not be valid.
6) An unformatted parameter area at 81h contains all the characters entered
after the command name (including leading and imbedded delimiters), with 80h
set to the number of characters. If the <, >, or | parameters were entered
on the command line, they (and the filenames associated with them) will not
appear in this area, because redirection of standard input and output is
transparent to applications.
(For EXE files only)
7) DS and ES registers are set to point to the PSP.
8) CS, IP, SS, and SP registers are set to the values passed by the linker.
(For COM files only)
9) For COM files, offset 6 (one word) contains the number of bytes availible in
the segment.
10) Register AX reflects the validity of drive specifiers entered with the
first two parameters as follows:
AL=0FFh is the first parameter contained an invalid drive specifier,
otherwise AL=00h.
AL=0FFh if the second parameter contained an invalid drive specifier,
otherwise AL=00h.
11) All four segment registers contain the segment address of the inital
allocation block, that starts within the PSP control block. All of user
memory is allocated to the program. If the program needs to invoke another
program through the EXEC function call (4Bh), it must first free some memory
through the SETBLOCK function call to provide space for the program being
invoked.
12) The Instruction Pointer (IP) is set to 100h.
13) The SP register is set to the end of the program's segment. The segment size
at offset 6 is rounded down to the paragraph size.
14) A word of zeroes is placed on top of the stack.
The PSP (with offsets in hexadecimal) is formatted as follows:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ P R O G R A M S E G M E N T P R E F I X ³
ÃÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ offset³ size ³ C O N T E N T S ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0000h ³ 2 bytes ³ int 20h ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0002h ³ 2 bytes ³ segment address, end of allocation block ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0004h ³ 1 byte ³ reserved, normally 0 ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0005h ³ 5 bytes ³ long call to MSDOS function dispatcher ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 000Ah ³ 4 bytes ³ previous termination handler interrupt vector (int 22h) ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 000Eh ³ 4 bytes ³ previous contents of ctrl-C interrupt vector (int 23h) ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0012h ³ 4 bytes ³ prev. critical error handler interrupt vector (int 24h) ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0016h ³ 22 bytes ³ reserved for DOS ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 002Ch ³ 2 bytes ³ segment address of environment block ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 002Eh ³ 34 bytes ³ reserved, DOS work area ³
ÀÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 4 bytes ³ stores the calling process's stack pointer when ³
³ ³ switching to DOS's internal stack. ³
ÚÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0050h ³ 3 bytes ³ int 21h, RETF instructions ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0053h ³ 2 bytes ³ reserved ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0055h ³ 7 bytes ³ reserved, or FCB#1 extension ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 005Ch ³ ³ default File Control Block #1 ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 006Ch ³ ³ default File Control Block #2 (overlaid if FCB #1 opened) ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0080h ³ 1 byte ³ parameter length ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0081h ³ ³ parameters ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 00FFh ³ 128 bytes³ command tail and default Disk Transfer Area (DTA) ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1. The first segment of availible memory is in segment (paragraph) form. For
example, 1000h would respresent 64k.
2. The word at offset 6 contains the number of bytes availible in the segment.
3. Offset 2Ch contains the segment address of the environment.
4. Programs must not alter any part of the PSP below offset 5Ch.
offset 0 contains hex bytes CD 20, the int 20h opcode. A program can end
by making a jump to this location when the CS points to the PSP.
For normal cases, int 21, function 4Ch should be used.
offset 2 contains the segment-paragraph address of the end of memory as
reported by DOS. (which may not be the same as the real end of RAM).
Multiply this number by 10h or 16 to get the amount of memory availible.
offset 4 reserved
offset 05 contains a long call to the DOS function dispatcher. Programs may
jump to this address instead of calling int 21 if they wish.
offsets 10, 14, 18 vectors
offset 2C is the segment:offset address of the environment for the program
using this particular PSP.
offset 2E The DWORD at PSP+2EH is used by DOS to store the calling process's
stack pointer when switching to DOS's own private stack - at the end of
a DOS function call, SS:SP is restored from this address.
offset 50h contains a long call to the DOS function dispatcher.
offsets 5C, 65, 6C contain FCB information for use with FCB function calls.
The first FCB may overlay the second if it is an extended call; your
program should revector these areas to a safe place if you intend to
use them.
offset 80h and 81h contain th elength and value of parameters passed on the
command line.
offset FF contains the DTA
STANDRD FILE CONTROL BLOCK
The standard file control block is defined as follows, with the offsets in
decimal:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ F I L E C O N T R O L B L O C K ³
ÃÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ Bytes ³ Function ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0 ³ Drive number. For example: ³
³ ³ Before open: 00h = default drive ³
³ ³ 01h = drive A: ³
³ ³ 02h = drive B: etc. ³
³ ³ After open: 00h = drive C: ³
³ ³ 01h = drive A: ³
³ ³ 02h = drive B: etc. ³
³ ³ 0 is replaced by the actual drive number during open. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1-8 ³ Filename, left justified with trailing blanks. If a reserved device ³
³ ³ name is placed here (such as PRN) do not include the optional colon. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 9-11 ³ Filename extension, left justified with trailing blanks. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 12-13 ³ Current block number relative to beginning of file, starting with 0 ³
³ ³ (set to 0 by the open function call). A block consists of 128 ³
³ ³ records, each of the size specified in the logical record size field.³
³ ³ The current block number is used with the current record field ³
³ ³ (below) for sequential reads and writes. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 14-15 ³ Logical record size in bytes. Set to 80h by the OPEN function call. ³
³ ³ If this is not correct, you must set the value because DOS uses it ³
³ ³ to determine the proper locations in the file for all disk reads and ³
³ ³ writes. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 16-19 ³ File size in bytes. In this 2 word field, the first word is the ³
³ ³ low-order part of the size. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 20-21 ³ Date the file was created or last updated. The mm/dd/yy are mapped ³
³ ³ as follows: ³
³ ³ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ³
³ ³ y y y y y y y m m m m d d d d d ³
³ ³ where: mm is 1-12 ³
³ ³ dd is 1-31 ³
³ ³ yy is 0-119 (1980-2099) ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 22-31 ³ Reserved for system use. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 32 ³ Current relative record number (0-127) within the current block. ³
³ ³ (See above). You must set this field before doing sequential ³
³ ³ read/write operations to the diskette. This field is not initialized ³
³ ³ by the open function call. ³
³ ³ If the record size is less than 64 bytes, both words are used. ³
³ ³ Otherwise, only the first 3 bytes are used. Note that if you use the ³
³ ³ File Control Block at 5Ch in the program segment, the last byte of ³
³ ³ the FCB overlaps the first byte of the unformatted parameter area. ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
note 1) An unopened FCB consists of the FCB prefix (if used), drive number, and
filename.ext properly filled in. An open FCB is one in which the
remaining fields have been filled in by the CREAT or OPEN function
calls.
2) Bytes 0-5 and 32-36 must be set by the user program. Bytes 16-31 are set
by DOS and must not be changed by user programs.
3) All word fields are stored with the least significant byte first. For
example, a record length of 128 is stored as 80h at offset 14, and 00h
at offset 15.
EXTENDED FILE CONTROL BLOCK
The extended file control block is used to create or search for files in the
disk directory that have special attributes.
It adds a 7 byte prefix to the FCB, formatted as follows:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ E X T E N D E D F I L E C O N T R O L B L O C K ³
ÃÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ Bytes ³ Function ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0 ³ Flag byte containing 0FFh to indicate an extended FCB. ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1-6 ³ Reserved ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 6-7 ³ Attribute byte. Refer to function call 11h (search first) for ³
³ ³ details on using the attribute bits during directory searches. This ³
³ ³ function is present to allow applications to define their own files ³
³ ³ as hidden (and thereby excluded from normal directory searches) and ³
³ ³ to allow selective directory searches. ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Any reference in the DOS function calls to an FCB, whether opened or unopened,
may use either a normal or extended FCB. If you are using an extended FCB, the
appropriate register should be set to the first byte of the prefix, rather than
the drive-number field.
MEMORY CONTROL BLOCKS
DOS keeps track of allocated and availible memory blocks, and provides three
function calls for application programs to communicate their memory needs to
DOS. These calls are 48h to allocate a memory block, 49h to free a previously
allocated memory block, and 4Ah (SETBLOCK) to change the size of an allocated
memory block.
CONTROL BLOCK
DOS manages memory as follows:
DOS build a control block for each block of memory, whether free or allocated.
For example, if a program issues an "allocate" (48h), DOS locates a block of
free memory that satisfies the request, and then "carves" the requested memory
out of that block. The requesting program is passed the location of the first
byte of the block that was allocated for it - a memory management control block,
describing the allocated block, has been built for the allocated block and a
second memory management control block describes the amount of space left in the
original free block of memory. When you do a setblock to shrink an allocated
block, DOS builds a memory management control block for the area being freed and
adds it to the chain of control blocks. Thus, any program that changed memory
that is not allocated to it stands a chance of destroying a DOS memory
management control block. This causes unpredictable results that don't show up
until an activity is performed where DOS uses its chain of control blocks. The
normal result is a memory allocation error, which means a system reset will be
required.
When a program (command or application program) is to be loaded, DOS uses the
EXEC function call 4Bh to perform the loading.
This is the same function call that is availible to applications programs for
loading other programs. This function call has two options:
Function 00h, to load and execute a program (this is what the command
processor uses to load and execute external commands)
Function 03h, to load an overlay (program) without executing it.
Although both functions perform their loading in the same way (relocation is
performed for EXE files) their handling of memory management is different.
FUNCTION 0: For function 0 to load and execute a program, EXEC first allocates
the largest availible block of memory (the new program's PSP will be at offset
0 in that block). Then EXEC loads the program. Thus, in most cases, the new
program owns all the memory from its PSP to the end of memory, including memory
occupied by the transient parent of COMMAND.COM. If the program were to issue
its own EXEC function call to load and execute another program, the request
would fail because no availible memory exists to load the new program into.
NOTE: For EXE programs, the amount of memory allocated is the size of the
program's memory image plus the value in the MAX_ALLOC field of the file's
header (offset 0Ch, if that much memory is availible. If not, EXEC
allocates the size of the program's memory image plus the value in the
MIN_ALLOC field in the header (offset 0Ah). These fields are set by the
Linker).
A well-behaved program uses the SETBLOCK function call when it receives
control, to shrink its allocated memory block down to the size it really needs.
A COM program should remember to set up its own stack before doing the SETBLOCK,
since it is likely that the default stack supplied by DOS lies in the area of
memory being used. This frees unneeded memory, which can be used for loading
other programs.
If the program requires additional memory during processing, it can obtain
the memory using the allocate function call and later free it using the free
memory function call.
When a program is loaded using EXEC function call 00h exits, its initial
allocation block (the block beginning with its PSP) is automatically freed
before the calling program regains control. It is the responsibility of all
programs to free any memory they allocate before exiting to the calling
program.
FUNCTION 3: For function 3, to load an overlay, no PSP is built and EXEC
assumes the calling program has already allocated memory to load the new program
into - it will NOT allocate memory for it. Thus the calling program should
either allow for the loading of overlays when it determines the amount of memory
to keep when issuing the SETBLOCK call, or should initially free as much memory
as possible. The calling program should then allocate a block (based on the size
of the program to be loaded) to hold the program that will be loaded using the
"load overlay" call. Note that "load overlay" does not check to see if the
calling program actually owns the memory block it has been instructed to load
into - it assumes the calling program has followed the rules. If the calling
program does not own the memory into which the overlay is being loaded, there is
a chance the program being loaded will overlay one of the control blocks that
DOS uses to keep track of memory blocks.
Programs loaded using function 3 should not issue any SETBLOCK calls since
they don't own the memory they are operating in. (This memory is owned by the
calling program)
Because programs loaded using function 3 are given control directly by (and
return contrrol directly to) the calling program, no memory is automatically
freed when the called program exits. It is up to the calling program to
determine the disposition of the memory that had been occupied by the exiting
program. Note that if the exiting program had itself allocated any memory, it
is responsible for freeing that memory before exiting.
MEMORY CONTROL BLOCKS
Only the first 5 bytes of the memory control block are used. The first byte
will always have the value of 4Dh or 5Ah. The value 5Ah indicates the block is
the last in a chain, all memory above it is unused. 4Dh means that the block is
intermediate in a chain, the memory above it belongs to the next program or to
DOS.
The next two bytes hold the PSP segment address of the program that owns the
corresponding block of memory. A value of 0 means the block is free to be
claimed, any other value represents a segment address. Bytes 3 and 4 indicate
the size in paragraphs of the memory block. If you know the address of the first
block, you can find the next block by adding the length of the memory block plus
1 to the segment address of the control block.
Finding the first block can be difficult, as this varies according to the DOS
version and the configuration.
The remaining 11 bytes are not currently used by DOS, and may contain "trash"
characters left in memory from previous applications.
If DOS determines that the allocation chain of memory control blocks has been
corrupted, it will halt the system and display the message "Memory Allocation
Error", and the system will halt, requiring a reboot.
Each memory block consists of a signature byte (4Dh or 5Ah) then a word which
is the PSP value of the owner of the block (which allocated it), followed by a
word which is the size in paragraphs of the block. The last block has a
signature of 5Ah. All others have 4Dh. If the owner is 0000 then the block is
free.
User memory is allocated from the lowest end of available memory that will
satisfy the request for memory.

View file

@ -0,0 +1,448 @@
CHAPTER 7
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
DOS File Structure
File Management Functions
Use DOS function calls to create, open, close, read, write, rename, find, and
erase files. There are two sets of function calls that DOS provides for support
of file management. They are:
* File Control Block function calls (0Fh-24h)
* Handle function calls (39h-62h)
Handle function calls are easier to use and are more powerful than FCB calls.
Microsoft recommends that the handle function calls be used when writing new
programs. DOS 3.0 up have been curtailing use of FCB function calls; it is
possible that future versions of DOS may not support FCB function calls.
The following table compares the use of FCB calls to Handle function calls:
FCB Calls Handle Calls
Access files in current Access files in ANY directory
directory only.
Requires the application Does not require use of an FCB.
program to maintain a file Requires a string with the drive,
control block to open, path, and filename to open, create,
create, rename or delete rename, or delete a file. For file
a file. For I/O requests, I/O requests, the application program
the application program must maintain a 16 bit file handle
also needs an FCB that is supplied by DOS.
The only reason an application should use FCB function calls is to maintain
the ability to run under DOS 1.x. To to this, the program may use only function
calls 00h-2Eh.
FCB FUNCTION CALLS
FCB function calls require the use of one File Control Block per open file,
which is maintained by the application program and DOS. The application program
supplies a pointer to the FCB and fills in ther appropriate fields required by
the specific function call. An FCB function call can perform file management on
any valid drive, but only in the current logged directory. By using the current
block, current record, and record length fields of the FCB, you can perform
sequential I/O by using the sequential read or write function calls. Random I/O
can be performed by filling in the random record and record length fields.
Several possible uses of FCB type calls are considered programming errors and
should not be done under any circumstances to avoid problems with file sharing
and compatibility with later versions of DOS.
Some errors are:
1) If program uses the same FCB structure to access more than one open file. By
opening a file using an FCB, doing I/O, and then replacing the filename field
in the file control block with a new filename, a program can open a second
file using the same FCB. This is invalid because DOS writes control info-
rmation about the file into the reserved fields of the FCB. If the program
then replaces the filename field with the original filename and then tries to
perform I/O on this file, DOS may become confused because the control info-
rmation has been changed. An FCB should never be used to open a second file
without closing the one that is currently open. If more than one File Control
Block is to be open concurrently, separate FCBs should be used.
2) A program should never try to use the reserved fields in the FCB, as the
function of the fields changes with different versions of DOS.
3) A delete or a rename on a file that is currently open is considered an error
and should not be attempted by an application program.
It is also good programming practice to close all files when I/O is done. This
avoids potential file sharing problems that require a limit on the number of
files concurrently open using FCB function calls.
HANDLE FUNCTION CALLS
The recommended method of file management is by using the extended "handle"
set of function calls. These calls are not restricted to the current directory.
Also, the handle calls allow the application program to define the type of
access that other processes can have concurrently with the same file if the file
is being shared.
To create or open a file, the application supplies a pointer to an ASCIIZ
string giving the name and location of the file. The ASCIIZ string contains an
optional drive letter, optional path, mandatory file specification, and a
terminal byte of 00h. The following is an example of an ASCIIZ string:
format [drive][path] filename.ext,0
DB "A:\path\filename.ext",0
If the file is being created, the application program also supplies the
attribute of the file. This is a set of values that defines the file read
only, hidden, system, directory, or volume label.
If the file is being opened, the program can define the sharing and access
modes that the file is opened in. The access mode informs DOS what operations
your program will perform on this file (read-only, write-only, or read/write)
The sharing mode controls the type of operations other processes may perform
concurrently on the file. A program can also control if a child process inherits
the open files of the parent. The sharing mode has meaning only if file sharing
is loaded when the file is opened.
To rename or delete a file, the appplication program simply needs to provide
a pointer to the ASCIIZ string containing the name and location of the file
and another string with the neew name if the file is being renamed.
The open or create function calls return a 16-bit value referred to as the
file handle. To do any I/O to a file, the program uses the handle to reference
the file. Once a file is opened, a program no longer needs to maintain the
ASCIIZ string pointing to the file, nor is there any need to stay in the same
directory. DOS keeps track of the location of the file regardless of what
directory is current.
Sequential I/O can be performed using the handle read (3Fh) or write (40h)
function calls. The offset in the file that IO is performed to is automatically
moved to the end of what was just read or written. If random I/O is desired, the
LSEEK (42h) function call can be used to set the offset into the file where I/O
is to be performed.
SPECIAL FILE HANDLES
DOS reserves five special file handles for use by itself and applications
programs. They are:
0000h STDIN Standard Input Device
0001h STDOUT Standard Output Device
0002h STDERR Standard Error Output Device
0003h STDAUX Standard Auxiliary Device
0004h STDPRN Standard Printer Device
These handles are predefined by DOS and can be used by an application program.
They do not need to be opened by a program, although a program can close these
handles. STDIN should be treated as a read-only file, and STDOUT and STDERR
should be treated as write-only files. STDIN and STDOUT can be redirected. All
handles inherited by a process can be redirected, but not at the command line.
These handles are very useful for doing I/O to and from the console device.
For example, you could read input from the keyboard using the read (3Fh)
function call and file handle 0000h (STDIN), and write output to the console
screen with the write function call (40h) and file handle 0001h (STDOUT). If
you wanted an output that could not be redirected, you could output it using
file handle 0002h (STDERR). This is very useful for error messages that must
be seen by a user.
File handles 0003h (STDAUX) and 0004h (STDPRN) can be both read from and
written to. STDAUX is typically a serial device and STDPRN is usually a parallel
device.
ASCII and BINARY MODE
I/O to files is done in binary mode. This means that the data is read or
written without modification. However, DOS can also read or write to devices in
ASCII mode. In ASCII mode, DOS does some string processing and modification to
the characters read and written. The predefined handles are in ASCII mode when
initialized by DOS. All other file handles that don't refer to devices are in
binary mode. A program, can use the IOCTL (44h) function call to set the mode
that I/O is to a device. The predefined file handles are all devices, so the
mode can be changed from ASCII to binary via IOCTL. Regular file handles that
are not devices are always in binary mode and cannot be changed to ASCII mode.
The ASCII/BINARY bit was called "raw" in DOS 2.x, but it is called ASCII/BINARY
in DOS 3.x.
The predefined file handles STDIN (0000h) and STDOUT (0001h) and STDERR
(0002h) are all duplicate handles. If the IOCTL function call is used to change
the mode of any of these three handles, the mode of all three handles is
changed. For example, if IOCTL was used to change STDOUT to binary mode, then
STDIN and STDERR would also be changed to binary mode.
FILE I/O IN BINARY (RAW) MODE
The following is true when a file is read in binary mode:
1) The characters ^S (scroll lock), ^P (print screen), ^C (control break) are
not checked for during the read. Therefore, no printer echo occurs if ^S or
^P are read.
2) There is no echo to STDOUT (0001h).
3) Read the number of specified bytes and returns immediately when the last
byte is received or the end of file reached.
4) Allows no editing of the ine input using the function keys if the input is
from STDIN (0000h).
The following is true when a file is written to in binary mode:
1) The characters ^S (scroll lock), ^P (print screen), ^C (control break) are
not checked for during the write. Therefore, no printer echo occurs.
2) There is no echo to STDOUT (0001h).
3) The exact number of bytes specified are written.
4) Does not caret (^) control characters. For example, ctrl-D is sent out as
byte 04h instead of the two bytes ^ and D.
5) Does not expand tabs into spaces.
FILE I/O IN ASCII (COOKED) MODE
The following is true when a file is read in ASCII mode:
1) Checks for the characters ^C,^S, and ^P.
2) Returns as many characters as there are in the device input buffer, or the
number of characters requested, whichever is less. If the number of
characters requested was less than the number of characters in the device
buffer, then the next read will address the remaining characters in the
buffer.
3) If there are no more bytes remaining in the device input buffer, read a
line (terminated by ^M) into the buffer. This line may be edited with the
function keys. The characters returned terminated with a sequence of 0Dh,
0Ah (^M,^J) if the number of characters requested is sufficient to include
them. For example, if 5 characters were requested, and only 3 were entered
before the carriage return (0Dh or ^M) was presented to DOS from the console
device, then the 3 characters entered and 0Dh and 0Ah would be returned.
However, if 5 characters were requested and 7 were entered before the
carriage return, only the first 5 characters would be returned. No 0Dh,0Ah
sequence would be returned in this case. If less than the number of
characters requested are entered when the carriage return is received, the
characters received and 0Dh,0Ah would be returned. The reason the 0Ah
(linefeed or ^J) is added to the returned characters is to make the devices
look like text files.
4) If a 1Ah (^Z) is found, the input is terminated at that point. No 0Dh,0Ah
(CR,LF) sequence is added to the string.
5) Echoing is performed.
6) Tabs are expanded.
The following is true when a file is written to in ASCII mode:
1) The characters ^S,^P,and ^C are checked for during the write operation.
2) Expands tabs to 8-character boundaries and fills with spaces (20h).
3) Carets control characters, for example, ^D is written as two bytes, ^ and D.
4) Bytes are output until the number specified is output or a ^Z is
encountered. The number actually output is returned to the user.
NUMBER OF OPEN FILES ALLOWED
The number of files that can be open concurrently is restricted by DOS. This
number is determined by how the file is opened or created (FCB or handle
function call) and the number specified by the FCBS and FILES commands in the
CONFIG.SYS file. The number of files allowed open by FCB function calls and the
number of files that can be opened by handle type calls are independent of one
another.
RESTRICTIONS ON FCB USAGE
If file sharing is not loaded using the SHARE command, there are no
restrictions on the nuumber of files concurrently open using FCB function calls.
However, when file sharing is loaded, the maximum number of FCBs open is set
by the the FCBS command in the CONFIG.SYS file.
The FCBS command has two values you can specify, 'm' and 'n'. The value for
'm' specifies the number of files that can be opened by FCBs, and the value 'n'
specifies the number of FCBs that are protected from being closed.
When the maximum number of FCB opens is exceeded, DOS automatically closes the
least recently used file. Any attempt to access this file results in an int 24h
critical error message "FCB not availible". If this occurs while an application
program is running, the value specified for 'm' in the FCBS command should be
increased.
When DOS determines the least recently used file to close, it does not include
the first 'n' files opened, therefore the first 'n' files are protected from
being closed.
RESTRICTIONS ON HANDLE USAGE
The number of files that can be open simultaneously by all processes is
determined by the FILES command in the CONFIG.SYS file. The number of files a
single process can open depends on the value specified for the FILES command. If
FILES is greater than or equal to 20, a single process can open 20 files. If
FILES is less than 20, the process can open less than 20 files. This value
includes three predefined handles: STDIN, STDOUT, and STDERR. This means only
17 additional handles can be added. DOS 3.3 includes a function to use more than
20 files per application.
ALLOCATING SPACE TO A FILE
Files are not nescessarily written sequentially on a disk. Space is allocated
as needed and the next location availible on the disk is allocated as space for
the next file being written. Therefore, if considerable file generation has
taken place, newly created files will not be written in sequential sectors.
However, due to the mapping (chaining) of file space via the File Allocation
Table (FAT) and the function calls availible, any file may be used in either a
sequential or random manner.
Space is allocated in increments called clusters. Cluster size varies
according to the media type. An application program should not concern itself
with the way that DOS allocates space to a file. The size of a cluster is only
important in that it determines the smallest amount of space that can be
allocated to a file. A disk is considered full when all clusters have been
allocated to files.
MSDOS / PCDOS DIFFERENCES
There is a problem of compatibility between MS-DOS and IBM PC-DOS having to
do with FCB Open and Create. The IBM 1.0, 1.1, and 2.0 documentation of OPEN
(call 0Fh) contains the following statement:
"The current block field (FCB bytes C-D) is set to zero [when an FCB is
opened]."
This statement is NOT true of MS-DOS 1.25 or MS-DOS 2.00. The difference is
intentional, and the reason is CP/M 1.4 compatibility. Zeroing that field is
not CP/M compatible. Some CP/M programs will not run when machine translated if
that field is zeroed. The reason it is zeroed in the IBM versions is that IBM
specifically requested that it be zeroed. This is the reason for the complaints
from some vendors about the fact that IBM MultiPlan will not run under MS-DOS.
It is probably the reason that some other IBM programs don't run under MS-DOS.
NOTE: Do what all MS/PC-DOS Systems programs do: Set every single FCB field you
want to use regardless of what the documentation says is initialized.
.EXE FILE STRUCTURE
The EXE files produced by the Linker program consist of two parts, control and
relocation information and the load module itself.
The control and relocation information, which is described below, is at the
beginning of the file in an area known as the header. The load module
immediately follows the header. The load module begins in the memory image of
the module contructed by the Linker.
When you are loading a file with the name *.EXE, DOS does NOT assume that it
is an EXE format file. It looks at the first two bytes for a signature telling
it that it is an EXE file. If it has the proper signature, then the load
proceeds. Otherwise, it presumes the file to be a .COM format file.
If the file has the EXE signature, then the internal consistency is checked.
Pre-2.0 versions of MSDOS did not check the signature byte for EXE files.
The .EXE format can support programs larger than 64K. It does this by
allowing separate segments to be defined for code, data, and the stack, each
of which can be up to 64K long. Programs in EXE format may contain explicit
references to segment addresses. A header in the EXE file has information for
DOS to resolve these references.
The .EXE header is formatted as follows:
ÚÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Offset ³ C O N T E N T S ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 00h ³ 4Dh ³ This is the Linker's signature to mark the file as a valid ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄ´ .EXE file (The ASCII letters M and Z, for Mark Zbikowski, ³
³ 01h ³ 5Ah ³ one of the major designers of DOS at Microsoft) ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 02h-03h ³ Length of the image mod 512 (remainder after dividing the load ³
³ ³ module image by 512) ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 04h-05h ³ Size of the file in 512 byte pages including the header. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 06h-07h ³ Number of relocation table items. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 08h-09h ³ Size of the header in 16 byte increments (paragraphs). This is ³
³ ³ used to locate the beginning of the load module in the file. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0Ah-0Bh ³ Minimum number of 16 byte paragraphs required above the end of ³
³ ³ the loaded program. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0Ch-0Dh ³ Maximum number of 16 byte paragraphs required above the end of ³
³ ³ the loaded program. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0Eh-0Fh ³ Displacement in paragraphs of stack segment within load module. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 10h-11h ³ Offset to be in SP register when the module is given control. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 12h-13h ³ Word Checksum - negative sum of all the words in the file, ³
³ ³ ignoring overflow. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 14h-15h ³ Offset to be in the IP register when the module is given control. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 16h-17h ³ Displacement in paragraphs of code segment within load module. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 18h-19h ³ Displacement in bytes of the first relocation item in the file. ³
ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1Ah-1Bh ³ Overlay number (0 for the resident part of the program) ³
ÀÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
THE RELOCATION TABLE
The word at 18h locates the first entry in the relocation table. The
relocation table is made up of a variable number of relocation items. The number
of items is contained at offset 06-07. The relocation item contains two fields
- a 2 byte offset value, followed by a 2 byte segment value. These two fields
represent the displacement into the load module before the module is given
control. The process is called relocation and is accomplished as follows:
1. A Program Segment Prefix is built following the resident portion of the
program that is performing the load operation.
2. The formatted part of the header is read into memory (its size is at
offset 08-09)
3. The load module size is determined by subtracting the header size from the
file size. Offsets 04-05 and 08-09 can be used for this calculation. The
actual size is downward adjusted based on the contents of offsets 02-03.
Note that all files created by the Linker programs prior to version 1.10
always placed a value of 4 at this location, regardless of the actual
program size. Therefore, Microsoft recommends that this field be ignored if
it contains a value of 4. Based on the setting of the high/low loader switch,
an appropriate segment is determined for loading the load module. This
segment is called the start segment.
4. The load module is read into memory beginning at the start segment. The
relocation table is an ordered list of relocation items. The first relocation
item is the one that has the lowest offset in the file.
5. The relocation table items are read into a work area one or more at a time.
6. Each relocation table item segment value is added to the start segment value.
The calculated segment, in conjunction with the relocation item offset value,
points to a word in the load module to which is added the start segment
value. The result is placed back into the word in the load module.
7. Once all the relocation items have been processed, the SS and SP registers
are set from the values in the header and the start segment value is added
to SS. The ES and DS registers are set to the segment address of the program
segment prefix. The start segment value is added to the header CS register
value. The result, along with the header IP value, is used to give the
module control.
"NEW" .EXE FORMAT (Microsoft Windows and OS/2)
The "old" EXE format is documented here. The "new" EXE format puts more
information into the header section and is currently used in applications that
run under Microsoft Windows. The linker that creates these files comes with the
Microsoft Windows Software Development Kit and is called LINK4. If you try to
run a Windows-linked program under DOS, you will get the error message "This
program requires Microsoft Windows".

View file

@ -0,0 +1,611 @@
CHAPTER 8
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
DOS DISK INFORMATION
THE DOS AREA
All disks and diskettes formatted by DOS are created with a sector size of 512
bytes. The DOS area (entire area for a diskette, DOS partition for hard disks)
is formatted as follows:
Boot record - 1 sector
First copy of the FAT - variable size
Second copy of the FAT - same size as first copy
Root directory - variable size
Data area
The following sections describe each of the allocated areas:
THE BOOT RECORD
The boot record resides on track 0, sector 1, side 0 of every diskette
formatted by the DOS FORMAT program. It is put on all disks to provide an error
message is you try to start up with a nonsystem disk in drive A:. For hard disks
the boot record resides on the first sector of the DOS partition.
THE DOS FILE ALLOCATION TABLE (FAT)
This section explains how DOS uses the FAT to convert the clusters of a file
into logical sector numbers. We recommend that system utilities use the DOS
handle calls rather than interpreting the FAT.
The FAT is used by DOS to allocate disk space for files, one cluster at a time.
The FAT consists of a 12 bit entry (1.5 bytes) for each cluster on the disk or
a 16 bit (2 bytes) entry when a hard disk has more than 20740 sectors as is the
case with fixed disks larger than 10Mb.
The first two FAT entries map a portion of the directory; these FAT entries
contain indicators of the size and format of the disk. The FAT can be in a 12
or 16 bit format. DOS determines whether a disk has a 12 or 16 bit FAT by
looking at the total number of allocation units on a disk. For all diskettes
and hard disks with DOS partitions less than 20,740 sectors, the FAT uses a 12
bit value to map a cluster. For larger partitions, DOS uses a 16 bit value.
The second, third, and fourth bit applicable for 16 bit FAT bytes always
contains 0FFFFh. The first byte is used as follows:
hex value meaning normally used
0F8h hard disk bootable hard disk at C:800
double sided 18 sector diskette PS/2 1.44 meg DSQD
0F9h double sided 15 sector diskette AT 1.2 meg DSQD
double sided 9 sector diskette Convertible 720k DSHD
0FCh single sided 9 sector diskette DOS 2.0, 180k SSDD
0FDh double sided 9 sector diskette DOS 2.0, 360k DSDD
0FEh single sided 8 sector diskette DOS 1.0, 160k SSDD
0FFh double sided 8 sector diskette DOS 1.1, 320k SSDD
The third FAT entry begins mapping the data area (cluster 002).
NOTE: These values are provided as a reference. Therefore, programs should not
make use of these values.
Each entry contains a hexadecimal character (or 4 for 16 bit FATs). ()
indicates the high order four bit value in the case of 16 bit FAT entries.
They can be:
(0)000h if the cluster is unused and availible
(0F)FF8h - (0F)FFFh to indicate the last cluster of a file
(X)XXXh any other hexadecimal numbers that are the cluster number
of the next cluster in the file. The cluster number is the
first cluster in the file that is kept in the file's
directory entry.
The values (0F)FF0h - (0F)FF7h are used to indicate reserved clusters.
(0F)FF7h indicates a bad cluster if it is not part of the allocation chain.
(0F)FF8h - (0F)FFFh are used as end of file markers.
The file allocation table always occupies the sector or sectors immediately
following the boot record. If the FAT is larger than 1 sector, the sectors
occupy consecutive sector numbers. Two copies of the FAT are written, one
following the other, for integrity. The FAT is read into one of the DOS buffers
whenever needed (open, allocate more space, etc).
USE OF THE 12 BIT FILE ALLOCATION TABLE
Obtain the starting cluster of the file from the directory entry.
Now, to locate each subsequent sector of the file:
1. Multiply the cluster number just used by 1.5 (each FAT entry is 1.5
bytes long).
2. The whole part of the product is offset into the FAT, pointing to the entry
that maps the cluster just used. That entry contains the cluster number of
the next cluster in the file.
3. Use a MOV instruction to move the word at the calculated FAT into a register.
4. If the last cluster used was an even number, keep the low order 12 bits of
the register, otherwise, keep the high order 12 bits.
5. If the resultant 12 bits are (0FF8h-0FFFh) no more clusters are in the file.
Otherwise, the next 12 bits contain the cluster number of the next cluster in
the file.
To convert the cluster to a logical sector number (relative sector, such as
that used by int 25h and 26h and DEBUG):
1. Subtract 2 from the cluster number
2. Multiply the result by the number of sectors per cluster.
3. Add the logical sector number of the beginning of the data area.
USE OF THE 16 BIT FILE ALLOCATION TABLE
Obtain the starting cluster of the file from the directory entry. Now to
locate each subsequent cluster of the file:
1. Multiply the cluster number used by 2 (each FAT entry is 2 bytes long).
2. Use the MOV word instruction to move the word at the calculated FAT offset
into a register.
3. If the resultant 16 bits are (0FF8h-0FFFFh) no more clusters are in the
file. Otherwise, the 16 bits contain the cluster number of the next cluster
in the file.
Compaq DOS makes availible a new disk type (6) with 32 bit partition values,
allowing 512 megabytes per hard disk (Compaq DOS 3.3.1)
DOS DISK DIRECTORY
The FORMAT command initially builds the root directory for all disks. Its
location (logical sector number) and the maximum number of entries are
availible through the device driver interfaces.
DIRECTORY ENTRIES
Since directories other than the root directory are actually files, there is
no limit to the number of entries that they may contain.
All directory entries are 32 bytes long, and are in the following format (byte
and offset are decimal). The following paragraphs describe the directory entry
bytes:
*BYTES 0-7
Bytes 0-7 represent the filename. The first byte of the filename indicates the
status of the filename. The status of a filename can contain the following
values:
00h Filename never used. This is used to limit the length of directory
searches, for performance reasons.
05h Indicates that the first character of the filename actually has an 0Edh
character.
0E5h Filename has been used but the file has been erased.
2Eh This entry is for a directory. If the second byte is also 2Eh, the
cluster field contains the cluster number of this directory's parent
directory. (0000h if the parent directory is the root directory).
Any other character is the first character of a filename.
*BYTES 8-10
These bytes indicate the filename extension.
*BYTE 11
This byte indicates the file's attribute. The attribute byte is mapped as
follows (values are in hexadecimal):
NOTE: Attributes 08h and 10h cannot be changed using function call 43h (CHMOD).
The system files IBMBIO.COM and IBMDOS.COM (or customized equivalent) are
marked as read-only, hidden, and system files. Files can be marked hidden when
they are created. Also, the read-only, hidden, and system and archive attributes
may be changed through the CHMOD function call.
01h Indicates that the file is marked read-only. An attempt to open the file
for output using function call 3Dh results in an error code being returned.
This value can be used with other values below.
02h Indicates a hidden file. The file is excluded from normal directory
searches.
04h Indicates a system file. This file is excluded from normal directory
searches.
08h Indicates that the entry contains the volume label in the first 11 bytes.
The entry contains no other usable information and may exist only in the
root directory.
20h Indicates an archive bit. This bit is set on whenever the file is written
to and closed. It is used by BACKUP and RESTORE.
All other bits are reserved, and must be 0.
*BYTES 12-21
reserved by DOS
*BYTES 22-23
These bytes contain the time when the file was created or last updated. The
time is mapped in the bits as follows:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ B Y T E 23 ³ B Y T E 22 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ F E D C B A 9 8 ³ 7 6 5 4 3 2 1 0 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ H H H H H ³ M M M M M M ³ D D D D D ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ binary # hrs 0-23 ³ binary # minutes 0-59 ³ bin. # 2-sec incr ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
NOTE: The time is stored with the least significant byte first.
*BYTES 24-25
This area contains the date when the file was created or last updated. The
mm/dd/yy are mapped in the bits as follows:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ B Y T E 25 ³ B Y T E 24 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ F E D C B A 9 8 ³ 7 6 5 4 3 2 1 0 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ Y Y Y Y Y Y Y ³ M M M M ³ D D D D D ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 0-119 (1980-2099) ³ 1-12 ³ 1-31 ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
NOTE: The date is stored with the least significant byte first.
*BYTES 26-27
This area contains the starting cluster number of the first cluster in the
file. The first cluster for data space on all fixed disks and floppy disks is
always cluster 002. The cluster number is stored with the least significant
byte first.
*BYTES 28-31
This area contains the file size in bytes. The first word contains the low
order part of the size. Both words are stored with the least significant byte
first.
File Allocation Table
offset size description
3 8 bytes system id (such as IBM 3.3)
11 2 bytes number of bytes per sector, ie 512 bytes is 200h
13 1 byte sectors per cluster (1 or 2)
14 2 bytes number of reserved sectors at beginning, 1 for floppies
16 1 byte number of copies of FAT, 2 for floppies
17 2 bytes number of root directory entries (64, 112, 256,etc)
19 2 bytes total sectors per disk
21 1 byte format ID (F8, F9, FC, FF, etc)
22 2 bytes number of sectors per FAT (1 or 2)
24 2 bytes number of sectors per track (8 or 9, 17)
26 2 bytes number of sides, heads, or cylinders (1 or 2 for floppy)
28 2 bytes number of special reserved sectors
THE DATA AREA
Allocation of space for a file (in the data area) is done only when needed
(it is not preallocated). The space is allocated one cluser (unit allocation)
at a time. A cluster is always one or more consecutive sector numbers, and all
of the clusters in a file are "chained" together in the FAT.
The clusters are arranged on disk to minimize head movement for multisided
media. All of the space on a track (or cylinder) is allocated before moving
on to the next track. This is accomplished by using the sequential sector
numbers on the lowest-numbered head, then all the sector numbers on the next
head, and so on until all sectors of all heads of the track are used. Then the
next sector used will be sector 1 of head 0 on the next track.
An interesting innovation that was introduced in MS-DOS 3.0: disk space that
is freed by erasing a file is not re-used immediately, unlike earlier versions
of DOS. Instead, free space is obtained from the area not yet used during the
current session, until all of it is used up. Only then will space that is freed
during the current session be re-used.
This feature minimizes fragmentation of files, since never-before-used space
is always contiguous. However, once any space has been freed by deleting a file,
that advantage vanishes at the next system boot. The feature also greatly
simplifies un-erasing files, provided that the need to do an un-erase is found
during the same session and also provided that the file occupies contiguous
clusters.
However, when one is using programs which make extensive use of temporary
files, each of which may be created and erased many times during a session,
the feature becomes a nuisance; it forces the permanent files to move farther
and farther into the inner tracks of the disk, thus increasing rather than
decreasing the amount of fragmentation which occurs.
The feature is implemented in DOS by means of a single 16-bit "last cluster
used" (LCU) pointer for each physical disk drive; this pointer is a part of
the physical drive table maintained by DOS. At boot time, the LCU pointer is
zeroed. Each time another cluster is obtained from the free-space pool (the
FAT), its number is written into the LCU pointer. Each time a fresh cluster
is required, the FAT is searched to locate a free one; in older versions of
DOS this search always began at Cluster 0000, but in 3.x it begins at the
cluster pointed to by the LCU pointer.
For hard disks, the size of the file allocation table and directory are
determined when FORMAT initializes it and are based on the size of the DOS
partition.
The following table gives the specifications for floppy disk formats:
# of sectors FAT size DIR DIR sectors total
disk DOS ver sides /track (sectors) (sectors) (entries) /cluster sectors
(5-1/4 inch)
160k (DOS 1.0) 1 8 (40) 1 4 64 1 320
320k (DOS 1.1) 2 8 (40) 1 7 112 2 360
180k (DOS 2.0) 1 9 (40) 2 4 64 1 640
360k (DOS 2.0) 2 9 (40) 2 7 112 2 720
1.2M (DOS 3.0) 2 15 (80) 7 14 224 1 2400
(3-1/2 inch)
720k (DOS 3.2) 2 9 (80) 3 7 112 2 1440
1.44M(DOS 3.3) 2 18 (80) 9 14 224 1 2880
Files in the data area are not nescessarily written sequentially on the first.
The data area space is allocated one cluster at a time, skipping over clusters
already allocated. The first free cluster found is the next cluster allocated,
regardless of its physical location on the disk. This permits the most efficient
utilization of disk space because clusters freed by erasing files can be
allocated for new files. Refer back to the description of the DOS FAT in this
chapter for more information.
Hard Disk Layout
The DOS hard disk routines perform the following services:
1) Allow multiple operating systems to utilize the hard disk without the need
to backup and restore files when changing operating systems.
2) Allow a user-selected operating system to be started from the hard disk.
I) In order to share the hard disk among operating systems, the disk may be
logically divided into 1 to 4 partitions. The space within a given
partition is contiguous, and can be dedicated to a specific operating
system. Each operating system may "own" only one partition in DOS versions
2.0 through 3.2. PCDOS 3.3 introduced the "Extended DOS Partition" which
allows multiple DOS partitions on the same hard disk. The FDISK.COM (or
similar program from other DOS vendors) utility allows the user to select
the number, type, and size of each partition. The partition information is
kept in a partition table that is embedded in the master fixed disk boot
record on the first sector of the disk. The format of this table varies
from version to version of DOS.
II) An operating system must consider its partition to be the entire disk,
and must ensure that its functions and utilities do not access other
partitions on the disk.
III) Each partition may contain a boot record on its first sector, and any
other programs or data that you choose - including a copy of an operating
system. For example, the DOS FORMAT command may be used to format and
place a copy of DOS in the DOS partition in the same manner that a
diskette is formatted. With the FDISK utility, you may designate a
partition as "active" (bootable). The master hard disk boot record causes
that partition's boot record to receive control when the system is started
or reset. Additional disk partitions could be FORTH, UNIX, Pick, CP/M-86,
or the UCSD p-System.
SYSTEM INITIALIZATION
The boot sequence is as follows:
1. System initialization first attempts to load an operating system from
diskette drive A. If the drive is not ready or a read error occurs, it then
attempts to read a master hard disk boot record on the first sector of the
first hard disk in the system. If unsuccessful, or if no hard disk is
present, it invokes ROM BASIC in an IBM PC or displays a disk error
message on most compatibles.
2. If initialization is successful, the master hard disk boot record is given
control and it examines the partition table embedded within it. If one of
the entries indicates an active (bootable) partition, its boot record is
read from the partition's first sector and given control.
3. If none of the partitions is bootable, ROM BASIC is invoked on an IBM PC or
a disk error on most compatibles.
4. If any of the boot indicators are invalid, or if more than one indicator is
marked as bootable, the message INVALID PARTITION TABLE is displayed and the
system stops.
5. If the partition's boot record cannot be successfully read within five
retries due to read errors, the message ERROR LOADING OPERATING SYSTEM
appears and the system stops.
6. If the partition's boot record does not contain a valid "signature", the
message MISSING OPERATING SYSTEM appears, and the system stops.
NOTE: When changing the size or location of any partition, you must ensure that
all existing data on the disk has been backed up. The partitioning program
will destroy the data on the disk.
BOOT RECORD/PARTITION TABLE
A boot record must be written on the first sector of all hard disks, and
must contain the following:
1. Code to load and give control to the boot record for one of four possible
operating systems.
2. A partition table at the end of the boot record. Each table entry is 16
bytes long, and contains the starting and ending cylinder, sector, and head
for each of four possible partitions, as well as the number of sectors
preceding the partition and the number of sectors occupied by the partition.
The "boot indicator" byte is used by the boot record to determine if one of
the partitions contains a loadable operating system. FDISK initialization
utilities mark a user-selected partition as "bootable" by placing a value
of 80h in the corresponding partition's boot indicator (setting all other
partitions' indicators to 0 at the same time). The presence of the 80h tells
the standard boot routine to load the sector whose location is contained in
the following three bytes. That sector is the actual boot record for the
selected operating system, and it is responsible for the remainder of the
system's loading process (as it is from the diskette). All boot records are
loaded at absolute address 0:7C00.
The partition table with its offsets into the boot record is:
(except for Wyse DOS 3.2 with 32 bit allocation table, and DOS 3.3-up)
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿
³ Offset / Purpose ³ ³ Head ³ Sector ³ Cylinder ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³ 1BEh partition 1 begin ³ boot ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³ 1C2h partition 1 end ³ syst ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´
³ 1C6h partition 1 relative sector ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1CAh partition 1 # sectors ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ´
³ 1CEh partition 2 begin ³ boot ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³ 1D2h partition 2 end ³ syst ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´
³ 1D6h partition 2 relative sector ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1DAh partition 2 # sectors ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ´
³ 1DEh partition 3 begin ³ boot ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³ 1E2h partition 3 end ³ syst ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´
³ 1E6h partition 3 relative sector ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1EAh partition 3 # sectors ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ´
³ 1EEh partition 4 begin ³ boot ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ´
³ 1F2h partition 4 end ³ syst ind ³ H ³ S ³ cyl ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄ´
³ 1F6h partition 4 relative sector ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 1FAh partition 4 # sectors ³ low word ³ high word ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ 1FEh signature ³ hex 55 ³ hex AA ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ
HARD DISK TECHNICAL INFORMATION
Boot indicator (boot ind): The boot indicator byte must contain 0 for a non-
bootable partition or 80h for a bootable partition. Only one partition can be
marked as bootable at a time.
System Indicator (sys ind): The sys ind field contains an indicator of the
operating system that "owns" the partition.
The system indicators are:
00h unknown (unspecified or non-DOS)
01h DOS 12 bit FAT
02h DOS 16 bit FAT
Cylinder (CYL) and Sector (S): The 1 byte fields labelled CYL contain the low
order 8 bits of the cylinder number - the high order 2 bits are in the high
order 2 bits of the sector (S) field. This corresponds with the ROM BIOS
interrupt 13h (disk I/O) requirements, to allow for a 10 bit cylinder number.
The fields are ordered in such a manner that only two MOV instructions are
required to properly set up the DX and CX registers for a ROM BIOS call to
load the appropriate boot record (hard disk booting is only possible from the
first hard disk in the system, where a BIOS drive number of 80h corresponds
to the boot indicator byte).
All partitions are allocated in cylinder multiples and begin on sector 1,
head 0.
EXCEPTION: The partition that is allocated at the beginning of the disk starts
at sector 2, to account for the hard disk's master boot record.
Relative Sector (rel sect): The number of sectors preceding each partition
on the disk is kept in the 4 byte field labelled "rel sect". This value is
obtained by counting the sectors beginning with cylinder 0, sector 1, head 0
of the disk, and incrementing the sector, head, and then track values up to
the beginning of the partition. This, if the disk has 17 sectors per track and
4 heads, and the second partition begins at cylinder 1, sector 1, head 0,and
the partition's starting relative sector is 68 (decimal) - there were 17
sectors on each of 4 heads on 1 track allocated ahead of it. The field is stored
with the least significant word first.
Number of sectors (#sects): The number of sectors allocated to the partition
is kept in the "# of sects" field. This is a 4 byte field stored least
significant word first.
Signature: The last 2 bytes of the boot record (55AAh) are used as a signature
to identify a valid boot record. Both this record and the partition boot record
are required to contain the signature at offset 1FEh.
The master disk boot record invokes ROM BASIC if no indicator byte reflects a
bootable system.
When a partition's boot record is given control. It is passed its partition
table entry address in the DS:SI registers.
DETERMINING FIXED DISK ALLOCATION
DOS determines disk allocation using the following formula:
D * BPD
TS - RS - ÄÄÄÄÄÄÄÄÄÄÄ
BPS
SPF = ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BPS * SPC
CF + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BPC
where:
TS total sectors on disk
RS the number of sectrs at the beginning of the disk that are reserved
for the boot record. DOS reserves 1 sector.
D The number of directory entries in the root directory.
BPD the number of bytes per directory entry. This is always 32.
BPS the number of bytes per logical sector. Typically 512, but you can
specify a different number with VDISK.
CF The number of FATS per disk. Usually 2. VDISK is 1.
SPF the number of sectors per FAT. Maximum 64.
SPC The number of sectors per allocation unit.
BPC the number of bytes per FAT entry. BPC is 1.5 for 12 bit FATs.
2 for 16 bit FATS.
To calculate the minimum partition size that will force a 16-bit FAT:
CYL = (max clusters * 8)/(HEADS * SPT)
where:
CYL number of cylinders on the disk
max clusters 4092 (maximum number of clusters for a 12 bit FAT)
HEADS number of heads on the hard disk
SPT sectors per track (normally 17 on MFM)
note: DOS 2.0 uses a "first fit" algorithm when allocating file space on the
hard disk. Each time an application requests disk space, it will scan from the
beginning of the FAT until it finds a contiguous peice of storage large enough
for the file.
DOS 3.0 keeps a pointer into the disk space, and begins its search from the
point it last left off. This pointer is lost when the system is rebooted.
This is called the "next fit" algorithm. It is faster than the first fit and
helps minimize fragmentation.
In either case, if the FCB function calls are used instead of the handle
function calls, the file will be broken into peices starting with the first
availible space on the disk.
Comment to 826. Comment(s).
----------
Better late than never...
A partition table entry for the IBM AT is set up as follows:
DB drive ; 0 or 80H, 80H marks a bootable, active partition
DB head1 ; starting heads
DW trksec1 ; starting track/sector (CX value for INT 13)
DB system ; see below
DB head2 ; ending head
DW trksec2 ; ending track/sector
DD sector1 ; absolute # of starting sector
DD sector2 ; absolute # of last sector
The system byte is different for different O/S entries:
1 DOS, 12-bit FAT entries
4 DOS, 16-bit FAT entries
DB Concurrent DOS
F2 2nd partition for Sperry machines with large disks
And so on. There are bytes for XENIX, Prologue and lots of other O/S.
Many manufacturers diddle with these system bytes to implement more than 1 DOS
partition per disk. The only one I know about who violates the rule that only
one DOS partition (1 or 4) per disk may exist is Tandon.

View file

@ -0,0 +1,758 @@
CHAPTER 9
Programming Technical Reference - IBM
Copyright 1988, Dave Williams
INSTALLABLE DEVICE DRIVERS
DEVICE DRIVER FORMAT
A device driver is a COM or EXE file that contains all of the code needed to
control an add-in device. It has a special header to identify it as a device,
define the strategy and interrupt entry points, and define its various
attributes.
NOTE: For device drivers the COM file must not use the ORG 100h. Since the
driver does not use the program segment prefix, it is simply loaded
without offset. Therefore the memory image file must have an origin of 0
(ORG 0 or no ORG statement).
TYPES OF DEVICES
There are two types of devices: Character devices and Block devices. Their
attributes are as follows:
Character devices are designed to do character I/O in a serial manner like
CON, AUX, and PRN. These devices have names like CON, AUX, CLOCK$, and you can
open channels (handles or FCBs) to do input and output with them. Because
character devices have only one name, they can only support one device.
Block devices are the fixed disk or diskette drives on a system. They can do
random I/O in peices called blocks, which are usually the physical sector
size of the disk. These devices are not named as character devices are, and
cannot be opened directly. Instead they are mapped by using the drive letters
A,B,C etc. Block devices can have units within them. In this way, a single block
driver can be responsible for one or more disk drives. For example, the first
block device driver can be responsible for drives A,B,C,and D. This means it has
four units defined and therefore takes up four drive letters. The position of
the driver in the chain of all drives determines the way in which the drive
letters correspond. For example, if the device driver is the first block driver
in the device chain, and it defines four units, then these devices are called
A,B,C, and D. If the second device driver defines three units, then those units
are E,F,and G. DOS 1.x allows 16 devices. DOS 2.x allows 63, and DOS 3.x allows
26. It is recommended that drivers limit themselves to 26 devices for
compatibility with DOS 3.x.
DOS doesn't care about the position of installed character devices versus
block devices. The installed character devices get put into the chain ahead of
resident character devices so that you can override the system's default driver
for CON etc.
Although it is sometimes beleived that installed block devices get linked into
the chain BEHIND the resident block devices, if you look at the actual device
chain, this is not true (though it is true in the sense that installed block
devices get assigned drive letters in sequence, starting with the next letter
after the last one assigned to a resident block device).
DEVICE HEADER
A device driver requires a device header at the beginning of the file. This
is the format of the device header:
Field Length
Pointer to next device header field dword
Attribute word
Pointer to device strategy routine word
Pointer to device interrupt routine word
Name/Unit field 8 bytes
POINTER TO NEXT DEVICE HEADER FIELD
The device header field is a pointer to the device header of the next device
driver. It is a doubleword field that is set by DOS at the time the device
driver is loaded. The first word is an offset and the second word is the
segment.
If you are loading only one device driver, set the device header field to -1
before loading the device. If you are loading more than one device driver, set
the first word of the device driver header to the offset of the next device
driver's header. Set the device driver header field of the last device driver
to -1.
ATTRIBUTE FIELD
The attribute field is a word field that describes the attributes of the
device driver to the system. The attributes are:
word bits (decimal)
15 1 character device
0 block device
14 1 supports IOCTL
0 doesn't support IOCTL
13 1 non-IBM format (block only)
0 IBM format
12 not documented - unknown
11 1 supports removeable media
0 doesn't support removeable media
10 reserved for DOS
through
4 reserved for DOS
3 1 current block device
0 not current block device
2 1 current NUL device
0 not current NUL device
1 1 current standard output device
0 not current standard output device
BIT 15 is the device type bit. Use it to tell the system the that driver is a
block or character device.
BIT 14 is the IOCTL bit. It is used for both character and block devices. Use
it to tell DOS whether the device driver can handle control strings
through the IOCTL function call 44h.
If a device driver cannot process control strings, it should set bit
14 to 0. This way DOS can return an error is an attempt is made through
the IOCTL function call to send or receive control strings to the
device. If a device can process control strings, it should set bit 14
to 1. This way, DOS makes calls to the IOCTL input and output device
function to send and receive IOCTL strings.
The IOCTL functions allow data to be sent to and from the device
without actually doing a normal read or write. In this way, the device
driver can use the data for its own use, (for example, setting a baud
rate or stop bits, changing form lengths, etc.) It is up to the device
to interpret the information that is passed to it, but the information
must not be treated as a normal I/O request.
BIT 13 is the non-IBM format bit. It is used for block devices only. It affects
the operation of the Get BPB (BIOS parameter block) device call.
BIT 11 is the open/close removeable media bit. Use it to tell DOS if the
device driver can handle removeable media. (DOS 3.x only)
BIT 3 is the clock device bit. It is used for character devices only. Use it
to tell DOS if your character device driver is the new CLOCK$ device.
BIT 2 is the NUL attribute bit. It is used for character devices only. Use it
to tell DOS if your character device driver is a NUL device. Although
there is a NUL device attribute bit, you cannot reassign the NUL device.
This is an attribute that exists for DOS so that DOS can tell if the NUL
device is being used.
BIT 0 are the standard input and output bits. They are used for character
& devices only. Use these bits to tell DOS if your character device
BIT 1 driver is the new standard input device or standard output device.
POINTER TO STRATEGY AND INTERRUPT ROUTINES
These two fields are pointers to the entry points of the strategy and input
routines. They are word values, so they must be in the same segment as the
device header.
NAME/UNIT FIELD
This is an 8-byte field that contains the name of a character device or the
unit of a block device. For the character names, the name is left-justified and
the space is filled to 8 bytes. For block devices, the number of units can be
placed in the first byte. This is optional because DOS fills in this location
with the value returned by the driver's INIT code.
CREATING A DEVICE DRIVER
To create a device driver that DOS can install, perform the following:
1) Create a memory image file or an EXE file with a device header at the start
of the file.
2) Originate the code (including the device header) at 0, not 100h.
3) Set the next device header field. Refer to "Pointer to Next Device Header
Attribute Field" for more information.
4) Set the attribute field of the device header. Refer to "Attribute Field" for
more information.
5) Set the entry points for the interrupt and strategy routines.
6) Fill in the name/unit field with the name of the character device or the unit
number of the block device.
DOS always processes installable character device drivers before handling the
default devices. So to install a new CON device, simply name the device CON.
Be sure to set the standard input device and standard output device bits in
the attribute field of a new CON device. The scan of the device list stops on
the first match so the installable device driver takes precedence.
NOTE: Because DOS can install the device driver anywhere in memory, care
must be taken in any FAR memory references. You should not expect that
your driver will be loaded in the same place every time.
INSTALLING DEVICE DRIVERS
DOS installs new device drivers dynamically at boot time by reading and
processing the DEVICE command in the config.sys file. For example, if you have
written a device driver called DRIVER1, to install it put this command in the
CONFIG.SYS file:
DEVICE=DRIVER1
DOS calls a device driver at its strategy entry point first, passing in a
request header the information describing what DOS wants the device driver
to do.
This strategy routine does not perform the request but rather queues the
request or saves a pointer to the request header. The second entry point is
the interrupt routine and is called by DOS immediately after the strategy
routine returns. The interrupt routine is called with no parameters. Its
function is to perform the operation based on the queued request and set up
any return infromation.
DOS passes the pointer to the request header in ES:BX. This structure consists
of a fixed length header (Request Header) followed by data pertinent to the
operation to be performed.
NOTE: It is the responsibility of the device driver to preserve the machine
state. For example, save all registers on entry and restore them on exit.
The stack used by DOS has enough room on it to save all the registers. If more
stack space is needed, it is the device driver's responsibility to allocate and
maintain another stack.
All calls to execute device drivers are FAR calls. FAR returns should be
executed to return to DOS.
INSTALLING CHARACTER DEVICES
One of the functions defined for each device is INIT. This routine is called
only once when the device is installed and never again. The INIT routine returns
the following:
A) A location to the first free byte of memory after the device driver, like a
TSR that is stored in the terminating address field. This way, the
initialization code can be used once and then thrown away to save space.
B) After setting the address field, a character device driver can set the status
word and return.
INSTALLING BLOCK DEVICES
Block devices are installed in the same way as character devices. The
difference is that block devices return additional information. Block devices
must also return:
A) The number of units in the block device. This number determines the logical
names the devices will have. For example, if the current logical device
letter is F at the time of the install call, and the block device driver INIT
routine returns three logical units, the letters G, H, and I are assigned to
the units. The mapping is determined by the position of the driver in the
device list and the number of units in the device. The number of units
returned by INIT overrides the value in the name/unit field of the device
header.
B) A pointer to a BPB (BIOS parameter block) pointer array. This is a pointer
to an array of *n* word pointers there *n* is the number of units defined.
These word pointers point to BPBs. This way, if all of the units are the
same, the entire array can point to the same BPB to save space.
The BPB contains information pertinent to the devices such as the sector
size, number of sectors per allocation unit, and so forth. The sector size of
the BPB cannot be greater than the maximum allotted size set at DOS
initialization time.
NOTE: This array must be protected below the free pointer set by the return.
C) The media descriptor byte. This byte is passed to devices so that they know
what parameters DOS is currently using for a particular drive unit.
Block devices can take several approaches. They can be *dumb* or *smart*. A
dumb device would define a unit (and therefore a BPB) for each possible media
drive combination. Unit 0=drive 0;single side, unit 1=drive 0;double side, etc.
For this approach, the media descriptor bytes would mean nothing. A smart
device would allow multiple media per unit. In this case, the BPB table
returned at INIT must define space large enough to acommodate the largest
possible medias supported (sector size in BPB must be as large as maximum
sector size DOS is currently using). Smart drivers will use the media byte to
pass information about what media is currently in a unit.
REQUEST HEADER
The request header passes the information describing what DOS wants the
device driver to do.
ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Length ³ F i e l d ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ BYTE ³ Length in bytes of the request header plus any data at end ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ BYTE ³ Unit code. The subunit the operation is for (minor device) ³
³ ³ Has no meaning for character devices. ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ Command code ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 8 BYTES ³ Deserved for DOS ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³(variable)³ Data appropriate for the operation ³
ÀÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
UNIT CODE FIELD
The unit code field identifies which unit in a block device driver the request
is for. For example, if a block device driver has three units defined, then the
possible values of the unit code field would be 0,1,and 2.
COMMAND CODE FIELD
The command code field in the request header can have the following values:
CODE FUNCTION
0 INIT
1 MEDIA CHECK (block only,NOP for character)
2 BUILD BPB (block only, NOP for character)
3 IOCTL input (called only if IOCTL bit is 1)
4 INPUT (read)
5 NONDESTRUCTIVE INPUT NO WAIT (character devices only)
6 INPUT STATUS (character devices only)
7 INPUT FLUSH (character devices only)
8 OUTPUT (write)
9 OUTPUT (write with verify)
10 OUTPUT STATUS (character devices only)
11 OUTPUT FLUSH (character devices only)
12 IOCTL OUTPUT (called only if IOCTL bit is 1)
13 DEVICE OPEN (called only if OPEN/CLOSE/RM bit is set)
14 DEVICE CLOSE (called only if OPEN/CLOSE/RM bit is set)
15 REMOVEABLE MEDIA (called only if OPEN/CLOSE/RM bit is set and
device is block)
NOTE: Command codes 13,14,and 15 are for use with DOS versions 3.x.
STATUS FIELD
The status field in the request header contains:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ D E V I C E D R I V E R S T A T U S F I E L D ³
ÃÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ B ³ 0 ³ ³
³ ³ 1 ³ ³
³ Y ³ 2 ³ ³
³ ³ 3 ³ Error message return code ³
³ T ³ 4 ³ (with bit 15=1) ³
³ ³ 5 ³ ³
³ E ³ 6 ³ ³
³ ³ 7 ³ ³
ÃÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ bit ³ 8 ³ DONE ³
ÃÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ bit ³ 9 ³ BUSY ³
ÃÄÄÄÄÄÄÄÅÄÄÄÁÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ bits ³ 10 - 14 ³ Reserved ³
ÃÄÄÄÄÄÄÄÅÄÄÄÄÂÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ bit ³ 15 ³ Error ³
ÀÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
The status word field is zero on entry and is set by the driver interrupt
routine on return.
BIT 15 is the error bit. If this bit is set, the low 8 bits of the status word
(7-0) indicate the error code.
BITS 14-10 are reserved.
BIT 9 is the busy bit. It is only set by status calls and the removable media
call. See "STATUS" and "REMOVABLE MEDIA" in this chapter for more
information about the calls.
BIT 8 is the done bit. If it is set, it means the operation is complete. The
driver sets the bit to 1 when it exits.
The low 8 bits of the status word define an error message if bit 15 is set.
These errors are:
00h Write protect violation 01h Unknown unit
02h Device not ready 03h Unknown command
04h CRC error 05h Bad drive request structure length
06h seek error 07h unknown media
08h sector not found 09h printer out of paper
0Ah write fault 0Bh read fault
0Ch general failure 0Dh reserved
0Eh reserved 0Fh invalid disk change
DEVICE DRIVER FUNCTIONS
All strategy routines are called with ES:BX pointing to the request header.
The interrupt routines get the pointers to the request header from the queue
the strategy routines store them in. The command code in the request header
tells the driver which function to perform.
NOTE: all DWORD pointers are stored offset first, then segment.
The following function call parameters are described:
INIT
MEDIA CHECK
BUILD BPB (BIOS PARAMETER BLOCK)
MEDIA DESCRIPTOR BYTE
INPUT OR OUTPUT
NONDESTRUCTIVE INPUT NO WAIT
STATUS
FLUSH
OPEN OR CLOSE
REMOVABLE MEDIA
INIT
Command code=0
ES:BX pointer to request header. Format of header:
length field
13 bytes request header
dword number of units (not set by character devices)
dword Ending address of resident program code
dword Pointer to BPB array (not set by character devices)
/pointer to remainder of arguments
byte Drive number (3x only)
The driver must do the following:
A) set the number of units (block devices only)
B) set up the pointer to the BPB array (block devices only)
C) perform any initialization code (to modems, printers, etc)
D) Set the ending address of the resident program code
E) set the status word in the request header.
To obtain information obtained from CONFIG.SYS to a device driver at INIT
time, the BPB pointer field points to a buffer containing the information
passed from CONFIG.SYS following the =. The buffer that DOS passes to the
driver at INIT after the file specification contains an ASCII string for the
file OPEN. The ASCII string (ending in 0h) is terminated by a carriage return
(0Dh) and linefeed (0Ah). If there is no parameter information after the file
specification, the file specification is immediately followed by a linefeed
(0Ah). This information is read-only and only system calls 01h-0Ch and 30h can
be issued by the INIT code of the driver.
The last byte parameter contains the drive letter for the first unit of a
block driver. For example, 0=A, 1=B etc.
If an INIT routine determines that it cannot set up the device and wants to
abort without using any memory, follow this procedure:
A) set the number of units to 0
B) set the ending offset address at 0
C) set the ending offsret segment address to the code segment (CS)
NOTE: If there are multiple device drivers in a single memory image file, the
ending address returned by the last INIT called is the one DOS uses. It is
recommended that all device drivers in a single memory image file return
the same ending address.
MEDIA CHECK
command code=1
ES:BX pointer to request header. Format of header:
length field
13 bytes request header
byte media descriptor from DOS
byte return
dword returns a pointer to the previous volume ID (if bit
11=1 and disk change is returned) (DOS 3.x)
When the command code field is 1, DOS calls MEDIA CHECK for a drive unit and
passes its current media descriptor byte. See "Media Descriptor Byte" later in
this chapter for more information about the byte. MEDIA CHECK returns one of
the following:
A) media not changed C) not sure
B) media changed D) error code
The driver must perform the following:
A) set the status word in the request header
B) set the return byte
-1 media has been changed
0 don't know if media has been changed
1 media has not been changed
DOS 3.x: If the driver has set the removable media bit 11 of the device header
attribute word to 1 and the driver returns -1 (media changed), the driver must
set the DWORD pointer to the previous volume identification field. If DOS
determines that the media changed is an error, DOS generates an error 0Fh
(invalid disk change) on behalf of the device. If the driver does not implement
volume identification support, but has bit 11 set to 1, the driver should set a
pointer to the string "NO NAME",0.
MEDIA DESCRIPTOR
Currently the media descriptor byte has been defined for a few media types.
This byte should be idetnical to the media byte if the device has the non-IBM
format bit off. These predetermined values are:
media descriptor byte => 1 1 1 1 1 0 0 0
(numerical order) 7 6 5 4 3 2 1 0
BIT MEANING
0 1=2 sided 0=not 2 sided
1 1=8 sector 0=not 8 sector
2 1=removeable 0=nonremoveable
3-7 must be set to 1
Examples of current DOS media descriptor bytes:
media sides sectors ID byte
hard disk * * 0F8h
5-1/4 floppy 2 15 0F9h
5-1/4 floppy 1 9 0FCh
5-1/4 floppy 2 9 0FDh
5-1/4 floppy 2 8 0FFh
5-1/4 floppy 1 8 0FEh
8" floppy 1 26 0FEh *
8" floppy 2 26 0FDh
8" floppy 2 8 0FEh *
*NOTE: The two Media Descriptor Bytes that are the same for 8" diskettes (0FEh)
are not a misprint. To determine whether you are using a single sided or double
sided diskette, attempt to read the second side, and if an error occurs you can
assume the diskette is single sided.
BUILD BPB (BIOS Parameter Block)
command code =2
ES:BX pointer to request header. Format:
length field
13 bytes request header
byte media descriptor from DOS
dword transfer address (buffer address)
dword pointer to BPB table
DOS calls BUILD BPB under the following two conditions:
A) If "media changed" is returned
B) If "not sure" is returned, there are no used buffers. Used buffers are
buffers with changed data that has not yet been written to the disk.
The driver must do the following:
A) set the pointer to the BPB
B) set the status word in the request header.
The driver must determine the correct media type currently in the unit to
return the pointer to the BPB table. The way the buffer is used (pointer
passed by DOS) is determined by the non-IBM format bit in the attribute field
of the device header. If bit 13=0 (device is IBM compatible), the buffer
contains the first sector of the FAT (most importantly the FAT ID byte). The
driver must not alter this buffer in this case. If bit 13=1 the buffer is a
one sector scratch area which can be used for anything.
For drivers that support volume identification and disk change, the call
should cause a new volume identification to be read off the disk. This call
indicates that the disk has been legally changed.
If the device is IBM compatible, it must be true that the first sector of the
first FAT is located at the same sector for all possible media. This is
because the FAT sector is read before the media is actually determined.
The information relating to the BPB for a particular media is kept in the boot
sector for the media. In particular, the format of the boot sector is:
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ For DOS 2.x, 3 byte near jump (0E9h) For DOS 3.x, 2 byte near jump (0EBh) ³
³ followed by a NOP (90h) ³
ÃÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ 8 bytes ³ OEM name and version ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ BYTE ³ ³ sectors per allocation unit (must be a power of 2) ³
ÃÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ B ³ reserved sectors (strarting at logical sector 0) ³
ÃÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ BYTE ³ ³ number of FATs ³
ÃÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ P ³ max number of root directory entries ³
ÃÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ ³ number of sectors in logical image (total number of ³
³ ³ ³ sectors in media, including boot sector directories, etc.) ³
ÃÄÄÄÄÄÄÄÄÄÄ´ B ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ BYTE ³ ³ media descriptor ³
ÃÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ ³ number of sectors occupied by a single FAT ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ sectors per track ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ number of heads ³
ÃÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ WORD ³ number of hidden sectors ³
ÀÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
The three words at the end return information about the media. The number of
heads is useful for supporting different multihead drives that have the same
storage capacity but a different number of surfaces. The number of hidden
sectors is useful for drive partitioning schemes.
INPUT / OUTPUT
command codes=3,4,8,9,and 12
ES:BX pointer to request header. Format:
length field
13 bytes request header
byte media descriptor byte
dword transfer address (buffer address)
word byte/sector count
dword (DOS 3.x) pointer to the volume ID if error code 0Fh
is returned
The driver must perform the following:
A) set the status word in the request header
B) perform the requested function
C) set the actual number of sectors or bytes tranferred
NOTE: No error checking is performed on an IOCTL I/O call. However the driver
must set the return sector or byte count to the actual number of bytes
transferred.
The following applies to block device drivers:
Under certain circumstances the device driver may be asked to do a write
operation of 64k bytes that seems to be a *wrap around* of the transfer address
in the device driver request packet. This arises due to an optimization added to
write code in DOS. It will only happen in writes that are within a sector size
of 64k on files that are being exetended past the current end of file. It is
allowable for the device driver to ignore the balance of the write that wraps
around, if it so chooses. For example, a write of 10000h bytes worth of sectors
with a transfer address of XXXX:1 ignores the last two bytes.
Remember: A program that uses DOS function calls can never request an input or
output function of more than 0FFFFh bytes, therefore, a wrap around
in the transfer (buffer) segment can never occur. It is for this
reason you can ignore bytes that would have wrapped around in the
tranfer segment.
If the driver returns an error code of 0Fh (invalid disk change) it must put
a DWORD pointer to an ASCIIZ string which is the correct volume ID to ask the
user to reinsert the disk.
DOS 3.x:
The reference count of open files on the field (maintained by the OPEN and
CLOSE calls) allows the driver to determine when to return error 0Fh. If there
are no open files (reference count=0) and the disk has been changed, the I/O
is all right, and error 0Fh is not returned. If there are open files
(reference count > 0) and the disk has been changed, an error 0Fh condition
may exist.
NONDESTRUCTIVE INPUT NO WAIT
command code=5
ES:BX pointer to request header. Format:
length field
13 bytes request header
byte read from device
The driver must do the following:
A) return a byte from the device
B) set the status word in the request header.
If the character device returns busy bit=0 (characters in the buffer), then
the next character that would be read is returned. This character is not removed
form the buffer (hence the term nondestructive input). This call allows DOS to
look ahead one character.
STATUS
command codes=8 and 10
ES:BX pointer to a request header. Format:
length field
13 bytes request header
This driver must perform the following:
A) perform the requested function
B) set the busy bit
C) set the status word in the request header.
The busy bit is set as follows:
For input on character devices: if the busy bit is 1 on return, a write
request would wait for completion of a current request. If the busy bit is 0,
there is no current request. Therefore, a write request would start immediately.
For input on character devices with a buffer: if the busy bit is 1 on return,
a read request does to the physical device. If the busy bit is 0, there are
characters in the device buffer and a read returns quickly. It also indicates
that a user has typed something. DOS assumes all character devices have a type-
ahead input buffer. Devices that do not have this buffer should always return
busy=0 so that DOS does not hang waiting for information to be put in a buffer
that does not exist.
FLUSH
command codes=7 and 11
ES:BX pointer
length field
13 bytes request header
This call tells the driver to flush (terminate) all pending requests that it
has knowledge of. Its primary use is to flush the input queue on character
devices.
The driver must set the status word in the request header upon return.
OPEN or CLOSE (3.x)
command codes=13 and 14
ES:BX pointer
length field
13 bytes static request header
These calls are designed to give the device information about the current file
activity on the device if bit 11 of the attribute word is set. On block
devices, these calls can be used to manage local buffering. The device can keep
a reference count. Every OPEN causes the device to increment the reference
count. Every CLOSE causes the device to decrement the reference count. When the
reference count is 0, if means there are no open files in the device. Therefore,
the device should flush buffers inside the device it has written to because now
the user can change the media on a removeable media drive. If the media had been
changed, it is advisable to reset the reference count to 0 without flushing the
buffers. This can be thought of as "last close causes flush". These calls are
more useful on character devices. The OPEN call can be used to send a device
initialization string. On a printer, this could cause a string to be sent to set
the font, page size, etc. so that the printer would always be in a known state
in the I/O stream. Similarly, a CLOSE call can be used to send a post string
(like a form feed) at the end of an I/O stream. Using IOCTL to set these pre and
post strings provides a flexible mechanism of serial I/O device stream control.
NOTE: Since all processes have access to STDIN,STDOUT,STDERR,STDAUX, and STDPRN
(handles 0,1,2,3,and 4) the CON, AUX, and PRN devices are always open.
REMOVABLE MEDIA (DOS 3.x)
command code=15
ES:BX pointer
length field
13 bytes status request header
To use this call, set bit 11 of the attribute field to 1. Block devices can
only use this call through a subfunction of the IOCTL function call (44h).
This call is useful because it allows a utility to know whether it is dealing
with a nonremovable media drive or with a removable media drive. For example,
the FORMAT utility needs to know whether a drive is removable or nonremovable
because it prints different versions of some prompts.
The information is returned in the BUSY bit of the status word. If the busy
bit is 1, the media is nonremovable.
NOTE: No error checking is performed. It is assumed that this call always
succeeds.
THE CLOCK$ DEVICE
To allow a clock board to be integrated into the system for TIME and DATE,
the CLOCK$ device is used. This device defines and performs functions like any
other character device (most functions will be reset done bit, reset error bit,
and return). When a read or write to this device occurs, 6 bytes are
transferred. The first 2 bytes are a word, which is the count of days since
01-01-80. The third byte is minutes, the fourth is hours, the fifth is
hundredths of a second, and the sixth is seconds.
Reading the CLOCK$ device gets the date and time, writing to it sets the date
and time.

View file

@ -5,7 +5,7 @@ permalink: /pubs/pc/programming/
---
PC Programming Guides
---
---------------------
The following is a list of programming guides that were useful during the development of PCjs. Additional
information (errata, disks, etc) is provided where available.

View file

@ -0,0 +1,72 @@
/*
* From "Puzzled Programmers", p. 32:
*
* Can you write a program that finds a four-digit number that is the sum of the fourth powers of its digits?
* In C or Pascal, your program should execute in less than 1 second; in BASIC, it should take about 35 seconds.
*
* As one of the fictitious programmers in the book says:
*
* "That's not hard. Just generate all the four-digit numbers, take the fourth power of each digit, add them up,
* and see if that's the same as the four-digit number."
*
* But as another notes:
*
* "Well, yes, that would work, but it's not very efficient and would make a rather slow program."
*
* Obvious performance considerations include:
*
* 1) There are only 10 possible powers-of-four we're dealing with, so it would be best to calculate all ten
* ahead of time, rather than calculating each one thousands of times in a brute-force approach.
*
* 2) We might only want to sum unique combinations of those powers, since it's a waste of time doing it for, say,
* "1123", "1231", and any other combination of two 1s, one 2, and one 3. However, since every combination of
* digits does have a unique value, and since we want to display all values meeting the criteria, there might not
* be a useful optimization along these lines.
*
* One wrinkle is the digit 0: we'll assume that by "four-digit number", the puzzle didn't really mean to include
* numbers with leading zeros, like "0007" and "0099", so we'll start with 1000.
*
* The solutions in "Puzzled Programmers" are very much hard-coded around the 4-digit nature of the puzzle, because
* they all rely on four nested loops (one loop per decimal place). They also perform a small optimization that
* is really only noticeable when using BASIC: calculate a powers-of-four sum for every tenth number, and then for the
* next ten numbers, they need only do one more addition for the final digit (ie, in the ones place). I added the
* same optimization below, but without the necessity of a hard-coded number of loops, allowing the "power" variable
* to be changed in order to investigate whether any 5-digit numbers, 6-digit numbers, etc, have similar properties.
*/
"use strict";
let p = new Array(10), power = 4, digits = power;
let start = Math.pow(10, digits-1), end = Math.pow(10, digits);
/**
* sumPowers(n)
*
* @param {number} n
* @returns {number}
*/
function sumPowers(n) {
let total = 0;
while (n) {
total += p[n % 10];
n = (n / 10)|0;
}
return total;
}
function run() {
for (let d = 0; d < 10; d++) {
p[d] = Math.pow(d, power);
}
let n = start;
while (true) {
let sum = sumPowers(n);
for (let d = 0; d <= 9; d++) {
if (sum + p[d] == n + d) console.log(n + d);
}
n += 10;
if (n >= end) break;
}
}
run();

View file

@ -35,8 +35,8 @@
<li><a href="/apps/">Apps</a></li>
<li><a href="/devices/">Devices</a></li>
<li><a href="/disks/">Disks</a></li>
<li><a href="/pubs/">Docs</a></li>
<li><a href="/pubs/about/">About</a></li>
<li><a href="/pubs/docs/">Docs</a></li>
<li><a href="/pubs/docs/about/">About</a></li>
</ul>
</div>
<div class="common-top-right">

View file

@ -35,8 +35,8 @@
<li><a href="/apps/">Apps</a></li>
<li><a href="/devices/">Devices</a></li>
<li><a href="/disks/">Disks</a></li>
<li><a href="/pubs/">Docs</a></li>
<li><a href="/pubs/about/">About</a></li>
<li><a href="/pubs/docs/">Docs</a></li>
<li><a href="/pubs/docs/about/">About</a></li>
</ul>
</div>
<div class="common-top-right">

View file

@ -35,8 +35,8 @@
<li><a href="/apps/">Apps</a></li>
<li><a href="/devices/">Devices</a></li>
<li><a href="/disks/">Disks</a></li>
<li><a href="/pubs/">Docs</a></li>
<li><a href="/pubs/about/">About</a></li>
<li><a href="/pubs/docs/">Docs</a></li>
<li><a href="/pubs/docs/about/">About</a></li>
</ul>
</div>
<div class="common-top-right">

View file

@ -35,8 +35,8 @@
<li><a href="/apps/">Apps</a></li>
<li><a href="/devices/">Devices</a></li>
<li><a href="/disks/">Disks</a></li>
<li><a href="/pubs/">Docs</a></li>
<li><a href="/pubs/about/">About</a></li>
<li><a href="/pubs/docs/">Docs</a></li>
<li><a href="/pubs/docs/about/">About</a></li>
</ul>
</div>
<div class="common-top-right">