Browse Source

inital commit

master
Adam 4 years ago
commit
50868cd2d2
  1. 7051
      AG.DOC
  2. 227
      PROGREF/0_CONTS.A
  3. 34
      PROGREF/0_FRONT.A
  4. 3175
      PROGREF/1A_CALLS.A
  5. 2688
      PROGREF/1B_CALLS.A
  6. 3520
      PROGREF/1C_CALLS.A
  7. 3710
      PROGREF/1D_CALLS.A
  8. 3533
      PROGREF/1E_CALLS.A
  9. 3558
      PROGREF/2_DEVDR.A
  10. 623
      PROGREF/3_TECH.A
  11. 393
      PROGREF/4_CTRLB.A
  12. 360
      PROGREF/5_NLS.A
  13. 203
      PROGREF/6_EXE.A
  14. 2555
      PROGREF/7_OMF.A
  15. 440
      PROGREF/8_HINTS.A
  16. 1203
      PROGREF/INDEX.A
  17. 238
      README.BF
  18. 776
      README.DIS
  19. 31
      SRC/BIOS/BIOMES.INC
  20. 87
      SRC/BIOS/BIOSTRUC.INC
  21. 76
      SRC/BIOS/CLOCKSUB.INC
  22. 50
      SRC/BIOS/CMOSEQU.INC
  23. 22
      SRC/BIOS/DSKPRM.INC
  24. 32
      SRC/BIOS/JUMPMAC.INC
  25. 1
      SRC/BIOS/LOCSCR
  26. 107
      SRC/BIOS/MAKEFILE
  27. 494
      SRC/BIOS/MS96TPI.INC
  28. 281
      SRC/BIOS/MSAUX.ASM
  29. BIN
      SRC/BIOS/MSAUX.OBJ
  30. 118
      SRC/BIOS/MSBDS.INC
  31. 5
      SRC/BIOS/MSBIO.LNK
  32. 693
      SRC/BIOS/MSBIO1.ASM
  33. BIN
      SRC/BIOS/MSBIO1.OBJ
  34. 650
      SRC/BIOS/MSBIO2.ASM
  35. BIN
      SRC/BIOS/MSBIO2.OBJ
  36. 295
      SRC/BIOS/MSCLOCK.ASM
  37. BIN
      SRC/BIOS/MSCLOCK.OBJ
  38. 216
      SRC/BIOS/MSCON.ASM
  39. BIN
      SRC/BIOS/MSCON.OBJ
  40. 882
      SRC/BIOS/MSDATA.INC
  41. 2408
      SRC/BIOS/MSDISK.ASM
  42. BIN
      SRC/BIOS/MSDISK.OBJ
  43. 65
      SRC/BIOS/MSEQU.INC
  44. 72
      SRC/BIOS/MSEXTRN.INC
  45. 46
      SRC/BIOS/MSGROUP.INC
  46. 418
      SRC/BIOS/MSHARD.ASM
  47. BIN
      SRC/BIOS/MSHARD.OBJ
  48. 2213
      SRC/BIOS/MSINIT.ASM
  49. BIN
      SRC/BIOS/MSINIT.OBJ
  50. 1036
      SRC/BIOS/MSIOCTL.INC
  51. 767
      SRC/BIOS/MSLOAD.ASM
  52. 52
      SRC/BIOS/MSLOAD.INC
  53. BIN
      SRC/BIOS/MSLOAD.OBJ
  54. 274
      SRC/BIOS/MSLPT.ASM
  55. BIN
      SRC/BIOS/MSLPT.OBJ
  56. 192
      SRC/BIOS/MSMACRO.INC
  57. 306
      SRC/BIOS/MSSTACK.INC
  58. 297
      SRC/BIOS/MSVOLID.INC
  59. 20
      SRC/BIOS/PUSHPOP.INC
  60. 162
      SRC/BIOS/READCLOC.INC
  61. 270
      SRC/BIOS/STKINIT.INC
  62. 6
      SRC/BIOS/STKMES.INC
  63. 868
      SRC/BIOS/SYSCONF.ASM
  64. BIN
      SRC/BIOS/SYSCONF.OBJ
  65. 18
      SRC/BIOS/SYSIMES.ASM
  66. 68
      SRC/BIOS/SYSIMES.INC
  67. BIN
      SRC/BIOS/SYSIMES.OBJ
  68. 1084
      SRC/BIOS/SYSINIT1.ASM
  69. BIN
      SRC/BIOS/SYSINIT1.OBJ
  70. 1256
      SRC/BIOS/SYSINIT2.ASM
  71. BIN
      SRC/BIOS/SYSINIT2.OBJ
  72. 64
      SRC/BOOT/BOOT11.INC
  73. 38
      SRC/BOOT/MAKEFILE
  74. 7
      SRC/BOOT/MESSAGES.INC
  75. 386
      SRC/BOOT/MSBOOT.ASM
  76. 650
      SRC/BUGFIX/BIOS/MSBIO2.ASM
  77. BIN
      SRC/BUGFIX/CMD/COMMAND/COMMAND.COM
  78. BIN
      SRC/BUGFIX/CMD/FDISK/FDISK.COM
  79. 3032
      SRC/BUGFIX/CMD/FORMAT/FORMAT.ASM
  80. 68
      SRC/BUGFIX/CMD/FORMAT/MESSAGES.ASM
  81. 139
      SRC/BUGFIX/CMD/FORMAT/MESSAGES.INC
  82. BIN
      SRC/BUGFIX/DOS/HANDLE.OBJ
  83. 9
      SRC/CMD/FORMAT/BOOTMES.INC
  84. 6
      SRC/CMD/FORMAT/FILESIZE.INC
  85. 3032
      SRC/CMD/FORMAT/FORMAT.ASM
  86. 2
      SRC/CMD/FORMAT/FORMAT.LNK
  87. 141
      SRC/CMD/FORMAT/FORPROC.ASM
  88. 58
      SRC/CMD/FORMAT/MAKEFILE
  89. BIN
      SRC/CMD/FORMAT/MAKE_INC.BAS
  90. 68
      SRC/CMD/FORMAT/MESSAGES.ASM
  91. 139
      SRC/CMD/FORMAT/MESSAGES.INC
  92. 1204
      SRC/CMD/FORMAT/OEMFOR.ASM
  93. 14
      SRC/CMD/MAKEFILE
  94. 61
      SRC/CMD/PRINT/MAKEFILE
  95. 386
      SRC/CMD/PRINT/NPRINTF.ASM
  96. 213
      SRC/CMD/PRINT/PRIDEFS.INC
  97. 2
      SRC/CMD/PRINT/PRINT.LNK
  98. 2189
      SRC/CMD/PRINT/PRINT_R.ASM
  99. 34
      SRC/CMD/PRINT/PRINT_RM.ASM
  100. 34
      SRC/CMD/PRINT/PRINT_RM.INC

7051
AG.DOC
File diff suppressed because it is too large
View File

227
PROGREF/0_CONTS.A

@ -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
_ _ | | _ _

34
PROGREF/0_FRONT.A

@ -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

2688
PROGREF/1B_CALLS.A
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

3710
PROGREF/1D_CALLS.A
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

3558
PROGREF/2_DEVDR.A
File diff suppressed because it is too large
View File

623
PROGREF/3_TECH.A

@ -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
_ _ | | _ _

393
PROGREF/4_CTRLB.A

@ -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
_ _ | | _ _

360
PROGREF/5_NLS.A

@ -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
_ _ | | _ _

203
PROGREF/6_EXE.A

@ -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

440
PROGREF/8_HINTS.A

@ -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

238
README.BF

@ -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;

776
README.DIS

@ -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.

31
SRC/BIOS/BIOMES.INC

@ -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


87
SRC/BIOS/BIOSTRUC.INC

@ -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

76
SRC/BIOS/CLOCKSUB.INC

@ -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
;

50
SRC/BIOS/CMOSEQU.INC

@ -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


22
SRC/BIOS/DSKPRM.INC

@ -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

32
SRC/BIOS/JUMPMAC.INC

@ -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


1
SRC/BIOS/LOCSCR

@ -0,0 +1 @@
70

107
SRC/BIOS/MAKEFILE

@ -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

494
SRC/BIOS/MS96TPI.INC

@ -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

281
SRC/BIOS/MSAUX.ASM

@ -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

BIN
SRC/BIOS/MSAUX.OBJ

118
SRC/BIOS/MSBDS.INC

@ -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

5
SRC/BIOS/MSBIO.LNK

@ -0,0 +1,5 @@
msbio1+mscon+msaux+mslpt+msclock+msdisk+
msbio2+mshard+msinit+sysinit1+sysconf+sysinit2+sysimes,
msbio,
msbio/m;


693
SRC/BIOS/MSBIO1.ASM

@ -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

BIN
SRC/BIOS/MSBIO1.OBJ

650
SRC/BIOS/MSBIO2.ASM

@ -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

BIN
SRC/BIOS/MSBIO2.OBJ

295
SRC/BIOS/MSCLOCK.ASM

@ -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

BIN
SRC/BIOS/MSCLOCK.OBJ

216
SRC/BIOS/MSCON.ASM

@ -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

BIN
SRC/BIOS/MSCON.OBJ

882
SRC/BIOS/MSDATA.INC

@ -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

BIN
SRC/BIOS/MSDISK.OBJ

65
SRC/BIOS/MSEQU.INC

@ -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


72
SRC/BIOS/MSEXTRN.INC

@ -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

46
SRC/BIOS/MSGROUP.INC

@ -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


418
SRC/BIOS/MSHARD.ASM

@ -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

BIN
SRC/BIOS/MSHARD.OBJ

2213
SRC/BIOS/MSINIT.ASM
File diff suppressed because it is too large
View File

BIN
SRC/BIOS/MSINIT.OBJ

1036
SRC/BIOS/MSIOCTL.INC
File diff suppressed because it is too large
View File

767
SRC/BIOS/MSLOAD.ASM

@ -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

52
SRC/BIOS/MSLOAD.INC

@ -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


BIN
SRC/BIOS/MSLOAD.OBJ

274
SRC/BIOS/MSLPT.ASM

@ -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

BIN
SRC/BIOS/MSLPT.OBJ

192
SRC/BIOS/MSMACRO.INC

@ -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

306
SRC/BIOS/MSSTACK.INC

@ -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

297
SRC/BIOS/MSVOLID.INC

@ -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

20
SRC/BIOS/PUSHPOP.INC

@ -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

162
SRC/BIOS/READCLOC.INC

@ -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

270
SRC/BIOS/STKINIT.INC

@ -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

6
SRC/BIOS/STKMES.INC

@ -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
;

868
SRC/BIOS/SYSCONF.ASM

@ -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


BIN
SRC/BIOS/SYSCONF.OBJ

18
SRC/BIOS/SYSIMES.ASM

@ -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

68
SRC/BIOS/SYSIMES.INC

@ -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


BIN
SRC/BIOS/SYSIMES.OBJ

1084
SRC/BIOS/SYSINIT1.ASM
File diff suppressed because it is too large
View File

BIN
SRC/BIOS/SYSINIT1.OBJ

1256
SRC/BIOS/SYSINIT2.ASM
File diff suppressed because it is too large
View File

BIN
SRC/BIOS/SYSINIT2.OBJ

64
SRC/BOOT/BOOT11.INC

@ -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

38
SRC/BOOT/MAKEFILE

@ -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

7
SRC/BOOT/MESSAGES.INC

@ -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

386
SRC/BOOT/MSBOOT.ASM

@ -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

650
SRC/BUGFIX/BIOS/MSBIO2.ASM

@ -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

BIN
SRC/BUGFIX/CMD/COMMAND/COMMAND.COM

BIN
SRC/BUGFIX/CMD/FDISK/FDISK.COM

3032
SRC/BUGFIX/CMD/FORMAT/FORMAT.ASM
File diff suppressed because it is too large
View File

68
SRC/BUGFIX/CMD/FORMAT/MESSAGES.ASM

@ -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

139
SRC/BUGFIX/CMD/FORMAT/MESSAGES.INC

@ -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

BIN
SRC/BUGFIX/DOS/HANDLE.OBJ

9
SRC/CMD/FORMAT/BOOTMES.INC

@ -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

6
SRC/CMD/FORMAT/FILESIZE.INC

@ -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

2
SRC/CMD/FORMAT/FORMAT.LNK

@ -0,0 +1,2 @@
format.obj forproc.obj messages.obj oemfor.obj ..\..\libc\printf.obj
format.exe /m;

141
SRC/CMD/FORMAT/FORPROC.ASM

@ -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

58
SRC/CMD/FORMAT/MAKEFILE

@ -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

BIN
SRC/CMD/FORMAT/MAKE_INC.BAS

68
SRC/CMD/FORMAT/MESSAGES.ASM

@ -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

139
SRC/CMD/FORMAT/MESSAGES.INC

@ -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

14
SRC/CMD/MAKEFILE

@ -0,0 +1,14 @@
make=msmake /I makefile
all:
cd format
$(make)
cd ..\print
$(make)
cd ..\sort
$(make)
cd ..\sys
$(make)
cd ..


61
SRC/CMD/PRINT/MAKEFILE

@ -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


386
SRC/CMD/PRINT/NPRINTF.ASM

@ -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

213
SRC/CMD/PRINT/PRIDEFS.INC

@ -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


2
SRC/CMD/PRINT/PRINT.LNK

@ -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

34
SRC/CMD/PRINT/PRINT_RM.ASM

@ -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

34
SRC/CMD/PRINT/PRINT_RM.INC

@ -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

Loading…
Cancel
Save