;
; MBOOT.ASM ver 3.1
; Revised March 1983 by John Johnston
; to suit the Osborne-1
; Use is made of the punch and reader routines in the
; BIOS, and also of the serial status routine.
; the IOBYTE should be set to have the Punch
; and Reader set to use the Serial Port.
; NO CHECKING OF THE ABOVE ASSIGNMENT IS DONE
;
; (revised 8 Jun 82 by Bill Bolton)
;
;MODEM BOOT PROGRAM by Keith Petersen, W8SDZ.
;Thanks to John Taylor for idea of incorporating
;simple terminal routine.  Based on MODEM.ASM V2.0,
;by Ward Christensen with enhancements from MODEM527.
;
;CP/M - CP/M file transfer program (receive only)
;
;This program is intended for use as a way to
;initially transfer MODEM.COM or MODEM.ASM to
;a new user.  It may be used with almost any
;modem (see equates).
;
;A simple terminal routine at start of program allows
;user to communicate with a remote system prior to
;receiving a file to make it possible to down-load
;a file without intervention on the part of the host
;system's operator.
;
;COMMANDS:  MBOOT FILENAME.FILETYPE
; or  MBOOT A:FILENAME.FILETYPE
; or  MBOOT B:FILENAME.FILETYPE
;
;The program will operate as a dumb terminal until
;an 'ESC' key is typed (ctrl-[).  It then branches
;to the receive routine.  The user may also exit
;to CP/M without opening the receive file by typing
;ctrl-E from the terminal.  The values for the escape
;and exit keys may be changed in accordance with the
;needs of the user - some keyboards do not have the
;'ESC' and/or provision for control characters.
;See equates.
;
;NOTE: Comments for the source code and tabs have been
;removed to make this file easier to transport from one
;system to another. It may look strange but will assemble
;OK (KBP)
;
FALSE EQU 0
TRUE  EQU NOT FALSE
;
STDCPM EQU TRUE  ;TRUE, IS STANDARD CP/M
ALTCPM EQU FALSE ;TRUE, IS ALTERNATE CP/M FOR H8 OR TRS80
;
 IF STDCPM
BASE EQU 0
 ENDIF
;
 IF ALTCPM
BASE EQU 4200H
 ENDIF
;
EXITCHR EQU 05H ;CTL-E TO EXIT TERM MODE TO CP/M
ESC	EQU 1BH ;ESCAPE TO EXIT TERM MODE TO FILE RCVE
;
SPEED EQU 4	;CPU speed in Mhz  (to nearest Mhz)
;
;CHANGE THESE EQUATES FOR YOUR MODEM PORT REQUIREMENTS
;
INITREQ EQU FALSE ;TRUE,  IF MODEM PORT INITIALISATION REQUIRED
;
MODSNDB EQU 02H ;YOUR BIT TO TEST FOR SEND
MODSNDR EQU 02H ;YOUR VALUE WHEN READY
MODRCVB EQU 01H ;YOUR BIT TO TEST FOR RECEIVE
MODRCVR EQU 01H ;YOUR VALUE WHEN READY
;
;
ERRLIM EQU 10
;
SOH EQU 1
EOT EQU 4
ACK EQU 6
NAK EQU 15H
CAN EQU 18H
LF EQU 10
CR EQU 13
;
BDOS EQU BASE+5
FCB EQU BASE+5CH
;
 ORG BASE+100H
;
 LXI H,0
 DAD SP
 SHLD STACK
 LXI SP,STACK
 CALL INITADR
 CALL ILPRT
 DB 'MBOOT 3.1 as of '
 DB '28/Mar/83',CR,LF,0
 LDA FCB+1
 CPI ' '
 JNZ TERMI
 CALL ILPRT
 DB '++NO FILE NAME SPECIFIED++',CR,LF,0
 JMP EXIT
;
TERMI CALL INITMOD
 CALL READER
 CALL READER
 CALL ILPRT
 DB 'TERMINAL MODE',CR,LF
 DB 'CTRL-E exits to CP/M, ESC starts file transfer'
 DB CR,LF,0
;
TERM CALL STAT
 JZ TERML
 CALL KEYIN
 CPI EXITCHR
 JZ EXIT
 CPI ESC
 JZ RCVFIL
 CALL PUNCH
;
TERML CALL SERSTAT
 ANI MODRCVB
 CPI MODRCVR
 JNZ TERM
 CALL READER
 ANI 7FH
 CALL TYPE
 JMP TERM
;
RCVFIL CALL ERASFIL
 CALL MAKEFIL
 CALL ILPRT
 DB 'FILE OPEN, READY TO RECEIVE',CR,LF,0
;
RCVLP CALL RCVSECT
 JC RCVEOT
 CALL WRSECT
 CALL INCRSNO
 CALL SENDACK
 JMP RCVLP
;
RCVEOT CALL WRBLOCK
 CALL SENDACK
 CALL CLOSFIL
 CALL ERXIT
 DB CR,LF,'TRANSFER COMPLETE$'
;
RCVSECT XRA A
 STA ERRCT
;
RCVRPT MVI B,SPEED*10
 CALL RECV
 JC RCVSERR
 CPI SOH
 JZ RCVSOH
 ORA A
 JZ RCVRPT
 CPI EOT
 STC
 RZ
;
RCVSERR MVI B,SPEED
 CALL RECV
 JNC RCVSERR
 MVI A,NAK
 CALL SEND
 LDA ERRCT
 INR A
 STA ERRCT
 CPI ERRLIM
 JC RCVRPT
;
RCVSABT CALL CLOSFIL
 CALL ERXIT
 DB '++UNABLE TO RECEIVE BLOCK'
 DB CR,LF,'++ABORTING++$'
;
RCVSOH MVI B,SPEED
 CALL RECV
 JC RCVSERR
 MOV D,A
 CALL RECV
 JC RCVSERR
 CMA
 CMP D
 JZ RCVDATA
 JMP RCVSERR
;
RCVDATA MOV A,D
 STA RCVSNO
 MVI C,0
 LXI H,BASE+80H
;
RCVCHR MVI B,SPEED
 CALL RECV
 JC RCVSERR
 MOV M,A
 INR L
 JNZ RCVCHR
 MOV D,C
 MVI B,SPEED
 CALL RECV
 JC RCVSERR
 CMP D
 JNZ RCVSERR
 LDA RCVSNO
 MOV B,A
 LDA SECTNO
 CMP B
 JZ RECVACK
 INR A
 CMP B
 JNZ ABORT
 RET
;
RECVACK CALL SENDACK
 JMP RCVSECT
;
SENDACK MVI A,ACK
;
SEND PUSH PSW
 ADD C
 MOV C,A
;
SENDW CALL SERSTAT
 ANI MODSNDB
 CPI MODSNDR
 JNZ SENDW
 POP PSW
 CALL PUNCH
 RET
;
ABORT LXI SP,STACK
;
ABORTL MVI B,SPEED
 CALL RECV
 JNC ABORTL
 MVI A,CAN
 CALL SEND
;
ABORTW MVI B,1
 CALL RECV
 JNC ABORTW
 MVI A,' '
 CALL SEND
 CALL ERXIT
 DB 'MBOOT PROGRAM CANCELLED$'
;
INCRSNO LDA SECTNO
 INR A
 STA SECTNO
 RET
;
ERASFIL LXI D,FCB
 MVI C,17
 CALL BDOS
 INR A
 RZ
 CALL ILPRT
 DB '++ FILE EXISTS, TYPE Y TO ERASE: ',0
 CALL KEYIN
 PUSH PSW
 CALL TYPE
 CALL CRLF
 POP PSW
 ANI 5FH
 CPI 'Y'
 JNZ MXIT
 LXI D,FCB
 MVI C,19
 JMP BDOS
;
MAKEFIL LXI D,FCB
 MVI C,22
 CALL BDOS
 INR A
 RNZ
 CALL ERXIT
 DB '++ERROR - CAN''T MAKE FILE',CR,LF
 DB 'DIRECTORY MUST BE FULL$'
;
CLOSFIL LXI D,FCB
 MVI C,16
 CALL BDOS
 INR A
 RNZ
 CALL ERXIT
 DB '++CAN''T CLOSE FILE$'
;
WRSECT LHLD SECPTR
 XCHG
 LXI H,BASE+80H
 CALL MOVE128
 XCHG
 SHLD SECPTR
 LDA SECINBF
 INR A
 STA SECINBF
 CPI 16
 RNZ
;
WRBLOCK LDA SECINBF
 ORA A
 RZ
 MOV C,A
 LXI D,DBUF
;
DKWRLP PUSH H
 PUSH D
 PUSH B
 MVI C,26
 CALL BDOS
 LXI D,FCB
 MVI C,21
 CALL BDOS
 POP B
 POP D
 POP H
 ORA A
 JNZ WRERR
 LXI H,80H
 DAD D
 XCHG
 DCR C
 JNZ DKWRLP
 XRA A
 STA SECINBF
 LXI H,DBUF
 SHLD SECPTR
;
RSDMA LXI D,BASE+80H
 MVI C,26
 JMP BDOS
;
WRERR CALL RSDMA
 CALL ILPRT
 DB '++ERROR WRITING FILE',CR,LF,0
 JMP ABORT
;
RECV PUSH D
MSEC LXI D,12500
;
MWTI CALL SERSTAT
 ANI MODRCVB
 CPI MODRCVR
 JZ MCHAR
 DCR E
 JNZ MWTI
 DCR D
 JNZ MWTI
 DCR B
 JNZ MSEC
 POP D
 STC
 RET
;
MCHAR CALL READER
 POP D
 PUSH PSW
 ADD C
 MOV C,A
 POP PSW
 ORA A
 RET
;
INITADR LHLD BASE+1
 LXI D,3
 DAD D
 SHLD VSTAT+1
 DAD D
 SHLD VKEYIN+1
 DAD D
 SHLD VTYPE+1
 DAD D ;HL--> LISTOUT
 DAD D ;HL--> PUNCH OUT
 SHLD VPUNCH+1
 DAD D ;HL--> READER IN
 SHLD VREADER+1
 LXI D,4EH
 DAD D
 SHLD VSERSTAT+1
 RET
;
INITMOD EQU $
;
 IF INITREQ     ;Insert any UART initialisation code here
 ENDIF
;
;
 RET   ; <--THIS RET MUST BE HERE
;
CRLF MVI A,CR
 CALL TYPE
 MVI A,LF
;
TYPE PUSH PSW
 PUSH B
 PUSH D
 PUSH H
 MOV C,A
VTYPE CALL $-$
 POP H
 POP D
 POP B
 POP PSW
 RET
;
STAT PUSH B
 PUSH D
 PUSH H
VSTAT CALL $-$
 POP H
 POP D
 POP B
 ORA A
 RET
;
KEYIN PUSH B
 PUSH D
 PUSH H
VKEYIN CALL $-$
 POP H
 POP D
 POP B
 ANI 7FH
 RET
PUNCH PUSH PSW
 PUSH B
 PUSH D
 PUSH H
 MOV C,A
VPUNCH CALL $-$
 POP H
 POP D
 POP B
 POP PSW
 RET
READER PUSH B
 PUSH D
 PUSH H
VREADER CALL $-$
 POP H
 POP D
 POP B
 RET
SERSTAT PUSH B
 PUSH D
 PUSH H
VSERSTAT CALL $-$
 POP H
 POP D
 POP B
 RET
;
ILPRT XTHL
;
ILPLP MOV A,M
 ORA A
 JZ ILPRET
 CALL TYPE
 INX H
 JMP ILPLP
;
ILPRET XTHL
 RET
ERXIT POP D
 MVI C,9
 CALL BDOS
;
MXIT CALL ILPRT
 DB CR,LF,'DON''T FORGET TO DISCONNECT MODEM'
 DB CR,LF,0
;
EXIT LHLD STACK
 SPHL
 RET
;
MOVE128 MVI B,128
;
MOVE MOV A,M
 STAX D
 INX H
 INX D
 DCR B
 JNZ MOVE
 RET
;
RCVSNO DB 0
SECTNO DB 0
ERRCT DB 0
EOFLG DB 0
SECPTR DW DBUF
SECINBF DB 0
 DS 60
STACK EQU 05000H
DBUF EQU $
;
 END
