;******************************************************
;******************************************************
; Revision History
;******************************************************

FALSE	equ	0
TRUE	equ	not FALSE

CPUSPD	equ	20000		;CPU speed in MHz X 10,000

;----------------------------------------------------------
; Altair 8800 Disk Controller Equates (These are the same
; for the 88-DCDD controller and the 88-MDS controller.)
;----------------------------------------------------------
DENABL	equ	08H		;Drive Enable output
DDISBL	  equ	  80h		  ;disable disk controller

DSTAT	equ	08H		;Status input (active low)
ENWDAT	  equ	  01H		  ;-Enter Write Data
MVHEAD	  equ	  02H		  ;-Move Head OK
HDSTAT	  equ	  04H		  ;-Head Status
DRVRDY	  equ	  08H		  ;-Drive Ready
INTSTA	  equ	  20H		  ;-Interrupts Enabled
TRACK0	  equ	  40H		  ;-Track 0 detected
NRDA	  equ	  80H		  ;-New Read Data Available

DCTRL	equ	09H		  ;Drive Control output
STEPIN	  equ	  01H		  ;Step-In
STPOUT	  equ	  02H		  ;Step-Out
HDLOAD	  equ	  04H		  ;8" disk: load head
				  ;Minidisk: restart 6.4 S timer
HDUNLD	  equ	  08h		  ;unload head (8" only)
IENABL	  equ	  10H		  ;Enable sector interrupt
IDSABL	  equ	  20H		  ;Disable interrupts
WENABL	  equ	  80H		  ;Enable drive write circuits

DSECTR	equ	09H		;Sector Position input
SVALID	  equ	  01h		  ;Sector Valid (1st 30 uS
				  ;..of sector pulse)
SECMSK	  equ	  3Eh		  ;Sector mask for MDSEC

DDATA	equ	0AH		;Disk Data (input/output)

;-----------------
; Disk Parameters
;-----------------
BPS	equ	128		;data bytes/sector
MDSPT	equ	16		;Minidisk sectors/track
				;this code assumes SPT for 8"
				;disks = MDSPT * 2.
;**************
; ASCII equates
;**************
ASCII	equ	30h		;ASCII number bias
CTRLC	equ	03h		;^C
CR	equ	0Dh		;carriage return
LF	equ	0Ah		;line feed
ESC	equ	1Bh		;"ESCAPE" KEY
QUOTE	equ	27h		;Single quote
BS	equ	5Fh		;Backspace???? for Sol-20???
DEL	equ	7Fh		;delete

;******=============================
;* MS *   Measure and report spindle
;******   revolution time in mSec
;===================================
NSMSPD:

;--------------------------------------------------------
; Determine if this is an 8" disk or a minidisk, and set
; c to the correct sectors/track for the detected disk.
; An 8" disk has 20h sectors, numbered 0-1Fh. A minidisk
; has 10h sectors, numbered 0-0Fh.
;--------------------------------------------------------

; wait for the highest minidisk sector, sector number 0Fh

CKDSK1:	in	DSECTR		;Read the sector position

	ani	SECMSK+SVALID	;Mask sector bits, and hunt
	cpi	(MDSPT-1)*2	;..for minidisk last sector
	jnz	CKDSK1		;..only while SVALID is 0

; wait for this sector to pass

CKDSK2:	in	DSECTR		;Read the sector position
	rrc			;wait for invalid sector
	jnc	CKDSK2

; wait for and get the next sector number

CKDSK3:	in	DSECTR		;Read the sector position
	rrc			;put SVALID in carry
	jc	CKDSK3		;wait for sector to be valid

; The next sector after sector 0Fh will be 0 for a minidisk,
; and 10h for an 8" disk. Adding MDSPT (10h) to that value
; will compute c=10h (for minidisks) or c=20h (for 8" disks).

	ani	SECMSK/2	;Mask sector bits
	adi	MDSPT		;compute a = SPT



	mov	c,a		;..and save in c<<<<<<<<<<<<<<<c=SPT<<<<<<<





;******=============================================
;* MS *   Measure and report spindle revolution time
;******   assuming a 2.0000 MHz CPU (set in CPUSPD)
;===================================================
NSMSPD:	call	NSELCT		;load the head

MSLOOP:	call	PCRLF		;print CR,LF, trash bc


	lxi	h,0		;(10)timer
	mvi	b,4*16???	;(7)number of sector-times
				;test for 4 revolutions
>>>>>>>>>>>>these need to take 32 uS per pass>>>>>>>>>>>>>>>>>>>
;wait for initial sector

NSTLP0:	inr	a		;(5)stall
	in	DSECTR		;(10)
	ani	SVALID		;(7) sector pulse?
	jnz	NSTLP0		;(10)

;Measure time for b sectors, using hl

NSTLP1:	inx	h		;(5)bump timer

	in	DSECTR		;(10)
	ani	SVALID		;(7)sector pulse?
	jnz	NSTLP2		;(10)

;inner loop: 32 cycles per spin

	ldax	d		;(7)stall
	inx	h		;(5)make up for time outside loop

	dcr	b		;(5)next sector
	jnz	NSTLP1		;(10)

;exactly 40 cycles  (20 uS) outside the inner loop

;hl = time in units of 20 uS. Carry is clear here.

	call	DIVIDE		;print in mS

	call	ILPRNT
	db	' mS/re','v'+80h

;Keep measuring until the user types Mode Select

	call	TSTMOD
	jmp	MSLOOP	
	
;***Subroutine***********************************
; Print hl in decimal mS on the console
; On Entry:
;  hl = value in uS times CPUSPD
; Trashes all registers
;************************************************
DIVIDE:	mvi	d,5		;5 digits
	mvi	c,0		;MSB of (c,hl)

DDLOOP:	mov	a,d		;time for decimal?
	cpi	2		;2 digits after decimal
	mvi	b,'.'
	cz	SOUT		;y:print b='.'

	push	d
	lxi	d,-CPUSPD	;divisor=CPU speed
	call	DECDIG
	pop	d

	dcr	d	
	jnz	DDLOOP

	ret

;---Local Subroutine--------------------------------
; Divide hl by bc and print whole number quotent
; On Entry:
;   (c,hl)=dividend
;   de=negative of divisor
; On Exit:
;   Quotent is printed always
;   (c,hl)=remainder X 10
; trashes psw,b,de
;---------------------------------------------------
DECDIG:	mov	a,c		;a=dividend high byte
	lxi	b,('0'-1)*256+0FFh ;init b=ASCII quotient
				;..(will go 1 too many times)
				;create c=MSB of divisor

;divide a,hl by (b,de). The result will be an ASCII number
;in c, The remainder will be 16 bits on the stack

	push	h		;set up stack

DIGLP:	inx	sp		;chuck stack value
	inx	sp		;pop to garbage
	push	h		;remember prior result

	inr	b		;bump quotent
	dad	d		;add a negative number
	adc	c		;catch carry bit
	jc	DIGLP

	pop	h		;hl=remainder

;c = quotent in ASCII, hl = remainder in binary
;Compute (c,hl) := hl X 10 (could be up to 19 bits)

	mov	d,h		;temp save X1
	mov	e,l

	xra	a
	mov	c,a

	dad	h		;X2
	adc	a		;b=0: catch carry

	dad	h		;x4
	adc	a		;MSB
		
	dad	d		;x5
	adc	c		;b=0: catch carry

	dad	h		;X10
	adc	a		;MSB

	mov	c,a		;(c,hl) = remainder X 10

	jmp	SOUT		;print b


