home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
rcpm
/
run201.lbr
/
RUN201.AZM
/
RUN201.ASM
Wrap
Assembly Source File
|
1987-08-28
|
7KB
|
232 lines
;RUN.ASM
;
;Charles E. Horn,PE
;Horn Engineering Associates
;Garland, TX
;28 April 1984
;(No rights reserved)
;
;======================================================================
;REVISION HISTORY
;
;06/11/85 Corrected error in computation of load address in
; code as noted. [CEH 06/11/85]
;======================================================================
;RUN is a variation of the original RUNFILE program by Phil Cary. That
;program was designed for use on an RBBS and permits one to execute
;a selected program from a selected high user area, even though the
;file is not normally accessible to the user or caller. With this
;technique, the file can be executed without alteration of the wheel
;byte.
;
;RUN is somewhat different. RUNFILE loads the program loader just
;below the BDOS and over a portion of the CCP. This is no problem if
;the executed program (such as RBBS) exits with a warmboot, which
;reloads the CCP. However, some programs exit directly to CP/M without
;a warmboot (such as SD.COM). If it is allowed to do this when called
;from RUNFILE, the CCP will remain corrupt. RUN solves this problem
;by locating the program loader just below the CCP.
;
;RUN requires specification of a file name in the command line. This can
;be at least as secure as an 8-character password because the file in
;the high user area can be named anything and will not be accessible for
;view by directory if the BBS does not normally permit a user to access
;these high areas. This is the purpose of MAXUSR and MAXDRV in the
;various RBBS utilities, such as NZCPR.
;
;The command syntax is: A>RUN <filename>
;
;The program will also support the usual command line extensions if the
;target program normally extracts them from the CP/M default DMA area.
;For example, RUN SD $A would work. RUN SD B: $A would not work because
;the extra $A entry would clobber the CP/M secondary FCB. However, the
;variation RUN B:SD $A would cause the target file, SD in user 14, for
;example, to go to drive B: and display all files in all user areas.
;This program also offers an option to build the target file name into
;the program so that it will operate in the same mode as the RUNFILE
;program. In this case the command would simply be RUN.
;
;
WRCON: EQU 2 ;Console output
PRINTF: EQU 9 ;Print string
BDOS: EQU 5 ;Bdos Call
SELDRV: EQU 14 ;Select Default Drive
OPEN: EQU 15 ;Open file
READ: EQU 20 ;Read sequential
SETDMA: EQU 26 ;Set DMA Address
USER: EQU 32 ;Set user area
RDS: EQU 13 ;Reset disk system
;
CPMFCB: EQU 5CH ;CP/M primary FCB address
CP2FCB: EQU 6CH ;CP/M secondary FCB address
;
;MISC EQUATES
;
CR: EQU 0DH
LF: EQU 0AH
BLANK: EQU 20H
;
;
ORG 100H
;
;
JMP START ;Skip following data
;
;
;CHANGE THE FOLLOWING TO MEET YOUR REQUIREMENTS
;
RETDRV: EQU 0 ;Exit to Drive A
RETUSR: EQU 0 ;..and User 0
DEFDRV: EQU 'A'-'@' ;Drive containing the COM file you want
DEFUSR: EQU 14 ;User area " " " " "
;
RUNFIL: DB 'XFILE ' ;Filename you are CALLING
;Eight Chars-->> ^^^^^^^^<< ;
;
;NOTE: If it desired to build the target file name into this program
; without using the command line technique, change the code in
; the program as noted below. In this case, the user can not
; use RUN to execute any arbitrary file, but is stuck with the
; one that is built in above.
;
ERRMSG: DB CR,LF
DB 'You must be Kidding.....',CR,LF,'$' ;Print Error Message
;
;NOTE: The above message gives the user no idea of what RUN does.
;
START: MVI C,8 ;Move the filename into fcb
LXI H,CPMFCB+1 ;location of filename
;
;NOTE: Replace the operand "CPMFCB+1" in the above instruction with
; "RUNFIL" if the internal name at the label RUNFIL is going to
; be the target file.
;
LXI D,FCB+1 ;destination
CALL MOVE ;8 bytes
;
MVI C,11 ;Clear the primary CP/M FCB
LXI H,CPMFCB+1 ;Destination
CALL BLANKS ;Put in blanks
MVI C,11 ;Clear the secondary CP/M FCB
LXI D,CP2FCB+1 ;Destination
CALL BLANKS ;Put in blanks
;
; If you need to reset the default drive back to 'A' then
; include the next three lines of code.
;
MVI C,SELDRV ;If necessary to locate BRUN, for example
MVI E,00H ;Set Default Drive back to A
CALL BDOS ;Set it
;
MVI C,USER ;set up area of the target file
MVI E,DEFUSR ;Desired user area
CALL BDOS ;do it
;
LHLD BDOS+1 ;get BDOS entry address [ver201 fixes]
lxi b,-6-2048 ;offset to start of ccp
dad b ;pointer to ccp in HL
LXI B,-CODELN ;Subtract length of code to be moved
DAD B ;To make room at top of TPA
SHLD JMPR+1 ;Fill in jump address below
PUSH H ;Save relocated loader address
;
; Code to cause loader to return to drive and user designated
; by RETDRV and RETUSR per EQUates at top, in case loaded program
; returns to CP/M without a warmboot.
;
XCHG
LXI H,SETRET-LOADER ;Distance between start of loader
;..and RET jump address
DAD D ;Compute relocated address
SHLD JMPRET+1 ;..and plant it in loader
POP H ;Recover relocated loader address
;
PUSH H ;Save code address for RET
XCHG ;And use to calculate final location of FCB
LXI H,FCB-LOADER ;Distance between start of loader and FCB
DAD D ;Add address computed above
SHLD FCBR+1 ;And put in LXI below for eventual file read
PUSH H ;Save FCB destination address
LXI H,LOADER ;Point to start of loader
MVI C,CODELN ;Length of loader
CALL MOVE ;Destination still in DE from above
POP D ;Recover FCB address (saved as push H above)
MVI C,OPEN ;
CALL BDOS ;Open file
INR A ;
JZ ERROR ;signal if error
LXI H,100H ;Point to start of TPA for set DMA below
RET ;To address on stack which is start of loader
;
LOADER: PUSH H ;DMA address at start of TPA
XCHG ;Put in DE for DMA set
MVI C,SETDMA
CALL BDOS ;Set DMA address
;
FCBR: LXI D,$-$ ;Address of moved FCB filled in earlier
MVI C,READ ;
CALL BDOS ;Read next record
ORA A ;Check for end of file
POP H
JMPRET: JNZ $-$ ;EOF -> JMP to SETRET (address patched above)
LXI D,128 ;....and bump DMA address
DAD D
;
JMPR: JMP $-$ ;jump to loader address filled in earlier
;
; If the loaded program exits without a warmboot, the following
; code will assure that we are not left in the user area that
; the loaded program normally resides.
;
SETRET: MVI C,RDS ;Reset disk system and restore default DMA
CALL BDOS
MVI C,SELDRV ;Set default drive before return
MVI E,RETDRV
CALL BDOS
MVI C,USER ;Set default user before return
MVI E,RETUSR
CALL BDOS
JMP 100H ;Go run the program in memory
;
FCB: DB DEFDRV ;drive code
DS 8 ;room for filename
DB 'COM' ;File type
DB 0,0,0,0,0,0 ;Zero out remaining 24 bytes of FCB
DB 0,0,0,0,0,0
DB 0,0,0,0,0,0
DB 0,0,0,0,0,0
;
CODELN: EQU $-LOADER ;computes size of loader code for move
;
MOVE: ; C= # Bytes, HL= Source, DE= Destination
;
MOV A,M
STAX D
INX H
INX D
DCR C
JNZ MOVE
RET
;
BLANKS: ; C= # blanks, HL = Destination
;
MVI A,BLANK
MOV M,A
INX H
DCR C
JNZ BLANKS
RET
;
ERROR: LXI D,ERRMSG
CALL PRNMSG
JMP 0
;
;Write a string of characters to the CRT
;
PRNMSG: MVI C,PRINTF
CALL BDOS
RET
;
END
;
S