mirror of https://github.com/AR1972/DOS3.3
commit
50868cd2d2
229 changed files with 81271 additions and 0 deletions
-
7051AG.DOC
-
227PROGREF/0_CONTS.A
-
34PROGREF/0_FRONT.A
-
3175PROGREF/1A_CALLS.A
-
2688PROGREF/1B_CALLS.A
-
3520PROGREF/1C_CALLS.A
-
3710PROGREF/1D_CALLS.A
-
3533PROGREF/1E_CALLS.A
-
3558PROGREF/2_DEVDR.A
-
623PROGREF/3_TECH.A
-
393PROGREF/4_CTRLB.A
-
360PROGREF/5_NLS.A
-
203PROGREF/6_EXE.A
-
2555PROGREF/7_OMF.A
-
440PROGREF/8_HINTS.A
-
1203PROGREF/INDEX.A
-
238README.BF
-
776README.DIS
-
31SRC/BIOS/BIOMES.INC
-
87SRC/BIOS/BIOSTRUC.INC
-
76SRC/BIOS/CLOCKSUB.INC
-
50SRC/BIOS/CMOSEQU.INC
-
22SRC/BIOS/DSKPRM.INC
-
32SRC/BIOS/JUMPMAC.INC
-
1SRC/BIOS/LOCSCR
-
107SRC/BIOS/MAKEFILE
-
494SRC/BIOS/MS96TPI.INC
-
281SRC/BIOS/MSAUX.ASM
-
BINSRC/BIOS/MSAUX.OBJ
-
118SRC/BIOS/MSBDS.INC
-
5SRC/BIOS/MSBIO.LNK
-
693SRC/BIOS/MSBIO1.ASM
-
BINSRC/BIOS/MSBIO1.OBJ
-
650SRC/BIOS/MSBIO2.ASM
-
BINSRC/BIOS/MSBIO2.OBJ
-
295SRC/BIOS/MSCLOCK.ASM
-
BINSRC/BIOS/MSCLOCK.OBJ
-
216SRC/BIOS/MSCON.ASM
-
BINSRC/BIOS/MSCON.OBJ
-
882SRC/BIOS/MSDATA.INC
-
2408SRC/BIOS/MSDISK.ASM
-
BINSRC/BIOS/MSDISK.OBJ
-
65SRC/BIOS/MSEQU.INC
-
72SRC/BIOS/MSEXTRN.INC
-
46SRC/BIOS/MSGROUP.INC
-
418SRC/BIOS/MSHARD.ASM
-
BINSRC/BIOS/MSHARD.OBJ
-
2213SRC/BIOS/MSINIT.ASM
-
BINSRC/BIOS/MSINIT.OBJ
-
1036SRC/BIOS/MSIOCTL.INC
-
767SRC/BIOS/MSLOAD.ASM
-
52SRC/BIOS/MSLOAD.INC
-
BINSRC/BIOS/MSLOAD.OBJ
-
274SRC/BIOS/MSLPT.ASM
-
BINSRC/BIOS/MSLPT.OBJ
-
192SRC/BIOS/MSMACRO.INC
-
306SRC/BIOS/MSSTACK.INC
-
297SRC/BIOS/MSVOLID.INC
-
20SRC/BIOS/PUSHPOP.INC
-
162SRC/BIOS/READCLOC.INC
-
270SRC/BIOS/STKINIT.INC
-
6SRC/BIOS/STKMES.INC
-
868SRC/BIOS/SYSCONF.ASM
-
BINSRC/BIOS/SYSCONF.OBJ
-
18SRC/BIOS/SYSIMES.ASM
-
68SRC/BIOS/SYSIMES.INC
-
BINSRC/BIOS/SYSIMES.OBJ
-
1084SRC/BIOS/SYSINIT1.ASM
-
BINSRC/BIOS/SYSINIT1.OBJ
-
1256SRC/BIOS/SYSINIT2.ASM
-
BINSRC/BIOS/SYSINIT2.OBJ
-
64SRC/BOOT/BOOT11.INC
-
38SRC/BOOT/MAKEFILE
-
7SRC/BOOT/MESSAGES.INC
-
386SRC/BOOT/MSBOOT.ASM
-
650SRC/BUGFIX/BIOS/MSBIO2.ASM
-
BINSRC/BUGFIX/CMD/COMMAND/COMMAND.COM
-
BINSRC/BUGFIX/CMD/FDISK/FDISK.COM
-
3032SRC/BUGFIX/CMD/FORMAT/FORMAT.ASM
-
68SRC/BUGFIX/CMD/FORMAT/MESSAGES.ASM
-
139SRC/BUGFIX/CMD/FORMAT/MESSAGES.INC
-
BINSRC/BUGFIX/DOS/HANDLE.OBJ
-
9SRC/CMD/FORMAT/BOOTMES.INC
-
6SRC/CMD/FORMAT/FILESIZE.INC
-
3032SRC/CMD/FORMAT/FORMAT.ASM
-
2SRC/CMD/FORMAT/FORMAT.LNK
-
141SRC/CMD/FORMAT/FORPROC.ASM
-
58SRC/CMD/FORMAT/MAKEFILE
-
BINSRC/CMD/FORMAT/MAKE_INC.BAS
-
68SRC/CMD/FORMAT/MESSAGES.ASM
-
139SRC/CMD/FORMAT/MESSAGES.INC
-
1204SRC/CMD/FORMAT/OEMFOR.ASM
-
14SRC/CMD/MAKEFILE
-
61SRC/CMD/PRINT/MAKEFILE
-
386SRC/CMD/PRINT/NPRINTF.ASM
-
213SRC/CMD/PRINT/PRIDEFS.INC
-
2SRC/CMD/PRINT/PRINT.LNK
-
2189SRC/CMD/PRINT/PRINT_R.ASM
-
34SRC/CMD/PRINT/PRINT_RM.ASM
-
34SRC/CMD/PRINT/PRINT_RM.INC
7051
AG.DOC
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,227 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
Contents |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
1 System Calls 1 |
|||
|
|||
1.1 Introduction 3 |
|||
1.2 Standard Character Device I/O 4 |
|||
1.3 Memory Management 5 |
|||
1.4 Process Management 7 |
|||
1.5 File and Directory Management 9 |
|||
1.6 Microsoft Networks 14 |
|||
1.7 National Language Support 15 |
|||
1.8 Miscellaneous System-Management Functions 16 |
|||
1.9 Old System Calls 17 |
|||
1.10 Using the System Calls 21 |
|||
1.11 Interrupts 35 |
|||
1.12 Function Requests 53 |
|||
|
|||
2 MS-DOS Device Drivers 323 |
|||
|
|||
2.1 Introduction 325 |
|||
2.2 Format of a Device Driver 326 |
|||
2.3 How to Create a Device Driver 328 |
|||
2.4 Installing Device Drivers 329 |
|||
2.5 Device Headers 330 |
|||
2.6 Request Header 334 |
|||
2.7 Device Driver Functions 337 |
|||
2.8 The Media Descriptor Byte 351 |
|||
2.9 Format of a Media Descriptor Table 351 |
|||
2.10 The CLOCK Device 353 |
|||
2.11 Anatomy of a Device Call 354 |
|||
2.12 Two Sample Device Drivers 355 |
|||
|
|||
3 MS-DOS Technical Information 383 |
|||
|
|||
3.1 Introduction 385 |
|||
3.2 MS-DOS Initialization 385 |
|||
3.3 The Command Processor 386 |
|||
3.4 MS-DOS Disk Allocation 387 |
|||
3.5 MS-DOS Disk Directory 387 |
|||
3.6 File Allocation Table (FAT) 390 |
|||
3.7 MS-DOS Standard Disk Formats 392 |
|||
|
|||
4 MS-DOS Control Blocks |
|||
and Work Areas 395 |
|||
|
|||
iii |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
Contents |
|||
|
|||
4.1 Introduction 397 |
|||
4.2 Typical Contents of an MS-DOS Memory Map 397 |
|||
4.3 MS-DOS Program Segment 398 |
|||
|
|||
5 National Language Support 403 |
|||
|
|||
5.1 Introduction 405 |
|||
5.2 National Language Support Calls 405 |
|||
5.3 Font Files 406 |
|||
|
|||
6 .Exe File Structure and Loading 411 |
|||
|
|||
6.1 Format of a File Header 413 |
|||
6.2 The Relocation Table 414 |
|||
|
|||
7 Microsoft Relocatable |
|||
Object Module Formats 417 |
|||
|
|||
7.1 Introduction 419 |
|||
7.2 Module Identification and Attributes 423 |
|||
7.3 Conceptual Framework for Fixups 425 |
|||
7.4 Record Sequence 431 |
|||
7.5 Introducing the Record Formats 433 |
|||
7.6 Microsoft Type Representations |
|||
for Communal Variables 460 |
|||
|
|||
8 Programming Hints 463 |
|||
|
|||
8.1 Introduction 465 |
|||
8.2 Interrupts 465 |
|||
8.3 System Calls 466 |
|||
8.4 Device Management 467 |
|||
8.5 Memory Management 468 |
|||
8.6 Process Management 468 |
|||
8.7 File and Directory Management 469 |
|||
8.8 Miscellaneous 471 |
|||
|
|||
|
|||
iv |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
Figures |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Figure 1.1 Example of the 8088 Registers 25 |
|||
|
|||
Figure 1.2 Sample Program with Common Skeleton 26 |
|||
|
|||
Figure 2.1 Sample Device Header 330 |
|||
|
|||
Figure 2.2 Attribute Word for Character Devices 333 |
|||
|
|||
Figure 2.3 Attribute Word for Block Devices 333 |
|||
|
|||
Figure 2.4 Request Header 335 |
|||
|
|||
Figure 2.5 Format of a Boot Sector 352 |
|||
|
|||
Figure 2.6 Format of a Clock Device 354 |
|||
|
|||
Figure 4.1 Program Segment Prefix 402 |
|||
|
|||
Figure 5.1 Font File Structure 407 |
|||
|
|||
Figure 7.1 Location Types 427 |
|||
|
|||
|
|||
|
|||
v |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
Tables |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Table 1.1 Standard Character I/O Function Requests 4 |
|||
|
|||
Table 1.2 Memory Management Function Requests 5 |
|||
|
|||
Table 1.3 Process-Management Function Requests 7 |
|||
|
|||
Table 1.4 Predefined Device Handles 9 |
|||
|
|||
Table 1.5 File-Related Function Requests 10 |
|||
|
|||
Table 1.6 File-Sharing Function Requests 11 |
|||
|
|||
Table 1.7 Device-Related Function Requests 12 |
|||
|
|||
Table 1.8 Directory-Related Function Requests 12 |
|||
|
|||
Table 1.9 File Attributes 13 |
|||
|
|||
Table 1.10 Microsoft Networks Function Requests 14 |
|||
|
|||
Table 1.11 National Language-Support Function Requests 15 |
|||
|
|||
Table 1.12 Miscellaneous System-Management Function Requests 16 |
|||
|
|||
Table 1.13 Old System Calls and Their Replacements 17 |
|||
|
|||
Table 1.14 Format of the File Control Block (FCB) 18 |
|||
|
|||
Table 1.15 Error Codes Returned in AX 22 |
|||
|
|||
Table 1.16 MS-DOS Interrupts, Numeric Order 27 |
|||
|
|||
Table 1.17 MS-DOS Interrupts, Alphabetic Order 27 |
|||
|
|||
Table 1.18 MS-DOS Function Requests, Numeric Order 28 |
|||
|
|||
Table 1.19 MS-DOS Function Requests, Alphabetic Order 31 |
|||
|
|||
Table 1.20 Bit values for Function 29H 133 |
|||
|
|||
Table 1.21 Sharing Mode Bit Values 174 |
|||
|
|||
Table 1.22 Access Code Bit Values 175 |
|||
|
|||
Table 1.23 MS-DOS Data Bit Values 193 |
|||
|
|||
Table 1.24 Contents of the Parameter Block 239 |
|||
|
|||
Table 1.25 Contents of the Parameter Block 243 |
|||
|
|||
Table 1.26 250 |
|||
|
|||
Table 1.27 Allocation Strategy 263 |
|||
|
|||
Table 2.1 For Character Devices: 331 |
|||
|
|||
vi |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
Contents |
|||
|
|||
Table 2.2 For Block Devices: 331 |
|||
|
|||
Table 3.1 MS-DOS Standard Removable-Disk Formats 393 |
|||
|
|||
Table 3.2 MS-DOS Standard Removable Disk Formats (High-Density) 393 |
|||
|
|||
Table 7.1 Object Module Record Formats 419 |
|||
|
|||
Table 7.2 Combination Attribute Example 438 |
|||
|
|||
|
|||
|
|||
vii |
|||
|
|||
_ _ | | _ _ |
|||
|
@ -0,0 +1,34 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
Microsoft (R) MS-DOS |
|||
Version 3.3 |
|||
_ ________________________________________________________________ |
|||
|
|||
Programmer's Reference |
|||
|
|||
Microsoft Corporation |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
All rights reserved. |
|||
|
|||
Simultaneously published in the United States and |
|||
Canada. |
|||
|
|||
Microsoft(R), the Microsoft logo, MS-DOS(R), and XENIX(R) are registered trademarks |
|||
of Microsoft Corporation. |
|||
|
|||
IBM(R), IBM Personal Computer(R), IBM PC(R), and PC-DOS(R) are registered trade- |
|||
marks of International Business Machines Corporation. |
|||
|
|||
INTEL(R) is a registered trademark of Intel Corporation. |
|||
|
|||
Document No. 410630014-330-R04-0787 |
|||
|
|||
_ _ | | _ _ |
|||
|
3175
PROGREF/1A_CALLS.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2688
PROGREF/1B_CALLS.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
3520
PROGREF/1C_CALLS.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
3710
PROGREF/1D_CALLS.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
3533
PROGREF/1E_CALLS.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
3558
PROGREF/2_DEVDR.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,623 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Technical Information |
|||
|
|||
_ _______________________________________ |
|||
|
|||
|
|||
3.1 Introduction |
|||
|
|||
This chapter describes how MS-DOS initializes and how it allocates disk |
|||
space for the root directory, the File Allocation Tables (FAT), and the |
|||
data area. For programmers writing installable device drivers, this |
|||
chapter explains MS-DOS disk directory entries and File Allocation |
|||
Tables. At the end of the chapter, Tables 3.1 and 3.2 describe MS-DOS |
|||
standard formats for floppy disks. |
|||
|
|||
3.2 MS-DOS Initialization |
|||
|
|||
MS-DOS initialization consists of several steps. When you reset your com- |
|||
puter or turn on its power, the ROM (Read Only Memory) BIOS is invoked |
|||
and performs hardware checks and initialization. The ROM BIOS then |
|||
examines drive A for the boot sector. If it locates a boot sector, the ROM |
|||
BIOS reads it into low memory and gives it control. If it doesn't find the |
|||
boot sector, the ROM BIOS then looks in the active partition of the hard |
|||
disk. If it still doesn't find the boot sector, the ROM BIOS then invokes |
|||
ROM BASIC. |
|||
|
|||
On a removable disk (3.5-inch, 5.25-inch, or 8-inch disk), the boot sector |
|||
sector is always located on track 0, sector 1, side 0 of the disk. On a hard |
|||
disk, the boot sector begins on the first sector of the MS-DOS partition. |
|||
The hard disk boot sector also includes a partition table. This table |
|||
identifies the active MS-DOS partition and any other partitions, such as |
|||
an extended MS-DOS partition, on the hard disk. Note that extended |
|||
MS-DOS partitions are not bootable. |
|||
|
|||
The boot sector then reads the following files, in the order listed: |
|||
|
|||
io.sys |
|||
msdos.sys |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Note |
|||
|
|||
Versions of MS-DOS prior to 3.3 required the io.sys file to be contigu- |
|||
ous. This is no longer a requirement. |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Next, the system initialization routine SYSINIT loads all of the resident |
|||
device drivers. Then, it searches for a config.sys file on the boot disk. |
|||
SYSINIT allocates memory for buffers and files, based on settings in the |
|||
config.sys file, or system default settings. If the config.sys file specifies any |
|||
|
|||
3 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
installable device drivers, these are installed next. |
|||
|
|||
Finally, SYSINIT executes the MS-DOS command processor, |
|||
command.com. |
|||
|
|||
3.3 The Command Processor |
|||
|
|||
The command processor command.com consists of three parts: |
|||
|
|||
o A resident part resides in memory immediately following msdos.sys |
|||
and its data area. This part contains routines to process Inter- |
|||
rupts 22H (Terminate Process Exit Address), 23H (CONTROL-C Exit |
|||
Address), and 24H (Critical-Error-Handler Address), as well as a |
|||
routine to reload the transient part, if needed. All standard |
|||
MS-DOS error handling is done within this part of command.com. |
|||
This includes displaying error messages and processing the Abort, |
|||
Retry, Fail, or Ignore messages. |
|||
|
|||
o An initialization part follows the resident part. During startup, the |
|||
initialization part is given control; it contains the processor setup |
|||
routine in the autoexec.bat file. The initialization part determines |
|||
the segment address at which programs can be loaded, and because |
|||
it is no longer needed, is overlaid by the first program that |
|||
command.com loads. |
|||
|
|||
o A transient part is loaded at the high end of memory. This part |
|||
contains all the internal command processors and the batch file |
|||
processor. |
|||
|
|||
The transient part of the command processor produces the system |
|||
prompt (A>, for example), reads commands from the keyboard (or |
|||
from batch files), and causes them to be executed. For external |
|||
commands, the transient part builds a command line and issues |
|||
Function 4BH (Load and Execute Program) to load and transfer |
|||
control to the program. |
|||
|
|||
|
|||
3.4 MS-DOS Disk Allocation |
|||
|
|||
The area on a disk partitioned for use by MS-DOS is formatted as follows: |
|||
|
|||
1. Reserved area\(emvariable size |
|||
|
|||
2. First copy of File Allocation Table\(emvariable size |
|||
|
|||
|
|||
|
|||
4 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Technical Information |
|||
|
|||
_ _______________________________________ |
|||
|
|||
3. Additional copies of File Allocation Table\(emvariable size (optional) |
|||
|
|||
4. Root directory\(emvariable size |
|||
|
|||
5. File data area |
|||
|
|||
Space for a file in the data area is not preallocated. The space is allocated |
|||
one cluster at a time. A cluster consists of one or more consecutive sectors |
|||
(the number of sectors in a cluster must be a power of 2); the cluster size is |
|||
determined at format time. All the clusters for a file are "chained" |
|||
together in the File Allocation Table, discussed in greater detail in Section |
|||
3.5, "File Allocation Table (FAT)." MS-DOS normally keeps a second copy |
|||
of the FAT for consistency, except in the case of reliable storage such as a |
|||
virtual RAM disk. Should the disk develop a bad sector in the middle of |
|||
the first FAT, MS-DOS can use the second. This avoids loss of data due to |
|||
an unreadable FAT. |
|||
|
|||
3.5 MS-DOS Disk Directory |
|||
|
|||
The format utility builds the root directory for all disks. This directory's |
|||
location on the disk and the maximum number of entries are dependent on |
|||
the media. Specifications for standard removable-disk formats are outlined |
|||
later in this chapter. Note, however, that MS-DOS regards directories, |
|||
other than the root directory, as files, so there is no limit to the number of |
|||
files that the subdirectories under the root directory may contain. |
|||
|
|||
All directory entries are 32 bytes in length and are in the following format |
|||
(note that byte offsets are in hexadecimal): |
|||
|
|||
Byte |
|||
Function |
|||
_ ________________________________________________________________ |
|||
|
|||
|
|||
0-7 Filename. Eight characters, left-aligned and padded, if neces- |
|||
sary, with blanks. The first byte of this field indicates the file |
|||
status as follows: |
|||
_ _____________________________________________________ |
|||
|
|||
00H The directory entry has never been used. This is used |
|||
to limit the length of directory searches, for perfor- |
|||
mance reasons. |
|||
|
|||
05H The first character of the filename contains an E5H |
|||
character. |
|||
|
|||
2EH The 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). Otherwise, bytes 01H |
|||
through 0AH are all spaces, and the cluster field con- |
|||
tains the cluster number of this directory. |
|||
|
|||
5 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
E5H The file was used, but it has since been erased. |
|||
|
|||
Any other character is the first character of a filename. |
|||
|
|||
8-0A Filename extension. |
|||
|
|||
0B File attribute. The attribute byte is mapped as follows |
|||
(values are in hexadecimal): |
|||
|
|||
|
|||
Byte |
|||
Contents |
|||
_ _____________________________________________________ |
|||
|
|||
01H File is marked read-only. An attempt to open the file |
|||
for writing using Function 3DH (Open Handle) results |
|||
in an error code being returned. This value can be |
|||
used in programs along with the other attributes in |
|||
this list. Attempts to delete the file with Function |
|||
13H (Delete File) or Function 41H (Delete Directory |
|||
Entry) will also fail. |
|||
|
|||
02H Hidden file. The file is excluded from normal directory |
|||
searches. |
|||
|
|||
04H System file. The file is excluded from normal directory |
|||
searches. |
|||
|
|||
08H The entry contains the volume label in the first 11 |
|||
bytes. The entry contains no other usable information |
|||
(except date and time of creation), and may exist only |
|||
in the root directory. |
|||
|
|||
10H The entry defines a subdirectory, and is excluded from |
|||
normal directory searches. |
|||
|
|||
20H Archive bit. The bit is set to "on" whenever the file |
|||
has been written to and closed. |
|||
|
|||
Note: The system files (io.sys and msdos.sys) are |
|||
marked as read-only, hidden, and system files. Files |
|||
can be marked hidden when they are created. Also, |
|||
you may change the read-only, hidden, system, and |
|||
archive attributes through Function 43H (Get/Set File |
|||
Attributes). |
|||
|
|||
0C-15 Reserved. |
|||
|
|||
16-17 Time the file was created or last updated. The hour, minutes, |
|||
and seconds are mapped into two bytes as follows (bit 7 on |
|||
the left, 0 on the right): |
|||
|
|||
Offset 17H |
|||
| H | H | H | H | H | M | M | M | |
|||
|
|||
Offset 16H |
|||
| M | M | M | S | S | S | S | S | |
|||
|
|||
6 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Technical Information |
|||
|
|||
_ _______________________________________ |
|||
|
|||
where: |
|||
|
|||
H is the binary number of hours (0-23). |
|||
M is the binary number of minutes (0-59). |
|||
S is the binary number of two-second increments. |
|||
|
|||
|
|||
18-19 Date the file was created or last updated. The year, month, |
|||
and day are mapped into two bytes as follows: |
|||
|
|||
Offset 19H |
|||
| Y | Y | Y | Y | Y | Y | Y | M | |
|||
|
|||
Offset 18H |
|||
| M | M | M | D | D | D | D | D | |
|||
|
|||
where: |
|||
|
|||
Y is the year, 0-119 (1980-2099). |
|||
M is the month (1-12). |
|||
D is the day of the month (1-31). |
|||
|
|||
|
|||
1A-1B Starting cluster; the number of the first cluster in the file. |
|||
|
|||
o Note that the first cluster for data space on all disks is |
|||
cluster 002. |
|||
|
|||
o The cluster number is stored with the least significant |
|||
byte first. |
|||
|
|||
o For details about converting cluster numbers to logical |
|||
sector numbers, see Sections 3.5.1 and 3.5.2. |
|||
|
|||
|
|||
1C-1F File size in bytes. The first word of this four-byte field is the |
|||
low-order part of the size. |
|||
|
|||
|
|||
3.6 File Allocation Table (FAT) |
|||
|
|||
This section explains how MS-DOS allocates disk space in the data area |
|||
for a file by using the File Allocation Table to convert the clusters of a file |
|||
to logical sector numbers. The device driver is then responsible for locat- |
|||
ing the logical sector on the disk. Programs should use the MS-DOS file |
|||
management function calls for accessing files. Programs that access the |
|||
FAT are not guaranteed to be upwardly-compatible with future releases of |
|||
MS-DOS. The following information is useful to system programmers who |
|||
wish to write installable device drivers. |
|||
|
|||
The File Allocation Table is an array of 12-bit entries (1.5 bytes) for each |
|||
cluster on the disk. For disks containing more than 4085 clusters, a 16-bit |
|||
FAT entry is used. |
|||
|
|||
|
|||
|
|||
7 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
The first two FAT entries are reserved; however, the device driver may use |
|||
the first byte as a FAT ID byte for determining media. For hard disks, the |
|||
value of this byte is F8H. See Tables 3.1 and 3.2 for the media byte |
|||
descriptors used for 8-inch, 5.25-inch, and 3.5-inch disks. |
|||
|
|||
The third FAT entry, which starts at byte offset 4, begins the mapping of |
|||
the data area (cluster 002). The operating system does not always sequen- |
|||
tially write (to the disk) files in the data area. Instead, the system allo- |
|||
cates the data area one cluster at a time, skipping over clusters it has |
|||
already allocated. The first free cluster following the last cluster allocated |
|||
for that file is the next cluster allocated, regardless of its physical location |
|||
on the disk. This permits the most efficient use of disk space, since if you |
|||
erase old files, you can free clusters, which the operating system can then |
|||
allocate for new files. |
|||
|
|||
Each FAT entry contains three or four hexadecimal characters, depending |
|||
on whether it is a 12-bit or 16-bit entry: |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
(0)000 If the cluster is unused and available. |
|||
|
|||
(F)FF7 The cluster has a bad sector in it if it is not part of any |
|||
cluster chain. MS-DOS will not allocate such a cluster. So |
|||
for its report, the chkdsk command counts the number of |
|||
bad clusters, which are not part of any allocation chain. |
|||
|
|||
(F)FF8-FFF The last cluster of a file. |
|||
|
|||
(X)XXX Any other characters that are the cluster number of the |
|||
next cluster in the file. The number of the first cluster in |
|||
the file is in the file's directory entry. |
|||
|
|||
The File Allocation Table always begins on the first sector after the |
|||
reserved sectors. If the FAT is larger than one sector, the sectors are con- |
|||
tiguous. The operating system usually writes two copies of the FAT to |
|||
preserve data integrity. MS-DOS reads the FAT into one of its buffers, |
|||
whenever needed (open, read, write, etc.). The operating system also gives |
|||
this buffer a high priority to keep it in memory as long as possible. |
|||
|
|||
3.6.1 How to Use the FAT (12-Bit FAT Entries) |
|||
|
|||
To get the starting cluster of a file, examine its directory entry (in the |
|||
FAT). Then, to locate each subsequent cluster of the file, follow these |
|||
steps: |
|||
|
|||
1. Multiply the cluster number just used by 1.5 (each FAT entry is |
|||
1.5 bytes in length). |
|||
|
|||
2. The whole part of the product is an offset into the FAT, pointing |
|||
to the entry that maps the cluster just used. That entry contains |
|||
the cluster number of the next cluster of the file. |
|||
|
|||
8 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Technical Information |
|||
|
|||
_ _______________________________________ |
|||
|
|||
3. Use a MOV instruction to move the word at the calculated FAT |
|||
offset into a register. |
|||
|
|||
4. If the last cluster used was an even number, keep the low-order 12 |
|||
bits of the register by using the AND operator with 0FFFH and the |
|||
register. If the last cluster used was an odd number, keep the |
|||
high-order 12 bits by using the SHR instruction to shift the register |
|||
right four bits. |
|||
|
|||
5. If the resultant 12 bits are 0FF8H-0FFFH, the file contains no |
|||
more clusters. Otherwise, the 12 bits contain the number of the |
|||
next cluster in the file. |
|||
|
|||
To convert the cluster to a logical sector number (relative sector, such as |
|||
that used by Interrupts 25H and 26H (Absolute Disk Read/Write) and by |
|||
debug), follow these steps: |
|||
|
|||
1. Subtract two from the cluster number. |
|||
|
|||
2. Multiply the result by the number of sectors per cluster. |
|||
|
|||
3. To this result, add the logical sector number of the beginning of |
|||
the data area. |
|||
|
|||
|
|||
3.6.2 How to Use the FAT (16-Bit FAT Entries) |
|||
|
|||
To get the starting cluster of a file, examine its directory entry (in the |
|||
FAT). Then, to find the next file cluster, follow these steps: |
|||
|
|||
1. Multiply the cluster number last used by 2 (each FAT entry is 2 |
|||
bytes). |
|||
|
|||
2. Use a MOV WORD instruction to move the word at the calculated |
|||
FAT offset into a register. |
|||
|
|||
3. If the resultant 16 bits are 0FFF8-0FFFH, no more clusters are in |
|||
the file. Otherwise, the 16 bits contain the number of the next |
|||
cluster in the file. |
|||
|
|||
|
|||
3.7 MS-DOS Standard Disk Formats |
|||
|
|||
MS-DOS arranges data clusters on a disk to minimize head movement. |
|||
MS-DOS then allocates all the space on one track (or cylinder) before mov- |
|||
ing to the next. It uses the sequential sectors on the lowest-numbered |
|||
head, then all the sectors on the next head, and so on, until it has used all |
|||
the sectors on all the heads of the track. |
|||
|
|||
|
|||
|
|||
9 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
The size of the MS-DOS partition on a hard disk determines the size of the |
|||
FAT and root directory. Likewise, the type of floppy disk (tracks per side, |
|||
sectors per track, etc.) determines how MS-DOS uses the disk. The remov- |
|||
able disk formats listed in Tables 3.1 and 3.2 are standard and should be |
|||
readable in the appropriate standard drive. |
|||
|
|||
|
|||
10 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Technical Information |
|||
|
|||
_ _______________________________________ |
|||
|
|||
Table 3.1 |
|||
|
|||
MS-DOS Standard Removable-Disk Formats |
|||
|
|||
_ _________________________________________________________________________ |
|||
|
|||
Disk Size in inches 5.25 8 |
|||
|
|||
_ _________________________________________________________________________ |
|||
|
|||
WORD no. heads 1 1 2 2 1 2 1 |
|||
|
|||
Tracks/side 40 40 40 40 77 77 77 |
|||
|
|||
WORD sectors/track 8 9 8 9 26 26 8 |
|||
|
|||
WORD bytes/sector 512 512 512 512 128 128 024 |
|||
|
|||
BYTE sectors/ cluster 1 1 2 2 4 4 1 |
|||
|
|||
WORD reserved sectors 1 1 1 1 1 4 1 |
|||
|
|||
Byte no. FATs 2 2 2 2 2 2 2 |
|||
|
|||
WORD root directory entries 64 64 112 112 68 68 192 |
|||
|
|||
WORD no. sectors 320 360 640 720 2002 2002 616 |
|||
|
|||
BYTE media descriptor FE FC FF FD *FE FD *FE |
|||
|
|||
WORD sectors/FAT 1 2 1 2 6 6 2 |
|||
|
|||
WORD no. hidden sectors 0 0 0 0 0 0 0 |
|||
|
|||
_ _________________________________________________________________________ |
|||
|
|||
*The two media descriptor bytes are the same for 8" disks (FEH). This is not a misprint. To |
|||
establish whether a disk is single- or double-density, try a read of a single-density address |
|||
mark. If an error occurs, the media is double-density. |
|||
|
|||
Table 3.2 |
|||
|
|||
MS-DOS Standard Removable Disk Formats (High-Density) |
|||
|
|||
_ _________________________________________________________________________ |
|||
|
|||
Disk Size in inches 3.5 or 5.25 3.5 5.25 |
|||
|
|||
_ _________________________________________________________________________ |
|||
|
|||
WORD no. heads 1 2 2 2 2 2 |
|||
|
|||
Tracks/side 80 80 80 80 80 80 |
|||
|
|||
WORD sectors/track 8 9 8 9 18 15 |
|||
|
|||
WORD bytes/sector 512 512 512 512 512 512 |
|||
|
|||
BYTE sectors/cluster 2 2 2 2 1 1 |
|||
|
|||
WORD reserved sectors 1 1 1 1 1 1 |
|||
|
|||
BYTE no. FATs 2 2 2 2 2 2 |
|||
|
|||
WORD root dir entries 112 112 112 112 224 224 |
|||
|
|||
WORD no. sectors 640 720 1280 1440 2880 2400 |
|||
|
|||
BYTE media descriptor* FA FC FB F9 F0 F9 |
|||
|
|||
WORD sectors/FAT 1 2 2 3 9 7 |
|||
|
|||
WORD no. hidden sectors 0 0 0 0 0 0 |
|||
|
|||
_ _________________________________________________________________________ |
|||
|
|||
*The value F0H in the media descriptor byte may be used to describe other media types. |
|||
|
|||
|
|||
11 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
Chapter 3 |
|||
|
|||
MS-DOS Technical Information |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
3.1 Introduction 3 |
|||
|
|||
3.2 MS-DOS Initialization 3 |
|||
|
|||
3.3 The Command Processor 4 |
|||
|
|||
3.4 MS-DOS Disk Allocation 4 |
|||
|
|||
3.5 MS-DOS Disk Directory 5 |
|||
|
|||
3.6 File Allocation Table (FAT) 7 |
|||
|
|||
3.6.1 How to Use the FAT (12-Bit FAT Entries) 8 |
|||
|
|||
3.6.2 How to Use the FAT (16-Bit FAT Entries) 9 |
|||
|
|||
3.7 MS-DOS Standard Disk Formats 9 |
|||
|
|||
|
|||
|
|||
12 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
12 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
@ -0,0 +1,393 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Control Blocks and Work Areas |
|||
|
|||
_ ______________________________________________ |
|||
|
|||
|
|||
4.1 Introduction |
|||
|
|||
This chapter describes a typical MS-DOS memory map and explains how a |
|||
program is loaded into memory. It also describes the structure of an |
|||
MS-DOS program segment and the contents of register segments for .exe |
|||
and .com program files. |
|||
|
|||
4.2 Typical Contents of an MS-DOS Memory |
|||
Map |
|||
|
|||
A typical MS-DOS memory map contains the following information: |
|||
|
|||
|
|||
+-----------------------------------------------------+ |
|||
| ROM and Video Buffers | |
|||
+-----------------------------------------------------+ |
|||
| Transient Part of COMMAND.COM | |
|||
+-----------------------------------------------------+ |
|||
| | |
|||
| | |
|||
| | |
|||
| | |
|||
| Transient Program Area | |
|||
|- - - - - - - - - - - - - - - - - - - - - - - - - - -| |
|||
| | |
|||
| | |
|||
| | |
|||
| | |
|||
| External Commands and Utilities | |
|||
| | |
|||
+-----------------------------------------------------+ |
|||
| Resident Part of COMMAND.COM | |
|||
+-----------------------------------------------------+ |
|||
| MS-DOS buffers, control areas, & installed drivers | |
|||
+-----------------------------------------------------+ |
|||
| | |
|||
| MSDOS.SYS | |
|||
+-----------------------------------------------------+ |
|||
| IO.SYS and resident device drivers | |
|||
+-----------------------------------------------------+ |
|||
| Interrupt Vectors | |
|||
0 +-----------------------------------------------------+ |
|||
|
|||
During system initialization, MS-DOS loads the io.sys and msdos.sys files |
|||
into low memory (Note that in MS-DOS 3.3, these files are not required to |
|||
be written contiguously to the disk). The io.sys system file is the MS-DOS |
|||
interface to hardware. The msdos.sys system file includes MS-DOS inter- |
|||
rupt handlers, service routines (Interrupt 21H functions). |
|||
|
|||
3 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
Next, the system initialization routine loads the resident and installable |
|||
device drivers. Above the installable device drivers, MS-DOS writes the |
|||
resident part of command.com. This part includes interrupt handlers for |
|||
Interrupts 22H (Terminate Process Exit Address), 23H (CONTROL-C |
|||
Handler Address), 24H (Critical-Error-Handler Address) and code to reload |
|||
the transient part. The transient part of command.com is reloaded into |
|||
high memory. It includes the command interpreter, the internal MS-DOS |
|||
commands, and the batch processor. |
|||
|
|||
External command and utility (.com and .exe) files are loaded into the |
|||
transient program area. MS-DOS also allocates 256 bytes for user stack |
|||
used with .com files. User memory is allocated from the lowest end of |
|||
available memory that fulfills the allocation request. |
|||
|
|||
4.3 MS-DOS Program Segment |
|||
|
|||
When you type an external command or execute a program through Func- |
|||
tion 4BH (Load and Execute Program, also called EXEC), MS-DOS deter- |
|||
mines the lowest available free memory address to use as the start of the |
|||
program. The memory starting at this address is called the Program Seg- |
|||
ment. |
|||
|
|||
The EXEC system call sets up the first 256 bytes of the Program Segment |
|||
for the program being loaded into memory. The program is then loaded |
|||
following this block. An .exe file with minalloc and maxalloc both set to |
|||
zero is loaded as high as possible. |
|||
|
|||
At offset 0 within the Program Segment, MS-DOS builds the Program Seg- |
|||
ment Prefix control block. The program returns from EXEC by one of five |
|||
methods: |
|||
|
|||
o By issuing an Interrupt 21H with AH=4CH |
|||
|
|||
o By issuing an Interrupt 21H with AH=31H (Keep Process) |
|||
|
|||
o By a long jump to offset 0 in the Program Segment Prefix |
|||
|
|||
o By issuing an Interrupt 20H with CS:0 pointing at the PSP |
|||
|
|||
o By issuing an Interrupt 21H with register AH=0 and with CS:0 |
|||
pointing at the PSP |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Note |
|||
|
|||
The first two methods are preferred for functionality, compatibility, |
|||
and efficiency in future versions of MS-DOS. |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
4 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Control Blocks and Work Areas |
|||
|
|||
_ ______________________________________________ |
|||
|
|||
All five methods transfer control to the program that issued the EXEC |
|||
call. The first two methods return a completion code. They also restore |
|||
the addresses of Interrupts 22H, 23H, and 24H (Terminate Process Exit |
|||
Address, CONTROL-C Handler Address, and Critical-Error-Handler Address) |
|||
from the values saved in the Program Segment Prefix of the terminating |
|||
program. Control then passes to the terminate address. |
|||
|
|||
If a program returns to command.com, control transfers to the resident |
|||
portion. If the program is a batch file (in process), it continues. Other- |
|||
wise, command.com performs a checksum on the transient part, reloads it |
|||
if necessary, issues the system prompt, and waits for you to type another |
|||
command. |
|||
|
|||
When a program receives control, the following conditions are in effect: |
|||
|
|||
For all programs: |
|||
|
|||
o The segment address of the passed environment is at offset 2CH in |
|||
the Program Segment Prefix. |
|||
|
|||
o The environment is a series of ASCII strings (totaling less than 32K) |
|||
in the form: |
|||
|
|||
NAME=parameter |
|||
|
|||
o A byte of zeros terminates each string, and another byte of zeros |
|||
terminates the set of strings. |
|||
|
|||
Following the last byte of zeros is a set of initial arguments that |
|||
the operating system passes to a program. This set of arguments |
|||
contains a word count followed by an ASCII string. If the file is in |
|||
the current directory, the ASCII string contains the drive and path- |
|||
name of the executable program as passed to the EXEC function |
|||
call. If the file is not in the current directory, EXEC concatenates |
|||
the name of the file with the name of the path. Programs may use |
|||
this area to determine where the program was loaded. |
|||
|
|||
o The environment built by the command processor contains at least |
|||
a comspec= string (the parameters on comspec define the path |
|||
that MS-DOS uses to locate command.com on disk). The last path |
|||
and prompt commands issued are also in the environment, along |
|||
with any environment strings you have defined with the MS-DOS |
|||
set command. |
|||
|
|||
o EXEC passes a copy of the invoking process environment. If your |
|||
application uses a "keep process" concept, you should be aware |
|||
that the copy of the environment passed to you is static. That is, |
|||
it will not change even if you issue subsequent set, path, or |
|||
prompt commands. Conversely, any modification of the passed |
|||
environment by the application is not reflected in the parent pro- |
|||
cess environment. For instance, a program cannot change the |
|||
MS-DOS environment values as the set command does. |
|||
|
|||
5 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
o The Disk Transfer Address (DTA) is set to 80H (default DTA in the |
|||
Program Segment Prefix). The Program Segment Prefix contains |
|||
file control blocks at 5CH and 6CH. MS-DOS formats these blocks |
|||
using the first two parameters that you typed when entering the |
|||
command. If either parameter contained a pathname, then the |
|||
corresponding FCB contains only the valid drive number. The |
|||
filename field is not valid. |
|||
|
|||
o An unformatted parameter area at 81H contains all the characters |
|||
typed after the command (including leading and embedded delim- |
|||
iters), with the byte at 80H set to the number of characters. If you |
|||
type <, >, or parameters on the command line, they do not |
|||
appear in this area (nor the filenames associated with them). |
|||
Redirection of standard input and output is transparent to appli- |
|||
cations. |
|||
|
|||
o Offset 6 (one word) contains the number of bytes available in the |
|||
segment. |
|||
|
|||
o Register AX indicates whether the drive specifiers (entered with the |
|||
first two parameters) are valid, as follows: |
|||
|
|||
AL=FF if the first parameter contained an invalid drive specifier |
|||
(otherwise AL=00) |
|||
|
|||
AH=FF if the second parameter contained an invalid drive |
|||
specifier (otherwise AH=00) |
|||
|
|||
o Offset 2 (one word) contains the segment address of the first byte |
|||
of unavailable memory. Programs must not modify addresses |
|||
beyond this point unless these addresses were obtained by allocat- |
|||
ing memory via Function 48H (Allocate Memory). |
|||
|
|||
|
|||
For Executable (.exe) Programs: |
|||
|
|||
o DS and ES registers point to the Program Segment Prefix. |
|||
|
|||
o CS,IP,SS, and SP registers contain the values that Microsoft link |
|||
sets in the .exe image. |
|||
|
|||
|
|||
For Executable (.com) Programs: |
|||
|
|||
o All four segment registers contain the segment address of the ini- |
|||
tial allocation block that starts with the Program Segment Prefix |
|||
control block. |
|||
|
|||
o .com programs allocate all of user memory. If the program invokes |
|||
another program through Function 4BH (EXEC), it must first free |
|||
some memory through Function 4AH (Set Block) to provide space |
|||
for the program being executed. |
|||
|
|||
|
|||
|
|||
6 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
MS-DOS Control Blocks and Work Areas |
|||
|
|||
_ ______________________________________________ |
|||
|
|||
o The Instruction Pointer (IP) is set to 100H. |
|||
|
|||
o The Stack Pointer register is set to the end of the program's seg- |
|||
ment. The segment size at offset 6 is reduced by 100H to allow for |
|||
a stack of that size. |
|||
|
|||
o A .com program places a word of zeros on top of the stack. Then |
|||
by doing a RET instruction last, your program can exit to |
|||
command.com. This method assumes, however, that you have |
|||
maintained your stack and code segments. |
|||
|
|||
Figure 4.1 illustrates the format of the Program Segment Prefix. All |
|||
offsets are in hexadecimal. |
|||
|
|||
(Offsets in Hex) |
|||
0 ----------------------------------------------------------- |
|||
| | End of | | |
|||
| INT 20H | alloc. | Reserved | |
|||
| | block | 04H | |
|||
8 ----------------------------------------------------------- |
|||
| | Terminate address | CONTROL-C exit | |
|||
| Reserved | (IP, CS) | address (IP) | |
|||
| | | | |
|||
10----------------------------------------------------------- |
|||
|CONTROL-C | Hard error exit address | | |
|||
|exit | (IP, CS) | | |
|||
|address (CS)| | | |
|||
---------------------------------------- | |
|||
| | |
|||
| Used by MS-DOS | |
|||
| | |
|||
| 5CH | |
|||
| | |
|||
----------------------------------------------------------- |
|||
| | |
|||
| Formatted Parameter Area 1 formatted as standard | |
|||
| unopened FCB 6CH | |
|||
----------------------------------------------------------- |
|||
| | |
|||
| Formatted Parameter Area 2 formatted as standard | |
|||
| unopened FCB (overlaid if FCB at 5CH is opened) | |
|||
80----------------------------------------------------------- |
|||
| Unformatted Parameter Area | |
|||
| (default Disk Transfer Area) | |
|||
| Initially contains command invocation line. | |
|||
----------------------------------------------------------- |
|||
100 |
|||
|
|||
|
|||
Figure 4.1 Program Segment Prefix |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Important |
|||
|
|||
7 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
Programs must not alter any part of the Program Segment Prefix |
|||
below offset 5CH. |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
|
|||
|
|||
8 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
Chapter 4 |
|||
|
|||
MS-DOS Control Blocks |
|||
|
|||
and Work Areas |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
4.1 Introduction 3 |
|||
|
|||
4.2 Typical Contents of an MS-DOS Memory Map 3 |
|||
|
|||
4.3 MS-DOS Program Segment 4 |
|||
|
|||
|
|||
|
|||
1 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
8 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
@ -0,0 +1,360 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
National Language Support |
|||
|
|||
_ ____________________________________ |
|||
|
|||
|
|||
5.1 Introduction |
|||
|
|||
National language support for this version of MS-DOS 3.3 includes these |
|||
major features: |
|||
|
|||
o Country-dependent information |
|||
|
|||
o Support for national keyboard layouts |
|||
|
|||
o Programming interfaces for national language support |
|||
|
|||
o Utility commands |
|||
|
|||
Country-dependent information is available on a per-country basis and |
|||
includes the following: |
|||
|
|||
o Time, date, and currency |
|||
|
|||
o Lowercase-to-uppercase character-conversion tables |
|||
|
|||
o Collating sequence for character sorting |
|||
|
|||
o Valid single-byte characters used in filenames |
|||
|
|||
Selectable keyboard support for different keyboard layouts is provided. |
|||
|
|||
The MS-DOS 3.3 programming interfaces for national language support |
|||
allow applications to use the country-dependent information just |
|||
described. To access this information, applications do not need to change |
|||
the current country code of the system. |
|||
|
|||
Utility commands allow the user to select the keyboard layout and system |
|||
country code. |
|||
|
|||
This version of MS-DOS does not support right-to-left national languages. |
|||
|
|||
5.2 National Language Support Calls |
|||
|
|||
The following function calls allow an application to tailor its operation to |
|||
the current country code and to accept or change the current code page. |
|||
A country code defines the country in which you live or work. MS-DOS |
|||
uses this code to prepare and assign default code pages for your system. A |
|||
code page is a table that defines the character set you are using. A |
|||
character set is a country-specific or language-specific group of characters |
|||
that are translated from the code page table and displayed on your screen |
|||
or printer. Each code page character set contains 256 characters. |
|||
|
|||
|
|||
|
|||
3 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
The following function calls are also used by MS-DOS 3.3 to support the |
|||
National Language requirements: |
|||
|
|||
o Function 44H, Code 0CH (Generic IOCtl) \(em supports code page |
|||
switching on a per-device basis. |
|||
|
|||
o Function 65H (Get Extended Country Information) \(em returns |
|||
standard country information, and points to related case-map or |
|||
collating tables. |
|||
|
|||
o Function 66H (Get/Set Global Code Page) \(em gets or sets the code |
|||
page used by the kernel and by all devices. |
|||
|
|||
These functions support access to country-dependent information, all of |
|||
which resides in one file named country.sys. |
|||
|
|||
5.3 Font Files |
|||
|
|||
Font files, also called code page information files, contain the images of |
|||
code page character sets for use by console-screen or printer devices. |
|||
These font files are identified by a filename extension of .cpi. Four font |
|||
files are included with MS-DOS 3.3: |
|||
|
|||
Font file |
|||
Supported device |
|||
_ ________________________________________________________________ |
|||
|
|||
ega.cpi Color console used with an EGA card |
|||
|
|||
lcd.cpi Liquid crystal display |
|||
|
|||
4201.cpi IBM Proprinter |
|||
|
|||
5202.cpi Quietwriter III printer |
|||
|
|||
|
|||
5.3.1 Font File Structure |
|||
|
|||
The contents of printer or console-screen font files are structured as fol- |
|||
lows: |
|||
|
|||
+--------------------------------------+ |
|||
| 22-BYTE File Header | |
|||
+--------------------------------------+ |
|||
| WORD Information Header | |
|||
+--------------------------------------+ |
|||
| 13-BYTE Code Page Entry Header | |
|||
+--------------------------------------+ |
|||
| 6-BYTE Font Data Header | |
|||
+--------------------------------------+ |
|||
| Variable size Font Header(s) | |
|||
+--------------------------------------+ |
|||
|
|||
4 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
National Language Support |
|||
|
|||
_ ____________________________________ |
|||
|
|||
|
|||
|
|||
|
|||
Figure 5.1 Font File Structure |
|||
|
|||
The font file fields are described in the following sections. |
|||
|
|||
5.3.1.1 File Header |
|||
|
|||
Each file must begin with a file header that includes the following: |
|||
|
|||
Length |
|||
Parameter |
|||
_ ________________________________________________________________ |
|||
|
|||
8 BYTES File tag |
|||
|
|||
8 BYTES Reserved |
|||
|
|||
WORD Number of pointers |
|||
|
|||
2 WORDS Offset |
|||
|
|||
where: |
|||
|
|||
File tag begins with the byte 0FFH and is followed by a string "font " |
|||
(seven characters). |
|||
|
|||
Reserved is eight bytes of zeros. |
|||
|
|||
Number of pointers is the number of pointers in the header. For MS-DOS |
|||
3.3, the value of this word should be 1. |
|||
|
|||
Offset is the two-word offset from the beginning of the file. |
|||
|
|||
5.3.1.2 Information Header |
|||
|
|||
Following the file header is a one-word information header: |
|||
|
|||
Length |
|||
Parameter |
|||
_ ________________________________________________________________ |
|||
|
|||
WORD Number of code pages |
|||
|
|||
where: |
|||
|
|||
Number of code pages is the number of code page entries in the file. |
|||
|
|||
|
|||
5 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
5.3.1.3 Code Page Entry Header |
|||
|
|||
For each code page entry, a header in the following format is included in |
|||
the font file: |
|||
|
|||
Length |
|||
Parameter |
|||
_ ________________________________________________________________ |
|||
|
|||
WORD Length |
|||
|
|||
WORD Pointer |
|||
|
|||
WORD Device type |
|||
|
|||
8 BYTES Device subtype |
|||
|
|||
WORD Code page ID |
|||
|
|||
WORD Reserved |
|||
|
|||
2 WORDS Offset |
|||
|
|||
where: |
|||
|
|||
Length is the size of the code page entry header. |
|||
|
|||
Pointer points to the next code page entry header (last header=0, 0). |
|||
|
|||
Device type is 1 if the device is a console screen, or 2 if the device is a |
|||
printer. |
|||
|
|||
Device subtype names the type of console screen or printer. This field also |
|||
determines the name of the font file. For example, if the subtype is |
|||
"CGA," the font file name is cga.cpi |
|||
|
|||
Code page ID defines a valid three-digit code page identification number. |
|||
Valid code page numbers are 437, 850, 860, 863, and 865. |
|||
|
|||
Reserved is eight bytes of zeros. |
|||
|
|||
Offset is a pointer to the Font Data Header. |
|||
|
|||
5.3.1.4 Font Data Header |
|||
|
|||
The Font Data Header includes the following fields: |
|||
|
|||
Length |
|||
Parameter |
|||
_ ________________________________________________________________ |
|||
|
|||
WORD Reserved |
|||
|
|||
WORD Number of fonts |
|||
|
|||
|
|||
|
|||
6 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
National Language Support |
|||
|
|||
_ ____________________________________ |
|||
|
|||
WORD Length of font data |
|||
|
|||
where: |
|||
|
|||
Reserved must be 1. |
|||
|
|||
Number of fonts is equal to the number of fonts defined in the font file. |
|||
|
|||
Length of font data is equal to the size of the font-data portion of the font |
|||
file. |
|||
|
|||
5.3.1.5 Font Header |
|||
|
|||
The font-data portion of a font file will vary for each device. The struc- |
|||
ture of the font-data portion consists of a set of data for each font type. |
|||
The following illustrates the data portion of a font file for a console-screen |
|||
device: |
|||
|
|||
font_header: |
|||
db 16, 8 ; character pixels |
|||
; (rows, columns) |
|||
db 0, 0 ; aspect ratio (unused) |
|||
dw 256 ; number of characters in set |
|||
|
|||
|
|||
len_data equ ($ - font_header) |
|||
|
|||
|
|||
|
|||
|
|||
7 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
Chapter 5 |
|||
|
|||
National Language Support |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
5.1 Introduction 3 |
|||
|
|||
5.2 National Language Support Calls 3 |
|||
|
|||
5.3 Font Files 4 |
|||
|
|||
5.3.1 Font File Structure 4 |
|||
|
|||
5.3.1.1 File Header 5 |
|||
|
|||
5.3.1.2 Information Header 5 |
|||
|
|||
5.3.1.3 Code Page Entry Header 6 |
|||
|
|||
5.3.1.4 Font Data Header 6 |
|||
|
|||
5.3.1.5 Font Header 7 |
|||
|
|||
|
|||
|
|||
1 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
7 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
@ -0,0 +1,203 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
.Exe File Structure and Loading |
|||
|
|||
_ _______________________________________ |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
Note |
|||
|
|||
This chapter describes .exe file structure and loading procedures for |
|||
systems that use a version of MS-DOS earlier than 2.0. For MS-DOS |
|||
versions 2.0 and later, use Function 4B00H (Load and Execute a Pro- |
|||
gram) to load (or load and execute) an .exe file. |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
The .exe files produced by link consist of two parts: |
|||
|
|||
o Control and relocation information |
|||
|
|||
o The load module |
|||
|
|||
The control and relocation information is at the beginning of the file in an |
|||
area called the header. Immediately following this header is the load |
|||
module. |
|||
|
|||
6.1 Format of a File Header |
|||
|
|||
The header is formatted as follows (note that offsets are in hexadecimal): |
|||
|
|||
Offset |
|||
Contents |
|||
_ ________________________________________________________________ |
|||
|
|||
0-1 Must contain 4DH, 5AH. |
|||
|
|||
2-3 Number of bytes contained in last page; useful for reading |
|||
overlays. |
|||
|
|||
4-5 Size of the file in 512-byte pages, including the header. |
|||
|
|||
6-7 Number of relocation entries in table. |
|||
|
|||
8-9 Size of the header in 16-byte paragraphs. Used to locate the |
|||
beginning of the load module in the file. |
|||
|
|||
AH-BH Minimum number of 16-byte paragraphs required above the |
|||
end of the loaded program. |
|||
|
|||
CH-DH Maximum number of 16-byte paragraphs required above the |
|||
end of the loaded program. If both minalloc and maxalloc |
|||
are 0, the program is loaded as high as possible. |
|||
|
|||
EH-FH Initial value to be loaded into stack segment before starting |
|||
program execution. Must be adjusted by relocation. |
|||
|
|||
|
|||
|
|||
3 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
10-11 Value to be loaded into the SP register before starting pro- |
|||
gram execution. |
|||
|
|||
12-13 Negative sum of all the words in the file. |
|||
|
|||
14-15 Initial value to be loaded into the IP register before starting |
|||
program execution. |
|||
|
|||
16-17 Initial value to be loaded into the CS register before starting |
|||
program execution. Must be adjusted by relocation. |
|||
|
|||
18-19 Relative byte offset from beginning of run file to relocation |
|||
table. |
|||
|
|||
1AH-1BH The number of the overlay as generated by link. |
|||
|
|||
|
|||
6.2 The Relocation Table |
|||
|
|||
The relocation table that follows the formatted area above, consists of a |
|||
variable number of relocation items. Each relocation item contains two |
|||
fields: a two-byte offset value, followed by a two-byte segment value. |
|||
These two fields contain the offset into a word's load module. This item |
|||
requires modification before the module is given control. The following |
|||
steps describe this process: |
|||
|
|||
1. The formatted part of the header is read into memory. Its size is |
|||
1BH. |
|||
|
|||
2. MS-DOS allocates a portion of memory depending on the size of |
|||
the load module and the allocation numbers (AH-BH and CH-DH). |
|||
MS-DOS then attempts to allocate 0FFFH paragraphs. This |
|||
attempt always fails, and returns the size of the largest free block. |
|||
If this block is smaller than minalloc and loadsize, there is no |
|||
memory error. But if this block is larger than maxalloc and |
|||
loadsize, MS-DOS allocates (maxalloc + loadsize). Otherwise, it |
|||
allocates the largest free block of memory. |
|||
|
|||
3. A Program Segment Prefix is built in the lowest part of the allo- |
|||
cated memory. |
|||
|
|||
4. MS-DOS calculates the load module size (using offsets 4-5 and 8-9) |
|||
by subtracting the header size from the file size. The actual size is |
|||
adjusted down based on the contents of offsets 2-3. The operating |
|||
system determines (based on the setting of the high/low load |
|||
switch) an appropriate segment, called the start segment, where it |
|||
loads the load module. |
|||
|
|||
5. The load module is read into memory beginning with the start seg- |
|||
ment. |
|||
|
|||
|
|||
|
|||
4 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
.Exe File Structure and Loading |
|||
|
|||
_ _______________________________________ |
|||
|
|||
6. The items in the relocation table are read into a work area. |
|||
|
|||
7. MS-DOS adds the segment value of each relocation table item to |
|||
the start segment value. This calculated segment, plus value, |
|||
points to the module to which the start segment value is added. |
|||
The result is then placed back into the word in the load module. |
|||
|
|||
8. Once all relocation items have been processed, the operating sys- |
|||
tem sets the SS and SP registers, using the values in the header. |
|||
MS-DOS then adds the start segment value to SS and sets the ES |
|||
and DS registers to the segment address of the Program Segment |
|||
Prefix. The start segment value is then added to the header CS |
|||
register value. The result, along with the header IP value, is the |
|||
initial CS:IP to transfer to before starting execution of the pro- |
|||
gram. |
|||
|
|||
|
|||
|
|||
5 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
Chapter 6 |
|||
|
|||
.Exe File Structure and Loading |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
6.1 Format of a File Header 3 |
|||
|
|||
6.2 The Relocation Table 4 |
|||
|
|||
|
|||
|
|||
1 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
5 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
2555
PROGREF/7_OMF.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,440 @@ |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
Programming Hints |
|||
|
|||
_ ______________________________ |
|||
|
|||
|
|||
8.1 Introduction |
|||
|
|||
This chapter describes recommended MS-DOS 3.3 programming pro- |
|||
cedures. By using these programming hints, you can ensure compatibility |
|||
with future versions of MS-DOS. |
|||
|
|||
The hints are organized in the following categories: |
|||
|
|||
o Interrupts |
|||
|
|||
o System Calls |
|||
|
|||
o Device Management |
|||
|
|||
o Memory Management |
|||
|
|||
o Process Management |
|||
|
|||
o File and Directory Management |
|||
|
|||
o Miscellaneous |
|||
|
|||
|
|||
8.2 Interrupts |
|||
|
|||
o Never explicitly issue Interrupt 22H (Terminate Process Exit |
|||
Address). |
|||
|
|||
Only the DOS should do this. To change the terminate address, |
|||
use Function 35H (Get Interrupt Vector) to get the current address |
|||
and save it, then use Function 25H (Set Interrupt Vector) to |
|||
change the Interrupt 22H entry in the vector table to point to the |
|||
new terminate address. |
|||
|
|||
o Use Interrupt 24H (Critical-Error-Handler Address) with care. The |
|||
Interrupt 24H handler must preserve the ES register. |
|||
|
|||
An Interrupt 24H handler can issue only the system calls 01H-0CH. |
|||
Making any other calls destroys the MS-DOS stack and prevents |
|||
successful use of the Retry or Ignore options. |
|||
|
|||
When using the Retry or Ignore options, you must preserve the SS, |
|||
SP, DS, BX, CX, and DX registers. |
|||
|
|||
o When an Interrupt 24H (Critical-Error-Handler Address) is |
|||
received, always IRET back to MS-DOS with one of the standard |
|||
responses. |
|||
|
|||
Programs that do not IRET from Interrupt 24H leave the system in |
|||
an unpredictable state until a function call other than 01H-0CH is |
|||
made. The Ignore option may leave incorrect or invalid data in |
|||
|
|||
3 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
internal system buffers. |
|||
|
|||
o Avoid trapping Interrupt 23H (CONTROL-C Handler Address) and |
|||
Interrupt 24H (Critical-Error-Handler Address). Don't rely on trap- |
|||
ping errors via Interrupt 24H as part of a copy protection scheme. |
|||
|
|||
These methods might not be included in future releases of |
|||
MS-DOS. |
|||
|
|||
o A user program must never issue Interrupt 23H (CONTROL-C |
|||
Handler Address). |
|||
|
|||
Only MS-DOS may issue Interrupt 23H. |
|||
|
|||
o Save any registers that your program uses before issuing Interrupt |
|||
25H (Absolute Disk Read) or Interrupt 26H (Absolute Disk Write). |
|||
|
|||
These interrupts destroy all registers except for the segment regis- |
|||
ters. |
|||
|
|||
Avoid writing or reading an interrupt vector directly to or from |
|||
memory. |
|||
|
|||
o Use Functions 25H and 35H (Set Interrupt Vector and Get Inter- |
|||
rupt Vector) to set and get values in the interrupt table. |
|||
|
|||
|
|||
8.3 System Calls |
|||
|
|||
o Use new system calls. |
|||
|
|||
Avoid using system calls that have been superseded by new calls |
|||
unless the program must maintain backward compatibility with |
|||
MS-DOS versions before 2.0. See Section 1.9, "Old System Calls", |
|||
for a list of these new calls. |
|||
|
|||
o Avoid using functions 01H-0CH and 26H (Create New PSP). |
|||
|
|||
Use the new "tools" approach for reading and writing on standard |
|||
input and output. Use Function 4BH (Load and Execute Program) |
|||
instead of 26H to execute a child process. |
|||
|
|||
o Use file-sharing calls if more than one process is in effect. |
|||
|
|||
For more information, see File Sharing, in Section 1.5.2, "File- |
|||
Related Function Requests." |
|||
|
|||
o Use networking calls where appropriate. |
|||
|
|||
Some forms of IOCtl can only be used with Microsoft Networks. |
|||
For more information, and a list of these calls, see Section 1.6, |
|||
"Microsoft Networks," |
|||
|
|||
4 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
Programming Hints |
|||
|
|||
_ ______________________________ |
|||
|
|||
o When selecting a disk with Function 0EH (Select Disk), treat the |
|||
value returned in AL with care. |
|||
|
|||
The value in AL specifies the maximum number of logical drives; it |
|||
does not specify which drives are valid. |
|||
|
|||
|
|||
8.4 Device Management |
|||
|
|||
o Use installable device drivers. |
|||
|
|||
MS-DOS provides a modular device driver structure for the BIOS, |
|||
allowing you to configure and install device drivers at boot time. |
|||
Block device drivers transmit a block of data at a time, while char- |
|||
acter device drivers transmit a byte of data at a time. |
|||
|
|||
Examples of both types of device drivers are given in Chapter 2, "- |
|||
MS-DOS Device Drivers." |
|||
|
|||
o Use buffered I/O. |
|||
|
|||
The device drivers can handle streams of data up to 64K bytes. To |
|||
improve performance when sending a large amount of output to |
|||
the screen, you can send it with one system call. |
|||
|
|||
o Programs that use direct console I/O via Function 06H and 07H |
|||
(Direct Console I/O and Direct Console Input) and that want to |
|||
read CONTROL-C as data should ensure that CONTROL-C checking is |
|||
off. |
|||
|
|||
The program should ensure that CONTROL-C checking is off by using |
|||
Function 33H (CONTROL-C Check). |
|||
|
|||
o Be compatible with international support. |
|||
|
|||
To provide support for international character sets, MS-DOS |
|||
recognizes all possible byte values as significant characters in |
|||
filenames and data streams. MS-DOS versions before 2.0 ignored |
|||
the high bit in the MS-DOS filename. |
|||
|
|||
|
|||
8.5 Memory Management |
|||
|
|||
o Use memory management. |
|||
|
|||
MS-DOS keeps track of allocated memory by writing a memory |
|||
control block at the beginning of each area of memory. Programs |
|||
should use Functions 48H (Allocate Memory), 49H (Free Allocated |
|||
Memory), and 4AH (Set Block) to release unneeded memory. |
|||
|
|||
5 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
This allows for future compatibility. For more information, see |
|||
Section 1.3, "Memory Management." |
|||
|
|||
o Use only allocated memory. |
|||
|
|||
Don't directly access memory that was not provided as a result of a |
|||
system call. Do not use fixed addressing, use only relative refer- |
|||
ences. |
|||
|
|||
A program that uses memory that has not been allocated to it may |
|||
destroy other memory control blocks or cause other applications to |
|||
fail. |
|||
|
|||
|
|||
8.6 Process Management |
|||
|
|||
o Use Function 4BH (Load and Execute Program, or EXEC) to load |
|||
and execute programs. |
|||
|
|||
EXEC is the preferred call to use when loading programs and pro- |
|||
gram overlays. Using the EXEC call instead of hard-coding infor- |
|||
mation about how to load an .exe file (or always assuming that |
|||
your file is a .com file) isolates your program from changes in .exe |
|||
file formats and future releases of MS-DOS. |
|||
|
|||
o Use Function 31H (Keep Process), instead of Interrupt 27H (Ter- |
|||
minate But Stay Resident). |
|||
|
|||
Function 31H allows programs that are greater than 64K bytes to |
|||
terminate and stay resident. |
|||
|
|||
o Programs should terminate using Function 4CH (End Process). |
|||
|
|||
Programs that terminate by one of the following must ensure that |
|||
the CS register contains the segment address of the PSP: |
|||
|
|||
o A long jump to offset 0 in the PSP |
|||
|
|||
o Issuing an Interrupt 20H with CS:0 pointing at the PSP |
|||
|
|||
o Issuing an Interrupt 21H with AH=0, CS:0 pointing at the PSP |
|||
|
|||
o A long call to location 50H in the PSP with AH=0 |
|||
|
|||
|
|||
|
|||
6 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
Programming Hints |
|||
|
|||
_ ______________________________ |
|||
|
|||
|
|||
8.7 File and Directory Management |
|||
|
|||
o Use the MS-DOS file management system. |
|||
|
|||
Using the MS-DOS file system ensures program compatibility with |
|||
future MS-DOS versions through compatible disk formats and con- |
|||
sistent internal storage. |
|||
|
|||
o Use file handles instead of FCBs. |
|||
|
|||
A handle is a 16-bit number that MS-DOS returns when a file is |
|||
opened or created using Functions 3CH, 3DH, 5AH, or 5BH (Create |
|||
Handle, Open Handle, Create Temporary File, or Create New File). |
|||
The MS-DOS file-related function requests that use handles are |
|||
listed in Table 1.5 in Chapter 1, "System Calls." |
|||
|
|||
Although the default maximum number of open files is 20, this |
|||
limit can be raised to 64K by Function 67H (Set Handle Count). |
|||
For more information on this system call, see Chapter 1, "System |
|||
Calls." |
|||
|
|||
You should use these calls instead of the old file-related functions |
|||
that use FCBs (file control blocks). This is because a file operation |
|||
can simply pass its handle rather than maintaining FCB informa- |
|||
tion. If you must use FCBs, be sure the program closes them and |
|||
does not move them around in memory. |
|||
|
|||
o Close files that have changed in length before issuing an Interrupt |
|||
20H (Program Terminate), Function 00H (Terminate Program), |
|||
Function 4CH (End Process), or Function 0DH (Reset Disk). |
|||
|
|||
If you do not close a changed file, its length will not be recorded |
|||
correctly in the directory. |
|||
|
|||
o Close files when they are no longer needed. |
|||
|
|||
Closing unneeded files increases efficiency in a networking environ- |
|||
ment. |
|||
|
|||
o If a program does use FCBs, that program should not close an FCB |
|||
file and then continue writing to it. This practice will not work in |
|||
a network environment, and is not recommended under any cir- |
|||
cumstances. |
|||
|
|||
o Change disks only if all files on the disk are closed. |
|||
|
|||
If you don't close all the files, any information in internal system |
|||
buffers may be written incorrectly to a changed disk. |
|||
|
|||
|
|||
|
|||
7 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
8.7.1 Locking Files |
|||
|
|||
o Programs should not rely on being denied access to a locked region. |
|||
|
|||
To determine the status of a region, first, attempt to lock it, then |
|||
examine its error code. |
|||
|
|||
o Programs should not close a file with a locked region or terminate |
|||
with an open file that contains a locked region. |
|||
|
|||
The result of this procedure is undefined. Programs that might be |
|||
terminated by an Interrupt 23H or Interrupt 24H (CONTROL-C |
|||
Handler Address or Critical-Error-Handler Address) should trap |
|||
these interrupts and unlock any locked regions before exiting. |
|||
|
|||
|
|||
8.8 Miscellaneous |
|||
|
|||
o Avoid timing dependencies. |
|||
|
|||
Various machines use CPUs of different speeds. Also, programs |
|||
that rely upon the speed of the clock for timing are not dependable |
|||
in a networking environment. |
|||
|
|||
o Use the documented interface to the operating system. If either |
|||
the hardware or media change, the operating system can use the |
|||
features without modification. |
|||
|
|||
Don't use the ROM support provided by the OEM (Original Equip- |
|||
ment Manufacturer). |
|||
|
|||
Don't directly address the video memory. |
|||
|
|||
Don't use undocumented function calls, interrupts, or features. |
|||
|
|||
These items may change or may not exist in future MS-DOS ver- |
|||
sions. If you do use these features, you will make your program |
|||
highly non-portable. |
|||
|
|||
o Use the .exe format rather than the .com format. |
|||
|
|||
.Exe files are relocatable; .com files are direct memory images that |
|||
load at a specific place and have no room for additional control |
|||
information. .Exe files have headers that can be expanded for com- |
|||
patibility with future MS-DOS versions. |
|||
|
|||
o Use the environment to pass information to applications. |
|||
|
|||
The environment allows a parent process to pass information to a |
|||
child process. The command.com file is usually the parent process |
|||
to every application, so it can easily pass default drive and path |
|||
information to the application. |
|||
|
|||
8 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
Programming Hints |
|||
|
|||
_ ______________________________ |
|||
|
|||
|
|||
Chapter 8 |
|||
|
|||
Programming Hints |
|||
|
|||
_ ________________________________________________________________ |
|||
|
|||
8.1 Introduction 3 |
|||
|
|||
8.2 Interrupts 3 |
|||
|
|||
8.3 System Calls 4 |
|||
|
|||
8.4 Device Management 5 |
|||
|
|||
8.5 Memory Management 5 |
|||
|
|||
8.6 Process Management 6 |
|||
|
|||
8.7 File and Directory Management 7 |
|||
|
|||
8.7.1 Locking Files 8 |
|||
|
|||
8.8 Miscellaneous 8 |
|||
|
|||
|
|||
|
|||
9 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
|||
_ ______________ |
|||
|
|||
|
|||
9 |
|||
|
|||
_ _ | | _ _ |
|||
|
|||
|
|||
|
1203
PROGREF/INDEX.A
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,238 @@ |
|||
DOCUMENTATION FOR MS-DOS 3.30 BUGFIX DISKETTE |
|||
|
|||
This diskette contains code for bugfixes in the MS-DOS 3.30 Release that |
|||
are corrected in the Microsoft MS-DOS 3.30 Packaged Product. These may also |
|||
be corrected in an OEM's 3.30 product by utilizing the code on this diskette. |
|||
To to this, just copy the files on this disk over the corresponding files in |
|||
the DISTRIBUTION DISKETTE tree before doing the builds and making up your |
|||
OEM product. |
|||
|
|||
********************************************************************* |
|||
|
|||
Problem: FDISK: logical drive creation doesn't show on fdisk. |
|||
|
|||
Run FDISK. Create a primary partition and then an extended |
|||
partition. While creating the extended partition the menu |
|||
sequence to create logical drives in the extended partition |
|||
should turn up, but it doesn't. |
|||
|
|||
Solution: |
|||
|
|||
Difference in versions of the C compiler (we used C 4.0 |
|||
instead of C 3.0) exposed a bug in the forcing of a constant |
|||
to a long unsigned number. The two compilers treat this |
|||
differently. |
|||
|
|||
Changes made were: |
|||
|
|||
a) FDISK.H : line 14 DOS_MAX = 64*1024 ....old |
|||
DOS_MAX = 65536L ....new |
|||
b) INT13.C : (not related to problem, was just something |
|||
noticed along the way) |
|||
line 148 max_head[0] ...old |
|||
max_head[i] ...new |
|||
|
|||
|
|||
************************************************************************* |
|||
|
|||
MS-DOS 3.30 Beta FORMAT d: /S on very small partitions problem |
|||
|
|||
Description: Attempting to do a FORMAT d: /S on a hard disk partition |
|||
that is smaller than the space required for the system files |
|||
resulted in the system files overwritting other partitions |
|||
and format reporting approximately 4 GB of free space. |
|||
|
|||
Problem: The problem is simply that a check is never done to see if |
|||
enough free space exists to load the system files after the |
|||
formatting is done. This problem also occurs on PC-DOS 3.30. |
|||
|
|||
Solution: The solution is to add a check to make sure that there is |
|||
enough free space for the system files before we attempt to |
|||
copy them. This was done by adding a routine called |
|||
CHKSPACE which is called just before WRITEDOS in the module |
|||
FORMAT.ASM. CHKSPACE uses DOS interrupt Get Disk Free Space |
|||
and compares the number of available clusters with the number |
|||
required for the system files. If the amount of free space |
|||
is greater than or equal to the amount of space required by |
|||
the system files, CHKSPACE returns with the carry flag clear. |
|||
Otherwise, it returns withe the carry flag set. Following the |
|||
call to CHKSPACE is a check for carry. If carry is set, the |
|||
message "No room for system on destination disk" is printed |
|||
and the system files are not copied. If carry is not set, |
|||
control continues on to WRITEDOS. |
|||
|
|||
Modules: Fixing this bug required changing FORMAT.ASM, MESSAGES.ASM, |
|||
and MESSAGES.INC. |
|||
|
|||
Documentation: The entry for "No room for system on destination disk" in |
|||
the messages section of the DOS manual states that this error |
|||
message is the result of a SYS command. This should be changed |
|||
to read SYS or FORMAT. In addition, the entry assumes that the |
|||
destination disk is always a diskette and suggests that the |
|||
appropriate action is to format a blank diskette with the /S |
|||
option. This will do you no good if you are trying to add the |
|||
system files to a hard disk partition. The recommended action |
|||
should include using FDISK to make the partition larger and |
|||
retrying the command if the error occured while attempting to |
|||
format a hard disk partition with the /S option. |
|||
|
|||
|
|||
************************************************************************** |
|||
|
|||
Problem: Volumes in abundance cause boot problems. |
|||
|
|||
Create primary partition and then the extended partition. |
|||
in the extended partition create the maximum number of |
|||
volumes permitted, i.e. 23. Try booting machine off a 3.30 |
|||
floppy the machine is down on its knees. Problem doesn't |
|||
exist if you have volumes < 23. Problem only on 6M AT. |
|||
|
|||
Solution: |
|||
|
|||
MSBIO2 has a buffer of 23 BDSMs at the end. MSBIO2 is followed |
|||
by MSHARD. Since the BDSMs are substancially long in size |
|||
the bios relocates MSHARD to the paragraph boundary after |
|||
the last BDSM used. This works fine for volumes < 23. |
|||
However if all 23 BDSMs are used up MSHARD is relocated to |
|||
the next para boundary which happens to be within MSHARD |
|||
itself. So MSHARD ends up destroying itself. |
|||
|
|||
Fix - a para buffer between the last BDSM and MSHARD in |
|||
MSBIO2.ASM. |
|||
|
|||
|
|||
********************************************************************** |
|||
|
|||
Problem: |
|||
|
|||
On exercising last two sysinit error messages dos code is |
|||
displayed instead of just the messages. |
|||
|
|||
Solution: |
|||
|
|||
In calculating the location where to load dos, a constant is |
|||
used to indicate the size of the sysinit segment. this is |
|||
different for us. |
|||
|
|||
Changes: In msequ.inc changed sysize from 200 to 203. |
|||
|
|||
Further changes planned: Change the sysize constant to a variable sizing |
|||
the sysinit segment. |
|||
|
|||
|
|||
************************************************************************* |
|||
|
|||
Problem: type filename > "=" hangs the system. |
|||
|
|||
Not only = in quotes but any delimitor causes problems. |
|||
|
|||
This comes from a basic lack of consistency in the treatment |
|||
of the role of the " character. In command line parsing anything |
|||
between " ----- " is not interpreted. But in forming filenames |
|||
a " is taken as a valid character. Once the '>' character is |
|||
reached the parser begins forming the filename and takes " as |
|||
the first character. The following = is taken as a delimitor and |
|||
the filename ended. When the filename is formed the processing |
|||
returns to the command line parsing main routine and sees the |
|||
next ". After this it just moves anything that comes along till |
|||
it meets the next quote and ends up destroying the stack. |
|||
|
|||
Solution: changed filename parsing code to test for quote and decrement |
|||
the number of quotes. File changed - tmisc1.asm |
|||
|
|||
|
|||
************************************************************************ |
|||
|
|||
Problem: DOS FDISK creates partition which overlaps Xenix partition. |
|||
|
|||
Create bad track table (xenix) and then a xenix partition |
|||
which occupies whole disk. then boot dos and create partiton |
|||
asking it to use all of the space for dos. It just does that |
|||
overlapping the partition over the xenix partition. |
|||
|
|||
Problem: 3.3 fdisk was not handling the no space condition. |
|||
|
|||
Solution: |
|||
|
|||
added code to detect no space condition and report error on |
|||
such a condition. files changed fdisk.c and space.c. also |
|||
when dos tries to create primary partition with a space |
|||
requested from the user added error message when there is |
|||
no space. |
|||
|
|||
|
|||
************************************************************************ |
|||
|
|||
Problem: |
|||
|
|||
The bug is that the routine make_partition had been checking for a free |
|||
"slot" in the Master Boot Record and aborting the menu if there was none. |
|||
This action is not desirable if the user wishes to create a Logical DOS |
|||
volume in an existing Extended DOS Partition. |
|||
|
|||
There are several circumstances where this problem becomes evident. |
|||
Probably the most common problem would be experienced on a large hard disk with several |
|||
DOS partitions defined on it (COMPAQ is not the only OEM to support |
|||
multiple DOS partitions on a hard disk...). |
|||
|
|||
Consider a disk with 4 DOS partitions defined on it and the user wants to |
|||
delete ONE of the DOS partitions so that an Extended DOS partition may be |
|||
defined. After doing this, the ext_create_partition routine allows the |
|||
user to define logical DOS volumes. |
|||
|
|||
The user decides that the Logical DOS Volumes he previously created are not |
|||
satisfactory after having left FDISK, perhaps he had previously defined |
|||
only one Logical DOS Volume and it did not use the entire Extended |
|||
Partition. |
|||
|
|||
This time FDISK will not allow the user to select the Create Logical |
|||
Volume menu option because there are no free "slots" in the Master Boot |
|||
Record although there may well be plenty of space within the Extended DOS |
|||
partition. |
|||
|
|||
NOTE: This problem also occurs with the OS/2 implementation of FDISK. |
|||
|
|||
|
|||
************************************************************************* |
|||
|
|||
Problem: Extend file handle count is broken. |
|||
|
|||
Solution: The para calculation code in handle.asm to calculate the number |
|||
of paragraphs needed is coded wrongly. For handle values |
|||
less than a para away from the maximum this will cause a carry. |
|||
The subsequent rotate by 4 should shift the carry in. IBM 3.3 |
|||
doesn't use the appropriate rotate instruction. |
|||
|
|||
************************************************************************** |
|||
|
|||
Problem: Disk info initialisation in extended volume wrongly done. |
|||
|
|||
The problem involves creation of Logical DOS Volumes in |
|||
an Extended DOS Partition. As you know, each Logical DOS Volume |
|||
has a "dummy" Master Boot Record which is necessary to define |
|||
the extent of its Logical Volume and to indicate the location of |
|||
the next Logical Volume (if one exists). The "dummy" Master |
|||
Boot Record for each Logical Volume (except the last one) |
|||
contains an entry with a system indicator byte with the value of |
|||
5 - this is the pointer to the next volume. The END_HEAD number |
|||
of this type 5 record is ONE greater than the greatest physical |
|||
head number on the drive. |
|||
|
|||
|
|||
This occurs because the entries in the "max_head" array are |
|||
initialized to be one more than the greatest physical head |
|||
number in the routine "get_disk_info()" in the file INT13.C for |
|||
use in calculations. The routine "write_ext_boot_to_disk" in |
|||
the file DISKOUT.C does not subtract one from the max_head value |
|||
before placeing it into the extended boot record - which is what |
|||
results in the "End_Head" field being wrong for the type 5 |
|||
record. |
|||
|
|||
The line in "write_ext_boot_to_disk" where the subtraction |
|||
should take place is shown below... |
|||
|
|||
/* End head */ |
|||
boot_record[0x1D3] = max_head[disk]; |
|||
|
|||
Solution: As mentioned above the line given above should be |
|||
boot_record[0x1d3] = max_head[disk] - 1; |
@ -0,0 +1,776 @@ |
|||
SUPPLEMENT TO MS-DOS 2.XX/3.XX ADAPTATION GUIDE |
|||
|
|||
DOCUMENTATION FOR THE MS-DOS 3.30 DISTRIBUTION DISKETTES |
|||
|
|||
This documentation consists of release layout information, a diskette |
|||
directory, instructions for use, and a list of differences between the |
|||
CLONE VERSION and the MS VERSION. |
|||
|
|||
1. MS-DOS 3.30 RELEASE LAYOUT |
|||
|
|||
------------------------------------------------------------------------------ |
|||
| SOURCE CODE | |
|||
| | |
|||
| 10 96 TPI diskettes | |
|||
| readme.src | |
|||
| Not generally available to OEMS - For Customer Support/Maintenance | |
|||
------------------------------------------------------------------------------ |
|||
[] [] [] [] [] |
|||
[] [] [] [] [] |
|||
SWITCHES SET FOR SWITCHES SET FOR SWITCHES SET FOR |
|||
MS VERSION CLONE VERSION CLONE VERSION |
|||
[] [] [] [] [] |
|||
\[]/ [] \[]/ [] [] |
|||
\/ [] \/ [] BUGFIXES |
|||
------------------- [] ------------------- [] APPLIED |
|||
| | [] | | [] [] |
|||
| MS VERSION | [] | CLONE VERSION | [] [] |
|||
| SUPPLEMENTAL | [] | MESSAGE MODULES | [] [] |
|||
| MESSAGE MODULES | [] | | [] [] |
|||
| | [] | For all files | [] [] |
|||
| COMMAND.COM | [] | except for those| [] [] |
|||
| DEBUG.EXE | [] | with complete | [] [] |
|||
| MORE.COM | [] | source on the | [] [] |
|||
| RECOVER.EXE | [] | CLONE VERSION | [] [] |
|||
| SHARE.EXE | [] | DISTRIBUTION | [] [] |
|||
| MSDOS.SYS | [] | DISKETTES | [] [] |
|||
| | [] | readme.mes | [] [] |
|||
|1 96 TPI diskette| [] |1 96 TPI diskette| [] [] |
|||
|avail. on request| [] |avail. on request| [] [] |
|||
------------------- [] ------------------- [] [] |
|||
[] [] [] [] [] |
|||
\[]/ \[]/ \[]/ \[]/ \[]/ |
|||
\/ \/ \/ \/ \/ |
|||
------------------------ ------------------------- ------------------------- |
|||
| | | | | | |
|||
| MS VERSION | | CLONE VERSION | |MICROSOFT MS-DOS 3.30 | |
|||
| SUPPLEMENTAL | | DISTRIBUTION DISKETTES| | PACKAGED PRODUCT | |
|||
| DISTRIBUTION DISKETTE| | readme.dis | | | |
|||
| 1 96 TPI diskette | | 2 96 TPI diskettes | | 2 48 TPI DISKETTES | |
|||
| Available on request | | In OEM Adaptation Kit | | In OEM Adaptation Kit : |
|||
------------------------ ------------------------- ------------------------- |
|||
------------------------- |
|||
| BUGFIX DISKETTE | |
|||
| FIXES THAT MAY BE | |
|||
|APPLIED TO MS-DOS 3.30 | |
|||
| readme.bf | |
|||
| 1 96 TPI diskette | |
|||
| In OEM Adaptation Kit | |
|||
------------------------- |
|||
|
|||
|
|||
|
|||
Additional Materials that are part of the OEM Adaptation Kit: |
|||
|
|||
2.XX/3.XX Adaptation Guide 1 96 TPI diskette |
|||
|
|||
Machine Readable Documentation |
|||
User's Guide/User's Reference 2 96 TPI diskette |
|||
Programmer's Reference |
|||
|
|||
Hard Copy Documentation |
|||
User's Guide |
|||
User's Reference |
|||
Programmer's Reference |
|||
|
|||
|
|||
Additional Material that is available on request through an OEM's |
|||
OEM Account Manager: |
|||
|
|||
1. Undocumented System Calls Information |
|||
2. Microsoft MASM 4.00 Retail Package |
|||
|
|||
(Most OEMS either already have these two items or do not have a use for them) |
|||
|
|||
|
|||
The CLONE VERSION DISTRIBUTION DISKETTES contain the files that were produced |
|||
from MS-DOS SOURCE CODE assembled with the IBMVER switch on but the |
|||
IBMCOPYRIGHT switch off. They contain full SOURCE CODE to IO.SYS, MSBOOT, |
|||
FORMAT.EXE, PRINT.EXE, SORT.EXE and partial source code to MSDOS.SYS to allow |
|||
for the customization of DOSMES.INC. MSDOS32101 is a bootable disk. |
|||
|
|||
The MS VERSION SUPPLEMENTAL DISKETTE contains files that were produced from |
|||
MS-DOS SOURCE CODE assembled with the MS-VER switch on and the IBMVER and |
|||
IBMCOPYRIGHT switch off. They contain the executables for the four files DEBUG, |
|||
MORE, RECOVER and SHARE as well as partial source for MSDOS.SYS to allow for |
|||
its customization. These are all the files with version switches in them except |
|||
for the files with complete source on the CLONE VERSION. |
|||
|
|||
The MS-DOS 3.30 PACKAGED PRODUCT contains file that were produced from MS-DOS |
|||
SOURCE CODE assembled with the IBMVER switch on but the IBMCOPYRIGHT |
|||
switch off. These two disks that are identical to the disks in the manufactured |
|||
packaged product. There is a boot disk and supplemental disk. |
|||
|
|||
The CLONE VERSION MESSAGE MODULES contain all the source code that must be |
|||
modified for translation to a language other than English. |
|||
These message source modules can be modified, then assembled and linked with the |
|||
object modules that are provided to make the executables. The object modules |
|||
in this release were made from MS-DOS SOURCE CODE assembled with IBMVER switch |
|||
on and the MSVER and IBMCOPYRIGHT switches off. Code is provided to make all |
|||
the executables on the CLONE VERSION DISTRIBUTION DISKETTES except for |
|||
the files that have complete source provided on the CLONE VERSION DISTRIBUTION |
|||
DISKETTES: IO.SYS, MSBOOT.BIN, FORMAT.EXE, PRINT.EXE, SORT.EXE, SYS.COM, and |
|||
MSDOS.SYS (partial source). |
|||
|
|||
Microsoft now offers complete translations including documentation for the |
|||
following languages: French, German, Spanish, Portuguese, Italian and Dutch. |
|||
OEMs who would like one or more of these translations added to their OEM |
|||
contract should contact their Microsoft OEM Account Manager. |
|||
|
|||
MS VERSION SUPPLEMENTAL MESSAGE MODULES contain all the source code that |
|||
must be modified for translation to a language other than English for the |
|||
six files: COMMMAND.COM, DEBUG.EXE, MORE.COM, RECOVER.EXE, SHARE.EXE and |
|||
MSDOS.SYS. They are used the same way as the CLONE VERSION MESSAGE MODULES, |
|||
except the the files they are linked to have been assembled with the |
|||
MSVER switch on. |
|||
|
|||
The MS-DOS CLONE VERSION DISTRIBUTION DISKETTES, and the PACKAGE PRODUCT |
|||
DISKETTES are provided as a part the MS-DOS 3.30 Standard OEM ADAPATION KIT. |
|||
|
|||
The CLONE VERSION MESSAGE MODULES, the MS VERSION SUPPLEMENTAL MESSAGE MODULES |
|||
and the MSVER SUPPLEMENTAL DISTRIBUTION DISKETTE, MODULES may be available to |
|||
an OEM under special conditions by request through their Microsoft OEM Account |
|||
Manager. |
|||
|
|||
The SOURCE CODE release is not generally available to OEMS, however, it is |
|||
archived for support purposes by OEM Customer Support. |
|||
|
|||
The BUGFIX DISKETTE contains code that fixes certain known problems in the |
|||
MS-DOS 3.30 Release. These fixes have been applied to the MS-DOS 3.30 |
|||
PACKAGED PRODUCT, but were not applied to the the MS-DOS 3.30 OEM Release |
|||
to maintain IBM COMPATIBILITY. An OEM can use this code to apply these |
|||
bugfixes to their product. The specific bugs are described in the release |
|||
notes and in the the README.BF file on the BUGFIX DISKETTE. |
|||
|
|||
|
|||
|
|||
2. Diskette Directories |
|||
|
|||
MS-DOS 3.20 CLONE VERSION DISTRIBUTION DISKETTES MS330DIS01 |
|||
|
|||
io.sys system file - BIOS |
|||
msdos.sys system file - DOS |
|||
command.com command interpreter |
|||
|
|||
distrib\bin <dir> |
|||
|
|||
append.com utility to set a search path for data files |
|||
assign.com utility to assign a drive letter to a different drive |
|||
attrib.exe utility to change or display a file's attribue (read/read only) |
|||
backup.com utility to backup one or more files from one disk to another |
|||
chkdsk.com utility to scan disks, check for allocation errors & repair them |
|||
debug.com utility for debugging |
|||
diskcomp.com utility to compare to contents of one disk with another |
|||
diskcopy.com utility to copy disks formatting when necessary |
|||
edlin.com line editor |
|||
exe2bin.exe utility to convert .EXE files to .COM files |
|||
fdisk.com utility to configure hard disk |
|||
find.exe filter to find text strings in files |
|||
format.com utility to format disks |
|||
graftabl.com graphic character generation driver |
|||
graphics.com utility to print a graphics display on a printer |
|||
join.exe utility to join a drive to a specific pathname |
|||
keyb.com utility to replace ROM resident english keyboard program with |
|||
non-english keyboard program |
|||
label.exe utility to change or create a disk volume ID |
|||
link.exe linker 2.40 (part of the MS-DOS 3.30) product |
|||
mode.com utility to configure parallel and serial ports |
|||
more.com utility to send output to the console one screen at a time |
|||
nlsfunc.exe utiltiy to provide support for extended country information |
|||
print.com utility to print text files on a line printer |
|||
recover.com utility to recover disk directory |
|||
replace.exe utility to update previous verison on files on a disk |
|||
restore.exe utility to restore files that were backed up with backup.exe |
|||
share.exe utility to install file sharing and locking |
|||
sort.exe utility to read standard input, sort data and write to a device |
|||
subst.exe utility to substitute a string alias for a pathname |
|||
sys.com utility to transfer msdos system files |
|||
tree.com utility to display the directory structure & contents of a drive |
|||
xcopy.exe utility to copy files, directories and lower level directories |
|||
|
|||
|
|||
dev <dir> |
|||
|
|||
ansi.sys installable console device driver |
|||
country.sys used to identify the date, time, collating sequence, |
|||
capitalization and folding format for a given country |
|||
display.sys allows use of code page switching for the display |
|||
driver.sys installable device driver to support external drives |
|||
keyboard.sys allows use of code page switch for the keyboard |
|||
printer.sys allows use of code page switching for the printer |
|||
ramdrive.sys installable RAM disk device driver |
|||
vdisk.sys installable RAM disk device driver |
|||
|
|||
src <dir> |
|||
|
|||
makefile builds all CLONE VERSION DISTRIBUTION buildables |
|||
|
|||
src\bios <dir> |
|||
|
|||
biomes.inc io.sys include file |
|||
biostruc.inc io.sys include file |
|||
clocksub.inc io.sys include file |
|||
cmosequ.inc io.sys include file |
|||
dskprm.inc io.sys include file |
|||
jumpmac.inc io.sys include file |
|||
locscr exe2bin location script |
|||
makefile io.sys link script |
|||
ms96tpi.inc io.sys include file |
|||
msaux.asm io.sys source file |
|||
msbds.inc io.sys include file |
|||
msbio.lnk msbio.link script |
|||
msbio1.asm io.sys source file |
|||
msbio2.asm io.sys source file |
|||
msclock.asm io.sys source file |
|||
mscon.asm io.sys source file |
|||
msdata.inc io.sys include file |
|||
msdisk.asm io.sys source file |
|||
msequ.inc io.sys include file |
|||
msextrn.inc io.sys include file |
|||
msgroup.inc io.sys include file |
|||
mshard.asm io.sys source file |
|||
msinit.asm io.sys source file |
|||
msioctl.inc io.sys include file |
|||
msload.asm io.sys source file |
|||
msload.inc io.sys include file |
|||
mslpt.asm io.sys source file |
|||
msmacro.inc io.sys include file |
|||
msstack.inc io.sys include file |
|||
msvolid.inc io.sys include file |
|||
pushpop.inc io.sys include file |
|||
readcloc.inc io.sys include file |
|||
stkinit.inc io.sys include file |
|||
stkmes.inc io.sys include file |
|||
sysconf.asm io.sys source file |
|||
sysimes.asm io.sys source file - message text |
|||
sysimes.inc io.sys include file |
|||
sysinit1.asm io.sys source file - system initialization |
|||
sysinit2.asm io.sys source file - system initialization |
|||
|
|||
|
|||
|
|||
src\boot <dir> |
|||
|
|||
boot.inc msboot include file |
|||
boot11.inc msboot include file |
|||
makefile msboot make file |
|||
messages.inc msboot message file |
|||
msboot.asm msboot source file |
|||
msboot.bin boot sector |
|||
|
|||
|
|||
|
|||
MS-DOS 3.20 CLONE VERSION DISTRIBUTION DISKETTES MS320DIS02 |
|||
|
|||
src\cmd\format <dir> |
|||
|
|||
bootmes.inc format include file |
|||
format.asm format generic source file |
|||
format.lnk format link script |
|||
forproc.asm format source file |
|||
make_inc.bas BASIC program to establish system size - makes filesize.inc |
|||
makefile makefile for format.com |
|||
messages.asm format message source file |
|||
messages.inc format include file |
|||
oemfor.asm format OEM specific source file |
|||
|
|||
|
|||
src\cmd\print <dir> |
|||
|
|||
makefile makefile for print.com |
|||
nprintf.asm print source file |
|||
pridefs.inc print include file |
|||
print.lnk print link script |
|||
print_r.asm print resident source code |
|||
print_rm.asm print resident message source code |
|||
print_rm.inc print resident include file |
|||
print_t.asm print transient source code |
|||
print_tm.asm print transient message source code |
|||
print_tm.inc print transient include file |
|||
|
|||
|
|||
src\cmd\sort <dir> |
|||
|
|||
makefile make file for sort.exe |
|||
messages.asm sort message file |
|||
sort.asm sort source file |
|||
sort.lnk sort link response file |
|||
|
|||
|
|||
src\cmd\sys <dir> |
|||
|
|||
build.bat batch file to build sys.exe |
|||
messages.asm sys message file |
|||
sys.asm sys source file |
|||
sys.lnk sys link response file |
|||
|
|||
src\dos <dir> |
|||
|
|||
abort.obj msdos.sys object module |
|||
alloc.obj msdos.sys object module |
|||
arena.inc msdos.sys include file |
|||
bpb.inc msdos.sys include file |
|||
buf.obj msdos.sys object module |
|||
buffer.inc msdos.sys include file |
|||
close.obj msdos.sys object module |
|||
const2.obj msdos.sys object module |
|||
cpmfcb.inc msdos.sys include file |
|||
cpmio.obj msdos.sys object module |
|||
cpmio2.obj msdos.sys object module |
|||
create.obj msdos.sys object module |
|||
crit.obj msdos.sys object module |
|||
curdir.obj msdos.sys object module |
|||
delete.obj msdos.sys object module |
|||
dev.obj msdos.sys object module |
|||
devsym.inc msdos.sys include file |
|||
dinfo.obj msdos.sys object module |
|||
dir.obj msdos.sys object module |
|||
dir2.obj msdos.sys object module |
|||
dircall.obj msdos.sys object module |
|||
dirent.inc msdos.sys include file |
|||
disk.obj msdos.sys object module |
|||
disk2.obj msdos.sys object module |
|||
disk3.obj msdos.sys object module |
|||
divmes.inc msdos.sys include file |
|||
doscntry.inc msdos.sys include file |
|||
dosmac.inc msdos.sys include file |
|||
dosseg.inc msdos.sys include file |
|||
dossym.inc msdos.sys include file |
|||
dpb.inc msdos.sys include file |
|||
dpl.inc msdos.sys include file |
|||
dup.obj msdos.sys object module |
|||
error.inc msdos.sys include file |
|||
exe.inc msdos.sys include file |
|||
fat.obj msdos.sys object module |
|||
fcb.obj msdos.sys object module |
|||
fcbio.obj msdos.sys object module |
|||
fcbio2.obj msdos.sys object module |
|||
file.obj msdos.sys object module |
|||
filemode.inc msdos.sys include file |
|||
find.inc msdos.sys include file |
|||
finfo.obj msdos.sys object module |
|||
getset.obj msdos.sys object module |
|||
handle.obj msdos.sys object module |
|||
intnat.inc msdos.sys include file |
|||
ioctl.inc msdos.sys include file |
|||
ioctl.obj msdos.sys object module |
|||
isearch.obj msdos.sys object module |
|||
lock.obj msdos.sys object module |
|||
macro.obj msdos.sys object module |
|||
macro2.obj msdos.sys object module |
|||
makefile msdos.sys makefile |
|||
mi.inc msdos.sys include file |
|||
misc.obj msdos.sys object module |
|||
misc2.obj msdos.sys object module |
|||
mknode.obj msdos.sys object module |
|||
msdos.lnk msdos.sys link script |
|||
mult.inc msdos.sys include file |
|||
nibdos.obj msdos.sys object module |
|||
open.obj msdos.sys object module |
|||
parse.obj msdos.sys object module |
|||
path.obj msdos.sys object module |
|||
pdb.inc msdos.sys include file |
|||
proc.obj msdos.sys object module |
|||
rename.obj msdos.sys object module |
|||
rom.obj msdos.sys object module |
|||
search.obj msdos.sys object module |
|||
sf.inc msdos.sys include file |
|||
share.obj msdos.sys object module |
|||
smdossym.inc msdos.sys include file |
|||
srvcall.obj msdos.sys object module |
|||
stdcode.obj msdos.sys object module |
|||
stdctrlc.obj msdos.sys object module |
|||
stddata.obj msdos.sys object module |
|||
stddisp.obj msdos.sys object module |
|||
stddosme.asm msdos.sys source file |
|||
stddosme.obj msdos.sys object module |
|||
stdsw.inc msdos.sys include file |
|||
stdtable.obj msdos.sys object module |
|||
syscall.inc msdos.sys include file |
|||
sysvar.inc msdos.sys include file |
|||
time.obj msdos.sys object module |
|||
util.obj msdos.sys object module |
|||
vector.inc msdos.sys include file |
|||
|
|||
|
|||
|
|||
src\inc <dir> |
|||
|
|||
macro.inc general msdos include file |
|||
struc.inc general msdos include file |
|||
version.inc general msdos include file |
|||
versiona.inc general msdos include file |
|||
|
|||
|
|||
|
|||
src\libc <dir> |
|||
|
|||
The files in this directory are needed when linking various msdos files. |
|||
|
|||
cds.obj |
|||
dpb.obj |
|||
errtst.obj |
|||
itoupper.obj |
|||
join.c |
|||
kstring.c |
|||
printf.asm |
|||
string.c |
|||
sysvar.c |
|||
|
|||
|
|||
tools <dir> |
|||
|
|||
The files in this directory are used to make the parts of the MSDOS product. |
|||
None of these files(except exe2bin.exe), however are part of the MS-DOS product |
|||
and they should not be supplied to an OEM's customers. |
|||
|
|||
convert.exe special file to change certain .EXE files to .COM files |
|||
dbof.exe used to insure that boot record is located proper on disk |
|||
exe2bin.exe same as exe2bin.exe in product - it is included here as |
|||
as a convenience |
|||
exefix.exe used by some makefiles to convert .EXE files to .COM files |
|||
gwbasic.exe same gwbasics as in packaged procduct. It is used by the |
|||
makefile in format - it is included here as a convenience |
|||
link.exe linker used to build msdos |
|||
masm.exe masm.exe from Retail Macro Assember 4.00 Product |
|||
masm401.exe special masm used to build IO.SYS |
|||
msmake.exe make utility - renamed msmake to distinquish it from XENIX make |
|||
|
|||
3. Instruction for use. |
|||
|
|||
The MS-DOS release installation procedure is described in Chapter 3 of |
|||
the MS-DOS 2.XX/3.XX adaptation guide. |
|||
|
|||
It is recommended that the DISTRIBUTION DISKETTES be copied over |
|||
to a hard disk with the XCOPY.EXE command. This will set up |
|||
a directory tree that the makefiles can use properly. All the |
|||
buildables on the DISTRIBUTION DISKETTES can be built by setting |
|||
the PATH to SRC\TOOLS and running the MAKEFILE in the SRC directory. |
|||
It is important that the file be built in the order that they are |
|||
by this makefile as there are some dependencies on former builds |
|||
having occurred. |
|||
|
|||
It is also recommended that MS-DOS 3.30 is installed on the build |
|||
machine and that the build occurs under MS-DOS 3.30. This will |
|||
insure that any version dependent tools will perform properly. MS-DOS |
|||
3.30 can be installed on the build machine by booting from the floppy |
|||
with the boot disk from either the DISTRIBUTION DISKETTES or the PACKAGED |
|||
PRODUCT and then using the SYS command or FORMAT /S to get the system to the |
|||
hard disk. |
|||
|
|||
System Filenames are MSDOS.SYS and IO.SYS in FORMAT and SYS. |
|||
|
|||
FORMAT.EXE and SYS.COM have the boot sector installed with INSBIN.EXE. |
|||
|
|||
The OEM NUMBER is FF. |
|||
|
|||
Build Scripts require that the files EXE2BIN.EXE and DEBUG.EXE be in the PATH. |
|||
|
|||
The 8-bit OEM Serial number may be installed with DEBUG by patching MSDOS.SYS |
|||
at location 355H (455 under DEBUG). |
|||
|
|||
The 24-bit OEM User number may be installed with DEBUG by patching MSDOS.SYS |
|||
at location 352H (452 under DEBUG). |
|||
|
|||
SYSINIT LINK REQUIREMENTS. |
|||
|
|||
SYSINIT1.obj now requires an external FAR routine called StackInit |
|||
to be linked. This routine has available to it the parameters |
|||
|
|||
STACK_ADDR: DWORD |
|||
STACK_SIZE: WORD |
|||
STACK_COUNT: WORD |
|||
|
|||
|
|||
StackInit initializes the Stack Heap and corresponding interrupt |
|||
vectors used to handle potential hardware driven stack overflows. |
|||
After completing its task, StackInit issues a RETF to return to |
|||
SYSINIT1. |
|||
To use the IBM compatible SYSINIT1, the OEM must |
|||
provide the FAR ROUTINE StackInit, whose only task is to issue a |
|||
RETF. |
|||
|
|||
|
|||
The CONVERT utility is provided in the TOOLS directory to |
|||
rename certain .EXE utilties as .COM files if desired. The CONVERT utility |
|||
is not part of the MS-DOS product and should be used only as |
|||
described as follows: |
|||
|
|||
|
|||
Documentation for CONVERT.EXE |
|||
|
|||
CONVERT is used by entering CONVERT and an .EXE file name (with the .EXE |
|||
extension). |
|||
|
|||
CONVERT FOO.EXE |
|||
|
|||
will build a FOO.COM file |
|||
|
|||
|
|||
CONVERT adds an .EXE loader onto the .EXE file image |
|||
|
|||
It should not be confused with EXE2BIN.EXE |
|||
|
|||
These are the differences: |
|||
|
|||
EXE2BIN |
|||
|
|||
- EXE2BIN is a utility for converting .EXE files to binary (.COM). |
|||
|
|||
- EXE2BIN produces a .COM file which is smaller than the .EXE file. |
|||
|
|||
- EXE2BIN may only convert files conforming to a certain documented set of |
|||
requirements. |
|||
|
|||
- EXE2BIN can only be used on a file written as .COM file (ORG 100h, not |
|||
stack segment). |
|||
|
|||
|
|||
CONVERT |
|||
|
|||
- CONVERT transforms an .EXE file into a .COM file by appending the |
|||
MS-DOS loader to the end of the file. |
|||
|
|||
- A CONVERTed file will be larger than an equivalent .EXE file. |
|||
|
|||
- CONVERT will convert ANY .EXE program. |
|||
|
|||
- CONVERT should only be used in UNUSUAL circumstances, such as when |
|||
an application program demands that a file have a .COM extension. |
|||
|
|||
|
|||
|
|||
4. Differences in the files in the MS VERSION and CLONE VERSION of MS-DOS |
|||
|
|||
This is a complete list of the differences between the MS VERSION and the |
|||
CLONE VERSION of MS-DOS at the 3.XX level. It is intended to illustrate how |
|||
few the differences actually are. These differences occur as a result of |
|||
conditional assemblies based on whether MSVER or IBMVER is TRUE at the time |
|||
of assembly. |
|||
|
|||
CLONE VERSION MS VERSION |
|||
DOS |
|||
================================================================== |
|||
|
|||
OEM_HANDLER OEM_HANDLER code OEM_HANDLER code |
|||
for call F8 NOT included for call F8 included |
|||
|
|||
DOS header IBM Text MSDOS text |
|||
|
|||
Print of DOS NO YES |
|||
version at |
|||
boot time |
|||
|
|||
INT 25,26 AH YES NO |
|||
error code |
|||
mapping |
|||
|
|||
International Large set US table only |
|||
tables |
|||
|
|||
Case map call IBM PC specific None |
|||
in internat |
|||
tables |
|||
|
|||
Function Key IBM PC Z-19 (Zenith terminal) |
|||
definition |
|||
|
|||
^N defined as NO YES |
|||
special char |
|||
equivalent |
|||
to ^P |
|||
|
|||
****************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
SHARE |
|||
================================================================== |
|||
|
|||
NOTE: The MS VERSION and CLONE VERSION do have minor |
|||
differences and will not file compare. The differences |
|||
have to do with the DOS data modules linked in with SHARE. |
|||
The CLONE VERSION SHARE, MSDOS and REDIR should be used only with |
|||
each other and the MS VERSION SHARE, MSDOS and REDIR should be |
|||
used only with each other. |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
COMMAND |
|||
================================================================== |
|||
|
|||
CLS Special IBM code to detect Assumes ANSI support, |
|||
if ANSI driver installed. outputs ANSI CLS sequence. |
|||
If no ANSI driver, CLS done |
|||
by direct calls to INT 10H |
|||
|
|||
ROM exec Special code for PC-Jr ROM No ROM exec code |
|||
cartridges. |
|||
|
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
PRINT |
|||
================================================================== |
|||
INT 17,13,14,5,15 handlers No special handlers |
|||
|
|||
IBM specific timer int code No timer int code |
|||
|
|||
NOTE: SOURCE CODE FOR PRINT IS SENT SO THAT |
|||
OEMs CAN PORT THEM TO THEIR MACHINES. |
|||
|
|||
NOTE: SETTING THE IBM SWITCHES TO TRUE IN PRINT |
|||
WILL NOT YIELD A BINARY THAT IS THE SAME AS THE IBM |
|||
3.2 . |
|||
|
|||
In PRINT's case this is due to some slight code |
|||
re-organization that was needed to get a valid |
|||
PRINT with the IBM switches set to FALSE. |
|||
|
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
DEBUG |
|||
================================================================== |
|||
INT controler Contains code to twiddle No code included |
|||
one of the 8259 interrupt |
|||
controller registers to |
|||
fix the trace of the timer |
|||
int problems |
|||
|
|||
Screen Width Issues INT 10H to get Assumes screen is at |
|||
screen width. least 80 column |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
FORMAT |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
SYS |
|||
================================================================== |
|||
|
|||
Put Boot Contains Boot sector No put boot code |
|||
output code to put |
|||
correct boot sectors |
|||
on SYSed disks |
|||
|
|||
Check for valid Uses INT 25 to make sure Minimal checking of |
|||
destination that destination disk is MSDOS.SYS size |
|||
empty or has correct IBM |
|||
bootable disk format |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
RECOVER |
|||
================================================================== |
|||
ROM COM AREA Twiddles a byte in the ROM No code |
|||
TWIDDLE communication area on single |
|||
drive systems to indicate |
|||
drive changed. |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
EXE2BIN |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
CHKDSK |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
FIND |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
ASSIGN |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
ATTRIB |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
SUBST |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
* ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
JOIN |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
EDLIN |
|||
================================================================== |
|||
MS VERSION CLONE VERSION |
|||
ARE IDENTICAL |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
MORE |
|||
================================================================== |
|||
Screen Width Issues INT 10H to get Assumes screen is |
|||
width of screen at least 80 column |
|||
|
|||
Non printing Assumes all chars < 20H Assumes chars < 20H |
|||
chars except for BELL (07) are are non printing and |
|||
printing characters which do not advance the |
|||
advance the cursor one cursor if output |
|||
position if output. |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
SORT |
|||
================================================================== |
|||
Internat chars Defines coalating sequence Chars > 7FH are sorted |
|||
for some chars > 7FH approp in value order |
|||
to IBM international char |
|||
sets |
|||
|
|||
***************************************************************************** |
|||
|
|||
CLONE VERSION MS VERSION |
|||
BIOS (SYSINIT) |
|||
================================================================== |
|||
MEM scan Mem scan code not included Includes memory scan |
|||
Assumes BIOS sets memory code if OEM BIOS |
|||
size variable always. does not set memory |
|||
size variable. |
@ -0,0 +1,31 @@ |
|||
|
|||
;;Rev 3.30 Modification |
|||
; SINGLE DRIVE MESSAGE FOR BIOS. NUL TERMINATED. |
|||
IFNDEF PATHSTART |
|||
PATHSTART MACRO INDEX,ABBR |
|||
IFDEF PATHGEN |
|||
PUBLIC ABBR&INDEX&S,ABBR&INDEX&E |
|||
ABBR&INDEX&S LABEL BYTE |
|||
ENDIF |
|||
ENDM |
|||
ENDIF |
|||
|
|||
IFNDEF PATHEND |
|||
PATHEND MACRO INDEX,ABBR |
|||
IFDEF PATHGEN |
|||
ABBR&INDEX&E LABEL BYTE |
|||
ENDIF |
|||
ENDM |
|||
ENDIF |
|||
|
|||
PATHSTART 001,BIOMS |
|||
|
|||
; |
|||
; Single drive message for msbio.com. Nul terminated. ;;End of Modification |
|||
; |
|||
|
|||
SNGMSG DB CR,LF,"Insert diskette for drive " |
|||
DRVLET DB "A: and strike",CR,LF,"any key when ready",CR,LF,LF,0 |
|||
|
|||
PATHEND 001,BIOMS |
|||
|
@ -0,0 +1,87 @@ |
|||
|
|||
|
|||
;;Rev 3.30 Modification |
|||
; ROM BIOS CALL PACKET STRUCTURES |
|||
|
|||
;******************************* |
|||
;System Service call ( Int 15h ) |
|||
;******************************* |
|||
;Function AH = 0C0h, Return system configuration |
|||
;For PC and PCJR on return: |
|||
; (AH) = 80h |
|||
; (CY) = 1 |
|||
;For PCXT, PC PORTABLE and PCAT on return: |
|||
; (AH) = 86h |
|||
; (CY) = 1 |
|||
;For all others: |
|||
; (AH) = 0 |
|||
; (CY) = 0 |
|||
; (ES:BX) = pointer to system descriptor vector in ROS |
|||
; System descriptor : |
|||
; DW xxxx length of descriptor in bytes, |
|||
; minimum length = 8 |
|||
; DB xx model byte |
|||
; 0FFh = PC |
|||
; 0FEh = PC/XT, Portable |
|||
; 0FDh = PC/JR |
|||
; 0FCh = PC/AT |
|||
; 0F9h = Convertable |
|||
; 0F8h = Model 80 |
|||
; 0E0 thru 0EFh = reserved |
|||
; |
|||
; DB xx secondary model byte |
|||
; 000h = PC1 |
|||
; 000h = PC/XT, Portable |
|||
; 000h = PC/JR |
|||
; 000h = PC/AT |
|||
; 001h = PC/AT Model 339 |
|||
; 003h = PC/RT |
|||
; 000h = Convertable |
|||
; |
|||
; DB xx bios revision level |
|||
; 00 for first release, subsequent release |
|||
; of code with same model byte and |
|||
; secondary model byte require revison level |
|||
; to increase by one. |
|||
; |
|||
; DB xx feature information byte 1 |
|||
; X0000000 = 1, bios use DMA channel 3 |
|||
; = 0, DMA channel 3 not used |
|||
; |
|||
; 0X000000 = 1, 2nd Interrupt chip present |
|||
; = 0, 2nd Interrupt chip not present |
|||
; |
|||
; 00X00000 = 1, Real Time Clock present |
|||
; = 0, Real Time Clock not present |
|||
; |
|||
; 000X0000 = 1, Keyboard escape sequence(INT 15h) |
|||
; called in keyboard interrupt |
|||
; (Int 09h). |
|||
; = 0, Keyboard escape sequence not |
|||
; called. |
|||
; 0000XXXX reserved |
|||
; |
|||
; DB xx feature information byte 2 - reserved |
|||
; |
|||
; DB xx feature information byte 2 - reserved |
|||
; |
|||
; DB xx feature information byte 2 - reserved |
|||
; |
|||
; DB xx feature information byte 2 - reserved |
|||
; |
|||
|
|||
BIOS_SYSTEM_DESCRIPTOR struc |
|||
bios_SD_leng dw ? |
|||
bios_SD_modelbyte db ? |
|||
bios_SD_scnd_modelbyte db ? |
|||
db ? |
|||
bios_SD_featurebyte1 db ? |
|||
db 4 dup (?) |
|||
BIOS_SYSTEM_DESCRIPTOR ends |
|||
|
|||
;FeatureByte1 bit map equates |
|||
DMAchannel3 equ 10000000b |
|||
ScndIntController equ 01000000b |
|||
RealTimeClock equ 00100000b |
|||
KeyEscapeSeq equ 00010000b |
|||
;;End of Modification |
@ -0,0 +1,76 @@ |
|||
|
|||
; |
|||
; date_verify loosely checks bcd date values to be in range in bin_date_time |
|||
; |
|||
date_verify: ; |
|||
cmp byte ptr bin_date_time+0,20h ; century check |
|||
ja date_error ; jmp error |
|||
jz century_20 ; jmp in 20th century |
|||
cmp byte ptr bin_date_time+0,19h ; century check |
|||
jb date_error ; jmp error |
|||
cmp byte ptr bin_date_time+1,80h ; year check |
|||
jb date_error ; jmp error |
|||
century_20: ; |
|||
cmp byte ptr bin_date_time+1,99h ; year check |
|||
ja date_error ; jmp error |
|||
cmp byte ptr bin_date_time+2,12h ; month check |
|||
ja date_error ; jmp error |
|||
cmp byte ptr bin_date_time+2,00h ; month check |
|||
jbe date_error ; jmp error |
|||
cmp byte ptr bin_date_time+3,31h ; day check |
|||
ja date_error ; jmp error |
|||
cmp byte ptr bin_date_time+3,00h ; day check |
|||
jbe date_error ; jmp error |
|||
clc ; set success flag |
|||
ret ; |
|||
date_error: ; |
|||
stc ; set error flag |
|||
ret ; |
|||
|
|||
; |
|||
; time_verify very loosely checks bcd date values to be in range in bin_date_time |
|||
; |
|||
time_verify: |
|||
cmp byte ptr bin_date_time+0,24H |
|||
ja time_error |
|||
cmp byte ptr bin_date_time+1,59H |
|||
ja time_error |
|||
cmp byte ptr bin_date_time+2,59H |
|||
ja time_error |
|||
clc |
|||
ret |
|||
time_error: |
|||
stc |
|||
ret |
|||
|
|||
; |
|||
; bcd_verify checks values in bin_date_time to be valid |
|||
; bcd numerals. carry set if any nibble out of range |
|||
; |
|||
bcd_verify: ; |
|||
mov cx,4 ; 4 bytes to check |
|||
mov bx,offset bin_date_time ; |
|||
bv_loop: ; |
|||
mov al,[bx] ; get a bcd number (0..99) |
|||
mov ah,al ; |
|||
and ax,0f00fh ; 10's place in high ah, 1's in al |
|||
cmp al,10 ; is 1's place in range? |
|||
ja bv_error ; jmp out of range |
|||
shr ah,1 ; swap nibbles |
|||
shr ah,1 ; ... |
|||
shr ah,1 ; ... |
|||
shr ah,1 ; ... |
|||
and ah,0fh ; get rid of any erroneous bits |
|||
cmp ah,10 ; is 10's place in range |
|||
ja bv_error ; jmp out of range |
|||
inc bx ; next byte |
|||
dec cx ; |
|||
jnz bv_loop ; |
|||
clc ; set success flag |
|||
ret ; |
|||
bv_error: ; |
|||
stc ; set error flag |
|||
ret ; |
|||
; |
|||
; Dos 3.30 - The real time clock structures were moved to msbio2.asm |
|||
; |
@ -0,0 +1,50 @@ |
|||
;;Rev 3.30 Modification |
|||
;Equates for CMOS. |
|||
|
|||
;---------------------------------------- |
|||
; CMOS EQUATES FOR THIS SYSTEM : |
|||
;------------------------------------------------------------------------------- |
|||
CMOS_PORT EQU 070H ; I/O ADDRESS OF CMOS ADDRESS PORT |
|||
CMOS_DATA EQU 071H ; I/O ADDRESS OF CMOS DATA PORT |
|||
NMI EQU 10000000B ; DISABLE NMI INTERRUPTS MASK - |
|||
; HIGH BIT OF CMOS LOCATION ADDRESS |
|||
|
|||
;---------- CMOS TABLE LOCATION ADDRESS'S ## ----------------------------------- |
|||
CMOS_SECONDS EQU 000H ; SECONDS |
|||
CMOS_SEC_ALARM EQU 001H ; SECONDS ALARM ## NOTE: ALL LOCATIONS |
|||
CMOS_MINUTES EQU 002H ; MINUTES | IN THE CMOS AREA |
|||
CMOS_MIN_ALARM EQU 003H ; MINUTES ALARM | ARE IBM USE ONLY |
|||
CMOS_HOURS EQU 004H ; HOURS | AND SUBJECT TO |
|||
CMOS_HR_ALARM EQU 005H ; HOURS ALARM | CHANGE. ONLY THE |
|||
CMOS_DAY_WEEK EQU 006H ; DAY OF THE WEEK | POST & BIOS CODE |
|||
CMOS_DAY_MONTH EQU 007H ; DAY OF THE MONTH | SHOULD DIRECTLY |
|||
CMOS_MONTH EQU 008H ; MONTH | ACCESS LOCATIONS |
|||
CMOS_YEAR EQU 009H ; YEAR (TWO DIGITS) | IN CMOS STORAGE. |
|||
CMOS_REG_A EQU 00AH ; STATUS REGISTER A '----------------- |
|||
CMOS_REG_B EQU 00BH ; STATUS REGISTER B ALARM |
|||
CMOS_REG_C EQU 00CH ; STATUS REGISTER C FLAGS |
|||
CMOS_REG_D EQU 00DH ; STATUS REGISTER D BATTERY |
|||
CMOS_DIAG EQU 00EH ; POST DIAGNOSTIC STATUS RESULTS BYTE |
|||
CMOS_SHUT_DOWN EQU 00FH ; SHUTDOWN STATUS COMMAND BYTE |
|||
CMOS_DISKETTE EQU 010H ; DISKETTE DRIVE TYPE BYTE ; |
|||
; EQU 011H ; - RESERVED ;C |
|||
CMOS_DISK EQU 012H ; FIXED DISK TYPE BYTE ;H |
|||
; EQU 013H ; - RESERVED ;E |
|||
CMOS_EQUIP EQU 014H ; EQUIPMENT WORD LOW BYTE ;C |
|||
CMOS_B_M_S_LO EQU 015H ; BASE MEMORY SIZE - LOW BYTE (X1024) ;K |
|||
CMOS_B_M_S_HI EQU 016H ; BASE MEMORY SIZE - HIGH BYTE ;S |
|||
CMOS_E_M_S_LO EQU 017H ; EXPANSION MEMORY SIZE - LOW BYTE ;U |
|||
CMOS_E_M_S_HI EQU 018H ; EXPANSION MEMORY SIZE - HIGH BYTE ;M |
|||
CMOS_DISK_1 EQU 019H ; FIXED DISK TYPE - DRIVE C EXTENSION ;E |
|||
CMOS_DISK_2 EQU 01AH ; FIXED DISK TYPE - DRIVE D EXTENSION ;D |
|||
; EQU 01BH ; - 1BH THROUGH 2DH - RESERVED ; |
|||
CMOS_CKSUM_HI EQU 02EH ; CMOS CHECKSUM - HIGH BYTE ;* |
|||
CMOS_CKSUM_LO EQU 02FH ; CMOS CHECKSUM - LOW BYTE ;* |
|||
CMOS_U_M_S_LO EQU 030H ; USABLE MEMORY ABOVE 1 MEG - LOW BYTE |
|||
CMOS_U_M_S_HI EQU 031H ; USABLE MEMORY ABOVE 1 MEG - HIGH BYTE |
|||
CMOS_CENTURY EQU 032H ; DATE CENTURY BYTE (BCD) |
|||
CMOS_INFO128 EQU 033H ; 128KB INFORMATION STATUS FLAG BYTE |
|||
; EQU 034H ; - 34H THROUGH 3FH - RESERVED |
|||
; |
|||
;;End of Modification |
|||
|
@ -0,0 +1,22 @@ |
|||
; The following structure defines the disk parameter table |
|||
; pointed to by Interrupt vector 1EH (location 0:78H) |
|||
|
|||
DISK_PARMS STRUC |
|||
DISK_SPECIFY_1 DB ? |
|||
DISK_SPECIFY_2 DB ? |
|||
DISK_MOTOR_WAIT DB ? ; Wait till motor off |
|||
DISK_SECTOR_SIZ DB ? ; Bytes/Sector (2 = 512) |
|||
DISK_EOT DB ? ; Sectors per track (MAX) |
|||
DISK_RW_GAP DB ? ; Read Write Gap |
|||
DISK_DTL DB ? |
|||
DISK_FORMT_GAP DB ? ; Format Gap Length |
|||
DISK_FILL DB ? ; Format Fill Byte |
|||
DISK_HEAD_STTL DB ? ; Head Settle Time (MSec) |
|||
DISK_MOTOR_STRT DB ? ; Motor start delay |
|||
DISK_PARMS ENDS |
|||
|
|||
ROMStatus equ 1 |
|||
ROMRead equ 2 |
|||
ROMWrite equ 3 |
|||
ROMVerify equ 4 |
|||
ROMFormat equ 5 |
@ -0,0 +1,32 @@ |
|||
|
|||
;;Rev 3.30 Modification |
|||
; |
|||
; given a label <lbl> either 2 byte jump to another label <lbl>_J |
|||
; if it is near enough or 3 byte jump to <lbl> |
|||
; |
|||
|
|||
jump macro lbl |
|||
local a |
|||
.xcref |
|||
|
|||
ifndef lbl&_j ;; is this the first invocation |
|||
a: |
|||
JMP lbl |
|||
ELSE |
|||
IF (lbl&_J GE $) OR ($-lbl&_J GT 126) |
|||
a: |
|||
JMP lbl ;; is the jump too far away? |
|||
ELSE |
|||
a: |
|||
JMP lbl&_J ;; do the short one... |
|||
ENDIF |
|||
ENDIF |
|||
lbl&_j = a |
|||
.cref |
|||
endm |
|||
.xcref jump |
|||
;REDEFINE THE ABOVE MACRO TO ALWAYS TRY A 3 BYTE NEAR JUMP |
|||
JUMP MACRO LBL |
|||
JMP LBL |
|||
ENDM ;;End of Modification |
|||
|
@ -0,0 +1 @@ |
|||
70 |
@ -0,0 +1,107 @@ |
|||
#*** Makefile for BIOS |
|||
|
|||
DEST =io |
|||
MSG =messages |
|||
DOS =..\dos |
|||
|
|||
# Definitions for Assembler |
|||
|
|||
ASM =masm |
|||
AFLAGS =-Mx -t |
|||
AINC =-I. -I..\inc -I$(DOS) |
|||
|
|||
# Definitions for C compiler |
|||
|
|||
CC =cl |
|||
CFLAGS =-Ox -X -Zlp |
|||
CINC =-I. -I..\h |
|||
|
|||
# Definitions for Linker |
|||
|
|||
LINK =link |
|||
|
|||
# Built-in rules |
|||
|
|||
.asm.obj: |
|||
$(ASM) $(AFLAGS) $(AINC) $*.asm,$*.obj; |
|||
|
|||
.asm.lst: |
|||
$(ASM) -l $(AFLAGS) $(AINC) $*.asm; |
|||
|
|||
.c.obj: |
|||
$(CC) -c $(CFLAGS) $(CINC) -Fo$*.obj $*.c |
|||
|
|||
.c.lst: |
|||
$(CC) -c $(CFLAGS) $(CINC) -Fc$*.cod -Fo$*.obj $*.c |
|||
|
|||
.exe.com: |
|||
reloc $*.exe $*.com |
|||
|
|||
# Dependencies |
|||
|
|||
msload.obj: msload.asm msload.inc |
|||
|
|||
msload.com: msload.obj |
|||
LINK msload.obj,msload,,; |
|||
exe2bin msload.exe msload.com |
|||
del msload.exe |
|||
|
|||
msbio1.obj: msbio1.asm msdata.inc msgroup.inc jumpmac.inc pushpop.inc \ |
|||
$(DOS)\devsym.inc dskprm.inc msmacro.inc |
|||
|
|||
|
|||
mscon.obj: mscon.asm msgroup.inc jumpmac.inc msmacro.inc |
|||
|
|||
msaux.obj: msaux.asm msgroup.inc jumpmac.inc msmacro.inc |
|||
|
|||
mslpt.obj: mslpt.asm msgroup.inc msequ.inc msbds.inc msmacro.inc \ |
|||
$(dos)\devsym.inc $(dos)\ioctl.inc $(dos)\bpb.inc |
|||
|
|||
msclock.obj: msclock.asm msgroup.inc msmacro.inc |
|||
|
|||
msdisk.obj: msdisk.asm msgroup.inc msequ.inc msbds.inc pushpop.inc \ |
|||
msmacro.inc $(dos)\devsym.inc dskprm.inc msioctl.inc \ |
|||
$(dos)\ioctl.inc $(dos)\bpb.inc |
|||
|
|||
msinit.obj: msinit.asm msgroup.inc dskprm.inc msequ.inc msbds.inc \ |
|||
msmacro.inc readclock.inc clocksub.inc msextrn.inc |
|||
|
|||
sysinit1.obj: sysinit1.asm msstack.inc stkmes.inc stkinit.inc \ |
|||
$(dos)\devsym.inc $(dos)\ioctl.inc $(dos)\smdossym.inc \ |
|||
$(dos)\dosmac.inc $(dos)\bpb.inc $(dos)\buffer.inc \ |
|||
$(dos)\sysvar.inc $(dos)\vector.inc $(dos)\dirent.inc \ |
|||
$(dos)\dpb.inc $(dos)\curdir.inc $(dos)\pdb.inc $(dos)\exe.inc \ |
|||
$(dos)\sf.inc $(dos)\arena.inc $(dos)\intnat.inc $(dos)\mi.inc \ |
|||
$(dos)\syscall.inc |
|||
masm401 $(AFLAGS) $(AINC) sysinit1; |
|||
|
|||
sysconf.obj: sysconf.asm $(dos)\devsym.inc $(dos)\ioctl.inc \ |
|||
$(dos)\smdossym.inc $(dos)\dosmac.inc $(dos)\bpb.inc $(dos)\buffer.inc \ |
|||
$(dos)\sysvar.inc $(dos)\vector.inc $(dos)\dirent.inc \ |
|||
$(dos)\dpb.inc $(dos)\curdir.inc $(dos)\pdb.inc $(dos)\exe.inc \ |
|||
$(dos)\sf.inc $(dos)\arena.inc $(dos)\intnat.inc $(dos)\mi.inc \ |
|||
$(dos)\syscall.inc |
|||
|
|||
sysinit2.obj: sysinit2.asm $(dos)\devsym.inc $(dos)\ioctl.inc \ |
|||
$(dos)\smdossym.inc $(dos)\dosmac.inc $(dos)\bpb.inc $(dos)\buffer.inc \ |
|||
$(dos)\sysvar.inc $(dos)\vector.inc $(dos)\dirent.inc \ |
|||
$(dos)\dpb.inc $(dos)\curdir.inc \ |
|||
$(dos)\pdb.inc $(dos)\exe.inc $(dos)\sf.inc $(dos)\arena.inc \ |
|||
$(dos)\intnat.inc $(dos)\mi.inc $(dos)\syscall.inc |
|||
|
|||
sysimes.obj: sysimes.asm msmacro.inc sysimes.inc msequ.inc msbds.inc |
|||
|
|||
msbio2.obj: msbio2.asm msgroup.inc msequ.inc msbds.inc $(dos)\devsym.inc \ |
|||
pushpop.inc msmacro.inc biomes.inc ms96tpi.inc msvolid.inc |
|||
|
|||
mshard.obj: mshard.asm |
|||
|
|||
msbio.bin: msbio1.obj mscon.obj msaux.obj mslpt.obj msclock.obj \ |
|||
msdisk.obj msbio2.obj msinit.obj mshard.obj sysinit1.obj \ |
|||
sysconf.obj sysinit2.obj sysimes.obj |
|||
link @msbio.lnk |
|||
exe2bin msbio.exe msbio.bin < locscr |
|||
copy /b msload.com+msbio.bin io.sys |
|||
del msbio.bin |
|||
del msbio.exe |
|||
del msload.com |
@ -0,0 +1,494 @@ |
|||
|
|||
;------------------------------------------------------------------------ |
|||
; : |
|||
; File: ms96tpi.asm : |
|||
; : |
|||
; This file contains code to support the 96 tpi drives. The code : |
|||
; is included in the bio if the machine has at least one drive with : |
|||
; changeline support. If the machine has no changeline drives then : |
|||
; the code is not kept in the bio at system initialization time. : |
|||
; : |
|||
;------------------------------------------------------------------------ |
|||
|
|||
|
|||
;------------------------------------------------------------------------ |
|||
; : |
|||
; DISK OPEN/CLOSE ROUTINES : |
|||
; : |
|||
;------------------------------------------------------------------------ |
|||
|
|||
DSK$OPEN: |
|||
PUBLIC DSK$OPEN |
|||
Message fTestDisk,<"Disk Open "> ; print debug messages |
|||
MNUM fTestDisk,AX |
|||
Message fTestDisk,<CR,LF> |
|||
; AL is logical drive |
|||
call SetDrive ; Get BDS for drive |
|||
inc WORD PTR ds:[di].opcnt |
|||
jmp EXIT |
|||
|
|||
DSK$CLOSE: |
|||
PUBLIC DSK$CLOSE |
|||
Message fTestDisk,<"Disk Close "> ; print debug messages |
|||
MNUM fTestDisk,AX |
|||
Message fTestDisk,<CR,LF> |
|||
; AL is logical drive |
|||
call SetDrive ; Get BDS for drive |
|||
cmp WORD PTR ds:[di].opcnt,0 |
|||
jz EXITJX ; Watch out for wrap |
|||
dec WORD PTR ds:[di].opcnt |
|||
EXITJX: |
|||
jmp EXIT |
|||
|
|||
; |
|||
; ChkOpCnt checks the number of open files on drive. |
|||
; |
|||
; Input : DS:DI points to current BDS for drive. |
|||
; |
|||
; Return : zero set if no open files |
|||
; zero reset if open files |
|||
; |
|||
|
|||
ChkOpCnt: |
|||
Message fTest96,<"Check open count "> ; print debug messages |
|||
MNUM fTest96,AX |
|||
Message fTest96,<CR,LF> |
|||
cmp WORD PTR ds:[di].opcnt,0 |
|||
ret |
|||
|
|||
; |
|||
; At media check time, we need to really get down and check what the change is. |
|||
; This is GUARANTEED to be expensive. |
|||
; |
|||
; On entry AL contains logical drive number |
|||
; |
|||
|
|||
public mediacheck |
|||
MediaCheck: |
|||
call CheckSingle ; make sure correct disk is in place |
|||
xor SI,SI |
|||
call HasChange |
|||
jz MediaRet |
|||
call CheckROMChange |
|||
jnz MediaDoVOLID |
|||
push AX |
|||
push DX |
|||
; see if changeline has been triggered |
|||
;;Rev 3.30 Modification |
|||
mov DL, DS:[DI.drivenum] ; set logical drive number |
|||
mov AH, 16h ; get changeline status |
|||
int 13h ; call rom diskette routine |
|||
;;End of Modification |
|||
pop DX |
|||
pop AX |
|||
jc MediaDoVolid ; if changeline was triggered jmp |
|||
mov SI,1 ; else signal no change |
|||
|
|||
|
|||
; There are some drives with changeline that "lose" the changeline indication |
|||
; if a different drive is accessed after the current one. In order to avoid |
|||
; missing a media change, we return an "I don't know" to DOS if the changeline |
|||
; is not active AND we are accessing a different drive from the last one. |
|||
; If we are accessing the same drive, then we can safely rely on the changeline |
|||
; status. |
|||
|
|||
PUBLIC LOSECHNG |
|||
LOSECHNG: |
|||
mov bl,cs:[Tim_Drv] ; get last drive accessed |
|||
cmp byte ptr [di].DriveNum,bl |
|||
jz MediaRet |
|||
; Do the 2 second twiddle. If time >= 2 seconds, do a volid check. |
|||
; Otherwise return "I don't know" (Strictly speaking, we should return a |
|||
; "Not Changed" here since the 2 second test said no change.) - RS. |
|||
|
|||
SaveReg <AX,CX,DX> |
|||
call Check_Time_Of_Access |
|||
RestoreReg <DX,CX,AX> |
|||
or si,si |
|||
jz MediaDoVolid ; Check_Time says ">= 2 secs passed" |
|||
xor si,si ; return "I don't know" |
|||
Public MediaRet |
|||
MediaRet: |
|||
ret |
|||
|
|||
|
|||
; |
|||
; MediaDoVolid: if this is called somehow the media was changed. Look at |
|||
; VID to see. We do not look at FAT because this may be different since we |
|||
; only set MedByt when doing a READ or WRITE. |
|||
; |
|||
|
|||
MediaDoVolid: |
|||
call GETBP ; build a new BPB in current BDS |
|||
jc MediaRet |
|||
call Check_VID |
|||
jnc MediaRet |
|||
call MapError ; fix up AL for return to DOS |
|||
ret |
|||
|
|||
; |
|||
; Checklatchio: |
|||
; |
|||
; Simple, quick check of latched change. If no indication, then return |
|||
; otherwise do expensive check. If the expensive test fails, POP off the |
|||
; return and set AL = 15 (for invalid media change) which will be returned to |
|||
; DOS. |
|||
; |
|||
public checklatchio |
|||
CheckLatchIO: |
|||
; If returning fake BPB then assume the disk has not changed |
|||
; test word ptr ds:[di].flags, RETURN_FAKE_BPB |
|||
; jnz CheckRet |
|||
;;Rev 3.30 Modification |
|||
call HasChange ;change line supported? |
|||
jz CheckRet ;No. Just return |
|||
;;End of Modification |
|||
call ChkOpCnt |
|||
jnz CheckROM |
|||
CheckRet: |
|||
ret |
|||
; |
|||
; Check for past ROM indications. If no ROM change indicated, then return OK. |
|||
; |
|||
public checkrom |
|||
CheckROM: |
|||
call CheckROMChange |
|||
jz CheckRet ; no change |
|||
; |
|||
; We now see that a change line has been seen in the past. Let's do the |
|||
; expensive verification. |
|||
; |
|||
Message fTest96,<"CheckROMChange says yes...",CR,LF> |
|||
call GETBP ; build BPB in current BDS |
|||
jc Ret_No_Error_Map ; GETBP has already called MapError |
|||
call Check_VID |
|||
jc CheckLatchRet ; disk error trying to read in. |
|||
or SI,SI ; Is changed for sure? |
|||
jns CheckRet |
|||
call ReturnVid |
|||
CheckLatchRet: |
|||
call MapError ; fix up AL for return to DOS |
|||
Ret_No_Error_Map: |
|||
stc ; indicate an error |
|||
pop si ; pop off return address |
|||
ret |
|||
|
|||
|
|||
|
|||
; |
|||
; CheckFatVID: |
|||
; |
|||
; Check the FAT and the VID. Return in DI -1 or 0. Return with carry set |
|||
; ONLY if there was a disk error. Return that error code in AX. |
|||
; |
|||
public checkfatvid |
|||
CheckFATVID: |
|||
Message fTest96,<"Check FAT",CR,LF> |
|||
call FAT_Check |
|||
or SI,SI |
|||
js Changed_Drv |
|||
; |
|||
; The fat was the same. How about the volume ID? |
|||
; |
|||
Check_VID: |
|||
Message fTest96,<"Check VID",CR,LF> |
|||
call Read_volume_ID |
|||
jc CheckFatRet |
|||
call Check_Volume_id |
|||
or SI,SI |
|||
jnz Changed_Drv |
|||
Message fTest96,<"VID not changed",CR,LF> |
|||
call ResetChanged |
|||
CheckFatRet: |
|||
ret |
|||
Changed_Drv: |
|||
mov cs:[Tim_Drv],-1 ; Ensure that we ask ROM for media |
|||
ret ; check next time round |
|||
|
|||
|
|||
|
|||
|
|||
; |
|||
; CheckIO: At I/O time the rom-bios returned an error. We need to |
|||
; determine if the error is due to a media change. If error code is not |
|||
; change-line error (06h) we just return. We pop off the call and jmp to |
|||
; harderr if we see an error. |
|||
; |
|||
; On entry: AH contains error code returned from rom-bios. |
|||
; |
|||
|
|||
public checkio |
|||
CheckIO: |
|||
cmp AH,06 ; change line error? |
|||
jnz CheckFatRet ; no - just return |
|||
call ChkOpCnt |
|||
jz CheckFATRet ; no open files |
|||
; If returning fake BPB then ignore disk changes |
|||
; test word ptr ds:[di].flags, RETURN_FAKE_BPB |
|||
; jnz IgnoreChange |
|||
call GETBP ; build up a new BPB in current BDS |
|||
jc No_Error_Map ; GETBP has already called MapError |
|||
call CheckFATVID |
|||
jc CheckIORet ; disk error trying to read in. |
|||
or SI,SI ; Is changed for sure? |
|||
js CheckIOErr ; yes changed |
|||
IgnoreChange: |
|||
inc BP ; allow a retry |
|||
ret |
|||
CheckIOErr: |
|||
call ReturnVid |
|||
CheckIORet: |
|||
stc ; make sure carry gets passed through |
|||
jmp HardErr |
|||
|
|||
No_Error_Map: |
|||
jmp HardErr2 |
|||
|
|||
|
|||
|
|||
|
|||
; |
|||
; Return VID sets up the VID for a return to DOS. |
|||
; |
|||
|
|||
Public ReturnVID |
|||
ReturnVID: |
|||
Message fTest96,<"Return VID",cr,lf> |
|||
push DS ; save pointer to current BDS |
|||
push di |
|||
push cx |
|||
call init_vid_loop ; Sets ES:DI -> vid |
|||
lds BX,cs:[PTRSAV] |
|||
mov [BX.EXTRA],DI |
|||
mov [BX.EXTRA+2],ES |
|||
pop cx |
|||
pop di ; restore current BDS |
|||
pop DS |
|||
;; MOV AH,6 ; INVALID MEDIA CHANGE |
|||
mov AH, 0Fh ; set error as 'invalid media change' |
|||
stc ; indicate error by setting carry flag |
|||
ret |
|||
|
|||
; |
|||
; Media_Set_VID: |
|||
; |
|||
; Moves the pointer to the volid for the drive into the original request packet |
|||
; On entry, DS:BX points to the original packet. |
|||
; No attempt is made to preserve registers. |
|||
; |
|||
|
|||
MEDIA_SET_VID: |
|||
PUBLIC MEDIA_SET_VID ;;Rev 3.30 Modification |
|||
call init_vid_loop ; Sets ES:DI -> vid ;;End of Modification |
|||
lds bx,cs:[PtrSav] ; get pointer to packet |
|||
mov word ptr [BX.TRANS+1],DI |
|||
mov word ptr [BX.TRANS+3],ES |
|||
ret |
|||
|
|||
|
|||
; |
|||
; HiDensity - examine a drive/media descriptor to set the media type. If |
|||
; the media descriptor is NOT F9 (not 96tpi or 3 1/2), we return and let the |
|||
; caller do the rest. Otherwise, we pop off the return and jump to the tail |
|||
; of GETBP. For 3.5" media, we just return. |
|||
; |
|||
; Inputs: DS:DI point to correct BDS for this drive |
|||
; AH has media byte |
|||
; |
|||
; Outputs: Carry clear |
|||
; No registers modified |
|||
; Carry set |
|||
; AL = sectors/fat |
|||
; BH = number of root directory entries |
|||
; BL = sectors per track |
|||
; CX = number of sectors |
|||
; DH = sectors per allocation unit |
|||
; DL = number of heads |
|||
; |
|||
hidensity: |
|||
PUBLIC HIDENSITY ;;Rev 3.30 Modification |
|||
;;End of Modification |
|||
; Check for correct drive |
|||
; |
|||
test word ptr ds:[di].flags,fChangeline ; is it special? |
|||
jz DoFloppy ; no, do normal floppy test |
|||
; |
|||
; We have a media byte that is pretty complex. Examine drive information |
|||
; table to see what kind it is. |
|||
; |
|||
cmp byte ptr ds:[di].FormFactor,ffSmall; Is it single-media? |
|||
jz DoFloppy ; yes, use fatid... |
|||
; |
|||
; 96 tpi drive |
|||
; |
|||
cmp AH,0F9h |
|||
jnz DoFloppy |
|||
mov al,7 ; seven sectors / fat |
|||
mov bx,224*256+0fh ; 224 root dir entries & 0f sector max |
|||
mov cx,80*15*2 ; 80 tracks, 15 sectors/track, 2 sides |
|||
mov dx,01*256+2 ; sectors/allocation unit & head max |
|||
popr: |
|||
add SP,2 ; pop off return address |
|||
jmp has1_res ; return to tail of GETBP |
|||
|
|||
|
|||
DoFloppy: |
|||
ret |
|||
|
|||
PATHSTART 001,TPI96 ;;Rev 3.30 Modification |
|||
;;End of Modification |
|||
; |
|||
; Certain poorly designed programs avoid DOS altogether and use INT 13 directly. |
|||
; These programs even retry operations and, thus, will ignore the disk change |
|||
; logic. |
|||
; |
|||
; We hook INT 13 and note all errors. |
|||
; |
|||
assume ds:nothing,es:nothing,ss:nothing |
|||
|
|||
Public REAL13 |
|||
Real13 dd ? |
|||
OldInt dd ? |
|||
dmy dw ? |
|||
|
|||
PATHEND 001,TPI96 ;;Rev 3.30 Modification |
|||
;;End of Modification |
|||
Public Int13 |
|||
Int13 proc FAR |
|||
pop word ptr OldInt |
|||
pop word ptr OldInt+2 |
|||
pop DMY |
|||
MESSAGE FTEST13,<"*"> ;;Rev 3.30 Modification |
|||
pushf ;;End of Modification |
|||
call REAL13 ; simulate another INT 13 |
|||
jc Err13 ; did an error occur? |
|||
jmp OldInt ; no, return and pop off flags |
|||
Err13: |
|||
MESSAGE FTEST13,<"INT 13 ERROR "> ;;Rev 3.30 Modification |
|||
MNUM FTEST13,AX |
|||
MESSAGE FTEST13,<CR,LF> |
|||
pushf ; save state |
|||
cmp AH,06h ; is error a 'change' error? |
|||
jz GOTERR ; yes, jump down |
|||
B: popf ; no, some other error, ignore it ;;End of Modification |
|||
jmp OldInt ; return and pop off flags |
|||
|
|||
|
|||
GotErr: or DL,DL ; is this for the hard disk? |
|||
js B ; yes, ignore |
|||
mov word ptr cs:[FlagBits],fChanged |
|||
call Set_Changed_DL |
|||
jmp B |
|||
INT13 endp |
|||
|
|||
|
|||
|
|||
; |
|||
; Set_Changed_DL - Sets flag bits according to bits set in [FlagBits]. |
|||
; Essentially used to indicate Changeline, or Format. |
|||
; |
|||
; Inputs: DL contains physical drive number |
|||
; [FlagBits] contains bits to set in the flag field in the BDSs |
|||
; Outputs: None |
|||
; Registers modified: Flags |
|||
; |
|||
|
|||
Set_Changed_DL: |
|||
PUBLIC SET_CHANGED_DL ;;Rev 3.30 Modification |
|||
Message ftest96,<"Set Changed",cr,lf> ;;End of Modification |
|||
push BX |
|||
push DX |
|||
mov BL,DL |
|||
ALL_SET: |
|||
mov dx,cs:[FlagBits] ; get bits to set in flag field |
|||
xor BH,BH |
|||
; |
|||
; In the virtual drive system we *must* flag the other drives as being changed |
|||
; |
|||
; assume first BDS is in this segment |
|||
push ax |
|||
push ds ; save current BDS |
|||
push di |
|||
lds di,dword ptr cs:[Start_BDS] |
|||
Scan_BDS: |
|||
cmp di,-1 |
|||
jz SkipSet |
|||
cmp byte ptr [di].DriveNum,bl |
|||
jnz Get_Next_BDS |
|||
; |
|||
; Someone may complain, but this *always* must be done when a disk change is |
|||
; noted. There are *no* other compromising circumstances. |
|||
; |
|||
SetChanged: |
|||
or word ptr ds:[di].flags,dx ; signal change on other drive |
|||
Get_Next_BDS: |
|||
mov ax,word ptr [di].link+2 ; go to next BDS |
|||
mov di,word ptr [di].link |
|||
mov ds,ax |
|||
jmp short Scan_BDS |
|||
SkipSet: |
|||
pop di ; restore current BDS |
|||
pop ds |
|||
pop ax |
|||
pop DX |
|||
pop BX |
|||
ret |
|||
|
|||
|
|||
|
|||
; |
|||
; CheckROMChange - see if external program has diddled ROM change line. |
|||
; |
|||
; Inputs: DS:DI points to current BDS. |
|||
; Outputs: Zero set - no change |
|||
; Zero reset - change |
|||
; Registers modified: none |
|||
|
|||
CheckROMChange: |
|||
MESSAGE FTEST13,<"CHECKROM "> ;;Rev 3.30 Modification |
|||
MNUM FTEST13 |
|||
MESSAGE FTEST13,<CR,LF> ;;End of Modification |
|||
test word ptr [di].flags,fChanged |
|||
ret |
|||
|
|||
|
|||
|
|||
|
|||
; |
|||
; ResetChanged - restore value of change line |
|||
; |
|||
; Inputs: DS:DI points to current BDS |
|||
; Outputs: none |
|||
; Registers modified: none |
|||
|
|||
ResetChanged: |
|||
MESSAGE FTEST13,<"RESETCHANGED "> ;;Rev 3.30 Modification |
|||
MNUM FTEST13 |
|||
MESSAGE FTEST13,<CR,LF> ;;End of Modification |
|||
and word ptr ds:[di].flags,NOT fChanged |
|||
ret |
|||
|
|||
|
|||
|
|||
; |
|||
; HasChange - see if drive can supply change line |
|||
; |
|||
; Inputs: DS:DI points to current BDS |
|||
; Outputs: Zero set - no change line available |
|||
; Zero reset - change line available |
|||
; Registers modified: none |
|||
|
|||
PUBLIC HASCHANGE ;;Rev 3.30 Modification |
|||
HasChange: |
|||
MESSAGE FTEST13,<"HASCHANGE "> |
|||
MNUM FTEST13 |
|||
MESSAGE FTEST13,<CR,LF> ;;End of Modification |
|||
test word ptr [di].flags,fChangeline |
|||
ret |
|||
|
|||
ASSUME DS:CODE |
|||
|
|||
include msvolid.inc |
|||
|
|||
Public End96tpi |
|||
End96tpi Label Byte |
@ -0,0 +1,281 @@ |
|||
TITLE MSAUX - DOS 3.3 |
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; A U X - AUXILARY DEVICE DRIVER : |
|||
; : |
|||
; : |
|||
; This file contains the Auxilary Device Driver. The : |
|||
; auxilary driver handles calls to and from the RS-232 port. : |
|||
; Three devices uses this code: AUX, COM1, and COM2. AUX and : |
|||
; COM1 talk to the zero RS-232 card and COM2 talks to the : |
|||
; 'one' RS-232 card. The beginning of the interrupt entry : |
|||
; point for these devices sets the variable AUXNUM in the : |
|||
; msbio.asm module. If the value is 0 the routines in this : |
|||
; file will talk to the the 'zero' card. If the value in : |
|||
; AUXNUM is 1 the routines will talk to the 'one' card. : |
|||
; The procedure GETDX is called to put the value 0 or 1 in : |
|||
; the DX register depending on the value in AUXBUF. : |
|||
; : |
|||
; The routines in this files are: : |
|||
; : |
|||
; routine function : |
|||
; ------- -------- : |
|||
; AUX$READ Read characters from the : |
|||
; specified device. : |
|||
; AUX$RDND Non-desrucrtive read with : |
|||
; no waiting. : |
|||
; AUX$FLSH Flush specified device input : |
|||
; buffer. : |
|||
; AUX$WRIT Write characters to the : |
|||
; specified device. : |
|||
; AUX$WRST Get status of specified : |
|||
; device : |
|||
; : |
|||
; These routines are not called directly. Call are made via : |
|||
; the strategy and interrupt entry point (see Device Header). : |
|||
; : |
|||
; Data structure: : |
|||
; The Aux Device has a two byte buffer called AUXBUF. The : |
|||
; first byte is for the zero card, the second byte is for the : |
|||
; one card. A zero value in the byte indicates the buffer is : |
|||
; empty. The routines use GETBX to get the address of the : |
|||
; buffer. : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
|
|||
;;Ver 3.30 modification --------------------------- |
|||
test=0 |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT |
|||
INCLUDE JUMPMAC.INC |
|||
INCLUDE MSMACRO.INC |
|||
|
|||
EXTRN ERR$CNT:NEAR ;MSBIO1 |
|||
EXTRN GETDX:NEAR ;MSBIO1 |
|||
EXTRN RDEXIT:NEAR ;MSCON |
|||
EXTRN EXIT:NEAR ;MSBIO1 |
|||
EXTRN BUS$EXIT:NEAR ;MSBIO1 |
|||
;DATA |
|||
EXTRN AUXBUF:BYTE ;MSDATA |
|||
|
|||
; VALUES IN AH, REQUESTING FUNCTION OF INT 14H IN ROM BIOS |
|||
AUXFUNC_SEND EQU 1 ;TRANSMIT |
|||
AUXFUNC_RECEIVE EQU 2 ;READ |
|||
AUXFUNC_STATUS EQU 3 ;REQUEST STATUS |
|||
|
|||
; ERROR FLAGS, REPORTED BY INT 14H |
|||
|
|||
; THESE FLAGS REPORTED IN AH: |
|||
FLAG_DATA_READY EQU 01H ;DATA READY |
|||
FLAG_OVERRUN EQU 02H ;OVERRUN ERROR |
|||
FLAG_PARITY EQU 04H ;PARITY ERROR |
|||
FLAG_FRAME EQU 08H ;FRAMING ERROR |
|||
FLAG_BREAK EQU 10H ;BREAK DETECT |
|||
FLAG_TRANHOL_EMP EQU 20H ;TRANSMIT HOLDING REGISTER EMPTY |
|||
FLAG_TRANSHF_EMP EQU 40H ;TRANSMIT SHIFT REGISTER EMPTY |
|||
FLAG_TIMEOUT EQU 80H ;TIMEOUT |
|||
|
|||
; THESE FLAGS REPORTED IN AL: |
|||
FLAG_DELTA_CTS EQU 01H ;DELTA CLEAR TO SEND |
|||
FLAG_DELTA_DSR EQU 02H ;DELTA DATA SET READY |
|||
FLAG_TRAIL_RING EQU 04H ;TRAILING EDGE RING INDICATOR |
|||
FLAG_DELTA_SIG EQU 08H ;DELTA RECEIVE LINE SIGNAL DETECT |
|||
FLAG_CTS EQU 10H ;CLEAR TO SEND |
|||
FLAG_DSR EQU 20H ;DATA SET READY |
|||
FLAG_RING EQU 40H ;RING INDICATOR |
|||
FLAG_REC_SIG EQU 80H ;RECEIVE LINE SIGNAL DETECT |
|||
;;End of modification ------------------ |
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Read zero or more characters from Auxilary Device : |
|||
; : |
|||
; input:es:[di] points to area to receive aux data : |
|||
; cx has number of bytes to be read : |
|||
; "auxnum" first byte has number of aux device (rel 0): |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
PUBLIC AUX$READ |
|||
AUX$READ PROC NEAR |
|||
ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE |
|||
jcxz EXVEC2 ; if no characters, get out |
|||
call GETBX ; put address of AUXBUF in BX |
|||
xor AX,AX ; clear AX register |
|||
xchg AL,[BX] ; Get character , if any, from |
|||
; buffer and clear buffer |
|||
or AL,AL ; if AL is nonzero there was a |
|||
; character in the buffer |
|||
jnz AUX2 ; if so skip AUXIN call |
|||
AUX1: ; |
|||
call AUXIN ; get character from port |
|||
AUX2: ; |
|||
stosb ; store character |
|||
loop AUX1 ; if more character, go around again |
|||
EXVEC2: ; |
|||
Jump EXIT ; all done, successful exit |
|||
AUX$READ ENDP |
|||
|
|||
; |
|||
; AUXIN: make a call on ROM BIOS to read character from |
|||
; the auxilary device, then do some error checking. |
|||
; If an error occurs then AUXIN jumps to ERR$CNT and |
|||
; does NOT return to where it was called from. |
|||
; |
|||
|
|||
AUXIN PROC NEAR |
|||
|
|||
mov ah,AUXFUNC_RECEIVE |
|||
call AUXOP |
|||
;check for Frame, Parity, or Overrun errors |
|||
;WARNING: these error bits are unpredictable |
|||
; if timeout (bit 7) is set |
|||
test ah,FLAG_FRAME or FLAG_PARITY or FLAG_OVERRUN |
|||
jz AROK ;No error if all bits are clear |
|||
|
|||
;Error getting character |
|||
add sp,+2 ;Remove rtn address (near call) |
|||
xor al,al |
|||
or al,FLAG_REC_SIG or FLAG_DSR or FLAG_CTS |
|||
|
|||
JUMP ERR$CNT |
|||
AROK: |
|||
RET ;CHAR JUST READ IS IN AL, STATUS IS IN AH |
|||
AUXIN ENDP |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Aux non-destructive read with no waiting : |
|||
; : |
|||
; input: es:[di] points to area to receive aux data : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
; |
|||
PUBLIC AUX$RDND |
|||
AUX$RDND PROC NEAR |
|||
ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE |
|||
call GETBX ; have BX point to AUXBUF |
|||
mov AL,[BX] ; copy contents of buffer to AL |
|||
or AL,AL ; if AL is non-zero (char in buffer) |
|||
jnz AUXRDX ; then return character |
|||
call AUXSTAT ; if not, get status of AUX device |
|||
TEST AH,FLAG_DATA_READY ;TEST DATA READY |
|||
jz AUXBUS ; then device is busy (not ready) |
|||
|
|||
TEST AL,FLAG_DSR ;TEST DATA SET READY |
|||
jz AUXBUS ; then device is busy (not ready) |
|||
call AUXIN ; else aux is ready, get character |
|||
call GETBX ; have bx point to AUXBUF |
|||
mov [BX],AL ; save character in buffer |
|||
AUXRDX: ; |
|||
Jump RDEXIT ; return character |
|||
|
|||
AUXBUS: ; |
|||
Jump BUS$EXIT ; jump to device busy exit |
|||
AUX$RDND ENDP |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Aux Output Status : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
PUBLIC AUX$WRST |
|||
AUX$WRST PROC NEAR |
|||
ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE |
|||
call AUXSTAT ; get status of AUX in AX |
|||
; now test to see if device is busy |
|||
; if this bit is not set, |
|||
;;Ver 3.30 modification ----------------------- |
|||
TEST AL,FLAG_DSR ;TEST DATA SET READY |
|||
jz AUXBUS ; then device is busy (not ready) |
|||
TEST AH,FLAG_TRANHOL_EMP ;TEST TRANSMIT HOLD REG EMPTY |
|||
;;End of modification ------------------------- |
|||
jz AUXBUS ; then device is busy (not ready) |
|||
Jump Exit |
|||
|
|||
AUX$WRST ENDP |
|||
|
|||
; |
|||
; AUXSTAT makes a call on the ROM-BIOS to determine the status |
|||
; of the auxilary device |
|||
; Outputs: |
|||
; AX is filled with status of port. |
|||
; DX is changes to specify which card - either 0, 1 (, 2, 3) ;ba |
|||
; NO other registers are modified |
|||
; |
|||
|
|||
AUXSTAT proc near |
|||
mov ah,AUXFUNC_STATUS |
|||
call AUXOP |
|||
ret |
|||
AUXSTAT endp |
|||
|
|||
AUXOP PROC NEAR |
|||
;AH=FUNCTION CODE |
|||
;0=INIT, 1=SEND, 2=RECEIVE, 3=STATUS |
|||
call GETDX ; have DX point to proper card |
|||
int 14h ; call rom-bios for status |
|||
ret |
|||
AUXOP ENDP |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Flush AUX Input buffer - set contents of AUXBUF to zero : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
PUBLIC AUX$FLSH |
|||
AUX$FLSH PROC NEAR |
|||
ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE |
|||
call GETBX ; get BX to point to AUXBUF |
|||
mov BYTE PTR [BX],0 ; zero out buffer |
|||
Jump Exit ; all done, successful return |
|||
AUX$FLSH ENDP |
|||
|
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Write to Auxilary Device : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
PUBLIC AUX$WRIT |
|||
AUX$WRIT PROC NEAR |
|||
ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE |
|||
jcxz EXVEC2 ; if CX is zero, no characters |
|||
; to be written, jump to exit |
|||
AUX$LOOP: |
|||
mov AL,ES:[DI] ; get character to be written |
|||
inc DI ; move DI pointer to next character |
|||
;;Ver 3.30 modification --------------------------- |
|||
MOV AH,AUXFUNC_SEND ;VALUE=1, INDICATES A WRITE |
|||
CALL AUXOP ;SEND CHARACTER OVER AUX PORT |
|||
|
|||
TEST AH,FLAG_TIMEOUT ;CHECK FOR ERROR |
|||
;;End of modification --------------------------- |
|||
jz AWOK ; then no error |
|||
mov AL,10 ; else indicate write fault |
|||
Jump ERR$CNT ; call error routines |
|||
|
|||
; if CX is non-zero, still more |
|||
AWOK: |
|||
loop AUX$LOOP ; more characrter to print |
|||
Jump Exit ; all done, successful return |
|||
AUX$WRIT ENDP |
|||
|
|||
|
|||
; |
|||
; GETBX puts the address of AUXBUF (the Auxilary Device buffer) |
|||
; in BX. After calling GETBX, a routine can get to AUXBUF |
|||
; with [BX]. |
|||
; |
|||
; NOTE: The getdx routine is in msbio1 and looks like: |
|||
; mov dx,word ptr cs:[auxnum] |
|||
; |
|||
GETBX PROC NEAR |
|||
call GETDX |
|||
mov BX,DX |
|||
add BX,OFFSET AUXBUF |
|||
ret |
|||
GETBX ENDP |
|||
|
|||
CODE ENDS |
|||
END |
@ -0,0 +1,118 @@ |
|||
; |
|||
; BDS is the Bios Data Structure. |
|||
; |
|||
; There is one BDS for each logical drive in the system. All the BDS's |
|||
; are linked together in a list with the pointer to the first BDS being |
|||
; found in Start_BDS. The BDS hold various values important to the disk |
|||
; drive. For example there is a field for last time accesses. As actions |
|||
; take place in the system the BDS are update to reflect the actions. |
|||
; For example is there is a read to a disk the last access field for the |
|||
; BDS for that drive is update to the current time. |
|||
; |
|||
; Values for various flags in BDS.Flags. |
|||
; |
|||
|
|||
fNon_Removable equ 01H ;For non-removable media |
|||
fChangeline equ 02H ;If changeline supported on drive |
|||
RETURN_FAKE_BPB equ 04H ; When set, don't do a build BPB |
|||
; just return the fake one |
|||
GOOD_TRACKLAYOUT equ 08H ; The track layout has no funny sectors |
|||
fI_Am_Mult equ 10H ;If more than one logical for this physical |
|||
fI_Own_Physical equ 20H ;Signify logical owner of this physical |
|||
fChanged equ 40H ;Indicates media changed |
|||
SET_DASD_true equ 80H ; Set DASD before next format |
|||
fChanged_by_format equ 100h |
|||
|
|||
; |
|||
; Various form factors to describe media |
|||
; |
|||
|
|||
ff48tpi equ 0 |
|||
ff96tpi equ 1 |
|||
ffSmall equ 2 |
|||
ffHardFile equ 5 |
|||
ffOther equ 7 |
|||
|
|||
BDS_Type struc |
|||
Link DD ? ; Link to next BDS |
|||
DriveNum DB ? ; Physical drive number |
|||
DriveLet DB ? ; DOS drive number |
|||
BytePerSec DW ? ; number of bytes/sec |
|||
SecPerClus DB ? ; sec per allocation unit |
|||
RESSEC DW ? ; number of reserved sectors |
|||
cFAT DB ? ; number of fats |
|||
cDir DW ? ; number of directory entries |
|||
DRVLIM DW ? ; number of sectors on medium |
|||
mediad DB ? ; media descriptor byte |
|||
cSecFat DW ? ; number of sectors/fat |
|||
SECLIM DW ? ; sectors per track |
|||
HDLIM DW ? ; max number of heads |
|||
HIDSEC DW ? ; number of hidden sectors |
|||
FatSiz DB ? ; flags... |
|||
Opcnt DW ? ; Open ref. count |
|||
Volid DB 12 dup (?) ; volume ID of medium |
|||
FormFactor DB ? ; form factor index |
|||
Flags DW ? ; various flags |
|||
cCyln DW ? ; max number of cylinders |
|||
RBytePerSec DW ? ; Recommended BPB |
|||
RSecPerClus DB ? |
|||
RRESSEC DW ? |
|||
RcFAT DB ? |
|||
RcDir DW ? |
|||
RDRVLIM DW ? |
|||
Rmediad DB ? |
|||
RcSecFat DW ? |
|||
RSECLIM DW ? |
|||
RHDLIM DW ? |
|||
RHIDSEC DW ? |
|||
RHHIDSEC DW ? |
|||
RLOGSEC DD ? |
|||
Reserve DB 6 dup (?) ; Reserved for future |
|||
; changed to word -- kcd9:85 |
|||
Track DB ? ; last track accessed on drive |
|||
Tim_Lo DW ? ; Time of last access. Keep |
|||
Tim_Hi DW ? ; these contiguous. |
|||
BDS_Type ends |
|||
|
|||
BPBSize = Track - RBytePerSec ; size in bytes of RecBPB area in the BDS |
|||
|
|||
|
|||
;;Rev 3.30 Modification |
|||
;********************************************************************* |
|||
; BDS structure for mini disk |
|||
;********************************************************************* |
|||
|
|||
BDSM_type struc |
|||
mlink DW -1 ;Link to next structure |
|||
DW ? |
|||
mdriveNum DB 80 ;Int 13 Drive Number |
|||
mdriveLet DB 3 ;Logical Drive Number |
|||
mBytePerSec DW 512 |
|||
mSecPerClus DB 1 ;Sectors/allocation unit |
|||
mRESSEC DW 1 ;Reserved sectors for DOS |
|||
mcFAT DB 2 ;No. of allocation tables |
|||
mcDIR DW 16 ;Number of directory entries |
|||
mDRVLIM DW 0 ;Number of sectors (at 512 bytes each) |
|||
mMediad DB 11111000B ;Media descriptor |
|||
mcSecFat DW 1 ;Number of FAT sectors |
|||
mSECLIM DW 0 ;Sector limit |
|||
mHDLIM DW 0 ;Head limit |
|||
mHIDSEC DW 0 ;Hidden sector count |
|||
mFatSiz DB 0 ;TRUE => bigfat |
|||
mOPCNT DW 0 ;Open Ref. Count |
|||
mVOLID DB "NO NAME " ;Volume ID for this disk |
|||
DB 0 ;ASCIZII for "NO NAME " |
|||
mFormFactor DB 3 ;Form Factor |
|||
mFLAGS DW 0020H ;Various Flags |
|||
mcCyln dw 40 ;max number of cylinders |
|||
mRecBPB db 31 dup (0) ;Recommended BPB for drive |
|||
mTrack db -1 |
|||
IsMini dw 1 ;Overlapping TIM_LOH |
|||
Hidden_Trks dw 0 ;Overlapping TIM_HIH |
|||
|
|||
;TIM_LOH DW -1 ;Keep these two contiguous (?) |
|||
;TIM_HIH DW -1 |
|||
BDSM_type ENDS |
|||
;****************************************************************************** |
|||
Max_mini_dsk_num = 23 ; Max # of mini disk bios can support |
|||
;;End of Modification |
@ -0,0 +1,5 @@ |
|||
msbio1+mscon+msaux+mslpt+msclock+msdisk+ |
|||
msbio2+mshard+msinit+sysinit1+sysconf+sysinit2+sysimes, |
|||
msbio, |
|||
msbio/m; |
|||
|
@ -0,0 +1,693 @@ |
|||
TITLE MSBIO MS-DOS 3.30 |
|||
|
|||
;------------------------------------------------------------------------------- |
|||
; : |
|||
; Microsoft Bio : |
|||
; : |
|||
; The file msbio.asm is the main file in the Mircosoft bio. This file : |
|||
; includes the other main files in the bio. Most of the routines are : |
|||
; in these include files. The main files included are: : |
|||
; : |
|||
; File Contains : |
|||
; : |
|||
; msdisk.inc Disk device driver routines : |
|||
; ms96tpi.inc Routines for 96tpi drives : |
|||
; msaux.inc Device driver for the rs-232 serial ports : |
|||
; msclock.inc Device driver for "clock$" device : |
|||
; mscon.inc Device driver for "con" : |
|||
; mslpt.inc Device driver for the printers : |
|||
; : |
|||
; Each of these files contain a header section documenting the code : |
|||
; in that file. : |
|||
; Msbio also includes several files for equ's, structure definition, : |
|||
; macro definitions, etc. These are: : |
|||
; : |
|||
; msbiomes.inc msmacro.inc devsym.inc : |
|||
; dskprm.inc error.inc : |
|||
; : |
|||
; Each of these file contains explanitory notes. : |
|||
; : |
|||
; The actual code in msbio can be broken down into several piece: : |
|||
; : |
|||
; macro definitions Several marco are defined in msbio. They : |
|||
; are a few odds and end that did not fit : |
|||
; anywhere else. : |
|||
; : |
|||
; Command Jump Table List of entry points in the device drivers. : |
|||
; See notation below for full explination. : |
|||
; : |
|||
; Interrupt and Strategy : |
|||
; Entry points Calls on the device driver first come to here. : |
|||
; There is common code with pushes registers and : |
|||
; the like before jumping to routines in the : |
|||
; driver files. The common exit points are also : |
|||
; in this file. : |
|||
; : |
|||
; Miscellaneous Code There are several routines and data structure : |
|||
; declarations. See below for details. : |
|||
; : |
|||
;------------------------------------------------------------------------------- |
|||
|
|||
|
|||
|
|||
; |
|||
; If the variable TEST is non-zero then code for debugging is included. |
|||
; The extra code will make the binary file nuch larger. |
|||
; The symbol is also defined in msequ.inc. Both must be changed to |
|||
; turn debugging on or off. |
|||
; |
|||
; The level of the debugging is controled by the variable fTestBits in |
|||
; this file. See the comment preceeding the variable for more information. |
|||
; The actual routines which print the messages are in msmacro.inc |
|||
; See the header comment in this file for more information. |
|||
; |
|||
;***For testing purposes, set the TEST flag to 1. Otherwise reset it. |
|||
|
|||
TEST=0 |
|||
|
|||
PATHGEN = 1 |
|||
|
|||
.SALL |
|||
; |
|||
; This is a DOSMAC macro which is used in DEVSYM which is included later. |
|||
; |
|||
|
|||
BREAK MACRO subtitle |
|||
SUBTTL subtitle |
|||
PAGE |
|||
ENDM |
|||
|
|||
; |
|||
; Some old versions of the 80286 have a bug in the chip. The popf |
|||
; instruction will enable interrupts. Therefore in a section of code with |
|||
; interrupts disabled and you need a popf instruction use the 'popff' |
|||
; macro instead. |
|||
; |
|||
|
|||
POPFF macro |
|||
jmp $+3 |
|||
iret |
|||
push cs |
|||
call $-2 |
|||
endm |
|||
|
|||
;;Rev 3.30 modification ----------------------------- |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT |
|||
|
|||
SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' |
|||
SYSINITSEG ENDS |
|||
|
|||
|
|||
INCLUDE JUMPMAC.INC |
|||
PATHSTART MACRO INDEX,ABBR |
|||
IFDEF PATHGEN |
|||
PUBLIC ABBR&INDEX&S,ABBR&INDEX&E |
|||
ABBR&INDEX&S LABEL BYTE |
|||
ENDIF |
|||
ENDM |
|||
|
|||
PATHEND MACRO INDEX,ABBR |
|||
IFDEF PATHGEN |
|||
ABBR&INDEX&E LABEL BYTE |
|||
ENDIF |
|||
ENDM |
|||
|
|||
INCLUDE PUSHPOP.INC |
|||
INCLUDE DEVSYM.INC ;MJB001 |
|||
;; End of Modification |
|||
|
|||
; |
|||
; Revision History |
|||
; |
|||
; REV 2.1 5/1/83 ARR added timer int handler and changed order of AUX |
|||
; PRN init for HAL0 |
|||
; |
|||
; REV 2.15 7/13/83 ARR Because of IBM design issues, and that BASCOM |
|||
; is ill behaved with respect to the 1CH timer interrupt, |
|||
; the timer handler has to be backed out! The intended |
|||
; code is commented out and has an ARR 2.15 annotation. |
|||
; This means the BIOS will go back to the multiple roll |
|||
; over bug. |
|||
; |
|||
; REV 2.20 8/5/83 ARR IBM makes hardware change. Now wants to use half |
|||
; height drives for HAL0, and back fit for PC/PC XT. Problem |
|||
; with head settle time. Previous drives got by on a 0 |
|||
; settle time, 1/2 hight drives need 15 head settle when |
|||
; doing WRITEs (0 ok on READ) if the head is being stepped. |
|||
; This requires a last track value to be kept so that BIOS |
|||
; knows when head is being moved. To help out |
|||
; programs that issue INT 13H directly, the head settle will |
|||
; normally be set to 15. It will be changed to 0 on READs, |
|||
; or on WRITEs which do not require head step. |
|||
; |
|||
; REV 2.21 8/11/83 MZ IBM wants write with verify to use head settle 0. |
|||
; Use same trick as above. |
|||
; |
|||
; REV 2.25 6/20/83 mjb001 added support for 96tpi and salmon |
|||
; |
|||
; REV 2.30 6/27/83 mjb002 added real-time clock |
|||
; |
|||
; REV 2.40 7/8/83 mjb003 added volume-id checking and int 2f macro |
|||
; definitions push* and pop* |
|||
; |
|||
; REV 2.41 7/12/83 ARR more 2.X enhancements. Open/Close media change |
|||
; |
|||
; REV 2.42 11/3/83 ARR more 2.X enhancements. Disk OPEN/CLOSE, FORMAT |
|||
; code and other misc hooked out to shrink BIOS. Code for |
|||
; Disk OPEN/CLOSE, FORMAT included only with 96tpi disks. |
|||
; |
|||
; Rev 2.43 12/6/83 MZ Examine boot sectors on hard disks for 16-bit fat |
|||
; check. Examine large fat bit in BPB for walk of media for |
|||
; DOS |
|||
; |
|||
; Rev 2.44 12/9/83 ARR Change to error reporting on INT 17H |
|||
; |
|||
; Rev 2.45 12/22/83 MZ Make head settle change only when disk parm is 0. |
|||
; |
|||
; Rev 3.21 3/20/87 SP Changed OUTCHR routine to always output to page 0. |
|||
|
|||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
|||
; |
|||
; IBM ADDRESSES FOR I/O |
|||
; |
|||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
|||
|
|||
include dskprm.inc |
|||
|
|||
SYSIZE = 100H ; number of paragraphs in sysinit module |
|||
LF = 10 ; line feed |
|||
CR = 13 ; carriage return |
|||
BACKSP = 8 ; backspace |
|||
BRKADR = 1BH * 4 ; 006C 1Bh break vector address |
|||
TIMADR = 1CH * 4 ; 0070 1Ch timer interrupt |
|||
DSKADR = 1EH * 4 ; address of ptr to disk parameters |
|||
SEC9 = 522H ; address of disk parameters |
|||
HEADSETTLE = SEC9+9 ; address of head settle time |
|||
NORMSETTLE = 15 ; Normal head settle |
|||
SPEEDSETTLE = 0 ; Speed up settle time |
|||
INITSPOT = 534H ; IBM wants 4 zeros here |
|||
AKPORT = 20H |
|||
EOI = 20H |
|||
|
|||
;;Rev 3.30 modification ----------------------------- |
|||
ASSUME CS:CODE,DS:NOTHING,ES:NOTHING |
|||
|
|||
EXTRN MEDIA$CHK:NEAR |
|||
EXTRN GET$BPB:NEAR |
|||
EXTRN DSK$INIT:NEAR |
|||
EXTRN DSK$READ:NEAR |
|||
EXTRN DSK$WRIT:NEAR |
|||
EXTRN DSK$WRITV:NEAR |
|||
EXTRN DSK$OPEN:NEAR |
|||
EXTRN DSK$CLOSE:NEAR |
|||
EXTRN DSK$REM:NEAR |
|||
EXTRN GENERIC$IOCTL:NEAR |
|||
EXTRN IOCTL$GETOWN:NEAR |
|||
EXTRN IOCTL$SETOWN:NEAR |
|||
EXTRN CON$READ:NEAR |
|||
EXTRN CON$RDND:NEAR |
|||
EXTRN CON$FLSH:NEAR |
|||
EXTRN CON$WRIT:NEAR |
|||
; EXTRN CON$GENIOCTL:NEAR |
|||
EXTRN AUX$READ:NEAR |
|||
EXTRN AUX$WRIT:NEAR |
|||
EXTRN AUX$FLSH:NEAR |
|||
EXTRN AUX$RDND:NEAR |
|||
EXTRN AUX$WRST:NEAR |
|||
EXTRN TIM$READ:NEAR |
|||
EXTRN TIM$WRIT:NEAR |
|||
EXTRN PRN$WRIT:NEAR |
|||
EXTRN PRN$STAT:NEAR |
|||
EXTRN PRN$TILBUSY:NEAR |
|||
EXTRN PRN$GENIOCTL:NEAR |
|||
EXTRN WRMSG:NEAR |
|||
;DATA AREAS |
|||
INCLUDE MSDATA.INC |
|||
;;End of modification ----------------------------- |
|||
|
|||
; |
|||
; The following variables and two routines (MSGOUT and MSGNUM) are used |
|||
; with the debug routines to print numbers and messages on the screen. |
|||
; |
|||
; The variable fTestBits controls the level of debugging in the system. |
|||
; See the comments and "equ's" in msmacro.inc for an explination of |
|||
; how to control the level of debugging. In a nutshell, setting |
|||
; fTestBits to fTestALL prints all the debugging messages. Setting |
|||
; it to fTestDisk prints all disk related messages, etc. |
|||
; |
|||
|
|||
if test |
|||
Public MSGNUM |
|||
MSGNUM: |
|||
pushf |
|||
test fTestBits,AX |
|||
jz MRet |
|||
push SI |
|||
push BX |
|||
push CX |
|||
push ES |
|||
push DI |
|||
mov DI,OFFSET NUMBUF |
|||
push CS |
|||
pop ES |
|||
mov CX,4 |
|||
NUMLOOP: |
|||
push CX |
|||
mov CL,4 |
|||
rol BX,CL |
|||
pop CX |
|||
push BX |
|||
and BX,0Fh |
|||
mov AL,Digits[BX] |
|||
stosb |
|||
pop BX |
|||
loop NumLoop |
|||
pop DI |
|||
pop ES |
|||
pop CX |
|||
pop BX |
|||
mov SI,OFFSET NUMBUF |
|||
call MSGOUT |
|||
pop SI |
|||
popf |
|||
ret |
|||
|
|||
Public MSGOUT |
|||
MSGOUT: |
|||
pushf |
|||
test fTestBits,ax |
|||
jz MRet |
|||
push DS |
|||
push AX |
|||
push BX |
|||
push CS |
|||
pop DS |
|||
call WRMSG |
|||
pop BX |
|||
pop AX |
|||
pop DS |
|||
MRet: |
|||
popf |
|||
ret |
|||
;;Rev 3.30 modification ----------------------------- |
|||
PUBLIC DUMPBYTES |
|||
;Dumpbytes will dump the bytes in memory in hex. Space will be put in |
|||
;between the bytes and CR, LF will be put at the end. - J.K. |
|||
;Input: DS:SI -> buffer to dump in Hex. |
|||
; CX -> # of bytes (Length of the buffer) |
|||
; |
|||
DUMPBYTES proc near |
|||
pushf |
|||
push ax |
|||
dumploops: |
|||
lodsb |
|||
mov ah, al |
|||
shr ah, 1 |
|||
shr ah, 1 |
|||
shr ah, 1 |
|||
shr ah, 1 |
|||
call hex_to_ascii |
|||
push ax |
|||
mov al, ah |
|||
call outchar |
|||
pop ax |
|||
call outchar |
|||
mov al, ' ' |
|||
call outchar |
|||
loop dumploops |
|||
|
|||
mov al, 0dh |
|||
call outchar |
|||
mov al, 0ah |
|||
call outchar |
|||
|
|||
pop ax |
|||
popf |
|||
ret |
|||
DUMPBYTES endp |
|||
|
|||
PUBLIC Hex_to_ascii |
|||
Hex_to_ascii proc near |
|||
and ax, 0f0fh |
|||
add ah, 30h |
|||
cmp ah, 3ah |
|||
jb hta_$1 |
|||
add ah, 7 |
|||
hta_$1: |
|||
add al, 30h |
|||
cmp al, 3ah |
|||
jb hta_$2 |
|||
add al, 7 |
|||
hta_$2: |
|||
ret |
|||
Hex_to_ascii endp |
|||
|
|||
PUBLIC outchar |
|||
Outchar proc near |
|||
PUSH AX |
|||
PUSH SI |
|||
PUSH DI |
|||
PUSH BP |
|||
PUSH BX |
|||
MOV AH, 0Eh ;SET COMMAND TO WRITE A CHAR |
|||
MOV BL, 7 ;SET FOREGROUND COLOR |
|||
mov bh,0 ; |
|||
INT 10h ;CALL ROM-BIOS |
|||
POP BX |
|||
POP BP |
|||
POP DI |
|||
POP SI |
|||
POP AX |
|||
RET |
|||
Outchar endp |
|||
|
|||
ENDIF |
|||
;;End of modification ----------------------------- |
|||
|
|||
; |
|||
; end of routines for debugging |
|||
; |
|||
INCLUDE MSMACRO.INC |
|||
|
|||
|
|||
|
|||
; |
|||
; The next nine equ's describe the offset into the request header for |
|||
; different information. For example STATUS is in byte 3 of the request |
|||
; header (starting count at zero). |
|||
; |
|||
|
|||
CMDLEN = 0 ; length of this command |
|||
UNIT = 1 ; sub unit specifier |
|||
CMD = 2 ; command code |
|||
STATUS = 3 ; status |
|||
MEDIA = 13 ; media descriptor |
|||
TRANS = 14 ; transfer address |
|||
COUNT = 18 ; count of blocks or characters |
|||
START = 20 ; first block to transfer |
|||
EXTRA = 22 ; Usually pointer to Vol Id for error 15 |
|||
|
|||
; |
|||
; Strategy is the strategy entry point for all default bio device drivers. |
|||
; All that is done is to save the pointer to the request header in the |
|||
; variable PtrSav. |
|||
; |
|||
|
|||
PUBLIC STRATEGY |
|||
STRATEGY PROC FAR |
|||
mov word ptr CS:[PTRSAV],BX |
|||
mov word ptr CS:[PTRSAV+2],ES |
|||
ret |
|||
|
|||
STRATEGY ENDP |
|||
|
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; |
|||
; Device entry point |
|||
; |
|||
; The following ten pieces of code are the interrupt entry points for the |
|||
; default device drivers. These small pieces of code have two jobs. |
|||
; |
|||
; 1) Make SI point to the beginning of the proper command jump table. |
|||
; SI must first be pushed to preserve original contents. |
|||
; 2) If the call is an AUX or a printer save the number of the |
|||
; request in AL. AL is moved to AUXNUM below. |
|||
; |
|||
|
|||
; |
|||
; Con device: |
|||
; |
|||
|
|||
;;Rev 3.30 modification ----------------------------- |
|||
PUBLIC CON$IN |
|||
CON$IN PROC FAR |
|||
PUSH SI |
|||
MOV SI,OFFSET CONTBL |
|||
JMP SHORT ENTRY |
|||
CON$IN ENDP |
|||
|
|||
PUBLIC AUX0$IN |
|||
AUX0$IN PROC FAR |
|||
PUSH SI |
|||
PUSH AX |
|||
XOR AL,AL |
|||
JMP SHORT AUXENT |
|||
AUX0$IN ENDP |
|||
|
|||
PUBLIC AUX1$IN |
|||
AUX1$IN PROC FAR |
|||
PUSH SI |
|||
PUSH AX |
|||
MOV AL,1 |
|||
JMP short AUXENT |
|||
AUX1$IN ENDP |
|||
|
|||
PUBLIC AUX2$IN |
|||
AUX2$IN proc far |
|||
push si |
|||
push ax |
|||
mov al,2 |
|||
jmp short AUXENT |
|||
AUX2$IN endp |
|||
|
|||
PUBLIC AUX3$IN |
|||
AUX3$IN proc far |
|||
push si |
|||
push ax |
|||
mov al,3 |
|||
jmp short AUXENT |
|||
|
|||
AUXENT: |
|||
MOV SI,OFFSET AUXTBL |
|||
JMP SHORT ENTRY1 |
|||
AUX3$IN ENDP |
|||
|
|||
PRN0$IN PROC FAR |
|||
PUBLIC PRN0$IN |
|||
|
|||
PUSH SI |
|||
PUSH AX |
|||
XOR AX,AX |
|||
JMP SHORT PRNENT |
|||
PRN0$IN ENDP |
|||
|
|||
PUBLIC PRN1$IN |
|||
PRN1$IN PROC FAR |
|||
PUSH SI |
|||
PUSH AX |
|||
XOR AL,AL |
|||
MOV AH,1 |
|||
JMP SHORT PRNENT |
|||
PRN1$IN ENDP |
|||
|
|||
PUBLIC PRN2$IN |
|||
PRN2$IN PROC FAR |
|||
PUSH SI |
|||
PUSH AX |
|||
MOV AL,1 |
|||
MOV AH,2 |
|||
JMP SHORT PRNENT |
|||
PRN2$IN ENDP |
|||
|
|||
PUBLIC PRN3$IN |
|||
PRN3$IN PROC FAR |
|||
PUSH SI |
|||
PUSH AX |
|||
MOV AL,2 |
|||
MOV AH,3 |
|||
PRNENT: |
|||
MOV SI,OFFSET PRNTBL |
|||
MOV CS:[PRINTDEV],AH ;SAVE INDEX TO ARRAY OF RETRY CNTS |
|||
JMP SHORT ENTRY1 |
|||
PRN3$IN ENDP |
|||
|
|||
PUBLIC TIM$IN |
|||
TIM$IN PROC FAR |
|||
PUSH SI |
|||
MOV SI,OFFSET TIMTBL |
|||
JMP SHORT ENTRY |
|||
TIM$IN ENDP |
|||
|
|||
PUBLIC DSK$IN |
|||
DSK$IN PROC FAR |
|||
push SI |
|||
mov SI,OFFSET DSKTBL |
|||
;;End of modification ----------------------------- |
|||
|
|||
|
|||
|
|||
; |
|||
; This section is the prolog to all default device drivers. All registers |
|||
; are saved, the registers are filled with information fromthe request header, |
|||
; and the routine from the jump table is called. Error checking is done |
|||
; to assure command code is valid. Before calling the routine in the |
|||
; jump table the register are: |
|||
; |
|||
; AH = Media Descriptor |
|||
; AL = Unit Code |
|||
; BX = offset to PTRSAV (request header is therefore at DS:BX) |
|||
; CX = count from request header |
|||
; DX = start sector |
|||
; ES:DI = tranfer address |
|||
; SI = points to jump table |
|||
; DS = points to this segment |
|||
; |
|||
; Once the routine finishes its job it jumps back to one of the eight |
|||
; pieces of code below labeled Exit Points. |
|||
; |
|||
|
|||
ENTRY: |
|||
push AX |
|||
ENTRY1: |
|||
push CX ; save all registers |
|||
push DX |
|||
push DI |
|||
push BP |
|||
push DS |
|||
push ES |
|||
push BX |
|||
|
|||
mov CS:[AUXNUM],AL ; save choice of AUX/PRN device |
|||
|
|||
lds BX,CS:[PTRSAV] ; get pointer to I/O packet |
|||
ASSUME DS:NOTHING |
|||
|
|||
mov AL,byte ptr DS:[BX].UNIT ;AL = UNIT CODE |
|||
mov AH,byte ptr DS:[BX].MEDIA ;AH = MEDIA DESCRIP |
|||
mov CX,word ptr DS:[BX].COUNT ;CX = COUNT |
|||
mov DX,word ptr DS:[BX].START ;DX = START SECTOR |
|||
|
|||
xchg DI,AX |
|||
mov AL,BYTE PTR DS:[BX].CMD |
|||
cmp AL,CS:[SI] ; is command code a valid number? |
|||
ja CMDERR ; no, jump to handle error |
|||
|
|||
cbw ; note that AL <= 15 means OK |
|||
shl AX,1 |
|||
add SI,AX ; get SI to point to address of routine |
|||
xchg AX,DI ; put proper value back into AX |
|||
; get ES:DI to point to transfer address |
|||
les DI,DWORD PTR DS:[BX].TRANS |
|||
push CS ; get DS equal to CS |
|||
pop DS |
|||
|
|||
ASSUME DS:CODE |
|||
|
|||
cld ; clear the direction flag |
|||
jmp WORD PTR [SI+1] ; go to the command |
|||
|
|||
DSK$IN ENDP |
|||
PAGE |
|||
;===================================================== |
|||
;= |
|||
;= SUBROUTINES SHARED BY MULTIPLE DEVICES |
|||
;= |
|||
;===================================================== |
|||
|
|||
|
|||
|
|||
;---------------------------------------------------------- |
|||
; |
|||
; Exit Points |
|||
; |
|||
; All device driver call return through one of these eight |
|||
; pieces of code. The code set error and status conditions |
|||
; and then restores the registers. |
|||
; |
|||
|
|||
PUBLIC BUS$EXIT ; device busy exit |
|||
BUS$EXIT PROC FAR |
|||
ASSUME DS:NOTHING |
|||
mov AH,00000011B ; set error code |
|||
jmp SHORT ERR1 |
|||
|
|||
PUBLIC CMDERR |
|||
CMDERR: |
|||
mov AL,3 ; unknown command error |
|||
|
|||
PUBLIC ERR$CNT |
|||
ERR$CNT: |
|||
lds BX,CS:[PTRSAV] |
|||
ASSUME DS:NOTHING |
|||
sub WORD PTR [BX].COUNT,CX ;# of successful I/O's |
|||
|
|||
PUBLIC ERR$EXIT |
|||
ERR$EXIT: |
|||
mov AH,10000001B ; mark error and return |
|||
jmp SHORT ERR1 |
|||
|
|||
BUS$EXIT ENDP |
|||
EXITP proc FAR |
|||
ASSUME DS:CODE |
|||
|
|||
EXIT$ZER: |
|||
lds BX,[PTRSAV] |
|||
ASSUME DS:NOTHING |
|||
xor AX,AX |
|||
mov WORD PTR [BX].COUNT,AX ; indicate no character read |
|||
|
|||
Public EXIT |
|||
EXIT: |
|||
ASSUME DS:NOTHING |
|||
mov AH,00000001B |
|||
ERR1: |
|||
ASSUME DS:NOTHING |
|||
lds BX,CS:[PTRSAV] |
|||
mov WORD PTR [BX].STATUS,AX ; mark operation complete |
|||
|
|||
pop BX ; restore register and return |
|||
pop ES |
|||
pop DS |
|||
pop BP |
|||
pop DI |
|||
pop DX |
|||
pop CX |
|||
pop AX |
|||
pop SI |
|||
ret |
|||
EXITP endp |
|||
|
|||
|
|||
;------------------------------------------------------------- |
|||
; |
|||
; Chrout - write out character in AL using current attribute |
|||
; |
|||
; called via int 29h |
|||
; |
|||
PUBLIC CHROUT |
|||
CHROUT = 29H |
|||
|
|||
Public OUTCHR |
|||
OUTCHR PROC FAR |
|||
push AX ; preserve affect registers |
|||
push SI |
|||
push DI |
|||
push BP |
|||
push bx ; |
|||
mov AH, 0Eh ; set command to write a character |
|||
mov bh,0 ; |
|||
mov BL, 7 ; set foreground color |
|||
int 10h ; call rom-bios |
|||
pop bx ; |
|||
pop BP ; restore registers |
|||
pop DI |
|||
pop SI |
|||
pop AX |
|||
iret |
|||
OUTCHR ENDP |
|||
|
|||
|
|||
;---------------------------------------------- |
|||
; |
|||
; Fill DX register with value in AUXNUM |
|||
; |
|||
|
|||
PUBLIC GETDX |
|||
GETDX PROC NEAR |
|||
mov DX,WORD PTR CS:[AUXNUM] |
|||
ret |
|||
GETDX ENDP |
|||
page |
|||
CODE ENDS |
|||
END |
@ -0,0 +1,650 @@ |
|||
TITLE MSBIO2 - DOS 3.3 |
|||
|
|||
;------------------------------------------------------------------------------- |
|||
; : |
|||
; Microsoft Bio : |
|||
; : |
|||
; The file msbio.asm is the main file in the Mircosoft bio. This file : |
|||
; includes the other main files in the bio. Most of the routines are : |
|||
; in these include files. The main files included are: : |
|||
; : |
|||
; File Contains : |
|||
; : |
|||
; msdisk.inc Disk device driver routines : |
|||
; ms96tpi.inc Routines for 96tpi drives : |
|||
; msaux.inc Device driver for the rs-232 serial ports : |
|||
; msclock.inc Device driver for "clock$" device : |
|||
; mscon.inc Device driver for "con" : |
|||
; mslpt.inc Device driver for the printers : |
|||
; : |
|||
; Each of these files contain a header section documenting the code : |
|||
; in that file. : |
|||
; Msbio also includes several files for equ's, structure definition, : |
|||
; macro definitions, etc. These are: : |
|||
; : |
|||
; msbiomes.inc msmacro.inc devsym.inc : |
|||
; dskprm.inc error.inc : |
|||
; : |
|||
; Each of these file contains explanitory notes. : |
|||
; : |
|||
; The actual code in msbio can be broken down into several piece: : |
|||
; : |
|||
; macro definitions Several marco are defined in msbio. They : |
|||
; are a few odds and end that did not fit : |
|||
; anywhere else. : |
|||
; : |
|||
; Command Jump Table List of entry points in the device drivers. : |
|||
; See notation below for full explination. : |
|||
; : |
|||
; Interrupt and Strategy : |
|||
; Entry points Calls on the device driver first come to here. : |
|||
; There is common code with pushes registers and : |
|||
; the like before jumping to routines in the : |
|||
; driver files. The common exit points are also : |
|||
; in this file. : |
|||
; : |
|||
; Miscellaneous Code There are several routines and data structure : |
|||
; declarations. See below for details. : |
|||
; : |
|||
;------------------------------------------------------------------------------- |
|||
|
|||
|
|||
|
|||
; |
|||
; If the variable TEST is non-zero then code for debugging is included. |
|||
; The extra code will make the binary file nuch larger. |
|||
; The symbol is also defined in msequ.inc. Both must be changed to |
|||
; turn debugging on or off. |
|||
; |
|||
; The level of the debugging is controled by the variable fTestBits in |
|||
; this file. See the comment preceeding the variable for more information. |
|||
; The actual routines which print the messages are in msmacro.inc |
|||
; See the header comment in this file for more information. |
|||
; |
|||
|
|||
|
|||
; |
|||
; Revision History |
|||
; |
|||
; REV 2.1 5/1/83 ARR added timer int handler and changed order of AUX |
|||
; PRN init for HAL0 |
|||
; |
|||
; REV 2.15 7/13/83 ARR Because of IBM design issues, and that BASCOM |
|||
; is ill behaved with respect to the 1CH timer interrupt, |
|||
; the timer handler has to be backed out! The intended |
|||
; code is commented out and has an ARR 2.15 annotation. |
|||
; This means the BIOS will go back to the multiple roll |
|||
; over bug. |
|||
; |
|||
; REV 2.20 8/5/83 ARR IBM makes hardware change. Now wants to use half |
|||
; height drives for HAL0, and back fit for PC/PC XT. Problem |
|||
; with head settle time. Previous drives got by on a 0 |
|||
; settle time, 1/2 hight drives need 15 head settle when |
|||
; doing WRITEs (0 ok on READ) if the head is being stepped. |
|||
; This requires a last track value to be kept so that BIOS |
|||
; knows when head is being moved. To help out |
|||
; programs that issue INT 13H directly, the head settle will |
|||
; normally be set to 15. It will be changed to 0 on READs, |
|||
; or on WRITEs which do not require head step. |
|||
; |
|||
; REV 2.21 8/11/83 MZ IBM wants write with verify to use head settle 0. |
|||
; Use same trick as above. |
|||
; |
|||
; REV 2.25 6/20/83 mjb001 added support for 96tpi and salmon |
|||
; |
|||
; REV 2.30 6/27/83 mjb002 added real-time clock |
|||
; |
|||
; REV 2.40 7/8/83 mjb003 added volume-id checking and int 2f macro |
|||
; definitions push* and pop* |
|||
; |
|||
; REV 2.41 7/12/83 ARR more 2.X enhancements. Open/Close media change |
|||
; |
|||
; REV 2.42 11/3/83 ARR more 2.X enhancements. Disk OPEN/CLOSE, FORMAT |
|||
; code and other misc hooked out to shrink BIOS. Code for |
|||
; Disk OPEN/CLOSE, FORMAT included only with 96tpi disks. |
|||
; |
|||
; Rev 2.43 12/6/83 MZ Examine boot sectors on hard disks for 16-bit fat |
|||
; check. Examine large fat bit in BPB for walk of media for |
|||
; DOS |
|||
; |
|||
; Rev 2.44 12/9/83 ARR Change to error reporting on INT 17H |
|||
; |
|||
; Rev 2.45 12/22/83 MZ Make head settle change only when disk parm is 0. |
|||
|
|||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
|||
; |
|||
; IBM ADDRESSES FOR I/O |
|||
; |
|||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
|||
|
|||
;Below was moved from sysinit1 |
|||
ROMSEGMENT EQU 0F000H |
|||
MODELBYTE EQU DS:BYTE PTR [0FFFEH] |
|||
MODELPCJR EQU 0FDH |
|||
|
|||
test=0 |
|||
;;Rev 3.30 modification ---------------------------- |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT |
|||
INCLUDE MSEQU.INC |
|||
INCLUDE DEVSYM.INC |
|||
INCLUDE PUSHPOP.INC |
|||
INCLUDE MSMACRO.INC |
|||
|
|||
ASSUME DS:NOTHING,ES:NOTHING |
|||
|
|||
EXTRN DSK$IN:NEAR |
|||
EXTRN SETPTRSAV:NEAR |
|||
EXTRN OUTCHR:NEAR |
|||
EXTRN SETDRIVE:NEAR |
|||
EXTRN FLUSH:NEAR |
|||
EXTRN HARDERR:NEAR |
|||
EXTRN HARDERR2:NEAR |
|||
EXTRN MAPERROR:NEAR |
|||
EXTRN GETBP:NEAR |
|||
EXTRN CHECKSINGLE:NEAR |
|||
EXTRN CHECK_TIME_OF_ACCESS:NEAR |
|||
EXTRN EXIT:NEAR |
|||
EXTRN HAS1:NEAR |
|||
EXTRN HAS1_res:NEAR |
|||
EXTRN READ_SECTOR:NEAR |
|||
EXTRN INT_2F_13:FAR |
|||
|
|||
EXTRN OLD13:DWORD |
|||
|
|||
;DATA |
|||
EXTRN PTRSAV:DWORD |
|||
EXTRN START_BDS:WORD |
|||
EXTRN FDRIVE1:WORD |
|||
EXTRN FDRIVE2:WORD |
|||
EXTRN FDRIVE3:WORD |
|||
EXTRN FDRIVE4:WORD |
|||
EXTRN FLAGBITS:WORD |
|||
EXTRN TIM_DRV:BYTE |
|||
EXTRN MEDBYT:BYTE |
|||
EXTRN DRVMAX:BYTE |
|||
|
|||
PATHSTART 005,DISK |
|||
EVENB |
|||
PUBLIC ORIG19 |
|||
ORIG19 DD ? |
|||
|
|||
PUBLIC INT19SEM |
|||
INT19SEM DB 0 ; INDICATE THAT ALL INT 19 |
|||
; INITIALIZATION IS COMPLETE |
|||
|
|||
IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77> |
|||
public Int19OLD&AA |
|||
Int19OLD&AA dd -1 ;Orignal hw int. vec for INT 19h. |
|||
ENDM |
|||
|
|||
EVENB |
|||
PUBLIC DSKDRVS |
|||
DSKDRVS DW FDRIVE1 |
|||
DW FDRIVE2 |
|||
DW FDRIVE3 |
|||
DW FDRIVE4 |
|||
PUBLIC HDSKTAB |
|||
HDSKTAB DW HDRIVE |
|||
DW DRIVEX |
|||
;* Next area is reseved for mini disk BPB pointers *** 4/7/86 |
|||
;* Don't change this pos. Should be add. from DskDrvs *** 4/7/86 |
|||
MINI_DISK_BPB_PTRS DB 40 dup (?) ;4/7/86 - mem res for Mini disk. |
|||
|
|||
EVENB |
|||
PUBLIC INT_2F_NEXT |
|||
INT_2F_NEXT DD ? |
|||
|
|||
RET_ADDR DD ? |
|||
|
|||
PATHEND 005,DISK |
|||
;;End of modification ---------------------------- |
|||
|
|||
; INT19 |
|||
; |
|||
; We "hook" the INT_REBOOT vector, because contrary to IBM documentation, |
|||
; it does NOT "bootstrap" the machine. It leaves memory almost untouched. |
|||
; Since the BIOS_INIT code assumes that certain Interrupt Vectors point to |
|||
; the ROM_BIOS we must "unhook" them before issuing the actual INT_REBOOT. |
|||
; Currently the following vectors need to be unhooked: |
|||
; 02,08,09,0A,0B,0C,0D,0E,70,72,73,74,75,76,77 |
|||
; |
|||
|
|||
Public Int19 |
|||
Int19 proc FAR |
|||
xor AX,AX ; get data segment to |
|||
mov DS,AX ; point to the vector table |
|||
assume ds:nothing |
|||
assume es:nothing |
|||
les DI,Old13 ; get ES to point to this segment |
|||
mov DS:[13h*4],DI ; restore old int13 value |
|||
mov DS:[13h*4+2],ES |
|||
|
|||
cmp Byte ptr Int19Sem, 0 |
|||
jnz int19vecs |
|||
jmp doint19 |
|||
|
|||
;;Dos 3.30 Will not support the PC-Jr |
|||
;;Rev 3.30 modification ---------------------------- |
|||
; ON THE PCJR, DON'T REPLACE ANY VECTORS |
|||
; MODEL BYTE DEFINITIONS FROM MSSTACK.ASM |
|||
; MOV AX,ROMSEGMENT |
|||
; MOV DS,AX |
|||
; MOV AL,MODELPCJR |
|||
; |
|||
; CMP AL,MODELBYTE |
|||
; JNE INT19VECS |
|||
; JMP DOINT19 |
|||
|
|||
|
|||
;Stacks code has changed these hardware interrupt vectors |
|||
;STKINIT in SYSINIT1 will initialzie Int19hOLDxx values. |
|||
int19vecs: |
|||
|
|||
; |
|||
; we now need to unhook all the vector replace to prevent stack overflow |
|||
; |
|||
|
|||
;;Rev 3.30 modification ---------------------------- |
|||
XOR AX,AX |
|||
MOV DS,AX |
|||
|
|||
IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77> |
|||
|
|||
LES DI,Int19OLD&AA |
|||
|
|||
mov ax,es ; Put segment where we can compare it |
|||
cmp ax,-1 ; OPT 0ffffh is not likely |
|||
je skip_int&AA ; OPT could get away without checking |
|||
cmp di,-1 ; OPT offset here. |
|||
je skip_int&AA |
|||
|
|||
MOV DS:[AA&H*4],DI |
|||
MOV DS:[AA&H*4+2],ES |
|||
skip_int&AA: |
|||
ENDM |
|||
;;End of modification ---------------------------- |
|||
|
|||
doint19: |
|||
LES DI,Orig19 |
|||
MOV DS:[19h*4],DI |
|||
MOV DS:[19h*4+2],ES |
|||
|
|||
INT 19h |
|||
INT19 ENDP |
|||
ASSUME DS:CODE |
|||
|
|||
;***************************************************************************** |
|||
PUBLIC DSK$INIT |
|||
DSK$INIT PROC NEAR |
|||
PUSH CS |
|||
POP DS |
|||
MOV AH,BYTE PTR DRVMAX |
|||
MOV DI,OFFSET DskDrvs |
|||
JMP SetPTRSAV |
|||
DSK$INIT ENDP |
|||
|
|||
|
|||
; |
|||
; Int 2f handler for external block drivers to communicate with the internal |
|||
; block driver in msdisk. The multiplex number chosen is 8. The handler |
|||
; sets up the pointer to the request packet in [PTRSAV] and then jumps to |
|||
; DSK$IN, the entry point for all disk requests. |
|||
; On exit from this driver (at EXIT), we will return to the external driver |
|||
; that issued this Int 2F, and can then remove the flags from the stack. |
|||
; This scheme allows us to have a small external device driver, and makes |
|||
; the maintainance of the various drivers (DRIVER and msBIO) much easier, |
|||
; since we only need to make changes in one place (most of the time). |
|||
; |
|||
; AL contains the Int2F function: |
|||
; 0 - Check for installed handler - RESERVED |
|||
; 1 - Install the BDS into the linked list |
|||
; 2 - DOS request |
|||
; |
|||
|
|||
MYNUM EQU 8 |
|||
|
|||
Public Int2F_Disk |
|||
Int2F_Disk PROC FAR |
|||
cmp ah,MYNUM |
|||
je Mine |
|||
jmp cs:[Int_2F_Next] ; chain to next Int 2F handler |
|||
Mine: |
|||
cmp al,0F8H ; IRET on reserved functions |
|||
jb Do_Func |
|||
IRET |
|||
Do_Func: |
|||
or al,al ; A GET INSTALLED STATE request? |
|||
jne Disp_Func |
|||
mov al,0FFH |
|||
IRET |
|||
Disp_Func: |
|||
Message fTestInit,<"Int2F_disk",cr,lf> |
|||
cmp al,1 ; Request for installing BDS? |
|||
jne Do_DOS_Req |
|||
call Install_BDS |
|||
IRET |
|||
|
|||
Do_DOS_Req: |
|||
; Set up pointer to request packet |
|||
MOV WORD PTR CS:[PTRSAV],BX |
|||
MOV WORD PTR CS:[PTRSAV+2],ES |
|||
jmp DSK$IN |
|||
|
|||
Int2F_Disk ENDP |
|||
|
|||
; |
|||
; Install_BDS installs a BDS a location DS:DI into the current linked list of |
|||
; BDS maintained by this device driver. It places the BDS at the END of the |
|||
; list. |
|||
Public Install_BDS |
|||
INSTALL_BDS PROC NEAR |
|||
message ftestinit,<"Install BDS",cr,lf> |
|||
; ds:di point to BDS to be installed |
|||
les si,dword ptr cs:[Start_BDS] ; Start at beginning of list |
|||
push es ; Save pointer to current BDS |
|||
push si |
|||
; es:si now point to BDS in linked list |
|||
Loop_Next_BDS: |
|||
cmp si,-1 ; got to end of linked list? |
|||
jz Install_Ret |
|||
; If we have several logical drives using the same physical drive, we must |
|||
; set the I_Am_Mult flag in each of the appropriate BDSs. |
|||
mov al,byte ptr ds:[di].DriveNum |
|||
cmp byte ptr es:[si].DriveNum,al |
|||
jnz Next_BDS |
|||
message ftestinit,<"Logical Drives",cr,lf> |
|||
xor bx,bx |
|||
mov bl,fI_Am_Mult |
|||
or word ptr ds:[di].flags,bx ; set flags in both BDSs concerned |
|||
or word ptr es:[si].flags,bx |
|||
mov bl,fI_Own_Physical |
|||
xor bx,-1 |
|||
and word ptr ds:[di].flags,bx ; reset that flag for 'new' BDS |
|||
; We must also set the fChangeline bit correctly. |
|||
mov bx,word ptr es:[si].flags ; determine if changeline available |
|||
and bl,fChangeline |
|||
xor bh,bh |
|||
or word ptr ds:[di].flags,bx |
|||
|
|||
Next_BDS: |
|||
; Before moving to next BDS, preserve pointer to current one. This is needed at |
|||
; the end when the new BDS is linked into the list. |
|||
pop bx ; discard previous pointer to BDS |
|||
pop bx |
|||
push es |
|||
push si |
|||
mov bx,word ptr es:[si].link + 2 |
|||
mov si,word ptr es:[si].link |
|||
mov es,bx |
|||
jmp short Loop_Next_BDS |
|||
|
|||
Install_Ret: |
|||
pop si ; Retrieve pointer to last BDS |
|||
pop es ; in linked list. |
|||
mov ax,ds |
|||
mov word ptr es:[si].link+2,ax ; install BDS |
|||
mov word ptr es:[si].link,di |
|||
mov word ptr ds:[di].link,-1 ; set NEXT pointer to NULL |
|||
RET |
|||
INSTALL_BDS ENDP |
|||
|
|||
; |
|||
; RE_INIT installs the Int 2F vector that will handle communication between |
|||
; external block drivers and the internal driver. It also installs the |
|||
; Reset_Int_13 interface. It is called by SYSYINIT |
|||
; |
|||
PUBLIC RE_INIT |
|||
RE_INIT PROC FAR |
|||
Message ftestinit,<"REINIT",CR,LF> |
|||
PUSH AX |
|||
PUSH DS |
|||
PUSH DI |
|||
XOR DI,DI |
|||
MOV DS,DI |
|||
MOV DI,2FH*4 ; point it to Int 2F Vector |
|||
MOV AX,WORD PTR DS:[DI] |
|||
MOV WORD PTR CS:[INT_2F_NEXT],AX |
|||
MOV AX,WORD PTR DS:[DI+2] ; preserve old Int 2F vector |
|||
MOV WORD PTR CS:[INT_2F_NEXT+2],AX |
|||
|
|||
; INSTALL the Reset_Int_13 |
|||
; interface |
|||
|
|||
|
|||
CLI |
|||
MOV Word Ptr DS:[DI],Offset Int_2f_13 ; install new vectors |
|||
MOV Word Ptr DS:[DI+2],CS |
|||
STI |
|||
POP DI |
|||
POP DS |
|||
POP AX |
|||
RET |
|||
|
|||
RE_INIT ENDP |
|||
|
|||
;------------------------------------------------- |
|||
; |
|||
; Ask to swap the disk in drive A: |
|||
; Using a different drive in a one drive system so |
|||
; request the user to change disks |
|||
; |
|||
Public SWPDSK |
|||
SWPDSK PROC NEAR |
|||
mov al,byte ptr ds:[di].drivelet ; get the drive letter |
|||
add al,"A" |
|||
mov cs:DRVLET,AL |
|||
push ds ; preserve segment register |
|||
push cs |
|||
pop ds |
|||
mov SI,OFFSET SNGMSG ; ds:si -> message |
|||
push BX |
|||
call WRMSG ;Print disk change message |
|||
call FLUSH |
|||
; wait for a keyboard character |
|||
xor AH, AH ; set command to read character |
|||
int 16h ; call rom-bios |
|||
POP BX |
|||
pop ds ; restore segment register |
|||
WRMRET: |
|||
ret |
|||
SWPDSK ENDP |
|||
|
|||
;---------------------------------------------- |
|||
; |
|||
; WrMsg writes out message pointed to by [SI] |
|||
; |
|||
Public WrMsg |
|||
WRMSG PROC NEAR |
|||
lodsb ; get the next character of the message |
|||
or AL,AL ; see fi end of message |
|||
jz WRMRET |
|||
pushf |
|||
push CS |
|||
call OUTCHR |
|||
jmp SHORT WRMSG |
|||
WRMSG ENDP |
|||
|
|||
INCLUDE BIOMES.INC |
|||
|
|||
; |
|||
; End of support for multiple floppies with no logical drives |
|||
; This is not 'special' any more because we now have the capability of |
|||
; defining logical drives in CONFIG.SYS. We therefore keep the code for |
|||
; swapping resident ALL the time. |
|||
; |
|||
|
|||
;;Rev 3.30 modification ---------------------------- |
|||
;Variables for Dynamic Relocatable modules |
|||
;These should be stay resident. |
|||
|
|||
public INT6C_RET_ADDR |
|||
INT6C_RET_ADDR DD ? ;ret add from INT 6C for P12 mach |
|||
|
|||
PATHSTART 001,CLK |
|||
; |
|||
; DATA STRUCTURES FOR REAL-TIME DATE AND TIME |
|||
; |
|||
public BIN_DATE_TIME |
|||
public MONTH_TABLE |
|||
public DAYCNT2 |
|||
public FEB29 |
|||
BIN_DATE_TIME: |
|||
DB 0 ; CENTURY (19 OR 20) OR HOURS (0-23) |
|||
DB 0 ; YEAR IN CENTURY (0-99) OR MINUTES (0-59) |
|||
DB 0 ; MONTH IN YEAR (1-12) OR SECONDS (0-59) |
|||
DB 0 ; DAY IN MONTH (1-31) |
|||
MONTH_TABLE: |
|||
DW 0 ;MJB002 JANUARY |
|||
DW 31 ;MJB002 FEBRUARY |
|||
DW 59 ;MJB002 |
|||
DW 90 ;MJB002 |
|||
DW 120 ;MJB002 |
|||
DW 151 ;MJB002 |
|||
DW 181 ;MJB002 |
|||
DW 212 ;MJB002 |
|||
DW 243 ;MJB002 |
|||
DW 273 ;MJB002 |
|||
DW 304 ;MJB002 |
|||
DW 334 ;MJB002 |
|||
DAYCNT2 DW 0000 ;MJB002 TEMP FOR CNT OF DAYS SINCE 1-1-80 |
|||
FEB29 DB 0 ;MJB002 FEBRUARY 29 IN A LEAP YEAR FLAG |
|||
PATHEND 001,CLK |
|||
|
|||
;;End of modification modification ---------------------------- |
|||
|
|||
Public EndFloppy |
|||
EndFloppy Label Byte |
|||
; |
|||
; End of code for virtual floppy drives |
|||
; |
|||
Public EndSwap |
|||
EndSwap Label Byte |
|||
|
|||
PATHSTART 004,BIO |
|||
|
|||
Public HNUM |
|||
HNUM DB 0 ; number of hardfile (hard drives) |
|||
|
|||
Public HardDrv |
|||
HARDDRV DB 80H ;Physical drive number of first hardfile |
|||
|
|||
|
|||
; |
|||
; "HDRIVE" is a hard disk with 512 byte sectors |
|||
; |
|||
|
|||
EVENB |
|||
Public BDSH |
|||
BDSH DW -1 ; Link to next structure |
|||
DW Code |
|||
DB 80h ; physical drive number |
|||
DB "C" ; Logical Drive Letter |
|||
Public HDRIVE |
|||
HDRIVE: |
|||
DW 512 |
|||
DB 1 ; Sectors/allocation unit |
|||
DW 1 ; Reserved sectors for DOS |
|||
DB 2 ; No. of allocation tables |
|||
DW 16 ; Number of directory entries |
|||
DW 0000 ; Number of sectors (at 512 bytes each) |
|||
DB 11111000B ; Media descriptor |
|||
DW 1 ; Number of FAT sectors |
|||
DW 00 ; Sector limit |
|||
DW 00 ; Head limit |
|||
DW 00 ; Hidden sector count |
|||
DB 0 ; TRUE => bigfat |
|||
OPCNTH DW 0 ; Open Ref. Count |
|||
VOLIDH DB "NO NAME ",0 ; Volume ID for this disk |
|||
DB 3 ; Form Factor |
|||
FLAGSH DW 0020H ; Various Flags |
|||
dw 40 ; number of cylinders |
|||
RecBPBH db 31 dup (?) ; Recommended BPB for drive |
|||
TRACKH DB -1 ; Last track accessed on this drive |
|||
TIM_LOH DW -1 ; Keep these two contiguous (?) |
|||
TIM_HIH DW -1 |
|||
; |
|||
; End of single hard disk section |
|||
; |
|||
|
|||
|
|||
Public EndOneHard |
|||
EndOneHard Label Byte |
|||
|
|||
|
|||
|
|||
|
|||
; |
|||
;"DRIVEX" is an extra type of drive usually reserved for an |
|||
; additional hard file |
|||
; |
|||
|
|||
EVENB |
|||
Public BDSX |
|||
BDSX DW -1 ; Link to next structure |
|||
DW Code |
|||
DB 81h ; physical drive number |
|||
DB "D" ; Logical Drive Letter |
|||
Public DRIVEX |
|||
DRIVEX: |
|||
DW 512 |
|||
DB 00 ; Sectors/allocation unit |
|||
DW 1 ; Reserved sectors for DOS |
|||
DB 2 ; No. of allocation tables |
|||
DW 0000 ; Number of directory entries |
|||
DW 0000 ; Number of sectors (at 512 bytes each) |
|||
DB 11111000B ; Media descriptor |
|||
DW 0000 ; Number of FAT sectors |
|||
DW 00 ; Sector limit |
|||
DW 00 ; Head limit |
|||
DW 00 ; Hidden sector count |
|||
DB 0 ; TRUE => bigfat |
|||
OPCNTD DW 0 ; Open Ref. Count |
|||
VOLIDD DB "NO NAME ",0 ; Volume ID for this disk |
|||
DB 3 ; Form Factor |
|||
FLAGSD DW 0020H ; Various Flags |
|||
dw 40 ; number of cylinders |
|||
RecBPBD db 31 dup (?) ; Recommended BPB for drive |
|||
TRACKD DB -1 ; Last track accessed on this drive |
|||
TIM_LOD DW -1 ; Keep these two contiguous |
|||
TIM_HID DW -1 |
|||
|
|||
; |
|||
; End of section for two hard disks |
|||
Public EndTwoHard |
|||
EndTwoHard Label Byte |
|||
|
|||
PATHEND 004,BIO |
|||
|
|||
|
|||
Public TwoHard |
|||
TWOHARD LABEL BYTE |
|||
|
|||
PAGE |
|||
include ms96tpi.inc |
|||
|
|||
;;Rev 3.30 modification ---------------------------- |
|||
;Memory allocation for BDSM table. |
|||
PUBLIC BDSMs |
|||
BDSMs BDSM_type Max_mini_dsk_num dup (<>) ;currently max. 23 |
|||
|
|||
;** End_of_BDSM defined in MSINIT.ASM will be used to set the appropriate |
|||
;** ending address of BDSM table. |
|||
;;End of modification ---------------------------- |
|||
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug005sp |
|||
; |
|||
;;3.3 BUG FIX -SUNILP ------------------------------ |
|||
;Paragraph buffer between the BDSMs and MSHARD |
|||
; |
|||
;The relocation code for MSHARD needs this. this cannot be used for |
|||
;anything. nothing can come before this or after this.....IMPORTANT!!!! |
|||
;don't get too smart and using this buffer for anything!!!!!! |
|||
; |
|||
; db 16 dup(0) |
|||
; |
|||
;end of bug fix buffer |
|||
;; |
|||
;;3.3 BUG FIX -SUNILP------------------------------ |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug005sp |
|||
CODE ENDS |
|||
END |
@ -0,0 +1,295 @@ |
|||
TITLE MSCLOCK - DOS 3.3 |
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; CLOCK DEVICE DRIVER : |
|||
; : |
|||
; : |
|||
; This file contains the Clock Device Driver. : |
|||
; : |
|||
; The routines in this files are: : |
|||
; : |
|||
; routine function : |
|||
; ------- -------- : |
|||
; TIM$WRIT Set the current time : |
|||
; TIM$READ Read the current time : |
|||
; Time_To_Ticks Convert time to corresponding : |
|||
; number of clock ticks : |
|||
; : |
|||
; The clock ticks at the rate of: : |
|||
; : |
|||
; 1193180/65536 ticks/second (about 18.2 ticks per second): |
|||
; See each routine for information on the use. : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
|
|||
|
|||
test=0 |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT |
|||
INCLUDE MSMACRO.INC |
|||
|
|||
EXTRN EXIT:NEAR |
|||
; |
|||
; DAYCNT is the number of days since 1-1-80. |
|||
; Each time the clock is read it is necessary to check if another day has |
|||
; passed. The ROM only returns the day rollover once so if it is missed |
|||
; the time will be off by a day. |
|||
; |
|||
EXTRN DAYCNT:WORD ;MSDATA |
|||
|
|||
;;Rev 3.30 Modification ------------------------------------------------ |
|||
; variables for real time clock setting |
|||
public HaveCMOSClock |
|||
HaveCMOSClock db 0 ;set by MSINIT. |
|||
public base_century |
|||
base_century db 19 |
|||
public base_year |
|||
base_year db 80 |
|||
public month_tab |
|||
month_tab db 31,28,31,30,31,30,31,31,30,31,30,31 |
|||
|
|||
; The following are indirect intra-segment call addresses. The |
|||
;procedures are defined in MSINIT for relocation. MSINIT will set these |
|||
;address when the relocation is done. |
|||
public BinToBCD |
|||
BinToBCD dw 0 ;should point to Bin_To_BCD proc in MSINIT |
|||
public DaycntToDay |
|||
DaycntToDay dw 0 ;should point to Daycnt_to_day in MSINIT |
|||
|
|||
;******************************************************************** |
|||
; Indirect call address of TIME_TO_TICKS procedure. |
|||
;This will be used by the relocatable portable suspend/resume code. |
|||
|
|||
public TimeToTicks |
|||
TimeToTicks dw Time_To_Ticks |
|||
|
|||
;;End of Modification ------------------------------------------------ |
|||
|
|||
;-------------------------------------------------------------------- |
|||
; |
|||
; Settime sets the current time |
|||
; |
|||
; On entry ES:[DI] has the current time: |
|||
; |
|||
; number of days since 1-1-80 (WORD) |
|||
; minutes (0-59) (BYTE) |
|||
; hours (0-23) (BYTE) |
|||
; hundredths of seconds (0-99) (BYTE) |
|||
; seconds (0-59) (BYTE) |
|||
; |
|||
; Each number has been checked for the correct range. |
|||
; |
|||
PUBLIC TIM$WRIT |
|||
TIM$WRIT PROC NEAR |
|||
ASSUME DS:CODE |
|||
mov AX,WORD PTR ES:[DI] |
|||
push AX ;DAYCNT. We need to set this at the very |
|||
; end to avoid tick windows. |
|||
;;Rev 3.30 Modification |
|||
cmp HaveCMOSClock, 0 |
|||
je No_CMOS_1 |
|||
mov al,es:[di+3] ;get binary hours |
|||
call BinToBCD ;convert to BCD |
|||
mov ch,al ;CH = BCD hours |
|||
mov al,es:[di+2] ;get binary minutes |
|||
call BinToBCD ;convert to BCD |
|||
mov cl,al ;CL = BCD minutes |
|||
mov al,es:[di+5] ;get binary seconds |
|||
call BinToBCD ;convert to BCD |
|||
mov dh,al ;DH = BCD seconds |
|||
mov dl,0 ;DL = 0 (ST) or 1 (DST) |
|||
cli ;turn off timer |
|||
mov ah,03h ;set RTC time |
|||
int 1Ah ;call rom bios clock routine |
|||
sti |
|||
|
|||
;;End of Modification |
|||
No_CMOS_1: |
|||
mov CX,WORD PTR ES:[DI+2] |
|||
mov DX,WORD PTR ES:[DI+4] |
|||
;;Rev 3.30 Modification |
|||
call time_to_ticks ; convert time to ticks |
|||
;CX:DX now has time in ticks |
|||
cli ; Turn off timer |
|||
mov AH, 1 ; command is set time in clock |
|||
int 1Ah ; call rom-bios clock routines |
|||
pop [DAYCNT] |
|||
sti |
|||
;CMOS clock ------------------------------------- |
|||
cmp HaveCMOSClock, 0 |
|||
je No_CMOS_2 |
|||
call DaycntToDay ; convert to BCD format |
|||
cli ; Turn off timer |
|||
mov AH,05h ; set RTC date |
|||
int 1Ah ; call rom-bios clock routines |
|||
sti |
|||
;------------------------------------------------ |
|||
|
|||
No_CMOS_2: |
|||
jmp EXIT |
|||
TIM$WRIT ENDP |
|||
;;End of Modification |
|||
|
|||
|
|||
|
|||
; |
|||
; convert time to ticks |
|||
; input : time in CX and DX |
|||
; ticks returned in CX:DX |
|||
; |
|||
public time_to_ticks |
|||
TIME_TO_TICKS PROC NEAR |
|||
|
|||
; first convert from Hour,min,sec,hund. to |
|||
; total number of 100th of seconds |
|||
mov AL,60 |
|||
mul CH ;Hours to minutes |
|||
mov CH,0 |
|||
add AX,CX ;Total minutes |
|||
mov CX,6000 ;60*100 |
|||
mov BX,DX ;Get out of the way of the multiply |
|||
mul CX ;Convert to 1/100 sec |
|||
mov CX,AX |
|||
mov AL,100 |
|||
mul BH ;Convert seconds to 1/100 sec |
|||
add CX,AX ;Combine seconds with hours and min. |
|||
adc DX,0 ;Ripple carry |
|||
mov BH,0 |
|||
add CX,BX ;Combine 1/100 sec |
|||
adc DX,0 |
|||
|
|||
;;Rev 3.30 Modification |
|||
;DX:CX IS TIME IN 1/100 SEC |
|||
XCHG AX,DX |
|||
XCHG AX,CX ;NOW TIME IS IN CX:AX |
|||
MOV BX,59659 |
|||
MUL BX ;MULTIPLY LOW HALF |
|||
XCHG DX,CX |
|||
XCHG AX,DX ;CX->AX, AX->DX, DX->CX |
|||
MUL BX ;MULTIPLY HIGH HALF |
|||
ADD AX,CX ;COMBINE OVERLAPPING PRODUCTS |
|||
ADC DX,0 |
|||
XCHG AX,DX ;AX:DX=TIME*59659 |
|||
MOV BX,5 |
|||
DIV BL ;DIVIDE HIGH HALF BY 5 |
|||
MOV CL,AL |
|||
MOV CH,0 |
|||
MOV AL,AH ;REMAINDER OF DIVIDE-BY-5 |
|||
CBW |
|||
XCHG AX,DX ;USE IT TO EXTEND LOW HALF |
|||
DIV BX ;DIVDE LOW HALF BY 5 |
|||
MOV DX,AX |
|||
; CX:DX is now number of ticks in time |
|||
ret |
|||
TIME_TO_TICKS ENDP |
|||
;;End of Modification |
|||
|
|||
|
|||
; |
|||
; Gettime reads date and time |
|||
; and returns the following information: |
|||
; |
|||
; ES:[DI] =count of days since 1-1-80 |
|||
; ES:[DI+2]=hours |
|||
; ES:[DI+3]=minutes |
|||
; ES:[DI+4]=seconds |
|||
; ES:[DI+5]=hundredths of seconds |
|||
; |
|||
PUBLIC TIM$READ |
|||
TIM$READ PROC NEAR |
|||
; read the clock |
|||
xor AH, AH ; set command to read clock |
|||
int 1Ah ; call rom-bios to get time |
|||
|
|||
or al,al ; check for a new day |
|||
jz noroll1 ; if al=0 then don't reset day count |
|||
INC [DAYCNT] ; CATCH ROLLOVE |
|||
noroll1: |
|||
MOV SI,[DAYCNT] |
|||
|
|||
; |
|||
; we now need to convert the time in tick to the time in 100th of |
|||
; seconds. The relation between tick and seconds is: |
|||
; |
|||
; 65536 seconds |
|||
; ---------------- |
|||
; 1,193,180 tick |
|||
; |
|||
; To get to 100th of second we need to multiply by 100. The equation is: |
|||
; |
|||
; Ticks from clock * 65536 * 100 |
|||
; --------------------------------- = time in 100th of seconds |
|||
; 1,193,180 |
|||
; |
|||
; Fortunately this fromula simplifies to: |
|||
; |
|||
; Ticks from clock * 5 * 65,536 |
|||
; --------------------------------- = time in 100th of seconds |
|||
; 59,659 |
|||
; |
|||
; The calculation is done by first multipling tick by 5. Next we divide by |
|||
; 59,659. In this division we multiply by 65,536 by shifting the dividend |
|||
; my 16 bits to the left. |
|||
; |
|||
; start with ticks in CX:DX |
|||
; multiply by 5 |
|||
MOV AX,CX |
|||
MOV BX,DX |
|||
SHL DX,1 |
|||
RCL CX,1 ;TIMES 2 |
|||
SHL DX,1 |
|||
RCL CX,1 ;TIMES 4 |
|||
ADD DX,BX |
|||
ADC AX,CX ;TIMES 5 |
|||
XCHG AX,DX |
|||
|
|||
|
|||
; now have ticks * 5 in DX:AX |
|||
; we now need to multiply by 65,536 and divide by 59659 d. |
|||
|
|||
mov CX,59659 ; get divisor |
|||
div CX |
|||
; DX now has remainder |
|||
; AX has high word of final quotient |
|||
mov BX,AX ; put high work if safe place |
|||
xor AX,AX ; this is the multiply by 65536 |
|||
div CX ; BX:AX now has time in 100th of seconds |
|||
|
|||
; |
|||
;Rounding based on the remainder may be added here |
|||
;The result in BX:AX is time in 1/100 second. |
|||
mov DX,BX |
|||
mov CX,200 ;Extract 1/100's |
|||
;Division by 200 is necessary to ensure no overflow--max result |
|||
;is number of seconds in a day/2 = 43200. |
|||
div CX |
|||
cmp DL,100 ;Remainder over 100? |
|||
jb NOADJ |
|||
sub DL,100 ;Keep 1/100's less than 100 |
|||
NOADJ: |
|||
cmc ;If we subtracted 100, carry is now set |
|||
mov BL,DL ;Save 1/100's |
|||
;To compensate for dividing by 200 instead of 100, we now multiply |
|||
;by two, shifting a one in if the remainder had exceeded 100. |
|||
rcl AX,1 |
|||
mov DL,0 |
|||
rcl DX,1 |
|||
mov CX,60 ;Divide out seconds |
|||
div CX |
|||
mov BH,DL ;Save the seconds |
|||
div CL ;Break into hours and minutes |
|||
xchg AL,AH |
|||
|
|||
;Time is now in AX:BX (hours, minutes, seconds, 1/100 sec) |
|||
|
|||
push AX |
|||
MOV AX,SI ; DAYCNT |
|||
stosw |
|||
pop AX |
|||
stosw |
|||
mov AX,BX |
|||
stosw |
|||
jmp EXIT |
|||
|
|||
TIM$READ ENDP |
|||
CODE ENDS |
|||
END |
@ -0,0 +1,216 @@ |
|||
TITLE MSCON - DOS 3.3 |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; C O N - CONSOLE DEVICE DRIVER : |
|||
; : |
|||
; : |
|||
; This file contains the Console Device Driver. The : |
|||
; console device driver sends characters to the moniter and : |
|||
; gets characters from the keyboard. : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
|
|||
;;Rev 3.30 Modification |
|||
test=0 |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT |
|||
INCLUDE JUMPMAC.INC |
|||
INCLUDE MSEQU.INC |
|||
INCLUDE MSMACRO.INC |
|||
|
|||
EXTRN EXIT:NEAR ;MSBIO1 |
|||
EXTRN BUS$EXIT:NEAR ;MSBIO1 |
|||
|
|||
;DATA |
|||
EXTRN PTRSAV:DWORD ;MSBIO1 |
|||
EXTRN FHAVEK09:BYTE ;MSDISK |
|||
EXTRN ALTAH:BYTE ;MSDATA |
|||
;;End of Modification |
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Console read routine : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
; |
|||
ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY PT |
|||
PUBLIC CON$READ |
|||
CON$READ PROC NEAR |
|||
; if CX is zero, no characters |
|||
jcxz CON$EXIT ; to be read -- just exit |
|||
CON$LOOP: |
|||
call CHRIN ; get char in AL |
|||
stosb ; store char at ES:DI, specified buffer |
|||
loop CON$LOOP ; if CX is non-zero more char to read |
|||
CON$EXIT: |
|||
Jump EXIT ; all done, successful return |
|||
CON$READ ENDP |
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Input single character into AL : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
CHRIN PROC NEAR |
|||
; set command to read character |
|||
xor AX, AX ; and clear AL |
|||
xchg AL,ALTAH ; get character & zero ALTAH |
|||
or AL, AL ; see if buffer has a character |
|||
jnz KEYRET ; if so - return this character |
|||
; if not - read single character |
|||
int 16h ; call ROM-Bios keyboard routine |
|||
ALT10: |
|||
or AX,AX ; Check for non-key after BREAK |
|||
jz CHRIN |
|||
cmp AX,7200h ; Check for CTRL-PRTSC |
|||
jnz ALT15 |
|||
mov AL,16 ; indicate prtsc |
|||
ALT15: |
|||
or AL,AL ; special case? |
|||
jnz KEYRET ; no, return with character |
|||
mov ALTAH, AH ; yes, store special key |
|||
KEYRET: |
|||
RET |
|||
CHRIN ENDP |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Keyboard non destructive read, no wait : |
|||
; : |
|||
; If bit 10 is set by the DOS in the status word of the request : |
|||
; packet, and there is no character in the input buffer, the : |
|||
; driver issues a system WAIT request to the ROM. On return : |
|||
; from the ROM, it returns a 'char-not-found' to the DOS. : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
|
|||
CONBUSJ: |
|||
ASSUME DS:NOTHING |
|||
JMP CONBUS |
|||
|
|||
ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY PT |
|||
PUBLIC CON$RDND |
|||
CON$RDND: |
|||
mov AL,[ALTAH] ; first see if there is a |
|||
or AL,AL ; character in the buffer? |
|||
jz RD1 ; with debugging code it is |
|||
jmp RDEXIT ; too far for conditional jump |
|||
|
|||
RD1: |
|||
; set command to 'see if |
|||
mov AH, 1 ; character available' |
|||
int 16h ; call ROM-BIOS keyboard routine |
|||
jz nochr ; with debugging code it is |
|||
jmp gotchr ; to far for conditional jump |
|||
nochr: |
|||
cmp fHaveK09, 0 |
|||
jz CONBUSJ |
|||
lds bx,[PTRSAV] ; get pointer to request header |
|||
ASSUME DS:NOTHING |
|||
test [bx].STATUS,0400H ; System WAIT enabled? |
|||
jz CONBUSJ ; no, get out |
|||
|
|||
message ftestcon,<"System WAIT stage",cr,lf> |
|||
|
|||
mov AX, 4100h ; set command for Wait on External |
|||
; event and condition type to |
|||
; any external event |
|||
xor BL,BL ; no timeout value |
|||
int 15h ; call rom-bios sleep function |
|||
message ftestcon,<"Out of wait. AX is "> |
|||
mnum ftestcon,ax |
|||
message ftestcon,<cr,lf> |
|||
jmp CONBUS ; after wait exit to con busy |
|||
|
|||
ASSUME DS:CODE |
|||
gotchr: |
|||
or AX, AX ; check for null after break |
|||
JNZ NOTBRK ; no, skip down |
|||
; note: AH is already zero, no need to set command |
|||
int 16h ;SB ; yes, read the null |
|||
Jump CON$RDND ; and get a real status |
|||
|
|||
NOTBRK: |
|||
cmp AX, 7200H ; check for ctrl-prtsc |
|||
jnz RDEXIT ; no |
|||
mov AL, 16 ; yes, indicate ctrl-prtsc |
|||
|
|||
PUBLIC RDEXIT |
|||
RDEXIT: |
|||
lds BX, [PTRSAV] ; get pointer to request header |
|||
ASSUME DS:NOTHING |
|||
mov [BX].MEDIA, AL ; move character into req. header |
|||
EXVEC: |
|||
Jump EXIT ; all done -- successful return |
|||
CONBUS: |
|||
ASSUME DS:NOTHING |
|||
Jump BUS$EXIT ; done -- con device is busy |
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Keyboard flush routine : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY PT |
|||
PUBLIC CON$FLSH |
|||
CON$FLSH: |
|||
call FLUSH |
|||
Jump Exit |
|||
|
|||
|
|||
PUBLIC FLUSH |
|||
FLUSH: |
|||
mov [ALTAH], 0 ; clear out holding buffer |
|||
|
|||
FlLoop: |
|||
;;Rev 3.30 Modification |
|||
; Is there a char there? |
|||
mov AH, 1 ; command code for check status |
|||
int 16h ; call rom-bios keyboard routine |
|||
; if z flag is set then no character |
|||
jz FlDone ; is ready, buffer is empty -- get out |
|||
xor AH, AH ; if zf is nof set, get character |
|||
int 16h ; call rom-bios to get character |
|||
jmp FlLoop ; repeat until buffer is empty |
|||
FlDone: |
|||
ret |
|||
;;Rev 3.30 Modification |
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Console Write Routine : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY PT |
|||
PUBLIC CON$WRIT |
|||
CON$WRIT: |
|||
jcxz EXVEC ; if CX is zero, get out |
|||
CON$LP: |
|||
mov AL,ES:[DI] ; get character |
|||
inc DI ; point to next character |
|||
int CHROUT ; Output character |
|||
loop CON$LP ; repeat until all through |
|||
Jump Exit |
|||
|
|||
|
|||
|
|||
;----------------------------------------------- |
|||
; |
|||
; BREAK KEY HANDLING |
|||
; |
|||
Public CBREAK |
|||
CBREAK: |
|||
mov CS:ALTAH, 3 ; indicate break key set |
|||
|
|||
|
|||
|
|||
Public INTRET |
|||
INTRET: |
|||
IRET |
|||
|
|||
CODE ENDS |
|||
END |
@ -0,0 +1,882 @@ |
|||
; |
|||
; After the boot sector reads in msbio it jumps to this location. Msbio |
|||
; immediately jumps to initialization code in msinit. |
|||
; |
|||
|
|||
EXTRN INIT:NEAR |
|||
|
|||
Public START$ |
|||
START$: |
|||
JMP INIT ; START$ patch by init to point to |
|||
; hdrive BPB |
|||
|
|||
|
|||
PATHSTART 001,BIO |
|||
|
|||
|
|||
;---------------------------------------------------------------------------- |
|||
; |
|||
; Command Jump Tables |
|||
; |
|||
; These tables hold the entry points for the various service routines |
|||
; for the different drivers. The index in the table is the command code for |
|||
; that funcion plus two. For example the command code for Read (input) is 4, |
|||
; The 6th (4 plus 2) entry in the table DSKTBL is DSK$READ - the command to |
|||
; read a disk. Commands which do not exist for a device are filled with |
|||
; exit (e.g. MediaCheck for CONTBL). The first entry in the table is the |
|||
; largest command code implemented for that device. This value is used |
|||
; for error checking. If new command codes are added then the first entry |
|||
; in the table must be incremented. |
|||
; |
|||
; BEWARE - These tables overlap somewhat! -c.p. |
|||
; |
|||
|
|||
; |
|||
; Disk: |
|||
; |
|||
|
|||
ODD |
|||
DSKTBL LABEL BYTE |
|||
DB 24 ; This is the size of the table YUK!!!! |
|||
DW DSK$INIT ; Code 0: INIT |
|||
DW MEDIA$CHK ; code 1: Media Check |
|||
DW GET$BPB ; code 2: BUILD BPB |
|||
DW CMDERR ; code 3: IOCTL input |
|||
DW DSK$READ ; code 4: INPUT |
|||
DW BUS$EXIT ; code 5: NONDESTRUCITVE INPUT, NO WAIT |
|||
DW EXIT ; code 6: INPUT STATUS |
|||
DW EXIT ; code 7: INPUT FLUSH |
|||
DW DSK$WRIT ; code 8: OUTPUT |
|||
DW DSK$WRITV ; code 9: OUTPUT with verify |
|||
DW EXIT ; code 10: OUTPUT STATUS |
|||
DW EXIT ; code 11: OUTPUT FLUSH |
|||
DW CMDERR ; code 12: IOCTL output |
|||
Public TABLE_PATCH |
|||
TABLE_PATCH LABEL WORD ;ARR 2.42 |
|||
DW DSK$OPEN ; code 13: DEVICE OPEN |
|||
DW DSK$CLOSE ; code 14: DEVICE CLOSE |
|||
DW DSK$REM ; code 15: REMOVABLE MEDIA |
|||
dw exit |
|||
dw exit |
|||
dw exit |
|||
DW GENERIC$IOCTL |
|||
dw exit |
|||
dw exit |
|||
dw exit |
|||
dw IOCTL$GETOWN |
|||
dw IOCTL$SETOWN |
|||
|
|||
; |
|||
; Console: |
|||
; |
|||
|
|||
ODD |
|||
CONTBL LABEL BYTE |
|||
DB 10 |
|||
DW EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW CMDERR |
|||
DW CON$READ |
|||
DW CON$RDND |
|||
DW EXIT |
|||
DW CON$FLSH |
|||
DW CON$WRIT |
|||
DW CON$WRIT |
|||
DW EXIT |
|||
|
|||
; |
|||
; Auxilary: |
|||
; |
|||
|
|||
ODD |
|||
AUXTBL LABEL BYTE |
|||
DB 10 |
|||
DW EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW CMDERR |
|||
DW AUX$READ |
|||
DW AUX$RDND |
|||
DW EXIT |
|||
DW AUX$FLSH |
|||
DW AUX$WRIT |
|||
DW AUX$WRIT |
|||
DW AUX$WRST |
|||
|
|||
; |
|||
; Clock: |
|||
; |
|||
|
|||
ODD |
|||
TIMTBL LABEL BYTE |
|||
DB 9 |
|||
DW EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW CMDERR |
|||
DW TIM$READ |
|||
DW BUS$EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW TIM$WRIT |
|||
DW TIM$WRIT |
|||
|
|||
; |
|||
; Printer: |
|||
; |
|||
|
|||
ODD |
|||
PRNTBL LABEL BYTE |
|||
DB 24 |
|||
DW EXIT ;INIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW CMDERR |
|||
DW EXIT$ZER ;INDICATE ZERO CHARS READ |
|||
DW BUS$EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW PRN$WRIT |
|||
DW PRN$WRIT |
|||
DW PRN$STAT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW EXIT |
|||
DW PRN$TilBusy |
|||
DW EXIT |
|||
DW EXIT |
|||
DW PRN$GenIOCTL |
|||
dw exit |
|||
dw exit |
|||
dw exit |
|||
dw CMDERR |
|||
dw CMDERR |
|||
|
|||
|
|||
EVENB |
|||
Public Old13 |
|||
OLD13 label DWORD |
|||
db '5986' ;Code for 3.30 |
|||
|
|||
|
|||
Public Orig13 |
|||
ORIG13 label DWORD |
|||
db '21',0,0 ;Code for 3.30 |
|||
|
|||
|
|||
; |
|||
; PTRSAV - pointer save |
|||
; |
|||
; This variable holds the pointer to the Request Header passed by a |
|||
; program wishing to use a device driver. When the strategy routine is |
|||
; called it puts the address of the Request header in this variable and |
|||
; returns. |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC PTRSAV |
|||
PTRSAV DD 0 |
|||
|
|||
|
|||
; |
|||
; Buffer for the AUX device driver |
|||
; |
|||
|
|||
;;Rev 3.30 Modification |
|||
PUBLIC AUXBUF |
|||
AUXBUF DB 0,0,0,0 ;SET OF 1 BYTE BUFFERS FOR COM 1,2,3, AND 4 |
|||
|
|||
|
|||
EVENB |
|||
PUBLIC PREVOPER,NUMBER_OF_SEC |
|||
;;End of Modification |
|||
PrevOper DW ? ; Holds ROM DISK INT request (i.e. Register AX). |
|||
Number_Of_Sec DB ? ; Holds number of sectors to read on an ECC error |
|||
|
|||
|
|||
;;Rev 3.30 Modification |
|||
IF ($-CODE) GT 100H |
|||
%OUT VDISK BUFFER NOT CORRECTLY LOCATED |
|||
ELSE |
|||
ORG 100H |
|||
ENDIF |
|||
PUBLIC VDISK_AREA |
|||
VDISK_AREA DB 108 DUP(0) ;FOR USE BY VDISK |
|||
;;End of Modification |
|||
|
|||
|
|||
; |
|||
; AUXNUM holds the number of the printer or AUX device requested. For |
|||
; example if printer 2 was called (PRN2$IN) AUXNUM is set to be one; with |
|||
; line printer 3 AUXNUM is set to 2. With this set the printer device driver |
|||
; can tell which printer to command applies to. |
|||
; |
|||
; WARNING!!! These are addressed together in GETDX |
|||
; |
|||
|
|||
EVENB |
|||
AUXNUM DB 0 |
|||
DB 0 |
|||
|
|||
|
|||
; |
|||
; Device Header for the CON Device Driver |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC CONHeader |
|||
CONHeader LABEL WORD |
|||
DD AUXDEV2 |
|||
DW 1000000000010011B ; Con in and con out + special |
|||
DW STRATEGY ; Strategy entry point |
|||
DW CON$IN ; interrupt entry point |
|||
DB 'CON ' ; device name |
|||
|
|||
|
|||
; |
|||
; Device Header for device "AUX" |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC AUXDEV2 |
|||
AUXDEV2 LABEL WORD ;HEADER FOR DEVICE "AUX" |
|||
DD PRNDEV2 |
|||
DW 1000000000000000B ; attribute word, character device |
|||
DW STRATEGY ; device strategy routine |
|||
DW AUX0$IN ; device interrupt routine |
|||
DB 'AUX ' ; device name |
|||
|
|||
|
|||
; |
|||
; Device Header for device PRN |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC PRNDEV2 |
|||
PRNDEV2 LABEL WORD ;HEADER FOR DEVICE "PRN" |
|||
DD TIMDEV |
|||
DW CharDev + OutTilBusy + Dev320 |
|||
DW STRATEGY |
|||
DW PRN0$IN |
|||
DB 'PRN ' |
|||
|
|||
|
|||
; |
|||
; Device Header for device CLOCK$ |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC TIMDEV |
|||
TIMDEV LABEL WORD |
|||
DD DSKDEV |
|||
DW 1000000000001000B |
|||
DW STRATEGY |
|||
DW TIM$IN |
|||
DB 'CLOCK$ ' |
|||
|
|||
|
|||
; |
|||
; Device Header for disk devices |
|||
; |
|||
; Device attribute bits: |
|||
; Bit 6 - DOS 3.2 Bit |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC DSKDEV |
|||
DSKDEV LABEL WORD |
|||
DD COM1DEV |
|||
DW 0000100001000000B ; DOS 3.2 |
|||
DW STRATEGY ; strategy routine |
|||
DW DSK$IN ; Interrupt entry point |
|||
|
|||
|
|||
; |
|||
; maximum number of drives |
|||
; |
|||
|
|||
DRVMAX DB 4 |
|||
Public DRVMAX |
|||
|
|||
|
|||
; |
|||
; Last drive accessed |
|||
; |
|||
|
|||
PUBLIC STEP_DRV |
|||
STEP_DRV DB -2 ; ARR 2.20 LAST DRIVE ACCESSED |
|||
|
|||
Public Phys_Drv |
|||
Phys_Drv DB 0 ; Used by setdrvie for getting |
|||
; BDS for logical drive, or physical |
|||
; drive. 0 => use logical |
|||
; 1 => use physical |
|||
|
|||
Public fHave96 |
|||
fHave96 DB 0 ; Flag to indicate presence of |
|||
; 96tpi support |
|||
|
|||
Public Single |
|||
Single DB 0 ; Used to detect single drive systems |
|||
|
|||
Public fHaveK09 |
|||
fHaveK09 DB 0 ;Indicates if this is a K09 or not |
|||
; used by console driver. |
|||
Public NEW_ROM |
|||
NEW_ROM DB 0 ;Set to 1 if we have a ROM that can |
|||
; handle strange media layouts. |
|||
|
|||
PUBLIC FSETOWNER |
|||
fSetOwner db ? ;=1 if we are setting the owner of a |
|||
;drive. (Examined by CheckSingle). |
|||
public Secrete_Code |
|||
Secrete_Code dw 'jk' ;Code for 3.30. |
|||
|
|||
|
|||
; |
|||
; Device Header for device "COM1" |
|||
; |
|||
|
|||
EVENB |
|||
Public COM1DEV |
|||
COM1DEV LABEL WORD |
|||
DD LPT1DEV |
|||
DW 1000000000000000B ; attribute word, character device |
|||
DW STRATEGY ; device strategy routine |
|||
DW AUX0$IN ; device interrupt routine |
|||
DB 'COM1 ' ; device name |
|||
|
|||
|
|||
; |
|||
; Device Header for device LPT1 |
|||
; |
|||
|
|||
EVENB |
|||
Public LPT1DEV |
|||
LPT1DEV LABEL WORD |
|||
DD LPT2DEV |
|||
DW CharDev + OutTilBusy + Dev320 |
|||
DW STRATEGY |
|||
DW PRN1$IN |
|||
DB 'LPT1 ' |
|||
|
|||
|
|||
; |
|||
; Device Header for device LPT2 |
|||
; |
|||
|
|||
EVENB |
|||
Public Lpt2Dev |
|||
LPT2DEV LABEL WORD |
|||
DD LPT3DEV |
|||
DW CharDev + OutTilBusy + Dev320 |
|||
DW STRATEGY |
|||
DW PRN2$IN |
|||
DB 'LPT2 ' |
|||
|
|||
; |
|||
; Device Header for device LPT3 |
|||
; |
|||
|
|||
EVENB |
|||
Public Lpt3Dev |
|||
LPT3DEV LABEL WORD |
|||
DD COM2DEV |
|||
DW CharDev + OutTilBusy + Dev320 |
|||
DW STRATEGY |
|||
DW PRN3$IN |
|||
DB 'LPT3 ' |
|||
|
|||
|
|||
; |
|||
; Device Header for device "COM2" |
|||
; |
|||
|
|||
EVENB |
|||
Public Com2Dev |
|||
COM2DEV LABEL WORD |
|||
dd COM3DEV |
|||
DW 1000000000000000B ; attribute word, character device |
|||
DW STRATEGY ; device strategy routine |
|||
DW AUX1$IN ; device interrupt routine |
|||
DB 'COM2 ' ; device name |
|||
|
|||
;;Rev 3.30 Modification |
|||
; |
|||
; Device header for device "COM3" |
|||
; |
|||
EVENB |
|||
PUBLIC COM3DEV |
|||
COM3DEV LABEL WORD |
|||
dd COM4DEV |
|||
dw 1000000000000000b ; character device attribute |
|||
dw STRATEGY |
|||
dw AUX2$IN ; com3 == aux2 |
|||
db 'COM3 ' |
|||
|
|||
; |
|||
; Device header for device "COM4" |
|||
; |
|||
EVENB |
|||
PUBLIC COM4DEV |
|||
COM4DEV LABEL WORD |
|||
dw -1,CODE |
|||
dw 1000000000000000b ; character device attribute |
|||
dw STRATEGY |
|||
dw AUX3$IN ; com4 == aux3 |
|||
db 'COM4 ' |
|||
|
|||
;;End of Modification |
|||
|
|||
|
|||
; Hard-wire the link to the next Int2f handler. |
|||
;;Rev 3.30 Modification |
|||
EVENB |
|||
PUBLIC Next2f_13 |
|||
NEXT2F_13 LABEL WORD |
|||
EXTRN INT2F_DISK:FAR ;MSBIO2 |
|||
DD INT2F_DISK |
|||
|
|||
|
|||
; |
|||
; Start of linked list of BDS's |
|||
; |
|||
|
|||
EVENB |
|||
Public Start_BDS |
|||
START_BDS LABEL WORD |
|||
DD BDS1 ;START OF BDS LINKED LIST. |
|||
;;End of Modification |
|||
|
|||
|
|||
; |
|||
; Some floppy drives do not have changeline support. The result is a |
|||
; large amount of inefficiency in the code. A media-check always returns |
|||
; "I don`t know". This cause DOS to reread the FAT on every access and |
|||
; always discard any cached data. |
|||
; We get around this inefficiency by implementing a "Logical Door Latch". |
|||
; The following three items are used to do this. The logical door latch is |
|||
; based on the premise that it is not physically possible to change floppy |
|||
; disks in a drive in under two seconds (most people take about 10). The |
|||
; logical door latch is implemented by saving the time of the last successful |
|||
; disk operation (in the value TIM_DRV). When a new request is made the |
|||
; current time is compared to the saved time. If less than two seconds have |
|||
; passed then the value "No Change" is returned. If more than two seconds |
|||
; have passed the value "Don't Know" is returned. |
|||
; There is one complecation to this algorithm. Some programs change the |
|||
; value of the timer. In this unfortunate case we have an invalid timer. |
|||
; This possiblity is detected by counting the number of disk operations |
|||
; which occur without any time passing. If this count exceeds the value of |
|||
; "AccessMax" we assume the counter is invalid and always return "Don't |
|||
; Know". The variable "AccessCount" is used to keep track of the number |
|||
; of disk operation which occur without the time changing. |
|||
; |
|||
|
|||
PUBLIC ACCESSCOUNT |
|||
AccessCount db 0 ; number of times media check called |
|||
|
|||
PUBLIC TIM_DRV |
|||
TIM_DRV DB -1 ; time when last disk I/O was performed |
|||
|
|||
PUBLIC FLAGBITS |
|||
FlagBits dw 0 ; Bits to set in flag field when doing |
|||
; a Set_Changed_DL |
|||
|
|||
PUBLIC MEDBYT |
|||
MedByt DB ? ; hold media byte from floppy |
|||
|
|||
EVENB |
|||
PUBLIC WRTVERIFY |
|||
WRTVERIFY LABEL WORD |
|||
|
|||
PUBLIC RFLAG |
|||
RFLAG DB ROMRead ;2 for read, 3 for write |
|||
VERIFY DB 0 ;1 if verify after write |
|||
|
|||
PUBLIC SECCNT |
|||
SECCNT DW 0 |
|||
|
|||
|
|||
Public HARDNUM |
|||
HARDNUM DB 99 ;logical drive number of first hardfile |
|||
|
|||
; |
|||
; Some of the older versions of the IBM rom-bios always assumed a seek would |
|||
; have to be made to read the diskette. Consequently a large head settle |
|||
; time was always used in the I/O operations. To get around this problem |
|||
; we need to continually adjust the head settle time. The following |
|||
; algorithm is used: |
|||
; |
|||
; Get the current head settle value. |
|||
; If it is 1, then |
|||
; set slow = 15 |
|||
; else |
|||
; set slow = value |
|||
; ... |
|||
; if we are seeking and writing then |
|||
; use slow |
|||
; else |
|||
; use fast |
|||
; ... |
|||
; restore current head settle value |
|||
; |
|||
|
|||
PUBLIC MOTORSTARTUP,SETTLECURRENT,SETTLESLOW |
|||
MotorStartup db ? ; value from table |
|||
SettleCurrent db ? ; value from table |
|||
SettleSlow db ? ; slow settle value |
|||
|
|||
NextSpeed DB ? ; value of speed to be used |
|||
|
|||
public save_head_sttl |
|||
Save_head_sttl db ? ;used by READ_SECTOR routine |
|||
|
|||
|
|||
Public EOT |
|||
EOT DB 9 |
|||
|
|||
; |
|||
; pointer to Disk Parameter Table |
|||
; |
|||
|
|||
EVENB |
|||
PUBLIC DPT |
|||
DPT DD ? |
|||
|
|||
; |
|||
; The following two sets of variables are used to hold values for |
|||
; disk I/O operations |
|||
; Keep the next two items contiguous - see IOCTL_Block for reason |
|||
|
|||
PUBLIC CURSEC,CURHD,CURTRK,SPSAV |
|||
CURSEC DB 0 ; current sector |
|||
CURHD DB 0 ; current head |
|||
CURTRK DW 0 ; current track |
|||
SPSAV DW 0 ; save the stack pointer |
|||
|
|||
; |
|||
; The following are used for IOCTL function calls |
|||
; |
|||
|
|||
PUBLIC FORMT_EOT,HDNUM,TRKNUM,GAP_PATCH |
|||
FORMT_EOT DB 8 ; EOT used for format |
|||
HDNUM DB 0 ; Head number |
|||
TRKNUM DW 0 ; Track being manipulated |
|||
GAP_PATCH DB 50h ; Format gap patched into DPT |
|||
|
|||
; |
|||
; Disk errors returned from the IBM rom |
|||
; |
|||
|
|||
Public ERRIN |
|||
ERRIN LABEL BYTE |
|||
DB 80H ; no response |
|||
DB 40H ; seek failure |
|||
DB 10H ; bad CRC |
|||
DB 8 ; DMA overrun |
|||
DB 6 ; media change |
|||
DB 4 ; sector not found |
|||
DB 3 ; write attempt to write-protect disk |
|||
PUBLIC LSTERR |
|||
LSTERR DB 0 ; all other errors |
|||
|
|||
; |
|||
; returned error code corresponding to above errors |
|||
; |
|||
|
|||
Public ERROUT |
|||
ERROUT LABEL BYTE |
|||
DB 2 ; no response |
|||
DB 6 ; seek failure |
|||
DB 4 ; bad CRC |
|||
DB 4 ; DMA overrun |
|||
DB 15 ; invalid media change |
|||
DB 8 ; sector not found |
|||
DB 0 ; write attempt on write-protect disk |
|||
DB 12 ; general error |
|||
|
|||
PUBLIC NUMERR |
|||
NUMERR = ERROUT-ERRIN |
|||
|
|||
|
|||
;------------------------------------------------------------- |
|||
; |
|||
; DiskSector is a 512 byte sector into which the boot sector |
|||
; is read. It is also used as read sector for DMA check for |
|||
; hard disk. |
|||
|
|||
|
|||
Public DiskSector |
|||
DiskSector db 11 dup(?) ; take care of 3 jump bytes plus OEM name. |
|||
PUBLIC BPB_IN_SECTOR |
|||
BPB_In_Sector dw ? |
|||
PUBLIC SECPERCLUSINSECTOR |
|||
SECPERCLUSINSECTOR DB ? |
|||
dw ? |
|||
db ? |
|||
dw ? |
|||
dw ? |
|||
PUBLIC MEDIABYTE |
|||
mediabyte db ? |
|||
dw ? |
|||
dw ? |
|||
dw ? |
|||
dw ? |
|||
db ? |
|||
db 512-($-DiskSector) dup (?) |
|||
|
|||
;--------------------------------------------------------------------- |
|||
; |
|||
; The "BDS"'s contain information for each drive in the system. |
|||
; There is one BDS for each logical drvie in the system. The BDS's |
|||
; are all linked together in a chain. The BDS contain various values |
|||
; important to the disk drive. Various values are updated whenever actions |
|||
; are performed. For example if a drive is read from the last time |
|||
; accessed fields are updated to the current time. |
|||
; Initial values: |
|||
; * Sectors/Alloc. unit in BPB initially set to -1 to signify that |
|||
; the BPB has not been filled. |
|||
; * Link is set to -1 to signify end of list. |
|||
; * number of cylinders in MaxParms initialized to -1 to indicate |
|||
; that the parameters have not been set. |
|||
; |
|||
; Start_BDS contains a pointer to the first BDS. It is through this |
|||
; pointer that routines find particular BDS (see SetDrive to see how |
|||
; this is done). |
|||
; |
|||
|
|||
EVENB |
|||
BDS1 LABEL WORD |
|||
DD BDS2 ;LINK TO NEXT STRUCTURE |
|||
DB 0 ;ROM DISK INT Drive Number |
|||
DB 0 ;Logical Drive Letter |
|||
PUBLIC FDRIVE1 |
|||
FDRIVE1 DW 512 ;Physical sector size in bytes |
|||
DB -1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 64 ;Number directory entries |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 00000000B ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 1 ;Head limit |
|||
DW 0 ;Hidden sector count |
|||
DB 0 ; TRUE => Large fats |
|||
OPCNT1 DW 0 ;Open Ref. Count |
|||
VOLID1 DB "NO NAME ",0 ;Volume ID for this disk |
|||
DB 3 ;Form Factor |
|||
FLAGS1 DW 0020H ;Various Flags |
|||
; DB 9 dup (0) ;Reserved for future use |
|||
dw 40 ; number of cylinders |
|||
RecBPB1 DW 512 ;Physical sector size in bytes |
|||
DB 1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 0E0H ;NUMBER DIRECTORY ENTRIES |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 0F0h ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 2 ;HEAD LIMIT |
|||
DW 0 ;Hidden sector count |
|||
DB 12 DUP (?) |
|||
TRACK1 DB -1 ;Last track accessed on this drive |
|||
TIM_LO1 DW -1 ;Keep these two contiguous (?) |
|||
TIM_HI1 DW -1 |
|||
|
|||
EVENB |
|||
BDS2 LABEL WORD |
|||
DD BDS3 ;LINK TO NEXT STRUCTURE |
|||
DB 0 ;INT 13 DRIVE NUMBER |
|||
DB 0 ;Logical Drive Letter |
|||
PUBLIC FDRIVE2 |
|||
FDRIVE2 DW 512 ;Physical sector size in bytes |
|||
DB -1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 64 ;Number directory entries |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 00000000B ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 1 ;Head limit |
|||
DW 0 ;Hidden sector count |
|||
DB 0 ; TRUE => Large fats |
|||
OPCNT2 DW 0 ;Open Ref. Count |
|||
VOLID2 DB "NO NAME ",0 ;Volume ID for this disk |
|||
DB 3 ;Form Factor |
|||
FLAGS2 DW 0020H ;Various Flags |
|||
; DB 9 dup (0) ;Reserved for future use |
|||
dw 40 ; number of cylinders |
|||
RecBPB2 DW 512 ;Physical sector size in bytes |
|||
DB 1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 0E0H ;NUMBER DIRECTORY ENTRIES |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 0F0h ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 2 ;HEAD LIMIT |
|||
DW 0 ;Hidden sector count |
|||
DB 12 DUP (?) |
|||
TRACK2 DB -1 ;Last track accessed on this drive |
|||
TIM_LO2 DW -1 ;Keep these two contiguous (?) |
|||
TIM_HI2 DW -1 |
|||
|
|||
EVENB |
|||
BDS3 LABEL WORD |
|||
DD BDS4 ;LINK TO NEXT STRUCTURE |
|||
DB 0 ;INT 13 DRIVE NUMBER |
|||
DB 0 ;Logical Drive Letter |
|||
PUBLIC FDRIVE3 |
|||
FDRIVE3 DW 512 ;Physical sector size in bytes |
|||
DB -1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 64 ;Number directory entries |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 00000000B ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 1 ;Head limit |
|||
DW 0 ;Hidden sector count |
|||
DB 0 ; TRUE => Large fats |
|||
OPCNT3 DW 0 ;Open Ref. Count |
|||
VOLID3 DB "NO NAME ",0 ;Volume ID for this disk |
|||
DB 3 ;Form Factor |
|||
FLAGS3 DW 0020H ;Various Flags |
|||
; DB 9 dup (0) ;Reserved for future use |
|||
dw 40 ; number of cylinders |
|||
RecBPB3 DW 512 ;Physical sector size in bytes |
|||
DB 1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 0E0H ;NUMBER DIRECTORY ENTRIES |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 0F0h ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 2 ;HEAD LIMIT |
|||
DW 0 ;Hidden sector count |
|||
DB 12 DUP (?) |
|||
TRACK3 DB -1 ;Last track accessed on this drive |
|||
TIM_LO3 DW -1 ;Keep these two contiguous (?) |
|||
TIM_HI3 DW -1 |
|||
|
|||
EVENB |
|||
BDS4 LABEL WORD |
|||
DW -1 ;Link to next structure |
|||
DW Code |
|||
DB 0 ;INT 13 DRIVE NUMBER |
|||
DB 0 ;Logical Drive Letter |
|||
PUBLIC FDRIVE4 |
|||
FDRIVE4 DW 512 ;Physical sector size in bytes |
|||
DB -1 ;Sectors/allocation unit |
|||
DW 1 ;Reserved sectors for DOS |
|||
DB 2 ;No. allocation tables |
|||
DW 64 ;Number directory entries |
|||
DW 9*40 ;Number sectors (at 512 bytes ea.) |
|||
DB 00000000B ;Media descriptor, initially 00H. |
|||
DW 2 ;Number of FAT sectors |
|||
DW 9 ;Sector limit |
|||
DW 1 ;Head limit |
|||
DW 0 ;Hidden sector count |
|||
DB 0 ; TRUE => Large fats |
|||
OPCNT4 DW 0 ;Open Ref. Count |
|||
VOLID4 DB "NO NAME ",0 ;Volume ID for this disk |
|||
DB 3 ;Form Factor |
|||
FLAGS4 DW 0020H ;Various Flags |
|||
; DB 9 dup (0) ;Reserved for future use |
|||
dw 40 ; number of cylinders |
|||
;;Rev 3.30 Modification |
|||
RECBPB4 DW 512 ;BYTES PER SECTOR |
|||
DB 1 ;SECTORS/ALLOCATION UNIT |
|||
DW 1 ;RESERVED SECTORS FOR DOS |
|||
DB 2 ;NO. ALLOCATION TABLES |
|||
DW 0E0H ;NUMBER DIRECTORY ENTRIES |
|||
DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.) |
|||
DB 0F0H ;MEDIA DESCRIPTOR, INITIALLY F0H. |
|||
DW 2 ;NUMBER OF FAT SECTORS |
|||
DW 9 ;SECTOR LIMIT |
|||
DW 2 ;HEAD LIMIT |
|||
DW 0 ;HIDDEN SECTOR COUNT |
|||
DB 12 DUP (?) |
|||
;;End of Modification |
|||
TRACK4 DB -1 ;Last track accessed on this drive |
|||
TIM_LO4 DW -1 ;Keep these two contiguous (?) |
|||
TIM_HI4 DW -1 |
|||
|
|||
|
|||
bpbType struc |
|||
spf db ? |
|||
spt db ? |
|||
cdire db ? |
|||
csec dw ? |
|||
spa db ? |
|||
chead db ? |
|||
bpbType ends |
|||
PUBLIC SM92 |
|||
sm92 bpbType <3,9,70H,2*9*80,2,2> |
|||
|
|||
|
|||
; |
|||
; ALTAH is a single character buffer used to handle special keys. |
|||
; |
|||
|
|||
PUBLIC ALTAH |
|||
ALTAH DB 0 ;Special key handling |
|||
|
|||
|
|||
; |
|||
; The following variable can be modified via IOCTL sub-function 16. In this |
|||
; way, the wait can be set to suit the speed of the particular printer being |
|||
; used. One for each printer device. |
|||
; |
|||
|
|||
PUBLIC PRINTDEV |
|||
PRINTDEV DB 0 ; Index into following array |
|||
|
|||
EVENB |
|||
PUBLIC WAIT_COUNT |
|||
WAIT_COUNT DW 4 dup (50h) ; Array of Retry counts for printer |
|||
|
|||
|
|||
; |
|||
; DAYCNT is the number of days since 1-1-80. |
|||
; Each time the clock is read it is necessary to check if another day has |
|||
; passed. The ROM only returns the day rollover once so if it is missed |
|||
; the time will be off by a day. |
|||
; |
|||
|
|||
EVENB |
|||
Public DAYCNT |
|||
DAYCNT DW 0 |
|||
|
|||
|
|||
; |
|||
; The following variables and two routines (MSGOUT and MSGNUM) are used |
|||
; with the debug routines to print numbers and messages on the screen. |
|||
; |
|||
; The variable fTestBits controls the level of debugging in the system. |
|||
; See the comments and "equ's" in msmacro.inc for an explination of |
|||
; how to control the level of debugging. In a nutshell, setting |
|||
; fTestBits to fTestALL prints all the debugging messages. Setting |
|||
; it to fTestDisk prints all disk related messages, etc. |
|||
; |
|||
|
|||
if test |
|||
Public NumBuf |
|||
NumBuf DB 5 dup (?) |
|||
Public Digits |
|||
Digits DB "0123456789ABCDEF" |
|||
Public fTestBits |
|||
FTESTBITS DW fTestDISK |
|||
endif |
|||
|
|||
|
|||
PATHEND 001,BIO |
2408
SRC/BIOS/MSDISK.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,65 @@ |
|||
|
|||
; file: msequ.asm contains various equ's used in the bio. The values |
|||
; are explained below. |
|||
; |
|||
|
|||
;IBMCOPYRIGHT EQU 0 |
|||
fTOOBIG EQU 80h |
|||
fBIG EQU 40h |
|||
ROMStatus EQU 1 |
|||
ROMRead EQU 2 |
|||
ROMWrite EQU 3 |
|||
ROMVerify EQU 4 |
|||
ROMFormat EQU 5 |
|||
vid_size EQU 12 |
|||
|
|||
include msbds.inc ; various equates for bds |
|||
include version.inc |
|||
|
|||
|
|||
IF IBMCOPYRIGHT |
|||
SYSIZE=200H ;NUMBER OF PARAGRAPHS IN SYSINIT MODULE ;;Rev 3.30 Modification |
|||
ELSE |
|||
SYSIZE=203H |
|||
ENDIF |
|||
RSINIT=0A3H ; RS-232 initialization ;;End of Modification |
|||
LF=10 ; line feed |
|||
CR=13 ; carriage return |
|||
BACKSP=8 ; backspace |
|||
BRKADR=1BH * 4 ; 006C 1BH break vector address |
|||
TIMADR=1CH * 4 ; 0070 1CH timer interrupt |
|||
DSKADR=1EH * 4 ; address of ptr to disk parameters |
|||
SEC9=522H ; address of disk parameters |
|||
HEADSETTLE=SEC9+9 ; address of head settle time |
|||
NORMSETTLE=15 ; Normal head settle |
|||
SPEEDSETTLE=0 ; Speed up settle time |
|||
INITSPOT=534H ; IBM wants 4 zeros here |
|||
AKPORT=20H |
|||
EOI=20H |
|||
CMDLEN = 0 ; length of this command |
|||
UNIT = 1 ; sub unit specifier |
|||
CMD = 2 ; command code |
|||
STATUS = 3 ; status |
|||
MEDIA = 13 ; media descriptor |
|||
TRANS = 14 ; transfer address |
|||
COUNT = 18 ; count of blocks or characters |
|||
START = 20 ; first block to transfer |
|||
EXTRA = 22 ; usually a pointer to Vol Id for error 15 |
|||
CHROUT = 29H |
|||
MAXERR = 5 |
|||
LSTDRV = 504H |
|||
|
|||
; location of boot sector on startup |
|||
BootBias = 200h |
|||
|
|||
NotBusyStatus = 10000000B ; not busy |
|||
AckStatus = 01000000B ; acknowledge (for what?) |
|||
NoPaperStatus = 00100000B ; No more paper |
|||
SelectedStatus = 00010000B ; The printer said it was selected |
|||
IOErrStatus = 00001000B ; Some kinda error |
|||
RESERVED = 00000110B ; NOPs |
|||
TimeOutStatus = 00000001B ; time out. |
|||
|
|||
PATHGEN = 1 |
|||
|
|||
|
@ -0,0 +1,72 @@ |
|||
|
|||
; |
|||
; file: msextrn.asm |
|||
; |
|||
; This file list the external variable used in the bio. |
|||
; |
|||
|
|||
EXTRN ORIG13:DWORD,ORIG19:DWORD |
|||
EXTRN COM2DEV:WORD,COM1DEV:WORD |
|||
EXTRN COM4DEV:WORD,COM3DEV:WORD ;3.30 |
|||
EXTRN LPT3DEV:WORD,LPT2DEV:WORD,LPT1DEV:WORD |
|||
EXTRN HARDDRV:BYTE,HARDNUM:BYTE,DRVMAX:BYTE,HDSKTAB:WORD |
|||
EXTRN DSKDRVS:WORD,HNUM:BYTE,EOT:BYTE,FHAVE96:BYTE |
|||
EXTRN REAL13:DWORD,DAYCNT:WORD,CONHeader:WORD |
|||
EXTRN TWOHARD:BYTE,INT_2F_NEXT:DWORD |
|||
EXTRN BDSH:WORD,BDSX:WORD,START_BDS:DWORD |
|||
EXTRN FHAVEK09:BYTE, NEW_ROM:BYTE |
|||
EXTRN Single:BYTE |
|||
EXTRN BDSMs:BYTE ;for Mini Disk 4/7/86 ;3.30 |
|||
EXTRN HaveCMOSClock:byte ;set by MSINIT. Used by MSCLOCK.AS;3.30 M |
|||
EXTRN BinToBCD:word ;set by MSINIT. Used by MSCLOCK.AS;3.30 M |
|||
EXTRN DaycntToDay:word ;set by MSINIT. Used by MSCLOCK.AS;3.30 M |
|||
|
|||
if test |
|||
IFNDEF NUMBUF ;3.30 |
|||
EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD |
|||
ENDIF ;3.30 |
|||
endif |
|||
|
|||
EXTRN START$:NEAR,ERROUT:NEAR,BLOCK13:FAR,INT19:FAR |
|||
EXTRN INTRET:NEAR,HDRIVE:NEAR,DRIVEX:NEAR,INT13:FAR,CBREAK:NEAR,OUTCHR:NEAR |
|||
EXTRN DISKRD:NEAR,MEDIA_PATCH:NEAR,GETBP1_PATCH:NEAR |
|||
EXTRN SET_PATCH:NEAR,DISKIO_PATCH:NEAR,DSKERR:NEAR,INIT_PATCH:NEAR |
|||
EXTRN TABLE_PATCH:NEAR,EXIT:NEAR,CHANGED_PATCH:NEAR |
|||
EXTRN ERRIN:NEAR,GETBP:NEAR,SWPDSK:NEAR ;3.30 |
|||
EXTRN OUTCHR:NEAR,WRMSG:NEAR,time_to_ticks:near |
|||
EXTRN INT2F_DISK:NEAR,INSTALL_BDS:NEAR,SETDRIVE:NEAR |
|||
|
|||
if test |
|||
IFNDEF NUMBUF ;3.30 |
|||
EXTRN MSGNUM:NEAR,MSGOUT:NEAR,dumpbytes:near,hex_to_ascii:near ;3.30 |
|||
EXTRN outchar:near ;3.30 |
|||
ENDIF ;3.30 |
|||
endif |
|||
|
|||
SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' |
|||
ASSUME CS:SYSINITSEG |
|||
|
|||
EXTRN CURRENT_DOS_LOCATION:WORD |
|||
EXTRN FINAL_DOS_LOCATION:WORD |
|||
EXTRN DEVICE_LIST:DWORD |
|||
EXTRN MEMORY_SIZE:WORD |
|||
EXTRN DEFAULT_DRIVE:BYTE |
|||
EXTRN BUFFERS:WORD |
|||
EXTRN SYSINIT:FAR |
|||
SYSINITSEG ENDS |
|||
|
|||
ASSUME CS:CODE ;3.30 |
|||
|
|||
; |
|||
; End of disk modules for configuration |
|||
; |
|||
EXTRN End96tpi:byte |
|||
EXTRN EndTwoHard:byte |
|||
EXTRN EndOneHard:byte |
|||
EXTRN EndSwap:byte |
|||
EXTRN EndFloppy:byte |
|||
; |
|||
; IBM fixed up AT ROM |
|||
; |
|||
EXTRN IBM_DISK_IO:FAR |
|||
|
@ -0,0 +1,46 @@ |
|||
EVBOUND = 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30 |
|||
; ALIGNS TO EVEN ;3.30 |
|||
; : : : : : : : : : : : : : : ;3.30 |
|||
IF EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30 |
|||
; : : : : : : : : : : : : : : ;3.30 |
|||
EVENB MACRO ;3.30 |
|||
EVEN ;;ADJUST TO EVEN BOUNDARY ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
ODD MACRO ;3.30 |
|||
;;GENERATE BOUNDARY PADDING TO FORCE ODD OFFSET ;3.30 |
|||
IF (($-CODE) MOD 2) EQ 0 ;3.30 |
|||
DB ? ;3.30 |
|||
ENDIF ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
CODE_SEGMENT MACRO ;3.30 |
|||
;;ALLIGN THE SEGMENT ON WORD BOUNDARY TO ALLOW FOR EVEN ALLIGNMENT OF DATA;3.30 |
|||
CODE SEGMENT WORD PUBLIC 'CODE' ;3.30 ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
; : : : : : : : : : : : : : : ;3.30 |
|||
ELSE ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT |
|||
; : : : : : : : : : : : : : : ;3.30 |
|||
;3.30 |
|||
EVENB MACRO ;3.30 |
|||
;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
ODD MACRO ;3.30 |
|||
;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
CODE_SEGMENT MACRO ;3.30 |
|||
;;SEGMENT IS ALLIGNED ON BYTE BOUNDARY FOR MINIMUM SIZE OF GENERATION ;3.30 |
|||
CODE SEGMENT BYTE PUBLIC 'CODE' ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
; : : : : : : : : : : : : : : ;3.30 |
|||
ENDIF ;3.30 |
|||
; : : : : : : : : : : : : : : ;3.30 |
|||
;3.30 |
|||
CODE_SEGMENT ;3.30 |
|||
ASSUME CS:CODE ;3.30 |
|||
;3.30 |
|||
|
@ -0,0 +1,418 @@ |
|||
;*** |
|||
; Title: Disk |
|||
; By: Michael Hanson |
|||
; C: Copyright (C) 1985-1987 by Microsoft corp. |
|||
; Date: 1/11/85 |
|||
; |
|||
; There is a bug in some versions of IBM's AT ROM BIOS |
|||
; interupts are not disabled during read operations. |
|||
; |
|||
; Use: This program should be chained in line with the disk |
|||
; interupt 13h, it intercepts read calls to the hard disk |
|||
; and handles them appropriately. For other functions it |
|||
; passes controll to OLD13, which should contain the |
|||
; address of the AT ROM disk routine. The entry point for |
|||
; this program is IBM_DISK_IO. |
|||
; |
|||
|
|||
|
|||
.286c ;Use 80286 non-protected mode |
|||
|
|||
BIOSEG = 040h ;Segment for ROM BIOS Data |
|||
ROMSEG = 0F000h ;Segment of ROM |
|||
|
|||
|
|||
BAD_DISK = 01 |
|||
|
|||
HF_PORT = 01F0h |
|||
HF_REG_PORT = 03F6h |
|||
|
|||
;* Offsets into Fixed disk parameter table |
|||
FDP_PRECOMP = 5 |
|||
FDP_CONTROL = 8 |
|||
|
|||
DATA SEGMENT AT BIOSEG ;ROM BIOS data segment |
|||
|
|||
ORG 42h |
|||
CMD_BLOCK DB 6 DUP (?) |
|||
|
|||
;* Offsets into CMD_BLOCK for registers |
|||
PRE_COMP = 0 ;Write Pre-compensation |
|||
SEC_CNT = 1 ;Sector count |
|||
SEC_NUM = 2 ;Sector number |
|||
CYL_LOW = 3 ;Cylinder number, low part |
|||
CYL_HIGH = 4 ;Cylinder number, high part |
|||
DRV_HEAD = 5 ;Drive/Head (Bit 7 = ECC mode, Bit 5 = 512 byte sectors, |
|||
; Bit 4 = drive number, Bits 3-0 have head number) |
|||
CMD_REG = 6 ;Command register |
|||
|
|||
|
|||
ORG 074h |
|||
|
|||
DISK_STATUS1 DB ? |
|||
HF_NUM DB ? |
|||
CONTROL_BYTE DB ? |
|||
|
|||
DATA ENDS |
|||
|
|||
|
|||
|
|||
;*** Define where the ROM routines are actually located |
|||
ROM SEGMENT AT ROMSEG |
|||
|
|||
ORG 02E1Eh |
|||
ROMCOMMAND PROC FAR |
|||
ROMCOMMAND ENDP |
|||
|
|||
ORG 02E7Fh |
|||
ROMWAIT PROC FAR |
|||
ROMWAIT ENDP |
|||
|
|||
ORG 02EE2h |
|||
ROMWAIT_DRQ PROC FAR |
|||
ROMWAIT_DRQ ENDP |
|||
|
|||
ORG 02EF8h |
|||
ROMCHECK_STATUS PROC FAR |
|||
ROMCHECK_STATUS ENDP |
|||
|
|||
ORG 02F69h |
|||
ROMCHECK_DMA PROC FAR |
|||
ROMCHECK_DMA ENDP |
|||
|
|||
ORG 02F8Eh |
|||
ROMGET_VEC PROC FAR |
|||
ROMGET_VEC ENDP |
|||
|
|||
ORG 0FF65h |
|||
ROMFRET PROC FAR ;Far return at F000:FF65 in AT ROM. |
|||
ROMFRET ENDP |
|||
|
|||
ROM ENDS |
|||
|
|||
|
|||
CODE SEGMENT BYTE PUBLIC 'code' |
|||
|
|||
EXTRN OLD13:DWORD ;Link to AT bios int 13h |
|||
|
|||
PUBLIC IBM_DISK_IO |
|||
|
|||
|
|||
ASSUME CS:CODE |
|||
ASSUME DS:DATA |
|||
|
|||
|
|||
;*** IBM_DISK_IO - main routine, fixes AT ROM bug |
|||
; |
|||
; ENTRY: (AH) = function, 02 or 0A for read. |
|||
; (DL) = drive number (80h or 81h). |
|||
; (DH) = head number. |
|||
; (CH) = cylinder number. |
|||
; (CL) = Sector number (high 2 bits has cylinder number). |
|||
; (AL) = number of sectors. |
|||
; (ES:BX) = address of read buffer. |
|||
; For more on register contents see ROM BIOS listing. |
|||
; Stack set up for return by an IRET. |
|||
; |
|||
; EXIT: (AH) = status of current operation. |
|||
; (CY) = 1 IF failed, 0 if successful. |
|||
; For other register contents see ROM BIOS listing. |
|||
; |
|||
; USES: |
|||
; |
|||
; |
|||
; WARNING: Uses OLD13 vector for non-read calls. |
|||
; Does direct calls to the AT ROM. |
|||
; Does segment arithmatic. |
|||
; |
|||
; EFFECTS: Performs DISK I/O operation. |
|||
; |
|||
IBM_DISK_IO PROC FAR |
|||
CMP DL, 80h |
|||
JB ATD1 ;Pass through floppy disk calls. |
|||
CMP AH, 02 |
|||
JE ATD2 ;Intercept call 02 (read sectors). |
|||
CMP AH, 0Ah |
|||
JE ATD2 ;and call 0Ah (read long). |
|||
ATD1: |
|||
JMP OLD13 ;Use ROM INT 13h handler. |
|||
ATD2: |
|||
PUSH BX |
|||
PUSH CX |
|||
PUSH DX |
|||
PUSH DI |
|||
PUSH DS |
|||
PUSH ES |
|||
PUSH AX |
|||
MOV AX,BIOSEG ;Establish BIOS segment addressing. |
|||
MOV DS,AX |
|||
MOV DISK_STATUS1, 0 ;Initially no error code. |
|||
AND DL, 07fh ;Mask to hard disk number |
|||
CMP DL, HF_NUM |
|||
JB ATD3 ;Disk number in range |
|||
MOV DISK_STATUS1, BAD_DISK |
|||
JMP SHORT ATD4 ;Disk number out of range error, return |
|||
|
|||
ATD3: |
|||
PUSH BX |
|||
MOV AX, ES ;Make ES:BX to Seg:000x form. |
|||
SHR BX, 4 |
|||
ADD AX, BX |
|||
MOV ES, AX |
|||
POP BX |
|||
AND BX,000Fh |
|||
PUSH CS |
|||
CALL CHECK_DMA |
|||
JC ATD4 ;Abort if DMA across segment boundary |
|||
|
|||
POP AX ;Restore AX register for SETCMD |
|||
PUSH AX |
|||
CALL SETCMD ;Set up command block for disk op |
|||
MOV DX, HF_REG_PORT |
|||
OUT DX, AL ;Write out command modifier |
|||
CALL DOCMD ;Carry out command |
|||
ATD4: |
|||
POP AX |
|||
MOV AH,DISK_STATUS1 ;On return AH has error code |
|||
STC |
|||
OR AH,AH |
|||
JNZ ATD5 ;Carry set if error |
|||
CLC |
|||
ATD5: |
|||
POP ES |
|||
POP DS |
|||
POP DI |
|||
POP DX |
|||
POP CX |
|||
POP BX |
|||
RET 2 ;Far return, dropping flags |
|||
IBM_DISK_IO ENDP |
|||
|
|||
|
|||
|
|||
;*** SETCMD - Set up CMD_BLOCK for the disk operation |
|||
; |
|||
; ENTRY: (DS) = BIOS Data segment. |
|||
; (ES:BX) in seg:000x form. |
|||
; Other registers as in INT 13h call |
|||
; |
|||
; EXIT: CMD_BLOCK set up for disk read call. |
|||
; CONTROL_BYTE set up for disk operation. |
|||
; (AL) = Control byte modifier |
|||
; |
|||
; |
|||
; Sets the fields of CMD_BLOCK using the register contents |
|||
; and the contents of the disk parameter block for the given drive. |
|||
; |
|||
; WARNING: (AX) destroyed. |
|||
; Does direct calls to the AT ROM. |
|||
; |
|||
SETCMD PROC NEAR |
|||
MOV CMD_BLOCK[SEC_CNT], AL |
|||
MOV CMD_BLOCK[CMD_REG], 020h ;Assume function 02 |
|||
CMP AH, 2 |
|||
JE SETC1 ;CMD_REG = 20h if function 02 (read) |
|||
MOV CMD_BLOCK[CMD_REG], 022h ;CMD_REG = 22h if function 0A (" long) |
|||
SETC1: ;No longer need value in AX |
|||
MOV AL, CL |
|||
AND AL, 03fh ;Mask to sector number |
|||
MOV CMD_BLOCK[SEC_NUM], AL |
|||
MOV CMD_BLOCK[CYL_LOW], CH |
|||
MOV AL, CL |
|||
SHR AL, 6 ;Get two high bits of cylender number |
|||
MOV CMD_BLOCK[CYL_HIGH], AL |
|||
MOV AX, DX |
|||
SHL AL, 4 ;Drive number |
|||
AND AH, 0Fh |
|||
OR AL, AH ;Head number |
|||
OR AL, 0A0h ;Set ECC and 512 bytes per sector |
|||
MOV CMD_BLOCK[DRV_HEAD], AL |
|||
PUSH ES ;GET_VEC destroys ES:BX |
|||
PUSH BX |
|||
PUSH CS |
|||
CALL GET_VEC |
|||
MOV AX, ES:FDP_PRECOMP[BX] ;Write pre-comp from disk parameters |
|||
SHR AX, 2 |
|||
MOV CMD_BLOCK[PRE_COMP],AL ;Only use low part |
|||
MOV AL, ES:FDP_CONTROL[BX] ;Control byte modifier |
|||
POP BX |
|||
POP ES |
|||
MOV AH, CONTROL_BYTE |
|||
AND AH, 0C0h ;Keep disable retry bits |
|||
OR AH, AL |
|||
MOV CONTROL_BYTE, AH |
|||
RET |
|||
SETCMD ENDP |
|||
|
|||
|
|||
|
|||
;*** DOCMD - Carry out READ operation to AT hard disk |
|||
; |
|||
; ENTRY: (ES:BX) = address for read in data. |
|||
; CMD_BLOCK set up for disk read. |
|||
; |
|||
; EXIT: Buffer at (ES:BX) contains data read. |
|||
; DISK_STATUS1 set to error code (0 if success). |
|||
; |
|||
; |
|||
; |
|||
; WARNING: (AX), (BL), (CX), (DX), (DI) destroyed. |
|||
; No check is made for DMA boundary overrun. |
|||
; |
|||
; EFFECTS: Programs disk controller. |
|||
; Performs disk input. |
|||
; |
|||
DOCMD PROC NEAR |
|||
MOV DI, BX ;(ES:DI) = data buffer addr. |
|||
PUSH CS |
|||
CALL COMMAND |
|||
JNZ DOC3 |
|||
DOC1: |
|||
PUSH CS |
|||
CALL WAIT ;Wait for controller to complete read |
|||
JNZ DOC3 |
|||
MOV CX, 100h ;256 words per sector |
|||
MOV DX, HF_PORT |
|||
CLD ;String op goes up |
|||
CLI ;Disable interrupts (BUG WAS FORGETTING THIS) |
|||
REPZ INSW ;Read in sector |
|||
STI |
|||
TEST CMD_BLOCK[CMD_REG], 02 |
|||
JZ DOC2 ;No ECC bytes to read. |
|||
PUSH CS |
|||
CALL WAIT_DRQ |
|||
JC DOC3 |
|||
MOV CX, 4 ;4 bytes of ECC |
|||
MOV DX, HF_PORT |
|||
CLI |
|||
REPZ INSB ;Read in ECC |
|||
STI |
|||
DOC2: |
|||
PUSH CS |
|||
CALL CHECK_STATUS |
|||
JNZ DOC3 ;Operation failed |
|||
DEC CMD_BLOCK[SEC_CNT] |
|||
JNZ DOC1 ;Loop while more sectors to read |
|||
DOC3: |
|||
RET |
|||
DOCMD ENDP |
|||
|
|||
|
|||
|
|||
;*** GET_VEC - Get pointer to hard disk parameters. |
|||
; |
|||
; ENTRY: (DL) = Low bit has hard disk number (0 or 1). |
|||
; |
|||
; EXIT: (ES:BX) = address of disk parameters table. |
|||
; |
|||
; USES: AX for segment computation. |
|||
; |
|||
; Loads ES:BX from interrupt table in low memory, vector 46h (disk 0) |
|||
; or 70h (disk 1). |
|||
; |
|||
; WARNING: (AX) destroyed. |
|||
; This does a direct call to the AT ROM. |
|||
; |
|||
GET_VEC PROC NEAR |
|||
PUSH OFFSET ROMFRET |
|||
JMP ROMGET_VEC |
|||
GET_VEC ENDP |
|||
|
|||
|
|||
|
|||
;*** COMMAND - Send contents of CMD_BLOCK to disk controller. |
|||
; |
|||
; ENTRY: Control_byte |
|||
; CMD_BLOCK - set up with values for hard disk controller. |
|||
; |
|||
; EXIT: DISK_STATUS1 = Error code. |
|||
; NZ if error, ZR for no error. |
|||
; |
|||
; |
|||
; WARNING: (AX), (CX), (DX) destroyed. |
|||
; Does a direct call to the AT ROM. |
|||
; |
|||
; EFFECTS: Programs disk controller. |
|||
; |
|||
COMMAND PROC NEAR |
|||
PUSH OFFSET ROMFRET |
|||
JMP ROMCOMMAND |
|||
COMMAND ENDP |
|||
|
|||
|
|||
|
|||
;*** WAIT - Wait for disk interrupt |
|||
; |
|||
; ENTRY: Nothing. |
|||
; |
|||
; EXIT: DISK_STATUS1 = Error code. |
|||
; NZ if error, ZR if no error. |
|||
; |
|||
; |
|||
; WARNING: (AX), (BL), (CX) destroyed. |
|||
; Does a direct call to the AT ROM. |
|||
; |
|||
; EFFECTS: Calls int 15h, function 9000h. |
|||
; |
|||
WAIT PROC NEAR |
|||
PUSH OFFSET ROMFRET |
|||
JMP ROMWAIT |
|||
WAIT ENDP |
|||
|
|||
|
|||
|
|||
;*** WAIT_DRQ - Wait for data request. |
|||
; |
|||
; ENTRY: Nothing. |
|||
; |
|||
; EXIT: DISK_STATUS1 = Error code. |
|||
; CY if error, NC if no error. |
|||
; |
|||
; |
|||
; WARNING: (AL), (CX), (DX) destroyed. |
|||
; Does a direct call to the AT ROM. |
|||
; |
|||
WAIT_DRQ PROC NEAR |
|||
PUSH OFFSET ROMFRET |
|||
JMP ROMWAIT_DRQ |
|||
WAIT_DRQ ENDP |
|||
|
|||
|
|||
|
|||
;*** CHECK_STATUS - Check hard disk status. |
|||
; |
|||
; ENTRY: Nothing. |
|||
; |
|||
; EXIT: DISK_STATUS1 = Error code. |
|||
; NZ if error, ZR if no error. |
|||
; |
|||
; |
|||
; WARNING: (AX), (CX), (DX) destroyed. |
|||
; Does a direct call to the AT ROM. |
|||
; |
|||
CHECK_STATUS PROC NEAR |
|||
PUSH OFFSET ROMFRET |
|||
JMP ROMCHECK_STATUS |
|||
CHECK_STATUS ENDP |
|||
|
|||
|
|||
|
|||
;*** CHECK_DMA - check for DMA overrun 64k segment. |
|||
; |
|||
; ENTRY: (ES:BX) = addr. of memory buffer in seg:000x form. |
|||
; CMD_BLOCK set up for operation. |
|||
; |
|||
; EXIT: DISK_STATUS1 - Error code. |
|||
; CY if error, NC if no error. |
|||
; |
|||
; |
|||
; WARNING: Does a direct call to the AT ROM. |
|||
; |
|||
CHECK_DMA PROC NEAR |
|||
PUSH OFFSET ROMFRET |
|||
JMP ROMCHECK_DMA |
|||
CHECK_DMA ENDP |
|||
|
|||
|
|||
CODE ENDS |
|||
END |
2213
SRC/BIOS/MSINIT.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1036
SRC/BIOS/MSIOCTL.INC
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,767 @@ |
|||
title Non-Contiguous BIOS Loader (MSLOAD) |
|||
|
|||
IF1 |
|||
%OUT ASSEMBLING: Non-Contiguous BIOS Loader (MSLOAD) |
|||
%OUT |
|||
ENDIF |
|||
|
|||
bootseg segment at 0h |
|||
org 7C00h |
|||
Boot_Sector label byte |
|||
org 7D00h |
|||
Relocate_Start label byte |
|||
bootseg ends |
|||
|
|||
|
|||
dosseg segment at 70h |
|||
org 00h |
|||
BIOS_Address label byte |
|||
|
|||
dosseg ends |
|||
|
|||
|
|||
cseg segment public para 'code' |
|||
assume cs:cseg,ds:cseg,es:cseg,ss:cseg |
|||
|
|||
|
|||
|
|||
include msload.inc |
|||
|
|||
org 0h |
|||
|
|||
start: |
|||
|
|||
subttl Setup Stack |
|||
page |
|||
;*********************************************************************** |
|||
; Setup_Stack |
|||
;*********************************************************************** |
|||
; |
|||
; Input: none |
|||
; |
|||
; Output: |
|||
; |
|||
; SS:SP = 0:7C00h |
|||
; AX destroyed |
|||
;----------------------------------------------------------------------- |
|||
; First thing is to reset the stack to a better and more known place. |
|||
; |
|||
; Move the stack to just under the boot record and relocation area (0:7C00h) |
|||
; |
|||
; Preserve all other registers |
|||
;---------------------------------------------------------------------- |
|||
|
|||
CLI ;Stop interrupts till stack ok |
|||
XOR AX,AX |
|||
MOV SS,AX ;Work in stack just below this routine |
|||
MOV SP,7C00h - 30 ;Leave room for stack frame |
|||
MOV BP,7C00h - 30 ;Point BP as stack index pointer |
|||
STI |
|||
|
|||
|
|||
subttl Save Input Values |
|||
page |
|||
;*********************************************************************** |
|||
; Save_Input_Values |
|||
;*********************************************************************** |
|||
; |
|||
; Input: none |
|||
; |
|||
; DL = INT 13 drive number we booted from |
|||
; CH = media byte |
|||
; BX = First data sector on disk (0-based) |
|||
; |
|||
; Output: |
|||
; |
|||
; BX = first data sector on disk |
|||
; CL = number of floppies including fake one |
|||
; CH = media byte |
|||
; |
|||
; [bp].Media_Byte = input CH |
|||
; [bp].Drive_Number = input DL |
|||
; [bp].First_Sector = input BX |
|||
; [bp].Drive_Boot = output AX |
|||
; [bp].Number_Floppy = output CL |
|||
; [bp].Number_Sectors = Sectors/track |
|||
; [bp].Number_Heads = heads/cylinder |
|||
; |
|||
; DS = 0 |
|||
; AX,DX,SI destroyed |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; Save input information |
|||
; |
|||
; Get Equipment Flag |
|||
; |
|||
; Find how many drives on system |
|||
; |
|||
; Figure out boot drive |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
Save_Input_Values: |
|||
mov [bp].First_Sector,bx |
|||
mov [bp].media_Byte,ch |
|||
mov [bp].Drive_Number,dl |
|||
; INT 11h ;GET EQUIPMENT STATUS |
|||
; ROL AL,1 ;Put bits 6 & 7 into bits 0 & 1 |
|||
; ROL AL,1 |
|||
; AND AX,3 ;Only look at bits 0 & 1 |
|||
; JNZ NOTsingle ;Zero means single drive system |
|||
; INC AX ;Pretend it's a two drive system |
|||
NOTSingle: |
|||
; INC AX ;AX has number of drives, 2-4 |
|||
;Is also 0 indexed boot drive if we |
|||
; booted off hard file |
|||
; MOV CL,AL ;CH is FAT ID, CL # floppies |
|||
; TEST DL,80H ;BOOT FROM FLOPPY ? |
|||
; JNZ GOTHRD ;NO. |
|||
; XOR AX,AX ;INDICATE BOOT FROM DRIVE A |
|||
GotHrd: |
|||
xor ax,ax ;Segment 0 |
|||
mov ds,ax |
|||
|
|||
assume ds:Bootseg |
|||
|
|||
mov ax,Boot_Sector.SECLIM ;Get Sectors per track |
|||
mov [bp].Sectors_Per_Track,ax |
|||
mov ax,Boot_Sector.HDLIM ;Get BPB heads per cylinder |
|||
mov [bp].Number_Of_Heads,ax |
|||
mov ax,Boot_Sector.cSecFat ;Get sectors per FAT |
|||
mov [bp].Number_Of_FAT_Sectors,ax |
|||
mov ax,Boot_Sector.cSecHid ;Get hidden sectors |
|||
mov [bp].Hidden_Sectors,ax |
|||
mov ax,Boot_Sector.cSecRes ;Get Reserved Sectors |
|||
mov [bp].Reserved_Sectors,ax |
|||
|
|||
|
|||
subttl Find_Cluster_Size |
|||
page |
|||
;*********************************************************************** |
|||
; Find_Cluster_Size |
|||
;*********************************************************************** |
|||
; |
|||
; Input: BPB information in loaded boot record at 0:7C00h |
|||
; |
|||
; Output: |
|||
; |
|||
; DS = 0 |
|||
; AX = Bytes/Cluster |
|||
; BX = Sectors/Cluster |
|||
; SI destroyed |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; |
|||
; Get Bytes/sector from BPB |
|||
; |
|||
; Get sectors/cluster from BPB |
|||
; |
|||
; Bytes/cluster = Bytes/sector * sector/cluster |
|||
;---------------------------------------------------------------------- |
|||
Find_Cluster_Size: |
|||
|
|||
;For the time being just assume the boot record is valid and the BPB |
|||
;is there. |
|||
|
|||
xor ax,ax ;Segment 0 |
|||
mov ds,ax |
|||
|
|||
assume ds:bootseg |
|||
|
|||
mov ax,Boot_Sector.ByteSec ;Get BPB bytes/sector |
|||
xor bx,bx |
|||
mov bl,Boot_Sector.cAlloc ;Get sectors/cluster |
|||
mul bx ;Bytes/cluster |
|||
mov [bp].Size_Cluster,ax ;Save it |
|||
|
|||
|
|||
|
|||
subttl Determine FAT size |
|||
page |
|||
;*********************************************************************** |
|||
; Determine_FAT_Size |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Determine if FAT is 12 or 16 bit FAT. 12 bit FAT if floppy, read MBR |
|||
; to find out what system id byte is. |
|||
; |
|||
; Input: [bp].Media_Byte = FAT ID Byte |
|||
; |
|||
; Output: |
|||
; |
|||
; [BP].Fat_Size = FAT12_bit or FAT16_bit |
|||
; ES = 0 |
|||
; All other registers destroyed |
|||
; |
|||
; Calls: READ_DISK |
|||
;----------------------------------------------------------------------- |
|||
;IF (not FAT ID of F8) |
|||
; {12 bit FAT} |
|||
;ELSE |
|||
; { |
|||
; Read in master boot record at 0:7C00h |
|||
; |
|||
; Scan system id bytes for 1 or 4 |
|||
; |
|||
; IF (Sys id = 4) |
|||
; {16 bit FAT} |
|||
; ELSE |
|||
; {IF (Sys id = 1) |
|||
; {12 bit FAT} |
|||
; ELSE |
|||
; {Error} |
|||
; ENDIF |
|||
; ENDIF |
|||
; ENDIF |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
Determine_FAT_Size: |
|||
mov [bp].FAT_Size,FAT12_bit ;Assume 12 bit fat |
|||
cmp [bp].Media_Byte,0F8h ;Is it floppy |
|||
jne FAT_Size_Found ;Yep, all set |
|||
mov [bp].Logical_Sector,0 ;Got hardfile, go get MBR |
|||
xor ax,ax |
|||
mov es,ax |
|||
mov di,offset Relocate_Start |
|||
mov [bp].Sector_Count,1 |
|||
call Disk_Read |
|||
mov si,offset Relocate_Start+1C2h |
|||
mov cx,4 |
|||
xor ax,ax |
|||
mov ds,ax |
|||
Find_Sys_Id: |
|||
mov [bp].FAT_Size,FAT12_bit ;Assume 12 bit fat |
|||
cmp byte ptr [si],1 |
|||
je FAT_Size_Found |
|||
mov [bp].FAT_Size,FAT16_bit ;Assume 12 bit fat |
|||
cmp byte ptr [si],4 |
|||
je Fat_Size_Found |
|||
add si,16 |
|||
loop Find_Sys_Id |
|||
;xxxxxxxxxxxxxxxxxxxxxxxxxx error |
|||
FAT_Size_Found: |
|||
|
|||
|
|||
subttl Determine First Cluster |
|||
page |
|||
;*********************************************************************** |
|||
; Determine_First_Cluster |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: Find the last cluster that was loaded |
|||
; |
|||
; |
|||
; Input: |
|||
; |
|||
; [BP].Size_Cluster |
|||
; Total_Length is offset of end of MSLOAD |
|||
; |
|||
; Output: |
|||
; |
|||
; [BP].Last_Found_Cluster = the last cluster loaded containing MSLOAD |
|||
; code. This is also the number of clusters |
|||
; with MSLOAD code +2 |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; |
|||
;Get length of loader portion of bios |
|||
; |
|||
;Divide by bytes/cluster |
|||
; |
|||
;If (Remainder = 0) |
|||
; {Last_Used_Cluster = quotient+2} |
|||
;Else |
|||
; {Last_Used_Cluster = quotient+3} |
|||
;---------------------------------------------------------------------- |
|||
Determine_First_Cluster: |
|||
mov [bp].Last_Found_Cluster,1 ;2 is the first cluster-1 |
|||
mov ax,offset Total_Length ;Get whole length |
|||
xor dx,dx |
|||
div [bp].Size_Cluster ;Div by bytes/sector |
|||
add [bp].Last_Found_Cluster,ax ;Save the result |
|||
cmp dx,0 ;Was there remainder? |
|||
je First_Cluster_Found ;No |
|||
inc [bp].Last_Found_Cluster ;Yes, round up |
|||
|
|||
First_Cluster_Found: |
|||
|
|||
|
|||
subttl Relocate |
|||
page |
|||
; |
|||
;*********************************************************************** |
|||
; RELOCATE |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Relocate the loader code to 0:7C00 - this will allow bios to be loaded |
|||
; underneath at 70:0 |
|||
; |
|||
; Input: none |
|||
; |
|||
; Output: es is set to 0 |
|||
; ds is set to cs (70h) |
|||
; ax,cx,si,di destroyed |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; Copy code from Relocate_Code to Relocate_Start (7C00h) |
|||
; |
|||
; The length to copy is Relocate_Length |
|||
; |
|||
; Jump to relocated code |
|||
;----------------------------------------------------------------------- |
|||
; |
|||
Relocate: |
|||
push cs ;Set up ds segreg |
|||
pop ds |
|||
xor ax,ax ;Set up ES segreg |
|||
mov es,ax |
|||
|
|||
assume es:bootseg,ds:cseg |
|||
|
|||
mov si,offset Relocate_Code ;Source |
|||
mov di,offset Relocate_Start ;Target |
|||
mov cx,Relocate_Length ;Length |
|||
rep movsb ;Go do it |
|||
|
|||
jmp far ptr Relocate_Start |
|||
|
|||
; |
|||
;************************************************************************* |
|||
;* RELOCATED CODE ******************************************************** |
|||
;************************************************************************* |
|||
; |
|||
|
|||
Relocate_Code label byte |
|||
|
|||
subttl Read In FAT |
|||
page |
|||
;*********************************************************************** |
|||
; Read_In_FAT |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Reads in the entire FAT at 0:8000. This gives the relocated portion |
|||
; of this loader a maximum size of 1024 bytes (8000 - 7C00). The max |
|||
; size of the FAT is 64 sectors (32k) so everything will fit under the |
|||
; 64k DMA boundary, so no problems with loading. |
|||
; |
|||
; Input: none |
|||
; |
|||
; Output: |
|||
; |
|||
; ES = 0 |
|||
; All sectors destroyed |
|||
; |
|||
; Calls: READ DISK |
|||
;----------------------------------------------------------------------- |
|||
; Get number of sectors in FAT |
|||
; |
|||
; Set ES:DI to 0:8000h |
|||
; |
|||
; Read in the sectors |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
Read_In_FAT: |
|||
xor ax,ax |
|||
mov ds,ax |
|||
|
|||
assume ds:bootseg |
|||
|
|||
mov ax,[bp].Number_Of_FAT_Sectors ;Get sectors/FAT |
|||
mov [bp].Sector_Count,ax ;Number of sectors to read |
|||
mov ax,[bp].Hidden_Sectors ;Hidden+Reserved = Fat |
|||
add ax,[bp].Reserved_Sectors |
|||
mov [bp].Logical_Sector,ax ;Save it, setup for read |
|||
xor ax,ax |
|||
mov es,ax |
|||
mov di,8000h ;Point to buffer |
|||
call Disk_Read |
|||
|
|||
subttl Keep Loaded BIO |
|||
page |
|||
;*********************************************************************** |
|||
; KEEP LOADED BIO |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Determine how much of bios was loaded in when the loader was loaded |
|||
; by the boot record (only the portion that is guaranteed to be |
|||
; contiguous |
|||
; |
|||
; Input: |
|||
; |
|||
; [BP].Last_Found_Cluster = number of clusters used for loader+2 |
|||
; |
|||
; Output: |
|||
; ES = DS = 70h |
|||
; DI = Next offset to load bios code |
|||
; AX,BX,CX,DX,SI destroyed |
|||
; |
|||
; [bp].Next_BIO_Location = DI on output |
|||
; [bp].Last_Cluster = last cluster loaded |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
;Number of clusters loaded+2 is in [BP].Last_Found_Cluster |
|||
; |
|||
;Multiply cluster * cluster size in bytes to get total loaded for MSLOAD |
|||
; |
|||
;Subtract TOTAL_LOADED - LOADBIO_SIZE to get loaded bios in last cluster |
|||
; |
|||
;Relocate this piece of bios down to 70:0 |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
Keep_Loaded_BIO: |
|||
push ds |
|||
mov ax,[bp].Last_Found_Cluster ;Point to last cluster loaded |
|||
sub ax,1 ;Get number of clusters loaded |
|||
mul [bp].Size_Cluster ;Get total bytes loaded by |
|||
;This is always < 64k, so |
|||
;lower 16 bits ok |
|||
sub ax,LoadBio_Size ;Get portion of bios loaded |
|||
mov cx,ax ;Save length to move |
|||
mov ax,70h ;Segment at 70h |
|||
mov ds,ax |
|||
mov es,ax |
|||
mov si,offset cs:Total_Length ;Point at bios |
|||
mov di,0 ;Point at 70:0 |
|||
rep movsb ;Relocate this code |
|||
mov [bp].Next_Bio_Location,di ;Save where to load next |
|||
pop ds |
|||
|
|||
subttl Get Contiguous Clusters |
|||
page |
|||
;*********************************************************************** |
|||
; Get_Contiguous_Clusters |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: Go find clusters as long as they are contiguous |
|||
; |
|||
; |
|||
; Input: |
|||
; |
|||
; [BP].Next_BIO_Location |
|||
; [BP]. |
|||
; |
|||
; |
|||
; Output: |
|||
; |
|||
; |
|||
; Calls: Get_Next_FAT_Entry |
|||
;----------------------------------------------------------------------- |
|||
; |
|||
;Set [BP].Sector_Count to Sectors per cluster |
|||
; |
|||
;Call Get_Next_FAT_Entry to get next cluster in file |
|||
; |
|||
;Call Check_for_EOF |
|||
; |
|||
;IF (NC returned) |
|||
; |
|||
; {Call Get_Next_FAT_Entry |
|||
; |
|||
; IF (New cluster is contig to old cluster) |
|||
; {Add sectors per cluster to [BP].Sector_Count |
|||
; |
|||
; Call Check_For_EOF |
|||
; |
|||
; IF (NC returned) |
|||
; |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
Get_Contiguous_Cluster: |
|||
xor ah,ah |
|||
mov al,Boot_Sector.cAlloc ;Assume we will get one cluster |
|||
mov [bp].Sector_Count,ax |
|||
call Get_Next_Fat_Entry ;Go get it |
|||
mov [bp].Last_Found_Cluster,ax ;Update the last one found |
|||
cmp [bp].EOF,End_Of_File |
|||
je GOTO_bios |
|||
|
|||
Got_Contig_Clusters: |
|||
sub ax,2 ;Zero base the cluster |
|||
xor ch,ch |
|||
mov cl,Boot_Sector.cAlloc ;Get sectors per cluster |
|||
mul cx ;Get how many |
|||
add ax,[bp].First_Sector ;See where the data sector starts |
|||
mov [bp].Logical_Sector,ax ;Save it |
|||
mov di,[bp].Next_Bio_Location ;Get where to put code |
|||
push [bp].Sector_Count ;Save how many sectors |
|||
mov ax,dosseg ;Get area to load code |
|||
mov es,ax |
|||
call Disk_Read |
|||
pop ax ;Get back total sectors read in |
|||
; jc ########## |
|||
mul Boot_Sector.ByteSec ;Get number of bytes we loaded |
|||
add [bp].Next_Bio_Location,ax ;Point to where to load next |
|||
jmp short Get_Contiguous_Cluster |
|||
|
|||
subttl GOTO bios |
|||
page |
|||
;*********************************************************************** |
|||
; GOTO_bios |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Set up required registers for bios, then jump to it (70:0) |
|||
; |
|||
; Input: none |
|||
; |
|||
; [bp].Media_Byte = media byte |
|||
; [bp].Drive_Number = INT 13 drive number we booted from |
|||
; [bp].First_Sector = First data sector on disk (0-based) |
|||
; |
|||
; Output: |
|||
; |
|||
; Required by MSINIT |
|||
; DL = INT 13 drive number we booted from |
|||
; CH = media byte |
|||
; BX = First data sector on disk (0-based) |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; |
|||
; Set up registers for MSINIT then do Far Jmp |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
GOTO_bios: |
|||
mov ch,[bp].Media_Byte ;Restore regs required for MSINT |
|||
mov dl,[bp].Drive_Number |
|||
mov bx,[bp].First_Sector |
|||
jmp far ptr bios_Address |
|||
|
|||
|
|||
|
|||
|
|||
subttl Disk Read |
|||
page |
|||
;*********************************************************************** |
|||
; Disk_Read |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Read in the [BP].Sector_Count number of sectors at ES:DI |
|||
; |
|||
; |
|||
; Input: none |
|||
; |
|||
; DI = Offset of start of read |
|||
; ES = Segment of read |
|||
; [bp].Sector_Count = number of sectors to read |
|||
; [bp].Logical_sector = starting sector |
|||
; Following is BPB info that must be setup prior to call |
|||
; [bp].Number_Of_Heads |
|||
; [bp].Number_Of_Sectors |
|||
; [bp].Drive_Number |
|||
; [bp].Sectors_Per_Track |
|||
; |
|||
; Output: |
|||
; |
|||
; ES = 0 |
|||
; AX,BX,CX,DX,SI,DI destroyed |
|||
; |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; Divide start sector by sectors per track |
|||
; The remainder is the actual sector number, 0 based |
|||
; |
|||
; Increment actual sector number to get 1 based |
|||
; |
|||
; The quotient is the number of tracks - divide by heads to get the cyl |
|||
; |
|||
; The remainder is actual head, the quotient is cylinder |
|||
; |
|||
; Figure the number of sectors in that track, set AL to this |
|||
; |
|||
; Do the read |
|||
; |
|||
; If Error, Do RESET, then redo the INT 13h |
|||
; |
|||
; If successful read, Subtract # sectors read from Sector_Count, Add to |
|||
; Logical Sector, add #sectors read * Sector_Size to BX; |
|||
; |
|||
; If Sector_Count <> 0 Do next read |
|||
;---------------------------------------------------------------------- |
|||
Disk_Read: |
|||
|
|||
; |
|||
; convert a logical sector into Track/sector/head. AX has the logical |
|||
; sector number |
|||
; |
|||
DODIV: |
|||
MOV cx,5 ;5 retries |
|||
|
|||
Try_Read: |
|||
PUSH cx ;Save it |
|||
|
|||
MOV AX,[bp].Logical_Sector ;Get starting sector |
|||
XOR DX,DX |
|||
DIV word ptr [bp].Sectors_Per_Track |
|||
MOV bx,[bp].Sectors_Per_Track ;Get number of sectors we can |
|||
sub bx,dx ;read in this track |
|||
mov si,bx |
|||
cmp [bp].Sector_Count,si ;Is possible sectors in track more |
|||
jae Got_Length ;than what we need to read? |
|||
mov si,[bp].Sector_Count ;Yes, only read what we need to |
|||
|
|||
Got_Length: |
|||
INC DL ; sector numbers are 1-based |
|||
MOV bl,dl ;Start sector in DL |
|||
XOR DX,DX |
|||
DIV word ptr [bp].Number_Of_Heads ;Start cyl in ax,head in DL |
|||
MOV DH,DL |
|||
; |
|||
; Issue one read request. ES:BX have the transfer address, AL is the number |
|||
; of sectors. |
|||
; |
|||
; |
|||
; Now convert to standard ROM call |
|||
; |
|||
mov cl,bl ;Get starting sector |
|||
ror ah,1 ;Set up high 2 bits |
|||
ror ah,1 ;Set up high 2 bits |
|||
or cl,ah ;Combine cyl/start sector |
|||
mov ch,al ;Set low order of cyl |
|||
mov bx,di ;Set offset |
|||
mov dl,[bp].Drive_Number ;Set drive |
|||
mov ax,si ;Set count |
|||
mov ah,02 ;Read Command |
|||
push ax ;Save regs |
|||
push di ; * |
|||
int 13h ;Call ROM-Bios |
|||
pop di ;Restore Regs |
|||
pop ax ; * |
|||
pop cx ;Get retry count back |
|||
jnc Read_OK |
|||
push cx |
|||
mov bx,di ; |
|||
push di ;Save Reg |
|||
mov dl,[bp].Drive_Number ;Set drive |
|||
mov ah,0 ;RESET Disk Command |
|||
int 13h ;Call ROM-Bios |
|||
pop di ;Restore Reg |
|||
pop cx |
|||
loop Try_Read |
|||
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx error |
|||
Read_OK: |
|||
xor ah,ah ;Mask out command, just get # read |
|||
sub [bp].Sector_Count,ax ;Bump number down |
|||
jz Read_Finished |
|||
add [bp].Logical_Sector,ax ;Where to start next time |
|||
xor bx,bx ;Get number sectors read |
|||
mov bl,al |
|||
mov ax,Boot_Sector.ByteSec ;Bytes per sector |
|||
mul bx ;Get total bytes read |
|||
add di,ax ;Add it to offset |
|||
jmp short DODIV |
|||
Read_Finished: |
|||
RET |
|||
|
|||
subttl GET NEXT FAT ENTRY |
|||
page |
|||
;*********************************************************************** |
|||
; GET_NEXT_FAT_ENTRY |
|||
;*********************************************************************** |
|||
; |
|||
; Notes: |
|||
; |
|||
; Given the last cluster found, this will return the next cluster of |
|||
; bios. If the last cluster is (F)FF8 - (F)FFF, then the final cluster |
|||
; of bios has been loaded, and control is passed to GOTO_bios |
|||
; |
|||
; Input: |
|||
; |
|||
; [bp].Last_Found_Cluster |
|||
; [bp].Fat_Size |
|||
; |
|||
; Output: |
|||
; |
|||
; [bp].Last_Found_Cluster (updated) |
|||
; |
|||
; Calls: none |
|||
;----------------------------------------------------------------------- |
|||
; Get Last_Found_Cluster |
|||
; |
|||
; IF (16 bit FAT) |
|||
; {IF (Last_Found_Cluster = FFF8 - FFFF) |
|||
; {JMP GOTO_bios} |
|||
; ELSE |
|||
; {Get offset by multiply cluster by 2} |
|||
; |
|||
; ELSE |
|||
; {IF (Last_Found_Cluster = FF8 - FFF) |
|||
; {JMP GOTO_bios} |
|||
; ELSE |
|||
; {Get offset by - multiply cluster by 3 |
|||
; |
|||
; Rotate right to divide by 2 |
|||
; |
|||
; IF (CY set - means odd number) |
|||
; {SHR 4 times to keep high twelve bits} |
|||
; |
|||
; ELSE |
|||
; {AND with 0FFFh to keep low 12 bits} |
|||
; } |
|||
; } |
|||
; |
|||
; Add in 8000h to get offset of next cluster in FAT buffer |
|||
; |
|||
;---------------------------------------------------------------------- |
|||
Get_Next_FAT_Entry: |
|||
|
|||
mov [bp].EOF,End_Of_File ;Assume last cluster |
|||
mov ax,[bp].Last_Found_Cluster ;Get last cluster |
|||
cmp [bp].Fat_Size,FAT12_bit |
|||
jne Got_16_Bit |
|||
xor bx,bx |
|||
mov bl,3 ;Mult by 3 |
|||
mul bx |
|||
shr ax,1 ;Div by 2 to get 1.5 |
|||
mov si,ax ;Get the final buffer offset |
|||
mov ax,[si]+8000h ;Get new cluster |
|||
test [bp].Last_Found_Cluster,1 ;Was last cluster odd? |
|||
jnz Odd_Result ;If Carry set it was odd |
|||
and ax,0FFFh ;Keep low 12 bits |
|||
jmp short Test_EOF |
|||
|
|||
Odd_Result: |
|||
mov cl,4 ;Keep high 12 bits for odd |
|||
shr ax,cl |
|||
Test_EOF: |
|||
cmp ax,0FF8h ;Is it last cluster? |
|||
jae Got_Cluster_Done ;Yep, all done here |
|||
jmp short Not_Last_CLuster |
|||
|
|||
Got_16_Bit: |
|||
shl ax,1 ;Multiply cluster by 2 |
|||
mov si,ax ;Get the final buffer offset |
|||
mov ax,[si]+8000h ;Get new cluster |
|||
cmp ax,0FFF8h |
|||
jae Got_Cluster_Done |
|||
|
|||
Not_Last_Cluster: |
|||
mov [bp].EOF,not End_Of_File ;Assume last cluster |
|||
|
|||
Got_Cluster_Done: |
|||
ret |
|||
|
|||
|
|||
|
|||
|
|||
Relocate_Length equ $ - Read_In_FAT |
|||
Total_Length label byte |
|||
LoadBIO_Size equ $ - Start |
|||
|
|||
cseg ends |
|||
end start |
@ -0,0 +1,52 @@ |
|||
;3.30 |
|||
Stack_Frame STRUC ;3.30 |
|||
Number_Of_Heads dw 0 ;3.30 |
|||
Size_Cluster dw 0 ;3.30 |
|||
Logical_Sector dw 0 ;3.30 |
|||
Sector_Count dw 0 ;3.30 |
|||
Number_Of_FAT_Sectors dw 0 ;3.30 |
|||
Hidden_Sectors dw 0 ;3.30 |
|||
Sector_Size dw 0 ;3.30 |
|||
Reserved_Sectors dw 0 ;3.30 |
|||
Last_Found_Cluster dw 0 ;3.30 |
|||
Next_BIO_Location dw 0 ;3.30 |
|||
First_Sector dw 0 ;3.30 |
|||
Sectors_Per_Track dw 0 ;3.30 |
|||
Drive_Number db 0 ;3.30 |
|||
FAT_Size db 0 ;3.30 |
|||
Media_Byte db 0 ;3.30 |
|||
EOF db 0 ;3.30 |
|||
;3.30 |
|||
Stack_Frame ENDS ;3.30 |
|||
;3.30 |
|||
;3.30 |
|||
BPB STRUC ;3.30 |
|||
JUMP DB 0 ;3.30 |
|||
DB 0 ;3.30 |
|||
DB 0 ;3.30 |
|||
OEM DB "IBM " ;3.30 |
|||
DB "3.3" ;3.30 |
|||
ByteSec DW 512 ; SIZE OF A PHYSICAL SECTOR ;3.30 |
|||
cAlloc DB 8 ; SECTORS PER ALLOCATION UNIT ;3.30 |
|||
cSecRes DW 1 ; NUMBER OF RESERVED SECTORS ;3.30 |
|||
cFat DB 2 ; NUMBER OF FATS ;3.30 |
|||
DirNum DW 512 ; NUMBER OF DIREC ENTRIES ;3.30 |
|||
NumSec DW 4*17*305-1 ; NUMBER OF SECTORS - NUMBER OF HI;3.30 DDEN SECTORS |
|||
MEDIA DB 0F8H ; MEDIA BYTE ;3.30 |
|||
cSecFat DW 8 ; NUMBER OF FAT SECTORS ;3.30 |
|||
SECLIM DW 17 ; SECTORS PER TRACK ;3.30 |
|||
HDLIM DW 4 ; NUMBER OF SURFACES ;3.30 |
|||
cSecHid DW 1 ; NUMBER OF HIDDEN SECTORS ;3.30 |
|||
hSecHid dw 0 ; high order word of Hidden Sector;3.30 s |
|||
BNumSec dd 0 ; 32 bit version of NUMBER OF SECT;3.30 ORS |
|||
; (when 16 bit version is zero) ;3.30 |
|||
Other db 6 dup(?) ; reserved for later expansion ;3.30 |
|||
BPB ENDS ;3.30 |
|||
;3.30 |
|||
;3.30 |
|||
;3.30 |
|||
End_Of_File equ 0FFh ;3.30 |
|||
FAT12_Bit equ 01h ;3.30 |
|||
FAT16_Bit equ 04h ;3.30 |
|||
;3.30 |
|||
|
@ -0,0 +1,274 @@ |
|||
TITLE MSLPT - DOS 3.3 ;3.30 |
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; P R N - PRINTER DEVICE : |
|||
; : |
|||
; : |
|||
; This file contains the Printer Device Driver. The : |
|||
; printer driver handles calls to the printers. Four devices : |
|||
; use this code: PRN, LPT1, LPT2, and LPT3. The beginning : |
|||
; of the interrupt entry point for these device sets the : |
|||
; variable AUXNUM in the msbio.asm module. The number is : |
|||
; in AUXNUM dictates which device will to written to: 0 for : |
|||
; PRN and LPT1, 1 for LPT2, and 2 for LPT3. : |
|||
; : |
|||
; The routines in this files are: : |
|||
; : |
|||
; routine function : |
|||
; ------- -------- : |
|||
; PRN$WRIT Write to printer device : |
|||
; PRN$STAT Printer status routine : |
|||
; PRN$TilBusy Print spooler routine : |
|||
; Prn$GenIOCTL Generic IOCTL routine : |
|||
; : |
|||
; These routines are not called directly. Call are made via : |
|||
; the strategy and interrupt entry point (see Device Header). : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
|
|||
test=0 ;3.30 |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT ;3.30 |
|||
INCLUDE MSEQU.INC ;3.30 |
|||
INCLUDE MSMACRO.INC ;3.30 |
|||
INCLUDE DEVSYM.INC ;3.30 |
|||
INCLUDE IOCTL.INC ;3.30 |
|||
;3.30 |
|||
EXTRN BUS$EXIT:NEAR ;MSBIO1 ;3.30 |
|||
EXTRN ERR$CNT:NEAR ;MSBIO1 ;3.30 |
|||
EXTRN CMDERR:NEAR ;MSBIO1 ;3.30 |
|||
EXTRN GETDX:NEAR ;MSBIO1 ;3.30 |
|||
EXTRN EXIT:NEAR ;MSBIO1 ;3.30 |
|||
EXTRN ERR$EXIT:NEAR ;MSBIO1 ;3.30 |
|||
;DATA ;3.30 |
|||
EXTRN PTRSAV:DWORD ;MSBIO1 ;3.30 |
|||
EXTRN TIMDEV:WORD ;MSCLOCK ;3.30 |
|||
EXTRN LPT2DEV:WORD ;MSBIO2 ;3.30 |
|||
EXTRN WAIT_COUNT:WORD ;MSDATA ;3.30 |
|||
EXTRN PRINTDEV:BYTE ;MSDATA ;3.30 |
|||
;3.30 |
|||
|
|||
|
|||
; IBM ROM STATUS BITS (I DON'T TRUST THEM, NEITHER SHOULD YOU) ;3.30 |
|||
;3.30 |
|||
NOTBUSYSTATUS = 10000000B ; NOT BUSY ;3.30 |
|||
ACKSTATUS = 01000000B ; ACKNOWLEDGE (FOR WHAT?) ;3.30 |
|||
NOPAPERSTATUS = 00100000B ; NO MORE PAPER ;3.30 |
|||
SELECTEDSTATUS = 00010000B ; THE PRINTER SAID IT WAS SELECTED;3.30 |
|||
IOERRSTATUS = 00001000B ; SOME KINDA ERROR ;3.30 |
|||
RESERVED = 00000110B ; NOPS ;3.30 |
|||
TIMEOUTSTATUS = 00000001B ; TIME OUT. ;3.30 |
|||
;3.30 |
|||
;3.30 |
|||
; WARNING!!! THE IBM ROM DOES NOT RETURN JUST ONE BIT. IT RETURNS A ;3.30 |
|||
; WHOLE SLEW OF BITS, ONLY ONE OF WHICH IS CORRECT. ;3.30 |
|||
;3.30 |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; WRITE TO PRINTER DEVICE : |
|||
; : |
|||
; CX has count of bytes to be printed : |
|||
; ES:DI point to source buffer contains characters : |
|||
; AuxNum (in msbio.asm) has printer number : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
PUBLIC PRN$WRIT ;3.30 |
|||
PRN$WRIT PROC NEAR ;3.30 |
|||
ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENT;3.30 RY |
|||
|
|||
jcxz EXVEC3 ; no chars to output, Get out |
|||
PRN$LOOP: |
|||
mov BX,2 ; Initialize retry flag |
|||
PRN$out: |
|||
mov AL,ES:[DI] ; Get a character into AL |
|||
inc DI ; Point to next character |
|||
XOR AH,AH ; AH=0 => OUTPUT CHAR IN DL ;3.30 |
|||
call PRNOP ; print character |
|||
jnz PrRetry ; if error, try to print again |
|||
loop PRN$LOOP ; if more character, keep printing |
|||
EXVEC3: |
|||
jmp EXIT |
|||
|
|||
PrRetry: |
|||
dec DI ; undo the inc above... |
|||
dec BX ; Decrement retry count |
|||
jnz PRN$out ; See if done with retrys |
|||
PMESSG: |
|||
JMP ERR$CNT ; if so return with the error |
|||
PRN$WRIT ENDP ;3.30 |
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; PRINTER STATUS ROUTINE : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
; |
|||
PUBLIC PRN$STAT ;3.30 |
|||
PRN$STAT PROC NEAR ;3.30 |
|||
ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENT;3.30 RY |
|||
;3.30 |
|||
call PRNSTAT ; get the status |
|||
jnz PMESSG ; if error jump to error routine |
|||
MOV AL,9 ; AGAIN, ASSUME OUT OF PAPER... ;3.30 |
|||
TEST AH,NOPAPERSTATUS ;3.30 |
|||
JNZ PMESSG ;3.30 |
|||
TEST AH,NOTBUSYSTATUS ;3.30 |
|||
jnz EXVEC3 ; if not busy return via EXVEC3 |
|||
JMP BUS$EXIT ; else busy, return to busy exit ;3.30 |
|||
PRN$STAT ENDP ;3.30 |
|||
|
|||
|
|||
|
|||
; |
|||
; PRNSTAT get printer status |
|||
; PRNOP print a character |
|||
; |
|||
; PRNSTAT and PRNOP are two routines which call on the ROM-BIOS |
|||
; printer routines. The routines share code which calls on the bios and |
|||
; then determines which, if any, error occured. PRNSTAT and PRNOP differ |
|||
; only by the value put into AH before the ROM-BIOS call. |
|||
; |
|||
; INPUT if PRNOP then character in AL |
|||
; |
|||
; OUTPUT - AL holds error code |
|||
; - AH status byte from printer |
|||
; - flag NZ if error |
|||
PRNSTAT PROC NEAR ;3.30 |
|||
mov AH, 2 ; set command for get status ;3.30* |
|||
PRNOP: ;3.30* |
|||
call GETDX ; determine which printer ;3.30* |
|||
int 17h ; call ROM-BIOS printer routine ;3.30* |
|||
|
|||
TEST AH,IOERRSTATUS ; I/O ERROR? ;3.30 |
|||
JZ CHECKNOTREADY ; NO, TRY NOT READY ;3.30 |
|||
;3.30 |
|||
; AT THIS POINT, WE KNOW WE HAVE AN ERROR. THE CONVERSE IS NOT TRUE. ;3.30 |
|||
;3.30 |
|||
MOV AL,9 ; FIRST, ASSUME OUT OF PAPER ;3.30 |
|||
TEST AH,NOPAPERSTATUS ; OUT OF PAPER SET? ;3.30 |
|||
JNZ RET1 ; YES, ERROR IS SET ;3.30 |
|||
INC AL ; INDICATE I/O ERROR ;3.30 |
|||
RET1: ;3.30 |
|||
;3.30 |
|||
; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT) ;3.30 |
|||
;3.30 |
|||
RET ; RETURN WITH ERROR ;3.30 |
|||
;3.30 |
|||
; THE BITS SAID NO ERROR. UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WOR;3.30 K |
|||
; HERE. ;3.30 |
|||
;3.30 |
|||
CHECKNOTREADY: ;3.30 |
|||
MOV AL,2 ; ASSUME NOT-READY ;3.30 |
|||
TEST AH,TIMEOUTSTATUS ; IS TIME-OUT SET? ;3.30 |
|||
; IF NZ THEN ERROR, ELSE OK??? ;3.30 |
|||
PRNOP2: ;3.30 |
|||
RET ;3.30 |
|||
PRNSTAT ENDP ;3.30 |
|||
|
|||
|
|||
;---------------------------------------------------------------- |
|||
; : |
|||
; Output until Busy : |
|||
; : |
|||
; Output until busy. This entry point is used EXCLUSIVELY by : |
|||
; the print spoolers. Under no curcumstances should the device : |
|||
; driver block waiting for the device to become ready. : |
|||
; : |
|||
; Inputs: CX has count of bytes to output. : |
|||
; ES:DI points to source buffer : |
|||
; Outputs: Set the number of bytes transferred : |
|||
; appropriately. : |
|||
; : |
|||
;---------------------------------------------------------------- |
|||
|
|||
PUBLIC PRN$TILBUSY ;3.30 |
|||
PRN$TILBUSY PROC NEAR ;3.30 |
|||
ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENT;3.30 RY |
|||
;3.30 |
|||
push DS ; save DS |
|||
push ES ; copy ES to DS |
|||
pop DS |
|||
ASSUME DS:NOTHING ;3.30 |
|||
|
|||
mov SI,DI ; everything is set for LODSB |
|||
PRN$TilBLoop: |
|||
push CX |
|||
push BX |
|||
xor BX,BX |
|||
mov BL,CS:[PRINTDEV] |
|||
shl BX,1 |
|||
mov CX,CS:WAIT_COUNT[BX] ; wait COUNT times to come ready |
|||
pop BX |
|||
PRN$GetStat: |
|||
call PrnStat ; get status |
|||
jnz PRN$BPERR ; if error jump to error routine |
|||
TEST AH,10000000B ; READY YET? ;3.30 |
|||
loopz PRN$GetStat ; if busy keep trying |
|||
pop CX ; get original count |
|||
jz PRN$BErr ; still not ready => done |
|||
lodsb |
|||
XOR AH,AH ;3.30 |
|||
call PrnOp ; print the character |
|||
jnz PRN$BErr ; error |
|||
loop PRN$TilBLoop ; go for more |
|||
PRN$B: |
|||
pop DS ; recover DS |
|||
lds BX,CS:[PTRSAV] ; get pointer to header |
|||
ASSUME DS:NOTHING ;3.30 |
|||
|
|||
sub WORD PTR [BX].COUNT,CX ; Determine number of succ. I/O's |
|||
jmp Exit ; all done, successful return |
|||
PRN$TILBUSY ENDP ;3.30 |
|||
|
|||
PRN$BPERR PROC NEAR ;3.30 |
|||
ASSUME DS:CODE ;3.30 |
|||
|
|||
pop CX ; recover number of char left |
|||
PRN$BErr: |
|||
pop DS ; get pointer to header |
|||
lds BX,CS:[PTRSAV] |
|||
ASSUME DS:NOTHING ;3.30 |
|||
|
|||
sub WORD PTR [BX].COUNT,CX ; Determine number of succ. I/O's |
|||
jmp err$exit ; jump to error exit |
|||
PRN$BPERR ENDP ;3.30 |
|||
|
|||
|
|||
; |
|||
; Prn$GenIOCTL: |
|||
; |
|||
; Manipulates the value in WAIT_COUNT depending on the value passed in the |
|||
; Generic IOCTL packet. |
|||
; It either sets or returns the current value for the retry count for the |
|||
; device. |
|||
; |
|||
PUBLIC PRN$GENIOCTL ;3.30 |
|||
PRN$GENIOCTL PROC NEAR ;3.30 |
|||
ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENT;3.30 RY |
|||
|
|||
les di,[PTRSAV] |
|||
cmp es:[di].MajorFunction,IOC_PC |
|||
je PrnFunc_OK |
|||
PrnFuncErr: |
|||
jmp CMDERR |
|||
|
|||
PrnFunc_OK: |
|||
mov al,es:[di].MinorFunction |
|||
les di,es:[di].GenericIOCTL_Packet |
|||
xor bx,bx |
|||
mov bl,[PRINTDEV] ; get index into retry counts |
|||
shl bx,1 |
|||
mov CX,WAIT_COUNT[BX] ; pull out retry count for device |
|||
cmp al,GET_RETRY_COUNT |
|||
jz PrnGetCount |
|||
cmp al,SET_RETRY_COUNT |
|||
jnz PrnFuncErr |
|||
mov cx,es:[di].RC_Count |
|||
PrnGetCount: |
|||
mov WAIT_COUNT[BX],CX ; place "new" retry count |
|||
mov es:[di].RC_Count,cx ; return current retry count |
|||
jmp EXIT |
|||
|
|||
PRN$GENIOCTL ENDP ;3.30 |
|||
CODE ENDS ;3.30 |
|||
END ;3.30 |
@ -0,0 +1,192 @@ |
|||
; |
|||
; This file contains three macros used in debugging the system. If the |
|||
; variable "test" (in msbio.asm) is nonzero code is included in the |
|||
; modules to print debugging messages. The level of debugging is controlled |
|||
; by the value of the variable fTestBits in msbio.asm. Specific bits in |
|||
; the variable determine which messages to print. The equ's below tell |
|||
; which bits control which funcitons. For example the fifth bit |
|||
; cooresponds to disk activity (see fTestDisk equ below). |
|||
; |
|||
; The macros in the file are: |
|||
; |
|||
; message Prints an ascii string on the screen. |
|||
; Example usage: |
|||
; |
|||
; message fTestDisk, <"Start Disk Write", CR, LF> |
|||
; message fTestINIT, <"Begin BDS initialization"> |
|||
; |
|||
; |
|||
; MNUM Print the value in a register or memory location on |
|||
; the screen. Value is displayed in hex. |
|||
; Usage: |
|||
; MNUM bitpattern, valueLocation |
|||
; |
|||
; valueLocation is typically a regester: |
|||
; |
|||
; mnum fTestCom, AX |
|||
; mnum fTestDisk, DX |
|||
; |
|||
; ValueLocation can also be a memory location: |
|||
; |
|||
; mnum fTestINIT, Final_Dos_Location |
|||
; |
|||
; If no valueLocation is given the macro defaults to |
|||
; the BX register. |
|||
; |
|||
; ZWAIT Stops the program until any key is pressed. |
|||
; |
|||
; |
|||
; The three macros preserve all register values. If "test" is zero |
|||
; defined during assembly then the marco produce no code. |
|||
; |
|||
|
|||
IF TEST ;3.30 |
|||
IFNDEF MSGOUT ;3.30 |
|||
EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30 |
|||
ENDIF ;3.30 |
|||
IFNDEF NUMBUF ;3.30 |
|||
EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30 |
|||
ENDIF ;3.30 |
|||
IFNDEF DUMPBYTES ;3.30 |
|||
EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30 |
|||
ENDIF ;3.30 |
|||
|
|||
|
|||
|
|||
fTestALL equ 1111111111111111b ; watch everything |
|||
fTestHARD equ 0000000000000001b ; watch hard disk initialization |
|||
fTest96 equ 0000000000000010b ; watch 96 tpi activity |
|||
FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30 |
|||
FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30 |
|||
FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30 |
|||
FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30 |
|||
FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE |
|||
FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30 |
|||
|
|||
|
|||
; |
|||
; message macro -- see above for description |
|||
; |
|||
|
|||
MESSAGE MACRO Bits,msg |
|||
LOCAL A,B ;3.30 |
|||
jmp SHORT b |
|||
a: db msg,0 |
|||
b: push SI |
|||
push AX |
|||
mov AX,Bits |
|||
mov SI,OFFSET a |
|||
call MSGOUT |
|||
pop AX |
|||
pop SI |
|||
endm |
|||
|
|||
|
|||
; |
|||
; mnum macro -- see above for description |
|||
; |
|||
|
|||
MNum MACRO Bits,num |
|||
push AX |
|||
ifb <num> |
|||
mov AX,Bits |
|||
call MSGNUM |
|||
else |
|||
push BX |
|||
mov BX,num |
|||
mov AX,Bits |
|||
call MSGNUM |
|||
pop BX |
|||
endif |
|||
pop AX |
|||
endm |
|||
|
|||
|
|||
; |
|||
; zwait macro -- see above for description |
|||
; |
|||
|
|||
ZWAIT MACRO |
|||
Message fTestALL,<"? "> |
|||
CALL ZWAITrtn |
|||
ENDM |
|||
|
|||
ZWAITrtn: |
|||
pushf ; save the flags |
|||
push AX ; preserve AX |
|||
xor AH, AH ; set command to get character ;3.30* |
|||
int 16h ; call rom keyboard routine ;3.30* |
|||
pop AX ; restore AX |
|||
popf ; restore the flags |
|||
ret |
|||
|
|||
;Dump_byte dumps the memory contents in hex. ;3.30 |
|||
;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30 |
|||
DUMP_BYTE MACRO DUMPSEG, DUMPOFFLABEL, BYTELENGTH ;3.30 |
|||
push es ;3.30 |
|||
PUSH DS ;3.30 |
|||
PUSH SI ;3.30 |
|||
PUSH CX ;3.30 |
|||
;3.30 |
|||
MOV CX, DUMPSEG ;3.30 |
|||
MOV DS, CX ;3.30 |
|||
MOV SI, OFFSET DUMPOFFLABEL ;3.30 |
|||
MOV CX, BYTELENGTH ;3.30 |
|||
call dumpbytes ;3.30 |
|||
;3.30 |
|||
POP CX ;3.30 |
|||
POP SI ;3.30 |
|||
POP DS ;3.30 |
|||
pop es ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30 |
|||
;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30 |
|||
DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30 |
|||
push es ;3.30 |
|||
PUSH DS ;3.30 |
|||
PUSH SI ;3.30 |
|||
PUSH CX ;3.30 |
|||
;3.30 |
|||
MOV CX, DUMPSEG ;3.30 |
|||
MOV DS, CX ;3.30 |
|||
MOV SI, DUMPOFFREG ;3.30 |
|||
MOV CX, BYTELENGTH ;3.30 |
|||
call dumpbytes ;3.30 |
|||
;3.30 |
|||
POP CX ;3.30 |
|||
POP SI ;3.30 |
|||
POP DS ;3.30 |
|||
pop es ;3.30 |
|||
ENDM ;3.30 |
|||
|
|||
else |
|||
; if test is not defined then make macro into null statements |
|||
Message macro |
|||
ENDM |
|||
|
|||
MNUM macro |
|||
ENDM |
|||
|
|||
ZWAIT macro |
|||
ENDM |
|||
|
|||
DUMP_BYTE MACRO ;3.30 |
|||
ENDM ;3.30 |
|||
DUMP_BYTE_REG MACRO ;3.30 |
|||
ENDM ;3.30 |
|||
ENDIF ;3.30 |
|||
;3.30 |
|||
PATHSTART MACRO INDEX,ABBR ;3.30 |
|||
IFDEF PATHGEN ;3.30 |
|||
PUBLIC ABBR&INDEX&S,ABBR&INDEX&E ;3.30 |
|||
ABBR&INDEX&S LABEL BYTE ;3.30 |
|||
ENDIF ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
PATHEND MACRO INDEX,ABBR ;3.30 |
|||
IFDEF PATHGEN ;3.30 |
|||
ABBR&INDEX&E LABEL BYTE ;3.30 |
|||
ENDIF ;3.30 |
|||
ENDM ;3.30 |
|||
|
@ -0,0 +1,306 @@ |
|||
; MSStack.inc |
|||
; |
|||
; Interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - AT level) |
|||
; should follow the standard Interrupt Sharing Scheme which has |
|||
; a standard header structure. |
|||
; Fyi, the following shows the relations between |
|||
; the interrupt vector and interrupt level. |
|||
; VEC(Hex) 2 8 9 A B C D E 70 72 73 74 76 77 |
|||
; LVL(Deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15 |
|||
; MSSTACK module modifies the following interrupt vectors |
|||
; to meet the standard Interrupt Sharing standard; |
|||
; A, B, C, D, E, 72, 73, 74, 76, 77. |
|||
; Also, for interrupt level 7 and 15, the FirstFlag in a standard header |
|||
; should be initialized to indicat whether this interrupt handler is |
|||
; the first (= 80h) or not. The FirstFlag entry of INT77h's |
|||
; program header is initialized in STKINIT.INC module. |
|||
; FirstFlag is only meaningful for interrupt level 7 and 15. |
|||
; |
|||
|
|||
; User specifies the number of stack elements - default = 9 |
|||
; minimum = 8 |
|||
; maximum = 64 |
|||
; |
|||
; Intercepts Asynchronous Hardware Interrupts only |
|||
; |
|||
; Picks a stack from pool of stacks and switches to it |
|||
; |
|||
; Calls the previously saved interrupt vector after pushing flags |
|||
; |
|||
; On return, returns the stack to the stack pool |
|||
; |
|||
|
|||
|
|||
; This is a modification of STACKS: |
|||
; 1. To fix a bug which was causing the program to take up too much space. |
|||
; 2. To dispense stack space from hi-mem first rather than low-mem first. |
|||
; . Clobbers the stack that got too big instead of innocent stack |
|||
; . Allows system to work if the only stack that got too big was the most |
|||
; deeply nested one |
|||
; 3. Disables NMI interrupts while setting the NMI vector. |
|||
; 4. Does not intercept any interupts on a PCjr. |
|||
; 5. Double checks that a nested interrupt didn't get the same stack. |
|||
; 6. Intercepts Ints 70, 72-77 for PC-ATs and other future products |
|||
|
|||
;The following variables are for MSSTACK.inc |
|||
EVEN |
|||
dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER |
|||
StackCount dw 0 |
|||
StackAt dw 0 |
|||
StackSize dw 0 |
|||
Stacks dw 0 |
|||
dw 0 |
|||
|
|||
FirstEntry dw Stacks |
|||
LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize |
|||
NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize |
|||
|
|||
;End of variables defined for MSSTACK. |
|||
|
|||
;******************************************************************* |
|||
;Macro Interrupt handler for the ordinary interrupt vectors and |
|||
;the shared interrupt vectors. |
|||
;***************************** |
|||
Stack_Main MACRO AA |
|||
ASSUME DS:NOTHING |
|||
ASSUME ES:NOTHING |
|||
ASSUME SS:NOTHING |
|||
PUBLIC Int&AA |
|||
PUBLIC Old&AA |
|||
;----------------------------- |
|||
ife IntSharingFlag ;if not IntSharingFlag |
|||
;----------------------------- |
|||
Old&AA DD 0 |
|||
Int&AA PROC FAR |
|||
;----------------------------- |
|||
else ;for shared interrupt. A Header exists. |
|||
|
|||
PUBLIC FirstFlag&AA |
|||
Int&AA PROC FAR |
|||
jmp short Entry_Int&AA&_Stk |
|||
Old&AA dd 0 ;Forward pointer |
|||
dw 424Bh ;compatible signature for Int. Sharing |
|||
FirstFlag&AA db 0 ;the firstly hooked. |
|||
jmp short Intret_&AA ;Reset routine. We don't care this. |
|||
db 7 dup (0) ;Reserved for future. |
|||
Entry_Int&AA&_Stk: |
|||
;----------------------------- |
|||
endif |
|||
;----------------------------- |
|||
|
|||
; |
|||
; Keyboard interrupt must have a three byte jump, a NOP and a zero byte |
|||
; as its first instruction for compatibility reasons |
|||
ifidn <&aa>,<09> |
|||
jmp Keyboard_lbl |
|||
nop |
|||
db 0 |
|||
Keyboard_lbl label near |
|||
endif |
|||
|
|||
; This patches INTERRUPT 75h to be "unhooked". We do this Wierdness, |
|||
; rather than never hooking INT 75h, to maintain maximum compat. with IBMs |
|||
; post production patch. |
|||
push ax |
|||
|
|||
ifidn <&aa>,<02> |
|||
|
|||
; ********************************************************************* |
|||
; |
|||
; This is special support for the P12 / NMI handler |
|||
; |
|||
; On the P12, there is a situation where an NMI can be caused by |
|||
; using the "OUT" instructions to certain ports. When this |
|||
; occurs, the P12 hardware *GUARANTEES* that **NOTHING** can stop |
|||
; the NMI or interfere with getting to the NMI handler. This |
|||
; includes other type of interrupts (hardware and software), and |
|||
; also includes other type of NMI's. When any NMI has occured, |
|||
; no other interrtupt (hardware, software or NMI) can occur until |
|||
; the software takes specific steps to allow further interrupting. |
|||
; |
|||
; For P12, the situation where the NMI is generated by the "OUT" |
|||
; to a control port requires "fixing-up" and re-attempting. In |
|||
; otherwords, it is actually a "restartable exception". In this |
|||
; case, the software handler must be able to get to the stack in |
|||
; order to figure out what instruction caused the problem, where |
|||
; it was "OUT"ing to and what value it was "OUT"ing. Therefore, |
|||
; we will not switch stacks in this situation. This situation is |
|||
; detected by interrogating port 62h, and checking for a bit value |
|||
; of 80h. If set, *****DO NOT SWITCH STACKS*****. |
|||
; |
|||
; ********************************************************************* |
|||
|
|||
push es |
|||
mov ax,0f000h |
|||
mov es,ax |
|||
cmp byte ptr es:[0fffeh],0f9h ;check if P12 |
|||
pop es |
|||
jne Normal&aa |
|||
|
|||
in al,62h |
|||
test al,80h |
|||
jz Normal&aa |
|||
|
|||
Special&aa: |
|||
pop ax |
|||
jmp dword ptr Old&aa |
|||
|
|||
Normal&aa: |
|||
|
|||
; ********************************************************************* |
|||
|
|||
endif |
|||
|
|||
push bp |
|||
push es |
|||
mov es, cs:[STACKS+2] ; Get segment of stacks |
|||
|
|||
mov bp,NextEntry ; get most likely candidate |
|||
mov al,Allocated |
|||
xchg AllocByte,al ; grab the entry |
|||
cmp al,Free ; still avail? |
|||
jne NotFree&aa |
|||
|
|||
sub NextEntry,EntrySize ; set for next interrupt |
|||
|
|||
Found&aa: |
|||
mov SavedSP,sp ; save sp value |
|||
mov SavedSS,ss ; save ss also |
|||
; mov IntLevel,aa&h ; save the int level |
|||
|
|||
mov ax,bp ; temp save of table offset |
|||
|
|||
mov bp,NewSP ; get new SP value |
|||
cmp es:[bp],ax ; check for offset into table |
|||
jne FoundBad&aa |
|||
|
|||
mov ax,es ; point ss,sp to the new stack |
|||
mov ss,ax |
|||
mov sp,bp |
|||
|
|||
pushf ; go execute the real interrupt handler |
|||
call dword ptr old&aa ; which will iret back to here |
|||
|
|||
mov bp,sp ; retrieve the table offset for us |
|||
mov bp,es:[bp] ; but leave it on the stack |
|||
mov ss,SavedSS ; get old stack back |
|||
mov sp,SavedSP |
|||
|
|||
; cmp AllocByte,Allocated ; If an error occured, |
|||
; jne NewError&aa ; do not free us |
|||
|
|||
mov AllocByte,Free ; free the entry |
|||
mov NextEntry,bp ; setup to use next time |
|||
|
|||
NewError&aa: |
|||
pop es |
|||
pop bp ; saved on entry |
|||
pop ax ; saved on entry |
|||
|
|||
INTRET_&AA: ;3.30 |
|||
iret ; done with this interrupt |
|||
|
|||
NotFree&aa: |
|||
cmp al,Allocated ; error flag |
|||
je findnext&aa ; no, continue |
|||
xchg AllocByte,al ; yes, restore error value |
|||
|
|||
FindNext&aa: |
|||
call LongPath |
|||
jmp Found&aa |
|||
|
|||
FoundBad&aa: |
|||
cmp bp,FirstEntry |
|||
jc findnext&aa |
|||
mov bp,ax ; flag this entry |
|||
mov AllocByte,Clobbered |
|||
; add bp,EntrySize ; and previous entry |
|||
; mov AllocByte,Overflowed |
|||
; sub bp,EntrySize |
|||
jmp findnext&aa ; keep looking |
|||
|
|||
int&aa endp |
|||
|
|||
|
|||
endm |
|||
|
|||
;***************************** ;3.30 |
|||
;End of Macro definition ;3.30 |
|||
;******************************************************************** ;3.30 |
|||
; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30 |
|||
;3.30 |
|||
IRP A,<02,08,09,70> ;3.30 |
|||
IntSharingFlag=0 ;3.30 |
|||
Stack_Main &A ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
IRP A,<0A,0B,0C,0D,0E,72,73,74,76,77> ;3.30 |
|||
IntSharingFlag=1 ;3.30 |
|||
Stack_Main &A ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
;******************************************************************** ;3.30 |
|||
;Common routines ;3.30 |
|||
|
|||
longpath: |
|||
mov bp,LastEntry ; start with last entry in table |
|||
|
|||
LPLOOPP: ;3.30 |
|||
cmp AllocByte,Free ; is entry free? |
|||
jne inuse ; no, try next one |
|||
|
|||
mov al,Allocated |
|||
xchg AllocByte,al ; allocate entry |
|||
cmp al,Free ; is it still free? |
|||
je found ; yes, go use it |
|||
|
|||
cmp al,Allocated ; is it other than Allocated or Free? |
|||
je inuse ; no, check the next one |
|||
|
|||
mov AllocByte,al ; yes, put back the error state |
|||
|
|||
inuse: |
|||
cmp bp,FirstEntry |
|||
je Fatal |
|||
sub bp,EntrySize |
|||
JMP LPLOOPP ;3.30 |
|||
|
|||
found: |
|||
ret |
|||
|
|||
page |
|||
|
|||
fatal proc near |
|||
push ds ;3.30 |
|||
mov ax, 0f000h ;loook at the model byte ;3.30 |
|||
mov ds, ax ;3.30 |
|||
cmp ds:byte ptr [0fffeh], 0f9h ;convertible ;3.30 |
|||
pop ds ;3.30 |
|||
jne Skip_NMIS ;3.30 |
|||
;3.30 |
|||
mov al,07h ; disable p12 NMIs |
|||
out 72h,al |
|||
|
|||
Skip_NMIS: ;3.30 |
|||
cli ; disable and mask |
|||
mov al,0ffh ; all other ints |
|||
out 021h,al |
|||
out 0a1h,al |
|||
|
|||
mov si,cs |
|||
mov ds,si |
|||
mov si,offset fatal_msg |
|||
|
|||
fatal_loop: |
|||
lodsb |
|||
cmp al,'$' |
|||
je fatal_done |
|||
|
|||
mov bl,7 ;3.30* |
|||
mov ah,14 ;3.30* |
|||
int 010h ; whoops, this enables ints ;3.30* |
|||
jmp fatal_loop |
|||
|
|||
fatal_done: |
|||
jmp fatal_done |
|||
fatal endp |
@ -0,0 +1,297 @@ |
|||
;------------------------------------------------------------------------- |
|||
; |
|||
; File: msvolid.asm |
|||
; This file contains the volume_id subroutines and data structures. |
|||
; |
|||
; Routines in this file are: |
|||
; Set_Volume_ID - main routine, calls other routines. |
|||
; read_volume_id - read the volume ID and tells if it has |
|||
; been changed. |
|||
; Transfer_volume_id - copy the volume ID from TMP to special |
|||
; drive. |
|||
; Check_Volume_ID - compare volume ID in TMP area with one |
|||
; expected for drive. |
|||
; Fat_Check - see of the fatID has changed in the |
|||
; specified drive. |
|||
; Init_Vid_loop - set up for VID scan or move |
|||
; |
|||
; |
|||
;------------------------------------------------------------------------- |
|||
|
|||
; |
|||
; length of the volume id |
|||
; |
|||
|
|||
vid_size equ 12 |
|||
|
|||
PATHSTART 001,VOLID ;3.30 |
|||
|
|||
; |
|||
; null volume id |
|||
; |
|||
|
|||
nul_vid db "NO NAME ",0 |
|||
|
|||
; |
|||
; data scratch area used to hold volume ids |
|||
; |
|||
|
|||
tmp_vid db "NO NAME ",0 |
|||
|
|||
PATHEND 001,VOLID ;3.30 |
|||
|
|||
; |
|||
; Set_Volume_ID |
|||
; If drive has changeline support, read in and set the volume_ID |
|||
; and the last FAT_ID byte. If no change line support then do nothing. |
|||
; |
|||
; On entry: |
|||
; DS:DI points to the BDS for this disk. |
|||
; AH contains media byte |
|||
; |
|||
; On Exit: |
|||
; Carry clear: |
|||
; Successful call |
|||
; Carry set |
|||
; Error and AX has error code |
|||
; |
|||
|
|||
Set_Volume_ID: |
|||
PUBLIC SET_VOLUME_ID ;3.30 |
|||
push dx ; save registers |
|||
push ax |
|||
CALL HasChange ; does drive have changeline support? |
|||
jz setvret ; no, get out |
|||
push di |
|||
call read_volume_ID ; read the volume ID |
|||
pop di |
|||
jc SetErr ; if error go to error routine |
|||
call transfer_volume_ID ; copy the volume id to special drive |
|||
call ResetChanged ; restore value of change line |
|||
|
|||
setvret: ; SET Volume RETurn |
|||
clc ; no error, clear carry flag |
|||
pop ax ; restore registers |
|||
pop dx |
|||
ret |
|||
SetErr: |
|||
pop dx ; pop stack but don't overwrite AX |
|||
pop dx ; restore DX |
|||
ret |
|||
|
|||
|
|||
|
|||
root_sec DW ? ;Root sector # |
|||
|
|||
|
|||
|
|||
|
|||
; |
|||
; read_volume_id read the volume ID and tells if it has been changed. |
|||
; |
|||
; On entry: |
|||
; DS:DI points to current BDS for drive. |
|||
; On Exit: |
|||
; Carry Clear |
|||
; SI = 1 No change |
|||
; SI = 0 ? |
|||
; SI = -1 Change |
|||
; |
|||
; Carry Set: |
|||
; Error and AX has error code. |
|||
; |
|||
|
|||
read_volume_id: |
|||
push ES ; preserve registers |
|||
push DX |
|||
push CX |
|||
push BX |
|||
push AX |
|||
push DS ; Preserve Current BDS |
|||
push DI |
|||
push cs ; get ES segment correct |
|||
pop es |
|||
push cs ; get DS segment correct |
|||
pop ds |
|||
mov di,offset tmp_vid |
|||
mov si,offset nul_vid |
|||
mov cx,vid_size |
|||
rep movsb ; initialize tmp_vid to null vi_id |
|||
|
|||
pop DI ; Restore Current BDS |
|||
pop DS |
|||
mov al,byte ptr ds:[di].cFAT ; # of fats |
|||
mov cx,word ptr ds:[di].csecfat ; sectors / fat |
|||
mul cl ; size taken by fats |
|||
add ax,word ptr ds:[di].ressec ; add on reserved sectors |
|||
; AX is now sector # (0 based) |
|||
mov cs:[root_sec],ax ; set initial value |
|||
mov ax,[di].cDir ; # root dir entries |
|||
mov cl,4 ; 16 entries/sector |
|||
shr ax,cl ; divide by 16 |
|||
mov cx,ax ; cx is # of sectors to scan |
|||
next_sec: |
|||
push cx ; save outer loop counter |
|||
mov ax,cs:[root_sec] ; get sector # |
|||
mov cx,word ptr ds:[di].seclim ; sectors / track |
|||
xor DX,DX |
|||
div cx |
|||
; set up registers for call to read_sector |
|||
inc DX ; dx= sectors into track, ax= track count from 0 |
|||
mov cl,dl ; sector to read |
|||
xor DX,DX |
|||
div word ptr ds:[di].hdlim ; # heads on this disc |
|||
mov dh,dl ; Head number |
|||
mov ch,al ; Track # |
|||
call read_sector ; get first sector of the root directory, |
|||
; ES:BX -> BOOT |
|||
jc ReadVIDErr ; error on read |
|||
mov cx,16 ; # of dir entries in a block of root |
|||
mov al,08h ; volume label bit |
|||
fvid_loop: |
|||
cmp byte ptr es:[bx],0 ; End of dir? |
|||
jz no_vid ; yes, no vol id |
|||
cmp byte ptr es:[bx],0E5h ; empty entry? |
|||
jz ent_loop ; yes, skip |
|||
test es:[bx+11],al ; is volume label bit set in fcb? |
|||
jnz found_vid ; jmp yes |
|||
ent_loop: |
|||
ADD BX,32 ;MJB003 ADD LENGTH OF DIRECTORY ENTRY ;3.30 |
|||
loop fvid_loop |
|||
pop cx ; outer loop |
|||
inc cs:[root_sec] ; next sector |
|||
loop next_sec ; continue |
|||
NotFound: |
|||
XOR SI,SI |
|||
jmp short fvid_ret |
|||
|
|||
found_vid: |
|||
pop cx ; clean stack of outer loop counter |
|||
mov si,bx ; point to volume_id |
|||
push ds ; preserve currnet BDS |
|||
push di |
|||
push es ; es:si points to volume id. |
|||
pop ds ; source segment |
|||
push cs |
|||
pop es ; destination segment |
|||
mov di,offset tmp_vid ; dest of volume_id |
|||
mov cx,vid_size -1 ; length of string minus NUL |
|||
rep movsb ; mov volume label to tmp_vid |
|||
xor al,al |
|||
stosb ; Null terminate |
|||
XOR SI,SI |
|||
pop DI ; restore current BDS |
|||
pop DS |
|||
fvid_ret: |
|||
pop ax |
|||
clc |
|||
RVIDRet: |
|||
pop BX ; restore register |
|||
pop CX |
|||
pop DX |
|||
pop ES |
|||
ret |
|||
no_vid: |
|||
pop cx ; clean stack of outer loop counter |
|||
jmp NotFound ; not found |
|||
ReadVIDErr: |
|||
pop SI |
|||
pop SI |
|||
jmp RVIDRet |
|||
|
|||
|
|||
|
|||
; |
|||
; Transfer_volume_id - copy the volume ID from TMP to special drive |
|||
; |
|||
; Inputs: DS:DI nas current BDS |
|||
; Outputs: BDS for drive has volume ID from TMP |
|||
; |
|||
|
|||
transfer_volume_ID: |
|||
push DS ; preserve current BDS |
|||
push DI |
|||
push ES |
|||
push SI |
|||
push CX |
|||
call init_vid_loop |
|||
cld |
|||
rep MOVSB ; transfer |
|||
pop CX |
|||
pop SI |
|||
pop ES |
|||
pop DI ; restore current BDS |
|||
pop DS |
|||
ret |
|||
|
|||
|
|||
; |
|||
; Check_Volume_ID - compare volume ID in TMP area with one expected for |
|||
; drive |
|||
; |
|||
; Inputs: DS:DI has current BDS for drive |
|||
; Outputs: SI = 0 if compare succeeds |
|||
; SI = -1 if compare fails. |
|||
|
|||
check_volume_id: |
|||
push DS ; preserve current BDS for drive |
|||
push DI |
|||
push ES |
|||
push CX |
|||
call init_vid_loop |
|||
cld |
|||
repz cmpsb ; are the 2 volume_ids the same? |
|||
mov si,0 ; assume unknown |
|||
jz check_vid_ret ; carry clear if jump taken |
|||
mov si,-1 ; failure |
|||
check_vid_ret: |
|||
pop CX |
|||
pop ES |
|||
pop DI ; restore current BDS |
|||
pop DS |
|||
ret |
|||
|
|||
; |
|||
; Fat_Check - see of the fatID has changed in the specified drive. |
|||
; - uses the FAT ID obtained from the boot sector. |
|||
; |
|||
; Inputs: MedByt is expected FAT ID |
|||
; DS:DI points to current BDS |
|||
; Output: Carry Clear |
|||
; SI = -1 if fat ID different, |
|||
; SI = 0 otherwise |
|||
; No other registers changed. |
|||
|
|||
FAT_CHECK: |
|||
push AX |
|||
xor SI, SI ; say FAT ID's are same. |
|||
mov AL, cs:MedByt |
|||
cmp AL, byte ptr [DI].Mediad ; compare it with the BDS medbyte |
|||
jz OKRET1 ; carry clear |
|||
dec SI |
|||
OkRet1: clc |
|||
pop AX |
|||
ret |
|||
|
|||
|
|||
; |
|||
; Init_Vid_loop - set up for VID scan or move |
|||
; |
|||
; Inputs: DS:DI pionts to BDS for the drive |
|||
; Outputs: DS:SI points to tmp_vid |
|||
; ES:DI points to vid for drive |
|||
; CX has size for VID compare |
|||
; |
|||
|
|||
init_vid_loop: |
|||
push ax |
|||
push ds |
|||
pop es |
|||
push cs |
|||
pop ds |
|||
mov si,offset tmp_vid ; source |
|||
add di,volid |
|||
mov cx,vid_size |
|||
pop ax |
|||
ret |
|||
|
@ -0,0 +1,20 @@ |
|||
IF1 ;3.30 |
|||
|
|||
SaveReg MACRO reglist ;; push those registers |
|||
IRP reg,<reglist> |
|||
?stackdepth = ?stackdepth + 1 |
|||
PUSH reg |
|||
ENDM |
|||
ENDM |
|||
.xcref SaveReg |
|||
|
|||
|
|||
RestoreReg MACRO reglist ;; pop those registers |
|||
IRP reg,<reglist> |
|||
?stackdepth = ?stackdepth - 1 |
|||
POP reg |
|||
ENDM |
|||
ENDM |
|||
.xcref RestoreReg |
|||
|
|||
ENDIF ;3.30 |
@ -0,0 +1,162 @@ |
|||
; SCCSID = @(#)readclock.asm 1.2 85/07/25 |
|||
;************************************************************************ |
|||
; |
|||
; read_real_date reads real-time clock for date and returns the number |
|||
; of days elapsed since 1-1-80 in si |
|||
; |
|||
read_real_date: ;mjb002 |
|||
PUSH AX |
|||
PUSH CX |
|||
PUSH DX |
|||
XOR AH,AH ; throw away clock roll over ;3.30* |
|||
INT 1AH ;3.30* |
|||
POP DX |
|||
POP CX |
|||
POP AX |
|||
|
|||
PUSH AX |
|||
PUSH BX |
|||
PUSH CX |
|||
PUSH DX |
|||
MOV CS:DAYCNT2,1 ;MJB002 REAL TIME CLOCK ERROR FLAG (+1 DA;3.30Y) |
|||
mov ah,4 ;mjb002 read date function code ;3.30* |
|||
int 1ah ;mjb002 read real-time clock ;3.30* |
|||
jnc read_ok ;mjb002 jmp success |
|||
jmp r_d_ret ;mjb002 jmp error |
|||
read_ok: ;mjb002 ******* get bcd values in binary ***** |
|||
mov byte ptr bin_date_time+0,ch ;mjb002 store as hex value |
|||
mov byte ptr bin_date_time+1,cl ;mjb002 ... |
|||
mov byte ptr bin_date_time+2,dh ;mjb002 ... |
|||
mov byte ptr bin_date_time+3,dl ;mjb002 ... |
|||
MOV CS:DAYCNT2,2 ;MJB002 READ OF R-T CLOCK SUCCESSFUL ;3.30 |
|||
call bcd_verify ;mjb002 verify bcd values in range |
|||
jc r_d_ret ;mjb002 jmp some value out of range |
|||
MOV CS:DAYCNT2,3 ;MJB002 READ OF R-T CLOCK SUCCESSFUL ;3.30 |
|||
call date_verify ;mjb002 verify date values in range |
|||
jc r_d_ret ;mjb002 jmp some value out of range |
|||
MOV CS:DAYCNT2,0 ;MJB002 VERIFY SUCCESSFUL ;3.30;3.30 |
|||
call in_bin ;mjb002 convert date to binary |
|||
;mjb002 ******* years since 1-1-80 ********* |
|||
mov al,byte ptr bin_date_time+1 ;mjb002 get years into century |
|||
cbw ;mjb002 |
|||
cmp byte ptr bin_date_time+0,20 ;mjb002 20th century? |
|||
jnz century_19 ;mjb002 jmp no |
|||
add ax,100 ;mjb002 add in a century |
|||
century_19: ;mjb002 |
|||
sub ax,80 ;mjb002 subtract off 1-1-80 |
|||
mov cl,4 ;mjb002 leap year every 4 |
|||
div cl ;mjb002 al= # leap year blocks, ah= remainder |
|||
mov bl,ah ;mjb002 save odd years |
|||
cbw ;mjb002 zero ah |
|||
mov cx,366+3*365 ;mjb002 # of days in leap year blocks |
|||
mul cx ;mjb002 dx:ax is result |
|||
MOV CS:DAYCNT2,AX ;MJB002 SAVE COUNT OF DAYS ;3.30 |
|||
mov al,bl ;mjb002 get odd years count |
|||
cbw ;mjb002 |
|||
or ax,ax ;mjb002 is ax= 0? |
|||
jz leap_year ;mjb002 jmp if none |
|||
mov cx,365 ;mjb002 days in year |
|||
mul cx ;mjb002 dx:ax is result |
|||
ADD CS:DAYCNT2,AX ;MJB002 ADD ON DAYS IN ODD YEARS ;3.30 |
|||
jmp short leap_adjustment ;mjb002 account for leap year |
|||
leap_year: ;mjb002 possibly account for a leap day |
|||
cmp byte ptr bin_date_time+2,2 ;mjb002 is month february |
|||
jbe no_leap_adjustment ;mjb002 jan or feb. no leap day yet. |
|||
leap_adjustment: ;mjb002 account for leap day |
|||
INC CS:DAYCNT2 ;MJB002 ... ;3.30 |
|||
no_leap_adjustment: ;mjb002 ******* get days of month ******* |
|||
mov cl,byte ptr bin_date_time+3 ;mjb002 ... |
|||
xor ch,ch ;mjb002 |
|||
dec cx ;mjb002 because of offset from day 1, not day 0 |
|||
ADD CS:DAYCNT2,CX ;MJB002 ******* GET DAYS IN MONTHS PRECEE;3.30DING ***** |
|||
mov cl,byte ptr bin_date_time+2 ;mjb002 get month |
|||
xor ch,ch ;mjb002 |
|||
dec cx ;mjb002 january starts at offset 0 |
|||
shl cx,1 ;mjb002 word offset |
|||
mov si,offset month_table ;mjb002 beginning of month_table |
|||
add si,cx ;mjb002 point into month table |
|||
mov ax,word ptr [si];mjb002 get # days in previous months |
|||
ADD CS:DAYCNT2,AX ;MJB002 ... ;3.30 |
|||
r_d_ret: ;mjb002 |
|||
MOV SI,CS:DAYCNT2 ;MJB002 RESULT IN SI ;3.30 |
|||
POP DX |
|||
POP CX |
|||
POP BX |
|||
POP AX |
|||
ret ;mjb002 |
|||
|
|||
r_t_retj: |
|||
xor cx,cx |
|||
xor dx,dx |
|||
jmp r_t_ret |
|||
; |
|||
; Read_Real_Time reads the time from the RTC. on exit, it has the number of |
|||
; ticks (at 18.2 ticks per sec.) in CX:DX. |
|||
; |
|||
Read_Real_Time: |
|||
mov ah,2 ;3.30* |
|||
int 1AH ;3.30* |
|||
jc r_t_retj |
|||
oktime: |
|||
mov byte ptr bin_date_time,ch ; hours |
|||
mov byte ptr bin_date_time+1,cl ; minutes |
|||
mov byte ptr bin_date_time+2,dh ; seconds |
|||
mov byte ptr bin_date_time+3,0 ; unused for time |
|||
call bcd_verify |
|||
jc r_t_retj |
|||
call time_verify |
|||
jc r_t_retj |
|||
call in_bin |
|||
MOV ch,byte ptr bin_date_time |
|||
MOV cl,byte ptr bin_date_time+1 |
|||
MOV dh,byte PTR bin_date_time+2 |
|||
MOV dl,byte PTR bin_date_time+3 |
|||
message ftestinit,<"Read Time "> |
|||
mnum ftestinit,cx |
|||
message ftestinit,<" "> |
|||
mnum ftestinit,dx |
|||
message ftestinit,<cr,lf> |
|||
; get time in ticks in CX:DX |
|||
CALL word ptr cs:TimeToTicks ;3.30 |
|||
message ftestinit,<"Conv Time "> |
|||
mnum ftestinit,cx |
|||
message ftestinit,<" "> |
|||
mnum ftestinit,dx |
|||
message ftestinit,<cr,lf> |
|||
r_t_ret: |
|||
ret |
|||
|
|||
; |
|||
; in_bin converts bin_date_time values from bcd to bin |
|||
; |
|||
in_bin: ;mjb002 |
|||
mov al,byte ptr bin_date_time+0 ; century or hours |
|||
call bcd_to_bin ; ... |
|||
mov byte ptr bin_date_time+0,al ; |
|||
mov al,byte ptr bin_date_time+1 ; years or minutes |
|||
call bcd_to_bin ; ... |
|||
mov byte ptr bin_date_time+1,al ; |
|||
mov al,byte ptr bin_date_time+2 ; months or seconds |
|||
call bcd_to_bin ; ... |
|||
mov byte ptr bin_date_time+2,al ; |
|||
mov al,byte ptr bin_date_time+3 ; days (not used for time) |
|||
call bcd_to_bin ; ... |
|||
mov byte ptr bin_date_time+3,al ; |
|||
ret ; |
|||
; |
|||
; bcd_to_bin converts two bcd nibbles in al (value <= 99.) to |
|||
; a binary representation in al |
|||
; ah is destroyed |
|||
; |
|||
bcd_to_bin: ;mjb002 |
|||
mov ah,al ;mjb002 copy bcd number to ah |
|||
and ax,0f00fh ;mjb002 clear unwanted nibbles |
|||
mov bl,al ;mjb002 save units place |
|||
xchg ah,al ;mjb002 10's place to al |
|||
xor ah,ah ;mjb002 ah not wanted |
|||
mov cl,4 ;mjb002 shift count |
|||
shr ax,cl ;mjb004 swap nibbles |
|||
mov cl,10 ;mjb002 convert al to ... |
|||
mul cl ;mjb002 ... its binary value |
|||
add al,bl ;mjb002 add in units |
|||
ret ;mjb002 |
@ -0,0 +1,270 @@ |
|||
; |
|||
; To follow the standard interrupt sharing scheme, MSSTACK.ASM ;3.30 |
|||
; has been modified. This initialization routine also has to ;3.30 |
|||
; be modified because for the interrupt level 7 and 15, FirstFlag ;3.30 |
|||
; should be set to signal that this interrupt handler is the ;3.30 |
|||
; first handler hooked to this interrupt vector. ;3.30 |
|||
; We determine this by looking at the instruction pointed by ;3.30 |
|||
; this vector. If it is IRET, then this handler should be the ;3.30 |
|||
; first one. In our case, only the interrupt vector 77h is the ;3.30 |
|||
; interrupt level 15. (We don't hook interrupt level 7.) ;3.30 |
|||
; 9/10/1986 ;3.30 |
|||
; The followings are mainly due to M.R.Turner; PTM fix of P886 12/3/86 ;3.30 |
|||
; Some design changes are needed to the above interrupt sharing ;3.30 |
|||
; method. The above sharing scheme assumes that 1). Interrupt ;3.30 |
|||
; sharing is NEVER done on levels that have BIOS support. 2). "Phantom" ;3.30 |
|||
; interrupts would only be generated on levels 7 and 15. ;3.30 |
|||
; These assumptions are not true any more. We have to use the FirstFlag ;3.30 |
|||
; for EVERY level of interrupt. We will set the firstFlag on the following;3.30 |
|||
; conditions: ;3.30 |
|||
; a. if the CS portion of the vector is 0000, then "first" ;3.30 |
|||
; b. else if CS:IP points to valid shared header, then NOT "first" ;3.30 |
|||
; c. else if CS:IP points to an IRET, then "first" ;3.30 |
|||
; d. else if CS:IP points to DUMMY, then "first" ;3.30 |
|||
; where DUMMY is - the CS portion must be F000, and the IP portion must ;3.30 |
|||
; be equal to the value at F000:FF01. This location is the initial value ;3.30 |
|||
; from VECTOR_TABLE for interrupt 7, one of the preserved addresses in all;3.30 |
|||
; the BIOSes for all of the machines. ;3.30 |
|||
; ;3.30 |
|||
; System design group requests BIOS to handle the phantom interrupts. ;3.30 |
|||
; ;3.30 |
|||
; The "Phantom" interrupt is an illegal interrupt such as an interrupt ;3.30 |
|||
; produced by the bogus adapter card even without interrupt request is ;3.30 |
|||
; set. More specifically, 1). The 8259 has a feature when running in ;3.30 |
|||
; edge triggered mode to latch a pulse and present the interrupt when ;3.30 |
|||
; the processor indicates interrupt acknowledge (INTA). The interrupt ;3.30 |
|||
; pulse was exist at the time of INTA to get a "phantom" interrupt. ;3.30 |
|||
; 2). or, this is caused by adapter cards placing a glitch on the ;3.30 |
|||
; interrupt line. ;3.30 |
|||
; ;3.30 |
|||
; To handle those "phantom" interrupts, the main stack code will check ;3.30 |
|||
; the own FirstFlag, and if it is not "first" (which means the forward ;3.30 |
|||
; pointer points to the legal shared interrupt handler), then pass the ;3.30 |
|||
; control. If it is the first, then the following action should be ;3.30 |
|||
; taken. We don't have to implement skack logic in this case. ;3.30 |
|||
; ;3.30 |
|||
; To implement this logic, we rather choose a simple method. ;3.30 |
|||
; If ont of the above "FirstFlag" conditions is met, we are not ;3.30 |
|||
; going to hook this interrupt vector. The reason is if the original ;3.30 |
|||
; vector points to "IRET" and do nothing, we don't need ;3.30 |
|||
; to implement the stack logic for it. This will simplify implementation;3.30 |
|||
; while maintaining compatibility with the old version of DOS. ;3.30 |
|||
; This implies that in the main stack code, there might be a stack code ;3.30 |
|||
; that will never be used, a dead code. ;3.30 |
|||
; ;3.30 |
|||
; 12/3/86 ;3.30 |
|||
;3.30 |
|||
;In - CS, DS -> sysinitseg, ES -> relocated stack code & data. ;3.30 |
|||
;3.30 |
|||
PAGE ;3.30 |
|||
StackInit proc near ;3.30 |
|||
;3.30 |
|||
PUSH AX ;SAVE ALL ;3.30 |
|||
PUSH DS ;3.30 |
|||
PUSH ES ;3.30 |
|||
PUSH BX ;3.30 |
|||
PUSH CX ;3.30 |
|||
PUSH DX ;3.30 |
|||
PUSH DI ;3.30 |
|||
PUSH SI ;3.30 |
|||
PUSH BP ;3.30 |
|||
;3.30 |
|||
;Currently ES -> stack code area ;3.30 |
|||
MOV AX, cs:[STACK_COUNT] ;defined in CS ;3.30 |
|||
MOV es:[STACKCOUNT], AX ;defined in STACK CODE AREA ;3.30 |
|||
MOV AX, [STACK_SIZE] ;in CS ;3.30 |
|||
MOV es:[STACKSIZE], AX ; ;3.30 |
|||
MOV AX, WORD PTR cs:[STACK_ADDR] ; OFFSET ;3.30 |
|||
MOV WORD PTR es:[STACKS], AX ;3.30 |
|||
MOV AX, WORD PTR cs:[STACK_ADDR+WORD] ; SEGMENT ;3.30 |
|||
MOV WORD PTR es:[STACKS+WORD], AX ;3.30 |
|||
;3.30 |
|||
; INITIALIZE THE DATA FIELDS WITH THE PARAMETERS ;3.30 |
|||
;3.30 |
|||
; "FIRSTENTRY" WILL ALWAYS BE AT STACKS ;3.30 |
|||
;3.30 |
|||
MOV BP, word ptr es:STACKS ; GET OFFSET OF STACK ;3.30 |
|||
MOV es:FIRSTENTRY,BP ;3.30 |
|||
;3.30 |
|||
; THE STACKS WILL ALWAYS IMMEDIATELY FOLLOW THE TABLE ENTRIES ;3.30 |
|||
;3.30 |
|||
MOV AX,ENTRYSIZE ;3.30 |
|||
MOV CX,es:STACKCOUNT ;3.30 |
|||
MUL CX ;3.30 |
|||
ADD AX,BP ;3.30 |
|||
MOV es:STACKAT,AX ;3.30 |
|||
MOV BX,AX ;3.30 |
|||
SUB BX,2 ;3.30 |
|||
;3.30 |
|||
; ZERO THE ENTIRE STACK AREA TO START WITH ;3.30 |
|||
;3.30 |
|||
MOV DI,es:STACKAT ;3.30 |
|||
MOV AX,es:STACKSIZE ;3.30 |
|||
MUL CX ;3.30 |
|||
MOV CX,AX ;3.30 |
|||
xor ax,ax ;3.30 |
|||
push es ;3.30 |
|||
pop ds ;ds = Relocated stack code seg.;3.30 |
|||
assume ds:nothing ;3.30 |
|||
;Now, DS -> stack code area ;3.30 |
|||
MOV ES, word ptr ds:[STACKS+2] ; GET SEGMENT OF STACK AREA.;3.30 |
|||
CLD ;3.30 |
|||
REP STOSB ;3.30 |
|||
;3.30 |
|||
MOV CX, ds:STACKCOUNT ;3.30 |
|||
;3.30 |
|||
; LOOP FOR "COUNT" TIMES, BUILDING A TABLE ENTRY ;3.30 |
|||
; cs = sysinitseg, ds = Relocated stack code seg , es = segment of stack space;3.30 |
|||
; CX = NUMBER OF ENTRIES ;3.30 |
|||
; ES:BP => BASE OF STACKS - 2 ;3.30 |
|||
; ES:BX => FIRST TABLE ENTRY ;3.30 |
|||
;3.30 |
|||
BUILDLOOP: ;3.30 |
|||
MOV ALLOCBYTE,FREE ;3.30 |
|||
MOV INTLEVEL,AL ;AX = 0 ;3.30 |
|||
MOV SAVEDSP,AX ;3.30 |
|||
MOV SAVEDSS,AX ;3.30 |
|||
ADD BX,ds:STACKSIZE ;3.30 |
|||
MOV NEWSP,BX ;3.30 |
|||
MOV ES:[BX],BP ;3.30 |
|||
ADD BP,ENTRYSIZE ;3.30 |
|||
;3.30 |
|||
LOOP BUILDLOOP ;3.30 |
|||
;3.30 |
|||
SUB BP,ENTRYSIZE ;3.30 |
|||
MOV ds:LASTENTRY,BP ;3.30 |
|||
MOV ds:NEXTENTRY,BP ;3.30 |
|||
;3.30 |
|||
push ds ;3.30 |
|||
mov ax, 0f000h ;loook at the model byte ;3.30 |
|||
mov ds, ax ;3.30 |
|||
cmp ds:byte ptr [0fffeh], 0f9h ;convertible?(P12) ;3.30 |
|||
pop ds ;3.30 |
|||
jne Skip_disableNMIS ;3.30 |
|||
;3.30 |
|||
MOV AL,07H ; DISABLE P12 NMIS ;3.30 |
|||
OUT 72H,AL ;3.30 |
|||
;3.30 |
|||
Skip_disableNMIS: ;3.30 |
|||
XOR AX,AX ;3.30 |
|||
MOV es,AX ;es - SEGID OF VECTOR TABLE AT 0;3.30 |
|||
ASSUME es:NOTHING ;ds - Relocated Stack code segment;3.30 |
|||
;3.30 |
|||
CLI ;3.30 |
|||
;3.30 |
|||
IRP AA,<02,08,09,70> ;3.30 |
|||
;3.30 |
|||
MOV SI,AA&H*4 ;PASS WHERE VECTOR IS TO BE ADJUSTED ;3.30 |
|||
mov di, offset Int19OLD&AA ;we have to set OLD&AA for Int19 handler too.;3.30 |
|||
MOV BX,OFFSET OLD&AA ;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30 |
|||
MOV DX,OFFSET INT&AA ;PASS WHERE NEW HANDLER IS ;3.30 |
|||
CALL NEW_INIT_LOOP ;ADJUST THE VECTOR TO NEW HANDLER, ;3.30 |
|||
; SAVING POINTER TO ORIGINAL OWNER ;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
IRP AA,<0A,0B,0C,0D,0E,72,73,74,76,77> ;shared interrupts ;3.30 |
|||
;3.30 |
|||
MOV SI,AA&H*4 ;PASS WHERE VECTOR IS TO BE ADJUSTED ;3.30 |
|||
push ds ;save relocated stack code segment ;3.30 |
|||
lds bx, es:[si] ;ds:bx -> original interrupt handler ;3.30 |
|||
push ds ;3.30 |
|||
pop dx ;dx = segment value ;3.30 |
|||
|
|||
cmp dx,0 |
|||
jz int&AA&_first |
|||
|
|||
cmp byte ptr ds:[bx],0cfh ;Does vector point to an IRET? |
|||
jz int&AA&_first |
|||
|
|||
cmp word ptr ds:[bx.6],424Bh ;Magic offset (see INT&AA, msstack.inc) |
|||
jz int&AA&_Not_first |
|||
|
|||
cmp dx,0f000h ;ROM BIOS segment |
|||
jnz int&AA&_Not_first |
|||
|
|||
push es |
|||
push dx |
|||
mov dx,0f000h |
|||
mov es,dx |
|||
cmp bx,word ptr es:0ff01h |
|||
pop dx |
|||
pop es |
|||
jz int&AA&_first |
|||
|
|||
int&AA&_Not_first: ;Not the first. We are going to hook vector.;3.30 |
|||
pop ds ;3.30 |
|||
mov di, offset Int19OLD&AA ;we have to set OLD&AA for Int19 handler too.;3.30 |
|||
mov BX, OFFSET OLD&AA ;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30 |
|||
MOV DX, OFFSET INT&AA ;PASS WHERE NEW HANDLER IS ;3.30 |
|||
CALL NEW_INIT_LOOP ;ADJUST THE VECTOR TO NEW HANDLER, SAVING;3.30 |
|||
;POINTER TO ORIGINAL OWNER. ;3.30 |
|||
jmp short int&AA&_end ;3.30 |
|||
int&AA&_first: ;the first. Don't have to hook stack code.;3.30 |
|||
pop ds ;3.30 |
|||
int&AA&_end: ;3.30 |
|||
;3.30 |
|||
ENDM ;3.30 |
|||
;3.30 |
|||
push ds ;3.30 |
|||
mov ax, 0f000h ;loook at the model byte ;3.30 |
|||
mov ds, ax ;3.30 |
|||
cmp ds:byte ptr [0fffeh], 0f9h ;convertible?(P12) ;3.30 |
|||
pop ds ;3.30 |
|||
jne Skip_EnableNMIS ;3.30 |
|||
;3.30 |
|||
MOV AL,27H ; ENABLE P12 NMIS ;3.30 |
|||
OUT 72H,AL ;3.30 |
|||
;3.30 |
|||
Skip_EnableNMIS: ;3.30 |
|||
STI ;3.30 |
|||
MOV AX,code ;3.30 |
|||
MOV DS,AX ;3.30 |
|||
ASSUME DS:CODE ;3.30 |
|||
;3.30 |
|||
; MOV SI,OFFSET STKMSG1 ;3.30 |
|||
; CALL WRMSG ;3.30 |
|||
;3.30 |
|||
mov [INT19SEM],1 ; INDICATE THAT INT 19 ;3.30 |
|||
; INITIALIZATION IS COMPLETE ;3.30 |
|||
;3.30 |
|||
POP BP ; RESTORE ALL ;3.30 |
|||
POP SI ;3.30 |
|||
POP DI ;3.30 |
|||
POP DX ;3.30 |
|||
POP CX ;3.30 |
|||
POP BX ;3.30 |
|||
;3.30 |
|||
POP ES ;3.30 |
|||
POP DS ;3.30 |
|||
assume ds:sysinitseg ;3.30 |
|||
POP AX ;3.30 |
|||
RET ;3.30 |
|||
STACKINIT ENDP ;3.30 |
|||
; ;3.30 |
|||
;3.30 |
|||
NEW_INIT_LOOP PROC NEAR ;3.30 |
|||
;INPUT: SI=OFSET INTO VECTOR TABLE OF THE PARTICULAR INT VECTOR BEING ADJUSTED ;3.30 |
|||
; BX=ds:OFFSET OF OLDxx, WHERE WILL BE SAVED THE POINTER TO ORIGINAL OWNER;3.30 |
|||
; DX=ds:OFFSET OF INTxx, THE NEW INTERRUPT HANDLER ;3.30 |
|||
; di=offset value of Int19OLD&AA variable in BIOS. ;3.30 |
|||
; es=ZERO, SEGID OF VECTOR TABLE ;3.30 |
|||
; ds=Relocated Stack code segment ;3.30 |
|||
;3.30 |
|||
MOV AX,es:[SI+0] ;REMEMBER OFFSET IN VECTOR ;3.30 |
|||
MOV WORD PTR ds:[BX],AX ; TO ORIGINAL OWNER in DS ;3.30 |
|||
MOV AX,es:[SI+2] ;REMEMBER SEGID IN VECTOR ;3.30 |
|||
MOV WORD PTR ds:[BX]+2,AX ; TO ORIGINAL OWNER in DS ;3.30 |
|||
push ds ;3.30 |
|||
mov ax, code ;3.30 |
|||
mov ds, ax ;Set Int19OLDxx value in BIOS for ;3.30 |
|||
mov ax,es:[si+0] ;Int 19 handler ;3.30 |
|||
mov word ptr ds:[di],ax ;3.30 |
|||
mov ax,es:[si+2] ;3.30 |
|||
mov word ptr ds:[di]+2,ax ;3.30 |
|||
pop ds ;3.30 |
|||
;3.30 |
|||
MOV WORD PTR es:[SI+0],DX ;SET VECTOR TO POINT TO NEW INT HANDLER ;3.30 |
|||
MOV es:[SI+2],ds ;3.30 |
|||
RET ;3.30 |
|||
NEW_INIT_LOOP ENDP ;3.30 |
|||
;3.30 |
@ -0,0 +1,6 @@ |
|||
PUBLIC FATAL_MSG ;3.30 |
|||
FATAL_MSG DB 0DH,0AH ;3.30 |
|||
DB 7,0DH,0AH ;3.30 |
|||
DB "Internal stack overflow",0DH,0AH ;3.30 |
|||
DB "System halted",0DH,0AH,"$" ;3.30 |
|||
; |
@ -0,0 +1,868 @@ |
|||
TITLE BIOS SYSTEM INITIALIZATION |
|||
TRUE EQU 0FFFFh |
|||
FALSE EQU 0 |
|||
|
|||
;IBMVER EQU TRUE |
|||
;IBM EQU IBMVER |
|||
STACKSW EQU TRUE ;Include Switchable Hardware Stacks |
|||
;IBMJAPVER EQU FALSE ;If TRUE set KANJI true also |
|||
;MSVER EQU FALSE |
|||
;ALTVECT EQU FALSE ;Switch to build ALTVECT version |
|||
;KANJI EQU FALSE |
|||
|
|||
INCLUDE version.inc |
|||
|
|||
IF IBMJAPVER |
|||
NOEXEC EQU TRUE |
|||
ELSE |
|||
NOEXEC EQU FALSE |
|||
ENDIF |
|||
|
|||
DOSSIZE EQU 0A000H |
|||
|
|||
.xlist |
|||
include smdossym.inc ; Reduced version of DOSSYM.INC ;3.30 |
|||
INCLUDE devsym.inc |
|||
include ioctl.inc |
|||
include BIOSTRUC.INC ;3.30 |
|||
.list |
|||
|
|||
IF NOT IBMJAPVER |
|||
EXTRN RE_INIT:FAR |
|||
ENDIF |
|||
|
|||
SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' |
|||
|
|||
ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING |
|||
|
|||
EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE,BADMEM:BYTE,BADBLOCK:BYTE |
|||
EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE |
|||
EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE |
|||
EXTRN BADSTACK:BYTE,BADCOUNTRYCOM:BYTE ;3.30 |
|||
EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE,INSUFMEMORY:BYTE ;3.30 |
|||
EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE,CONFIG:BYTE |
|||
EXTRN Cntry_Drv:BYTE,Cntry_Root:BYTE,Cntry_Path:BYTE ;3.30 |
|||
EXTRN DeviceParameters:byte ;3.30 |
|||
EXTRN MEMORY_SIZE:word ;3.30 |
|||
EXTRN BUFFERS:word ;3.30 |
|||
EXTRN FILES:byte,NUM_CDS:byte ;3.30 |
|||
EXTRN DOSINFO:dword,ENTRY_POINT:dword ;3.30 |
|||
EXTRN FCBS:byte,KEEP:byte ;3.30 |
|||
EXTRN CONFBOT:word,ALLOCLIM:word,COMMAND_LINE:byte ;3.30 |
|||
EXTRN ZERO:byte,SEPCHR:byte ;3.30 |
|||
EXTRN COUNT:word,CHRPTR:word,CNTRYFILEHANDLE:word ;3.30 |
|||
EXTRN MEMLO:word,MEMHI:word,PRMBLK:word,LDOFF:word ;3.30 |
|||
EXTRN PACKET:byte,UNITCOUNT:byte,BREAK_ADDR:dword ;3.30 |
|||
EXTRN BPB_ADDR:dword,DRIVENUMBER:byte,SYSI_COUNTRY:dword ;3.30 |
|||
;3.30 |
|||
EXTRN MEM_ERR:NEAR,SetDOSCountryInfo:NEAR ;3.30 |
|||
EXTRN PARAROUND:NEAR,TEMPCDS:NEAR ;3.30 |
|||
EXTRN Set_Country_Path:NEAR,Move_ASCIIZ:NEAR,DELIM:NEAR ;3.30 |
|||
EXTRN BADFIL:NEAR,ROUND:NEAR ;3.30 |
|||
|
|||
IF STACKSW |
|||
; |
|||
; Internal Stack Parameters |
|||
EntrySize equ 8 |
|||
|
|||
MinCount equ 8 |
|||
DefaultCount equ 9 |
|||
MaxCount equ 64 |
|||
|
|||
MinSize equ 32 |
|||
DefaultSize equ 128 |
|||
MaxSize equ 512 |
|||
|
|||
extrn stack_count:word ;3.30 |
|||
extrn stack_size:word ;3.30 |
|||
extrn stack_addr:dword ;3.30 |
|||
|
|||
ENDIF |
|||
|
|||
PUBLIC DOCONF ;3.30 |
|||
PUBLIC GETCHR ;3.30 |
|||
|
|||
;*************************************************************************;3.30 |
|||
;Take care of Config.sys file. ;3.30 |
|||
|
|||
DOCONF: |
|||
PUSH CS |
|||
POP DS |
|||
|
|||
ASSUME DS:SYSINITSEG |
|||
|
|||
MOV AX,(CHAR_OPER SHL 8) ;GET SWITCH CHARACTER |
|||
INT 21H |
|||
MOV [COMMAND_LINE+1],DL ; Set in default command line |
|||
|
|||
MOV DX,OFFSET CONFIG ;NOW POINTING TO FILE DESCRIPTION |
|||
MOV AX,OPEN SHL 8 ;OPEN FILE "CONFIG.SYS" |
|||
STC ;IN CASE OF INT 24 |
|||
INT 21H ;FUNCTION REQUEST |
|||
JC ENDCONF ;Wasn't there, or couldn't open ;3.30 |
|||
JMP NOPROB ;PROBLEM WITH OPEN |
|||
|
|||
ENDCONF: ;3.30 |
|||
return ;3.30 |
|||
|
|||
|
|||
BADOP: MOV DX,OFFSET BADOPM ;WANT TO PRINT COMMAND ERROR |
|||
invoke PRINT |
|||
JMP COFF |
|||
|
|||
NOPROB: ;GET FILE SIZE (NOTE < 64K!!) |
|||
MOV BX,AX |
|||
XOR CX,CX |
|||
XOR DX,DX |
|||
MOV AX,(LSEEK SHL 8) OR 2 |
|||
INT 21H |
|||
MOV [COUNT],AX |
|||
XOR DX,DX |
|||
MOV AX,LSEEK SHL 8 ;Reset pointer to beginning of file |
|||
INT 21H |
|||
MOV DX,CS |
|||
MOV AX,[COUNT] |
|||
call ParaRound |
|||
SUB DX,AX |
|||
SUB DX,11H ;ROOM FOR HEADER |
|||
MOV [CONFBOT],DX ; Config starts here |
|||
CALL TEMPCDS ; Finally get CDS to "safe" location |
|||
ASSUME DS:NOTHING,ES:NOTHING |
|||
|
|||
MOV DX,[CONFBOT] |
|||
MOV DS,DX |
|||
MOV ES,DX |
|||
XOR DX,DX |
|||
MOV CX,[COUNT] |
|||
MOV AH,READ |
|||
STC ;IN CASE OF INT 24 |
|||
INT 21H ;Function request |
|||
PUSHF |
|||
; |
|||
; Find the EOF mark in the file. If present, then trim length. |
|||
; |
|||
SaveReg <AX,DI,CX> |
|||
MOV AL,1Ah ; eof mark |
|||
MOV DI,DX ; point ro buffer |
|||
JCXZ PutEOL ; no chars |
|||
REPNZ SCASB ; find end |
|||
JNZ PutEOL ; none found and count exahusted |
|||
; |
|||
; We found a 1A. Back up |
|||
; |
|||
DEC DI ; backup past 1A |
|||
; |
|||
; Just for the halibut, stick in an extra EOL |
|||
; |
|||
PutEOL: |
|||
MOV AL,13 |
|||
STOSB ; CR |
|||
MOV AL,10 |
|||
STOSB ; LF |
|||
SUB DI,DX ; difference moved |
|||
MOV Count,DI ; new count |
|||
; |
|||
; Restore registers |
|||
; |
|||
RestoreReg <CX,DI,AX> |
|||
|
|||
PUSH CS |
|||
POP DS |
|||
ASSUME DS:SYSINITSEG |
|||
PUSH AX |
|||
MOV AH,CLOSE |
|||
INT 21H |
|||
POP AX |
|||
POPF |
|||
JC CONFERR ;IF NOT WE'VE GOT A PROBLEM |
|||
CMP CX,AX |
|||
JZ GETCOM ;COULDN'T READ THE FILE |
|||
CONFERR: |
|||
MOV DX,OFFSET CONFIG ;WANT TO PRINT CONFIG ERROR |
|||
CALL BADFIL |
|||
ENDCONV:JMP ENDCONF ;3.30 |
|||
|
|||
GETCOM: |
|||
invoke ORGANIZE ;ORGANIZE THE FILE |
|||
CALL GETCHR |
|||
|
|||
CONFLP: JC ENDCONV ;3.30 |
|||
MOV AH,AL |
|||
CALL GETCHR |
|||
JNC TryB |
|||
JMP BADOP |
|||
|
|||
COFF: PUSH CS |
|||
POP DS |
|||
invoke NEWLINE |
|||
JMP CONFLP |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Buffer command |
|||
;------------------------------------------------------------------------------ |
|||
TryB: CMP AH,'B' ;BUFFER COMMAND? |
|||
JNZ TRYC |
|||
invoke GETNUM |
|||
JZ TryBBad ; Gotta have at least one |
|||
CMP AX,100 ; check for max number |
|||
JB SaveBuf |
|||
TryBBad:JMP BadOp |
|||
SaveBuf: |
|||
MOV [BUFFERS],AX |
|||
CoffJ1: JMP COFF |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Break command |
|||
;------------------------------------------------------------------------------ |
|||
TryC: CMP AH,'C' |
|||
JZ GOTC |
|||
JMP TRYD |
|||
GOTC: |
|||
CMP AL,'O' ;FIRST LETTER OF "ON" or "OFF" |
|||
JNZ TryCBad |
|||
CALL GETCHR |
|||
JC TryCBad |
|||
CMP AL,'N' ;SECOND LETTER OF "ON" |
|||
JNZ TryCoff |
|||
MOV AH,SET_CTRL_C_TRAPPING ;TURN ON CONTROL-C CHECK |
|||
MOV AL,1 |
|||
MOV DL,AL |
|||
INT 21H |
|||
CoffJ2: JMP Coff |
|||
TryCOff:CMP AL,'F' |
|||
JNZ TryCBad ; Check for "OFF" |
|||
CALL GetChr |
|||
JC TryCBad |
|||
CMP AL,'F' |
|||
JZ COffJ2 |
|||
TryCBad:JMP BadOp |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Device command |
|||
;------------------------------------------------------------------------------ |
|||
TRYD: CMP AH,'D' |
|||
JZ GOTD |
|||
JMP TRYQ |
|||
GOTD: MOV BX,CS |
|||
MOV DS,BX |
|||
|
|||
MOV WORD PTR [BPB_ADDR],SI |
|||
MOV WORD PTR [BPB_ADDR+2],ES |
|||
|
|||
CALL ROUND |
|||
XOR AX,AX |
|||
MOV WORD PTR [ENTRY_POINT],AX |
|||
MOV AX,[MEMHI] |
|||
MOV WORD PTR [ENTRY_POINT+2],AX ;SET ENTRY POINT |
|||
|
|||
IF NOT NOEXEC |
|||
MOV [LDOFF],AX ;SET LOAD OFFSET |
|||
ENDIF |
|||
|
|||
PUSH ES |
|||
POP DS |
|||
ASSUME DS:NOTHING |
|||
MOV DX,SI ;DS:DX POINTS TO FILE NAME |
|||
|
|||
IF NOEXEC |
|||
LES BX,DWORD PTR CS:[MEMLO] |
|||
CALL LDFIL ;LOAD IN THE DEVICE DRIVER |
|||
ELSE |
|||
; We are going to open the cdevice driver and size it as is done |
|||
; in LDFIL. The reason we must do this is that EXEC does NO checking |
|||
; for us. We must make sure there is room to load the device without |
|||
; trashing SYSINIT. This code is not |
|||
; perfect (for instance .EXE device drivers are possible) because |
|||
; it does its sizing based on the assumption that the file being loaded |
|||
; is a .COM file. It is close enough to correctness to be usable. |
|||
MOV ES,AX ;ES:0 is LOAD addr |
|||
MOV AX,OPEN SHL 8 ;OPEN THE FILE |
|||
STC ;IN CASE OF INT 24 |
|||
INT 21H |
|||
JC BADLDRESET |
|||
MOV BX,AX ;Handle in BX |
|||
PUSH DX ; Save pointer to name |
|||
XOR CX,CX |
|||
XOR DX,DX |
|||
MOV AX,(LSEEK SHL 8) OR 2 |
|||
STC ;IN CASE OF INT 24 |
|||
INT 21H ; Get file size in DX:AX |
|||
JNC GO_AHEAD_LOAD |
|||
MOV AH,CLOSE ; Close file |
|||
INT 21H |
|||
POP DX ; Clean stack |
|||
STC ; Close may clear carry |
|||
JMP SHORT BADLDRESET |
|||
|
|||
GO_AHEAD_LOAD: |
|||
; Convert size in DX:AX to para in AX |
|||
ADD AX,15 ; Round up size for conversion to para |
|||
ADC DX,0 |
|||
MOV CL,4 |
|||
SHR AX,CL |
|||
MOV CL,12 |
|||
SHL DX,CL ; Low nibble of DX to high nibble |
|||
OR AX,DX ; AX is now # of para for file |
|||
|
|||
MOV CX,ES ; CX:0 is xaddr |
|||
ADD CX,AX ; New device will take up to here |
|||
JC MEM_ERRJY ; WOW!!!! |
|||
CMP CX,CS:[ALLOCLIM] |
|||
JB OKLDX |
|||
MEM_ERRJY: |
|||
JMP MEM_ERR |
|||
|
|||
OKLDX: |
|||
POP DX ; Recover name pointer |
|||
MOV AH,CLOSE ; Close file |
|||
INT 21H |
|||
MOV BX,CS |
|||
MOV ES,BX |
|||
MOV BX,OFFSET PRMBLK ;ES:BX POINTS TO PARAMETERS |
|||
MOV AL,3 |
|||
MOV AH,EXEC |
|||
STC ;IN CASE OF INT 24 |
|||
INT 21H ;LOAD IN THE DEVICE DRIVER |
|||
ENDIF |
|||
|
|||
BADLDRESET: |
|||
PUSH DS |
|||
POP ES ;ES:SI BACK TO CONFIG.SYS |
|||
PUSH CS |
|||
POP DS ;DS BACK TO SYSINIT |
|||
ASSUME DS:SYSINITSEG |
|||
JNC GOODLD |
|||
BADBRK: |
|||
cmp byte ptr es:[si], 13 ;file name is CR? ;3.30 |
|||
jne BADBRK_1 ;(entered "device=" without filename);3.30 ;3.30 |
|||
jmp BADOP ;"Unrecognized command in CONFIG.SYS";3.30 |
|||
BADBRK_1: ;3.30 |
|||
invoke BADLOAD |
|||
JMP COFF |
|||
|
|||
GOODLD: SaveReg <ES,SI> ;INITIALIZE THE DEVICE |
|||
Restore:MOV BL,ES:[SI] ; while ((c=*p) != 0) |
|||
OR BL,BL |
|||
JZ Got |
|||
INC SI ; p++; |
|||
JMP Restore |
|||
Got: MOV BYTE PTR ES:[SI],' ' ; *p = ' '; |
|||
SaveReg <ES,SI> |
|||
PUSH CS |
|||
POP ES |
|||
MOV BX,SDEVSTRAT |
|||
invoke CALLDEV ; CallDev (SDevStrat); |
|||
MOV BX,SDEVINT |
|||
invoke CALLDEV ; CallDev (SDevInt); |
|||
RestoreReg <SI,DS> |
|||
MOV BYTE PTR [SI],0 ; *p = 0; |
|||
|
|||
PUSH CS |
|||
POP DS |
|||
MOV AX,WORD PTR [BREAK_ADDR+2] |
|||
CMP AX,[MEMORY_SIZE] |
|||
JB BREAKOK |
|||
POP SI |
|||
POP ES |
|||
JMP BADBRK |
|||
|
|||
BREAKOK: |
|||
LDS DX,[ENTRY_POINT] ;SET DS:DX TO HEADER |
|||
MOV SI,DX |
|||
ADD SI,SDEVATT ;DS:SI POINTS TO ATTRIBUTES |
|||
LES DI,CS:[DOSINFO] ;ES:DI POINT TO DOS INFO |
|||
MOV AX,DS:[SI] ;GET ATTRIBUTES |
|||
TEST AX,DEVTYP ;TEST IF BLOCK DEV |
|||
JZ ISBLOCK |
|||
invoke SET_BREAK ; Go ahead and alloc mem for device |
|||
jc Erase_Dev ;dev driver's Init routine failed ;3.30 |
|||
TEST AX,ISCIN ;IS IT A CONSOLE IN? |
|||
JZ TRYCLK |
|||
MOV WORD PTR ES:[DI.SYSI_CON],DX |
|||
MOV WORD PTR ES:[DI.SYSI_CON+2],DS |
|||
|
|||
TRYCLK: TEST AX,ISCLOCK ;IS IT A CLOCK DEVICE? |
|||
JZ GOLINK |
|||
MOV WORD PTR ES:[DI+SYSI_CLOCK],DX |
|||
MOV WORD PTR ES:[DI+SYSI_CLOCK+2],DS |
|||
GOLINK: JMP LINKIT |
|||
|
|||
ISBLOCK: |
|||
MOV AL,CS:[UNITCOUNT] ;IF NO UNITS FOUND, erase the device |
|||
OR AL,AL |
|||
JNZ PERDRV |
|||
ERASE_DEV: |
|||
MOV AX,-1 ; No call to SET_BREAK yet, so no alloc |
|||
JMP ENDDEV |
|||
|
|||
PERDRV: |
|||
CBW ; WARNING NO DEVICE > 127 UNITS |
|||
MOV CX,AX |
|||
MOV DH,AH |
|||
MOV DL,ES:[DI.SYSI_NUMIO] ;GET NUMBER OF DEVICES |
|||
MOV AH,DL |
|||
ADD AH,AL ; Check for too many devices |
|||
CMP AH,26 ; 'A' - 'Z' is 26 devices |
|||
JBE OK_BLOCK |
|||
PUSH CS |
|||
POP DS |
|||
MOV DX,OFFSET BADBLOCK |
|||
invoke PRINT |
|||
JMP ERASE_DEV |
|||
|
|||
OK_BLOCK: |
|||
invoke SET_BREAK ; Alloc the device |
|||
ADD ES:[DI.SYSI_NUMIO],AL ;UPDATE THE AMOUNT |
|||
ADD CS:DriveNumber,AL ; remember amount for next device |
|||
LDS BX,CS:[BPB_ADDR] ;POINT TO BPB ARRAY |
|||
PERUNIT: |
|||
LES BP,CS:[DOSINFO] |
|||
LES BP,DWORD PTR ES:[BP.SYSI_DPB] ;GET FIRST DPB |
|||
|
|||
SCANDPB:CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1 |
|||
JZ FOUNDPB |
|||
LES BP,ES:[BP.DPB_NEXT_DPB] |
|||
JMP SCANDPB |
|||
FOUNDPB: |
|||
MOV AX,CS:[MEMLO] |
|||
MOV WORD PTR ES:[BP.DPB_NEXT_DPB],AX |
|||
MOV AX,CS:[MEMHI] |
|||
MOV WORD PTR ES:[BP.DPB_NEXT_DPB+2],AX |
|||
LES BP,DWORD PTR CS:[MEMLO] |
|||
ADD WORD PTR CS:[MEMLO],DPBSIZ |
|||
CALL ROUND ;Check for alloc error |
|||
MOV WORD PTR ES:[BP.DPB_NEXT_DPB],-1 |
|||
MOV ES:[BP.DPB_FIRST_ACCESS],-1 |
|||
|
|||
MOV SI,[BX] ;DS:SI POINTS TO BPB |
|||
INC BX |
|||
INC BX ;POINT TO NEXT GUY |
|||
MOV WORD PTR ES:[BP.DPB_DRIVE],DX |
|||
MOV AH,SETDPB ;HIDDEN SYSTEM CALL |
|||
INT 21H |
|||
MOV AX,ES:[BP.DPB_SECTOR_SIZE] ;3.30 |
|||
PUSH ES ;3.30 |
|||
LES DI,CS:[DOSINFO] ;ES:DI POINT TO DOS INFO ;3.30 |
|||
CMP AX,ES:[DI.SYSI_MAXSEC] ;3.30 |
|||
POP ES ;3.30 |
|||
JBE NOTMAX ;3.30 |
|||
POP SI ;3.30 |
|||
POP ES ;3.30 |
|||
MOV DX,OFFSET BADSIZ_PRE ;3.30 |
|||
MOV BX,OFFSET BADSIZ_POST ;3.30 |
|||
invoke PRNERR ;3.30 |
|||
JMP COFF ;3.30 |
|||
|
|||
NOTMAX: PUSH DS |
|||
PUSH DX |
|||
LDS DX,CS:[ENTRY_POINT] |
|||
MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR],DX |
|||
MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR+2],DS |
|||
POP DX |
|||
POP DS |
|||
INC DX |
|||
INC DH |
|||
LOOP PERUNIT |
|||
PUSH CS |
|||
POP DS |
|||
CALL TEMPCDS ; Set CDS for new drives |
|||
|
|||
LINKIT: |
|||
LES DI,CS:[DOSINFO] ;ES:DI = DOS TABLE |
|||
MOV CX,WORD PTR ES:[DI.SYSI_DEV] ;DX:CX = HEAD OF LIST |
|||
MOV DX,WORD PTR ES:[DI.SYSI_DEV+2] |
|||
|
|||
LDS SI,CS:[ENTRY_POINT] ;DS:SI = DEVICE LOCATION |
|||
MOV WORD PTR ES:[DI.SYSI_DEV],SI ;SET HEAD OF LIST IN DOS |
|||
MOV WORD PTR ES:[DI.SYSI_DEV+2],DS |
|||
MOV AX,DS:[SI] ;GET POINTER TO NEXT DEVICE |
|||
MOV WORD PTR CS:[ENTRY_POINT],AX ;AND SAVE IT |
|||
|
|||
MOV WORD PTR DS:[SI],CX ;LINK IN THE DRIVER |
|||
MOV WORD PTR DS:[SI+2],DX |
|||
ENDDEV: |
|||
POP SI |
|||
POP ES |
|||
INC AX ;AX = FFFF (no more devs if YES)? |
|||
JZ COFFJ3 |
|||
JMP GOODLD ;OTHERWISE PRETEND WE LOADED IT IN |
|||
COFFJ3: JMP COFF |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Country command |
|||
; The syntax is: ;3.30 |
|||
; COUNTRY=country id {,codepage {,path}} ;3.30 |
|||
; COUNTRY=country id {,,path} :Default CODEPAGE ID in DOS ;3.30 |
|||
;------------------------------------------------------------------------------ |
|||
TRYQ: |
|||
CMP AH,'Q' ;3.30 |
|||
JZ TRYQ_CONT ;3.30 |
|||
JMP TRYF ;3.30 |
|||
TRYQ_CONT: ;3.30 |
|||
invoke GETNUM ;3.30 |
|||
JZ TryQBad ; 0 is never a valid code, or number is;3.30 |
|||
; bad ;3.30 |
|||
MOV BX,AX ; Country code in BX ;3.30 |
|||
;3.30 |
|||
; 5/26/86 ;3.30 |
|||
MOV DX,0 ; assume no code page id ;3.30 |
|||
;3.30 |
|||
invoke skip_delim ;skip the delimeters after the first nu;3.30m |
|||
jc TryQ_Def_File ;no more characters left? then use defa;3.30ult file |
|||
cmp al, 13 ; ;3.30 |
|||
je TryQ_Def_File ;3.30 |
|||
cmp al, 10 ;3.30 |
|||
jne TRYQ_YES_EXTENDED ;3.30 |
|||
inc [COUNT] ;This is for NEWLINE routine in COFF. ;3.30 |
|||
dec [CHRPTR] ;3.30 |
|||
COFFJ41: ;3.30 |
|||
JMP TryQ_Def_File ;O.K. no code page, no path specified. ;3.30Use default path. |
|||
;3.30 |
|||
TRYQ_YES_EXTENDED: ;3.30 |
|||
cmp al, ',' ;was the second comma? ;3.30 |
|||
jne TryQ_GETNUM ;3.30 |
|||
invoke skip_delim ;Yes, skip ',' and other possible delim;3.30 |
|||
jmp short TRYQ_PATH ;and No code page id entered. ;3.30 |
|||
TRYQ_GETNUM: ;3.30 |
|||
invoke GETNUM ;3.30 |
|||
jc TryQBadCOM ;"Country=xxx,path" will not be accepte;3.30d. |
|||
; jc TRYQ_PATH ;Codepage is not specified. No code pag;3.30e. |
|||
; ;At this point, AL already contain the ;3.30 |
|||
; ;first char of the PATH. ;3.30 |
|||
jz TryQBad ;codepage=0 entered. Error ;3.30 |
|||
mov DX, AX ;save code page in DX ;3.30 |
|||
invoke skip_delim ;move CHRPTR to the path string ;3.30 |
|||
jc TryQ_Def_File ;no more char? then use default filenam;3.30e |
|||
cmp al, 13 ;3.30 |
|||
je TryQ_Def_File ;3.30 |
|||
cmp al, 10 ;3.30 |
|||
jne TryQ_PATH ;path entered. ;3.30 |
|||
inc [COUNT] ;3.30 |
|||
dec [CHRPTR] ;3.30 |
|||
TryQ_Def_File: ;3.30 |
|||
push dx ;save code page ;3.30 |
|||
mov cs:CNTRY_DRV, 0 ;flag that the default path has been us;3.30ed!!! |
|||
mov dx, offset CNTRY_ROOT ;the default path ;3.30 |
|||
jmp TRYQ_OPEN ;3.30 |
|||
;3.30 |
|||
TryQBad: ;"Invalid country code or code page" ;3.30 |
|||
STC ;3.30 |
|||
MOV DX,OFFSET BADCOUNTRY ;3.30 |
|||
jmp TryQChkErr ;3.30 |
|||
;3.30 |
|||
TryQBadCOM: ;Error in COUNTRY command ;3.30 |
|||
STC ;3.30 |
|||
MOV DX,OFFSET BADCOUNTRYCOM ;3.30 |
|||
jmp TryQChkErr ;3.30 |
|||
;3.30 |
|||
TRYQ_PATH: ;DS - sysinitseg, ES - CONFBOT, ;3.30 |
|||
mov CX, [COUNT] ;AL - the first char of path ;3.30 |
|||
inc CX ;BX - country id, DX - codepage id, 0 =;3.30 No code page |
|||
mov DI, SI ;3.30 |
|||
TRYQ_PATH_LOOP: ;find the end of path to put 0 after th;3.30at. |
|||
mov AL, byte ptr ES:[DI] ;3.30 |
|||
call delim ;3.30 |
|||
jz TRYQ_PATH_END ;3.30 |
|||
cmp al, 13 ;3.30 |
|||
jz TRYQ_PATH_END ;3.30 |
|||
inc DI ;3.30 |
|||
jmp short TRYQ_PATH_LOOP ;3.30 |
|||
TryQBad_Brg:jmp short TryQBad ;3.30 |
|||
TRYQ_PATH_END: ;3.30 |
|||
mov es:byte ptr [di], 0 ;make it a ASCIIZ string. (Organize did;3.30 not handle this string) |
|||
push ds ;switch ds,es ;3.30 |
|||
push es ;3.30 |
|||
pop ds ;3.30 |
|||
pop es ;3.30 |
|||
;3.30 |
|||
mov di, offset CNTRY_DRV ;move the user specified path to CNTRY_;3.30DRV |
|||
call Move_ASCIIZ ;3.30 |
|||
;3.30 |
|||
push ds ;restore ds,es ;3.30 |
|||
push es ;3.30 |
|||
pop ds ;3.30 |
|||
pop es ;3.30 |
|||
;3.30 |
|||
; call Set_Country_Path ;set CNTRY_DRV ;3.30 |
|||
;3.30 |
|||
push dx ;save DX ;3.30 |
|||
mov dx, offset CNTRY_DRV ;Now DS:DX -> CNTRY_DRV ;3.30 |
|||
TRYQ_OPEN: ;3.30 |
|||
mov ax, 3d00h ;open a file ;3.30 |
|||
stc ;3.30 |
|||
int 21h ;3.30 |
|||
pop dx ;restore codepage id ;3.30 |
|||
jc TryQFileBad ;open failure ;3.30 |
|||
;3.30 |
|||
mov cs:CntryFileHandle, ax ;save file handle ;3.30 |
|||
xchg ax, bx ;now, AX = country id, BX = file handle;3.30 |
|||
mov cx, cs:[MEMHI] ;3.30 |
|||
add cx, 128 ;I need 2K buffer to handle COUNTRY.SYS;3.30 |
|||
cmp cx, cs:[ALLOCLIM] ;3.30 |
|||
ja TryQMemory ;cannot allocate the buffer for country;3.30.sys |
|||
;3.30 |
|||
mov si, offset CNTRY_DRV ;DS:SI -> CNTRY_DRV ;3.30 |
|||
cmp byte ptr [si],0 ;default path? ;3.30 |
|||
jne TRYQ_Set_for_DOS ;3.30 |
|||
inc si ;3.30 |
|||
inc si ;DS:SI -> CNTRY_ROOT ;3.30 |
|||
TRYQ_Set_for_DOS: ;3.30 |
|||
les di, cs:SYSI_Country ;ES:DI -> country info tab in DOS ;3.30 |
|||
push di ;save di ;3.30 |
|||
add di, ccPath_CountrySys ;3.30 |
|||
call MOVE_ASCIIZ ;Set the path to COUNTRY.SYS in DOS. ;3.30 |
|||
pop di ;ES:DI -> country info tab again. ;3.30 |
|||
mov cx, cs:[MEMHI] ;3.30 |
|||
mov ds, cx ;3.30 |
|||
xor si, si ;DS:SI -> 2K buffer to be used. ;3.30 |
|||
call SetDOSCountryInfo ;now do the job!!! ;3.30 |
|||
jnc TryQchkERR ;read error or could not find country,c;3.30ode page combination |
|||
cmp cx, -1 ;Could not find matching country_id,cod;3.30e page? |
|||
je TryQBad_Brg ;then "Invalid country code or code pag;3.30e" |
|||
TryQFileBad: ;3.30 |
|||
cmp cs:CNTRY_DRV,0 ;Is the default file used? ;3.30 |
|||
je TryQDefBad ;3.30 |
|||
mov si, cs:[CONFBOT] ;3.30 |
|||
mov es, si ;3.30 |
|||
mov si, cs:[CHRPTR] ;3.30 |
|||
dec si ;ES:SI -> path in CONFBOT ;3.30 |
|||
jmp short TryQBADLOAD ;3.30 |
|||
TryQDefBad: ;Default file has been used. ;3.30 |
|||
push cs ;3.30 |
|||
pop es ;3.30 |
|||
mov si, offset CNTRY_ROOT ;ES:SI -> \COUNTRY.SYS in SYSINIT_SEG ;3.30 |
|||
TryQBADLOAD: ;3.30 |
|||
call BADLOAD ;DS will be restored to SYSINIT_SEG ;3.30 |
|||
mov cx, cs:[CONFBOT] ;3.30 |
|||
mov es, cx ;Restore ES -> CONFBOT. ;3.30 |
|||
jmp short CoffJ4 ;3.30 |
|||
TryQMemory: ;3.30 |
|||
MOV DX,OFFSET INSUFMEMORY ;3.30 |
|||
TryQChkErr: ;3.30 |
|||
mov cx, cs:[CONFBOT] ;3.30 |
|||
mov es, cx ;restore ES -> CONFBOT seg ;3.30 |
|||
push cs ;3.30 |
|||
pop ds ;retore DS to SYSINIT_SEG ;3.30 |
|||
jnc CoffJ4 ;if no error, then exit ;3.30 |
|||
invoke PRINT ;else show error message ;3.30 |
|||
CoffJ4: ;3.30 |
|||
mov bx, CntryFileHandle ;3.30 |
|||
mov ah, 3eh ;3.30 |
|||
int 21h ;close a file. Don't care even if it fa;3.30ils. |
|||
JMP COFF ;3.30 |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Files command |
|||
;------------------------------------------------------------------------------ |
|||
TRYF: |
|||
CMP AH,'F' |
|||
JNZ TRYL |
|||
invoke GETNUM |
|||
CMP AX,5 |
|||
JB TryFBad ; Gotta have at least 5 |
|||
CMP AX,256 |
|||
JAE TryFBad ; Has to be a byte |
|||
MOV [FILES],AL |
|||
CoffJ5: JMP COFF |
|||
TryFBad:JMP BadOp |
|||
;------------------------------------------------------------------------------ |
|||
; LastDrive command |
|||
;------------------------------------------------------------------------------ |
|||
TRYL: |
|||
CMP AH,'L' |
|||
JNZ TRYP |
|||
OR AL,020h |
|||
SUB AL,'a' |
|||
JB TryLBad |
|||
INC AL |
|||
CMP AL,26 ; a-z are allowed |
|||
JA TryLBad |
|||
MOV [NUM_CDS],AL |
|||
CoffJ6: JMP COFF |
|||
TryLBad:JMP BadOp |
|||
;------------------------------------------------------------------------------- |
|||
; Setting Drive Parameters |
|||
;------------------------------------------------------------------------------- |
|||
TRYP: |
|||
CMP AH,'P' |
|||
JNZ TRYK |
|||
invoke PARSELINE |
|||
JC TryLBad |
|||
invoke SETPARMS |
|||
INVOKE DIDDLEBACK |
|||
jc TryLBad |
|||
JMP COFF |
|||
;------------------------------------------------------------------------------- |
|||
; Setting Internal Stack Parameters |
|||
; STACK=M,N where |
|||
; M is the number of stacks (range 8 to 64, default 9) |
|||
; N is the stack size (range 32 to 512 bytes, default 128) |
|||
; 5/5/86: STACKS=0,0 implies no stack installation. ;3.30 |
|||
; Any combinations that are not within the specified limits will ;3.30 |
|||
; result in "Unrecognized command" error. ;3.30 |
|||
;------------------------------------------------------------------------------- |
|||
TRYK: |
|||
CMP AH,'K' |
|||
JNZ TRYW |
|||
|
|||
IF STACKSW ;3.30 |
|||
|
|||
MOV SepChr,',' |
|||
INVOKE GetNum ; Get number of stacks |
|||
MOV SepChr,0 |
|||
cmp ax, 0 ; 5/5/86 ;3.30 |
|||
je TRYK_0 ; Let's accept 0. ;3.30 |
|||
CMP AX, MinCount ; 8 <= Number of Stacks <= 64 |
|||
JB TryKBad |
|||
CMP AX, MaxCount |
|||
JA TryKBad |
|||
TRYK_0: ;3.30 |
|||
MOV [STACK_COUNT], AX |
|||
; |
|||
; Skip delimiters after the , |
|||
; |
|||
invoke Skip_delim ; ;3.30 |
|||
JC TryKBad |
|||
|
|||
INVOKE GetNum ; Get size of individual stack |
|||
JC TryKBad ; Number bad |
|||
|
|||
cmp ax, 0 ; 5/5/86 ;3.30 |
|||
je TRYK_SIZE0 ; 5/5/86. Accept 0 ;3.30 |
|||
|
|||
CMP AX, MinSize ; 32 <= Stack Size <= 512 |
|||
JB TryKBad |
|||
CMP AX, MaxSize |
|||
JA TryKBad |
|||
TRYK_SIZE0: ;3.30 |
|||
MOV [STACK_SIZE], AX |
|||
cmp ax,0 ;3.30 |
|||
je TRYK_BOTH0 ;3.30 |
|||
TRYK_OK: ;3.30 |
|||
mov word ptr [stack_addr], -1 ;set flag. user entered stacks= ;3.30 |
|||
JMP COFF |
|||
TRYK_BOTH0: ;3.30 |
|||
cmp [STACK_COUNT],0 ;stack_size=0. Stack_Count=0 too? ;3.30 |
|||
je TRYK_OK ;yes. accepted. ;3.30 |
|||
TryKBad: |
|||
MOV DX, OFFSET BADSTACK ; 5/26/86 "Invalid stack parameter";3.30 |
|||
invoke PRINT ;3.30 |
|||
JMP COFF ;3.30 |
|||
|
|||
ENDIF ;3.30 |
|||
;------------------------------------------------------------------------------ |
|||
; Switch command |
|||
;------------------------------------------------------------------------------ |
|||
TRYW: |
|||
CMP AH,'W' |
|||
JNZ TRYA |
|||
JMP BadOp ; no longer implemented |
|||
; MOV DL,AL |
|||
; MOV AX,(CHAR_OPER SHL 8) OR 1 ;SET SWITCH CHARACTER |
|||
; MOV [COMMAND_LINE+1],DL |
|||
; INT 21H |
|||
; JMP COFF |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Availdev command |
|||
;------------------------------------------------------------------------------ |
|||
TRYA: |
|||
CMP AH,'A' |
|||
JNZ TRYS |
|||
JMP BadOp ; NO LONGER IMPLEMENTED |
|||
; CMP AL,'F' ;FIRST LETTER OF "FALSE" |
|||
; JNZ COFFJ7 |
|||
; MOV AX,(CHAR_OPER SHL 8) OR 3 ;TURN ON "/DEV" PREFIX |
|||
; XOR DL,DL |
|||
; INT 21H |
|||
;COFFJ7: JMP COFF |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; shell command |
|||
;------------------------------------------------------------------------------ |
|||
TRYS: |
|||
CMP AH,'S' |
|||
JNZ TRYX |
|||
MOV [COMMAND_LINE+1],0 |
|||
MOV DI,OFFSET COMMND + 1 |
|||
MOV [DI-1],AL |
|||
STORESHELL: |
|||
CALL GETCHR |
|||
OR AL,AL |
|||
JZ GETSHPARMS |
|||
CMP AL," " |
|||
JB ENDSH |
|||
MOV [DI],AL |
|||
INC DI |
|||
JMP STORESHELL |
|||
|
|||
ENDSH: |
|||
MOV BYTE PTR [DI],0 |
|||
CALL GETCHR |
|||
CMP AL,10 |
|||
JNZ CONV |
|||
CALL GETCHR |
|||
CONV: JMP CONFLP |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; FCBS Command |
|||
;------------------------------------------------------------------------------ |
|||
TRYX: |
|||
CMP AH,'X' |
|||
JNZ TRYZ |
|||
invoke GETNUM |
|||
JZ TryXBad ; gotta have at least one |
|||
CMP AX,256 |
|||
JAE TryXBad ; Can't be more than 8 bits worth |
|||
MOV [FCBS],AL |
|||
; |
|||
; Skip delimiters after the , |
|||
; |
|||
invoke Skip_delim ; ;3.30 |
|||
jc tryxbad |
|||
invoke GetNum |
|||
JC TryXBad ; Number bad (Zero is OK here) |
|||
CMP AX,256 |
|||
JAE TryXBad |
|||
CMP AL,FCBS |
|||
JA TryXBad |
|||
MOV Keep,AL |
|||
JMP COFF |
|||
TryXBad:JMP BadOp |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Bogus command |
|||
;------------------------------------------------------------------------------ |
|||
TRYZ: |
|||
JMP BADOP |
|||
|
|||
GETSHPARMS: |
|||
MOV BYTE PTR [DI],0 |
|||
MOV DI,OFFSET COMMAND_LINE+1 |
|||
PARMLOOP: |
|||
CALL GETCHR |
|||
CMP AL," " |
|||
JB ENDSH |
|||
MOV [DI],AL |
|||
INC DI |
|||
JMP PARMLOOP |
|||
|
|||
GETCHR: |
|||
PUSH CX |
|||
MOV CX,COUNT |
|||
JCXZ NOCHAR |
|||
MOV SI,CHRPTR |
|||
MOV AL,ES:[SI] |
|||
DEC COUNT |
|||
INC CHRPTR |
|||
CLC |
|||
GET_RET: |
|||
POP CX |
|||
return |
|||
NOCHAR: STC |
|||
JMP SHORT GET_RET |
|||
|
|||
|
|||
SYSINITSEG ENDS |
|||
END |
|||
|
@ -0,0 +1,18 @@ |
|||
TEST = 0 ;3.30 |
|||
include msequ.inc ;3.30 |
|||
include msmacro.inc ;3.30 |
|||
;3.30 |
|||
SYSINITSEG SEGMENT PUBLIC BYTE 'SYSTEM_INIT' ;3.30 |
|||
;3.30 |
|||
PUBLIC BADOPM,CRLFM,BADSIZ_PRE,BADLD_PRE,BADCOM,SYSSIZE,BADCOUNTRY ;3.30 |
|||
PUBLIC BADLD_POST,BADSIZ_POST,BADMEM,BADBLOCK,BADSTACK ;3.30 |
|||
PUBLIC INSUFMEMORY,BADCOUNTRYCOM ;3.30 |
|||
;3.30 |
|||
include sysimes.inc ;3.30 |
|||
;3.30 |
|||
SYSSIZE LABEL BYTE ;3.30 |
|||
;3.30 |
|||
PATHEND 001,SYSMES ;3.30 |
|||
;3.30 |
|||
SYSINITSEG ENDS ;3.30 |
|||
END ;3.30 |
@ -0,0 +1,68 @@ |
|||
|
|||
; |
|||
; printed when there is a bad command in CONFIG.SYS. '$' TERMINATED, note |
|||
; that this message includes crlfm. |
|||
; |
|||
|
|||
PATHSTART 001,SYSMES ;3.30 |
|||
BADOPM DB 13,10,"Unrecognized command in CONFIG.SYS" |
|||
|
|||
BADSIZ_POST LABEL BYTE |
|||
BADLD_POST LABEL BYTE |
|||
CRLFM DB 13,10,'$' |
|||
|
|||
|
|||
; |
|||
;PRINTED when installed device specifies too large a sector size.'$' terminated. |
|||
; FORM: <BADSIZ_PRE>device name<BADSIZ_POST> |
|||
; |
|||
|
|||
BADSIZ_PRE DB 13,10,"Sector size too large in file $" |
|||
|
|||
; |
|||
;PRINTED when installed device cannot be found. '$' terminated. |
|||
; FORM: <BADLD_PRE>device name<BADLD_POST> |
|||
; |
|||
|
|||
BADLD_PRE DB 13,10,"Bad or missing $" |
|||
|
|||
; |
|||
;PRINTED when command interpreter is not found. NUL terminated. |
|||
; FORM: <BADLD_PRE><BADCOM><BADLD_POST> |
|||
; |
|||
|
|||
BADCOM DB "Command Interpreter",0 |
|||
|
|||
;PRINTED when country code, code page combination was not found ;3.30 |
|||
; in country.sys file. '$' terminated. ;3.30 |
|||
; FORM: <BADCOUNTRY> ;3.30 |
|||
BADCOUNTRY DB 13,10,"Invalid country code or code page",13,10,"$" ;3.30 |
|||
;3.30 |
|||
;PRINTED when code page id is missing or wrong syntax. - J.K. ;3.30 |
|||
; FORM: <BADCOUNTRYCOM> ;3.30 |
|||
BADCOUNTRYCOM DB 13,10,"Error in COUNTRY command",13,10,"$" ;3.30 |
|||
;3.30 |
|||
;PRINTED when the memory left is not sufficient to handle COUTRY.SYS file ;3.30 |
|||
; FORM: <INSUFMEMORY> ;3.30 |
|||
INSUFMEMORY DB 13,10, "Insufficient memory for COUNTRY.SYS file",13,10,"$" ;3.30 |
|||
;3.30 |
|||
; |
|||
; PRINTED when there is insufficient memory. '$' TERMINATED, note |
|||
; that this message includes crlfm! |
|||
; |
|||
|
|||
BADMEM DB 13,10,"Configuration too large for memory",13,10,"$" |
|||
|
|||
; |
|||
; PRINTED when the attempt is made to install a block device which would |
|||
; have a drive letter > 'Z' |
|||
; |
|||
|
|||
BADBLOCK DB 13,10,"Too many Block Devices",13,10,"$" |
|||
|
|||
|
|||
; PRINTED when the attempt is made to install a stack with invalid ;3.30 |
|||
; combinations of # of stacks, stack size. - J.K. 5/23/86 ;3.30 |
|||
BADSTACK DB 13,10,"Invalid STACK parameters",13,10,"$" ;3.30 |
|||
;3.30 |
|||
|
1084
SRC/BIOS/SYSINIT1.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1256
SRC/BIOS/SYSINIT2.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,64 @@ |
|||
db 0EBH,027H,090H,008H,000H,014H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,0CDH |
|||
db 019H,0FAH,08CH,0C8H,08EH,0D8H,033H,0D2H |
|||
db 08EH,0D2H,0BCH,000H,07CH,0FBH,0B8H,060H |
|||
db 000H,08EH,0D8H,08EH,0C0H,033H,0D2H,08BH |
|||
db 0C2H,0CDH,013H,072H,069H,0E8H,085H,000H |
|||
db 072H,0DDH,02EH,083H,03EH,003H,07CH,008H |
|||
db 074H,006H,02EH,0C6H,006H,064H,07DH,002H |
|||
db 0BBH,000H,000H,02EH,08BH,00EH,003H,07CH |
|||
db 051H,0B0H,009H,02AH,0C1H,0B4H,000H,08BH |
|||
db 0F0H,056H,033H,0D2H,033H,0C0H,08AH,0C5H |
|||
db 02EH,0F6H,036H,064H,07DH,08AH,0E8H,08AH |
|||
db 0F4H,08BH,0C6H,0B4H,002H,0CDH,013H,072H |
|||
db 02DH,05EH,059H,02EH,029H,036H,005H,07CH |
|||
db 074H,01FH,08BH,0C6H,02EH,0F7H,026H,065H |
|||
db 07DH,003H,0D8H,0FEH,0C5H,0B1H,001H,051H |
|||
db 0BEH,008H,000H,02EH,03BH,036H,005H,07CH |
|||
db 07CH,005H,02EH,08BH,036H,005H,07CH,0EBH |
|||
db 0C0H,0EAH,000H,000H,060H,000H,0BEH,067H |
|||
db 07DH,0E8H,002H,000H,0EBH,0FEH,032H,0FFH |
|||
db 02EH,0ACH,024H,07FH,074H,00BH,056H,0B4H |
|||
db 00EH,0BBH,007H,000H,0CDH,010H,05EH,0EBH |
|||
db 0EFH,0C3H,0E9H,033H,0FFH,0BBH,000H,000H |
|||
db 0B9H,004H,000H,0B8H,001H,002H,0CDH,013H |
|||
db 01EH,072H,033H,08CH,0C8H,08EH,0D8H,0BFH |
|||
db 000H,000H,0B9H,00BH,000H,026H,080H,00DH |
|||
db 020H,026H,080H,04DH,020H,020H,047H,0E2H |
|||
db 0F4H,0BFH,000H,000H,0BEH,08BH,07DH,0B9H |
|||
db 00BH,000H,0FCH,0F3H,0A6H,075H,00FH,0BFH |
|||
db 020H,000H,0BEH,097H,07DH,0B9H,00BH,000H |
|||
db 0F3H,0A6H,075H,002H,01FH,0C3H,0BEH,01BH |
|||
db 07DH,0E8H,0A2H,0FFH,0B4H,000H,0CDH,016H |
|||
db 01FH,0F9H,0C3H,00DH,00AH,04EH,06FH,06EH |
|||
db 02DH,053H,079H,073H,074H,065H,06DH,020H |
|||
db 064H,069H,073H,06BH,020H,06FH,072H,020H |
|||
db 064H,069H,073H,06BH,020H,065H,072H,072H |
|||
db 06FH,072H,00DH,00AH,052H,065H,070H,06CH |
|||
db 061H,063H,065H,020H,061H,06EH,064H,020H |
|||
db 073H,074H,072H,069H,06BH,065H,020H,061H |
|||
db 06EH,079H,020H,06BH,065H,079H,020H,077H |
|||
db 068H,065H,06EH,020H,072H,065H,061H,064H |
|||
db 079H,00DH,00AH,000H,001H,000H,002H,00DH |
|||
db 00AH,044H,069H,073H,06BH,020H,042H,06FH |
|||
db 06FH,074H,020H,066H,061H,069H,06CH,075H |
|||
db 072H,065H,00DH,00AH,000H,04DH,069H,063H |
|||
db 072H,06FH,073H,06FH,066H,074H,02CH,049H |
|||
db 06EH,063H,020H,069H,06FH,020H,020H,020H |
|||
db 020H,020H,020H,073H,079H,073H,030H,06DH |
|||
db 073H,064H,06FH,073H,020H,020H,020H,073H |
|||
db 079H,073H,030H,005H,0C6H,006H,077H,02FH |
|||
db 0FFH,083H,07EH,0FCH,000H,075H,00BH,080H |
|||
db 07EH,0F7H,03BH,075H,005H,0C6H,006H,076H |
|||
db 02FH,0FFH,089H,0ECH,05DH,0CAH,004H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
|||
db 000H,000H,000H,000H,000H,000H,000H,000H |
@ -0,0 +1,38 @@ |
|||
#** makefile for Boot |
|||
|
|||
DEST = msboot |
|||
MSG = messages |
|||
|
|||
# Path definitions |
|||
|
|||
BIOS = ..\..\BIOS |
|||
DOS = ..\..\DOS |
|||
|
|||
# Definitions for assembler |
|||
|
|||
ASM = masm |
|||
AFLAGS = -Mx -t |
|||
AINC = -I..\..\inc |
|||
|
|||
# Definitions for C compiler |
|||
|
|||
CC = cl |
|||
CFLAGS = -Ox -Zlp |
|||
CINC = -I..\..\h |
|||
|
|||
# Definitions for linker |
|||
|
|||
LINK = link |
|||
LIBC = ..\..\libc |
|||
|
|||
|
|||
# Rules and Dependencies follow |
|||
|
|||
msboot.obj: msboot.asm $(MSG).inc |
|||
masm $(AFLAGS) $(AINC) msboot; |
|||
|
|||
msboot.bin: msboot.obj |
|||
LINK msboot; |
|||
EXE2BIN msboot.exe msboot.bin |
|||
DEL msboot.exe |
|||
DBOF msboot.bin boot.inc 7C00 200 |
@ -0,0 +1,7 @@ |
|||
; SCCSID = @(#)messages.inc 1.1 85/05/13 |
|||
; MESSAGES FOR THE BOOT SECTOR. NUL Terminated. |
|||
|
|||
SYSMSG DB 13,10,"Non-System disk or disk error" |
|||
DB 13,10,"Replace and strike any key when ready",13,10,0 |
|||
|
|||
DMSSG DB 13,10,"Disk Boot failure",13,10,0 |
@ -0,0 +1,386 @@ |
|||
; SCCSID = @(#)ibmboot.asm 1.1 85/05/13 |
|||
TITLE BOOT SECTOR 1 OF TRACK 0 - BOOT LOADER |
|||
|
|||
; Rev 1.0 ChrisP, AaronR and others. 2.0 format boot |
|||
; |
|||
; Rev 3.0 MarkZ Salmon enhancements |
|||
; 2.50 in label |
|||
; Rev 3.1 MarkZ 3.1 in label due to vagaries of SYSing to IBM drive D's |
|||
; This resulted in the BPB being off by 1. So we now trust |
|||
; 2.0 and 3.1 boot sectors and disbelieve 3.0. |
|||
; |
|||
; Rev 3.2 LeeAc Modify layout of extended BPB for >32M support |
|||
; Move PHYDRV to 3rd byte from end of sector |
|||
; so that it won't have to be moved again |
|||
; FORMAT and SYS count on PHYDRV being in a known location |
|||
; |
|||
; Rev. 3.3 DCLove Changed Sec 9 EOT field from 15 to 18. May 29, 1986. |
|||
; |
|||
; Rev 3.31 MarkT The COUNT value has a bogus check (JBE????) to determine |
|||
; if we've loaded in all the sectors of IO.SYS. This will |
|||
; cause too big of a load if the sectors per track is high |
|||
; enough, causing either a stack overflow or the boot code |
|||
; to be overwritten. |
|||
; |
|||
; |
|||
; The ROM in the IBM PC starts the boot process by performing a hardware |
|||
; initialization and a verification of all external devices. If all goes |
|||
; well, it will then load from the boot drive the sector from track 0, head 0, |
|||
; sector 1. This sector is placed at physical address 07C00h. The initial |
|||
; registers are set up as follows: CS=DS=ES=SS=0. IP=7C00h, SP=0400H. |
|||
; |
|||
; The code in this sector is responsible for locating the MSDOS device drivers |
|||
; (IO.SYS) and for placing the directory sector with this information at |
|||
; physical address 00500h. After loading in this sector, it reads in the |
|||
; entirety of the BIOS at BIOSEG:0 and does a long jump to that point. |
|||
; |
|||
; If no BIOS/DOS pair is found an error message is displayed and the user is |
|||
; prompted to reinsert another disk. If there is a disk error during the |
|||
; process, a message is displayed and things are halted. |
|||
; |
|||
; At the beginning of the boot sector, there is a table which describes the |
|||
; MSDOS structure of the media. This is equivalent to the BPB with some |
|||
; additional information describing the physical layout of the driver (heads, |
|||
; tracks, sectors) |
|||
; |
|||
|
|||
ORIGIN EQU 7C00H ; Origin of bootstrap LOADER |
|||
BIOSEG EQU 70H ; destingation segment of BIOS |
|||
BioOff EQU 700H ; offset of bios |
|||
cbSec EQU 512 |
|||
cbDirEnt EQU 32 |
|||
DirOff EQU 500h |
|||
|
|||
; |
|||
; Define the destination segment of the BIOS, including the initialization |
|||
; label |
|||
; |
|||
SEGBIOS SEGMENT AT BIOSEG |
|||
BIOS LABEL BYTE |
|||
SEGBIOS ENDS |
|||
|
|||
CODE SEGMENT |
|||
ASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING |
|||
ORG DirOff + 1Ch |
|||
BiosFS LABEL WORD |
|||
|
|||
ORG ORIGIN |
|||
|
|||
DSKADR = 1EH*4 ;POINTER TO DRIVE PARAMETERS |
|||
|
|||
Public $START |
|||
$START: |
|||
JMP START |
|||
;---------------------------------------------------------- |
|||
; |
|||
; THE FOLLOWING DATA CONFIGURES THE BOOT PROGRAM |
|||
; FOR ANY TYPE OF DRIVE OR HARDFILE |
|||
; |
|||
DB "MSDOS" |
|||
DB "3.3" |
|||
ByteSec DW cbSec ; SIZE OF A PHYSICAL SECTOR |
|||
DB 8 ; SECTORS PER ALLOCATION UNIT |
|||
cSecRes DW 1 ; NUMBER OF RESERVED SECTORS |
|||
cFat DB 2 ; NUMBER OF FATS |
|||
DirNum DW 512 ; NUMBER OF DIREC ENTRIES |
|||
DW 4*17*305-1 ; NUMBER OF SECTORS - NUMBER OF HIDDEN SECTORS |
|||
MEDIA DB 0F8H ; MEDIA BYTE |
|||
cSecFat DW 8 ; NUMBER OF FAT SECTORS |
|||
SECLIM DW 17 ; SECTORS PER TRACK |
|||
HDLIM DW 4 ; NUMBER OF SURFACES |
|||
cSecHid DW 1 ; NUMBER OF HIDDEN SECTORS |
|||
dw 0 ; high order word of Hiden Sectors |
|||
dd 0 ; 32 bit version of NUMBER OF SECTORS |
|||
; (when 16 bit version is zero) |
|||
db 6 dup(?) ; reserved for later expansion |
|||
|
|||
|
|||
CURHD DB ? ; Unitialized |
|||
|
|||
; this is an image of the disk parameter table. Zero entries are copied |
|||
; from the rom table at boot. |
|||
; |
|||
SEC9 DB 0 ; DISK_SPECIFY_1 |
|||
DB 0 ; DISK_SPECIFY_2 |
|||
DB 0 ; DISK_MOTOR_WAIT |
|||
DB 0 ; DISK_SECTOR_SIZ |
|||
DB 12h ; DISK_EOT |
|||
DB 0 ; DISK_RW_GAP |
|||
DB 0 ; DISK_DTL |
|||
DB 0 ; DISK_FORMT_GAP |
|||
DB 0 ; DISK_FILL |
|||
DB 1 ; DISK_HEAD_STTL |
|||
DB 0 ; DISK_MOTOR_STRT |
|||
|
|||
Public UDATA |
|||
UDATA LABEL WORD |
|||
BIOS$ EQU WORD PTR UDATA+1 |
|||
CURTRK EQU WORD PTR UDATA+3 |
|||
CURSEC EQU BYTE PTR UDATA+5 |
|||
COUNT EQU BYTE PTR UDATA+6 ; NUMBER OF BIOS SECTORS |
|||
BIOSAV EQU WORD PTR UDATA+7 |
|||
DIR$ EQU WORD PTR UDATA+9 |
|||
|
|||
START: |
|||
|
|||
; |
|||
; First thing is to reset the stack to a better and more known place. The ROM |
|||
; may change, but we'd like to get the stack in the correct place. |
|||
; |
|||
CLI ;Stop interrupts till stack ok |
|||
XOR AX,AX |
|||
MOV SS,AX ;Work in stack just below this routine |
|||
ASSUME SS:CODE |
|||
MOV SP,ORIGIN |
|||
PUSH SS |
|||
POP ES |
|||
ASSUME ES:CODE |
|||
; |
|||
; We copy the disk parameter table into a local area. We scan the table above |
|||
; for non-zero parameters. Any we see get changed to their non-zero values. |
|||
; |
|||
MOV BX,DSKADR |
|||
LDS SI,DWORD PTR SS:[BX] ; get address of disk table |
|||
PUSH DS ; save original vector for possible |
|||
PUSH SI ; restore |
|||
PUSH SS |
|||
PUSH BX |
|||
MOV DI,OFFSET Sec9 |
|||
MOV CX,11 |
|||
CLD |
|||
changeloop: |
|||
LODSB |
|||
CMP BYTE PTR ES:[DI],0 ; is the template zero? |
|||
JZ Store ; yes, store what we've got |
|||
MOV AL,ES:[DI] |
|||
Store: |
|||
STOSB |
|||
MOV AL,AH |
|||
LOOP ChangeLoop |
|||
; |
|||
; Place in new disk parameter table. |
|||
; |
|||
PUSH ES |
|||
POP DS |
|||
ASSUME DS:CODE |
|||
MOV [BX+2],AX |
|||
MOV [BX],OFFSET SEC9 |
|||
; |
|||
; We may now turn interrupts back on. Before this, there is a small window |
|||
; when a reboot command may come in when the disk parameter table is garbage |
|||
; |
|||
STI ;Interrupts OK now |
|||
; |
|||
; Reset the disk system just in case any thing funny has happened. |
|||
; |
|||
INT 13H ;Reset the system |
|||
JC RERROR |
|||
; |
|||
; The system is now prepared for us to begin reading. First, determine |
|||
; logical sector numbers of the start of the directory and the start of the |
|||
; data area. |
|||
; |
|||
MOV AL,cFat ;Determine sector dir starts on |
|||
CBW |
|||
MUL cSecFat |
|||
ADD AX,cSecHid |
|||
ADD AX,cSecRes |
|||
MOV [DIR$],AX ; AX = cFat*cSecFat + cSecRes + cSecHid |
|||
MOV [BIOS$],AX |
|||
; |
|||
; Take into account size of directory (only know number of directory entries) |
|||
; |
|||
MOV AX,cbDirEnt ; bytes per directory entry |
|||
MUL DirNum ; convert to bytes in directory |
|||
MOV BX,ByteSec ; add in sector size |
|||
ADD AX,BX |
|||
DEC AX ; decrement so that we round up |
|||
DIV BX ; convert to sector number |
|||
ADD [BIOS$],AX |
|||
; |
|||
; We load in the first directory sector and examine it to make sure the the |
|||
; BIOS and DOS are the first two directory entries. If they are not found, |
|||
; the user is prompted to insert a new disk. The directory sector is loaded |
|||
; into 00500h |
|||
; |
|||
MOV BX,DirOff ; sector to go in at 00500h |
|||
MOV AX,DIR$ ; logical sector of directory |
|||
CALL DODIV ; convert to sector, track, head |
|||
MOV AX,0201H ; disk read 1 sector |
|||
CALL DOCALL ; do the disk read |
|||
JB CKERR ; if errors try to recover |
|||
; |
|||
; Now we scan for the presence of IO.SYS and MSDOS.SYS. Check the |
|||
; first directory entry. |
|||
; |
|||
MOV DI,BX |
|||
MOV CX,11 |
|||
MOV SI,OFFSET BIO ; point to "bios com" |
|||
REPZ CMPSB ; see if the same |
|||
JNZ CKERR ; if not there advise the user |
|||
; |
|||
; Found the BIOS. Check the second directory entry. |
|||
; |
|||
LEA DI,[BX+20h] |
|||
MOV SI,OFFSET DOS ; point to "86dos com" |
|||
MOV CX,11 |
|||
REPZ CMPSB |
|||
JZ DoLoad |
|||
; |
|||
; There has been some recoverable error. Display a message and wait for a |
|||
; keystroke. |
|||
; |
|||
CKERR: MOV SI,OFFSET SYSMSG ; point to no system message |
|||
ErrOut: CALL WRITE ; and write on the screen |
|||
XOR AH,AH ; wait for response |
|||
INT 16H ; get character from keyboard |
|||
POP SI ; reset disk parameter table back to |
|||
POP DS ; rom |
|||
POP [SI] |
|||
POP [SI+2] |
|||
INT 19h ; Continue in loop till good disk |
|||
|
|||
RERROR: MOV SI,OFFSET DMSSG ; DISK ERROR MESSAGE |
|||
JMP ErrOut |
|||
; |
|||
; We now begin to load the BIOS in. Compute the number of sectors needed |
|||
; |
|||
DoLoad: |
|||
MOV AX,BiosFS ; get file size |
|||
XOR DX,DX ; presume < 64K |
|||
DIV ByteSec ; convert to sectors |
|||
INC AL ; reading in one more can't hurt |
|||
MOV COUNT,AL ; Store running count |
|||
MOV AX,BIOS$ ; get logical sector of beginning of BIOS |
|||
MOV BIOSAV,AX ; store away for real bios later |
|||
MOV BX,BioOff ; Load address from BIOSSEG |
|||
; |
|||
; Main read-in loop. |
|||
; ES:BX points to area to read. |
|||
; Count is the number of sectors remaining. |
|||
; BIOS$ is the next logical sector number to read |
|||
; |
|||
LOOPRD: |
|||
MOV AX,BIOS$ ; Starting sector |
|||
CALL DODIV |
|||
; |
|||
; CurHD is the head for this next disk request |
|||
; CurTrk is the track for this next request |
|||
; CurSec is the beginning sector number for this request |
|||
; |
|||
; Compute the number of sectors that we may be able to read in a single ROM |
|||
; request. |
|||
; |
|||
MOV AX,SECLIM |
|||
SUB AL,CURSEC |
|||
INC AX |
|||
; |
|||
; AX is the number of sectors that we may read. |
|||
; |
|||
|
|||
; |
|||
;New code for Rev 3.31 |
|||
;***************************************************************************** |
|||
|
|||
CMP COUNT,AL ;Is sectors we can read more than we need? |
|||
JAE GOT_SECTORS ;No, it is okay |
|||
MOV AL,COUNT ;Yes, only read in what is left |
|||
|
|||
GOT_SECTORS: |
|||
|
|||
;***************************************************************************** |
|||
;End of change |
|||
; |
|||
|
|||
|
|||
PUSH AX |
|||
CALL DOCALL |
|||
POP AX |
|||
JB RERROR ; If errors report and go to ROM BASIC |
|||
SUB COUNT,AL ; Are we finished? |
|||
; |
|||
;Old code replaced by Rev 3.3 |
|||
;******************************************************************** |
|||
; JBE DISKOK ; Yes -- transfer control to the DOS |
|||
;******************************************************************** |
|||
;New code for Rev 3.3 |
|||
; |
|||
|
|||
JZ DISKOK ; Yes -- transfer control to the DOS |
|||
|
|||
;******************************************************************** |
|||
;End of change |
|||
; |
|||
ADD BIOS$,AX ; increment logical sector position |
|||
MUL ByteSec ; determine next offset for read |
|||
ADD BX,AX ; (BX)=(BX)+(SI)*(Bytes per sector) |
|||
JMP LOOPRD ; Get next track |
|||
; |
|||
; IBMINIT requires the following input conditions: |
|||
; |
|||
; DL = INT 13 drive number we booted from |
|||
; CH = media byte |
|||
; BX = First data sector on disk (0-based) |
|||
; |
|||
DISKOK: |
|||
MOV CH,Media |
|||
MOV DL,PhyDrv |
|||
MOV BX,[BIOSAV] ;Get bios sector in bx |
|||
JMP FAR PTR BIOS ;CRANK UP THE DOS |
|||
|
|||
WRITE: LODSB ;GET NEXT CHARACTER |
|||
OR AL,AL ;clear the high bit |
|||
JZ ENDWR ;ERROR MESSAGE UP, JUMP TO BASIC |
|||
MOV AH,14 ;WILL WRITE CHARACTER & ATTRIBUTE |
|||
MOV BX,7 ;ATTRIBUTE |
|||
INT 10H ;PRINT THE CHARACTER |
|||
JMP WRITE |
|||
; |
|||
; convert a logical sector into Track/sector/head. AX has the logical |
|||
; sector number |
|||
; |
|||
DODIV: |
|||
XOR DX,DX |
|||
DIV SECLIM |
|||
INC DL ; sector numbers are 1-based |
|||
MOV CURSEC,DL |
|||
XOR DX,DX |
|||
DIV HDLIM |
|||
MOV CURHD,DL |
|||
MOV CURTRK,AX |
|||
ENDWR: RET |
|||
; |
|||
; Issue one read request. ES:BX have the transfer address, AL is the number |
|||
; of sectors. |
|||
; |
|||
DOCALL: MOV AH,2 |
|||
MOV DX,CURTRK |
|||
MOV CL,6 |
|||
SHL DH,CL |
|||
OR DH,CURSEC |
|||
MOV CX,DX |
|||
XCHG CH,CL |
|||
MOV DL, PHYDRV |
|||
mov dh, curhd |
|||
INT 13H |
|||
RET |
|||
|
|||
include messages.inc |
|||
|
|||
BIO DB "IO SYS" |
|||
DOS DB "MSDOS SYS" |
|||
|
|||
Free EQU (cbSec - 3) - ($-$start) |
|||
if Free LT 0 |
|||
%out FATAL PROBLEM:boot sector is too large |
|||
endif |
|||
|
|||
org origin + (cbSec - 3) |
|||
|
|||
; FORMAT and SYS count on PHYDRV being right here |
|||
PHYDRV db 0 |
|||
; Boot sector signature |
|||
db 55h,0aah |
|||
|
|||
CODE ENDS |
|||
END |
@ -0,0 +1,650 @@ |
|||
TITLE MSBIO2 - DOS 3.3 |
|||
|
|||
;------------------------------------------------------------------------------- |
|||
; : |
|||
; Microsoft Bio : |
|||
; : |
|||
; The file msbio.asm is the main file in the Mircosoft bio. This file : |
|||
; includes the other main files in the bio. Most of the routines are : |
|||
; in these include files. The main files included are: : |
|||
; : |
|||
; File Contains : |
|||
; : |
|||
; msdisk.inc Disk device driver routines : |
|||
; ms96tpi.inc Routines for 96tpi drives : |
|||
; msaux.inc Device driver for the rs-232 serial ports : |
|||
; msclock.inc Device driver for "clock$" device : |
|||
; mscon.inc Device driver for "con" : |
|||
; mslpt.inc Device driver for the printers : |
|||
; : |
|||
; Each of these files contain a header section documenting the code : |
|||
; in that file. : |
|||
; Msbio also includes several files for equ's, structure definition, : |
|||
; macro definitions, etc. These are: : |
|||
; : |
|||
; msbiomes.inc msmacro.inc devsym.inc : |
|||
; dskprm.inc error.inc : |
|||
; : |
|||
; Each of these file contains explanitory notes. : |
|||
; : |
|||
; The actual code in msbio can be broken down into several piece: : |
|||
; : |
|||
; macro definitions Several marco are defined in msbio. They : |
|||
; are a few odds and end that did not fit : |
|||
; anywhere else. : |
|||
; : |
|||
; Command Jump Table List of entry points in the device drivers. : |
|||
; See notation below for full explination. : |
|||
; : |
|||
; Interrupt and Strategy : |
|||
; Entry points Calls on the device driver first come to here. : |
|||
; There is common code with pushes registers and : |
|||
; the like before jumping to routines in the : |
|||
; driver files. The common exit points are also : |
|||
; in this file. : |
|||
; : |
|||
; Miscellaneous Code There are several routines and data structure : |
|||
; declarations. See below for details. : |
|||
; : |
|||
;------------------------------------------------------------------------------- |
|||
|
|||
|
|||
|
|||
; |
|||
; If the variable TEST is non-zero then code for debugging is included. |
|||
; The extra code will make the binary file nuch larger. |
|||
; The symbol is also defined in msequ.inc. Both must be changed to |
|||
; turn debugging on or off. |
|||
; |
|||
; The level of the debugging is controled by the variable fTestBits in |
|||
; this file. See the comment preceeding the variable for more information. |
|||
; The actual routines which print the messages are in msmacro.inc |
|||
; See the header comment in this file for more information. |
|||
; |
|||
|
|||
|
|||
; |
|||
; Revision History |
|||
; |
|||
; REV 2.1 5/1/83 ARR added timer int handler and changed order of AUX |
|||
; PRN init for HAL0 |
|||
; |
|||
; REV 2.15 7/13/83 ARR Because of IBM design issues, and that BASCOM |
|||
; is ill behaved with respect to the 1CH timer interrupt, |
|||
; the timer handler has to be backed out! The intended |
|||
; code is commented out and has an ARR 2.15 annotation. |
|||
; This means the BIOS will go back to the multiple roll |
|||
; over bug. |
|||
; |
|||
; REV 2.20 8/5/83 ARR IBM makes hardware change. Now wants to use half |
|||
; height drives for HAL0, and back fit for PC/PC XT. Problem |
|||
; with head settle time. Previous drives got by on a 0 |
|||
; settle time, 1/2 hight drives need 15 head settle when |
|||
; doing WRITEs (0 ok on READ) if the head is being stepped. |
|||
; This requires a last track value to be kept so that BIOS |
|||
; knows when head is being moved. To help out |
|||
; programs that issue INT 13H directly, the head settle will |
|||
; normally be set to 15. It will be changed to 0 on READs, |
|||
; or on WRITEs which do not require head step. |
|||
; |
|||
; REV 2.21 8/11/83 MZ IBM wants write with verify to use head settle 0. |
|||
; Use same trick as above. |
|||
; |
|||
; REV 2.25 6/20/83 mjb001 added support for 96tpi and salmon |
|||
; |
|||
; REV 2.30 6/27/83 mjb002 added real-time clock |
|||
; |
|||
; REV 2.40 7/8/83 mjb003 added volume-id checking and int 2f macro |
|||
; definitions push* and pop* |
|||
; |
|||
; REV 2.41 7/12/83 ARR more 2.X enhancements. Open/Close media change |
|||
; |
|||
; REV 2.42 11/3/83 ARR more 2.X enhancements. Disk OPEN/CLOSE, FORMAT |
|||
; code and other misc hooked out to shrink BIOS. Code for |
|||
; Disk OPEN/CLOSE, FORMAT included only with 96tpi disks. |
|||
; |
|||
; Rev 2.43 12/6/83 MZ Examine boot sectors on hard disks for 16-bit fat |
|||
; check. Examine large fat bit in BPB for walk of media for |
|||
; DOS |
|||
; |
|||
; Rev 2.44 12/9/83 ARR Change to error reporting on INT 17H |
|||
; |
|||
; Rev 2.45 12/22/83 MZ Make head settle change only when disk parm is 0. |
|||
|
|||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
|||
; |
|||
; IBM ADDRESSES FOR I/O |
|||
; |
|||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
|||
|
|||
;Below was moved from sysinit1 |
|||
ROMSEGMENT EQU 0F000H |
|||
MODELBYTE EQU DS:BYTE PTR [0FFFEH] |
|||
MODELPCJR EQU 0FDH |
|||
|
|||
test=0 |
|||
;;Rev 3.30 modification ---------------------------- |
|||
INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT |
|||
INCLUDE MSEQU.INC |
|||
INCLUDE DEVSYM.INC |
|||
INCLUDE PUSHPOP.INC |
|||
INCLUDE MSMACRO.INC |
|||
|
|||
ASSUME DS:NOTHING,ES:NOTHING |
|||
|
|||
EXTRN DSK$IN:NEAR |
|||
EXTRN SETPTRSAV:NEAR |
|||
EXTRN OUTCHR:NEAR |
|||
EXTRN SETDRIVE:NEAR |
|||
EXTRN FLUSH:NEAR |
|||
EXTRN HARDERR:NEAR |
|||
EXTRN HARDERR2:NEAR |
|||
EXTRN MAPERROR:NEAR |
|||
EXTRN GETBP:NEAR |
|||
EXTRN CHECKSINGLE:NEAR |
|||
EXTRN CHECK_TIME_OF_ACCESS:NEAR |
|||
EXTRN EXIT:NEAR |
|||
EXTRN HAS1:NEAR |
|||
EXTRN HAS1_res:NEAR |
|||
EXTRN READ_SECTOR:NEAR |
|||
EXTRN INT_2F_13:FAR |
|||
|
|||
EXTRN OLD13:DWORD |
|||
|
|||
;DATA |
|||
EXTRN PTRSAV:DWORD |
|||
EXTRN START_BDS:WORD |
|||
EXTRN FDRIVE1:WORD |
|||
EXTRN FDRIVE2:WORD |
|||
EXTRN FDRIVE3:WORD |
|||
EXTRN FDRIVE4:WORD |
|||
EXTRN FLAGBITS:WORD |
|||
EXTRN TIM_DRV:BYTE |
|||
EXTRN MEDBYT:BYTE |
|||
EXTRN DRVMAX:BYTE |
|||
|
|||
PATHSTART 005,DISK |
|||
EVENB |
|||
PUBLIC ORIG19 |
|||
ORIG19 DD ? |
|||
|
|||
PUBLIC INT19SEM |
|||
INT19SEM DB 0 ; INDICATE THAT ALL INT 19 |
|||
; INITIALIZATION IS COMPLETE |
|||
|
|||
IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77> |
|||
public Int19OLD&AA |
|||
Int19OLD&AA dd -1 ;Orignal hw int. vec for INT 19h. |
|||
ENDM |
|||
|
|||
EVENB |
|||
PUBLIC DSKDRVS |
|||
DSKDRVS DW FDRIVE1 |
|||
DW FDRIVE2 |
|||
DW FDRIVE3 |
|||
DW FDRIVE4 |
|||
PUBLIC HDSKTAB |
|||
HDSKTAB DW HDRIVE |
|||
DW DRIVEX |
|||
;* Next area is reseved for mini disk BPB pointers *** 4/7/86 |
|||
;* Don't change this pos. Should be add. from DskDrvs *** 4/7/86 |
|||
MINI_DISK_BPB_PTRS DB 40 dup (?) ;4/7/86 - mem res for Mini disk. |
|||
|
|||
EVENB |
|||
PUBLIC INT_2F_NEXT |
|||
INT_2F_NEXT DD ? |
|||
|
|||
RET_ADDR DD ? |
|||
|
|||
PATHEND 005,DISK |
|||
;;End of modification ---------------------------- |
|||
|
|||
; INT19 |
|||
; |
|||
; We "hook" the INT_REBOOT vector, because contrary to IBM documentation, |
|||
; it does NOT "bootstrap" the machine. It leaves memory almost untouched. |
|||
; Since the BIOS_INIT code assumes that certain Interrupt Vectors point to |
|||
; the ROM_BIOS we must "unhook" them before issuing the actual INT_REBOOT. |
|||
; Currently the following vectors need to be unhooked: |
|||
; 02,08,09,0A,0B,0C,0D,0E,70,72,73,74,75,76,77 |
|||
; |
|||
|
|||
Public Int19 |
|||
Int19 proc FAR |
|||
xor AX,AX ; get data segment to |
|||
mov DS,AX ; point to the vector table |
|||
assume ds:nothing |
|||
assume es:nothing |
|||
les DI,Old13 ; get ES to point to this segment |
|||
mov DS:[13h*4],DI ; restore old int13 value |
|||
mov DS:[13h*4+2],ES |
|||
|
|||
cmp Byte ptr Int19Sem, 0 |
|||
jnz int19vecs |
|||
jmp doint19 |
|||
|
|||
;;Dos 3.30 Will not support the PC-Jr |
|||
;;Rev 3.30 modification ---------------------------- |
|||
; ON THE PCJR, DON'T REPLACE ANY VECTORS |
|||
; MODEL BYTE DEFINITIONS FROM MSSTACK.ASM |
|||
; MOV AX,ROMSEGMENT |
|||
; MOV DS,AX |
|||
; MOV AL,MODELPCJR |
|||
; |
|||
; CMP AL,MODELBYTE |
|||
; JNE INT19VECS |
|||
; JMP DOINT19 |
|||
|
|||
|
|||
;Stacks code has changed these hardware interrupt vectors |
|||
;STKINIT in SYSINIT1 will initialzie Int19hOLDxx values. |
|||
int19vecs: |
|||
|
|||
; |
|||
; we now need to unhook all the vector replace to prevent stack overflow |
|||
; |
|||
|
|||
;;Rev 3.30 modification ---------------------------- |
|||
XOR AX,AX |
|||
MOV DS,AX |
|||
|
|||
IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77> |
|||
|
|||
LES DI,Int19OLD&AA |
|||
|
|||
mov ax,es ; Put segment where we can compare it |
|||
cmp ax,-1 ; OPT 0ffffh is not likely |
|||
je skip_int&AA ; OPT could get away without checking |
|||
cmp di,-1 ; OPT offset here. |
|||
je skip_int&AA |
|||
|
|||
MOV DS:[AA&H*4],DI |
|||
MOV DS:[AA&H*4+2],ES |
|||
skip_int&AA: |
|||
ENDM |
|||
;;End of modification ---------------------------- |
|||
|
|||
doint19: |
|||
LES DI,Orig19 |
|||
MOV DS:[19h*4],DI |
|||
MOV DS:[19h*4+2],ES |
|||
|
|||
INT 19h |
|||
INT19 ENDP |
|||
ASSUME DS:CODE |
|||
|
|||
;***************************************************************************** |
|||
PUBLIC DSK$INIT |
|||
DSK$INIT PROC NEAR |
|||
PUSH CS |
|||
POP DS |
|||
MOV AH,BYTE PTR DRVMAX |
|||
MOV DI,OFFSET DskDrvs |
|||
JMP SetPTRSAV |
|||
DSK$INIT ENDP |
|||
|
|||
|
|||
; |
|||
; Int 2f handler for external block drivers to communicate with the internal |
|||
; block driver in msdisk. The multiplex number chosen is 8. The handler |
|||
; sets up the pointer to the request packet in [PTRSAV] and then jumps to |
|||
; DSK$IN, the entry point for all disk requests. |
|||
; On exit from this driver (at EXIT), we will return to the external driver |
|||
; that issued this Int 2F, and can then remove the flags from the stack. |
|||
; This scheme allows us to have a small external device driver, and makes |
|||
; the maintainance of the various drivers (DRIVER and msBIO) much easier, |
|||
; since we only need to make changes in one place (most of the time). |
|||
; |
|||
; AL contains the Int2F function: |
|||
; 0 - Check for installed handler - RESERVED |
|||
; 1 - Install the BDS into the linked list |
|||
; 2 - DOS request |
|||
; |
|||
|
|||
MYNUM EQU 8 |
|||
|
|||
Public Int2F_Disk |
|||
Int2F_Disk PROC FAR |
|||
cmp ah,MYNUM |
|||
je Mine |
|||
jmp cs:[Int_2F_Next] ; chain to next Int 2F handler |
|||
Mine: |
|||
cmp al,0F8H ; IRET on reserved functions |
|||
jb Do_Func |
|||
IRET |
|||
Do_Func: |
|||
or al,al ; A GET INSTALLED STATE request? |
|||
jne Disp_Func |
|||
mov al,0FFH |
|||
IRET |
|||
Disp_Func: |
|||
Message fTestInit,<"Int2F_disk",cr,lf> |
|||
cmp al,1 ; Request for installing BDS? |
|||
jne Do_DOS_Req |
|||
call Install_BDS |
|||
IRET |
|||
|
|||
Do_DOS_Req: |
|||
; Set up pointer to request packet |
|||
MOV WORD PTR CS:[PTRSAV],BX |
|||
MOV WORD PTR CS:[PTRSAV+2],ES |
|||
jmp DSK$IN |
|||
|
|||
Int2F_Disk ENDP |
|||
|
|||
; |
|||
; Install_BDS installs a BDS a location DS:DI into the current linked list of |
|||
; BDS maintained by this device driver. It places the BDS at the END of the |
|||
; list. |
|||
Public Install_BDS |
|||
INSTALL_BDS PROC NEAR |
|||
message ftestinit,<"Install BDS",cr,lf> |
|||
; ds:di point to BDS to be installed |
|||
les si,dword ptr cs:[Start_BDS] ; Start at beginning of list |
|||
push es ; Save pointer to current BDS |
|||
push si |
|||
; es:si now point to BDS in linked list |
|||
Loop_Next_BDS: |
|||
cmp si,-1 ; got to end of linked list? |
|||
jz Install_Ret |
|||
; If we have several logical drives using the same physical drive, we must |
|||
; set the I_Am_Mult flag in each of the appropriate BDSs. |
|||
mov al,byte ptr ds:[di].DriveNum |
|||
cmp byte ptr es:[si].DriveNum,al |
|||
jnz Next_BDS |
|||
message ftestinit,<"Logical Drives",cr,lf> |
|||
xor bx,bx |
|||
mov bl,fI_Am_Mult |
|||
or word ptr ds:[di].flags,bx ; set flags in both BDSs concerned |
|||
or word ptr es:[si].flags,bx |
|||
mov bl,fI_Own_Physical |
|||
xor bx,-1 |
|||
and word ptr ds:[di].flags,bx ; reset that flag for 'new' BDS |
|||
; We must also set the fChangeline bit correctly. |
|||
mov bx,word ptr es:[si].flags ; determine if changeline available |
|||
and bl,fChangeline |
|||
xor bh,bh |
|||
or word ptr ds:[di].flags,bx |
|||
|
|||
Next_BDS: |
|||
; Before moving to next BDS, preserve pointer to current one. This is needed at |
|||
; the end when the new BDS is linked into the list. |
|||
pop bx ; discard previous pointer to BDS |
|||
pop bx |
|||
push es |
|||
push si |
|||
mov bx,word ptr es:[si].link + 2 |
|||
mov si,word ptr es:[si].link |
|||
mov es,bx |
|||
jmp short Loop_Next_BDS |
|||
|
|||
Install_Ret: |
|||
pop si ; Retrieve pointer to last BDS |
|||
pop es ; in linked list. |
|||
mov ax,ds |
|||
mov word ptr es:[si].link+2,ax ; install BDS |
|||
mov word ptr es:[si].link,di |
|||
mov word ptr ds:[di].link,-1 ; set NEXT pointer to NULL |
|||
RET |
|||
INSTALL_BDS ENDP |
|||
|
|||
; |
|||
; RE_INIT installs the Int 2F vector that will handle communication between |
|||
; external block drivers and the internal driver. It also installs the |
|||
; Reset_Int_13 interface. It is called by SYSYINIT |
|||
; |
|||
PUBLIC RE_INIT |
|||
RE_INIT PROC FAR |
|||
Message ftestinit,<"REINIT",CR,LF> |
|||
PUSH AX |
|||
PUSH DS |
|||
PUSH DI |
|||
XOR DI,DI |
|||
MOV DS,DI |
|||
MOV DI,2FH*4 ; point it to Int 2F Vector |
|||
MOV AX,WORD PTR DS:[DI] |
|||
MOV WORD PTR CS:[INT_2F_NEXT],AX |
|||
MOV AX,WORD PTR DS:[DI+2] ; preserve old Int 2F vector |
|||
MOV WORD PTR CS:[INT_2F_NEXT+2],AX |
|||
|
|||
; INSTALL the Reset_Int_13 |
|||
; interface |
|||
|
|||
|
|||
CLI |
|||
MOV Word Ptr DS:[DI],Offset Int_2f_13 ; install new vectors |
|||
MOV Word Ptr DS:[DI+2],CS |
|||
STI |
|||
POP DI |
|||
POP DS |
|||
POP AX |
|||
RET |
|||
|
|||
RE_INIT ENDP |
|||
|
|||
;------------------------------------------------- |
|||
; |
|||
; Ask to swap the disk in drive A: |
|||
; Using a different drive in a one drive system so |
|||
; request the user to change disks |
|||
; |
|||
Public SWPDSK |
|||
SWPDSK PROC NEAR |
|||
mov al,byte ptr ds:[di].drivelet ; get the drive letter |
|||
add al,"A" |
|||
mov cs:DRVLET,AL |
|||
push ds ; preserve segment register |
|||
push cs |
|||
pop ds |
|||
mov SI,OFFSET SNGMSG ; ds:si -> message |
|||
push BX |
|||
call WRMSG ;Print disk change message |
|||
call FLUSH |
|||
; wait for a keyboard character |
|||
xor AH, AH ; set command to read character |
|||
int 16h ; call rom-bios |
|||
POP BX |
|||
pop ds ; restore segment register |
|||
WRMRET: |
|||
ret |
|||
SWPDSK ENDP |
|||
|
|||
;---------------------------------------------- |
|||
; |
|||
; WrMsg writes out message pointed to by [SI] |
|||
; |
|||
Public WrMsg |
|||
WRMSG PROC NEAR |
|||
lodsb ; get the next character of the message |
|||
or AL,AL ; see fi end of message |
|||
jz WRMRET |
|||
pushf |
|||
push CS |
|||
call OUTCHR |
|||
jmp SHORT WRMSG |
|||
WRMSG ENDP |
|||
|
|||
INCLUDE BIOMES.INC |
|||
|
|||
; |
|||
; End of support for multiple floppies with no logical drives |
|||
; This is not 'special' any more because we now have the capability of |
|||
; defining logical drives in CONFIG.SYS. We therefore keep the code for |
|||
; swapping resident ALL the time. |
|||
; |
|||
|
|||
;;Rev 3.30 modification ---------------------------- |
|||
;Variables for Dynamic Relocatable modules |
|||
;These should be stay resident. |
|||
|
|||
public INT6C_RET_ADDR |
|||
INT6C_RET_ADDR DD ? ;ret add from INT 6C for P12 mach |
|||
|
|||
PATHSTART 001,CLK |
|||
; |
|||
; DATA STRUCTURES FOR REAL-TIME DATE AND TIME |
|||
; |
|||
public BIN_DATE_TIME |
|||
public MONTH_TABLE |
|||
public DAYCNT2 |
|||
public FEB29 |
|||
BIN_DATE_TIME: |
|||
DB 0 ; CENTURY (19 OR 20) OR HOURS (0-23) |
|||
DB 0 ; YEAR IN CENTURY (0-99) OR MINUTES (0-59) |
|||
DB 0 ; MONTH IN YEAR (1-12) OR SECONDS (0-59) |
|||
DB 0 ; DAY IN MONTH (1-31) |
|||
MONTH_TABLE: |
|||
DW 0 ;MJB002 JANUARY |
|||
DW 31 ;MJB002 FEBRUARY |
|||
DW 59 ;MJB002 |
|||
DW 90 ;MJB002 |
|||
DW 120 ;MJB002 |
|||
DW 151 ;MJB002 |
|||
DW 181 ;MJB002 |
|||
DW 212 ;MJB002 |
|||
DW 243 ;MJB002 |
|||
DW 273 ;MJB002 |
|||
DW 304 ;MJB002 |
|||
DW 334 ;MJB002 |
|||
DAYCNT2 DW 0000 ;MJB002 TEMP FOR CNT OF DAYS SINCE 1-1-80 |
|||
FEB29 DB 0 ;MJB002 FEBRUARY 29 IN A LEAP YEAR FLAG |
|||
PATHEND 001,CLK |
|||
|
|||
;;End of modification modification ---------------------------- |
|||
|
|||
Public EndFloppy |
|||
EndFloppy Label Byte |
|||
; |
|||
; End of code for virtual floppy drives |
|||
; |
|||
Public EndSwap |
|||
EndSwap Label Byte |
|||
|
|||
PATHSTART 004,BIO |
|||
|
|||
Public HNUM |
|||
HNUM DB 0 ; number of hardfile (hard drives) |
|||
|
|||
Public HardDrv |
|||
HARDDRV DB 80H ;Physical drive number of first hardfile |
|||
|
|||
|
|||
; |
|||
; "HDRIVE" is a hard disk with 512 byte sectors |
|||
; |
|||
|
|||
EVENB |
|||
Public BDSH |
|||
BDSH DW -1 ; Link to next structure |
|||
DW Code |
|||
DB 80h ; physical drive number |
|||
DB "C" ; Logical Drive Letter |
|||
Public HDRIVE |
|||
HDRIVE: |
|||
DW 512 |
|||
DB 1 ; Sectors/allocation unit |
|||
DW 1 ; Reserved sectors for DOS |
|||
DB 2 ; No. of allocation tables |
|||
DW 16 ; Number of directory entries |
|||
DW 0000 ; Number of sectors (at 512 bytes each) |
|||
DB 11111000B ; Media descriptor |
|||
DW 1 ; Number of FAT sectors |
|||
DW 00 ; Sector limit |
|||
DW 00 ; Head limit |
|||
DW 00 ; Hidden sector count |
|||
DB 0 ; TRUE => bigfat |
|||
OPCNTH DW 0 ; Open Ref. Count |
|||
VOLIDH DB "NO NAME ",0 ; Volume ID for this disk |
|||
DB 3 ; Form Factor |
|||
FLAGSH DW 0020H ; Various Flags |
|||
dw 40 ; number of cylinders |
|||
RecBPBH db 31 dup (?) ; Recommended BPB for drive |
|||
TRACKH DB -1 ; Last track accessed on this drive |
|||
TIM_LOH DW -1 ; Keep these two contiguous (?) |
|||
TIM_HIH DW -1 |
|||
; |
|||
; End of single hard disk section |
|||
; |
|||
|
|||
|
|||
Public EndOneHard |
|||
EndOneHard Label Byte |
|||
|
|||
|
|||
|
|||
|
|||
; |
|||
;"DRIVEX" is an extra type of drive usually reserved for an |
|||
; additional hard file |
|||
; |
|||
|
|||
EVENB |
|||
Public BDSX |
|||
BDSX DW -1 ; Link to next structure |
|||
DW Code |
|||
DB 81h ; physical drive number |
|||
DB "D" ; Logical Drive Letter |
|||
Public DRIVEX |
|||
DRIVEX: |
|||
DW 512 |
|||
DB 00 ; Sectors/allocation unit |
|||
DW 1 ; Reserved sectors for DOS |
|||
DB 2 ; No. of allocation tables |
|||
DW 0000 ; Number of directory entries |
|||
DW 0000 ; Number of sectors (at 512 bytes each) |
|||
DB 11111000B ; Media descriptor |
|||
DW 0000 ; Number of FAT sectors |
|||
DW 00 ; Sector limit |
|||
DW 00 ; Head limit |
|||
DW 00 ; Hidden sector count |
|||
DB 0 ; TRUE => bigfat |
|||
OPCNTD DW 0 ; Open Ref. Count |
|||
VOLIDD DB "NO NAME ",0 ; Volume ID for this disk |
|||
DB 3 ; Form Factor |
|||
FLAGSD DW 0020H ; Various Flags |
|||
dw 40 ; number of cylinders |
|||
RecBPBD db 31 dup (?) ; Recommended BPB for drive |
|||
TRACKD DB -1 ; Last track accessed on this drive |
|||
TIM_LOD DW -1 ; Keep these two contiguous |
|||
TIM_HID DW -1 |
|||
|
|||
; |
|||
; End of section for two hard disks |
|||
Public EndTwoHard |
|||
EndTwoHard Label Byte |
|||
|
|||
PATHEND 004,BIO |
|||
|
|||
|
|||
Public TwoHard |
|||
TWOHARD LABEL BYTE |
|||
|
|||
PAGE |
|||
include ms96tpi.inc |
|||
|
|||
;;Rev 3.30 modification ---------------------------- |
|||
;Memory allocation for BDSM table. |
|||
PUBLIC BDSMs |
|||
BDSMs BDSM_type Max_mini_dsk_num dup (<>) ;currently max. 23 |
|||
|
|||
;** End_of_BDSM defined in MSINIT.ASM will be used to set the appropriate |
|||
;** ending address of BDSM table. |
|||
;;End of modification ---------------------------- |
|||
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug005sp |
|||
; |
|||
;;3.3 BUG FIX -SUNILP ------------------------------ |
|||
;Paragraph buffer between the BDSMs and MSHARD |
|||
; |
|||
;The relocation code for MSHARD needs this. this cannot be used for |
|||
;anything. nothing can come before this or after this.....IMPORTANT!!!! |
|||
;don't get too smart and using this buffer for anything!!!!!! |
|||
; |
|||
db 16 dup(0) |
|||
; |
|||
;end of bug fix buffer |
|||
;; |
|||
;;3.3 BUG FIX -SUNILP------------------------------ |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug005sp |
|||
CODE ENDS |
|||
END |
3032
SRC/BUGFIX/CMD/FORMAT/FORMAT.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,68 @@ |
|||
; SCCSID = @(#)messages.asm 1.10 85/08/13 |
|||
TITLE FORMAT Messages |
|||
|
|||
data segment public 'DATA' |
|||
|
|||
public Yes_Byte |
|||
public No_Byte |
|||
public msgCRLF |
|||
public msgCurrentTrack |
|||
public msgSystemTransfered |
|||
public msgFormatComplete |
|||
public msgInterrupt |
|||
public msgInsertDisk |
|||
public msgHardDiskWarning |
|||
public msgFormatAnother? |
|||
public msgInsertDosDisk |
|||
public msgReInsertDisk |
|||
public msgLabelPrompt |
|||
public msgTotalDiskSpace |
|||
public msgSystemSpace |
|||
public msgBadSpace |
|||
public msgDataSpace |
|||
public msgFormatNotSupported |
|||
public msgInvalidDeviceParameters |
|||
public msgErrorInIOCTL |
|||
public msgNotBlockDevice |
|||
public msgFATwriteError |
|||
public msgDirectoryWriteError |
|||
public msgAssignedDrive |
|||
public msgNeedDrive |
|||
public msgBadDosVersion |
|||
public msgNoSystemFiles |
|||
public msgTooManyFilesOpen |
|||
public msgNetDrive |
|||
public msgBadCharacters |
|||
public msgBadDrive |
|||
public msgInvalidParameter |
|||
public msgParametersNotSupported |
|||
public msgFormatFailure |
|||
public msgNotSystemDisk |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
; reintroduce following public for fix |
|||
public msgNoRoomDestDisk |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
public msgDiskUnusable |
|||
public msgOutOfMemory |
|||
public msgWriteProtected |
|||
public msgNotReady |
|||
public msgBootWriteError |
|||
public msgDirectoryReadError |
|||
public msgBadVolumeId |
|||
public msgWhatIsVolumeId? |
|||
public msgIncompatibleParameters |
|||
public msgIncompatibleParametersForHardDisk |
|||
public msgBadPartitionTable |
|||
public msgParametersNotSupportedByDrive |
|||
public msgPartitionTableReadError |
|||
public msgPartitionTableWriteError |
|||
|
|||
CR equ 13 |
|||
LF equ 10 |
|||
|
|||
; Oem dependent messages |
|||
|
|||
include messages.inc |
|||
|
|||
data ends |
|||
END |
@ -0,0 +1,139 @@ |
|||
; SCCSID = @(#)messages.inc 1.6 85/08/02 |
|||
|
|||
DEBUG EQU 0 ; for Boot sector installation check |
|||
|
|||
IF DEBUG |
|||
public msgFormatBroken |
|||
ENDIF |
|||
|
|||
; THE FOLLOWING ONE BYTE CHARACTERS ARE THE PROMPT ANSWERS. |
|||
; THEY MUST BE LOWER CASE, AND THE UPPER TO LOWER, OR LOWER |
|||
; TO LOWER CONVERSION MUST BE DOABLE BY "OR AL,20h". |
|||
; Yes/No Answers |
|||
|
|||
Yes_Byte db "y" |
|||
No_Byte db "n" |
|||
|
|||
msgCRLF db CR, LF, 0 |
|||
|
|||
; Status messages |
|||
|
|||
msgCurrentTrack db "Head: %3d Cylinder: %4d", CR, 0 |
|||
|
|||
msgSystemTransfered db "System transferred",CR,LF,0 |
|||
|
|||
msgInterrupt db 13,10, 10, 0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgFormatComplete db "Format complete ",CR,LF,0 |
|||
|
|||
; Prompts |
|||
|
|||
msgInsertDisk db "Insert new diskette for drive %c:",CR,LF |
|||
db "and strike ENTER when ready",0 |
|||
|
|||
msgHardDiskWarning db CR,LF |
|||
db "WARNING, ALL DATA ON NON-REMOVABLE DISK",CR,LF |
|||
db "DRIVE %c: WILL BE LOST!",CR,LF |
|||
db "Proceed with Format (Y/N)?",0 |
|||
|
|||
msgFormatAnother? db "Format another (Y/N)?",0 |
|||
|
|||
msgInsertDosDisk db "Insert DOS disk in drive %c:", CR, LF |
|||
db "and strike ENTER when ready", CR, LF, 0 |
|||
|
|||
msgReInsertDisk db "Re-insert diskette for drive %c:",0 |
|||
|
|||
msgLabelPrompt db "Volume label (11 characters, ENTER for none)? ",0 |
|||
|
|||
; Disk usage messages |
|||
|
|||
msgTotalDiskSpace db "%l10d bytes total disk space", CR, LF, 0 |
|||
|
|||
msgSystemSpace db "%l10d bytes used by system", CR, LF, 0 |
|||
|
|||
msgBadSpace db "%l10d bytes in bad sectors", CR, LF, 0 |
|||
|
|||
msgDataSpace db "%l10d bytes available on disk",CR,LF,0 |
|||
|
|||
; Error messages |
|||
|
|||
msgFormatNotSupported db "Format not supported on drive %c:", CR,LF,0 |
|||
|
|||
msgInvalidDeviceParameters db "Invalid device parameters from device driver" |
|||
db CR, LF, 0 |
|||
|
|||
msgErrorInIOCTL db "Error in IOCTL call", CR, LF, 0 |
|||
|
|||
msgNotBlockDevice db "Not a block device", CR, LF, 0 |
|||
|
|||
msgFATwriteError db "Error writing FAT", CR, LF, 0 |
|||
|
|||
msgDirectoryWriteError db "Error writing directory", CR, LF, 0 |
|||
|
|||
msgAssignedDrive db "Cannot format an ASSIGNed or SUBSTed drive. ", CR, LF, 0 |
|||
|
|||
msgNeedDrive db "Drive letter must be specified",CR,LF,0 |
|||
|
|||
msgBadDosVersion db "Incorrect DOS version",CR,LF,"$" |
|||
|
|||
msgNoSystemFiles db "Cannot find System Files",CR,LF,0 |
|||
|
|||
msgTooManyFilesOpen db "Too many open files",CR,LF,0 |
|||
|
|||
msgNetDrive db "Cannot FORMAT a Network drive", CR, LF, 0 |
|||
|
|||
msgBadCharacters db "Invalid characters in volume label", CR, LF, 0 |
|||
|
|||
msgBadDrive db "Invalid drive specification", CR, LF, 0 |
|||
|
|||
msgInvalidParameter db "Invalid parameter", CR, LF, 0 |
|||
|
|||
msgParametersNotSupported db "Parameters not supported",CR,LF,0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgFormatFailure db "Format failure ",CR,LF,0 |
|||
|
|||
msgNotSystemDisk db "Disk unsuitable for system disk", CR, LF, 0 |
|||
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
; reintroduce following message for fix |
|||
msgNoRoomDestDisk db "No room for system on destination disk", CR, LF, 0 |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
|
|||
msgDiskUnusable db "Invalid media or Track 0 bad - disk unusable", CR, LF, 0 |
|||
|
|||
msgOutOfMemory db "Insufficient memory for system transfer", CR, LF, 0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgWriteProtected db "Attempted write-protect violation", CR, LF, 0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgNotReady db "Drive not ready ", CR, LF, 0 |
|||
|
|||
|
|||
msgBootWriteError db "Unable to write BOOT", CR, LF, 0 |
|||
|
|||
msgDirectoryReadError db "Error reading directory", CR, LF, 0 |
|||
|
|||
msgBadVolumeId db "Invalid Volume ID", CR, LF, 0 |
|||
|
|||
msgWhatIsVolumeId? db "Enter current Volume Label for drive %c: ", 0 |
|||
|
|||
msgIncompatibleParameters db "Parameters not compatible", CR,LF,0 |
|||
|
|||
msgIncompatibleParametersForHardDisk db "Parameters not compatible" |
|||
db " with fixed disk", CR,LF,0 |
|||
|
|||
msgBadPartitionTable db "Bad Partition Table", CR, LF, 0 |
|||
|
|||
msgParametersNotSupportedByDrive db "Parameters not Supported by Drive", CR, LF, 0 |
|||
|
|||
msgPartitionTableReadError db "Error reading partition table", CR, LF, 0 |
|||
|
|||
msgPartitionTableWriteError db "Error writing partition table", CR, LF, 0 |
|||
|
|||
IF DEBUG |
|||
msgFormatBroken db "Format Broken", CR, LF, 0 |
|||
ENDIF |
|||
|
@ -0,0 +1,9 @@ |
|||
; SCCSID = @(#)bootmes.inc 1.1 85/04/18 |
|||
|
|||
; Message Include file for OEMFOR.ASM |
|||
|
|||
; THIS IS A SPECIAL MESSAGE WHICH IS INCLUDED IN THE "FAKE" IO.SYS |
|||
; FILE PLACED ON DISKS FORMATTED /B. NOTE THAT IT IS NUL TERMINATED. |
|||
|
|||
NO_SYS_MESS: |
|||
DB "Non-System disk or disk error",13,10,0 |
@ -0,0 +1,6 @@ |
|||
|
|||
%out ..filesize.inc |
|||
|
|||
BIOS_SIZE equ 22528 ; actually 22341 |
|||
DOS_SIZE equ 30208 ; actually 30128 |
|||
|
3032
SRC/CMD/FORMAT/FORMAT.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,2 @@ |
|||
format.obj forproc.obj messages.obj oemfor.obj ..\..\libc\printf.obj |
|||
format.exe /m; |
@ -0,0 +1,141 @@ |
|||
; SCCSID = @(#)forproc.asm 1.2 85/07/25 |
|||
.xlist |
|||
.xcref |
|||
BREAK MACRO subtitle |
|||
SUBTTL subtitle |
|||
PAGE |
|||
ENDM |
|||
|
|||
INCLUDE SYSCALL.INC |
|||
.cref |
|||
.list |
|||
data segment public 'DATA' |
|||
data ends |
|||
|
|||
code segment public 'CODE' |
|||
assume cs:code,ds:data |
|||
|
|||
PUBLIC FormatAnother?,Yes?,REPORT,USER_STRING |
|||
public fdsksiz,badsiz,syssiz,datasiz,biosiz |
|||
|
|||
extrn std_printf:near,crlf:near,PrintString:near |
|||
|
|||
data segment |
|||
extrn driveLetter:byte |
|||
|
|||
; In formes.asm |
|||
extrn msgInsertDisk:byte |
|||
extrn msgFormatAnother?:byte |
|||
extrn msgTotalDiskSpace:byte |
|||
extrn msgSystemSpace:byte |
|||
extrn msgBadSpace:byte |
|||
extrn msgDataSpace:byte |
|||
extrn yes_byte:byte |
|||
extrn no_byte:byte |
|||
|
|||
extrn inbuff:byte |
|||
|
|||
ptr_msgTotalDiskSpace dw offset msgTotalDiskSpace |
|||
fdsksiz dd 0 |
|||
|
|||
ptr_msgSystemSpace dw offset msgSystemSpace |
|||
syssiz dd 0 |
|||
biosiz dd 0 |
|||
|
|||
ptr_msgBadSpace dw offset msgBadSpace |
|||
badsiz dd 0 |
|||
|
|||
ptr_msgDataSpace dw offset msgDataSpace |
|||
datasiz dd 0 |
|||
|
|||
ptr_msgInsertDisk dw offset msgInsertDisk |
|||
dw offset driveLetter |
|||
data ends |
|||
|
|||
FormatAnother? proc near |
|||
; Wait for key. If yes return carry clear, else no. Insures |
|||
; explicit Y or N answer. |
|||
lea dx, msgFormatAnother? |
|||
call PrintString |
|||
CALL Yes? |
|||
JNC WAIT20 |
|||
JZ WAIT20 |
|||
CALL CRLF |
|||
JMP SHORT FormatAnother? |
|||
FormatAnother? endp |
|||
|
|||
Yes? proc near |
|||
|
|||
; Wait for key. If YES return carry clear,else carry set. |
|||
; If carry is set, Z is set if explicit NO, else key was not Yes or No. |
|||
CALL USER_STRING |
|||
JNZ GETBYT |
|||
XOR AL,AL ; So that CMP with [NO_BYTE] is NZ |
|||
JMP SHORT CHECK_NO |
|||
|
|||
GETBYT: |
|||
MOV AL,BYTE PTR [INBUFF+2] |
|||
OR AL,20H ; Convert to lower case |
|||
CMP AL,[YES_BYTE] |
|||
JZ WAIT20 ; Carry clear if jump |
|||
CHECK_NO: |
|||
CMP AL,[NO_BYTE] |
|||
STC ; Set carry (wasn't Yes) |
|||
WAIT20: RET |
|||
|
|||
Yes? endp |
|||
|
|||
USER_STRING: |
|||
; Get a string from user. Z is set if user typed no chars (imm CR) |
|||
; We need to flush a second time to get rid of incoming Kanji characters also. |
|||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 ; Clean out input |
|||
INT 21H |
|||
MOV DX,OFFSET INBUFF |
|||
MOV AH,STD_CON_STRING_INPUT |
|||
INT 21H |
|||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 ; Clean out input |
|||
INT 21H |
|||
CMP BYTE PTR [INBUFF+1],0 |
|||
RET |
|||
|
|||
;********************************************* |
|||
; Make a status report including the following information: |
|||
; Total disk capacity |
|||
; Total system area used |
|||
; Total bad space allocated |
|||
; Total data space available |
|||
|
|||
REPORT: |
|||
lea dx, ptr_msgTotalDiskSpace |
|||
call std_printf |
|||
cmp WORD PTR SYSSIZ,0 |
|||
JNZ SHOWSYS |
|||
cmp WORD PTR SYSSIZ+2,0 |
|||
JZ CHKBAD |
|||
SHOWSYS: |
|||
MOV dx,OFFSET ptr_msgSystemSpace |
|||
CALL std_printf ;Report space used by system |
|||
CHKBAD: |
|||
cmp WORD PTR BADSIZ,0 |
|||
JNZ SHOWBAD |
|||
cmp WORD PTR BADSIZ+2,0 |
|||
JZ SHOWDATA |
|||
SHOWBAD: |
|||
lea dx, ptr_msgBadSpace |
|||
call std_printf |
|||
SHOWDATA: |
|||
MOV CX,WORD PTR FDSKSIZ |
|||
MOV BX,WORD PTR FDSKSIZ+2 |
|||
SUB CX,WORD PTR BADSIZ |
|||
SBB BX,WORD PTR BADSIZ+2 |
|||
SUB CX,WORD PTR SYSSIZ |
|||
SBB BX,WORD PTR SYSSIZ+2 |
|||
MOV word ptr datasiz,CX |
|||
MOV word ptr datasiz+2,BX |
|||
lea dx, ptr_msgDataSpace |
|||
call std_printf |
|||
call crlf |
|||
RET |
|||
|
|||
code ends |
|||
end |
@ -0,0 +1,58 @@ |
|||
#** makefile for format |
|||
|
|||
DEST =format |
|||
MSG =messages |
|||
|
|||
# Path definitions |
|||
|
|||
BIOS =..\..\BIOS |
|||
BOOT =..\..\BOOT |
|||
DOS =..\..\DOS |
|||
|
|||
# Definitions for assembler |
|||
|
|||
ASM =masm |
|||
AFLAGS =-Mx -t |
|||
AINC =-I..\..\inc -I$(DOS) |
|||
|
|||
# Definitions for C compiler |
|||
|
|||
CC =cl |
|||
CFLAGS =-c -Ox -Zlp |
|||
CINC =-I..\..\h |
|||
|
|||
# Definitions for linker |
|||
|
|||
LINK =link |
|||
LIBC =..\..\libc |
|||
|
|||
|
|||
# Rules and Dependencies follow |
|||
|
|||
filesize.inc: $(DOS)\msdos.sys $(BIOS)\io.sys |
|||
GWBASIC MAKE_INC |
|||
|
|||
FORMAT.OBJ: FORMAT.ASM $(DOS)\DOSMAC.INC $(DOS)\BPB.INC \ |
|||
$(DOS)\DIRENT.INC $(DOS)\DPB.INC $(DOS)\CURDIR.INC \ |
|||
$(DOS)\CPMFCB.INC $(DOS)\PDB.INC \ |
|||
$(DOS)\ERROR.INC $(DOS)\SYSCALL.INC $(DOS)\IOCTL.INC |
|||
masm $(AFLAGS) $(AINC) FORMAT; |
|||
|
|||
$(MSG).OBJ: $(MSG).ASM $(MSG).inc |
|||
masm $(AFLAGS) $(AINC) $(MSG); |
|||
|
|||
FORPROC.OBJ: FORPROC.ASM $(DOS)\SYSCALL.INC |
|||
masm $(AFLAGS) $(AINC) FORPROC; |
|||
|
|||
OEMFOR.OBJ: OEMFOR.ASM $(DOS)\DOSMAC.INC $(DOS)\SYSCALL.INC $(DOS)\BPB.INC \ |
|||
$(DOS)\DIRENT.INC bootmes.inc $(DOS)\IOCTL.INC \ |
|||
$(BOOT)\BOOT.INC $(BOOT)\BOOT11.INC filesize.inc |
|||
masm $(AFLAGS) $(AINC) OEMFOR; |
|||
|
|||
$(LIBC)\printf.obj: $(LIBC)\printf.asm |
|||
masm $(AFLAGS) $(AINC) $(LIBC)\printf,$(LIBC)\printf; |
|||
|
|||
FORMAT.EXE: FORMAT.OBJ FORPROC.OBJ $(MSG).OBJ OEMFOR.OBJ $(LIBC)\PRINTF.OBJ |
|||
LINK @FORMAT.LNK |
|||
convert format.exe |
|||
del format.exe |
@ -0,0 +1,68 @@ |
|||
; SCCSID = @(#)messages.asm 1.10 85/08/13 |
|||
TITLE FORMAT Messages |
|||
|
|||
data segment public 'DATA' |
|||
|
|||
public Yes_Byte |
|||
public No_Byte |
|||
public msgCRLF |
|||
public msgCurrentTrack |
|||
public msgSystemTransfered |
|||
public msgFormatComplete |
|||
public msgInterrupt |
|||
public msgInsertDisk |
|||
public msgHardDiskWarning |
|||
public msgFormatAnother? |
|||
public msgInsertDosDisk |
|||
public msgReInsertDisk |
|||
public msgLabelPrompt |
|||
public msgTotalDiskSpace |
|||
public msgSystemSpace |
|||
public msgBadSpace |
|||
public msgDataSpace |
|||
public msgFormatNotSupported |
|||
public msgInvalidDeviceParameters |
|||
public msgErrorInIOCTL |
|||
public msgNotBlockDevice |
|||
public msgFATwriteError |
|||
public msgDirectoryWriteError |
|||
public msgAssignedDrive |
|||
public msgNeedDrive |
|||
public msgBadDosVersion |
|||
public msgNoSystemFiles |
|||
public msgTooManyFilesOpen |
|||
public msgNetDrive |
|||
public msgBadCharacters |
|||
public msgBadDrive |
|||
public msgInvalidParameter |
|||
public msgParametersNotSupported |
|||
public msgFormatFailure |
|||
public msgNotSystemDisk |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
; reintroduce following public for fix |
|||
; public msgNoRoomDestDisk |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
public msgDiskUnusable |
|||
public msgOutOfMemory |
|||
public msgWriteProtected |
|||
public msgNotReady |
|||
public msgBootWriteError |
|||
public msgDirectoryReadError |
|||
public msgBadVolumeId |
|||
public msgWhatIsVolumeId? |
|||
public msgIncompatibleParameters |
|||
public msgIncompatibleParametersForHardDisk |
|||
public msgBadPartitionTable |
|||
public msgParametersNotSupportedByDrive |
|||
public msgPartitionTableReadError |
|||
public msgPartitionTableWriteError |
|||
|
|||
CR equ 13 |
|||
LF equ 10 |
|||
|
|||
; Oem dependent messages |
|||
|
|||
include messages.inc |
|||
|
|||
data ends |
|||
END |
@ -0,0 +1,139 @@ |
|||
; SCCSID = @(#)messages.inc 1.6 85/08/02 |
|||
|
|||
DEBUG EQU 0 ; for Boot sector installation check |
|||
|
|||
IF DEBUG |
|||
public msgFormatBroken |
|||
ENDIF |
|||
|
|||
; THE FOLLOWING ONE BYTE CHARACTERS ARE THE PROMPT ANSWERS. |
|||
; THEY MUST BE LOWER CASE, AND THE UPPER TO LOWER, OR LOWER |
|||
; TO LOWER CONVERSION MUST BE DOABLE BY "OR AL,20h". |
|||
; Yes/No Answers |
|||
|
|||
Yes_Byte db "y" |
|||
No_Byte db "n" |
|||
|
|||
msgCRLF db CR, LF, 0 |
|||
|
|||
; Status messages |
|||
|
|||
msgCurrentTrack db "Head: %3d Cylinder: %4d", CR, 0 |
|||
|
|||
msgSystemTransfered db "System transferred",CR,LF,0 |
|||
|
|||
msgInterrupt db 13,10, 10, 0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgFormatComplete db "Format complete ",CR,LF,0 |
|||
|
|||
; Prompts |
|||
|
|||
msgInsertDisk db "Insert new diskette for drive %c:",CR,LF |
|||
db "and strike ENTER when ready",0 |
|||
|
|||
msgHardDiskWarning db CR,LF |
|||
db "WARNING, ALL DATA ON NON-REMOVABLE DISK",CR,LF |
|||
db "DRIVE %c: WILL BE LOST!",CR,LF |
|||
db "Proceed with Format (Y/N)?",0 |
|||
|
|||
msgFormatAnother? db "Format another (Y/N)?",0 |
|||
|
|||
msgInsertDosDisk db "Insert DOS disk in drive %c:", CR, LF |
|||
db "and strike ENTER when ready", CR, LF, 0 |
|||
|
|||
msgReInsertDisk db "Re-insert diskette for drive %c:",0 |
|||
|
|||
msgLabelPrompt db "Volume label (11 characters, ENTER for none)? ",0 |
|||
|
|||
; Disk usage messages |
|||
|
|||
msgTotalDiskSpace db "%l10d bytes total disk space", CR, LF, 0 |
|||
|
|||
msgSystemSpace db "%l10d bytes used by system", CR, LF, 0 |
|||
|
|||
msgBadSpace db "%l10d bytes in bad sectors", CR, LF, 0 |
|||
|
|||
msgDataSpace db "%l10d bytes available on disk",CR,LF,0 |
|||
|
|||
; Error messages |
|||
|
|||
msgFormatNotSupported db "Format not supported on drive %c:", CR,LF,0 |
|||
|
|||
msgInvalidDeviceParameters db "Invalid device parameters from device driver" |
|||
db CR, LF, 0 |
|||
|
|||
msgErrorInIOCTL db "Error in IOCTL call", CR, LF, 0 |
|||
|
|||
msgNotBlockDevice db "Not a block device", CR, LF, 0 |
|||
|
|||
msgFATwriteError db "Error writing FAT", CR, LF, 0 |
|||
|
|||
msgDirectoryWriteError db "Error writing directory", CR, LF, 0 |
|||
|
|||
msgAssignedDrive db "Cannot format an ASSIGNed or SUBSTed drive. ", CR, LF, 0 |
|||
|
|||
msgNeedDrive db "Drive letter must be specified",CR,LF,0 |
|||
|
|||
msgBadDosVersion db "Incorrect DOS version",CR,LF,"$" |
|||
|
|||
msgNoSystemFiles db "Cannot find System Files",CR,LF,0 |
|||
|
|||
msgTooManyFilesOpen db "Too many open files",CR,LF,0 |
|||
|
|||
msgNetDrive db "Cannot FORMAT a Network drive", CR, LF, 0 |
|||
|
|||
msgBadCharacters db "Invalid characters in volume label", CR, LF, 0 |
|||
|
|||
msgBadDrive db "Invalid drive specification", CR, LF, 0 |
|||
|
|||
msgInvalidParameter db "Invalid parameter", CR, LF, 0 |
|||
|
|||
msgParametersNotSupported db "Parameters not supported",CR,LF,0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgFormatFailure db "Format failure ",CR,LF,0 |
|||
|
|||
msgNotSystemDisk db "Disk unsuitable for system disk", CR, LF, 0 |
|||
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
; reintroduce following message for fix |
|||
;msgNoRoomDestDisk db "No room for system on destination disk", CR, LF, 0 |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bug007sp |
|||
|
|||
msgDiskUnusable db "Invalid media or Track 0 bad - disk unusable", CR, LF, 0 |
|||
|
|||
msgOutOfMemory db "Insufficient memory for system transfer", CR, LF, 0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgWriteProtected db "Attempted write-protect violation", CR, LF, 0 |
|||
|
|||
; Note: This message must be long enough to wipe out message msgCurrentTrack |
|||
msgNotReady db "Drive not ready ", CR, LF, 0 |
|||
|
|||
|
|||
msgBootWriteError db "Unable to write BOOT", CR, LF, 0 |
|||
|
|||
msgDirectoryReadError db "Error reading directory", CR, LF, 0 |
|||
|
|||
msgBadVolumeId db "Invalid Volume ID", CR, LF, 0 |
|||
|
|||
msgWhatIsVolumeId? db "Enter current Volume Label for drive %c: ", 0 |
|||
|
|||
msgIncompatibleParameters db "Parameters not compatible", CR,LF,0 |
|||
|
|||
msgIncompatibleParametersForHardDisk db "Parameters not compatible" |
|||
db " with fixed disk", CR,LF,0 |
|||
|
|||
msgBadPartitionTable db "Bad Partition Table", CR, LF, 0 |
|||
|
|||
msgParametersNotSupportedByDrive db "Parameters not Supported by Drive", CR, LF, 0 |
|||
|
|||
msgPartitionTableReadError db "Error reading partition table", CR, LF, 0 |
|||
|
|||
msgPartitionTableWriteError db "Error writing partition table", CR, LF, 0 |
|||
|
|||
IF DEBUG |
|||
msgFormatBroken db "Format Broken", CR, LF, 0 |
|||
ENDIF |
|||
|
1204
SRC/CMD/FORMAT/OEMFOR.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,14 @@ |
|||
make=msmake /I makefile |
|||
|
|||
all: |
|||
cd format |
|||
$(make) |
|||
cd ..\print |
|||
$(make) |
|||
cd ..\sort |
|||
$(make) |
|||
cd ..\sys |
|||
$(make) |
|||
cd .. |
|||
|
|||
|
@ -0,0 +1,61 @@ |
|||
#** makefile for print |
|||
|
|||
DEST =print |
|||
MSG =messages |
|||
|
|||
# Path definitions |
|||
|
|||
BIOS =..\..\BIOS |
|||
DOS =..\..\DOS |
|||
|
|||
# Definitions for assembler |
|||
|
|||
ASM =masm |
|||
AFLAGS =-Mx -t |
|||
AINC =-I..\..\inc -I$(DOS) |
|||
|
|||
# Definitions for C compiler |
|||
|
|||
CC =cl |
|||
CFLAGS =-c -Ox -Zlp |
|||
CINC =-I..\..\h |
|||
|
|||
# Definitions for linker |
|||
|
|||
LINK =link |
|||
LIBC =..\..\libc |
|||
|
|||
|
|||
# Rules and Dependencies follow |
|||
|
|||
PRINT_RM.OBJ: PRINT_RM.ASM print_rm.inc PRIDEFS.inc \ |
|||
$(DOS)\DEVSYM.INC $(DOS)\SYSCALL.INC $(DOS)\ERROR.INC \ |
|||
$(DOS)\SYSVAR.INC $(DOS)\FIND.INC |
|||
masm $(AFLAGS) $(AINC) PRINT_RM; |
|||
|
|||
PRINT_R.OBJ: PRINT_R.ASM PRIDEFS.inc \ |
|||
$(DOS)\DEVSYM.INC $(DOS)\SYSCALL.INC $(DOS)\ERROR.INC \ |
|||
$(DOS)\SYSVAR.INC $(DOS)\FIND.INC |
|||
masm $(AFLAGS) $(AINC) PRINT_R; |
|||
|
|||
PRINT_T.OBJ: PRINT_T.ASM PRIDEFS.inc \ |
|||
$(DOS)\DEVSYM.INC $(DOS)\SYSCALL.INC $(DOS)\ERROR.INC \ |
|||
$(DOS)\SYSVAR.INC $(DOS)\FIND.INC |
|||
masm $(AFLAGS) $(AINC) PRINT_T; |
|||
|
|||
PRINT_TM.OBJ: PRINT_TM.ASM print_tm.inc PRIDEFS.inc \ |
|||
$(DOS)\DEVSYM.INC $(DOS)\SYSCALL.INC $(DOS)\ERROR.INC \ |
|||
$(DOS)\SYSVAR.INC $(DOS)\FIND.INC |
|||
masm $(AFLAGS) $(AINC) PRINT_TM; |
|||
|
|||
NPRINTF.OBJ: NPRINTF.ASM PRIDEFS.inc \ |
|||
$(DOS)\DEVSYM.INC $(DOS)\SYSCALL.INC $(DOS)\ERROR.INC \ |
|||
$(DOS)\SYSVAR.INC $(DOS)\FIND.INC |
|||
masm $(AFLAGS) $(AINC) NPRINTF; |
|||
|
|||
PRINT.EXE: PRINT_RM.OBJ PRINT_R.OBJ PRINT_T.OBJ \ |
|||
PRINT_TM.OBJ NPRINTF.OBJ |
|||
LINK @PRINT.LNK |
|||
CONVERT PRINT.EXE |
|||
DEL PRINT.EXE |
|||
|
@ -0,0 +1,386 @@ |
|||
; SCCSID = @(#)nprintf.asm 4.1 85/07/17 |
|||
INCLUDE pridefs.inc |
|||
|
|||
|
|||
BREAK <Message Printing Routine> |
|||
|
|||
; |
|||
; MSDOS V3.00 PRINT |
|||
; |
|||
; Message Printing Routine |
|||
; |
|||
|
|||
|
|||
DATA SEGMENT PUBLIC BYTE |
|||
|
|||
extrn crlf_ptr:word |
|||
|
|||
Public NPR001S, NPR001E |
|||
NPR001S equ $ |
|||
|
|||
PRINTF_LEFT DB 0 |
|||
PRINTF_LONG DB 0 |
|||
PRINTF_HEX DB 0 |
|||
TABLE_INDEX DB 0 |
|||
S_FLAG DB 0 |
|||
PRINTF_WIDTH DW 0 |
|||
PRINTF_BASE DW 0 |
|||
PAD_CHAR DB " " |
|||
|
|||
PRINTF_TABLE DB "0123456789ABCDEFabcdef" |
|||
|
|||
PRINTF_STACK STRUC |
|||
OLDES DW ? |
|||
OLDDS DW ? |
|||
OLDSI DW ? |
|||
OLDDI DW ? |
|||
OLDAX DW ? |
|||
OLDBX DW ? |
|||
OLDCX DW ? |
|||
OLDBP DW ? |
|||
STRING DW ? |
|||
OLDCS DW ? |
|||
PRINTF_STACK ENDS |
|||
|
|||
PRINTF_ARGS STRUC |
|||
CONSTR DW ? |
|||
ARG DW ? |
|||
PRINTF_ARGS ENDS |
|||
|
|||
BUFSIZ EQU 20 |
|||
PRINTF_BUF DB BUFSIZ DUP (?) |
|||
db 0 ;This buffer is always nul terminated |
|||
BUFEND DW $-PRINTF_BUF |
|||
|
|||
NPR001E equ $ |
|||
|
|||
DATA ENDS |
|||
|
|||
|
|||
Code Segment public para |
|||
|
|||
ASSUME CS:DG,DS:nothing,ES:nothing,SS:Stack |
|||
|
|||
PUBLIC PRINTF,STD_PRINTF,PRINTF_CRLF |
|||
|
|||
PRINTF_CRLF: |
|||
CALL STD_PRINTF |
|||
crlf2: |
|||
mov dx,offset dg:crlf_ptr |
|||
STD_PRINTF: |
|||
PUSH DX |
|||
PRINTF: |
|||
PUSH BP ;Save the callers' registers |
|||
PUSH CX |
|||
PUSH BX |
|||
PUSH AX |
|||
PUSH DI |
|||
PUSH SI |
|||
PUSH ES |
|||
PUSH DS |
|||
MOV BP,SP |
|||
PUSH CS |
|||
POP ES ;ES points to Printf segment |
|||
CALL Clear_flags ; initialize the world |
|||
|
|||
MOV DI,DS |
|||
MOV SI,ES |
|||
CMP SI,DI |
|||
JZ S |
|||
HLT |
|||
S: |
|||
|
|||
MOV DI,OFFSET DG:PRINTF_BUF ;DI points to the output buffer |
|||
MOV BP,[BP.STRING] ;BP points to the argument list |
|||
MOV SI,DS:[BP] ;SI points to the control string |
|||
XOR BX,BX ;BX is the index into the arg list |
|||
GET_CHAR: |
|||
LODSB ;Get a character |
|||
CMP AL,"%" ;Is it a conversion specifier? |
|||
JZ CONV_CHAR ;Yes - find out which one |
|||
OR AL,AL ;Is it the end of the control string? |
|||
JZ PRINTF_DONE ;Yes - then we're done |
|||
CALL OUTCHR ;Otherwise store the character |
|||
JMP SHORT GET_CHAR ;And go get another |
|||
|
|||
PRINTF_DONE: |
|||
CALL FLUSH |
|||
POP DS |
|||
POP ES |
|||
POP SI |
|||
POP DI |
|||
POP AX |
|||
POP BX |
|||
POP CX |
|||
POP BP |
|||
POP DX |
|||
RET |
|||
|
|||
PRINTF_PERCENT: |
|||
CALL OUTCHR |
|||
JMP GET_CHAR |
|||
|
|||
CONV_CHAR: |
|||
;Look for any format specifiers preceeding the conversion character |
|||
LODSB |
|||
CMP AL,"%" ;Just print the % |
|||
JZ PRINTF_PERCENT |
|||
CMP AL,"-" ;Right justify the field |
|||
JZ LEFT_ADJ |
|||
CMP AL,"+" ;Left justify the field |
|||
JZ NXT_CONV_CHAR |
|||
CMP AL,"L" ;Is it a long integer |
|||
JZ LONG_INT |
|||
CMP AL,"l" |
|||
JZ LONG_INT |
|||
CMP AL,"0" ;Is it a precision specification |
|||
JB LOOK_CONV_CHAR |
|||
CMP AL,"9" |
|||
JA LOOK_CONV_CHAR |
|||
CMP AL,"0" |
|||
JNZ NOT_PAD |
|||
CMP CS:[PRINTF_WIDTH],0 |
|||
JNZ NOT_PAD |
|||
MOV CS:BYTE PTR [PAD_CHAR],"0" |
|||
NOT_PAD: |
|||
PUSH AX ;Adjust decimal place on precision |
|||
MOV AX,10 |
|||
MUL CS:[PRINTF_WIDTH] |
|||
MOV CS:[PRINTF_WIDTH],AX |
|||
POP AX |
|||
XOR AH,AH |
|||
SUB AL,"0" |
|||
ADD CS:[PRINTF_WIDTH],AX ;And save the total |
|||
JMP SHORT NXT_CONV_CHAR |
|||
|
|||
;Set the correct flags for the options in a conversion |
|||
|
|||
LEFT_ADJ: |
|||
INC CS:BYTE PTR[PRINTF_LEFT] |
|||
JMP SHORT NXT_CONV_CHAR |
|||
|
|||
LONG_INT: |
|||
INC CS:BYTE PTR[PRINTF_LONG] |
|||
NXT_CONV_CHAR: |
|||
JMP CONV_CHAR |
|||
|
|||
;Look for a conversion character |
|||
|
|||
LOOK_CONV_CHAR: |
|||
CMP AL,"X" |
|||
JZ HEX_UP |
|||
|
|||
;Make all other conversion characters upper case |
|||
|
|||
CMP AL,"a" |
|||
JB CAPS |
|||
CMP AL,"z" |
|||
JG CAPS |
|||
AND AL,0DFH |
|||
CAPS: |
|||
CMP AL,"X" |
|||
JZ HEX_LO |
|||
CMP AL,"D" |
|||
JZ DECIMAL |
|||
CMP AL,"C" |
|||
JZ C_PUT_CHAR |
|||
CMP AL,"S" |
|||
JZ S_PUT_STRG |
|||
|
|||
;Didn't find any legal conversion character - IGNORE it |
|||
|
|||
call clear_flags |
|||
jmp get_char |
|||
|
|||
HEX_LO: |
|||
MOV CS:[TABLE_INDEX],6 ;Will print lower case hex digits |
|||
HEX_UP: |
|||
MOV CS:[PRINTF_BASE],16 ;Hex conversion |
|||
JMP CONV_TO_NUM |
|||
|
|||
DECIMAL: |
|||
MOV CS:[PRINTF_BASE],10 ;Decimal conversion |
|||
JMP CONV_TO_NUM |
|||
|
|||
S_PUT_STRG: |
|||
INC CS:[S_FLAG] ;It's a string specifier |
|||
C_PUT_CHAR: |
|||
PUSH SI ;Save pointer to control string |
|||
MOV SI,BX |
|||
ADD BX,2 |
|||
MOV SI,ds:[BP+SI.ARG] ;Point to the % string or character |
|||
CMP BYTE PTR CS:[S_FLAG],0 |
|||
JNZ S_PUT_1 |
|||
LODSB |
|||
cmp al,0 |
|||
jz short c_s_end |
|||
CALL OUTCHR ;Put it into our buffer |
|||
JMP SHORT C_S_END |
|||
|
|||
S_PUT_1: |
|||
mov cx,cs:[printf_width] |
|||
or cx,cx |
|||
jz s_put_2 |
|||
cmp cs:byte ptr[printf_left],0 |
|||
jnz s_put_2 |
|||
push si |
|||
call Pad_string |
|||
pop si |
|||
s_put_2: |
|||
push si |
|||
s_put_3: |
|||
LODSB ;Put them all in our buffer |
|||
CMP AL,0 |
|||
jz s_put_4 |
|||
CALL OUTCHR |
|||
jmp short S_PUT_3 |
|||
s_put_4: |
|||
pop si |
|||
cmp byte ptr[printf_left],0 |
|||
jz c_s_end |
|||
mov cx,cs:[printf_width] |
|||
or cx,cx |
|||
jz c_s_end |
|||
call Pad_string |
|||
C_S_END: |
|||
call clear_flags |
|||
POP SI ;Restore control string pointer |
|||
JMP GET_CHAR ;Go get another character |
|||
|
|||
pad_string: |
|||
xor dx,dx |
|||
count_loop: |
|||
lodsb |
|||
or al,al |
|||
jz count_done |
|||
inc dx |
|||
jmp short count_loop |
|||
count_done: |
|||
sub cx,dx |
|||
jbe count_ret |
|||
call pad |
|||
count_ret: |
|||
ret |
|||
|
|||
CONV_TO_NUM: |
|||
|
|||
PUSH SI ;Save pointer to control string |
|||
MOV SI,BX ;Get index into argument list |
|||
ADD BX,2 ;Increment the index |
|||
MOV AX,ds:[BP+SI.ARG] ;Lo word of number in SI |
|||
CMP BYTE PTR CS:[PRINTF_LONG],0 ;Is this is a short or long integer? |
|||
JZ NOT_LONG_INT |
|||
MOV SI,BX ;Copy index |
|||
ADD BX,2 ;Increment the index |
|||
MOV DX,ds:[BP+SI.ARG] ;Hi word of number in BP |
|||
JMP SHORT DO_CONV |
|||
NOT_LONG_INT: |
|||
XOR DX,DX ;Hi word is zero |
|||
DO_CONV: |
|||
PUSH BX ;Save index into arguemnt list |
|||
MOV si,CS:[PRINTF_BASE] |
|||
MOV cx,CS:[PRINTF_WIDTH] |
|||
CALL PNUM |
|||
CALL PAD |
|||
CONV_DONE: |
|||
call clear_flags |
|||
POP BX |
|||
POP SI |
|||
jmp get_char |
|||
|
|||
PNUM: |
|||
DEC CX |
|||
PUSH AX |
|||
MOV AX,DX |
|||
XOR DX,DX |
|||
DIV SI |
|||
MOV BX,AX |
|||
POP AX |
|||
DIV SI |
|||
XCHG BX,DX |
|||
PUSH AX |
|||
OR AX,DX |
|||
POP AX |
|||
JZ DO_PAD |
|||
PUSH BX |
|||
CALL PNUM |
|||
POP BX |
|||
JMP SHORT REM |
|||
DO_PAD: |
|||
CMP CS:BYTE PTR[PRINTF_LEFT],0 |
|||
JNZ REM |
|||
CALL PAD |
|||
REM: |
|||
MOV AX,BX |
|||
CMP AL,10 |
|||
JB NOT_HEX |
|||
CMP CS:BYTE PTR [PRINTF_HEX],0 |
|||
JNZ NOT_HEX |
|||
ADD AL,CS:BYTE PTR [TABLE_INDEX] |
|||
NOT_HEX: |
|||
MOV BX,OFFSET dg:PRINTF_TABLE |
|||
PUSH DS |
|||
PUSH CS |
|||
POP DS |
|||
XLAT 0 |
|||
POP DS |
|||
push cx |
|||
CALL OUTCHR |
|||
pop cx |
|||
RET |
|||
|
|||
PAD: |
|||
OR CX,CX |
|||
JLE PAD_DONE |
|||
MOV AL,CS:BYTE PTR [PAD_CHAR] |
|||
PAD_LOOP: |
|||
push cx |
|||
CALL OUTCHR |
|||
pop cx |
|||
LOOP PAD_LOOP |
|||
PAD_DONE: |
|||
RET |
|||
|
|||
OUTCHR: |
|||
STOSB |
|||
CMP DI,offset dg:bufend-1 ;Don't count the nul |
|||
jz foob2 |
|||
ret |
|||
foob2: |
|||
MOV CX,BUFSIZ |
|||
WRITE_CHARS: |
|||
push bx |
|||
MOV BX,1 |
|||
push ds |
|||
PUSH CS |
|||
POP DS |
|||
MOV DX,OFFSET dg:PRINTF_BUF |
|||
MOV AH,WRITE |
|||
INT 21H |
|||
pop ds |
|||
pop bx |
|||
MOV DI,OFFSET dg:PRINTF_BUF |
|||
RET |
|||
|
|||
FLUSH: |
|||
CMP DI,OFFSET dg:PRINTF_BUF |
|||
jnz foob1 |
|||
ret |
|||
foob1: |
|||
SUB DI,OFFSET dg:PRINTF_BUF |
|||
MOV CX,DI |
|||
call write_chars |
|||
ret |
|||
|
|||
CLEAR_FLAGS: |
|||
XOR ax,ax |
|||
MOV BYTE PTR CS:[PRINTF_LEFT],al ;Reset justifing flag |
|||
MOV BYTE PTR CS:[PRINTF_LONG],al ;Reset long flag |
|||
MOV BYTE PTR CS:[TABLE_INDEX],al ;Reset hex table index |
|||
MOV CS:[PRINTF_WIDTH],ax ;Reinitialize width to 0 |
|||
MOV BYTE PTR CS:[PAD_CHAR]," " ;Reset padding character |
|||
MOV BYTE PTR CS:[S_FLAG],al ;Clear the string flag |
|||
ret |
|||
|
|||
Code Ends |
|||
End |
@ -0,0 +1,213 @@ |
|||
; SCCSID = @(#)pridefs.asm 4.4 85/07/17 |
|||
title 3.00 Print Utility |
|||
|
|||
;MS-DOS PSPRINT/PRINT program for background printing of text files |
|||
; to the list device. |
|||
; |
|||
; IBM SERVER VERSION |
|||
; |
|||
; INT 28H is a software interrupt generated by the DOS |
|||
; in its I/O wait loops. This spooler can be assembled for |
|||
; operation using only this interrupt which is portable from |
|||
; system to system. It may also be assembled to use a hardware |
|||
; timer interrupt in addition to the software INT 28H. The |
|||
; purpose of using hardware interrupts is to allow printing to |
|||
; continue during programs which do not enter the system and |
|||
; therefore causes the INT 28H to go away. A timer interrupt is |
|||
; chosen in preference to a "printer buffer empty" interrupt |
|||
; because PRINT in the timer form is generic. It can be given |
|||
; the name of any currently installed character device as the |
|||
; "printer", this makes it portable to devices which are |
|||
; installed by the user even in the hardware case. It could be |
|||
; modified to use a buffer empty interrupt (no code is given for |
|||
; this case), if this is done the PROMPT and BADMES messages and |
|||
; their associated code should be removed as PRINT will then be |
|||
; device specific. |
|||
; |
|||
; V1.00 07/03/82 |
|||
; V2.00 07/05/83 A.Reynolds |
|||
; New INT 2FH interface, Pathnames, context switch. |
|||
; V2.50 09/14/83 M.A.Ulloa |
|||
; Turned it back to a print |
|||
; 11/21/83 M.A.Ulloa |
|||
; Repaired bug in file cancel code |
|||
; 11/28/83 M.A.Ulloa |
|||
; Added int 23 and 24 handlers to transient. |
|||
; 01/27/84 M.A.Ulloa |
|||
; Allways checks for valid drive. |
|||
; V3.00 02/03/84 M.A.Ulloa |
|||
; Partitioned so as to assemble on a PC |
|||
; By the by, it is V3.00 now. |
|||
; 05/23/85 K.G.Schulmeisters |
|||
; Chains into INT19 (bootstrap) to unhook |
|||
; INT_1C (timer) and INT_15 (AT's Wait On Event) |
|||
; |
|||
|
|||
|
|||
; Aaron's rambling: |
|||
; |
|||
; BEWARE ALL YEE WHO ENTER HERE. |
|||
; PRINT is an amazingly complex program. MS-DOS versions below 3.00 are |
|||
; NOT re-entrant, this means that this utility is basically not a |
|||
; possibility. It gets by on the fact that it is written by the same |
|||
; person who wrote the OS. Since you are not that person, you must be very |
|||
; careful about making any modification to this utility. There are a |
|||
; number of things which may seem to be unnecessary on first examination. |
|||
; BEWARE, almost every line of code is there for a very good reason. The |
|||
; order of things is very carefully chosen. PRINT is full of potential |
|||
; windows, make sure that you do not open one by careless modification. Do |
|||
; not look for a lot of help from the comments, a complete explanation |
|||
; would probably fill a book. A succesful modifier will have an in-depth |
|||
; knowledge of the internal function of MS-DOS, and of the PRINT utility |
|||
; itself through in depth study of the comments AND the code. |
|||
|
|||
|
|||
subttl General Definition |
|||
page |
|||
|
|||
|
|||
FALSE EQU 0 |
|||
TRUE EQU NOT FALSE |
|||
|
|||
;IBM EQU TRUE |
|||
;IBMVER EQU IBM |
|||
;MSVER EQU FALSE |
|||
|
|||
include version.inc |
|||
|
|||
IF MSVER |
|||
HARDINT EQU FALSE ;No hardware ints |
|||
AINT EQU FALSE ;No need to do interrupt acknowledge |
|||
ENDIF |
|||
|
|||
IF IBM |
|||
HARDINT EQU TRUE |
|||
INTLOC EQU 1CH ;Hardware interrupt location (Timer) |
|||
REBOOT EQU 19H ;ROM BIOS "Bootstrap" |
|||
AINT EQU TRUE ;Acknowledge interrupts |
|||
EOI EQU 20H ;End Of Interrupt "instruction" |
|||
AKPORT EQU 20H ;Interrupt Acknowledge port |
|||
ENDIF |
|||
|
|||
; The following values have to do with the ERRCNT variable and the CNTMES |
|||
; message. The values define levels at wich it is assumed an off-line error |
|||
; exists. ERRCNT1 defines the value of ERRCNT above which the CNTMES message |
|||
; is printed by the transient. ERRCNT2 defines the value of ERRCNT above |
|||
; which the resident will give up trying to print messages on the printer, it |
|||
; is much greater than ERRCNT1 because a much tighter loop is involved. The |
|||
; bounding event which determines the correct value is the time required to |
|||
; do a form feed. |
|||
|
|||
IF IBM |
|||
ERRCNT1 EQU 1500 |
|||
ERRCNT2 EQU 20000 |
|||
ELSE |
|||
ERRCNT1 EQU 1500 |
|||
ERRCNT2 EQU 20000 |
|||
ENDIF |
|||
|
|||
|
|||
;WARNING DANGER WARNING: |
|||
; PRINT is a systems utility. It is clearly understood that it may have |
|||
; to be entirely re-written for future versions of MS-DOS. The following |
|||
; TWO vectors are version specific, they may not exist at all in future |
|||
; versions. If they do exist, they may function differently. |
|||
; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS |
|||
; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM. |
|||
; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON |
|||
; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS. |
|||
|
|||
SOFTINT EQU 28H ;Software interrupt generated by DOS |
|||
ComInt EQU 2FH ;Communications interrupt used by PSPRINT |
|||
; Multiplex number 0 and 1 |
|||
|
|||
;----- Default (and Minimal) Print queue length |
|||
DefQueueLen equ 10 ; 10 files worth |
|||
MinQueueLen equ 4 ; 4 files worth min |
|||
MaxQueueLen equ 32 ; 32 files worth max. |
|||
|
|||
;----- Maximum length of a file name (incl nul) |
|||
MaxFileLen equ 64 |
|||
|
|||
; **************** Bogosity Warning ***************** |
|||
; Below is the equate that MaxFile SHOULD be. Since the 3.0/3.1 documentation |
|||
; documents each queue entry as being 64 chars long. Yes it is known that |
|||
; that causes Print to misbehave on files deep in trees. But for |
|||
; compatibilities sake, IBM insisted that we change the code back to the |
|||
; way it was. |
|||
;MaxFileLen equ 63 + 2 + 12 ; 63 characters as Command.com's |
|||
; max. path length |
|||
; 2 character for the Drive ext. |
|||
; 12 characters for the max. valid |
|||
; DOS filename |
|||
|
|||
|
|||
.xlist |
|||
.xcref |
|||
BREAK MACRO subtitle |
|||
SUBTTL subtitle |
|||
PAGE |
|||
ENDM |
|||
|
|||
stdin EQU 0 |
|||
stdout EQU 1 |
|||
stderr EQU 2 |
|||
stdaux EQU 3 |
|||
stdprn EQU 4 |
|||
|
|||
INCLUDE DEVSYM.INC |
|||
INCLUDE SYSCALL.INC |
|||
INCLUDE ERROR.INC |
|||
INCLUDE SYSVAR.INC |
|||
INCLUDE FIND.INC |
|||
include dpl.inc |
|||
INCLUDE PDB.INC |
|||
INCLUDE SYSCALL.INC |
|||
INCLUDE MI.INC |
|||
include versiona.inc |
|||
.list |
|||
.cref |
|||
|
|||
|
|||
error_busy EQU 9 |
|||
error_queue_full EQU 8 |
|||
error_name_too_long EQU 12 |
|||
|
|||
IF1 |
|||
IF IBM |
|||
%out IBM VERSION |
|||
ELSE |
|||
%out MS-DOS VERSION |
|||
ENDIF |
|||
ENDIF |
|||
|
|||
BREAK <Segment Definitions> |
|||
|
|||
|
|||
CodeR Segment public para |
|||
CodeR EndS |
|||
|
|||
Code Segment public para |
|||
Code EndS |
|||
|
|||
Data Segment public byte |
|||
Data EndS |
|||
|
|||
Stack Segment Stack |
|||
Stack Ends |
|||
|
|||
DG group Code,Data,Stack |
|||
|
|||
SaveReg MACRO reglist ;; push those registers |
|||
IRP reg,<reglist> |
|||
PUSH reg |
|||
ENDM |
|||
ENDM |
|||
.xcref SaveReg |
|||
|
|||
RestoreReg MACRO reglist ;; pop those registers |
|||
IRP reg,<reglist> |
|||
POP reg |
|||
ENDM |
|||
ENDM |
|||
|
@ -0,0 +1,2 @@ |
|||
PRINT_RM PRINT_R PRINT_T PRINT_TM NPRINTF |
|||
PRINT.EXE /m; |
2189
SRC/CMD/PRINT/PRINT_R.ASM
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,34 @@ |
|||
; SCCSID = @(#)print_rmes.asm 4.1 85/07/17 |
|||
INCLUDE pridefs.inc |
|||
|
|||
|
|||
BREAK <Resident Portion Messages> |
|||
|
|||
; |
|||
; MSDOS V3.00 PRINT |
|||
; |
|||
; Resident Portion Messages |
|||
; |
|||
; 02/15/84 MAU Created as a separate link module |
|||
; from the include file. should |
|||
; always be linked first!! |
|||
; |
|||
|
|||
CodeR Segment public para |
|||
|
|||
public ERRMES, ERRMEST, BELMES, ErrMesT2, CanMes, CanFilNAm |
|||
public AllCan, ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, |
|||
public ERR7, ERR8, ERR9, ERR10, ERR11, ERR12, FATMES |
|||
public BADDRVM, BADMES, badmeslen, GOODMES, goodmeslen |
|||
|
|||
;INT 24 messages A La COMMAND |
|||
Public PRMES001S, PRMES001E |
|||
PRMES001S equ $ |
|||
|
|||
include print_rm.inc |
|||
|
|||
PRMES001E equ $ |
|||
|
|||
CodeR EndS |
|||
|
|||
End |
@ -0,0 +1,34 @@ |
|||
|
|||
ERRMES DB 13,10,13,10,"**********",13,10,"$" |
|||
ERRMEST DB " error reading file",13,10,"$" |
|||
BELMES DB 13,0CH,7,"$" |
|||
|
|||
ErrMesT2 db "File not found",13,10,"$" |
|||
|
|||
CanMes DB 13,10,13,10,"File $" |
|||
CanFilNam DB " canceled by operator$" |
|||
|
|||
AllCan DB 13,10,13,10,"All files canceled by operator$" |
|||
|
|||
ERR0 DB "Write protect$" |
|||
ERR1 DB "Bad unit$" |
|||
ERR2 DB "Not ready$" |
|||
ERR3 DB "Bad command$" |
|||
ERR4 DB "Data$" |
|||
ERR5 DB "Bad call format$" |
|||
ERR6 DB "Seek$" |
|||
ERR7 DB "Non-DOS disk$" |
|||
ERR8 DB "Sector not found$" |
|||
ERR9 DB "No paper$" |
|||
ERR10 DB "Write fault$" |
|||
ERR11 DB "Read fault$" |
|||
ERR12 DB "Disk$" |
|||
|
|||
FATMES DB "File allocation table bad drive " |
|||
BADDRVM DB "A.",13,10,"$" |
|||
|
|||
BADMES DB "List output is not assigned to a device",13,10 |
|||
badmeslen dw $-badmes |
|||
GOODMES DB "Resident part of PRINT installed",13,10 |
|||
goodmeslen dw $-goodmes |
|||
|
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue