;;
;;
;;	MBMODE98.ASM    for PC-9801 or PC-286  with PC9861K or B98-01
;;
;;		INIT RS-232C PORT 
;;
;;		Copyright  7th FEB. 1990 JE1ILR MOKKUN
;;

cr	equ	0dh
lf	equ	0ah

_int0	equ	0bh     	; int #0 vector
_int1	equ	0dh     	; int #1
_int2	equ	0eh     	; int #2

pic1	equ	0002h
pic2	equ	000ah


mask0	equ	0efh
mask1	equ	0bfh
mask2	equ	0f7h
mask3	equ	0h
mask4	equ	0h

mask_n0	equ	010h
mask_n1	equ	040h
mask_n2	equ	008h
mask_n3	equ	0h
mask_n4	equ	0h

rate0	equ	075h    	; 8253 counter2
rate1	equ	0d1h        	; CH1 rate reg.
rate2	equ	0d5h        	; CH2
rate3	equ	0h        	; CH3
rate4	equ	0h        	; CH4
rate5	equ	077h    	; 8253 control word reg.

mode0	equ	032h    	; 
mode1	equ	0b3h    	; 
mode2	equ	0bbh    	; 
mode3	equ	0h    	; 
mode4	equ	0h    	; 

ssw	equ	0a3feh
cmd8253	equ	0b6h
prn_status	equ	042h
combios	equ	014h
inquiry	equ	04h
leave	equ	0aa55h
t_aiwa	equ	0ch
;;
;;

print	macro	msgadr
	mov	ah,09h
	lea	dx,msgadr
	int	21h
	endm

comchek	macro	channel
	mov	dx,channel
	mov	ah,inquiry
	int	combios
	endm

;;

CSEG	SEGMENT
	ASSUME	CS:CSEG, DS:CSEG

	ORG	80H
cmdlin:	DB	128 DUP(?)

	ORG	100H
start:
	jmp	open

opn_msg:
	db	cr,lf
	db	'MBMODE98 ver0.9  by JE1ILR Mokkun'
	db	cr,lf,'$'
use_msg:
	db	cr,lf
	db	'MBMODE98 <CH number> [baud rate] [bits] [parity] [stop bit]'
	db	cr,lf,lf
	db	'ch number	RS232C-0,1,2 or more',cr,lf
	db	'baud rate	75 - 38400 baud',cr,lf
	db	'bit      	BITS-5,6,7 or 8 bit , character length',cr,lf
	db	'parity  	PARITY-NONE , EVEN , ODD',cr,lf
	db	'stop bit	STOP-1 or 2 bit',cr,lf
	db	cr,lf
	db	'example	MBMODE98 RS232C-0 9600 BITS-8 PARITY-NONE STOP-1',cr,lf
	db	'	MBMODE98 R-0 96 B-8 P-N S-1',cr,lf
	db	'	MBMODE98 R-0',cr,lf,lf
	db	'** CAUTION',cr,lf
	db	'	in default of all parameter, set it from MEMORY SW',cr,lf
	db	'	without CH number.',cr,lf
	db	cr,lf,'$'
bios_er_msg:
	db	'COMBIOS not stay here.',cr,lf
	db	cr,lf,'$'
cpu_er_msg:
	db	'No suport this machene.',cr,lf
	db	cr,lf,'$'
rate_er_msg:
	db	'CH'
com_ch:
	db	'0'
	db	' Baud rate set error.',cr,lf
	db	cr,lf,'$'
bit_er_msg:
	db	'Character length set error.',cr,lf
	db	cr,lf,'$'
per_er_msg:
	db	'Parity bit set error.',cr,lf
	db	cr,lf,'$'
stop_er_msg:
	db	'Stop bit set error.',cr,lf
	db	cr,lf,'$'
max_ch:	db	0h
baud:	db	0
baud1:	dw	rate0
baud2:	dw	rate5
set:
	db	0
	dw	mode0,mode1,mode2,mode3,mode4

para_r:	db	'RS'
para_r1:
	db	'R-'
para_b:	db	' B'
para_p:	db	' P'
para_s:	db	' S'
b_75:	db	'75'
b_15:	db	'15'
b_30:	db	'30'
b_60:	db	'60'
b_12:	db	'12'
b_24:	db	'24'
b_48:	db	'48'
b_96:	db	'96'
b_192:	db	'19'
b_384:	db	'38'

clk_5:	dw	4096	;2048	;4096
clk_8:	dw	3328	;1664	;6656
clk_10:	dw	4096	;2048	;8192

pic:	dw	pic1,pic1,pic1,pic2,pic2
mask_e:	db	mask0,mask1,mask2,mask3,mask4
mask_n:	db	mask_n0,mask_n1,mask_n2,mask_n3,mask_n4

find:
	push	bp			; BX=CHRACTER, BP=CH No.
	mov	cl,byte ptr [cmdlin]
	xor	ax,ax
	mov	bp,ax
find_loop:
	inc	bp
	dec	cl
	jz	find_exit
	mov	ax,word ptr cmdlin[bp]
	cmp	ax,bx
	jne	find_loop
	mov	ax,word ptr cmdlin+2[bp]
	mov	bx,bp
	jmp	find_done
find_exit:
	mov	ax,0ffffh
find_done:
	pop	bp				; AX=find CHR  or 0ffffh
	ret					; BX=count


find1:
;	push	bp
;	mov	bp,bx

find1_loop:
	inc	bx
	dec	cl
	jz	find1_exit
	mov	ah,byte ptr cmdlin[bx]
	cmp	ah,al
	jne	find1_loop

	inc	bx
	mov	ah,byte ptr cmdlin[bx]
	jmp	find1_done
find1_exit:
	mov	ax,0ffffh
find1_done:
;	pop	bp
	ret

io_wait:
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	jmp	short	$+2
	ret



use:
	print	use_msg
	mov	al,01h
	jmp	done
exit:
	print	use_msg
	print	bios_er_msg
	mov	al,02h
	jmp	done

io_err:
	print	bios_er_msg
	mov	al,02h
	jmp	done

rate_error:
	print	rate_er_msg
	mov	al,03h
	jmp	done
b_err:
	print	bit_er_msg
	mov	al,04h
	jmp	done
p_err:
	print	per_er_msg
	mov	al,05h
	jmp	done
s_err:
	print	stop_er_msg
	mov	al,06h
	jmp	done
cpu_err:
	print	cpu_er_msg
	mov	al,7h
	jmp	done

open:
	print opn_msg

chk_bios:
	xor	bp,bp

	mov	dx,0h		;CH 0
	mov	ah,inquiry
	int	combios		;COMBIOS
	cmp	ax,leave	;stay here ?
	jne	exit		;No, error exit

	mov	dx,01h		;CH 1
	mov	ah,inquiry
	int	combios		;COMBIOS
	cmp	ax,leave	;stay here ?
	jne	ch_set

	mov	dx,02h		;CH 2
	mov	ah,inquiry
	int	combios		;COMBIOS
	cmp	ax,leave	;stay here ?
	jne	ch_set
	mov	dx,03h
	jmp	ch_set

	mov	dx,03h		;CH 3
	mov	ah,inquiry
	int	combios		;COMBIOS
	cmp	ax,leave	;stay here ?
	jne	ch_set

	mov	dx,04h		;CH 4
	mov	ah,inquiry
	int	combios		;COMBIOS
	cmp	ax,leave	;stay here ?
	jne	ch_set
	mov	dx,05h		; max CH+1
ch_set:
	dec	dx
	or	dl,030h  	; max CH ASSCII code
	mov	byte ptr max_ch,dl	;store max CH No. ASCII
	
command:
	xor	cx,cx
	mov	cl,byte ptr [cmdlin]	;load top of buffer pointer
	cmp	cl,2			; some CHR ?
	jle	usage			; No exit

	push	ds
	mov	ax,ssw
	mov	ds,ax
	mov	al,byte ptr ds:[2]	; read memry sw1 0A3FE2H
	and	al,0feh			;set baud rate
	or	al,02h			; 1/16 mode
	mov	byte ptr cs:set,al	;  and store it

	mov	al,byte ptr ds:[6]	; read memory sw2 0A3FE6H
	and	al,0fh   		; get baud rate
;	dec	al			; and shift 1/16 mode
;	dec	al
	mov	byte ptr cs:baud,al	; and store it
	pop	ds

trans_chr:
	mov	bx,cx
trans_loop:
	mov	al,byte ptr cmdlin[bx]
;	and	al,not('a'-'A')

	cmp	al,060h
	jbe	trans1
	and	al,05fh			; 'a' - 'A' transrate
trans1:
	mov	byte ptr cmdlin[bx],al
	dec	bx
	loop	trans_loop

param_r:


	mov	bx,word ptr [para_r]	;get PARAMETER CHR
	call	find
	cmp	ax,0ffffh  	;no find ?
	jne	param_r1	; find it
	
	mov	bx,word ptr [para_r1]	;get PARAMETER CHR
	
	call	find
	cmp	ax,0ffffh  	;no find ?
	je	usage    	;error exit
param_r1:
	cmp	al,'-'  	;switch CHR
	je	set_r    	;
	mov	al,'-'
	call	find1
	
	cmp	ax,0ffffh	;no find ?
	je	usage		;error exit
set_r:
	cmp	ah,'0'
	jb	bios_error
	cmp	ah,byte ptr [max_ch]	;max PORT No.
	ja	bios_error
	mov	byte ptr com_ch,ah
	and	ah,07h
	mov	al,ah
	xor	ah,ah
	mov	bp,ax   	;BP = com_ch No.
;	cmp	bp,0h
;	je	pset_baud_end	;skip preset_baud rate
;pset_baud:
;	mov	al,t_aiwa		;for AIWA ch2,3 baud rate
;	sub	al,byte ptr [baud] 	;
;	je	ba_error
;	mov	byte ptr baud,al 	;
;pset_baud_end:
	jmp	param_baud
usage:
	jmp	use
bios_error:
	jmp	io_err
ba_error:
	jmp	b_err






param_baud:
	mov	bx,word ptr [b_75] 	;75 baud (AIWA B98-01 only)
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p15    		;yes exit
	mov	byte ptr baud,01h	;??
	jmp	param_baud_end
p15:
	mov	bx,word ptr [b_15] 	;150 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p30		;yes exit

	mov	byte ptr baud,02h	;??
	jmp	param_baud_end
p30:
	mov	bx,word ptr [b_30] 	;300 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p60		;yes exit

	mov	byte ptr baud,03h
	jmp	param_baud_end
p60:
	mov	bx,word ptr [b_60] 	;600 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p12		;yes exit

	mov	byte ptr baud,04h
	jmp	param_baud_end
p12:
	mov	bx,word ptr [b_12] 	;1200 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p24		;yes exit

	mov	byte ptr baud,05h
	jmp	param_baud_end
p24:
	mov	bx,word ptr [b_24] 	;2400 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p48		;yes exit

	mov	byte ptr baud,06h
	jmp	param_baud_end
p48:
	mov	bx,word ptr [b_48] 	;4800 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p96		;yes exit

	mov	byte ptr baud,07h
	jmp	param_baud_end
p96:
	mov	bx,word ptr [b_96] 	;9600 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p192		;yes exit

	mov	byte ptr baud,08h
	jmp	param_baud_end
p192:
	mov	bx,word ptr [b_192] 	;19200 baud
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	p384		;yes exit

	mov	byte ptr baud,09h
	jmp	param_baud_end
p384:
	mov	bx,word ptr [b_384] 	;38400 baud (AIWA only ?)
	
	call	find
	
	cmp	ax,0ffffh  	;no find ?
	je	param_baud_end	;yes exit

	mov	byte ptr baud,0ah

param_baud_end:
;	cmp	bp,0h
;	je	set_baud_end	;skip set_baud rate
;set_baud:
;	mov	al,t_aiwa		;for AIWA ch2,3 baud rate
;	sub	al,byte ptr [baud] 	;
;	mov	byte ptr baud,al 	;
;set_baud_end:






param_b:
	mov	bx,word ptr [para_b]	;get PARAMETER CHR
	call	find
	cmp	ax,0ffffh  	;no find ?
	je	param_b_end    	;error exit

	cmp	al,'-'  	;switch CHR
	je	set_b    	;
	mov	al,'-'
	call	find1
	cmp	ax,0ffffh		;no find ?
	je	param_b_end	;error exit
set_b:
	mov	al,byte ptr [set]
	and	al,0f3h

set_b_5:
	cmp	ah,'5'  	;5 BIT CODE ?
	jb	b_error

set_b_6:
	cmp	ah,'6'  	;6 BIT CODE ?
	jne	set_b_7

	or	al,04h

set_b_7:
	cmp	ah,'7'  	;7 BIT CODE ?
	jne	set_b_8

	or	al,08h

set_b_8:
	cmp	ah,'8'  	;8 BIT CODE ?
	ja	b_error
	jne	set_b_end
	or	al,0ch

set_b_end:
	mov	byte ptr set,al	;store it
param_b_end:
	jmp	param_p
b_error:
	jmp	b_err



param_p:
	mov	bx,word ptr [para_p]	;get PARAMETER CHR
	
	call	find
	cmp	ax,0ffffh  	;no find ?
	je	param_p_end    	;error exit

	cmp	al,'-'  	;switch CHR
	je	set_p    	;
	mov	al,'-'
	call	find1
	cmp	ax,0ffffh		;no find ?
	je	param_p_end	;error exit

set_p:
	mov	al,byte ptr [set]
	and	al,0cfh
set_pn:
	cmp	ah,'N'   	;NONE ?
	je	set_p_end
set_pe:
	cmp	ah,'E'  	;EVEN ?
	jne	set_po

	or	al,010h
	jmp	set_p_end
set_po:
	cmp	ah,'O'  	;ODD ?
	jne	p_error

	or	al,030h
set_p_end:
	mov	byte ptr set,al	;store it
param_p_end:
	jmp	param_s
p_error:
	jmp	p_err
s_error:
	jmp	s_err



param_s:
	mov	bx,word ptr [para_s]	;get PARAMETER CHR
	
	call	find
	cmp	ax,0ffffh  	;no find ?
	je	param_s_end    	;error exit

	cmp	al,'-'  	;switch CHR
	je	set_s    	;
	mov	al,'-'
	call	find1
	cmp	ax,0ffffh		;no find ?
	je	param_s_end	;error exit

set_s:
	mov	al,byte ptr [set]
	and	al,03fh
set_s1:
	cmp	ah,'1'
	jne	set_s15
	
	or	al,040h
	jmp	set_s_end
set_s15:
	cmp	ah,'.'
	jne	set_s2
	
	or	al,080h
	jmp	set_s_end
set_s2:
	cmp	ah,'2'
	jne	s_error
	
	or	al,0ch
	
set_s_end:
	mov	byte ptr set,al	;store it
param_s_end:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

setting:
	cmp	bp,0h   	;channel No.0 ?
	je	com0    	;Yes go

	
ext_ch:	
	mov	al,t_aiwa	;BAUD RATE No. for AIWA SHIFT
	sub	al,byte ptr [baud]
;	mov	al,byte ptr [baud]	; parameter set
	mov	dx,bp   	; Ch number
	mov	ah,0h   	; baud rate set command
	int	combios     	; CALL BIOS
	cmp	ax,0h   	; good code = 0h
	je	s8251
	jmp	rate_error	; error = 0ffffh

com0:
	mov	dx,prn_status	; CPU mode,type REG.
	in	al,dx
	test	al,080h
	jne	com0_new
	test	al,040h
	jne	cpu_error	; no suport it !
com0_5:
;	mov	ax,word ptr [clk_5]
	lea	bx,clk_5
	jmp	n8259

cpu_error:
	jmp	cpu_err

com0_new:
	test	al,020h
	jne	com0_8
com0_10:
;	mov	ax,word ptr [clk_10]
	lea	bx,clk_10
	jmp	n8259
com0_8:
;	mov	ax,word ptr [clk_8]
	lea	bx,clk_8
	jmp	n8259
	



n8259:	jmp	com0_8253
	cli
	push	bx
	mov	bx,bp
	shl	bx,1
	mov	dx,word ptr pic[bx]
	in	al,dx
	mov	ah,byte ptr mask_n[bp]
	or	al,ah
	out	dx,al
	pop	bx
	sti






com0_8253:
	mov	al,byte ptr cmd8253	;
	mov	dx,word ptr baud2
	out	dx,al
	mov	cl,byte ptr [baud]
	mov	ax,word ptr [bx]
	shr	ax,cl
	mov	dx,word ptr baud1
	out	dx,al
	mov	dx,word ptr baud1
	mov	al,ah
	out	dx,al
	
;;
;;
s8251:
	mov	bx,bp
	shl	bx,1
	inc	bx
	mov	dx,word ptr set[bx]	;load mode reg address
	mov	al,0h
	out	dx,al   	; dummy command
	call	io_wait
	out	dx,al
	call	io_wait
	out	dx,al
	call	io_wait

	mov	al,40h   	; reset command
	out	dx,al
	call	io_wait

	mov	al,byte ptr [set]  	; command
	out	dx,al
	call	io_wait

	mov	al,37h   	; mode
	out	dx,al
	call	io_wait

e8259:
;割り込み許可
	cli
	mov	bx,bp
	shl	bx,1
	mov	dx,word ptr pic[bx]
	in	al,dx
	mov	ah,byte ptr mask_e[bp]
	and	al,ah
	out	dx,al
	sti

	mov	al,0h
done:
	mov	ah,04ch
	int	21h

	cseg	ends
	end start
