;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;:
;;;;        AKI-H8 Control program for H8/3664 Ver.3.4
;;;;        2013/05/30 switch preset signal receiver
;;;;
;;;;        2013/0530 Add the midiChannel & cc check routine in the real time
;;;;
;;;;        2012/0929 Change the cc start number from #1 to #47
;;;;        preset #0 = preset #47
;;;;        
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	.include	"yasuski3.inc"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Interrupt Vector Defines 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        .section vector, data, locate=h'0000
        .data.w     start

        .org       h'002e
        .data.w    int_scr3



    	.section rom,data, locate=h'1000

swaddr00:  .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr01:  .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 1, 1, 1, 1 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr02:  .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr03:  .data.b  0, 0, 0, 0, 1, 1, 1, 1 
           .data.b  1, 1, 1, 1, 1, 1, 1, 1 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr04:  .data.b  1, 1, 1, 1, 1, 1, 1, 1 
           .data.b  1, 1, 1, 1, 1, 1, 1, 1 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr05:  .data.b  1, 1, 1, 1, 1, 1, 1, 1 
           .data.b  1, 1, 1, 1, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr06:  .data.b  1, 1, 1, 1, 1, 1, 1, 1 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr07:  .data.b  0, 0, 0, 0, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 
           .data.b  0, 0, 0, 0, 0, 0, 0, 0 

swaddr08:  .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 1, 1, 1, 1

swaddr09:  .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 0, 0, 0, 0

swaddr10:  .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 1, 1, 1, 1

           
swaddr11:  .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  1, 1, 1, 1, 1, 1, 1, 1

swaddr12:  .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 1, 1, 1, 1
           .data.b  1, 1, 1, 1, 1, 1, 1, 1

swaddr13:  .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 1, 1, 1, 1
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  0, 0, 0, 0, 1, 1, 1, 1

swaddr14:  .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  1, 1, 1, 1, 1, 1, 1, 1

swaddr15:  .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  0, 0, 0, 0, 0, 0, 0, 0
           .data.b  1, 1, 1, 1, 1, 1, 1, 1
           .data.b  0, 0, 0, 0, 0, 0, 0, 0



swnum00:  .data.b  1, 2, 3, 4, 5, 6, 7, 8 
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20,21,22,23,24
          .data.b 25,26,27,28,29,30,31,32

swnum01:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12, 1, 2, 3, 4
          .data.b 13,14,15,16,17,18,19,20
          .data.b 21,22,23,24,25,26,27,28

swnum02:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20,21,22,23,24

swnum03:  .data.b  1, 2, 3, 4, 1, 2, 3, 4
          .data.b  5, 6, 7, 8, 9,10,11,12
          .data.b  5, 6, 7, 8, 9,10,11,12
          .data.b 13,14,15,16,17,18,19,20

swnum04:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16

swnum05:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9, 10,11,12,1, 2, 3, 4
          .data.b  5, 6, 7, 8, 9,10,11,12
          .data.b 13,14,15,16,17,18,19,20

swnum06:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20,21,22,23,24

swnum07:  .data.b  1, 2, 3, 4, 1, 2, 3, 4
          .data.b  5, 6, 7, 8, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20,21,22,23,24

swnum08:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16

swnum09:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20, 4, 3, 2, 1
          .data.b  8, 7, 6, 5,29,30,31,32

swnum10:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20,21,22,23,24
          .data.b 25,26,27,28,29,30,31,32

swnum11:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20,21,22,23,24
          .data.b  1, 2, 3, 4, 5, 6, 7, 8

swnum12:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b 17,18,19,20, 1, 2, 3, 4
          .data.b  5, 6, 7, 8, 9,10,11,12

swnum13:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9, 10,11,12,1, 2, 3, 4
          .data.b 13,14,15,16,17,18,19,20
          .data.b 21,22,23,24, 5, 6, 7, 8

swnum14:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b  9,10,11,12,13,14,15,16

swnum15:  .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  1, 2, 3, 4, 5, 6, 7, 8
          .data.b  9,10,11,12,13,14,15,16
          .data.b  9,10,11,12,13,14,15,16


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Variables in work RAM area
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        .section ram,data,locate=h'f780  ;for 3664

ports_01   .res.l          4

setcnt  .res.b         32         ;switch numbers assign matrix 16
 
setsw   .res.b         32         ;switch status preset for cc/pgm 8*2 port

samp_00        .res.b   8
samp_01        .res.b   8
samp_02        .res.b   8
samp_03        .res.b   8

ad_old	       .res.b	8
ad_sent        .res.b	8

midch	       .res.b   1         ;set midi ch
cc             .res.b   1         ;set control change status
ccnum          .res.b   1         ;set controll change start number
pgm            .res.b	1         ;set program change status
pgnum          .res.b   1         ;set program change start number
pgm_memory     .res.b   1

swptn          .res.b   1         ;set sw type preset number
port_counter     .res.b   1         ;set counter value
polarity       .res.b   1         ;set sw polarity
ad_flag        .res.b   1


sb	  .res.b	1
fsm	  .res.b	1
byte2	  .res.b	1
led       .res.b        1

           .org          h'f980
rx_fifo    .res.b        512

           .org          h'fb90
tx_fifo    .res.b        512

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; register allocation
;;; er0 : temporary  (for midi tx buffer)
;;; er1 : temporary
;;; er2 : temporary
;;; er3 : temporary
;;; er4 : temporary
;;; er5 : receive buffer pointer (e5: end, r5: top)
;;; er6 : transmit buffer pointer (e6: end, r6: top)
;;; er7 : stack pointer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; cc inputs x 16    port5 & port8
;;; AD inputs x  8    portB
;;; sw pattern        port1 #0,1 bit
;;; Midi CH           port1 #4,5,6,7 bit
;;; cc start#         port7 MSB cc start from 47,11,21,31,41,51,61,71
;;; pgm start#        fixed to "1"
;;;
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Main 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        .section program,code,locate=h'0034

start:
      mov.l   #h'ff7f,er7            ; stack pointer set
      jsr     @memory_set            ; Work RAM clear and FIFO pointer
      jsr     @sci_init             
      jsr     @wait_100msec          ; Wait  
      jsr     @input_enable	     ; Port init

      jsr     @midi_channel_set      ; get configuration
      jsr     @control_number_set
      jsr     @switch_preset
      jsr     @load_sw_num          ; loading switch numbers  
      jsr     @load_sw_num2

      jsr     @midi_start
     
loop:
      jsr     @sampling_00
      jsr     @tx_midi_check
      jsr     @sampling_01
      jsr     @rx_midi_check
      jsr     @sampling_02
      jsr     @digital_check
      jsr     @sampling_03
      jsr     @analog_check
;      jsr     @midi_channel_set      
;      jsr     @control_number_set
      jmp     @loop


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; digital port check
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

digital_check:
	
        sub.l	er1,er1
        sub.l	er3,er3

        sub.l   er2,er2
        mov.b   r2l,@port_counter

_dc_loop:
	
	mov.b	@pdr5,r0h               ; r0h is current port data

	mov.b	@(ports_01,er1),r2l	; r2l is previous port data
	mov.b	r0h,@(ports_01,er1)
	xor.b	r0h,r2l		        ; r2l is now update flag

	mov.b	#0,r2h		        ; r2h  is a counter

        bra _check_bits

_dc_loop_2:
	
	mov.b	@pdr8,r0h               ; r0h is current port data

	mov.b	@(ports_01,er1),r2l	; r2l is previous port data
	mov.b	r0h,@(ports_01,er1)
	xor.b	r0h,r2l		        ; r2l is now update flag

	mov.b	#0,r2h		        ; r2h  is a counter

        bra _check_bits

;>>>>> inner loop top

_check_bits:	

	btst	r2h,r2l                 ; checking the update flag
	beq	_next_bit

        sub.l   er3,er3
        mov.b   r2h,r3l
        mov.b   @port_counter,r0h
        add.b   r0h,r3l
        mov.b   #0,r0h

	mov.b	@(setsw,er3),r0h        ; uploading sw setting
        cmp.b    #0,r0h                 ; checking the data flag
        bne     _program_cng            ; branch when z flag = zero
        bra     _control_cng

_control_cng:

	mov.b	@cc,r0l         ; sending controll change status
	jsr	@tx_fifo_set

        mov.b   #1,r0l
	mov.b	@(setcnt,er3),r0l     ; uploading control change default number


        mov.b   @ccnum,r0h            ; uploading preset cc number
	add.b	r0h,r0l               ; plus offset preset number
	jsr	@tx_fifo_set

	mov.b	@(ports_01,er1),r0h
	btst	r2h,r0h	              ; checking the bit"n" sw status

	beq	__set_off
	mov.b	#h'7f,r0l	; set 127 value
	bra	__set_st
__set_off:
	mov.b	#h'00,r0l	; set 0 value
__set_st:
	jsr	@tx_fifo_set
        bra     _next_bit 

_program_cng:
	mov.b	@pgm,r0l        ; sending program change status
	jsr	@tx_fifo_set

        mov.b   #1,r0h
	mov.b	@(setcnt,er3),r0l      ; sending program change number
        mov.b   @pgnum,r0h
        dec.b    r0h
	add.b	r0h,r0l                ; plus offset preset number
	jsr	@tx_fifo_set

_next_bit:
        add.b	#1,r2h              ; counter plus 1
	cmp.b	#8,r2h              ; detecting full count
	bne	_check_bits

;>>>>> inner loop end

_next_port:
        mov.b  @port_counter,r0h
        add.b  r0h,r2h
        mov.b  r2h,@port_counter
        sub.b  r2h,r2h
        add.l  #4,er1
        cmp.l  #4,er1 
        beq    _dc_loop_2

;<<< outer loop end

	rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; sampling the analog inputs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sampling_00:

        sub.l   er1,er1
        sub.l   er2,er2
        sub.l   er3,er3            ; AD port counter (r3l)        

        mov.l   #adda,er2          ; vector addr of adah

_samp00_loop:
        bclr    #5,@adcsr
        mov.b   r3l,@adcsr        ; preset the AD control register
        bset    #5,@adcsr         ; start convert
_wait_samp00:
        btst    #7,@adcsr         ; wait for AD complete
        beq     _wait_samp00
        bclr    #7,@adcsr         ; clear the AD complete flag

        mov.b   @er2,r1l           ;uploading AD data
        extu.w  r1

        mov.w   r1,e1

        sub.w   r1,r1
        mov.b   @(samp_00,er3),r1l ;old AD data
        extu.w  r1


        add.w   r1,e1                   ;add all data and div by 2
        sub.w   r1,r1                   ;clr
        mov.b   #2,r1l
        divxu.b r1l,e1                  ;r1 contains meaned ad data
        mov.w   e1,r1

        mov.b   r1l,@(samp_00,er3)      ;stock the latest data

        inc.b   r3l                     ; AD port counter
        cmp.b   #8,r3l
        beq     samp00_end
        add.l   #2,er2
        cmp.l   #addd,er2               ; vector addr for addh
        ble     _samp00_loop
        mov.l   #adda,er2               ; vector addr for adah
        bra     _samp00_loop
samp00_end

        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sampling_01:

        sub.l   er1,er1
        sub.l   er2,er2
        sub.l   er3,er3            ; AD port counter (r3l)        

        mov.l   #adda,er2          ; vector addr of adah

_samp01_loop:
        bclr    #5,@adcsr
        mov.b   r3l,@adcsr        ; preset the AD control register
        bset    #5,@adcsr         ; start convert
_wait_samp01:
        btst    #7,@adcsr         ; wait for AD complete
        beq     _wait_samp01
        bclr    #7,@adcsr         ; clear the AD complete flag

        mov.b   @er2,r1l           ;uploading AD data
        extu.w  r1

        mov.w   r1,e1

        sub.w   r1,r1
        mov.b   @(samp_01,er3),r1l ;old AD data
        extu.w  r1


        add.w   r1,e1                   ;add all data and div by 2
        sub.w   r1,r1                   ;clr
        mov.b   #2,r1l
        divxu.b r1l,e1                  ;r1 contains meaned ad data
        mov.w   e1,r1

        mov.b   r1l,@(samp_01,er3)      ;stock the latest data

        inc.b   r3l                     ; AD port counter
        cmp.b   #8,r3l
        beq     samp01_end
        add.l   #2,er2
        cmp.l   #addd,er2               ; vector addr for addh
        ble     _samp01_loop
        mov.l   #adda,er2               ; vector addr for adah
        bra     _samp01_loop
samp01_end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sampling_02:

        sub.l   er1,er1
        sub.l   er2,er2
        sub.l   er3,er3            ; AD port counter (r3l)        

        mov.l   #adda,er2          ; vector addr of adah

_samp02_loop:
        bclr    #5,@adcsr
        mov.b   r3l,@adcsr        ; preset the AD control register
        bset    #5,@adcsr         ; start convert

_wait_samp02:
        btst    #7,@adcsr         ; wait for AD complete
        beq     _wait_samp02
        bclr    #7,@adcsr         ; clear the AD complete flag

        mov.b   @er2,r1l           ;uploading AD data
        extu.w  r1

        mov.w   r1,e1

        sub.w   r1,r1
        mov.b   @(samp_02,er3),r1l ;old AD data
        extu.w  r1


        add.w   r1,e1                   ;add all data and div by 2
        sub.w   r1,r1                   ;clr
        mov.b   #2,r1l
        divxu.b r1l,e1                  ;r1 contains meaned ad data
        mov.w   e1,r1

        mov.b   r1l,@(samp_02,er3)      ;stock the latest data

        inc.b   r3l                     ; AD port counter
        cmp.b   #8,r3l
        beq     samp02_end
        add.l   #2,er2
        cmp.l   #addd,er2               ; vector addr for addh
        ble     _samp02_loop
        mov.l   #adda,er2               ; vector addr for adah
        bra     _samp02_loop
samp02_end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sampling_03:

        sub.l   er1,er1
        sub.l   er2,er2
        sub.l   er3,er3            ; AD port counter (r3l)        

        mov.l   #adda,er2          ; vector addr of adah

_samp03_loop:
        bclr    #5,@adcsr
        mov.b   r3l,@adcsr        ; preset the AD control register
        bset    #5,@adcsr         ; start convert

_wait_samp03:
        btst    #7,@adcsr         ; wait for AD complete
        beq     _wait_samp03
        bclr    #7,@adcsr         ; clear the AD complete flag

        mov.b   @er2,r1l           ;uploading AD data
        extu.w  r1

        mov.w   r1,e1

        sub.w   r1,r1
        mov.b   @(samp_03,er3),r1l ;old AD data
        extu.w  r1


        add.w   r1,e1                   ;add all data and div by 2
        sub.w   r1,r1                   ;clr
        mov.b   #2,r1l
        divxu.b r1l,e1                  ;r1 contains meaned ad data
        mov.w   e1,r1

        mov.b   r1l,@(samp_03,er3)      ;stock the latest data

        inc.b   r3l                     ; AD port counter
        cmp.b   #8,r3l
        beq     samp03_end
        add.l   #2,er2
        cmp.l   #addd,er2               ; vector addr for addh
        ble     _samp03_loop
        mov.l   #adda,er2               ; vector addr for adah
        bra     _samp03_loop
samp03_end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; analog port check
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

analog_check:

       sub.l   er1,er1
       sub.l   er2,er2
       sub.l   er3,er3            ; AD port counter (r3l)

_ad_loop:
        mov.b   @(samp_00,er3),r1l       ;uploading AD data buffer
        extu.w  r1
        mov.w   r1,e1
        sub.w   r1,r1

        mov.b   @(samp_01,er3),r2l
        extu.w  r2
        mov.w   r2,e2
        sub.w   r2,r2
       
        mov.b   @(samp_02,er3),r1l
        extu.w  r1

        mov.b   @(samp_03,er3),r2l
        extu.w  r2

        add.w   e1,e2                   ;add all data and div by 4
        add.w   e2,r2
        add.w   r2,r1

        sub.w   r2,r2

        mov.b   #4,r2l
        divxu.b r2l,r1                  ;r1 contains meaned ad data

        sub.b   r1h,r1h

        mov.b   @(ad_old,er3),r1h
        mov.b   r1l,@(ad_old,er3)

        shlr.b  r1l                 ;right shift 8bit->7bit
        shlr.b  r1h                 ;right shift 8bit->7bit     

        cmp.b   r1h,r1l                 ;compare the AD data new,old
        beq     _next_ad
        bmi     _minus              
   

_plus:
        sub.b   r1h,r1l                 ; r1l-r1h -> r1l
        mov.b   #1,r1h
        cmp.b   r1h,r1l                  ; r1l>1 ?
        bge     _data_flag_on
        bra     _next_ad

_minus:
        sub.b   r1l,r1h                 ; r1h-r1l -> r1h
        mov.b   #1,r1l
        cmp.b   r1l,r1h                  ; r1h>1 ???????????
        bge     _data_flag_on
        bra     _next_ad

_data_flag_on:
        bset    r3l,r0h                 ; set the AD flag

_next_ad:
        inc.b   r3l                     ; AD port counter
        cmp.b   #8,r3l
        beq     _send_ad
        bra     _ad_loop

_send_ad:
        mov.b   #8,r3l
_send_loop:
        dec.b   r3l
        btst    r3l,r0h
        beq     _send_next
        bclr    r3l,r0h

        mov.b   @(ad_old,er3),r2l
        shlr.b  r2l                     ;right shift 8bit->7bit
        mov.b   @(ad_sent,er3),r2h
        cmp.b   r2h,r2l                 ;compare the MIDI data new,old
        beq     _send_next

_Data_out:
        mov.b   @cc,r0l
        jsr     @tx_fifo_set

        mov.b   @ccnum,r0l          ; cc number read
        cmp.b   #67,r0l             ; branch if cc number is greater than 67
        blt     gt_cc71
        mov.b   #111,r0l            ; ad/cc number preset to 101
        bra     count_ad

gt_cc71:
        mov.b   #101,r0l            ; ad/cc number preset to 111

count_ad:
        add.b   r3l,r0l
        jsr     @tx_fifo_set

        mov.b   @(ad_old,er3),r0l
        shlr.b  r0l                 ;right shift 8bit->7bit
        mov.b   r0l,@(ad_sent,er3)

adValue:
       jsr     @tx_fifo_set

_send_next:
       cmp.b   #0,r3l
       bne     _send_loop

       rts



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI transmit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

tx_midi_check:
	cmp.w	r6,e6		;r6: tx_top, e6: tx_end
        bne     _tx_exist
        rts
_tx_exist:
        btst    #7,@ssr                 ; test TRDE
        bne     _tx_seq
        rts
_tx_seq:
	sub.l	er1,er1
	mov.w	e6,r1
	mov.b	@(tx_fifo,er1),r0l
	mov.b	r0l,@tdr
	inc.w	#1,r1
	bclr	#1,r1h            ; tx buffer 512
	mov.w	r1,e6
        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI transmit buffer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

tx_fifo_set:
	push.l	er1
	sub.l	er1,er1
	mov.w	r6,r1
	mov.b	r0l,@(tx_fifo,er1) ; r0l contains tx data
	inc.w	#1,r6
	bclr	#1,r6h             ; tx buffer 512
	pop.l	er1
        rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI sw data Receive
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

rx_midi_check:
	cmp.w	r5,e5		;r5: rx_top, e5: rx_end
	beq	_skip
        bra     _rx_routine
_skip:   
        rts

_rx_routine:
	sub.l	er1,er1
	mov.w	e5,r1
	mov.b	@(rx_fifo,er1),r0h	; rx data -> [r0h]
	inc.w	#1,r1
	bclr	#1,r1h                 ;rx buffer 512
	mov.w	r1,e5	
        btst    #7,r0h          ;detecting status or data
        beq     after_second    ;jump when detecting data
	cmp.b	#h'F0,r0h
	bls	no_special
	rts
no_special:
	mov.b	r0h,@sb
	sub.b	r1l,r1l			; clear r1l -> @fsm
	and.b	#h'F0,r0h
	mov.b	#h'C0,r1h	
	cmp.b	r0h,r1h
	beq	mark_2byte
	mov.b	#h'D0,r1h	
	cmp.b	r0h,r1h
	beq	mark_2byte
	bra	mark_3byte
mark_2byte:
	bset	#is_2byte,r1l
	mov.b	r1l,@fsm
	rts
mark_3byte:
	bset	#is_3byte,r1l
	mov.b	r1l,@fsm
	rts
after_second:		; we have rx data in [r0h]
	mov.b	@fsm,r1l
	btst	#is_2byte,r1l
        beq     check_3byte
	mov.b	@sb,r0l
	jsr	@tx_fifo_set
	mov.b	r0h,r0l
	jsr	@tx_fifo_set
        rts
check_3byte:
	btst	#has_byte2,r1l
	bne	send_3byte
	mov.b	r0h,@byte2
	bset	#has_byte2,r1l
	mov.b	r1l,@fsm
        rts
send_3byte:
	mov.b	@sb,r0l
	jsr	@tx_fifo_set
	mov.b	@byte2,r0l
	jsr	@tx_fifo_set
	mov.b	r0h,r0l
	jsr	@tx_fifo_set
	bclr	#has_byte2,r1l
	mov.b	r1l,@fsm
_end_rx:
        rts



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;SCI init 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sci_init:
        mov.b   #b'00000000,r0l
        mov.b   r0l,@scr3
        mov.b   #b'00000000,r0l

;        mov.b   #15,r0l
;        mov.b   r0l,@brr               ; bitRateSet for 16MHz
        mov.b   #19,r0l
        mov.b   r0l,@brr               ; bitRateSet for 20MHz

        mov.w   #500,r0                  

_sci_wait:
        dec.w   #1,r0
        bne     _sci_wait


	mov.b	#b'00000010,r0l        ; TXD enable
	mov.b	r0l,@pmr1 

        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;Midi Start 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

midi_start:
        mov.b   #b'01110000,r0l         ; receive only 10100000 = Transmit Only
        mov.b   r0l,@scr3


        andc    #b'01111111,ccr         ; interrupt enable

	rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;Stack and work RAM init 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
memory_set:

       mov.l   #h'f780,er2             ; ram start addr for 3664 
       mov.w   #h'0700,r1              ; clear <2k bites

       mov.b   #0,r0l

_ram_clear:
        mov.b   r0l,@er2
        inc.l   #1,er2
        dec.w   #1,r1
        bne     _ram_clear
        sub.l	er4,er4
	sub.l	er5,er5
	sub.l	er6,er6
	rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Input channels initialization
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

input_enable:


	mov.b	#b'00000000,r0l

	mov.b	r0l,@pcr5
	mov.b	r0l,@pcr8
        mov.b   r0l,@pcr1
        mov.b   r0l,@pcr7

        jsr     @wait_10msec
	rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Timer / Counter Routines 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


wait_500msec:
	push.l	er1
	push.l	er2
        mov.l   #500,er1
_wait_1:
        jsr     @wait_1msec
        sub.l   #1,er1
        bne     _wait_1
	pop.l	er2
	pop.l	er1
        rts

wait_100msec:
	push.l	er1
	push.l	er2
        mov.l   #100,er1
_wait_2:
        jsr     @wait_1msec
        sub.l   #1,er1
        bne     _wait_2
	pop.l	er2
	pop.l	er1
        rts

wait_10msec:
	push.l	er1
	push.l	er2
        mov.l  #10,er1
_wait_3:
        jsr    @wait_1msec
        sub.l  #1,er1
        bne    _wait_3
        pop.l  er2
        pop.l  er1
        rts

wait_1msec:
        mov.l   #2048,er2
_wait_4:
        sub.l   #1,er2
        bne     _wait_4
        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Get configuration from input port
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

midi_channel_set:

	mov.b	@pdr1,r1l        ;loading the port data
        shlr.b  r1l               ;shift data from msb 4bit to the lsb 4 bit
        shlr.b  r1l 
        shlr.b  r1l 
        shlr.b  r1l  

	and.b	#h'0F,r1l         ;msb 4bit clear

	cmp.b   #0,r1l            ;zero detect
        bne     ch_out
        
        mov.b   #10,r1l           ;preset value 10

ch_out:

        dec.b   r1l     

	mov.b	r1l,@midch

        rts

control_number_set:

	mov.b	@pdr7,r3l        ;loading port data
        and.b   #b'01110000,r3l   ;msb reset to zero

	sub.w	r2,r2             ;clear
	mov.b	r3l,r2l
       
	and.b	#h'0F,r3l         ;clear msb 4bit,  r3l contains BCD lower 4bits  

        and.b   #h'F0,r2l         ;clear lsb 4bit,  r2l contains BCD upper 4bits
        shlr.b  r2l               ;shift data from msb 4bit to the lsb 4 bit
        shlr.b  r2l 
        shlr.b  r2l 
        shlr.b  r2l  

	mov.b	#10,r1l           ;loading value #10
        mulxu.b r2l,r1            ;multiplex by 10
	add.b	r1l,r3l           ;binary code

        cmp.b   #0, r3l             ;detecting zero
        beq     preset_47
        inc.b   r3l               ;offset +1 the data starts from 11,21,31,41,51,61,71
        bra     ccstatus_out

preset_47:  
        mov.b   #47,r3l            ;preset #47
        bra     ccstatus_out

ccstatus_out:

        dec.b   r3l

	mov.b	r3l,@ccnum
	mov.b	#h'B0,r1h           ;B0 = control change status
        mov.b   @midch,r2l
	or.b	r2l,r1h              ;plus midi ch number info 
	mov.b	r1h,@cc             ;midi status info = BnH

pgstatus_out:

        mov.b   #0,r3l              ; start from pgm number zero = #1

send_pgm:
	mov.b	r3l,@pgnum
	mov.b	#h'C0,r1h           ;C0 = program change status
        mov.b   @midch,r2l
	or.b	r2l,r1h             ;plus midi ch number info 
	mov.b	r1h,@pgm            ;midi status info = CnH

	rts



switch_preset:

	mov.b	@pdr1,r1l        ;loading the port data

	and.b	#b'00000011,r1l         ;msb 6bit clear

	mov.b	r1l,@swptn

	rts



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; set the number from look up table
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

load_sw_num:

        mov.b   @swptn,r3l
        cmp.b     #3,r3l
        beq        sw_01
        cmp.b     #0,r3l
        beq        sw_00
        rts

sw_00:

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

num_data_load00:
 
        mov.b   @(swnum00,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load00

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

sw_data_load00:

        mov.b   @(swaddr00,er0), r1h
        mov.b   r1h, @(setsw,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     sw_data_load00

        rts

sw_01:

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

num_data_load06:
 
        mov.b   @(swnum06,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load06

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

sw_data_load06:

        mov.b   @(swaddr06,er0), r1h
        mov.b   r1h, @(setsw,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     sw_data_load06


        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

load_sw_num2:

        mov.b   @swptn,r3l
        cmp.b     #1,r3l
        beq        sw_03
        cmp.b     #2,r3l
        beq        sw_02
        rts

sw_02:

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

num_data_load02:
 
        mov.b   @(swnum02,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load02

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

sw_data_load02:

        mov.b   @(swaddr02,er0), r1h
        mov.b   r1h, @(setsw,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     sw_data_load02

        rts

sw_03:

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

num_data_load03:
 
        mov.b   @(swnum03,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load03

        sub.l   er0,er0
        sub.l   er1,er1
        sub.l   er2,er2

sw_data_load03:

        mov.b   @(swaddr03,er0), r1h
        mov.b   r1h, @(setsw,er0)
        add.l   #1,er0

        cmp.l   #31,er0

        ble     sw_data_load03

              
        rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Exception handling routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

int_scr3:
	
	push.l	er3
	bclr	#6,@scr3		;Desable Receive interrupt
	mov.b	@rdr,r3h		;get midi rx
	btst	#5,@ssr
	bne	rx_err			;jump if error has occured

	mov.b	r3h,@(rx_fifo,er5)	;rx to fifo
	inc.w	#1,r5
	bclr	#1,r5h
	bra     rx_ok


rx_err:

	mov.b	@ssr,r3l
	mov.b	#H'80,r3l
	mov.b	r3l,@ssr		;clearing the error

rx_ok:
	bset	#6,@scr3		;enable receive int
	pop.l	er3
	rte				


        .end



