Date : Wed, 16 May 1984 17:50:47-PDT (Wed)
From : harpo!seismo!hao!kpno!terak!jb@Ucb-Vax.ARPA
Subject: Download Bootstrap
I doubt that this is the program referred to, but
will make it available as one solution to this
Catch-22 problem...
; Copyright 1984 by John M. Blalock
; ####################################
; ## ##
; ## GETIT.ASM ##
; ## ##
; ## Written by: ##
; ## ##
; ## John M. Blalock ##
; ## March 24, 1984 ##
; ## ##
; ####################################
; Last updated May 15, 1984, JMB
; This program is a very simple CP/M terminal and ASCII
; text capture program. Once customized for your
; particular computer, it will enable you to communicate to
; another computer via a serial port. It is expected that
; the serial port will be connected to a modem. GETIT will
; allow you to transfer ASCII files from the remote
; computer to yours and save them on disk as long as the
; files are no larger than the available capture buffer.
; Longer files will have to be broken up into smaller
; segments and recombined on your computer with PIP.
; Once you have established communications with the remote
; computer, entering Ctl-Y from your console will cause
; GETIT to start saving text sent from the remote computer
; into a RAM buffer that starts at 0100H. This capture
; function can be toggled on and/or off by subsequent entry
; of another Ctl-Y. An ASCII BELL character is sent to the
; console when capture is toggled on, and nothing is sent
; when it is toggled off.
; Entering Ctl-E will cause GETIT to exit to CP/M after
; first telling you the decimal number of pages in the
; capture buffer. GETIT will also exit when the buffer is
; filled. An X-OFF (Ctl-S) is first sent to the remote
; computer that will stop further output by it as long as
; it supports the X-ON/X-OFF protocol. The captured data
; will be in your RAM starting at 0100H and can be saved to
; disk by entering SAVE nn FILENAME.EXT where nn is the
; number of pages GETIT told you to SAVE.
; GETIT is purposefully short and simple to facilitate
; entry of its source code from the keyboard. Leave out
; the comments - you have them here. Probably the first
; thing for which you will want to use it (and perhaps its
; only use) is to download a better, more capable
; communications program. But it does solve the Catch-22
; problem of not being able to download any communications
; program because you don't have any to start with. If
; MDM730.HEX is available on the remote computer, capture
; it with GETIT, LOAD it, and now you have a good
; communications program.
; GETIT is released for use in the public domain for non-
; profit usage only. If it helps you sell your product, I
; would like to share in the profits. If you sell GETIT, I
; want all the profits. Any questions should be addressed
; to John Blalock, Blalock and Associates, PO Box 39356,
; Phoenix, AZ 85069. Include an SASE if you want a reply.
; MODEM CONSTANTS - You will need to change these to match
; your particular UART. If your UART transmit buffer empty
; and/or receive data available bits are low true, you'll
; have to change the conditional jumps that test these bits
; from JNZ to JZ and from JZ to JNZ. The affected lines
; are marked with an asterick (*) in the comments below.
MDATA EQU 080H ;MODEM DATA PORT
MSTAT EQU 081H ;MODEM STATUS PORT
TXRDY EQU 001H ;TX BUFFER EMPTY BIT
RXRDY EQU 002H ;RX DATA AVAILABLE BIT
; Equate DEST to 0100H bytes or more below the CCP in your
; version of CP/M. The higher it is, the larger the
; capture buffer will be. I have 52.5K bytes available in
; the capture buffer with my version of CP/M and the
; following DEST value.
DEST EQU 0D300H ;PROGRAM IS RELOCATED TO HERE
; The following equates shouldn't require any changes for a
; standard CP/M system.
BASE EQU 0000H ;CP/M BASE ADDRESS
BUFF EQU BASE+0100H ;CAPTURE BUFFER START ADDRESS
BDOS EQU 0005H ;BDOS ENTRY ADDRESS
STACK EQU DEST+100H ;GETIT TOP OF STACK
CAPT EQU 'Y'-40H ;CTL-Y = START/STOP CAPTURE
EXIT EQU 'E'-40H ;CTL-E = STOP, EXIT TO CP/M
BELL EQU 07H ;BEEP THE CONSOLE
CR EQU 0DH ;ASCII CARRIAGE RETURN
LF EQU 0AH ;ASCII LINE FEED
ORG BUFF ;PROGRAM STARTS HERE
BEGIN LDA BASE+2 ;GET BIOS PAGE NUMBER AND
STA PCONST+2 ; PATCH PROGRAM WITH YOUR
STA PCONIN+2 ; BIOS ENTRY ADDRESSES
STA PCONOUT+2
LXI H,0000 ;CLEAR HL
DAD SP ;ORIG SP TO HL
SHLD SPSAVE ;SAVE FOR LATER
LXI SP,STACK ;INIT STACK POINTER
INIT ;Insert here any code required to initialize your
;UART if it is not already initialized by some
;other program or your CP/M cold boot routine.
BMOVE LXI D,DEST ;BLOCK MOVE DESTINATION
LXI H,START ;FIRST ADDRESS TO MOVE
MVI C,PEND-START ;NUMBER OF BYTES TO MOVE
MVLOOP MOV A,M ;GET A BYTE
STAX D ;MOVE IT
INX H ;BUMP POINTERS
INX D
DCR C ;COUNT THE BYTE
JNZ MVLOOP ;LOOP 'TIL DONE
JMP GETIT ;NOW GO RUN THE PROGRAM
START EQU $ ;START OF RELOCATED CODE
OFFSET EQU DEST-START ;PROGRAM OFFSET AMOUNT
GETIT EQU $+OFFSET ;PROGRAM START IN HI MEMORY
LXI H,BUFF ;INITIALIZE BUFFER POINTER
GETLP EQU $+OFFSET ;MAIN PROGRAM LOOP
IN MSTAT ;GET MODEM STATUS
ANI RXRDY ;DATA AVAILABLE ?
JNZ RXDRDY ;YES, THEN JUMP *
CALL CONST ;NO, CHECK KEYBOARD
ORA A ;ANYTHING TYPED ?
JZ GETLP ;NO, THEN LOOP FOREVER
CALL CONIN ;YES, GET IT
CPI CAPT ;CTL-Y ?
JZ TOGCAPT ;YES, TOGGLE CAPTURE FLAG
CPI EXIT ;CTL-E ?
JZ ENDIT1 ;YES, WE'RE DONE FOR NOW
MOV C,A ;NO, MOVE CHARACTER TO C
CALL SENDIT ;SEND THE CHARACTER
JMP GETLP ;LOOP FOREVER
SENDIT EQU $+OFFSET ;SEND (C) TO MODEM
IN MSTAT ;GET MODEM STATUS
ANI TXRDY ;TX BUFFER EMPTY ?
JZ SENDIT ;NO, LOOP UNTIL EMPTY *
MOV A,C ;CHAR TO REG A
OUT MDATA ;SEND TO MODEM
RET
RXDRDY EQU $+OFFSET ;RX DATA IS AVAILABLE
IN MDATA ;GET MODEM CHARACTER
ANI 7FH ;CLEAR PARITY BIT
MOV C,A ;PUT IN REG C
LDA CAPTFG ;GET CAPTURE FLAG
ORA A ;WANT TO SAVE IT ?
JZ NOSAVE ;NO, THEN DON'T SAVE
MOV M,C ;YES, PUT CHAR IN MEMORY
INX H ;INCREMENT POINTER
MOV A,H ;CHECK FOR TOO FAR
CPI DEST SHR 8 ;CAN'T SAVE THIS MUCH
JZ ENDIT ;EXIT IF BUFFER IS FULL
;Insert "JMP GETLP" here if you miss characters
;due to the delay caused by your CONOUT routine.
;This should only be necessary if your console is
;not much faster than the incoming data rate.
;You'll have to figure out some way to determine
;when the data has been captured, however.
NOSAVE EQU $+OFFSET ;NOT SAVING OR NOT FULL
CALL CONOUT ;DISPLAY RECEIVED CHAR
JMP GETLP ;AND LOOP SOME MORE
TOGCAPT EQU $+OFFSET ;TOGGLE CAPTURE FLAG
LDA CAPTFG ;GET IT
CMA ;COMPLEMENT IT
STA CAPTFG ;RESTORE FLAG
ORA A ;CAPTURE NOW ON ?
JZ GETLP ;NO, BACK TO LOOPING
MVI C,BELL ;YES, TELL USER CAPTURE
CALL CONOUT ; HAS BEEN TOGGLED ON
JMP GETLP ;BACK TO LOOPING
ENDIT EQU $+OFFSET ;BUFFER FULL, GO TO CP/M
MVI C,'S'-40H ;STOP OUTPUT IF POSSIBLE
CALL SENDIT ; WITH A CTL-S
ENDIT1 EQU $+OFFSET ;ENTER HERE TO EXIT W/O ^S
MVI A,'Z'-40H ;END OF FILE FLAG
MOV M,A ;SAVE IN BUFFER
MOV A,H ;GET NUM OF PAGES TO SAVE
PUSH PSW ;SAVE ON STACK
LXI D,SAVE ;POINT DE TO "SAVE" MESSAGE
MVI C,9 ;PRINT STRING FUNCTION
CALL BDOS ;PRINT EXITING MESSAGE
POP PSW ;RESTORE NUMBER OF PAGES
MVI C,'0' ;INIT HUNDREDS DIGIT
HUND EQU $+OFFSET ;LOOP HERE 'TIL < 100
SUI 100 ;ANY HUNDREDS DIGITS?
JC TENS ;NO, CHECK TENS
INR C ;YES, BUMP HUNDREDS DIGIT
JMP HUND ;ANY MORE HUNDREDS ?
TENS EQU $+OFFSET ;NO MORE HUNDREDS
ADI 100 ;PUT BACK 100
PUSH PSW ;SAVE COUNT
CALL CONOUT ;PRINT HUNDREDS DIGIT
POP PSW ;RESTORE COUNT
MVI C,'0' ;INIT TENS DIGIT
TEN1 EQU $+OFFSET ;LOOP HERE 'TIL < 10
SUI 10 ;ANY TENS DIGITS?
JC ONES ;NO, CHECK ONES
INR C ;YES, BUMP TENS DIGIT
JMP TEN1 ;ANY MORE TENS?
ONES EQU $+OFFSET ;NO MORE TENS
ADI 10+'0' ;PUT BACK 10, ADD ASCII BIAS
PUSH PSW ;SAVE NUMBER
CALL CONOUT ;PRINT TENS DIGIT
POP PSW ;RESTORE ONES DIGIT
MOV C,A ;PASS TO CONOUT IN REG C
CALL CONOUT ;PRINT ONES DIGIT
LHLD SPSAVE ;GET OLD STACK POINTER
SPHL ;PUT IN SP
RET ;BACK TO CP/M
CONST EQU $+OFFSET ;PATCHED BY PROGRAM TO
PCONST JMP BASE+6H ; YOUR BIOS CONST ADDRESS
CONIN EQU $+OFFSET ;PATCHED BY PROGRAM TO
PCONIN JMP BASE+9H ; YOUR BIOS CONIN ADDRESS
CONOUT EQU $+OFFSET ;PATCHED BY PROGRAM TO
PCONOUT JMP BASE+0CH ; YOUR BIOS CONOUT ADDRESS
SAVE EQU $+OFFSET ;EXITING MESSAGE
DB BELL,CR,LF,LF,'GETIT exiting, SAVE $'
CAPTFG EQU $+OFFSET ;CAPTURE FLAG
DB 0 ;00 = NO CAPTURE, DEFAULT
PEND EQU $ ;END OF RELOCATED PROGRAM
SPSAVE EQU $+OFFSET ;ORIG SP SAVED HERE
DS 2 ;DON'T INCLUDE IN BLOCK MOVE
END