; CARRY.ASM ver 1.2 ; (revised 6/24/81) ; by Keith Petersen, W8SDZ ; ;This program runs up in high RAM. It gets there ;by being moved there when CARRY ;is typed. ; ;The program in high RAM does the following: ; ;Loads and executes a .COM file named in command line, ;but first waits for the user to change disks. ;Arguements after requested .COM file name are passed ;to the executed program, thus making it possible to ;run ED or Wordmaster. ; ;Why this is useful: Users of single-drive systems ;may not have room for ED, WM, ASM, LOAD, or other ;such programs on their "work" disk. This program ;makes it possible to change disks, get the editor ;assembler or loader, then change disks again. CARRY ;must be on the same disk with the COM file it is to ;get. ; ;Command: CARRY ED MYFILE.ASM ; (gets ED.COM to edit MYFILE.ASM) ; ;Fixes/updates (in reverse order to minimize reading time): ; ;06/24/81 Added more documentation about ENDMARK. (KBP) ; ;NOTE: If you add improvements or otherwise update ;this program, please modem a copy of the new file ;to "TECHNICAL CBBS" in Dearborn, Michigan - phone ;313-846-6127 (110, 300, 450 or 600 baud). Use the ;filename CARRYXX.NEW where XX is the new version nr. ;------------------------------------------------ ; ;A marker has been placed at the end of this file to ;deliberately print an error message during assembly ;in order to determine the actual ending address of ;the program. The error message will not affect the ;assembly. Make sure you have free memory available ;up to the address shown. ; ;Change the following equate to an area in your ;high memory where this program may patch itself in. ;This may be below BDOS, provided that sufficient ;space is available below CARRY to load the requested ;COM file. ; DEST EQU 0FA00H ;RUNNING LOCATION OF CODE ; ;------------------------------------------------ ; BASE EQU 0 ;PUT 4200H HERE FOR ALTERNATE CP/M ; PRINT EQU 9 OPEN EQU 15 STDMA EQU 26 BDOS EQU BASE+5 FCB EQU BASE+5CH FCBEXT EQU FCB+12 FCB2 EQU BASE+6CH ; CR EQU 0DH LF EQU 0AH ; ORG BASE+100H ; ;Move the program up to high RAM and jump to it. ; MOVEUP: LXI B,PEND-START+1 ;NUMBER OF BYTES TO MOVE LXI H,DEST+PEND-START+1 ;END OF MOVED CODE LXI D,SOURCE+PEND-START ;END OF SOURCE CODE ; MVLP: LDAX D ;GET BYTE DCX H ;BUMP POINTERS MOV M,A ;NEW HOME DCX D DCX B ;BUMP BYTE COUNT MOV A,B ;CHECK IF ZERO ORA C JNZ MVLP ;IF NOT, DO SOME MORE PCHL ;JUMP TO "START" ; SOURCE EQU $ ;BOUNDARY MEMORY MARKER ; OFFSET EQU DEST-SOURCE ;RELOC AMOUNT ;-----------------------------------------------; ; The following code gets moved ; ; to high RAM located at "DEST", ; ; where it is executed. ; ;-----------------------------------------------; ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XX C A U T I O N : If modifying anything XX ;XX in this program from here on: XX ;XX A-L-L labels must be of the form: XX ;XX LABEL EQU $+OFFSET XX ;XX in order that the relocation to high XX ;XX RAM work successfully. Forgetting to XX ;XX specify '$+OFFSET' will cause the pro- XX ;XX gram to JMP into whatever is currently XX ;XX in low memory, with unpredictable XX ;XX results. Be careful.... XX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; START EQU $+OFFSET LXI SP,STACK ;SET UP LOCAL STACK POINTER ;Move requested file name to our FCB LXI H,FCB ;SOURCE LXI D,MYFCB ;DESTINATION MVI B,9 ;LENGTH CALL MOVE ;MOVE THE NAME ;Move arguement to default FCB LXI H,FCB2 ;SOURCE LXI D,FCB ;DESTINATION MVI B,13 ;LENGTH CALL MOVE ;MOVE THE NAME ;Clear FCB2 and initialize our FCB MVI A,' ' STA FCB2+1 XRA A STA FCB2 STA FCBEXT STA MYFCB+32 ;Set DMA address to 80H LXI D,BASE+80H MVI C,STDMA CALL BDOS ;Open the file LXI D,MYFCB MVI C,OPEN CALL BDOS ;Did it exist? INR A ;A=> 0 MEANS "NO" JZ BYERR ;NO FILE, EXIT ERROR MSG ; OPENOK EQU $+OFFSET LXI D,BASE+100H ;POINT TO TPA ; READLP EQU $+OFFSET PUSH D ;SAVE BUFFER ADDRESS PUSH B PUSH H MVI C,STDMA CALL BDOS ;Read a sector LXI D,MYFCB MVI C,20 ;READ CALL BDOS POP H POP B ORA A ;OK? JNZ EOF ;NOT OK, MUST BE EOF POP D ;GET DMA ADDR LXI H,80H ;LENGTH OF 1 SECT. DAD D ;CALC NEXT BUFF ADDR XCHG ;PUT IT BACK IN DE JMP READLP ;LOOP ; ;Got return code on read, see if error or EOF ; EOF EQU $+OFFSET POP D ;DELETE STACKED BUFFER ADDR ;A has return code from read DCR A ;EOF? JZ RSDMA ;YES, EXIT ; ;Read error - exit with message BYERR EQU $+OFFSET CALL ERXIT ;PRINT: DB CR,LF,'++DISK READ ERROR or FILE NOT FOUND++',CR,LF,'$' ; ;Exit with error message ERXIT EQU $+OFFSET POP D MVI C,9 ;PRINT ERROR MESSAGE CALL BDOS ; ERXIT2 EQU $+OFFSET XRA A STA BASE+4 ;SET DRIVE A:, USER 0 JMP BASE ; ;Reset DMA address to normal RSDMA EQU $+OFFSET LXI D,BASE+80H MVI C,STDMA CALL BDOS ; REASK EQU $+OFFSET LXI D,RDYMSG MVI C,9 ;PRINT READY MESSAGE CALL BDOS MVI C,1 ;GET CONSOLE CHAR. CALL BDOS CPI 'C'-40H ;CTL-C? JZ ERXIT2 ;YES, EXIT CPI CR ;CARRIAGE RETURN? JNZ REASK ; MVI C,13 ;RESET DISK SYSTEM CALL BDOS ; ;Leave warm boot address on stack, them execute file LXI H,BASE+0 PUSH H JMP BASE+100H ;EXECUTE PROGRAM ; ;Move (HL) to (DE), length in (B) ; MOVE EQU $+OFFSET MOV A,M ;GET A BYTE STAX D ;PUT AT NEW HOME INX D ;BUMP POINTERS INX H DCR B ;DEC BYTE COUNT JNZ MOVE ;IF MORE, DO IT RET ;IF NOT,RETURN ; RDYMSG EQU $+OFFSET DB CR,LF,'CHANGE DISKS THEN PRESS RETURN ' DB 'TO CONTINUE (CTL-C ABORTS) > $' ; MYFCB EQU $+OFFSET DB 0,' COM',0 ; PEND EQU $+OFFSET ;END OF RELOCATED CODE ; DS 20 ;ROOM FOR OUR FCB DS 40 ;ROOM FOR OUR STACK STACK EQU $+OFFSET ;LOCAL STACK ; ENDMARK EQU $+OFFSET ;! IGNORE ERROR. THIS MARKS END OF PGM ; END