Info-IBMPC%USC-ISIB@sri-unix.UUCP (04/20/84)
From: Info-IBMPC Digest <Info-IBMPC@USC-ISIB>
Info-IBMPC Digest Friday, 20 April 1984 Volume 3 : Issue 45
This Week's Editor: Billy Brackenridge
Today's Topic:
COMPUSERVE IBM SIG PCDOS/MASM NOTES
----------------------------------------------------------------------
Date: 19 Apr 1984 1452-PST
From: VERNE@USC-ECL.ARPA
Subject: PCDOS/MASM NOTES
To: INFO-IBMPC@USC-ISIB
-------------------- THE PRECEEDING INFO IS FROM THE -----------------------
COMPUSERVE IBM SIG
[70205,1217]
PCDOS.TIP 16-Apr-84 62635
Disposition:
Notes and Observations
-
on
-
IBM PC-DOS and Microsoft MS-DOS
-
Releases 2.0 and 2.1
-
April, 1984
This document is a collection of data from various sources,
including bulletin boards, magazines, seminar handouts, and
independent research.
WARNING: This information is provided without warranty of any kind.
Each individual must determine the applicability and accuracy ofthis
information to their specific environment.
If you have corrections, additions, or comments, please send them
to:
John Chapman
844 S. Madison St.
Hinsdale, Illinois 60521
Or, send EMAIL to userid [70205,1217] on CompuServ,
or MAIL to userid $AC on PCSHARE
BATCH PROCESSING
To modify the DOS 2.0 command interpreter so that the default is echo off
when a batch file is run,
C>debug \command.com
-e1721 28 1f
-e364a 24 26 c6 06 6e 09 00 e9 19 e8
-w
Writing 4500 bytes
-q
The DOS Environment is accessible for use in BATs.
The standard keywords COMSPEC, PATH, PROMPT et al can all be read and set.
New keywords can be set and checked within BATs. The keywords are saved
across BAT executions.
For instance BATs can check which screen is active using SET conventions
as follows:
. NOTE leading and trailing Percent signs
IF %SCREEN% == MONO GOTO COLOR
IF %SCREEN% == COLOR GOTO MONO
:COLOR
SET SCREEN=COLOR
. NOTE no spaces around '=' in SET
MODE CO80
EXIT
:MONO
SET SCREEN=MONO
MODE MONO
EXIT
. SCREEN is set and saved across BAT executions
Another example using a link convention allows BATs to call BATs:
*****CALL.BAT*****
IF NOT %BATLABEL% == . GOTO %BATLABEL%
. note BATLABEL is assumed to be set to '.' as a null value
ECHO DO SOME STUFF HERE
SET BATCALR=%0
. give the called BAT my name to get back
. then leave word where to come back to
SET BATLABEL=RETURN
. set further parms to save %1 thru %9 if necessary
CALLED
:RETURN
ECHO FINISH UP HERE AFTER RETURN
PC/MS-DOS Tips (2.0/2.1) 2
The DOS Environment is accessible for use in BATs. (Cont'd)
*****CALLED.BAT*****
ECHO DO STUFF WE WERE CALLED TO DO
. return to caller
%BATCALR%
. separate keywords will be necessary if further calls
. will be made
A note of caution (this is documented), the environment at boot time,
is limited (I believe to only 128 bytes). If any resident modules are
installed (i.e. PRINT, MODE, or GRAPHICS) the area cannot be expanded.
You can SET enough variables from within AUTOEXEC.BAT to get enough
space to get by.
I would also recommend setting up a set of conventions and preinitializing
the parms you'll use to '.'; Null parameters are removed from the
environment.
In summary -
The rules are simple
SET a parm without percent signs
refer to them by enclosing them in percent signs
I hope this discovery will generate a lot of re-thinking some BAT
techniques.
PC/MS-DOS Tips (2.0/2.1) 3
Current MSDOS 1.xx - 2.xx Disk formats
(T. Jennings 19 Aug 83)
Disk Type Type Code
.......................................................
Single Density Single Sided 8" (SD128)
**** Double Density Single Sided 8" (DD1024)
**** FIDO's 8" Double Density (DD1K)
Double Density Double Sided 8" (DD1024-2)
IBM Displaywriter System disk (SD256)
IBM Displaywriter System disk (DD256-2)
IBM PC 8 Sector Single Sided (IBM8)
IBM PC 9 Sector Single Sided (IBM9)
IBM PC 8 Sector Double Sided (IBM8-2)
IBM PC 9 Sector Double Sided (IBM9-2)
Single Density Double Sided 8" (SD128-2)
**** Never did get Microsoft to figure out which one these
is the "correct" 8 inch format. Who knows.
Type Dir Disk Fats Blk Res Sec FAT
Code Size Size size secs size ID
.....................................................
SD128 68 251K 2 512 1 128 FE
DD1K 192 660K 2 1024 1 1024 FE
DD1024 96 612K 2 1024 1 1024 FE
DD1024-2 192 1232K 2 1024 1 1024 FF
SD256 80 287K 2 512 2 256 FA Note 1
DD256-2 172 1001K 2 1024 2 256 FB Note 2
IBM8 64 162K 2 512 1 512 FE
IBM9 64 180K 2 512 1 512 FC
IBM8-2 112 320K 2 1024 1 512 FF
IBM9-2 112 360K 2 1024 1 512 FD
SD128-2 68 2 512 4 128 FC
Type trks secs res sec FAT dir 1st 2nd 1st 1st totl num.
Code trk secs size size size FAT FAT dir data secs heads
......................................................................
SD128 77 26 1 128 6 17 1 7 13 30 2002 1
DD1024 77 8 1 1024 1 3 1 2 3 6 616 1
DD1024-2 77 8 1 1024 2 6 1 3 5 11 1232 2
SD256 77 15 17 256 4 10 2 6 10 20 1155 1
Note 1
DD256-2 77 26 54 256 6 20 2 8 14 34 4004 2
Note 2
IBM8 40 8 1 512 1 4 1 2 3 7 320 1
IBM9 40 9 1 512 2 4 1 3 5 9 360 1
IBM8-2 40 8 1 512 1 7 1 3 5 10 640 2
IBM9-2 40 9 1 512 2 7 1 3 5 12 720 2
SD128-2 77 26 4 128 12 17 4 16 28 45 4004 2
Note 1:
15 sector bias in BIOS
Note 2:
52 sector bias in BIOS
PC/MS-DOS Tips (2.0/2.1) 4
Additional feature in DEBUG command
There is a compare feature in DEBUG that is not in the documentation. Two
blocks of memory can be compared, byte by byte with the following
command:
-C AD1 AD2 AD3
DEBUG will compare the memory block from AD1 to AD2 with the memory block
starting at AD3. The results appear in a table showing both blocks side
by side with the addresses and the corresponding contents.
(from IBM.PC Users Group of Winnipeg)
PC/MS-DOS Tips (2.0/2.1) 5
Program File Formats
The order of the segments in memory is determined by the linker; and
all the segments are contiguous, unless you do some really determined and
tricky hacking. Supposedly, the linker determines the order of the
segments by putting them in "alphabetical order by segment name", or at
least that's what the documentation says it's supposed to do; but I've
found that it puts them in the order in which they're encountered in the
program source code, unless you create a dummy file (see LINK
instructions) with a different sequence and make it first in the LINK
list of OBJ modules. (I generally put them in source in the sequence
code, data, stack; they always come out in that order, regardless of
segment names, unless I use the dummy file. Let's assume that sequence
for the remainder of this discussion.)
With an .EXE file, just before execution, the registers are as follows:
AX - ostensibly per doc, zero; seems to contain the number
of characters in the command tail, though
BX:CX - 32-bit number showing load module memory size in bytes
(good for dynamically allocating memory)
DX - zero
SS:SP - if you defined a stack segment, these are loaded
accordingly; if not, SS=CS, SP=0FFFFH or end of
memory
DS and ES - SEGMENT address of "program header" (see below)
CS:IP - far address of label in "END" statement of program
The program header is the standard 256-byte .COM file "header",
similar to what you would expect to see at 00-FFH in CP/M 2.x (but see
doc for important differences!). Therefore, DS = CS - 10H (which is 100H
divided by 10H) if the code seg is the first (owest) in memory, because
it points to a location 100H before the start of the code seg.
PC/MS-DOS Tips (2.0/2.1) 6
Program File Formats (Cont'd)
Now, if CS is, say, 9E3H when you come up, then DS and ES will contain
9D3H. (Remember, though, that your code thinks it starts at 9E3:0, zero
being the address you specified in your END directive, and the
instruction pointer will actually contain zero.) These values have
nothing at all to do with the place at which your data seg is located;
they point at that "program header". At location 9D3:80 (DS:80) is the
command tail, if you're gonna reference that; its length is in AX (I
believe) and is also pointed to by the expression DS:80 (just like CP/M;
data starts at 81H), or to say it another way, in this case absolute
memory location 09DB0 (09D30+80). But your code segment is, say, 400H
long, and the linker knew that 'cause the assembler told it so in the
seg, the instructions
MOV AX,DATASEG
MOV DS,AX
MOV ES,AX
(where DATASEG is the name of your data segment) will have been resolved
by the linker in this way; the first instruction of those three was
interpreted by the assembler as an immediate move, but the "data" to be
moved into AX was marked as relocatable. The linker leaves instructions
for the loader to add 9E3H (or whatever address the loader decided was a
good place to put the program) to the value of the "constant" DATASEG,
which is equal to 40H (400H/10H) because it's being "loaded" into a
segment register, and when you look at that instruction under DEBUG it
would say MOV AX,0A23H. (Obviously, this is the process of address
resolution.) In absolute addresses, the codeseg starts at 09E30H, and the
dataseg 400H later at 0A230H; in 8086 shorthand that's 9E3:0 and A23:0
respectively. (This assumes the stackseg is last, say at A98:0; that
would imply that your data seg was (0A98H-0A23H)*10H, or 750H, in
length.)
Almost all instructions accessing data use DS as "base" register,
unless you override that with a prefix (as in MOV AX,ES:BLKCTR). All
instructions accessing storage require one of the segregs as "base"
register. (String primitives ALWAYS work with DS and/or ES and can't be
overridden by a prefix; instructions using BP as an "index" are relative
to SS, unless overridden by a prefix; otherwise, it's DS when not
overridden. Be careful!)
PC/MS-DOS Tips (2.0/2.1) 7
Program File Formats (Cont'd)
In BAL, you give the assembler a USING statement; that tells it that
offsets will be computed relative to the first operand of the USING
***Sender closed connection***
=== Network Mail from host usc-isib on Fri Apr 20 15:34:13 ===