	.title 'Read sectors from the hard disk to a CP/M file'
	.sbttl 'READ0'
version	==	1
revision==	1
	.pabs
	.phex
	.loc	100h
	jmp	START

; 		Program: READ0

; Read into a buffer from a specified track and sector
; number a specified number of sectors from the hard 
; disk.  This is done using BIOS calls found at the 
; bottom of the program.
; Next, write to floppy disk in the form of a CP/M 
; file whose name the user specifies.
;
; Data is taken from the console or the command line.
; Acceptable entry parameters are as follows:
;
; A>READ0 FLOPFILE.EXT [ HDtrack HDsector numsectors ]
; A>READ0 FLOPFILE.EXT
;
; In the latter case, READ0 will ask for the 
; missing hard disk information.
;
; Step 1 - Read in specified sectors from hard disk
; Step 2 - Print data to a specified CP/M file.
;
;---------
; MAIN BODY
;

mxdskSEC    =   80h ; maximum number of sectors on disk
mxdskTRK    =   16  ; maximum number of tracks on disk
DMAaddr: .word	00h ; addr ( in file buffer ) for DMA
FCBaddr:.word	0000h	; address of FCB (here or 5Ch)

; File Control Block. See CP/M users guide for details.
FCB:	.byte	00h
filnam:	.byte	20h,20h,20h,20h,20h,20h
	.byte	20h,20h,20h,20h,20h
	.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;
DSKname:.byte	00	;Holder for I/O drive number
FCBcnt:	.byte	00h	;Counter of FCB bytes tranfered
numSEC:	.byte	00h	;Number of sectors to I/O
bufaddr:.word	00h	;Current address in FCB 
WBOOT	=	00h	;Warm Boot entry point
BDOS	=	05h	;Common CP/M entry point
incon	=	01h	;CP/M console input function
cstat	=	0Bh	;CP/M console status function
bufread	=	0Ah	;CP/M console buffer function
resetdsk=	0Dh	;CP/M disk system reset funct.
logdsk	=	0Eh	;CP/M select disk function
open	=	0Fh	;CP/M file open function
close	=	10h	;CP/M file close function
kill	=	13h	;CP/M file delete function
CPMwrite=	15h	;CP/M file sector write funct.
create	=	16h	;CP/M file create function
interdrv=	19h	;CP/M drive interrogate funct.
dma	=	1Ah	;CP/M Dir Mem Addr set function
cr	=	0Dh	;carriage return
lf	=	0Ah	;line feed
blank	=	20h	;ascii blank
period	=	2Eh	;ascii period
colon	=	3Ah	;ascii colon
EOF	=	1Ah	;end marker for file & buf I/O

; Space for 15-chr CP/M maintained buffer
conbuf:	.byte	15,0
	.byte	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
clrBYTS:.ascii	'                          '

; Buffer for holding data read from the hard disk
; and writing to the floppy disk.
filebuf=1000h	; File Buffer starts here

START:
; Print log-on message
	lxi	H,LOGmsg
	call	prtmsg
; Initialize 
Š	mvi	A,0
	sta	FCBcnt	;zero the counter
;
	lxi	H,filnam;FCB file name location
	shld	bufaddr
;
	lxi	H,FCB
	shld	FCBaddr ;FCB address (if no com line)
;
	mvi	C,interdrv
	call	BDOS
	sta	DSKname	; save default drive select
;
	lxi	H,80h	; 80h holds length of com line
	mov	A,M	; get the com line length
	add	L	; A = A + L
	mov	L,A	; HL= last com line addr
	inx	H
	mvi	M,blank
	inx	H
	mvi	M,blank	; pad end of com line w/blanks

;---GET THE STARTING TRACK AND SECTOR, AND GET THE
;   NUMBER OF SECTORS TO READ FROM THE HARD DISK.

; Check the command line for  TRK SEC NUMSEC 
SCANCOM:
	lxi	H,80h	; command line address
	mov	A,M	; get the length of com line
	cpi	2	; Is com line just garbage?
	jrc	getTRK	; Yes. Get data from user.
; Command line exists.  Pass over the file name
; to the expected data
..1:	inx	H	; No. Look for non-blnk
	mov	A,M	; character.
	cpi	blank	; Have we found it?
	jrz	..1	; No. Try next character.
..2:	inx	H	; Yes. Now look for 
	mov	A,M	; next blank character
	cpi	blank	; Have we found it?
	jrnz	..2	; No. Try next character
; Get the starting track number from the command line.
	call	eatblank; Yes. Eat any more blanks.
	call	makHBYT	; And make chr(s) into a byte
	cpi	mxdskTRK; Is it within bounds.
	jnc	getTRK	; No. Ask user for data.
	sta	curTRK	; then save as starting track
; Get the starting sector from the commmand line.
	call	eatblank
	call	makHBYT
	cpi	mxdskSEC; Is it within bounds?
	jnc	getTRK	; No. Ask user for data.
	cpi	1	; Is it within bounds?
	jc	getTRK	; No. sector value is 0
	sta	curSEC	; Yes. save as current sector.
; Get the number of sectors to read from command line.
	call	eatblank
	call	makHBYT
	sta	numSEC
; All hard disk data received from command line.
	jmp	readHD	; Read the hard disk data.

getTRK:	lxi	H,crlf	 ; space down a line
	call	prtmsg
	lxi	H,TRKmsg ; ask which track
	call	putBUF	 ; read console buffer
; A=length of buffer \ HL=(addr of 1st buf chr)-1
	cpi	0	 ; just a car ret?
	push	PSW
	lxi	H,errmsg
	cz	prtmsg
	pop	PSW
	jrz	getTRK	    ; ask again
	lxi	H,conbuf+2  ; get CP/M console address
	call	makHBYT	    ; make chrs into a hex byte
	cpi	mxdskTRK    ; is it with in bounds?
	jrz	savTRK	    ; Yes.
	jrc	savTRK	    ; Yes.
	lxi	H,errmsg    ; No. Print error message
	call	prtmsg
	jmpr	getTRK	    ; and try again.
savTRK:	sta	curTRK	    ; Yes. Store entry

getSEC:	lxi	H,SECmsg ; ask which sector
	call	putBUF	 ; read console buffer
; A=length of buffer \ HL=(addr of 1st buf chr)-1
	cpi	0	 ; just a car ret?
	push	PSW
	lxi	H,errmsg
	cz	prtmsg
	pop	PSW
	jz	getSEC	; ask again
	lxi	H,conbuf+2 ; CP/M console buffer addr
	call	makHBYT	; make chrs into a hex byte
	cpi	1	; is it within bounds?
	jrc	..2	; too low?	
	cpi	mxdskSEC; too high?
	jz	savSEC	; No. save the byte
	jc	savSEC	; No. save the byte
..2:	lxi	H,errmsg; Yes. Print the error message
	call	prtmsg
	jmp	getSEC	; and ask again.
savSEC:	sta	curSEC	; Yes.  Store entry

getNS:	lxi	H,NSmsg ; ask how many sectors
	call	putBUF	 ; read console buffer
; A=length of buffer \ HL=(addr of 1st buf chr)-1
	cpi	0	 ; just a car ret?
	push	PSW
	lxi	H,errmsg
	cz	prtmsg
	pop	PSW
	jrz	getNS	; ask again
	lxi	H,conbuf+2 ; CP/M console buffer addr
	call	makHBYT	; make chrs into a hex byte
	cpi	1	; is it within bounds?
	jrnc	savNS	; is entry 0?
	lxi	H,errmsg; Yes. print error message
	call	prtmsg
	jmpr	getNS	; and ask again.
savNS:	sta	numSEC	; Valid entry. Store it.

; Valid hard disk track and sector number received.
; Number of sectors to read from hard disk received.
; Display starting track and sector to the user.
; Also, display number of sectors to write.

	lxi	H,crlf	; space down a line
	call	prtmsg	
	lxi	H,HEADmsg ; print the header
	call	prtmsg
	lxi	H,space4  ; space over 4 spaces
	call	prtmsg
	lda	curTRK
	call	prtbyt	  ; print current track
	lxi	H,space4  ; space over 4 spaces
	call	prtmsg
	lda	curSEC	   
	call	prtbyt	  ; print current sector
	lxi	H,space4  
	call	prtmsg
	lxi	H,space4
	call	prtmsg	  ; space over 8 spaces
	lda	numSEC
	call	prtbyt	  ; print no. of secs to write

; Verify data accuracy. Jump back to getTRK if bad data
	
ASKifOK:lxi	H,crlf	 ; space down a line
	call	prtmsg
	lxi	H,VERmsg
	call	prtmsg	 ; print 'data correct?' msg
	mvi	C,incon
	call	BDOS	 ; get console chr
	ani	0DFh	 ; make it upper case
	cpi	'N'
	jz	getTRK	 ; Data is incorrect
	cpi	'Y'
	jrz	readHD	 ; User says data is AOK
	cpi	3	 ; 3 is a Control-C
	jz	WBOOT	 ; abort if Control-C
	lxi	H,errmsg
	call	prtmsg	 ; print error message
	jmpr	ASKifOK	 ; bad entry. Ask again

; Read data from hard disk at specified track and secs

readHD:	lxi	H,crlf
	call	prtmsg	  ; space down a line
	call	chaMAPbyt ; assign unit 0 to hard disk
	call	HDread	  ; read from the disk
	call	resMAPbyt ; restore users unit 0 assmt

	lxi	H,readmsg ; tell user weve got the
	call	prtmsg	  ; data from the hard disk.

; Get file name from user or at CP/M's FCB at 5Ch.

; Check the command line. Get file name is possible.
	lxi	H,80h	; addr of length of com line
	mov	A,M	; A = length of com line
	cpi	2	; is com line garbage?
	jrc	GETFIL	; Yes. ask user for file name
	lxi	H,5Ch	; No. Load in default FCB addr
	shld	FCBaddr
	jmp	OPENFIL	; Try to open the file.
; Com line has no useable file name. Get it from user.
GETFIL:
	lxi	H,FCB	; set FCB address to inside
	shld	FCBaddr	; the program.
	lxi	H,entmsg
	call	prtmsg	;ask for file name
	call	putBUF	;read console buffer
; A=length of buffer  /  HL=(addr of 1st buffer chr)-1
	cpi	2	;just car ret?
	jnc	readbuf	;NO. Read file name 
	lxi	H,bfnmsg;Yes.
	call	prtmsg	;print 'bad file name' msg
	jmp	WBOOT	;and warm boot.

READBUF:
; Check for a drive select at the start of the file name
; in the console buffer.
	lxi	H,conbuf+1 ; get console buf address
..1:	inx	H	; get to next chr of buffer
	mov	A,M	; get the chr
	cpi	blank	; Is it a blank?
	jrz	..1	; Yes skip it.
	inx	H	; No. Get to 2nd buf chr addr
	mov	A,M	; get 2nd chr
	cpi	colon	; Was 1st chr a drive select?
	dcx	H	;
	dcx	H	; get back to 1st com buf chr
	jrnz	..2	; No, its only a file name
	inx	H	; Yes. Get back to 'drive name'
	mov	A,M	; Get the ascii drive name
	ani	0DFh	; make sure its UPPER CASE
	sui	'A'	; make the ascii chr numeric
	cpi	4	; Is drive select more than 'D'
	push	PSW
	push	H
	lxi	H,bfnmsg
	cnc	prtmsg	; Yes. Print the error message
	pop	H
	pop	PSW
	jnc	GETFIL	; and ask user for the data.
	sta	DSKname	; No. Its valid - we'll save it
	inx	H	; increment past the colon
; Load the file name into the File Control Block
..2:	inx	H	; next buffer chr address
	mov	A,M	; next buffer character
	cpi	blank	; Is chr a blank?
	jrz	..2	; Yes. Skip over it
	cpi	period	; No. Is it a period?
	cz	expand	; Yes. Leave padded blanks
	jrz	..2	; Yes. Now skip to next chr
; Reg A=Valid character.  Read into 'filnam' in FCB
	push	H	;save buf chr addr
	lhld	bufaddr
	cpi	'a'	;Is chr lower case?
	jrc	..3	;NO.
	ani	0DFh	;Yes. Make chr UPPER CASE
..3:	mov	M,A	;store chr at filnam addr
	inx	H	;next filnam addr
	shld	bufaddr
	pop	H	;restore buf chr addr
; increment character counter for FCB
	lda	FCBcnt
	inr	A
	cpi	11	;FCB filled in?
	jz	openfil
	sta	FCBcnt
	jmpr	..2	;get next buf chr
; Kill the specified file, then create and open it.
OPENFIL:
	mvi	C,resetdsk
	call	BDOS	; reset the disk system
	lda	DSKname	; disk for I/O
	mov	E,A
	mvi	C,logdsk
	call	BDOS	; log the I/O disk
	mvi	C,kill
	lded	FCBaddr
	call	BDOS	; kill the file
	mvi	C,create
	lded	FCBaddr
	call	BDOS	; create the file
	mvi	C,open
	lded	FCBaddr
	call	BDOS	; open the file
	cpi	0FFh
	jrnz	writefil; AOK open, read into buffer
	lxi	H,badmsg
	call	prtmsg	;'cant open file' message
	jmp	GETFIL	; ask again for file name.

; File is open.  Write to it from buffer (until EOF)	

;-----------------------------------
ŠWRITEFIL:
; Print 'file opened' message
	lxi	H,fomsg
	call	prtmsg
; Initialize the DMA address
	lxi	H,filebuf
	shld	DMAaddr
; Initialize the sector counter
	lda	numSEC
	sta	SECcnt	; number of sectors to write
writesec:
; Set the dma address
	mvi	C,dma	;dma-set function
	lded	DMAaddr	;get dma addr in DE
	call	BDOS	
; Read in a 128-byte sector into the dma address
	mvi	C,CPMwrite
	lded	FCBaddr
	call	BDOS	;read the sector
; Successful write? If not, die
	cpi	00	;successful read?
	jrz	..1	;Yes. continue
	lxi	H,badmsg;NO.
	call	prtmsg	; print 'can't write' msg
	jmp	WBOOT	; and Die.
; Increment the dma address 
..1:	lhld	DMAaddr
	lxi	D,128
	dad	D
	shld	DMAaddr
; Decrement the sector counter
	lda	SECcnt
	dcr	A
	sta	SECcnt	; sectors left to write
	cpi	0	; all sectors written?
	jrz	closefil; Yes. close the file
; Loop back and read another sector
	jmp	writesec

closefil:
	lxi	H,fcmsg ;print file-closed msg
	call	prtmsg
	lxi	H,crlf
	call	prtmsg	;and space down a line
	mvi	C,close
	lded	FCBaddr
	call	BDOS	; close the file
	lxi	H,finmsg
	call	prtmsg	; print closing message
	jmp	WBOOT	; and warm boot.
;--------
;Subroutine:	EXPAND
;  Regs  in:
;  Regs out:
; Destroyed:
EXPAND:
; Leave blanks between file name and extension in FCB
	push	PSW	;save condition flags
	lda	FCBcnt	;no. of chrs transfered
	mov	B,A
	mvi	A,8	;eight total spaces
	sta	FCBcnt	;move counter to 8th pos
	sub	B
	cpi	0
	jrz	..1	;no pads nessecary
	jm	prterr	;terminal error
	push	H	;save file name addr
	lhld	bufaddr	;get FCB addr
..2:	dcr	A	;decr counter
	inx	H	;incr buf addr
	cpi	0
	jrnz	..2	;leave more padded blanks
	shld	bufaddr
	pop	H	;restore file name address
..1:	pop	PSW	;restore flags
	ret

;----------
; Subroutine: 	eatblank
; Regs  in:	HL= Present buffer address
; Regs out:	HL= Addr of 1st non-blank buffer addr
;		A = num of chrs before next blank
; Destroyed	A,B
eatblank: 
	mvi	B,0	; B is the chr counter
..1:	inx	H	; get to next buffer address
	mov	A,M
	cpi	blank	; Is chr a blank?
	jrz	..1	; Yes. keep scanning.
	inr	B	; No. Increment chr counter
	push	H	; and save non-blnk chr addr
..2:	inx	H	; get to next chr address
	inr	B	; increment chr counter
	mov	A,M	; get the chr
	cpi	blank	; Is chr a blank?
	jrnz	..2	; No. Keep scanning for one.
	dcr	B	; Yes. decrement chr counter
	mov	A,B	; and put it in A.
	pop	H	; restore non-blnk chr addr
	ret		; and return.

;----END OF MAIN BODY
;
; UTILITY SUBROUTINES
;
;----------
; Subroutine:	prtmsg
; Regs  in:	HL=addr of string to be printed
; Regs out:	none
; Destroyed:	A,HL,C
prtmsg:	mov	A,M
	ora	A
	rz		; finished if a null
	push	H
	mov	C,A
	call	CONOUT
	pop	H
	inx	H
	jmpr	prtmsg

;----------
; Subroutine:	prtbyt
; Regs  in:	A=byte to be printed
; Regs out:	none
;Destroyed:	A,any and/or all others
; Print a byte to the console.
prtbyt:
	push	PSW	; save the chr
	rlc
	rlc
	rlc
	rlc
	call	prtnbl
	pop	PSW
	call	prtnbl
	ret
prtnbl:	ani	0Fh
	adi	'0'
	cpi	'9'+1
	mov	C,A
	jc	CONOUT
	adi	'A'-'9'-1
	mov	C,A
	jmp	CONOUT
;----------
; Subroutine:	prterr
; Regs  in:	none
; Regs out:	none
; Destroyed:
;Terminate the program with a message and warm boot.
PRTERR:	lxi	H,TERMmsg
Š	call	prtmsg	;print 'TERMINAL ERROR' msg
	jmp	WBOOT


;----------
;		Subroutine: makDBYT
; Regs  in:	A=length of console buffer
; Regs out:	A=decimal byte made from console buffer
;Destroyed:	HL,A,B,C
;Make a decimal byte from one or two buffer chrs
makDBYT:
	cpi	1	   ; just one chr
	mvi	B,0
	lxi	H,conbuf+2 ; load 1st chr addr
	jrz	..1
;multiply first chr by 10 and save
	mov	A,M
	sui	'0'	; make ascii chr numeric
	mov	B,A	; save original number
	rlc
	rlc
	rlc
	mov	C,A
	mov	A,B
	rlc
	add	C
	mov	B,A	;save 10*number in B
	inx	H	; get 2nd chr addr
..1:	mov	A,M
	sui	'0'	; make ascii chr numeric
	add	B	; add the two chrs
	ret
;----------
;		Subroutine: makHBYT
; Regs  in:	A  = length of console buffer
;		HL = 1st character address
; Regs out:	A=hex byte made from console buffer
;		HL = address of last chr used.
;Destroyed:	B,C
;Make a hex byte from one or two buffer chrs
makHBYT:
	cpi	1	   ; just one chr?
	mvi	B,0
	jrz	aa1	   ; process 1st chr only
;multiply first chr by 16 and save in B
	mov	A,M	; get 1st chr
	inx	H	; get to next chr
	cpi	'A'
	jm	aa2
	ani	0DFh	; make all letters upper case
	sui	'A'-'9'-1
aa2:	sui	'0'
	cpi	0
	jz	aa1	; skip mult if nibble is 0
	ora	A	; reset carry flag
	rlc
	rlc
	rlc
	rlc
	mov	B,A	;save 16*firstnumber in B
aa1:	mov	A,M	; get 2nd chr
	cpi	'A'
	jm	aa3
	ani	0DFh	; make all letters upper case
	sui	'A'-'9'-1
aa3:	sui	'0'
	ora	A	; reset the flags
	add	B	; add the two chrs
	ret

;----------
;		Subroutine: cvtbcd
; Regs  in:	A=byte to be converted
; Regs out:	A=byte, in BCD format
; Destroyed:	B
;Convert binary to BCD
cvtbcd:
	ora	A
	rz
	mov	B,A
	xra	A
..1:	inr	A
	daa
	djnz	..1


;----------
;		Subroutine: putBUF
; Regs  in:	HL=address of message to print
; Regs out:	A =number of chrs put in buffer
; 		HL=(addr of 1st buf chr)-1
;Destroyed:
;Put console input in a buffer
putBUF:
	call	prtmsg
	call	clrBUF	 ; clear the console buffer	
	mvi	C,bufread ; CP/M console buffer read
	lxi	D,conbuf ; address of console buffer
	call	BDOS	 ; put console input in buffer
	lxi	H,conbuf+1
	mov	A,M	 ; put num of buffer chrs in A
	ret
;----------
;		Subroutine: clrBUF
; Regs  in:	none
; Regs out:
; Destroyed:
;Clear the console buffer at address 'conbuf'
clrBUF:
	lxi	B,15
	lxi	H,clrBYTS
	lxi	D,conbuf+2
	ldir
	ret

;----------
; Output Messages
;
LOGmsg:	.ascii	[cr][lf]'READ0 VER. '
	.byte	version+'0','.'
	.byte 	revision/10+'0',revision@10+'0'
	.ascii	[cr][lf]
	.ascii	'Hard disk to Floppy disk CP/M file'
	.asciz	'write utility program.'[cr][lf][lf]
entmsg:	.asciz	[cr]'Enter floppy file name  - '
bfnmsg:	.asciz	[cr][lf]'Invalid file name found'
badmsg:	.asciz	[cr][lf]'Cant open or write to file'
fomsg:	.asciz	[cr][lf]'File opened.'
fcmsg:	.asciz	[cr][lf]'File closed.'
RDYmsg:	.asciz	[cr][lf]'Ready. '
VERmsg:	.asciz	[cr][lf]' Is data correct? '
HEADmsg:.ascii	[cr][lf]'  TRACK  SECT  SECTS TO READ'
	.ascii	[cr][lf]'  -----  ----      -----'
crlf:	.asciz	[cr][lf]
errmsg:	.ascii	[cr][lf]'Incorrect entry.  Control-C '
	.asciz	'aborts program.  Please try again.'
TERMmsg:.asciz	[cr][lf]'***  TERMINAL ERROR  ***'
endmsg:	.asciz	[cr][lf]'Exiting from READ0'
readmsg:.asciz	'Data read from hard disk'[cr][lf]
finmsg:	.asciz	[cr][lf]'Data written to floppy disk'
space4:	.asciz	'    '
TRKmsg:	.ascii	[cr][lf]'Starting track  number '
	.asciz	'(in hex)? '
SECmsg:	.ascii	[cr][lf]'Starting sector number '
	.asciz	'(in hex)? '
NSmsg:	.ascii	[cr][lf]'Number of sectors to '
	.asciz	'read (in hex)? '
.page
;*********************************************
;*                                           *
;* HARD DISK INPUT DATA, DEFS, & SUBROUTINES *
;*                                           *
;*********************************************

HDbyt	=	10000000b ; byte assigns hard disk to 0
MAPbyt:	.byte	00h	; users unit 0 assignment
curTRK:	.byte	00h	; current track for disk I/O
curSEC:	.byte	00h	; current sector for disk I/O
SECcnt:	.byte	00h	; number of secs left for I/O

;----------
;Subroutine:	chaMAPbyt
; Regs  in:	none
; Regs out:	none
;Destroyed:	any and/or all registers

; Change the unit 0 assignment to that of a hard disk.
; Save the previous assignment for restoration.
chaMAPbyt:
	mvi	C,0
	call	SELDSK	; select unit 0 
	call	CPMmap	; get current unit 0 assignment
; Current unit 0 assignment (network,etc) returns in A
; BIOS address of the CP/M MAP byte returns in HL
	sta	MAPbyt	; save it for later restoration
	mvi	M,HDbyt	; assign unit 0 to a hard disk
	ret

;----------
;Subroutine:  	resMAPbyt
; Regs  in:	none
; Regs out:	none
;Destroyed:	any and/or all registers

; Restore the previous unit 0 assignment
resMAPbyt:
	call	CPMmap	; get current unit 0 assignment
;Current unit 0 assignment (hard disk) returns in A
;BIOS address of the CP/M MAP byte returns in HL
	lda	MAPbyt	; original unit 0 assignment
	mov	M,A	; restore previous assignment
	ret

;----------
;Subroutine:	HDread
; Regs  in:	none
; Regs out:	none
;Destroyed:

; Read from the hard disk into the buffer

HDread:
	lda	numSEC	; num of sectors to read
	sta	SECcnt	; sector counter
	lxi	H,filebuf
	shld	DMAaddr	;set value for first DMA addr
	call	HOME
	ora	A	; reset the carry flag
..1:	rc		; return if carry bit set
	mvi	C,0
	call	SELDSK	; select hard disk
	lda	curTRK	; load current track
	mov	C,A
	call	SETTRK	; select track 0
	lda	cursec	; load current sector
	mov	C,A
	call	SETSEC	; select current sector
	lbcd	DMAaddr
	call	SETDMA	; select proper buffer location
	call	READ	; and read from the disk
	call	INRdata	; increment DMA addr and sector
	jmpr	..1	; read until INRaddr sets carry

;----------
;Subroutine:	INRdata
; Regs  in:	none
; Regs out:	carry bit is set/reset (used as a flag)
;Destroyed:
; Decrement the sector counter. Set carry flag if done
; Increment the DMA address and sector number
INRdata:

dcrSEC:	lda	SECcnt	; number of SECs left to write
	dcr	A	; decrement,
	sta	SECcnt	; and save.
	cpi	0	; Are we done reading sectors?
	jrnz	..2	; NO. Increment the data
	stc		; YES. Set the carry bit
	ret		; and return.

..2:	lhld	DMAaddr	; get current DMA address
	lxi	D,128
	dad	D	; increment it by 128 bytes
	shld	DMAaddr	; and save as new DMA address

	lda	curSEC	; get the current sector
	inr	A	; increment,
	sta	curSEC	; and save as current sector
	cpi	mxdskSEC; Are we past last sector?
	jrz	..3	   ; no, return
	jrc	..3	   ; no, return

	lda	curTRK	; get track number
	cpi	mxdskTRK+1  ; past last track?
	jnc	prterr	; Yes. Terminal error. Abort.
	inr	A	; get to next track number
	sta	curTRK	; and save it.
	mvi	A,1	; Reset sector number to 1
	sta	curSEC	; and save it.
..3:	ora	A	; reset carry flag
	ret		; and return.

;----------
; Call bios directly using WBaddr in low memory
WBaddr	= WBOOT + 1

CONOUT:
	lhld	WBaddr
	lxi	D,09h
	dad	D
	pchl

HOME:
	lhld	WBaddr
	lxi	D,15h
	dad	D
	pchl
	
SELDSK:
	lhld	WBaddr
	lxi	D,18h
	dad	D
	pchl

SETTRK:
	lhld	WBaddr
	lxi	D,1Bh
	dad	D
	pchl

SETSEC:
	lhld	WBaddr
	lxi	D,1Eh
	dad	D
	pchl

SETDMA:
	lhld	WBaddr
	lxi	D,21h
	dad	D
	pchl

READ:
	lhld	WBaddr
	lxi	D,24h
	dad	D
	pchl

WRITE:
	lhld	WBaddr
	lxi	D,27h
	dad	D
	pchl

CPMMAP:
	lhld	WBaddr
	lxi	D,60h
	dad	D
	pchl

SETBYT:
	lhld	WBaddr
	lxi	D,66h
	dad	D
	pchl
	
	.blkb	60
stack:

.end

