		.286c
		page	60,132
		name	new_interface
		title	Slicer Concurrnet BIOS Version 1.0A  New Interface
		subttl	Data areas
.xlist
		page	+
		include biosdata.asm
		subttl	Macros
		page	+
.list
;----------------------------------------------------------------
;   Macros
;----------------------------------------------------------------
dp		macro	a
		dw	offset a
		dw	seg a
		endm

set		macro	num,val
		mov	w num,offset val
		mov	w num+2,seg val
		endm

boot_struc	struc
		db	3 dup (?)
our_name	db	8 dup (?)
cylinders	dw	?
heads		db	?
rw_cylinder	dw	?
wp_cylinder	dw	?
error_burst	db	?
step_rate1	db	?
sectors		dd	?
drives		db	?
boot_struc	ends

		subttl	Function dispatcher
		page	+
;----------------------------------------------------------------
; Error codes
;----------------------------------------------------------------
bad_command	equ	1
write_protect	equ	3
record_not_fnd	equ	4
dev_out_of_rng	equ	8h
crc_error	equ	10h
hardware_error	equ	20h
bad_seek	equ	40h
not_ready_error	equ	080h

d		equ	dword ptr
w		equ	word ptr
b		equ	byte ptr
;----------------------------------------------------------------
;		disk_flags
;----------------------------------------------------------------
disk_in_service	equ	00000001b
fop_waiting	equ	00000010b	;floppy done
f_nest		equ	00000100b
write_status	equ	00001000b
interuptable	equ	00010000b
sop_waiting	equ	00100000b	;sasi done
sasi_nest	equ	01000000b

disk_read_cmd	equ	10011000b
disk_write_cmd	equ	10111000b
ram_command	equ	11000000b
;
hd_control	equ	01000000b	;enable retrys immediate error correction
hd_read_cmd	equ	8
hd_write_cmd	equ	0ah

;		disk type
uninitialized	equ	10000000b
mini		equ	00010000b
double_density	equ	00100000b
double_track	equ	01000000b
sector_size_m	equ	00001100b
step_rate_m	equ	00000011b
concurrent_int	equ	0f9h

;----------------------------------------------------------------
;              com_flags
;----------------------------------------------------------------
com1_waiting	equ	00000001b
com2_waiting	equ	00000010b
com3_waiting	equ	00000100b
com4_waiting	equ	00001000b
com5_waiting	equ	00010000b
com6_waiting	equ	00100000b

		public	new_call_init,new_hdisk
		public	bootstrap,bootstrap1,bootstrap2
		extrn	old_load:near
		extrn	port1_write:near,port2_write:near
		extrn	port1_status:near,port2_status:near
		extrn	port3_write:near,port4_write:near
		extrn	port3_status:near,port4_status:near
		extrn	set_up_port1:near,set_up_port2:near
		extrn	set_up_port3:near,set_up_port4:near
 		extrn	ibm_serial:far
		extrn	disk_read:near,disk_write:near
		extrn	disk_read1:near,disk_write1:near
		extrn	sasi_io:near,sasi_io1:near
		extrn	disk_reset:near
		extrn	drive_mask:byte
		extrn	new_video:far,new_keyboard:far
		extrn	new_parallel:far,ibm_parallel:far
		extrn	moninit:near

boot_seg	segment	at 01200h
		org	0
boot_location	label	far
boot_seg	ends
rom_seg		segment	at 0c800h
		org	0
rom_id		label	word
page_sel	dw	?
rom_entry	label	far
rom_seg		ends

cgroup		group	code
code		segment byte public 'code'
		assume	cs:cgroup
;----------------------------------------------------------------
; Function dispatcher
;    Dispatches calls to all new BIOS functions
; input:
;   ah = channel #
;   al = function #
;   cx = transfer count
;   dx:bx = starting block for disk and disk like devices
;   es:si = buffer for all functions
;
; returns:
;   al = status
;        0 = no error
;        1 = bad command
;        3 = write protect
;        4 = record not found
;        8 = device out of range(bad pointer in jump table)
;        10= crc error
;        20= hardware error
;        40= bad seek
;        80= not ready or time out
;
;   cx = blocks successfully transfered
;   bl = status on return  On printer output ONLY
;   ah,bx,dx destroyed unless data explicitly returned in register
;   di,si,sp,bp,ds,es,ss unchanged
;----------------------------------------------------------------
internal_table	label	dword
		dp	new_disk		;channel 0
		dp	new_hdisk		;   "    1
		dp	new_port0_out		;   "    2
		dp	new_port0_in		;   "    3
		dp	new_port1_out		;   "    4
		dp	new_port1_in		;   "    5
		dp	new_video		;   "    6
		dp	new_keyboard		;   "    7
		dp	new_port2_out		;   "    8
		dp	new_port2_in		;   "    9
		dp	new_port3_out		;   "    a
		dp	new_port3_in		;   "    b
;		dp	new_port4_out
;		dp	new_port4_in
;		dp	new_port5_out
;		dp	new_port5_in
		dp	new_parallel		;   "    c
;		dp	new_time
		dp	equipment		;   "    d
		dp	ibm_parallel		;   "    e
		dp	ibm_serial		;   "	 f
;		dp	ibm_serial_in		;   "   10
internal_limit	equ	(this byte - internal_table)/4
dpb_ptr		dw	dpb0
		dw	dpb1
		dw	dpb2
		dw	dpb3

new_call_init	proc	near
		assume	ds:data,es:vectors
		set	vector_f8,dispatch
		mov	al,(uninitialized or step_rate_m)
		mov	d_type_0,al			;15ms step rate to boot with
		mov	d_type_1,al
		mov	d_type_2,al
		mov	d_type_3,al
		xor	al,al
		mov	port1_head,al
		mov	port1_tail,al
		mov	port2_head,al
		mov	port2_tail,al
		mov	port3_head,al
		mov	port3_tail,al
		mov	port4_head,al
		mov	port4_tail,al
		mov	com_hold_enable,0ffh		;enable hold on all channels
		mov	com_hold,0			;clear holds on all channels
		mov	external_limit,0
		mov	device_numbers,0		;floppy 1
		mov	device_numbers+(2*1),0		;floppy 2
		mov	device_numbers+(2*2),0		;floppy 3
		mov	device_numbers+(2*3),0		;floppy	4
		mov	device_numbers+(2*4),101h	;hard 1
		mov	device_numbers+(2*5),101h	;hard 2
		mov	device_numbers+(2*6),203h	;console
		mov	device_numbers+(2*7),405h	;printer
		mov	device_numbers+(2*8),203h	;aux
		mov	device_numbers+(2*9),0d0dh	;equipment
		mov	device_numbers+(2*0ah),203h	;port 1
		mov	device_numbers+(2*0bh),405h	;port 2
		mov	device_numbers+(2*0ch),809h	;port 3
		mov	device_numbers+(2*0dh),0a0bh	;port 4

		mov	device_numbers+(2*11h),0c0ch	;parallel printer
;----------------------------------------------------------------
;   get parameters from hard_disk
;----------------------------------------------------------------
		mov	ax,484h			;reset sasi
		int	0f8h
		mov	hdpb0.step_rate,0ffh
		mov	hdpb1.step_rate,0ffh
		mov	cx,5000
test_rdy_loop:	push	cx
		mov	ax,480h			;sasi write
		mov	bp,cgroup
		mov	si,offset test_0_ready
		mov	cx,0
		int	0f8h
		pop	cx
		cmp	al,not_ready_error
		jne	nns
		jmp	no_sasi
nns:
		or	al,al
		jz	hd0_ready
		loop	test_rdy_loop
		mov	cx,1
		jmp	no_sasi			;not ready
hd0_ready:
		mov	bp,cgroup
		mov	si,offset recal_0
		mov	cx,0
		mov	ax,480h
		int	0f8h
		or	al,al	 
		je	nns3
		jmp	no_sasi			;not ready
nns3:		mov	hd_last_drive,0		;don't send invalid parameters
		mov	cx,1
		mov	bx,0
		mov	dx,0
		mov	si,0
		mov	ax,1000h
		mov	es,ax
		mov	ax,400h			;load first sector from drive 0
		int	0f8h			;to get disk parameters
		or	al,al
		jz	nns4
		jmp	no_sasi
nns4:		mov	di,1000h
		mov	ax,es:[si].cylinders
		xchg	ah,al
		stos	b [di]
		xchg	ah,al
		stos	b [di]
		mov	al,es:[si].heads
		stos	b [di]
		mov	ax,es:[si].rw_cylinder
		xchg	ah,al
		stos	b [di]
		xchg	ah,al
		stos	b [di]
		mov	ax,es:[si].wp_cylinder
		xchg	ah,al
		stos	b [di]
		xchg	ah,al
		stos	b [di]
		mov	al,es:[si].error_burst
		stos	b [di]
		mov	bl,es:[si].step_rate1
		mov	di,si
		mov	si,1000h
		mov	ax,482h
		int	0f8h			;set parameters
		cmp	es:[di].drives,2
		je	nns6
		jmp	no_sasi			;only one disk
nns6:
		mov	cx,5000
test_rdy_loop1:	push	cx
		mov	ax,480h			;sasi write
		mov	bp,cgroup
		mov	si,offset test_1_ready
		mov	cx,0
		int	0f8h
		pop	cx
		cmp	al,not_ready_error
		jne	nns1
		jmp	no_sasi
nns1:
		or	al,al
		jz	hd1_ready
		loop	test_rdy_loop1
		mov	cx,1
		jmp	no_sasi			;not ready
hd1_ready:
		mov	bp,cgroup
		mov	si,offset recal_1
		mov	cx,0
		mov	ax,480h
		int	0f8h
		or	al,al	 
		jne	no_sasi			;not ready
		mov	hd_last_drive,1		;don't send invalid parameters
		mov	cx,1
		mov	bx,0
		mov	dx,0
		mov	si,0
		mov	ax,1000h
		mov	es,ax
		mov	ax,500h			;load first sector from drive 1
		int	0f8h			;to get disk parameters
		or	al,al
		jnz	no_sasi
		mov	di,1000h
		mov	ax,es:[si].cylinders
		xchg	ah,al
		stos	b [di]
		xchg	ah,al
		stos	b [di]
		mov	al,es:[si].heads
		stos	b [di]
		mov	ax,es:[si].rw_cylinder
		xchg	ah,al
		stos	b [di]
		xchg	ah,al
		stos	b [di]
		mov	ax,es:[si].wp_cylinder
		xchg	ah,al
		stos	b [di]
		xchg	ah,al
		stos	b [di]
		mov	al,es:[si].error_burst
		stos	b [di]
		mov	bl,es:[si].step_rate1
		mov	si,1000h
		mov	ax,582h
		int	0f8h			;set parameters
;
no_sasi:
get_param_done:
		ret
		assume	es:nothing,ds:data
new_call_init	endp
bootstrap	proc	near
		call	old_load
		xor	ax,ax
		call	bootstrap1	;boot drive 0	
		mov	disk_time_out,100 ;change time out longer
		call	bootstrap2	;boot hard drive
		call	romboot
		jmp	moninit
bootstrap	endp
romboot		proc	near
		push	ds
		mov	ax,rom_seg
		mov	ds,ax
		assume	ds:rom_seg
		mov	page_sel,0	;select page 0 of rom
		cmp	rom_id,0aa55h	;is it valid
		jne	no_rom
		jmp	rom_entry
no_rom:		pop	ds
		assume	ds:data
		ret
romboot		endp
bootstrap1	proc	near
		xor	ah,ah
		mov	bp,ax		;drive to boot from
		mov	ah,al
		mov	al,84h
		int	0f8h		;getparameters from drive
		or	al,al
		je	boot2
		jmp	boot_error
boot2:		mov	bl,1
		mov	cl,1
		mov	ax,bp
		mov	ah,al
		mov	al,82h
		int	0f8h		;set parameters
boot3:
		mov	cx,1
		xor	dx,dx
		xor	bx,bx
		mov	si,boot_seg
		mov	es,si
		mov	si,offset boot_location
		mov	ax,bp
		mov	ah,al
		mov	al,0
		int	0f8h		;read first sector
		or	al,al
		jnz	boot_error
		mov	disk_time_out,100	 ;change time out longer
		jmp	boot_location
boot_error:	ret
bootstrap1	endp
bootstrap2	proc	near
		mov	cx,4
boot13:		push	cx
		mov	cx,1
		xor	dx,dx
		xor	bx,bx
		mov	si,boot_seg
		mov	es,si
		mov	si,offset boot_location
		mov	ax,400h
		int	0f8h		;read first sector
		or	al,al
		jz	boot14
		pop	cx
		loop	boot13

		mov	si,cs
		mov	es,si
		mov	si,offset boot_mess
		mov	cx,boot_mess_len
		mov	ax,601h
		int	0f8h		;write mess
		ret
boot14:		mov	bp,4
		jmp	boot_location
boot_mess	db	'Boot Failure.',0dh,0ah
boot_mess_len	equ	(this byte - boot_mess)
bootstrap2	endp
dispatch	proc	far
		sti
		cld
		push	ds
		push	es
		push	bp
		push	si
		push	di
		push	bx
		mov	bx,data
		mov	ds,bx
		assume	ds:data
		cmp	ah,0feh
		jae	c_maintain		;update dispatch jump tables
		mov	di,ax
		shr	di,7
		and	di,not 1b		;channel #*2 in di
		mov	bx,device_numbers[di]	;bx has channel descriptor
		test	al,1
		je	d1
		xchg	bh,bl
d1:		xor	bh,bh			;bl has device #
		cmp	bl,080h
		jae	external_call
		cmp	bl,internal_limit
		jae	dev_out_of_range
		shl	bx,2
		mov	di,bx			;di is offset into jump table
		pop	bx
		call	internal_table[di]	;call internal function
		jmp	dispatch_done
external_call:	sub	bl,080h
		cmp	bl,external_limit
		jae	dev_out_of_range
		shl	bx,2
		lds	di,external_table
		add	di,bx
		pop	bx
		call	d ds:[di]		;call external function
		jmp	dispatch_done
;----------------------------------------------------------------
;  To reassign device numbers to a channel a call should be made
;  to channel FF.
;
;    Entry:
;         al: channel number
;         bl: new input device
;         bh: new output device
;    Exit
;         bl: old input device
;         bh: old output device
;
;
;----------------------------------------------------------------
c_maintain:	cmp	ah,0feh
		je	c_maintain1
		pop	bx			;al has channel number
		xchg	ax,bx			;bh bl have new device numbers
		xor	bh,bh			;for input and output
		shl	bx,1			;returns bx old device numbers
		xchg	device_numbers[bx],ax
		mov	bx,ax
		jmp	short dispatch_done
;----------------------------------------------------------------
;  To install external devices A call should be made to
;  channel FE.
;
;  Entry:
;    es:si  A buffer big enough to hold 4-byte pointers to all 
;           external functions.
;    dx:bx  A pointer to the Entry point of the function.
;  Exit:
;     bl:   device number assigned to the device.
;----------------------------------------------------------------
c_maintain1:	pop	bx
		push	ds
		mov	bp,si
		mov	cl,external_limit
		xor	ch,ch
		cld
		lds	di,external_table
		mov	ax,ds
		or	ax,di
		xchg	si,di
		jz	c_m1_new
		shl	cx,1
	rep	movs	w [di],w [si]	;copy old table to new table
c_m1_new:	pop	ds
		mov	ax,bx
		stos	w [di]
		mov	ax,dx
		stos	w [di]		;put new pointer in table
		mov	w external_table,bp
		mov	w external_table+2,es
		mov	bl,external_limit
		inc	external_limit
		add	bl,080h
		jmp	short dispatch_done

dev_out_of_range:
		mov	al,dev_out_of_rng
d_end:		pop	bx
dispatch_done:	pop	di
		pop	si
		pop	bp
		pop	es
		pop	ds
		iret
dispatch	endp
		subttl New Disk function calls
		page +
;----------------------------------------------------------------
;  New Disk function calls
;
;  input:
;     al = function #
;        0 = read logical sectors from disk
;        1 = write logical sectors to disk
;           cx = block count
;           bx = starting block
;           es:si = buffer
;
;        80= general purpose read
;        81= general purpose write
;           bl = head number
;           cl = number of blocks to transfer
;           ch = sector number
;           dl = track number
;           dh = command for 1797 fdc
;
;        82= set disk parameters marked with *
;        83= set all disk parameters
;        84= get disk parameters from disk (analyse format)
;        85= get current disk parameters
;            bl = number of heads  *
;            cl = sectors per track *
;            dl = disk type byte
;               uninitialized  10000000b
;               mini           00010000b
;               double_density 00100000b  *
;               double_track   01000000b  *
;               sector_size    00001100b  *
;               step_rate      00000011b
;
;        86= set time out values
;            bx = select count
;            cx = motor count
;            dx = contorller count
;
;        87= reset disk system
;            stops current operation and forces a restore before
;            next operation
;
;	79h= set or reset head settle bit and spinup time for
;	    motor on routine for floppy disk drives
;	     bx = 0 turn off head settle bit else turn on
;	     cx = length of spin up loop set long on boot	 
;
;   output
;     al = status
;----------------------------------------------------------------
new_disk	proc	far
		mov	drive_number,ah
		cmp	al,1
		jbe	ndrw
		cmp	al,080h
		jb	nd3
		jmp	nddp
nd3:	   
		cmp	al,79h
		jnz	badcont
		jmp	disk_speed		;change head settle and spinup time
badcont:	mov	al,bad_command		;bad command
		ret
ndrw:		mov	function_ptr,offset disk_read1
		mov	function_cmd,disk_read_cmd

		or	al,al			;setup pointer to function
		jz	nd1
		mov	function_ptr,offset disk_write1
		mov	function_cmd,disk_write_cmd

nd1:		mov	al,settle		;JONATHAN ADDED THIS 3/26
		and	al,4			;and out garbage
		or	function_cmd,al				       

		mov	nd_error_flag,0
		mov	al,ah
		mov	di,ax
		and	di,3h
		shl	di,1
		mov	di,dpb_ptr[di]		;di points to dpb for drive
		mov	ax,bx			;ax starting sector
		div	[di].sectors_per_trk
		inc	ah
		mov	sector_number,ah
		xor	ah,ah
		div	[di].number_of_heads
		mov	disk_track,al
		mov	head_number,ah
		mov	bp,cx			;store count in bp instead of cx
		mov	nd_sector_count,cx	;save count so it can be returned to caller
nd_xfer_loop:	mov	bx,si			;buffer address to bx
		mov	al,[di].sectors_per_trk
		sub	al,sector_number
		inc	al			;ax has number of sectors that can be transfered
		xor	ah,ah
		cmp	ax,bp
		jae	last_xfer
		mov	num_of_sectors,al
		mov	f_return,offset nd_cont
		or	disk_flags,f_nest
		mov	temp_ax,ax			;save ax
		mov	al,function_cmd
		jmp	[function_ptr]
nd_cont:	mov	ax,temp_ax			;restore ax
		cmp	al,num_of_sectors
		jne	nd_error		;
		cmp	diskette_status,0
		jne	nd_error
		sub	bp,ax				;adjust sector count
		mul	sector_size			;sector size is set by preceding disk op
		add	si,ax				;adjust buffer pointer
		jnc	nd2
		mov	ax,es
		add	ax,1000h			;if carry set inc es
		mov	es,ax
nd2:		inc	head_number
		mov	al,head_number
		cmp	al,[di].number_of_heads
		jl	no_track_increment
		inc	disk_track
		mov	head_number,0
no_track_increment:
		mov	sector_number,1
		jmp	nd_xfer_loop		
		
last_xfer:	
		and	disk_flags,not f_nest
		mov	ax,bp
		mov	num_of_sectors,al
		mov	f_return,offset nd_cont1
		mov	al,function_cmd
		jmp	[function_ptr]
nd_cont1:	cmp	nd_error_flag,0		;if error has occoured handle differently
		jne	nd9
		mov	al,num_of_sectors
		xor	ah,ah
		sub	bp,ax
		mov	cx,nd_sector_count
		sub	cx,bp
		mov	al,diskette_status
		ret

nd9:		mov	cx,nd_sector_count
		sub	cx,bp			;bp has block count from before error
		mov	al,nd_error_flag	;status from error
		ret
nd_error:
		mov	al,num_of_sectors
		xor	ah,ah
		sub	bp,ax			;adjust block count
		mov	al,diskette_status
		mov	nd_error_flag,al	;save status and flag error
		mov	function_cmd,ram_command
		mov	function_ptr,offset disk_read1
	 	mov	bx,0fffeh
		mov	es,bx			;set transfer address to point to rom so
						;we won't destroy anything important
		jmp	last_xfer		;read address mark is just a dummy command
						;to get us out of the interupt driven structure
						;of this part of the code

nddp:		sub	al,080h
		jnz	nd11
		jmp	nd_gpr			;general purpose read
nd11:
		dec	al
		jnz	nd12
		jmp	nd_gpw			;general purpose write
nd12:
		dec	al
		jz	nd_sdp			;set disk parameters
		dec	al
		jz	nd_sdp1			;set all disk parameters
		dec	al
		jnz	nd10
		jmp	nd_gdp			;get disk parameters from disk
nd10:
		dec	al
		jz	nd_gcdp
		dec	al
		jz	nd_sto
		dec	al
		jz	nd_reset		;disk reset
		mov	al,bad_command
		ret
nd_sto:		mov	motor_count,cx
		mov	select_count,bx
		mov	disk_time_out,dx
		mov	al,0
		ret
nd_gcdp:
		mov	al,ah
		xor	ah,ah
		mov	di,ax
		mov	dl,d_type_0[di]		;get disk type
		shl	di,1
		mov	di,dpb_ptr[di]		;di points to dpb for drive
		mov	bl,[di].number_of_heads
		mov	cl,[di].sectors_per_trk
		mov	al,0
		ret
nd_sdp:		and	dl,not (mini or uninitialized or step_rate_m)
		mov	al,ah			;clear unwanted bits
		xor	ah,ah
		mov	di,ax
		and	d_type_0[di],mini or uninitialized or step_rate_m
						;clear bits to be set
		or	d_type_0[di],dl		;set disk type
		shl	di,1
		mov	di,dpb_ptr[di]		;di points to dpb for drive
		mov	[di].number_of_heads,bl
		mov	[di].sectors_per_trk,cl
		mov	al,0
		ret
nd_sdp1:
		mov	al,ah
		xor	ah,ah
		mov	di,ax
		mov	d_type_0[di],dl		;set disk type
		shl	di,1
		mov	di,dpb_ptr[di]		;di points to dpb for drive
		mov	[di].number_of_heads,bl
		mov	[di].sectors_per_trk,cl
		mov	al,0
		ret
nd_reset:	call	disk_reset
		mov	al,0
		ret
nd_gpr:		mov	disk_track,dl
		mov	head_number,bl
		mov	sector_number,ch
		mov	num_of_sectors,cl

		mov	al,settle
		and	al,4		;ADDED BY JONATHAN
		or	dh,al
		mov	al,dh
   
		mov	bx,si
		int	0fdh			;file bios.ams disk_read
		mov	cl,num_of_sectors
		mov	al,diskette_status
		ret
nd_gpw:		mov	disk_track,dl
		mov	head_number,bl
		mov	sector_number,ch
		mov	num_of_sectors,cl


		mov	al,settle
		and	al,4		      ;ADDED BY JONATHAN
		or	dh,al
		mov	al,dh

		mov	bx,si
		int	0fdh			;file bios.asm disk_write
		mov	cl,num_of_sectors
		mov	al,diskette_status
		ret
;
nd_gdp:		mov	drive_number,ah
		mov	bl,ah
		xor	bh,bh
		mov	di,bx
		mov	al,cgroup:drive_mask[di]
		or	recal_required,al	;force recal on drive
		mov	num_of_sectors,1
		mov	disk_track,2
		mov	head_number,1
		and	d_type_0[di],not double_track
		test	d_type_0[di],uninitialized
		jz	nd7			;set double density mini if uninitialized
		or	d_type_0[di],mini or double_density
nd7:		mov	ax,data
		mov	es,ax
		mov	al,ram_command
		mov	bx,offset am_buffer
 		int	0fdh
;		call	disk_read		;read address mark from track 2 head 1
						;of a dbl density 5 inch disk
		cmp	diskette_status,0
		jne	nd4
		jmp	found_it
nd4:
		mov	head_number,0		;try head 0
		mov	num_of_sectors,1
		mov	bx,offset am_buffer
		mov	al,ram_command
 		int	0fdh		
;		call	disk_read
		cmp	diskette_status,0
		jne	nd5
		jmp	found_it
nd5:
		mov	head_number,1
		mov	num_of_sectors,1
		xor	d_type_0[di],double_density
		mov	bx,offset am_buffer
		mov	al,ram_command		;try other density head 1
		int	0fdh
;		call	disk_read
		cmp	diskette_status,0
		jne	nd6
		jmp	found_it
nd6:
		mov	head_number,0		;try head 0
		mov	num_of_sectors,1
		mov	bx,offset am_buffer
		mov	al,ram_command
		int	0fdh
;		call	disk_read
		cmp	diskette_status,0
		je	found_it
		test	d_type_0[di],uninitialized
		jz	not_found

		mov	head_number,1
		mov	num_of_sectors,1
		xor	d_type_0[di],mini
		mov	bx,offset am_buffer
		mov	al,ram_command		;try other size head 1
 		int	0fdh
;		call	disk_read
		cmp	diskette_status,0
		je	found_it
		mov	head_number,0
		mov	num_of_sectors,1
		mov	bx,offset am_buffer
		mov	al,ram_command		;try head 0
		int	0fdh
;		call	disk_read
		cmp	diskette_status,0
		je	found_it
		mov	head_number,1
		mov	num_of_sectors,1
		xor	d_type_0[di],double_density
		mov	bx,offset am_buffer
		mov	al,ram_command		;try other density head 1
		int	0fdh
;		call	disk_read
		cmp	diskette_status,0
		je	found_it
		mov	head_number,0
		mov	num_of_sectors,1
		mov	bx,offset am_buffer
		mov	al,ram_command		;try head 0
		int	0fdh
;		call	disk_read
		cmp	diskette_status,0
		je	found_it
not_found:	mov	al,not_ready_error
		ret
found_it:	and	d_type_0[di],not uninitialized
		mov	al,am_size
		shl	al,2
		and	al,sector_size_m
		and	d_type_0[di],not sector_size_m
		or	d_type_0[di],al		;set sector size
		and	d_type_0[di],not double_track		
		cmp	am_track,2
		je	nd8
		or	d_type_0[di],double_track
nd8:		mov	dl,d_type_0[di]
		mov	bl,head_number
		inc	bl
		mov	al,0
		ret

;*****************************************************

disk_speed:	mov	spin_up,cx
		cmp	bx,0
		jz	setle_off
		or	settle,4 	       ;head settle on
		jmp	spdone
setle_off:	and	settle,0fbh		;head settle off
spdone:		and	settle,7fh		;high bit flag need to spin up 
		ret

new_disk	endp

		subttl	New Hard Disk function calls
		page	+
;----------------------------------------------------------------
;  New Hard Disk function calls
;
;     al = function #
;        0 = read logical sectors from disk
;        1 = write logical sectors to disk
;           cx = block count
;           dl:bx = starting block
;           es:si = buffer
;
;        80= general purpose sasi read
;        81= general purpose sasi write
;           es:bx = buffer
;           bp:si = control block
;           cx    = block count
;           dx    = block size
;
;        82 = set all disk parameters
;        83 = get disk parameters
;            es:si = 8 byte area to fill with:
;               msb number of sectors
;               lsb number of sectors
;               number of heads
;               msb starting reduced write cylinder
;               lsb starting reduced write cylinder
;               msb starting write precomp cylinder
;               lsb starting write precomp cylinder
;               maximum length of error burst to be corrected
;               bl = step rate byte
;
;        84= reset sasi system
;----------------------------------------------------------------
hdpb_ptr	dw	hdpb0
		dw	hdpb1
new_hdisk	proc	far
		sub	ah,4
		cmp	ah,1
		jbe	hd1
		mov	al,dev_out_of_rng
		xor	cx,cx
		ret
hd1:		cmp	al,1
		jbe	hd2
		cmp	al,80h
		jb	hd10
		jmp	nhd_ef
hd10:
		mov	al,bad_command
		xor	cx,cx
		ret
hd2:		mov	hd_ax_temp,ax
		cmp	hd_last_drive,ah
		je	hd_do_op
		mov	hd_last_drive,ah
		mov	hd_si_temp,si
		mov	hd_bx_temp,bx
		mov	hd_cx_temp,cx
		mov	hd_dx_temp,dx
		mov	hd_es_temp,es

;this was a poor fix on a problem running two hard disks and should
;be changed some day jonathan 12-10-86
;		push	ax
;		mov	al,0ffh
;		mov	dx,100h			;sasi select port
;		out	dx,al			;deselect drive
;
;		mov	al,0
;		mov	dx,102h			;sasi reset port
;		out	dx,al			;pulse reset pin
;		mov	al,0ffh			;on controller
;		out	dx,al
;
;		pop	ax
;*********************************************
		mov	di,ax
		shr	di,7
		and	di,10b
		mov	bx,data
		mov	es,bx
		mov	bx,hdpb_ptr[di]
		mov	ax,200h			;write 1 block of 8 bytes to controler
		mov	cx,1
		mov	dx,8
		mov	bp,cgroup
		mov	si,offset set_parameters
		or	disk_flags,sasi_nest
		mov	sasi_return,offset hd3
		jmp	sasi_io1
hd3:		or	al,al
		mov	si,hd_si_temp
		mov	dx,hd_dx_temp
		mov	cx,hd_cx_temp
		mov	bx,hd_bx_temp
		mov	ax,hd_ax_temp
		mov	es,hd_es_temp
		jz	hd_do_op
		jmp	hd_error
hd_do_op:
		mov	di,ax
		shr	di,7
		and	di,10b
		mov	di,hdpb_ptr[di]

		and	dl,00011111b
		shl	ah,5
		and	ah,0100000b
		or	ah,dl
		or	al,al
		jz	hd_read_13
		mov	hd_command,hd_write_cmd
		mov	al,2			;write disk
		jmp	short hd_do_op1

hd_read_13:
		mov	hd_command,hd_read_cmd
		mov	al,1			;read from disk
hd_do_op1:
		mov	hd_command+1,ah		;starting block
		mov	hd_command+2,bh
		mov	hd_command+3,bl
		mov	hd_command+4,cl		;block count
		mov	bl,[di].step_rate
		and	bl,0fh
		or	bl,hd_control
		mov	hd_command+5,bl
		mov	bp,data
		mov	bx,si
		mov	si,offset hd_command
		mov	dx,200h			;block size
		and	disk_flags,not sasi_nest
		mov	sasi_return,offset hd6
		mov	ah,al			;command to ah
		jmp	sasi_io1
hd6:		or	al,al
		jz	hd19
		jmp	hd_error
hd19:
		ret



hd_error:
op_error:	mov	bp,cgroup
		mov	ax,hd_ax_temp
		or	ah,ah
		jnz	hde1
		mov	si,offset req_status_0
		jmp	short hde2
hde1:		mov	si,offset req_status_1
hde2:		mov	ax,data
		mov	es,ax
		mov	bx,offset hd_command
		mov	cx,1
		mov	dx,4
		mov	ah,1
		and	disk_flags,not sasi_nest
		mov	sasi_return,offset hd7
		jmp	sasi_io1
hd7:		or	al,al
		jz	hd8
		jmp	hard_error
hd8:
		mov	al,hd_command			;has status byte from controler
				    
status_xlat	macro	a,b
		local	c
		cmp	al,a
		jne	c
		or	sasi_status,b
c:		nop
		endm

		status_xlat 1,not_ready_error
		status_xlat 2,bad_seek
		status_xlat 3,not_ready_error
		status_xlat 4,not_ready_error
		status_xlat 6,bad_seek
		status_xlat 11h,crc_error
		status_xlat 12h,record_not_fnd
		status_xlat 15h,bad_seek
		status_xlat 19h,not_ready_error
		status_xlat 1ah,not_ready_error
		status_xlat 20h,not_ready_error
		status_xlat 21h,not_ready_error
		status_xlat 30h,not_ready_error
		status_xlat 31h,not_ready_error
		status_xlat 32h,not_ready_error
		ret
hard_error:
		or	sasi_status,hardware_error
		ret
nhd_ef:
		sub	al,80h
		jz	sasi_read
		dec	al
		jz	sasi_write
		dec	al
		jz	set_hdp
		dec	al
		jz	get_hdp
		dec	al
		jz	sasi_reset
		mov	al,bad_command
		xor	cx,cx
		ret
sasi_read:	mov	ah,1
		call	sasi_io
		ret
sasi_write:	mov	ah,2
		call	sasi_io
		ret
set_hdp:	mov	di,ax
		mov	hd_last_drive,0ffh
		shr	di,7
		and	di,10b
		mov	di,hdpb_ptr[di]
		mov	[di].step_rate,bl
		mov	ax,es
		mov	bx,ds
		mov	es,bx
		mov	ds,ax
		mov	cx,4
		rep	movsw
		ret

get_hdp:	mov	di,ax
		shr	di,7
		and	di,10b
		mov	di,hdpb_ptr[di]
		mov	bl,[di].step_rate
		xchg	si,di
		mov	cx,4
		rep	movsw
		ret


sasi_reset:	mov	ah,0
		mov	hd_last_drive,0ffh	;neither drive was last used
		call	sasi_io
		ret
new_hdisk	endp
set_parameters	db	0ch,0,0,0,0,0		;sasi set parameters command
req_status_0	db	3,0,0,0,0,0		;sasi reqest status command
req_status_1	db	3,20h,0,0,0,0		;sasi reqest status command
recal_0		db	1,0,0,0,0,0		;sasi recal drive 0
recal_1		db	1,20h,0,0,0,0		;sasi recal drive 1
test_0_ready	db	0,0,0,0,0,0		;test drive 0 ready
test_1_ready	db	0,20h,0,0,0,0		;test drive 1 ready

		subttl New Serial port calls
		page +
;----------------------------------------------------------------
;  New Serial Port function calls
;
;  input:
;     al = function #
;        0 = input characters
;        1 = output characters
;           cx = count
;           es:si = buffer
;
;        2 = input status
;        3 = output status
;           es:si = buffer      (next charecter to be read for input)
;
;	5 = setup serial port
;		bl bits 7,6,5 baud rate   4,3 parity  2 stopbit 1 0 char length
;			0=110		  x0 = none	0 =1     10 = 7
;			1=150		  01 = odd	1 = 2	 11 = 8
;			2=300		  11 = even
;			3=600
;			4=1200
;			5=2400
;			6=4800
;			7=9600					    
;
;        81= change hold enable (XON XOFF)
;           bl= 0 enable holds else disable
;             
;   output
;     al = status
;----------------------------------------------------------------
new_port0_in	proc	far
		mov	di,offset port1_buf
		mov	dl,2			;flag #2
		mov	dh,com1_waiting
		jmp	short npi1
new_port1_in:	mov	di,offset port2_buf
		mov	dl,3			;flag #3
		mov	dh,com2_waiting
npi1:		or	al,al
		jnz	npi_status
		jcxz	npi_done
npi2:		mov	bl,[di].tail
		cmp	bl,[di].head
		jne	npi_got_char
		mov	al,dl			;dl has flag number
		mov	ah,0
		or	com_flags,dh		;com_waiting
		int	concurrent_int		;wait for charecter
		jmp	npi2
npi_got_char:
		xor	bh,bh
		mov	al,[di][bx]
		mov	es:[si],al
		inc	si
		inc	bl
		and	bl,0fh
		mov	[di].tail,bl
		loop	npi2
		mov	al,0
npi_done:	ret
npi_status:
		mov	al,0		
		mov	bl,[di].tail
		cmp	bl,[di].head
		jne	npis_done
		mov	al,not_ready_error
npis_done:
		xor	bh,bh			;JONATHAN 4,1,86
		mov	ah,[di][bx]
		mov	es:[si],ah
		ret
new_port0_in	endp


new_port2_in	proc	far
		mov	di,offset port3_buf
		mov	dl,4			;flag #4
		mov	dh,com3_waiting
		jmp	short npi21
new_port3_in:	mov	di,offset port4_buf
		mov	dl,5			;flag #5
		mov	dh,com4_waiting
npi21:		or	al,al
		jnz	npi2_status
		jcxz	npi2_done
npi22:		mov	bl,[di].tail
		cmp	bl,[di].head
		jne	npi2_got_char
		mov	al,dl			;dl has flag number
		mov	ah,0
		or	com_flags,dh		;com_waiting
		int	concurrent_int		;wait for charecter
		jmp	npi22
npi2_got_char:
		xor	bh,bh
		mov	al,[di][bx]
		mov	es:[si],al
		inc	si
		inc	bl
		and	bl,0fh		;JONATHAN 7-16-86
		mov	[di].tail,bl
		loop	npi22
		mov	al,0
npi2_done:	ret
npi2_status:
		mov	al,0		
		mov	bl,[di].tail
		cmp	bl,[di].head
		jne	npis2_done
		mov	al,not_ready_error
npis2_done:
		mov	ah,[di][bx]
		mov	es:[si],ah
		ret
new_port2_in	endp


new_port0_out	proc	far
		cmp	al,81h
		je	npo4
		cmp	al,1
		jne	npo1
		cld
		jcxz	npo2
npo3:		lods	b es:[si]
		call	port1_write
		loop	npo3	  
		xor	bl,bl
		jmp 	short npo2
npo1:		cmp	al,3
		je	npo50
		cmp	al,5
		jne	npo2
		call	set_up_port1
npo50:		call	port1_status
npo2:		ret
npo4:		or	bl,bl
		jz	npo5
		and	com_hold_enable,not 1
		ret
npo5:		or	com_hold_enable,1
		ret
new_port0_out	endp
new_port1_out	proc	far
		cmp	al,81h
		je	npo14
		cmp	al,1
		jne	npo11
		cld
		jcxz	npo12
npo13:		lods	b es:[si]
		call	port2_write
		loop	npo13	   
		xor	bl,bl
		jmp	short npo12
npo11:		cmp	al,3
		je	npo51
		cmp	al,5
		jne	npo12
		call	set_up_port2
npo51:
		call	port2_status
npo12:		ret
npo14:		or	bl,bl
		jz	npo15
		and	com_hold_enable,not 10b
		ret
npo15:		or	com_hold_enable,10b
		ret
new_port1_out	endp
new_port2_out	proc	far
		cmp	al,81h
		je	npo24
		cmp	al,1
		jne	npo21
		cld
		jcxz	npo22
npo23:		lods	b es:[si]
		call	port3_write
		loop	npo23
		xor	bl,bl	   
		jmp	short npo22
npo21:		cmp	al,3
		je	npo52
		cmp	al,5
		jne	npo22
		call	set_up_port3
npo52:
		call	port3_status
npo22:		ret
npo24:		or	bl,bl
		jz	npo25
		and	com_hold_enable,not 100b
		ret
npo25:		or	com_hold_enable,100b
		ret
new_port2_out	endp
new_port3_out	proc	far
		cmp	al,81h
		je	npo34
		cmp	al,1
		jne	npo31
		cld
		jcxz	npo32
npo33:		lods	b es:[si]
		call	port4_write
		loop	npo33	  
		xor	bl,bl
		jmp	short npo32
npo31:		cmp	al,3
		je	npo53
		cmp	al,5
		jne	npo32
		call	set_up_port4
npo53:
		call	port4_status
npo32:		ret
npo34:		or	bl,bl
		jz	npo35
		and	com_hold_enable,not 1000b
		ret
npo35:		or	com_hold_enable,1000b
		ret
new_port3_out	endp
;----------------------------------------------------------------
;  Equipment
;    returns bx = memory size (k bytes)
;----------------------------------------------------------------
equipment	proc	far
		mov	bx,memory_size
		ret
equipment	endp

code		ends
		end

