;	disassembly of BOOT.SYS for Imsai IMDOS V2.05
;	address labels with Hnnnn are based on a system with 16k of memory.
;	named labels are the actual labels from the relocatable object file 

;	last edit: 11/30/14

;	ORG	0000h		for reference only

	PUBLIC	H0069,IOBYTE,WBOOTE,CKDIO,BOODSK,PRESRV,CCPDSK	;H0069 is hidden location

	EXTRN		ENSYS,VIOF

;DIO ROM vectors (unlabeled)

;HE003	EQU	0E003h
;HE006	EQU	0E006h
;HE00C	EQU	0E00Ch
;HE7FD	EQU	0E7FDh
;HE7FF	EQU	0E7FFh

;VIO ROM vectors (unlabeled)

;HF800	EQU	0F800h
;HF803	EQU	0F803h
;HFFFD	EQU	0FFFDh

	CSEG

	DB	01h		;LXI B,0FFFFh. this =0 if data disk
PRESRV:	DW	0FFFFh		;these are bits to validate VCB is present
IOBYTE:
WBOOTE:	MOV 	H,C
CCPDSK:
	MOV 	L,B
	SHLD	IOBYTE
	LXI 	SP,H0073

;check for DIO floppy controller. return nz if not found

CKDIO:	LXI 	H,0E7FDh	;address to test
	MVI 	A,44h		;bit pattern to test if DIO is present

;	RST 2 calls here (call 10h)

	MOV 	B,M
	CMA 	
	MOV 	M,A
	XRA 	M
	MOV 	M,B
	MOV 	B,A
	INR 	B

;exit here with B=1 if RAM or B=0 if ROM containing 'D' at E7FD, probably a 'DIO' floppy controller card

	RET			;first time returns to H007A on stack

;	RST 3 calls here (call 18h)
 	
	INR 	B		;B = 0 if DIO present
	DCR 	B
	JZ 	H0048		;taken if DIO
	OUT 	0FDh		;else must be the FIF controller
	RET

;read sector. must enter with B=0 if DIO controller present
;return A=FF and carry clear if no error, else A=0 and carry set for error
 	
H0020:	MVI 	A,10h		;set string ptr
	RST 	03		;call 18h
	MVI 	A,40h		;FIF string low address (= LOW H0040 which genesys doesn't recognize)
	RST 	03
	XRA 	A		;FIF string hi address
H0027:	RST 	03
H0028:	LXI 	H,H0041
	XRA 	A		;clear status
	MOV 	M,A
	RST 	03		;execute command
H002E:	XRA 	A
	SUB 	M
	JZ 	H002E		;wait for status change
	DCR 	M
	RZ			;return with carry clear and A=FF if ok, else A=5F and carry set for bad sector
	DCR 	A		;display error code (0 - status - 1 -> cma status)
	OUT 	0FFh		;now A=5E if bad sector
	SUI 	5Eh		;now =0
	RZ			;return carry set and A=0 for bad sector	
	MVI 	A,21h		;else restore drive and retry
	JMP 	H0027
H0040:	DB 21h			;read sector unit 0 command
H0041:	DB 00h			;status
H0042:	DW 0000h		;track (H0043 = track counter)	
H0044:	DB 02h			;sector
H0045:	DW H0080		;buffer address

; Volume Control Block
 	
BOODSK:	DB 04h			;flag in VCB set =0 when this disk gets booted
H0048:	JMP 	0E006h		;this is in VCB
	DB 68h			;VCB checksum, verified on boot
	DB 'DIANE  '		;Diane Hijcek, Imsai programmer
	DB 01h,01h,4Dh,00h	;VCB data
H0057:	DB 1Ah			;alternate sectors/track
	DB 00h
	DB 06h			;space between sectors - vcb data (skew)
	DB 0Dh
	DB 34h			;# of 80h blocks for system image
	DB 00h
H005D:	DB 00h,00h,00h
H0060:	DB 00h
H0061:	DB 1Ah			;sectors/track. if 0 then H0057 used instead
H0062:	DB 05h			;skew
	DB 00h,00h,00h,00h,00h,00h

;H0069 is a hidden location used by genesys to store the bdos serial# which
;is then used for synchronization and checksum verification tests.

H0069:	DW 0000h

	DB 00h			;directory offset
	DB 00h
	DB 40h			;# of directory entries
	DB 00h,07h,03h,0F3h	;VCB data
	DB 00h

; end of VCB

H0073:	DW H007A		;return address placed on stack
H0075:	MOV	B,L
	XRA 	A		;set z so sector is read
	STA 	BOODSK
H007A:	CZ 	H0020		;read sector (not called 1st time through, if FIF)
	JNC	H0075		;NC if read error, loop until read 

;next sector loads here

H0080:	LXI 	D,0000h		;0000 changed to load address set up by genesys 80h below top of memory
	LHLD	PRESRV
H0086:	MOV 	A,M		;move 80h block from (HL) to (DE) 
	STAX	D
	INX 	H
	INR 	E
	JNZ	H0086
	LDA 	H0061		;spt
	ORA 	A		;if nz then keep using it
	CALL	H00F4
H0094:	MOV 	C,A
H0095:	INR 	A
	STA 	H0044		;sector
H0099:	LXI 	H,0FF00h	;this gets self modified for buffer calculation
H009C:	DAD 	D
	DCR 	C
	JNZ	H009C		
	SHLD	H0045		;buffer address
	DCR 	A
	PUSH	PSW
	PUSH	H
	CZ 	H00D9
	POP 	H
	DAD 	H
	MOV 	A,H
	SUI 	03h		;self modified by genesys based on memory size

;the following comparison is set by genesys to # of sectors to read for system load = 48 for SD or 52 for DD
	CPI 	00h		;self modified by genesys
		
	CC 	H0028		;read next sector if not done loading
	MOV 	C,A		;=FF if read ok
	POP 	PSW
H00B6:	ADI 	05h		;add skew (self modified)
H00B8:	LXI 	H,H0061		;spt could get self modified to H0057 
	CMP 	M
	JM 	H0094
	SUB 	M
	JNZ	H0094
	MOV 	A,C
	MOV 	C,M
	MVI 	L,43h		;LOW H0043 not recognized by genesys
	INR 	M
	INR 	A
	JZ 	H0095
	MVI 	A,56h		;check if ROM contains 'V' at FFFDh for VIO
	LXI 	H,0FFFDh
	RST 	02
	MOV 	A,B
	STA	VIOF		;VIO FLAG = 0 if VIO is present
	JMP	ENSYS		;jmp to cold entry point
H00D9:	SHLD	H0099+1
	LHLD	H005D
	ORA 	H
	RZ 	
	XCHG	
	LDA 	H0060
	STA 	H0042		;track
	LDA 	H0062
	STA 	H00B6+1
H00EE:	LXI 	H,H00B8+1	
	MVI 	M,57h		;LOW H0057 not recognized by genesys
	RET 	
H00F4:	LXI 	D,0080h
	MVI 	A,05h		;skew
	CZ 	H00EE
	RET
	DB 00h,00h,02H 	

	END
