;-------------------------------------------------
;
;	AKI-H8 test : October 1998
;
;		( MIDI, Timer INT )
;
;-------------------------------------------------

;##### Port Defines #####
smr	.equ	h'0fffb0
brr	.equ	h'0fffb1
scr	.equ	h'0fffb2
tdr	.equ	h'0fffb3
ssr	.equ	h'0fffb4
rdr	.equ	h'0fffb5
pbddr	.equ	h'0fffd4
pbdr	.equ	h'0fffd6
iprb	.equ	h'0ffff8
tstr	.equ	h'0fff60
tsnc	.equ	h'0fff61
tmdr	.equ	h'0fff62
tfcr	.equ	h'0fff63
toer	.equ	h'0fff90
tocr	.equ	h'0fff91
tcr0	.equ	h'0fff64
tior0	.equ	h'0fff65
tier0	.equ	h'0fff66
tsr0	.equ	h'0fff67
tcnt0	.equ	h'0fff68
gra0	.equ	h'0fff6a
grb0	.equ	h'0fff6c

;##### Vector Defines #####
	.section vector,data,locate=h'000000
	.data.l	start
	.org	h'000060
	.data.l	int_timer0
	.org	h'0000d0
	.data.l	int_rx_error
	.data.l	int_rx_full

;##### Work RAM Data Defines #####
	.section ram,data,locate=h'0fef10
timer1	.res.w	1
timer2	.res.w	1
rx_top	.res.w	1
rx_end	.res.w	1
tx_top	.res.w	1
tx_end	.res.w	1
rsb	.res.b	1
channel	.res.b	1
dcb	.res.b	1
keyno	.res.b	1
data	.res.b	1
led	.res.b	1
flag	.res.b	1
	.org	h'0ff400
rx_fifo	.res.b	1024
	.org	h'0ff800
tx_fifo	.res.b	1024

;***** Reset --> Initialize --> Main Loop *****
	.section program,code,locate=h'000100
start:
	mov.l	#h'0fff0f,er7		; stack pointer set
	mov.l	#h'0fef10,er2
	mov.w	#h'0fe0,r1
	mov.b	#0,r0l
_ram_clear:
	mov.b	r0l,@er2
	inc.l	#1,er2
	dec.w	#1,r1
	bne	_ram_clear
	jsr	@sci0_init		; SCI initialize
	mov.b	#b'00100011,r0l
	mov.b	r0l,@tcr0		; Timer0 init : 2MHz clock
	bclr	#0,@tsr0		; Clear IMFA
	bset	#0,@tier0		; timer INT set
	mov.w	#49,r0			; 25usec INT
	mov.w	r0,@gra0
	mov.b	#b'11111111,r0l
	mov.b	r0l,@pbddr		; set : Port[B] all output
	jsr	@wait_500msec
	mov.b	#b'01110000,r0l		; tx/rx start !
	mov.b	r0l,@scr
	bset	#0,@tstr		; timer start !
	andc.b	#b'01111111,ccr		; interrupt enable
loop:
	jsr	@speed_check
	jsr	@timer_check
	jsr	@tx_midi_check
	jsr	@rx_midi_check
	jmp	@loop

;***** SCI init / MIDI Transmit Routines *****
sci0_init:
	mov.b	#b'00000000,r0l
	mov.b	r0l,@scr
	mov.b	#b'00000000,r0l
	mov.b	r0l,@smr
	mov.b	#15,r0l
	mov.b	r0l,@brr
	mov.w	#500,r0
_sci0_wait:
	dec.w	#1,r0
	bne	_sci0_wait
	mov.b	@ssr,r0l		; (dummy read)
	mov.b	#0,r0l
	mov.b	r0l,@ssr
	mov.b	#b'00001000,r0l
	mov.b	r0l,@iprb		; SCI0-int priority UP !
	rts
tx_midi_check:
	mov.w	@tx_top,r1
	mov.w	@tx_end,r6
	cmp.w	r1,r6
	bne	_tx_exist
	rts
_tx_exist:
	btst	#7,@ssr			; test TRDE
	bne	_tx_seq
	rts
_tx_seq:
	mov.w	#0,e6
	mov.b	@(tx_fifo,er6),r0l
	mov.b	r0l,@tdr
	bclr	#7,@ssr			; Transmit !
	inc.w	#1,r6
	bclr	#2,r6h
	mov.w	r6,@tx_end
	rts
tx_fifo_set:
	mov.w	@tx_top,r6
	mov.w	#0,e6
	mov.b	r0h,@(tx_fifo,er6)	; transmit data = [r0h]
	inc.w	#1,r6
	bclr	#2,r6h
	mov.w	r6,@tx_top
	rts

;***** Timer / Counter Routines *****
wait_500msec:
	mov.l	#500,er1
_wait_1:
	jsr	@wait_1msec
	sub.l	#1,er1
	bne	_wait_1
	rts
wait_1msec:
	mov.l	#2048,er2
_wait_2:
	sub.l	#1,er2
	bne	_wait_2
	rts
int_timer0:
	push.w	r0
	mov.b	#1,r0l
	mov.b	r0l,@flag
	btst	#0,@tsr0
	bclr	#0,@tsr0		; Clear IMFA
	pop.w	r0
	rte
timer_check:
	mov.b	@flag,r0l
	cmp.b	#0,r0l
	bne	_timer_event
	rts
_timer_event:
	mov.b	#0,r0l
	mov.b	r0l,@flag
	jsr	@nop100
	rts
speed_check:
	mov.w	@timer1,r1
	inc.w	#1,r1
	mov.w	r1,@timer1
	cmp.w	#50000,r1
	beq	_timer_1
	rts
_timer_1:
	mov.w	#0,r1
	mov.w	r1,@timer1
	mov.b	@led,r0l
	bnot	#7,r0l
	mov.b	r0l,@led
	mov.b	r0l,@pbdr		; write to Port[B]
	rts
nop100:
	.data.w	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.data.w	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.data.w	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.data.w	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	.data.w	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	rts

;***** Rx Interrupt / MIDI Receive Routines *****
int_rx_error:
	bclr	#5,@ssr
	bclr	#4,@ssr
	rte
int_rx_full:
	push.w	r0
	push.l	er5
	btst	#6,@ssr
	bclr	#6,@ssr
	mov.w	@rx_top,r5
	mov.w	#0,e5
	mov.b	@rdr,r0l
	mov.b	r0l,@(rx_fifo,er5)
	inc.w	#1,r5
	bclr	#2,r5h
	mov.w	r5,@rx_top
	pop.l	er5
	pop.w	r0
	rte
rx_midi_check:
	mov.w	@rx_top,r1
	mov.w	@rx_end,r5
	cmp.w	r1,r5
	bne	_rx_exist
	rts
_rx_exist:
	mov.w	#0,e5
	mov.b	@(rx_fifo,er5),r0h	; received data = [r0h]
	inc.w	#1,r5
	bclr	#2,r5h
	mov.w	r5,@rx_end
	btst	#7,r0h
	beq	running
	mov.b	r0h,r0l
	and.b	#b'11111000,r0l
	cmp.b	#b'11111000,r0l
	bne	_lower_f8
	rts
_lower_f8:
	and.b	#b'11110000,r0l
	cmp.b	#b'11110000,r0l
	bne	_lower_f0
	mov.b	#0,r0l
	mov.b	r0l,@rsb
	rts
_lower_f0
	mov.b	r0h,r0l
	and.b	#b'00001111,r0l
	mov.b	r0l,@channel
	mov.b	r0h,r0l
	and.b	#b'11110000,r0l
	mov.b	r0l,@rsb
	mov.b	#0,r0l
	mov.b	r0l,@dcb
	rts
running:
	mov.b	@rsb,r0l
	bne	_normal
	rts
_normal:
	cmp.b	#b'11000000,r0l
	beq	_2byte
	cmp.b	#b'11010000,r0l
	beq	_2byte
	mov.b	@dcb,r1l
	bne	_3byte
	inc.b	r1l
	mov.b	r1l,@dcb
	mov.b	r0h,@keyno
	rts
_2byte:
	mov.b	r0h,@data
	mov.b	@channel,r1l
	or.b	r1l,r0l
	mov.b	r0l,r0h
	jsr	@tx_fifo_set
	mov.b	@data,r0h
	jsr	@tx_fifo_set
	jsr	@led_monitor
	rts
_3byte:
	mov.b	#0,r1h
	mov.b	r1h,@dcb
	mov.b	r0h,@data
	mov.b	@channel,r1l
	or.b	r1l,r0l
	mov.b	r0l,r0h
	jsr	@tx_fifo_set
	mov.b	@keyno,r0h
	jsr	@tx_fifo_set
	jsr	@led_monitor
	mov.b	@data,r0h
	jsr	@tx_fifo_set
	rts

led_monitor:
	mov.b	@led,r0l
	mov.b	r0l,r2l
	and.b	#b'10000000,r2l
	mov.b	r0h,r2h
	and.b	#b'01111111,r2h
	or.b	r2l,r2h
	mov.b	r2h,@led
	mov.b	r2h,@pbdr		; write to Port[B]
	rts

	.end
