;prog to talk to punto and display
;engine parameters.

;all ok displays all rxd up to 32 bytes
;sends test byte 71h and rx's ack 5ah
;sends init bytes
;rx's and stores 6 iso bytes
;;to send commands yo ECU
;

 ASSUME	CS:CODE,DS:CODE, ES:CODE, SS:CODE
CODE		SEGMENT

;prog to send various signals to obd interface
;and interpret results if any

;assembler equates
tx		equ	03f8h
rx		equ	03f8h
dll		equ	03f8h
dlh		equ	03f9h
fcr		equ	03fah
lcr		equ	03fbh
mcr		equ	03fch
lsr		equ	03fdh
msr		equ	03feh


;set 1200 baud wait for data from ECU
;$#########   below init  ###############
init:
;set up for 1200baud
;tester	call	assem_word_string
	call	setup_timer
	call	reload		;load timer vals
	mov	b[baud_val],60h
	call	set_baud	;set baud rate
	call	dly_25ms
	call	mt_buff1	;start with clean buffer
	call	read_6bytes	;iso code
	call	dly_600ms	;wait 110msec
	call	send_init_byte
	mov	b[baud_val],15	;7812.5 baud closest
	call	set_baud
	call	dly_600ms
assem_again:
	call	assem_word_string
	call	send_txbyte
	call	next_reply
	;display response
	call	disp_results
	jmp	assem_again
	nop
	nop	;stop here
get_out1:
	mov	ah,04ch
	int	21h		;end prog
; another temp below



;temp below ************************************





;temp above ************************************


	nop
	nop

;///////////////////////////////////////////
;*******************  subs  *****************

send_txbyte:
	mov	dx,tx
	mov	al,b[word_string]
	out	dx,al
	ret


		
;remove sent char
echo_byte:
	mov	dx,lsr
	in	al,dx		;wait for byte
	and	al,01
	jne	echo_byte

	mov	dx,rx
	in	al,dx		;dump the val sent

				;rx the ECU data
				;timeout here	

next_reply:
	mov	si,0
	mov	b[ip_count],0
	call	dly_600ms
	mov	dx,lsr
	in	al,dx	
	and	al,1		;round again if no data
	je	no_data
store_rx_data:
	mov	dx,lsr		;kepp going till data gone
	in	al,dx	
	and	al,1	
	je	ret
				;all bytes should be in by now
	mov	dx,rx
	in	al,dx		;store data:
	inc	b[ip_count]	;how many bytes
	mov	b[rxd+si],al
	jmp	store_rx_data
	nop
	nop


no_data:
	mov	ah,9
	mov	dx,mess1
	int	21h
	ret





assem_word_string:
	mov	ah,9
	mov	dx,mess2
	int	21h			;give instructions
	mov	bx,0			;start at front of string
	mov	b[nib_count],0		;start with clean nibble
	mov	cx,0
read_kb:
	mov	si,0
	mov	ah,06		;check for key push
	mov	dl,0ffh
	int	21h
	jmp	$+2
	jne	valid_key	;jump if found
	jmp	read_kb		

		;validate key
valid_key:	
	mov	cx,27		;see if key is in allowed list
valid_key1:
	cmp	al,b[key_table+si]
	je	key_val		;jump out if its ok
	inc	si
	loop	valid_key1
	dec	si
	jmp	read_kb		;not here so ignore
	nop			;and get another one
key_val:
	call	disp_char	;display pushed key
	cmp	al,0dh		;if its <cr> then assemble it
	je	word_calc	;assemble true string here
	cmp	al,"q"
	je	get_out2

	cmp	al,"r"		;alter whole string?
	je	assem_word_string
	call	assem_byte
	jmp	read_kb
	ret

send_chart:
	mov	dx,tx
	mov	al,71h		;immo state
	out	dx,al
	ret

get_out2:
	pop	ax		;clear ret address
	push	get_out
	ret

word_calc:
	;if byte = odd then reject
	;if byte = even then cr/lf
	call	cr_lf
	cmp	b[nib_count],2
	jne	assem_word_string
	ret		;back to main

disp_char:
	mov	ah,02
	mov	dl,al
	int	21h
	ret

assem_byte:
				;moves 2 bytes into word_string
	push	w[nib_count]
	shr	w[nib_count],1
	jc	nib1

				;nib2
	pop	w[nib_count]
	call	hex_alpha
	mov	cl,4
	shl	al,cl
	mov	b[word_string+bx],al
	inc	w[nib_count]
	ret

nib1:

	pop	w[nib_count]
	call	hex_alpha
	or	b[word_string+bx],al
	inc	w[nib_count]
	inc	bl
	mov	al," "
	call	disp_char
	ret

hex_alpha:
	cmp	al,39h
	jle	numeric
	and	al,5fh		;made it upper case
	sub	al,7
numeric:
	sub	al,30h
	ret




disp_results:
	call	cr_lf
	push	si
	mov	si,0
	push	cx
	mov	cx,20		;print 20 bytes
res_dis:
	mov	al,b[rxd+si]
	cmp	b[ip_count],0
	je	line_done	;if no reply get out
				;byte in al

	call	hex_asc
	xchg	ah,al
	push	ax
	call	disp_char	;display first char
	pop	ax		;
	xchg	ah,al
	call	disp_char	;display second char
	mov	al," "
	call	disp_char
	inc	si
	dec	ip_count
	jz	line_done
	loop	res_dis
line_done:
	call	cr_lf
	pop	cx
	pop	si
	ret

hex_asc:
	push	cx
	push	dx
	mov	dl,al		;val in al
	shl	ax,4
	and	ah,0fh

	add	ah,30h
	cmp	ah,39h
	jng	under9
	add	ah,7
under9:
	mov	al,dl
	and	al,0fh
	add	al,30h
	cmp	al,39h
	jng	under99
	add	al,7
under99:
	pop	dx
	pop	cx		;val in ax
	ret




;send init byte 0f-aa-cc
send_init_byte:
	mov	dx,tx
	mov	si,0
send_init:
	mov	al,b[init_byte+si]
	out	dx,al		;send the byte
	call	dly_110ms	;110 ms apart
	inc	si
	cmp	si,3		;3 bytes in init block
	jne	send_init
	ret



read_6bytes:
	mov	ah,09
	mov	dx,mess3
	int	21h		;wait for iso mess
	mov	si,0		;buff offset start
	mov	b[ip_count],0	;set length = zero
read_iso:
	mov	ah,06		;check for key push
	mov	dl,0ffh		;get out if no data rx'd
	int	21h
	jmp	$+2
	jne	get_out		;jump if in loop
;read expected data
; read iso

	mov	dx,lsr		;wait for byte to appear
char_in:
	in	al,dx
	and	al,1
	jz	read_iso
read_char:
	inc	b[ip_count]	
	mov	dx,rx
	in	al,dx
	jmp	$+2
	;store char		;remove char
	mov	b[rxd+si],al	;store in buff
	inc	si
	cmp	si,6		;last byte?
	jne	read_iso
		;all done
	mov	ah,09
	mov	dx,mess4
	int	21h
	call	disp_results
	ret			;back to main

get_out:
	mov	ah,04ch
	int	21h

;change baud rate

;$#########  above init  ###############

;adjust for punto
set_baud:
	mov	dx,lcr
	mov	al,080h
	out	dx,al		;dlab on
	jmp	$+2

	mov	dx,dll		;this val for 1200 bd
	mov	al,b[baud_val]
;	mov	al,60h
	out	dx,al		;set baud rate lo
	jmp	$+2

	mov	dx,dlh		;this val for baud
	mov	al,0
	out	dx,al		;set baud rate hi
	jmp	$+2

	mov	dx,lcr		;1200,nopar,8,1,p
	mov	al,03h
	
	out	dx,al
	jmp	$+2

	mov	dx,fcr		;reset port
	mov	al,0c7h		;maybe c7?
	out	dx,al
	jmp	$+2
		;**********   end of baud setup
	ret

dly_10ms:
	mov	w(tim_c),10	;thats 10ms
	jmp	dly_1ms
dly_25ms:
	mov	w(tim_c),25	;thats 25ms
	jmp	dly_1ms
dly_110ms:
	mov	w(tim_c),110	;thats 110ms
	jmp	dly_1ms

dly_400ms:
	mov	w(tim_c),400	;thats 400ms
	jmp	dly_1ms
dly_600ms:
	mov	w(tim_c),600	;thats 600ms
	jmp	dly_1ms

dly_1ms:
	cli
	mov	al,0e8h		;ask for status
	out	43h,al
	in	al,42h
	jmp	$+2
	and	al,80h		;is bit 7 set?
	jne	dly_1ms		;still lo


dly_1ms1:
	mov	al,0e8h		;ask for status
	out	43h,al
	in	al,42h
	jmp	$+2
	and	al,80h		;is bit 7 set?
	je	dly_1ms1	;still hi

				;ok then dec the counter

	dec	w(tim_c)	;back tohex loop
	jnz	dly_1ms		;not done so back
				;its done so ret
	sti
	ret

mt_buff1:
	mov	dx,fcr		;start with clear buffs
	mov	al,0e7h
	out	dx,al
	jmp	$+2
check_fifo:
	mov	dx,lsr
	in	al,dx
	and	al,1		;no data?
	jz	mt_buff
	mov	dx,rx
	in	al,dx
	jmp	check_fifo
mt_buff:
	mov	dx,mcr		;set dtr +12v
	mov	al,1		;set rts -12v
	out	dx,al
	jmp	$+2
	mov	dx,fcr		;start with clear buffs
	mov	al,0e7h
	out	dx,al
	jmp	$+2
	ret

setup_timer:
	cli
	mov	al,0b6h		;load mode control reg
	out	43h,al		;for ls byte first
	jmp	$+2		;let settle

	in	al,61h
	or	al,03h		;set bit 0 hi
	and	al,0fdh		;shut off sound

	out	61h,al		;thats triggered
	jmp	$+2
	sti
	ret
reload:				;restart timer
	mov	al,89h		;load lsb
	out	42h,al
	jmp	$+2
	mov	al,04		;load msb
	out	42h,al		;for 1ms
	ret
;dump later
read_ans:			;just for proof of ECU prog
read_kb1:
	mov	ah,06		;check for key push
	mov	dl,0ffh		;get out if no data rx'd
	int	21h
	jmp	$+2
;	jne	get_out1	;jump if in loop
;read expected data
; read iso

	mov	dx,lsr		;wait for byte to appear
char_in1:
	in	al,dx
	and	al,1
	jz	read_kb1
read_char1:
	
	mov	dx,rx
	in	al,dx
	jmp	$+2
	ret			;back to main


cr_lf:
	mov	al,0dh
	call	disp_char
	mov	al,0ah
	call	disp_char
	ret




nib_count	db	0
word_string	db	0
ip_count	db	0
baud_val	db	0
tim_c		dw	0
;rxd		db	0,0,0,0,0,0
init_byte	db	0fh,0aah,0cch
key_table	db	"1","2","3","4","5","6","7","8","9","0"
		db	"A","B","C","D","E","F","R","Q",0DH
		db	"a","b","c","d","e","f","r","q"
rxd	db	32 dup (77)
mess1:		db	"No data received",0dh,0ah,"$"
mess2:		db	0ah,0dh,"enter request byte, then <CR>"
		db	0dh,0ah,"r = redo,   q = quit",0dh,0ah,"$"
mess3:		db	"waiting for iso code",0dh,0ah,"$"
mess4:		db	"received ok",0dh,0ah,"$"
	ENDS
	
	END
;all below is reference
;######################################
;######################################
;######################################
;######################################
;######################################
;######################################
