FALSE	EQU 0
TRUE	EQU NOT FALSE
STDCPM EQU TRUE
ALTCPM EQU FALSE
 IF STDCPM
BASE EQU 0
 ENDIF
 IF ALTCPM
BASE EQU 4200H
 ENDIF
EXITCHR EQU 01H
ESC EQU 19H
FASTCLK EQU FALSE
SIO	EQU	FALSE
I8251	EQU	FALSE
IMS6402	EQU	FALSE
INITREQ	EQU	FALSE
BINIT EQU FALSE
BINIT1 EQU 03H
BAUDRP EQU 333Q
MODCTLP EQU 335Q
MODDATP EQU 330Q
MODSNDB EQU 20H
MODSNDR EQU 20H
MODRCVB EQU 01H
MODRCVR EQU 01H
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 as of '
DB '3/21/81',CR,LF,0
LDA FCB+1
CPI ' '
JNZ TERMI
CALL ILPRT
DB 'It would be nice if you told me a file name.',CR,LF,0
JMP EXIT
TERMI: CALL INITMOD
 IN MODDATP
 IN MODDATP
 CALL ILPRT
 DB CR,LF,'System now in terminal mode',CR,LF
 DB 'CONTROL A EXITS TO CP/M, CONTROL Y BEGINS FILE TRANSFER.'
 DB CR,LF,0
TERM: CALL STAT
 JZ TERML
 CALL KEYIN
 CPI EXITCHR
 JZ EXIT
 CPI ESC
 JZ RCVFIL
 OUT MODDATP
TERML: IN MODCTLP
 ANI MODRCVB
 CPI MODRCVR
 JNZ TERM
 IN MODDATP
 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
 CALL ILPRT
 DB '*',0
 JMP RCVLP
RCVEOT: CALL WRBLOCK
 CALL ILPRT
 DB CR,LF,0
 CALL SENDACK
 CALL CLOSFIL
 CALL ERXIT
 DB CR,LF,'Transfer Complete... Congratulations!$'
RCVSECT: XRA A
 STA ERRCT
RCVRPT: MVI B,10
 CALL RECV
 JC RCVSERR
 CPI SOH
 JZ RCVSOH
 ORA A
 JZ RCVRPT
 CPI EOT
 STC
 RZ
RCVSERR: MVI B,1
 CALL RECV
 JNC RCVSERR
 MVI A,NAK
 CALL SEND
 CALL ILPRT
 DB CR,LF,' Retrying Sector ',0
 LDA ERRCT
 INR A
 STA ERRCT
 CPI ERRLIM
 JC RCVRPT
RCVSABT: CALL CLOSFIL
 CALL ERXIT
DB CR,LF,'Unable to receive block'
DB CR,LF,'Transfer aborted$'
RCVSOH: MVI B,1
 CALL RECV
 JC RCVSERR
 MOV D,A
 MVI B,1
 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,1
 CALL RECV
 JC RCVSERR
 MOV M,A
 INR L
 JNZ RCVCHR
 MOV D,C
 MVI B,1
 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: IN MODCTLP
 ANI MODSNDB
 CPI MODSNDR
 JNZ SENDW
 POP PSW
 OUT MODDATP
 RET
ABORT: LXI SP,STACK
ABORTL: MVI B,1
 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 'That file already exists. Type a Y to erase and overwrite. ',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 that file.',CR,LF
 DB 'The Directory must be full.$'
CLOSFIL: LXI D,FCB
 MVI C,16
 CALL BDOS
 INR A
 RNZ
 CALL ERXIT
 DB 'Sorry, but I can''t close that 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
 IF FASTCLK
 MOV A,B
 ADD A
 MOV B,A
 ENDIF
MSEC: LXI D,50000
MWTI: IN MODCTLP
 ANI MODRCVB
 CPI MODRCVR
 JZ MCHAR
 DCR E
 JNZ MWTI
 DCR D
 JNZ MWTI
 DCR B
 JNZ MSEC
 POP D
 STC
 RET
MCHAR: IN MODDATP
 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
 RET
INITMOD EQU $
IF INITREQ
 NOP
 NOP
 NOP
 ENDIF
IF BINIT
 MVI A,BINIT1
 OUT BAUDRP
 ENDIF
RET
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
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: DS 2
DBUF EQU $
END