		if2
		%out	Pass 2.
		endif
		.286c
		page	60,132
		name	ibm
		title	Slicer BIOS Version 2.0A (Monitor 1.3 emulation)
.xlist
		subttl	Data Areas
		page	+
		include	biosdata.asm
		page	+
.list
;--------------------------------------------------------------------------------
;	      BIOS for the Slicer. (C) Slicer Computers Inc.,  1985
;
;             Version 2.0                 April 4, 1985 
;	      By David Daney 1985
;
;
;--------------------------------------------------------------------------------
		subttl	Equates
		page
;----------------------------------------------------------------
;      E Q U A T E S
;----------------------------------------------------------------
b		equ	byte ptr  
w		equ	word ptr
hd0		equ	4
console		equ	6
aux_dev		equ	8
prn_dev		equ	7
input		equ	0
output		equ	1
in_status	equ	2
out_status	equ	3
function_call	equ	0f8h
disk_read_cmd	equ	10011000b
disk_write_cmd	equ	10111000b
time_out	equ	80h
not_ready_error	equ	80h
bad_seek	equ	40h
bad_crc		equ	10h
record_not_fnd	equ	04h
write_protect	equ	03h
bad_addr_mark	equ	02h
bad_cmd		equ	01h

int_stat	equ	8ah		;CHANGE
int_stat2	equ	9ah
du_out		equ	9ch
dureset		equ	9dh

		subttl	Externals and Publics
		page	+
;----------------------------------------------------------------
; Externals and Publics
;----------------------------------------------------------------
		public	old_call_init
		public	number_table
		public	print_al
		public	print_ax
		public	conout2
		public	old_load	;Jonathan
;ADDED FOR MAP
		public read,write,old_dispatch

		extrn	disk_read:near
		extrn	disk_write:near
		extrn	disk_reset:near
		extrn	drive_mask:byte

		subttl	Initialization Code
		page	+

cgroup		group	code

code		segment byte public 'code'
		assume	cs:cgroup
old_call_init	proc	near
;
set		macro	num,val
		mov	w num,offset val
		mov	w num+2,seg val
		endm
;
		assume	es:vectors
		set	vector_fb,old_dispatch
		set	vector_3b,old_dispatch
		assume	es:nothing

;initialize duout and duimr for old monitor calls were bl = 0ah, 0bh, 0ch, 0dh

		push    dx
		push	ax			
		push	ds
		mov	ax,data
		mov	ds,ax	  
		assume	ds:data
		mov	duout,0		;assumming all outputs resset fix later
		mov	dx,int_stat		;interrupt status register on slicer board
		in      al,dx		;read it
		mov	duimr,al	;save it if people call this through monitor it won't be screwed up
		pop	ds
		pop	ax
		pop	dx
		ret

old_call_init	endp
number_table	db	'0123456789ABCDEF'
old_table	dw	dispatch_end		;0
		dw	const			;1
		dw	conin			;2
		dw	conout			;3
		dw	dubin			;4
		dw	dubout			;5
		dw	dispatch_end
		dw	home			;6
		dw	read			;7
		dw	write			;8
		dw	duon			;9
		dw	duoff			;10
		dw	duhigh			;11
		dw	dulow			;12
		dw	lstout			;13
		dw	lstst			;14
		dw	dispatch_end		;15
		dw	dskcheck		;16
    		dw	dispatch_end
		dw	dolmess			;17
		dw	message			;18
		dw	hexword			;19
		dw	hexbyte			;20
		dw	decdisp			;21
		dw	clrscr			;22
		dw	crtset			;23
    		dw	old_load		;24 added by jonathan

old_dispatch	proc	far
		sti
		cld
		push	bp
		mov	bp,sp
		push	es
		push	ds
		push	si
		push	di
		push	cx
		push	dx
		push	ax
		mov	cx,data
		mov	es,cx
		assume	es:data
		cmp	bl,21h
		jae	dispatch_end
		xor	bh,bh
		shl	bx,1
		jmp	old_table[bx]
dispatch_end1:	pop	dx		;discard old ax
		jmp	short de3
dispatch_end:	pop	ax
de3:		pop	dx
		pop	cx
		pop	di
		pop	si
		pop	ds
		pop	es
		pop	bp
		ret	2
old_dispatch	endp
const		proc	near			;console input status
		mov	ah,console
		mov	al,in_status
		jmp	short const1
lstst:		mov	ah,prn_dev		;printer status
		mov	al,out_status
const1:
		mov	si,offset old_temp_char
		int	function_call
		or	al,al
		jz	const_rdy
		xor	al,al
		jmp	dispatch_end1
const_rdy:	mov	al,0ffh
		or	al,al
		jmp	dispatch_end1
const		endp
conin		proc	near			;console input
		mov	ah,console
		jmp	short conin1
dubin:		mov	ah,aux_dev		;aux input
conin1:		mov	al,input
		mov	si,offset old_temp_char
		mov	cx,1
		int	function_call
		mov	al,es:[si]
		jmp	dispatch_end1
conin		endp
conout2		proc	near			;output al to device in ah
		push	ax
		mov	si,offset old_temp_char
		mov	es:[si],al
		mov	al,output
		mov	cx,1
		int	function_call
		pop	ax
		ret
conout2		endp

conout		proc	near			;console output
		mov	ah,console
		jmp	short conout1
lstout:		mov	ah,prn_dev		;printer output
		jmp	short conout1
dubout:		mov	ah,aux_dev		;aux output
conout1:	call	conout2
		jmp	dispatch_end
conout		endp
home		proc	near			;home disk drive heads
		mov	bl,dsknum
		and	bx,03h			;mask for floppy disks only
		mov	al,cgroup:drive_mask[bx]
		or	recal_required,al
		jmp	dispatch_end
home		endp
read		proc	near
		mov	bx,es
		mov	ds,bx
		assume	ds:data
		mov	al,dsknum
		cmp	al,3 			;this means a disk greater than 3 must be a hard disk
		ja	hd_read			;that is not good it should be check with dskcheck call
		call	disk_setup
		mov	al,settle
		and	al,4
		or	al,disk_read_cmd		;ADDED BY JONATHAN
							;FOR HEAD DEBOUNCE
		call	disk_read
r0:		mov	ah,diskette_status
r00:		xor	al,al
		test	ah,write_protect
		jz	r1
		or	al,040h
r1:		test	ah,bad_crc
		jz	r2
		or	al,8
r2:		test	ah,time_out
		jz	r3
		or	al,080h
r3:		test	ah,record_not_fnd
		jz	r4
		or	al,010h
r4:		jmp	dispatch_end1

hd_read:	cmp	al,4
		je	r5  
		cmp 	al,5
		je	r7
r6:		mov	al,0ffh			;drive does not exist
		jmp	r4
r5:		cmp	hdpb0.step_rate,0ffh	;drive does not exist
		je	r6
		jmp     r8
r7: 		cmp	hdpb1.step_rate,0ffh
		je	r6
r8: 		push	ax
		mov	ax,dsktrack
		mov	bx,17
		mul	bx
		sub	ax,1
		sbb	dx,0
		add	al,dsksector
		adc	ah,0
		adc	dx,0
		mov	bx,ax			;sector number in dx:bx
		mov	cx,1
		mov	si,dskmem
		mov	es,dskseg
		pop	ax
		mov	ah,al
		mov	al,input
		int	function_call
		mov	ah,al			;status to ah
		jmp	r00			;xlat status and exit

read		endp

write		proc	near
		mov	bx,es
		mov	ds,bx
		mov	al,dsknum
		cmp	al,3
		ja	hd_write
		call	disk_setup
		mov	al,settle
		and	al,4
		or	al,disk_write_cmd		;ADDED BY JONATHAN
							;FOR HEAD DEBOUNCE
		call	disk_write
		jmp	r0
hd_write:	cmp	al,4
		je	w5
		cmp	al,5
		je	w7
w6:		mov	al,0ffh			;drive does not exist
		jmp	r4
w5:		cmp	hdpb0.step_rate,0ffh	;drive does not exist
		je	w6
		jmp     w8
w7:    		cmp	hdpb1.step_rate,0ffh
		je	w6
w8:		push	ax
		mov	ax,dsktrack
		mov	bx,17
		mul	bx
		sub	ax,1
		sbb	dx,0
		add	al,dsksector
		adc	ah,0
		adc	dx,0
		mov	bx,ax			;sector number in dx:bx
		mov	cx,1
		mov	si,dskmem
		mov	es,dskseg
		pop	ax
		mov	ah,al
		mov	al,output
		int	function_call
		mov	ah,al			;status to ah
		jmp	r00			;xlat status and exit

write		endp

disk_setup	proc	near
		mov	es,dskseg
		mov	bx,dskmem
		mov	drive_number,al
		mov	ax,dsktrack
		mov	disk_track,al
		mov	al,dsksector
		mov	ah,al
		and	al,07fh			;mask out side
		mov	sector_number,al
		shr	ah,7			;head number in bit 7
		mov	head_number,ah
		mov	num_of_sectors,1
		ret
disk_setup	endp

duon		proc	near
		mov	cl,al
		mov	dx,int_stat2		;interrupt stat on slicer board	 serial
		in	al,dx
		or	al,cl
		out	dx,al 		;set requested bits
		mov	duimr,al
		ret					   
duon		endp
duoff		proc	near
		mov	cl,al
		not	cl
		mov	dx,int_stat2		;interrupt stat on slicer  serial
		in	al,dx
		and	al,cl
		out	dx,al
		mov	duimr,al
		ret
duoff		endp

duhigh		proc	near
		mov	dx,du_out		;set outputs reg on slicer  serial
		out	dx,al
		or	duout,al
		mov	al,duout
		ret
duhigh		endp

dulow		proc	near
		mov	dx,dureset		;reset outputs seg on slicer serial    
		out	dx,al 
		not	al
		and	duout,al
		mov	al,duout
		ret
dulow		endp

dskcheck	proc	near
		mov	ax,es
		mov	ds,ax
		mov	ah,dsknum
		cmp	ah,3
		jae	dc1
		mov	al,84h			;analyse format
		int	function_call
		or	al,al
		jnz	dc2			;read error
		mov	al,dl
		shr	al,2			;sector size in bits 0,1
		and	al,3
		cmp	bl,2
		jne	dc3
		or	al,4			;2 sides
dc3:		mov	ah,8			;disk is floppy
		shr	dl,4
		and	dl,7
		or	ah,dl			;mini,d'density,half track
		xor	bx,bx			;set zero flag
		jmp	dispatch_end1
dc1:		mov	ax,1002h		;hard disk 512 byte sector
		xor	bx,bx
		jmp	dispatch_end1
dc2:		or	al,80h
		jmp	dispatch_end1
		assume	ds:nothing
dskcheck	endp
dolmess		proc	near
		mov	si,ds
		mov	es,si
		mov	di,dx
		mov	al,'$'
		mov	cx,0ffffh
	repne	scas	b [di]
		not	cx
		dec	cx
		mov	si,dx
		mov	ah,console
		mov	al,output
		int	function_call
		jmp	dispatch_end
dolmess		endp
message		proc	near
		mov	es,[bp+4]
		mov	di,[bp+2]
		mov	al,0
		mov	cx,0ffffh
	repne	scas	b [di]
		not	cx
		mov	si,[bp+2]
		add	[bp+2],cx
		dec	cx
		mov	ah,console
		mov	al,output
		int	function_call
		jmp	dispatch_end
message		endp


print_al	proc	near			;print al in hex ax not destroyed
		mov	bx,offset number_table
		mov	di,ax
		shr	al,4
		and	al,0fh
		xlat	number_table[bx]
		mov	ah,console
		call	conout2
		mov	bx,offset number_table
		mov	ax,di
		and	al,0fh
		xlat	number_table[bx]
		mov	ah,console
		call	conout2
		mov	ax,di
		ret
print_al	endp
print_ax	proc	near			;print ax in decimal
		mov	bx,10
		xor	dx,dx
		div	bx
		add	dl,'0'
		or	ax,ax
		jz	got_it
		push	dx
		call	print_ax
		pop	dx
got_it:		mov	ah,console
		mov	al,dl
		call	conout2
		ret
print_ax	endp



hexword		proc	near
		xchg	ah,al
		call	print_al
		xchg	ah,al
		call	print_al
		jmp	dispatch_end
hexword		endp
hexbyte		proc	near
		call	print_al
		jmp	dispatch_end
hexbyte		endp
decdisp		proc	near
		push	ax
		call	print_ax
		pop	ax
		jmp	dispatch_end
decdisp		endp

clrscr		proc	near
		
		mov	al,crt_mode
		mov	ah,0
		int	10h
		jmp	dispatch_end
clrscr		endp

crtset  	proc	near
		mov	bh,0			;page # may change this
		mov	bl,dh			;dh has column
		mov	dh,dl			;dl has row need to flop for int 10h
		mov	dl,bl
		mov	ax,200h
		int 	10h
		jmp	dispatch_end
crtset		endp

old_boot	equ	8800h	    
return		equ	12h
timer		equ	70h
romseg		equ	0f800h
intret		equ	7ffdh
			      
boot_info	struc
load_offset	dw	?	;this is address to load loader
load_segment	dw	?
run_offset	dw	?	;this is address to jump to once loader is loaded
run_segment	dw	?
num_of_sec	dw	? 	;number of sectors to load
bytes_per_sec	dw	?
sec_per_track	db	?
boot_info	ends
		

old_load	proc	near				
		mov	ax,87h		;reset disk system
		int	function_call
		or	al,al
		jz	old_l1
		jmp	boot_error
old_l1:	        mov	ax,84h		;analyse format
		int	function_call
		or	al,al
		jz	old_l2
		jmp	boot_error
old_l2:		mov	bl,1
		mov	cl,1
		mov	ax,82h
		int	function_call  
		mov	cx,1 		;number of sectors
		mov	bx,0		;sector number 1
		mov	ax,80h
		mov	es,ax		;load segment
		mov	si,0		;load offset
		mov	ax,0
		int	function_call	;read in first sector of disk to 80:0
		or	al,al
		jz	old_l3
		jmp	boot_error
				
old_l3:		mov	al,es:return	;look for ret instruction in old loader
		cmp	al,0c3h
		jne	not_cpm	       ;if no ret instruction not cpm disk
		push	offset old_l4
		push	old_boot
  		ret
old_l4:		cmp	al,1
		jnz	not_cpm 	;bx points to boot info off disk in ld4.a86
		push	bx
		mov	ax,85h			;get current disk prams
		int	function_call		
		pop	si
		push	si
		mov	ax,84h			;get disk prams
		int 	function_call
		xor	ch,ch
		mov	cl,es:[si.sec_per_track] 
		mov	ax,82h		       ;set disk prams
		int	function_call
		pop	bx
		push	bx
		mov	cx,es:[bx.num_of_sec]
		mov	si,es:[bx.load_offset] 
		mov	es,es:[bx.load_segment]
		mov	ax,0
		mov	bx,0
		int	function_call		;load loader at proper address	 
		pop	bx
		or	al,al
		jnz	boot_error
		mov	bx,es:[bx.run_offset]
		call	far ptr go		
				  
boot_error: 
not_cpm: 
		ret 
old_load	endp

go		proc	far	    
		push	es		;segment to jump to
		push	bx		;offset to jump to
	
		ret
go		endp
code		ends


		end


