home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
cpm86
/
mboot86.a86
< prev
next >
Wrap
Text File
|
1985-10-13
|
7KB
|
460 lines
;===============================================================;
; ;
; MBOOT86.A86 Ver 1.00 ;
; (preliminary release 11/08/83) ;
; ;
; This program accepts a file that comes in over ;
; an IBM ASYNC adapter board, port-0. ;
; ;
; **** BEWARE **** ;
; This codes is a 2 hour attempt at converting MBOOT ;
; from CP/M-80,8080 code TO CP/M-86,8086 code. It is ;
; not an exact translation!! Like MBOOT, is does have ;
; a terminal mode and will receive a file used the ;
; MODEM/XMODEM protocol. ;
; ;
; CREDITS ;
; MODEM BOOT(MBOOT) - Keith Petersen W8SDZ ;
; Terminal routine - John Taylor ;
; Based on MODEM.ASM - Ward Christensen ;
; MBOOT86 for CP/M-86 - Daniel Deward ;
; ;
; FOR THE CP/M-86 OPERATING SYSTEM ;
; To generate a .CMD file, ;
; A>asm86 mboot86 ;
; A>gencmd mboot86 ;
; ;
;===============================================================;
;
; BDOS FUNCTION NUMBERS
;
CONINP EQU 1 ;CONSOLE INPUT
CONOUT EQU 2 ;CONSOLE OUTPUT
CSTAT EQU 11 ;GET CONSOLE STATUS
;
; ASCII CONTROL CHARACTER EQUATES
;
SOH EQU 01H ;START OF HEADER
EOT EQU 04H ;END OF TRANSMISSION
CR EQU 0DH ;CARRIAGE RETURN
LF EQU 0AH ;LINE FEED
ESC EQU 1BH ;ESCAPE
ACK EQU 06H ;ACKNOWLEDGE
NAK EQU 15H ;NEGATIVE ACK
CAN EQU 18H ;CANCEL TRANSMISSION
;
ERRLIM EQU 10
EXITKEY EQU 03H ;CONTROL-C
;
; I/O PORT ASSIGNMENTS
;
MODDATP EQU 03F8H ;MODEM DATA PORT
MODCTLP EQU 03FDH ;MODEM CONTROL PORT
;
;
CSEG
CLI ;DISABLE INTERRUPTS
MOV DX,OFFSET MSG1 ;LOGON
CALL PSTRING
;
MOV AL,FCB+1 ;CHECK FOR FILE ON COMMAND LINE
CMP AL,' '
JNZ TERMI
;
MOV DX,OFFSET MSG2 ;NO FILE NAME SPECIFIED
CALL PSTRING
JMP EXIT
;
TERMI:
MOV DX,MODDATP
IN AL,DX ;GOBBLE UP GARBAGE
IN AL,DX
;
MOV DX,OFFSET MSG3 ;TERMINAL MODE
CALL PSTRING
;
TMODE:
CALL STAT ;GET KEYBOARD STATUS
JZ TERML ;NO CHAR READY
CALL KEYIN ;ESLE GET CHAR
CMP AL,EXITKEY ;TEST FOR EXIT
JNZ KEYOK
JMP EXIT
;
KEYOK:
CMP AL,ESC ;START FILE XFER ?
JZ RCVFIL
;
MOV DX,MODDATP
OUT DX,AL
;
TERML:
MOV DX,MODCTLP ;GET MODEM STATUS
IN AL,DX
TEST AL,01H
JZ TMODE ;NO CHAR YET
MOV DX,MODDATP ;GET MODEM DATA
IN AL,DX
CALL COUT
JMP TMODE
;
RCVFIL:
CALL MAKEFIL
MOV DX,OFFSET MSG4 ;FILE OPEN READY TO RECEIVE
CALL PSTRING
;
RCVLP:
CALL RCVSECT ;GET SECTOR
JC RCVEOT ;IF END OF TRANSFER
CALL WRSECT ;WRITE SECTOR
CALL INCRSNO ;ADVANCE SECTOR #
CALL SENDACK ;ACK RECORD
JMP RCVLP ;CONTINUE TILL EOT
;
RCVEOT:
CALL WRBLOCK ;WRITE OUT LAST BUFFER
CALL SENDACK ;SEND ACK
CALL CLOSEFIL ;CLOSE THE FILE
;
MOV DX,OFFSET MSG5 ;TRANSFER COMPLETE
CALL PSTRING
JMP EXIT
;
; SUBROUTINE RCVSECT
;
RCVSECT:
XOR AL,AL
MOV ERRCT,AL ;RESET ERROR COUNT
;
RCVRPT:
MOV CH,10 ;SET RETRY COUNT TO 10
CALL RECV
JC RCVSERR
CMP AL,SOH ;START OF HEADER
JZ RCVSOH ;GET IT
OR AL,AL
JZ RCVRPT
CMP AL,EOT ;END OF TRANSMISSION
STC ;INDICATE EOT
JNZ RCVSERR
JMP DORET ;YES, END OF TRANSMISSION
;
RCVSERR:
MOV CH,1
CALL RECV
JNC RCVSERR
;
MOV AL,NAK ;NAK THE BAD FRAME
CALL SEND
MOV AL,ERRCT
INC AL
MOV ERRCT,AL ;SAVE IT BACK
;
CMP AL,ERRLIM ;ERROR LIMIT REACHED ?
JC RCVRPT
;
; ABORT THE RECEIVE
;
RCVSABT:
CALL CLOSEFIL ;SAVE WHATEVER WE GOT
MOV DX,OFFSET MSG6 ;UNABLE TO RECEIVE BLOCK
CALL PSTRING
JMP EXIT
;
RCVSOH:
MOV CH,1 ;TIME OUT = 1 MSEC
CALL RECV ;GET A CHAR
JC RCVSERR
;
MOV DL,AL
MOV CH,1
CALL RECV
JC RCVSERR
;
NOT AL
CMP AL,DL
JZ RCVDATA
JMP RCVSERR
;
RCVDATA:
MOV AL,DL
MOV RCVSNO,AL
MOV CL,0
MOV DI,80H
;
RCVCHR:
MOV CH,1 ;TIME OUT OF 1 MSEC
CALL RECV
JC RCVSERR
;
MOV BYTE PTR[DI],AL ;SAVE THE CHARACTER
INC DI ;ADVANCE POINTER
CMP DI,0100H ;END OF BUFFER ?
JNZ RCVCHR ;CONTINUE UNTIL BUFFER FULL
;
MOV DL,CL ;SAVE CHECK SUM
MOV CH,1 ;SET TIME OUT TO 1 MSEC
CALL RECV
JC RCVSERR
CMP AL,DL
JNZ RCVSERR
;
MOV AL,RCVSNO
MOV BL,AL
MOV AL,SECTNO
CMP BL,AL
JZ RECVACK
INC AL
CMP BL,AL
JZ RCV0
JMP EXIT
;
RCV0: RET
;
;
RECVACK:
CALL SENDACK
JMP RCVSECT
;
SENDACK:
MOV AL,ACK
SEND: PUSH AX ;SAVE OUTPUT CHAR
ADD AL,CL
MOV CL,AL
;
SENDW: MOV DX,MODCTLP
IN AL,DX
TEST AL,20H
JZ SENDW
POP AX ;RESTORE OUTPUT CHAR
MOV DX,MODDATP
OUT DX,AL
RET
;
INCRSNO:
MOV AL,SECTNO
INC AL
MOV SECTNO,AL
RET
;
MAKEFIL:
MOV DX,OFFSET FCB
MOV CL,22
CALL BDOS
INC AL
JZ DIRFULL
JMP DORET
;
DIRFULL:
MOV DX,OFFSET MSG8
CALL PSTRING ;DIRCETORY FULL
JMP EXIT
;
CLOSEFIL:
MOV DX,OFFSET FCB
MOV CL,16
CALL BDOS
INC AL
JZ NOCLOSE
JMP DORET
;
NOCLOSE:
MOV DX,OFFSET MSG9 ;CAN'T CLOSE FILE
CALL PSTRING
JMP EXIT
;
WRSECT:
MOV DI,SECPTR
MOV SI,80H
CALL MOVE128 ;COPY TO DISK BUFFER
MOV SECPTR,DI ;SAVE NEW POINTER
;
MOV AL,SECINBF
INC AL
MOV SECINBF,AL
CMP AL,16
JZ WRBLOCK
JMP DORET
;
; OUTPUT BUFFER TO DISK
;
WRBLOCK:
MOV AL,SECINBF ;GET SECTOR COUNTER
OR AL,AL
JNZ WR0
JMP DORET
;
WR0:
MOV CL,AL ;CL = WRITE COUNTER
MOV DX,OFFSET DBUF
;
DKWRLP:
PUSH DX
PUSH BX
PUSH CX ;SAVE REGISTERS
;
MOV CL,26
CALL BDOS
;
STI ;ENABLE INTERRUPTS
MOV DX,OFFSET FCB
MOV CL,21
CALL BDOS
CLI ;DISABLE INTERRUPTS
;
POP CX
POP BX
POP DX
OR AL,AL ;TEST DISK WRITE STATUS
JNZ WRERR ;DISK WRITE ERROR
;
ADD DX,80H ;ADVANCE DMA POINTER
DEC CL
JNZ DKWRLP ;CONTINUE WRITTING
;
MOV SECINBF,0
MOV DX,OFFSET DBUF
MOV SECPTR,DX
;
RSDMA: MOV DX,80H
MOV CL,26
CALL BDOS
RET
;
WRERR: CALL RSDMA
MOV DX,OFFSET MSG10
CALL PSTRING ;ERROR IN WRITTING FILE
JMP EXIT
;
; RECV
; UPON ENTRY
; CH = # OF MSEC BEFORE TIME OUT
;
; UPON EXIT
; CL = UPDATED CHECKSUM
;
RECV:
PUSH DX
PUSH BX
MSEC: MOV BX,50000
MWTI: MOV DX,MODCTLP
IN AL,DX
TEST AL,01H
JNZ MCHAR
DEC BL
JNZ MWTI
DEC BH
JNZ MWTI
DEC CH
JNZ MSEC
POP BX
POP DX
STC
RET
;
MCHAR: MOV DX,MODDATP
IN AL,DX
ADD CL,AL ;UPDATE CHECKSUM
OR AL,AL
POP BX
POP DX
RET
;
MOVE128:
PUSH BX
MOV BL,128
MOVE: MOV AL,BYTE PTR [SI]
MOV BYTE PTR [DI],AL
INC SI
INC DI
DEC BL
JNZ MOVE
POP BX
RET
;
EXIT:
STI
MOV CL,0
CALL BDOS
;
PSTRING:
MOV CL,9
CALL BDOS
RET
;
KEYIN:
PUSH BX
PUSH DX
MOV CL,CONINP
CALL BDOS
POP DX
POP BX
RET
;
COUT:
PUSH BX
PUSH DX
MOV DL,AL
MOV CL,CONOUT
CALL BDOS
POP DX
POP BX
RET
;
STAT:
PUSH BX
PUSH DX
MOV CL,CSTAT
CALL BDOS
OR AL,AL
POP DX
POP BX
RET
;
DORET: RET
;
BDOS:
INT 224
RET
;
; DATA AREA
;
DSEG
ORG 5CH
FCB RB 35 ;FILE CONTROL BLOCK
BUFF RB 128 ;DISK WRITE BUFFER
;
DW 0 ;ALIGN TO WORD BOUNDARY
;
RCVSNO DB 0 ;RECEIVED SECTOR NUMBER
SECTNO DB 0 ;CURRENT SECTOR NUMBER
ERRCT DB 0 ;ERROR COUNT
SECPTR DW DBUF ;DISK BUFFER POINTER
SECINBF DB 0 ;# OF SECTORS IN DISK BUFFER
;
DBUF RS 4096 ;DISK BUFFER
DW 0
;
; MESSAGES
;
MSG1 DB CR,LF,'MBOOT FOR THE IBM-PC',CR,LF
DB 'Version 1.00',CR,LF,'$'
MSG2 DB CR,LF,'No file name specified',CR,LF,'$'
MSG3 DB CR,LF,'Terminal mode',CR,LF,LF,'$'
MSG4 DB CR,LF,'File open, ready to receive',CR,LF,'$'
MSG5 DB CR,LF,'Transfer complete',CR,LF,'$'
MSG6 DB CR,LF,'Unable to receive block',CR,LF,'$'
MSG8 DB CR,LF,'Directory full',CR,LF,'$'
MSG9 DB CR,LF,'Cannot close file',CR,LF,'$'
MSG10 DB CR,LF,'Error in writting file',CR,LF,'$'
;
END