mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
Upload
Digital Research
This commit is contained in:
214
CPM OPERATING SYSTEMS/CPM 2.X/CPM 2.2/PATCHES/CPM22APN.11
Normal file
214
CPM OPERATING SYSTEMS/CPM 2.X/CPM 2.2/PATCHES/CPM22APN.11
Normal file
@@ -0,0 +1,214 @@
|
||||
CP/M V2.2
|
||||
Application Note 11 9/30/82
|
||||
Chaining Programs
|
||||
|
||||
Copyright 1982 by Digital Research
|
||||
CP/M and CP/NET are registered trademarks of Digital Research.
|
||||
MP/M II and PL/I-80 are trademarks of Digital Research.
|
||||
Compiled October 1982
|
||||
|
||||
Applicable products and version numbers: CP/M V2.2, CP/NET ,
|
||||
and MP/M II .
|
||||
|
||||
Program: CHAIN1.COM and CHAIN2.COM
|
||||
|
||||
Menu-driven applications can be written to run under CP/M.
|
||||
If you develop applications using PL/I-80 , you can write the
|
||||
programs as a set of overlays. Often, the programs are written in
|
||||
assembly language, or require too much memory to make the overlay
|
||||
feature of PL/I-80 appropriate. Without using overlays, there are
|
||||
only two effective methods of chaining under CP/M V2.2.
|
||||
|
||||
The first method uses the CP/M SUBMIT facility, in which the
|
||||
main menu program creates a SUBMIT file that lists the programs to
|
||||
be chained. The file must be written to drive A, and have the name
|
||||
$$$.SUB.
|
||||
|
||||
The SUBMIT file consists of compatible lines, exactly like
|
||||
those you type at the console, following the system prompt. The
|
||||
commands are placed in reverse order, so the last command in the
|
||||
file is the first to be executed. Each command is placed in a 128-
|
||||
byte record with the following format:
|
||||
|
||||
:n:C1:C2:...:cn:0:...:
|
||||
|
||||
The first byte of the record contains the number of
|
||||
characters in the command (n), followed by the characters (c1-cn),
|
||||
and terminated with a zero. The number of characters in the command
|
||||
is written as a binary number and each character is represented in
|
||||
ASCII format. It does not matter what follows the terminating zero
|
||||
in the record. For example, if the command was STAT*.*, the first
|
||||
byte would be a binary 8, followed by the letters STAT*.* and
|
||||
terminated with a zero.
|
||||
|
||||
The second method of program chaining is simpler. You
|
||||
include a procedure in the menu program that loads the next program
|
||||
and chains to it. Each program that might chain to another program
|
||||
must include a copy of the procedure. The procedure must first move
|
||||
itself out of the way so that it is not overwritten by the program
|
||||
it is loading.
|
||||
|
||||
The example assembly language procedure is written to link
|
||||
with PL/I-80 modules as an external procedure. It can also be used
|
||||
in an assembly language menu program. To link to a PL/I-80 program,
|
||||
the following entry declaration must be included in the PL/I-80
|
||||
program that does the chaining:
|
||||
<EFBFBD>
|
||||
dcl chain entry (char(12));
|
||||
|
||||
The character 12 variable consists of the standard CP/M File
|
||||
Control Block (FCB) format. The format can be created in the PL/I-
|
||||
80 program as a structure. A char(12) variable can then be based at
|
||||
the same address as the structure for interfacing to the chain
|
||||
procedure. (See the following PL/I-80 program.)
|
||||
|
||||
Note: the drive is not an ASCII character, but a binary number
|
||||
between 0 and 16, where 0 is the current default drive and 1 through
|
||||
16 represent the CP/M drives A through P, respectively.
|
||||
|
||||
chain 1: proc options(main);
|
||||
/* chain subroutine tester */
|
||||
dcl 1 fcb static
|
||||
2 drive fixed(7) init(0),
|
||||
2 name char(8) init('CHAIN2');
|
||||
2 type char(3) init('COM'),
|
||||
dummy char(12) based(db),
|
||||
dp pointer,
|
||||
chain entry(char(12));
|
||||
put skip list('Chain Text program 1');
|
||||
dp = addr(fcb);
|
||||
call chain(dummy);
|
||||
put skip(2) list('Shouldn''t be here!!);
|
||||
end chain 1;
|
||||
|
||||
This program prints the message Chain Test program 1, and
|
||||
chains to the program CHAIN2.COM on the default drive. CHAIN2 is a
|
||||
program identical to CHAIN1, except that it prints Chain Test
|
||||
Program 2 and chains to CHAIN1.COM. CHAIN1 and CHAIN2 then continue
|
||||
to chain back and forth to each other.
|
||||
|
||||
Note: any statements following the call to the chain procedure are
|
||||
not executed because the chain procedure never returns.
|
||||
|
||||
The chain procedure consists of two routines. An
|
||||
initialization routine initializes the FCB for the program to be
|
||||
loaded. Then, the initialization routine relocates the loader and
|
||||
FCB to the very top of the Transient Program Area (TPA), immediately
|
||||
below the BDOS, so it will not be overwritten by the loaded program.
|
||||
The loader begins at the label, code:, and ends at the end of the
|
||||
FCB, at the statement, codelen equ $-code.
|
||||
|
||||
The loader routine sets the DMA address, reads a sector,
|
||||
checks for an end-of-file, increments the DMA addresses by 128
|
||||
bytes, and repeats the process. When the end-of-file is detected,
|
||||
it jumps to the chained program. The code is as follows:
|
||||
|
||||
public chain char(12)
|
||||
extrn ?signal
|
||||
,/* loads another COM file, and
|
||||
executes it */
|
||||
bdos equ 5
|
||||
<EFBFBD> openf equ 15
|
||||
readf equ 20
|
||||
dmaf equ 26
|
||||
|
||||
cseq
|
||||
chain. mov e,m ! inx h ! mov d, m ! xchg ;get first arg address
|
||||
lxi d, fcb ! mvi c, 12 ! call move ;move string to FCB
|
||||
lxi d, fcb+12 ! mvi a, 0 ! mvi c, 21
|
||||
call fill ;zero rest of FCB
|
||||
lhld bdos+1 ! lxi b, -code$len
|
||||
dad b ;make space at
|
||||
;top of TPA
|
||||
shld jmpr + 1 ;jump address
|
||||
push h ;save code address
|
||||
;for RET
|
||||
xchg ! lxi h, fcb-code ! dad d ;make address of FCB
|
||||
shld FCBR+1 ;and fix LXI
|
||||
push h ;save FCB
|
||||
;destination address
|
||||
|
||||
lxi h, code ! mvi c, code$len
|
||||
call move ;dest in DE
|
||||
pop d ;recover address of FCB
|
||||
mvi c, openf ! call BDOS ;open file
|
||||
inr a ! jz sig ;if any error,
|
||||
;signal error
|
||||
pop h ! sphl ! push h ;point stack to top
|
||||
;of TPA
|
||||
;and save code addr
|
||||
lxi h, 100h ;point to start of
|
||||
;TPA
|
||||
ret ;to loader "code"
|
||||
|
||||
code: push h ! xchg ! mvi c, dmaf
|
||||
call BDOS ;set the DMA address
|
||||
|
||||
FCBR lxi d, $-$ ! mvi c, readf !
|
||||
call BDOS ;read the next record
|
||||
ora a ! jnz 100h ;EOF -| start TPA
|
||||
pop h ! lxi d, 128 ! dad D ;recover and bump DMA
|
||||
|
||||
jmpr jmp $-$ ;jump to code
|
||||
FCB: ds 1 ;drive code
|
||||
ds 8 ;filename
|
||||
ds 3 ;filetype
|
||||
ds 4 ;control info
|
||||
ds 16 ;disk map
|
||||
ds 1 ;rrec
|
||||
codelen equ $-code
|
||||
|
||||
move: ;c = # bytes, hi = source, de = desti-
|
||||
nation
|
||||
mov a,m ! stax d
|
||||
inx h ! inx d ! dcr c
|
||||
jnz move
|
||||
<EFBFBD> ret
|
||||
fill: ;a = byte to fill, c = # bytes, de = start ad-
|
||||
dress
|
||||
stax d ! inx d
|
||||
dcr c ! jnz fill
|
||||
ret
|
||||
sig: lxi h, siglist ! call ?signal ! jmp 0;signal error
|
||||
siglist: ;(fixed(6),
|
||||
;bit(8),ptr,ptr)
|
||||
dw sigcode, sigsub, sigfil, message
|
||||
sigcode db 6 ;undefined file
|
||||
;error
|
||||
sigsub db 2 ;arbitrary subcode
|
||||
;for id
|
||||
sigfil dw fpb ;ptr to file
|
||||
;parameter block
|
||||
message dw quack ;auxiliary
|
||||
;operator message
|
||||
fpb ;PL/I fuke
|
||||
;oaraneter bkicj
|
||||
fcbptr dw FCB-1 ;fcb-1
|
||||
fpblst dw 0 ;(unused)ptr
|
||||
column dw 0 ;current column
|
||||
;fixed(15)
|
||||
curline dw 0 ;current line
|
||||
;fixed(15)
|
||||
curpage dw 0 ;current page
|
||||
;fixed(15)
|
||||
currec dw 0 ;(unused)fixed(15)
|
||||
lookchr db 0 ;look ahead char
|
||||
;char(1)
|
||||
ioend dw 0 ;i/o end address
|
||||
iostk dw 0 ;user stack upon
|
||||
;sio entry
|
||||
spacer ds 4 ;spacer
|
||||
linesz dw 0 ;line size
|
||||
;fixed(15)
|
||||
pagesz dw 0 ;page size
|
||||
;fixed(15)
|
||||
fixedsz dw 0 ;fixed size
|
||||
;fixed(15)
|
||||
blocksz dw 0 ;block size
|
||||
;fixed(15)
|
||||
filedes dw 0 ;block size
|
||||
;fixed(15)
|
||||
dtitle db 0 ;default title
|
||||
;char(14)varying
|
||||
quack db 17,'Bad Chain Attempt',0 ;error message
|
||||
|
||||
Reference in New Issue
Block a user