;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                
;    Midi Control Signal Generator for AudioHologram Ver4.1
; 
;    2013 12/16 by yasuski 
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
; what's new on Ver.4.1
;
;  checking the mode by btst #0 of @pdat1on start up routine.     
;  mode1 is the normal (running 31250 baud rate with midi mixer)
;  mode2 is the 2ch baud rate converter (receiving 31250bps and transmitting 38400bps)
;
; what's new on Ver.4.0
; 
; 1) activate the SCI1 output for converting the baud rate between 
;    31250 and 38400baud.
; 2) add the data output buffers for @tx_fifo and @tx2_fifo 
; 3) reduce the buffer size on @tx_fifo and @tx2_fifo from 1024 to 512bites
; 4) reconstruct the digital and analog sampling routine
; 5) remove the midi receive signal mixer on baud rate converter mode.
; 6) received midi signal on @tx2_fifo are transfered the baud rate to 38400
;
; what's new on Ver.3.1
;
; 1) add the midi output filter for stopping the buggy data streams
;
;
; what's new on Ver.3.0
;
; 1) add the 4 set of AD sampling data buffers for meaning the AD data
; 2) separate the sampling and ad data output routine
; 3) remove the wait_10ms on ad data output routine.
;
; what's new on Ver.2.8
;
; 1) Fixed the bug on PGM change preset shifting routine by sw #30
;
;
; what's new on Ver.2.7
;
; 1) change the digital check routine. The newer version sens the ports indivisually.
; 2) add the reset routine before ad convert start.
;
; what's new on Ver.2.6
;
; 1) change the data resolution on AD part from 7bit to 8bit. the data will be
; shifted to 7bit resolution before tx_fifo.  
;
; what's new on Ver.2.5
;  
; 1) add the offset detector for the program change presets.
; The preset number on port6 starts from #07x can change the program
; change bank groups in the realtime. It automatically calc the
; pgm bank size and align the pgm numbers. Although the system 
; requires the binary input ports for controlling the pgm change 
; grouping address. CAUTION! The ports only accept the BCD cords.
;
; 2) change the waiting time from 500ms to 10ms on the 
; start up routine
;
; 3) change the preset number from #100 to #001 when the 
; preset number input detect the value zero.
;
; 4)the switch #30 changes the pgm number group when the pgm preset 
; numbers are over #070
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	.include	"yasuski2.inc"

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


        .section vector,data,locate=h'000000
        .data.l start

        .org    h'000050
        .data.l int_wdt

        .org    h'0000d0
        .data.l int_rx_error
        .data.l int_rx_full
	.org	h'0000e0
	.data.l	int_rx2_error
	.data.l	int_rx2_full


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Port addresses in ROM area
;;;; On/Off 8bit x 4 ports = 32      -> port1~4
;;;; mapped to 
;;;; cc #31~62
;;;;
;;;; A/D 8in                         -> port7 
;;;; 7bit resolution / mapped to 
;;;; cc #101~108
;;;; 
;;;;
;;;; MIDI ch set                     -> port5 
;;;; MIDI program change set         -> port6
;;;; MIDI control change set         -> portA
;;;; switch pattern configuration    -> portB
;;;; switch status out for sw#17~32  -> port8
;;;; output when pgm signal detected -> port8 bit#5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	.section rom,data,locate=h'2000

ptaddr:     .data.l	pdat1,pdat2,pdat3,pdat4,pdat5,pdat6,pdat8,pdatA,pdatB
ptdir:      .data.l	pdir1,pdir2,pdir3,pdir4,pdir5,pdir6,pdir8,pdirA,pdirB



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'0fdf10  ;for 3052


ports_01	.res.l          9

bank_counter   .res.l   1
cksw           .res.l   1

setcnt  .res.b         32         ;switch numbers assign matrix 32
 
setsw   .res.b         32         ;switch status preset for cc/pgm 8*4 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

outputs        .res.b   1
counter_64     .res.b   1
swtrig         .res.b   1
pgm_flag       .res.b   1

data_flag      .res.b   1
sw_status8      .res.b   1
bit_counter     .res.b   1

dummy           .res.b   1

sb	  .res.b	1
sb2	  .res.b	1
fsm	  .res.b	1
fsm2	  .res.b	1
byte2	  .res.b	1
byte2_2   .res.b	1

offset_sw      .res.b	1
offset_flag    .res.b	1
offset_numbers .res.b   1
ext_port       .res.b   1

tx_buf     .res.b   1
tx2_buf     .res.b   1

          .org          h'0fe440
rx_fifo   .res.b             512
          .org          h'0fe640
rx2_fifo  .res.b             512
          .org          h'0fe840
tx_fifo   .res.b             512
          .org          h'0fea40
tx2_fifo   .res.b            512





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; register allocation
;;; er0 : temporary  (for midi tx buffer)
;;; er1 : temporary
;;; er2 : temporary
;;; er3 : temporary
;;; er4 : another receive buffer pointer (e4: end, r4: top)
;;; er5 : receive buffer pointer(e5: end, r5: top)
;;; er6 : transmit buffer pointer(e6: end,r6: top)
;;; er7 : stack pointer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Main 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


        .section program,code,locate=h'000100
start:
      mov.l   #h'0fff0f,er7          ; stack pointer set
      jsr     @memory_set            ; Work RAM clear and FIFO pointer

      jsr     @input_enable	     ; Port init

      mov.b   @pdat1,r1l

      btst    #0,r1l
      beq     converter
      bra     normal

converter:

      jsr     @wait_10msec          ; Wait  
      jsr     @sci_init              ; SCI initialize
      jsr     @wait_10msec          ; Wait
      jsr     @sci_init2             ; SCI initialize
      jsr     @wait_10msec          ; Wait

      jsr     @wdtinit

      jsr     @midi_channel_set      ; get configuration
      jsr     @control_number_set
      jsr     @switch_preset
      jsr     @load_sw_num          ; loading switch numbers  
      jsr     @control_out          ; output the control signal from port8

      jsr     @midi_start           ; MIDI tx/rx start
 
loop1:


      jsr     @rx_midi_check
      jsr     @tx_midi_check2

      jsr     @sampling_00
      jsr     @sampling_01
      jsr     @sampling_02
      jsr     @sampling_03

      jsr     @analog_check
      jsr     @tx_midi_check

      jsr     @digital_check
      jsr     @tx_midi_check

      jsr     @wdt_start
      jsr     @program_change_signal_check
      jsr     @pgm_number_set

      jmp     @loop1

normal:

      jsr     @wait_10msec          ; Wait  
      jsr     @sci_init_n              ; SCI initialize
      jsr     @wait_10msec          ; Wait
      jsr     @sci_init2_n             ; SCI initialize
      jsr     @wait_10msec          ; Wait

      jsr     @wdtinit


      jsr     @midi_channel_set      ; get configuration
      jsr     @control_number_set
      jsr     @switch_preset
      jsr     @load_sw_num          ; loading switch numbers  
      jsr     @control_out          ; output the control signal from port8

      jsr     @midi_start           ; MIDI tx/rx start
 
loop2:


      jsr     @rx_midi_check_n

      jsr     @sampling_00
      jsr     @sampling_01
      jsr     @sampling_02
      jsr     @sampling_03

      jsr     @analog_check
      jsr     @tx_midi_check_n

      jsr     @digital_check
      jsr     @tx_midi_check_n

      jsr     @wdt_start
      jsr     @program_change_signal_check
      jsr     @pgm_number_set

      jmp     @loop2



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; 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	@pdat1,r3h               ; r0h is current port data

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

        mov.b   r2l,@sw_status8

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

        bra _check_bits

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

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

        mov.b   r2l,@sw_status8

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

        bra _check_bits

_dc_loop_3:
	
	mov.b	@pdat3,r3h               ; r0h is current port data

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

        mov.b   r2l,@sw_status8

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

        bra _check_bits

_dc_loop_4:
	
	mov.b	@pdat4,r3h               ; r0h is current port data

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

        mov.b   r2l,@sw_status8

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

        bra _check_bits

;>>>>> inner loop top

_check_bits:

        mov.b   @sw_status8,r2l	

        mov.b   @bit_counter,r2h
	btst	r2h,r2l                 ; checking the update flag

	beq	_next_bit

        sub.l   er3,er3

        mov.b   @bit_counter,r2h
        mov.b   r2h,r3l

        mov.b   @port_counter,r2h
        add.b   r2h,r3l

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


_control_cng:

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

	mov.b	@(setcnt,er3),r2l     ; uploading control change default number


        mov.b   @ccnum,r2h            ; uploading preset cc number
	add.b	r2h,r2l               ; plus offset preset number
        mov.b   r2l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	@(ports_01,er1),r2l

        mov.b   @bit_counter,r2h
	btst	r2h,r2l	              ; checking the bit"n" sw status

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

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

	mov.b	@(setcnt,er3),r2l      ; sending program change number
        mov.b   @pgnum,r2h
        dec.b    r2h
	add.b	r2h,r2l                ; plus offset preset number
        mov.b   r2l,@tx_buf
	jsr	@tx_fifo_set

_next_bit:
        mov.b   @bit_counter,r2h
        add.b	#1,r2h              ; counter plus 1
        mov.b   r2h,@bit_counter

	cmp.b	#8,r2h              ; detecting full count
	bne	_check_bits

;>>>>> inner loop end

_next_port:
        mov.b  @port_counter,r3h
        add.b  r3h,r2h
        mov.b  r2h,@port_counter

        sub.b  r2h,r2h

        add.l  #4,er1
        cmp.l  #4,er1 
        beq    _dc_loop_2
        cmp.l  #8,er1
        beq    _dc_loop_3
        cmp.l  #12,er1
        beq    _dc_loop_4

;<<< 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   #adah,er2          ; vector addr of adah

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

        bclr    #7,@adctrl         ; 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   #addh,er2               ; vector addr for addh
        ble     _samp00_loop
        mov.l   #adah,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   #adah,er2          ; vector addr of adah

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

_wait_samp01:
        btst    #7,@adctrl         ; wait for AD complete
        beq     _wait_samp01

        bclr    #7,@adctrl         ; 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                  ;e1 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   #addh,er2               ; vector addr for addh
        ble     _samp01_loop
        mov.l   #adah,er2               ; vector addr for adah
        bra     _samp01_loop
samp01_end

        rts

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

sampling_02:

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

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

_samp02_loop:
        bclr    #5,@adctrl
        mov.b   r3l,@adctrl        ; preset the AD control register
        bset    #5,@adctrl         ; start convert
_wait_samp02:
        btst    #7,@adctrl         ; wait for AD complete
        beq     _wait_samp02

        bclr    #7,@adctrl         ; 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                  ;e1 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   #addh,er2               ; vector addr for addh
        ble     _samp02_loop
        mov.l   #adah,er2               ; vector addr for adah
        bra     _samp02_loop
samp02_end

        rts

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

sampling_03:

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

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

_samp03_loop:
        bclr    #5,@adctrl
        mov.b   r3l,@adctrl        ; preset the AD control register
        bset    #5,@adctrl         ; start convert
_wait_samp03:
        btst    #7,@adctrl         ; wait for AD complete
        beq     _wait_samp03

        bclr    #7,@adctrl         ; 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                  ;e1 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   #addh,er2               ; vector addr for addh
        ble     _samp03_loop
        mov.l   #adah,er2               ; vector addr for adah
        bra     _samp03_loop
samp03_end

        rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; 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,r1h                 ; set the AD flag
        mov.b   r1h,@data_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
       
        mov.b   @data_flag,r1h

        btst    r3l,r1h
        beq     _send_next
        bclr    r3l,r1h

        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,r1l

        mov.b   r1l,@tx_buf

        jsr     @tx_fifo_set

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

gt_cc71:
        mov.b   #109,r1l            ; ad/cc number preset to 109

count_ad:
        add.b   r3l,r1l

        mov.b   r1l,@tx_buf

        jsr     @tx_fifo_set

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

adValue:
        mov.b   r1l,@tx_buf

        jsr     @tx_fifo_set

_send_next:
       cmp.b   #0,r3l
       bne     _send_loop


       rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; read pgm number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

pgm_number_set:       

        sub.w   r3,r3
        mov.b   @pdat6,r3l        ;loading port data

        cmp.b   #b'01110000,r3l           ;preset #70~79 calls the preset number offset.      
        bge     pgm_sw_assigned
        
        mov.b   @pgm_memory,r3h
        cmp.b   r3h,r3l
        bne     load_number

        rts

pgm_sw_assigned:
        mov.b   @pdat4,r2h
        and.b   #b'00100000,r2h    ;trigger assigned to the switch matrix #30
        mov.b   @offset_sw,r2l
        mov.b   r2h,@offset_sw
        cmp.b   r2l,r2h            ;detect the difference
        bne     add_offset

        mov.b   @pgm_memory,r3h
        cmp.b   r3h,r3l
        bne     load_number

        rts

add_offset:
        btst    #5,r2h             ;detect the switched "on"
        bne     offset_enable
        sub.b   r2l,r2l
        mov.b   r2l,@offset_flag        ;off the flag
        bra     load_number
offset_enable:
        mov.b   #b'00000001,r2l    
        mov.b   r2l,@offset_flag        ;on the flag

load_number:
        mov.b   r3l,@pgm_memory

	sub.w	r2,r2             ;clear
	mov.b	r3l,r2l

        and.b   #b'01111111,r3l   ;msb reset to zero, because port6 has 7bit inputs
       
	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 coded output

        cmp.b   #0,r3l            ;detecting input zero
        beq     offset_00

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;optional offset detector;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        cmp.b   #70,r3l           ;preset number 70~79 call the offset generator routine.      
        bge     offset_gen
        bra     pgstatus_out


offset_00:
        mov.b   #1,r3l            ;when the input number is zero, preset #1
        bra     pgstatus_out



offset_gen:
        sub.w   r2,r2               ;clear 
        mov.b   @outputs,r3h        ;upload the program change sw group status and calc the magnitude on r2l
        mov.b   @ext_port,r2h
        add.b   r2h,r3h
        cmp.b   #0,r3h
        beq     pgstatus_out        ;branch to pgm output
        btst    #0,r3h
        beq     port_B
port_A: inc.b   r2l
port_B: btst    #1,r3h
        beq     port_C
        inc.b   r2l
port_C: btst    #2,r3h
        beq     port_D
        inc.b   r2l
port_D: btst    #3,r3h
        beq     port_E
        inc.b   r2l
port_E: btst    #4,r3h
        beq     port_F
        inc.b   r2l
port_F: btst    #5,r3h
        beq     port_G
        inc.b   r2l
port_G: btst    #6,r3h
        beq     port_H
        inc.b   r2l
port_H: btst    #7,r3h
        beq     pgstatus_out
        inc.b   r2l

calc_offset:
        sub.b   r3h,r3h
        sub.b   r2h,r2h
        mov.b   #4,r3h        
        mulxu.b r3h,r2

        sub.b   r2h,r2h

        mov.b   r2l,@offset_numbers        ;keep the offset numbers

        cmp.b   #70,r3l
        beq     offset_01
        cmp.b   #71,r3l
        beq     offset_02
        cmp.b   #72,r3l
        beq     offset_03
        cmp.b   #73,r3l
        beq     offset_04
        cmp.b   #74,r3l
        beq     offset_05
        cmp.b   #75,r3l
        beq     offset_06
        cmp.b   #76,r3l
        beq     offset_07
        cmp.b   #77,r3l
        beq     offset_08
        cmp.b   #78,r3l
        beq     offset_09
        cmp.b   #79,r3l
        beq     offset_10

        bra     pgstatus_out
                
offset_01:
        mov.b   #2,r3l             ;preset #70 has the starting numbers from #002
        mov.b   @offset_flag,r2h   ;sw #30 set the second stage pgm numbers
        btst    #0,r2h
        bne     oe_detected_01
        bra     pgstatus_out
oe_detected_01:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out


offset_02:
        mov.b   #2,r3l
        add.b   r2l,r3l            ;preset #71 is next group of the pgm change numbers
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_02
        bra     pgstatus_out
oe_detected_02:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out



offset_03:
        mov.b   #2,r3l
        mov.b   #2,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_03
        bra     pgstatus_out
oe_detected_03:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out


offset_04:
        mov.b   #2,r3l
        mov.b   #3,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_04
        bra     pgstatus_out
oe_detected_04:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

offset_05:
        mov.b   #2,r3l
        mov.b   #4,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_05
        bra     pgstatus_out
oe_detected_05:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

offset_06:
        mov.b   #2,r3l
        mov.b   #5,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_06
        bra     pgstatus_out
oe_detected_06:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

offset_07:
        mov.b   #2,r3l
        mov.b   #6,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_07
        bra     pgstatus_out
oe_detected_07:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

offset_08:
        mov.b   #2,r3l
        mov.b   #7,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_08
        bra     pgstatus_out
oe_detected_08:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

offset_09:
        mov.b   #2,r3l
        mov.b   #8,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_09
        bra     pgstatus_out
oe_detected_09:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

offset_10:
        mov.b   #2,r3l
        mov.b   #9,r3h
        mulxu.b r3h,r2
        add.b   r2l,r3l            ;
        mov.b   @offset_flag,r2h
        btst    #0,r2h
        bne     oe_detected_10
        bra     pgstatus_out
oe_detected_10:
        mov.b   @offset_numbers,r3h    
        add.b   r3h,r3l
        bra     pgstatus_out

;;;;;;;;;;;;;;;;;;;;;end of the optional offset detector;;;;;;;;;;;;;;;;


pgstatus_out:

        dec.b   r3l                 ; fix the 2nd bite offset on midi

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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; wdt start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wdt_start:
        sub.w   r3,r3
        mov.b   @pgm_flag,r3l
        btst    #0,r3l
        bne     wdt_run
        rts 

wdt_run: 
        bclr    #0,r3l
        mov.b   r3l,@pgm_flag

        sub.w   r3,r3

	mov.b	#b'00000000,r3l
        mov.b   r3l,@counter_64

        mov.b   @tcsr,r3l
        mov.w   #h'a507,r3                 ;clear counter
        mov.w   r3,@tcsr

        nop
        nop
        nop
        nop
        nop

        mov.b   @tcsr,r3l
        mov.w   #h'a527,r3                 ;start counter
        mov.w   r3,@tcsr
        nop
        nop
        nop
        nop
        nop

        rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; receive program change signal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

program_change_signal_check:
        sub.w   r3,r3
        mov.b   @swtrig,r3h
        btst    #0,r3h
        bne     signal_on
        rts

signal_on:   
        mov.b   @pdat8,r3l              ;uploading the data on port8
	bset	#4,r3l                  ;signal on
        mov.b   r3l,@pdat8              ;from port8   

        jsr     @wait_100msec            ;pulse width = 100ms

        bclr    #4,r3l                  ;signal off
        mov.b   r3l,@pdat8              ;from port8

        bclr    #0,r3h                  ;reset preset_flag
        mov.b   r3h,@swtrig
        rts



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

tx_midi_check:

	cmp.w	r6,e6		;r6: tx_top, e6: tx_end
        bne     _tx_exist
        rts
_tx_exist:
        btst    #7,@ssr0                 ; test TRDE
        bne     _tx_seq
        rts

_tx_seq:

	sub.l	er1,er1
	mov.w	e6,r1
	mov.b	@(tx_fifo,er1),r3l
	mov.b	r3l,@tdr0
	bclr	#7,@ssr0
	inc.w	#1,r1
	bclr	#1,r1h            ; tx buffer 512
	mov.w	r1,e6

        rts

tx_midi_check2:

	cmp.w	r0,e0		;r0: tx_top, e0: tx_end
        bne     _tx_exist2
        rts

_tx_exist2:
        btst    #7,@ssr1                 ; test TRDE
        bne     _tx_seq2
        rts
_tx_seq2:
	sub.l	er1,er1
	mov.w	e0,r1
	mov.b	@(tx2_fifo,er1),r3l
	mov.b	r3l,@tdr1
	bclr	#7,@ssr1
	inc.w	#1,r1
	bclr	#1,r1h            ; tx buffer 512
	mov.w	r1,e0

        rts

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

tx_fifo_set:
	push.l	er1
	sub.l	er1,er1

	mov.w	r6,r1
        mov.b   @tx_buf,r2l
	mov.b	r2l,@(tx_fifo,er1) ; r2l contains tx data
	inc.w	#1,r6
	bclr	#1,r6h             ; tx buffer 512

	pop.l	er1
        rts

tx2_fifo_set:
	push.l	er1
	sub.l	er1,er1

	mov.w	r0,r1
        mov.b   @tx2_buf,r2l
	mov.b	r2l,@(tx2_fifo,er1) ; r2l contains tx data
	inc.w	#1,r0
	bclr	#1,r0h             ; tx buffer 512
	pop.l	er1

        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI transmit Normal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

tx_midi_check_n:

	cmp.w	r6,e6		;r6: tx_top, e6: tx_end
        bne     _tx_exist
        rts
_tx_exist_n:
        btst    #7,@ssr0                 ; test TRDE
        bne     _tx_seq
        rts

_tx_seq_n:

	sub.l	er1,er1
	mov.w	e6,r1
	mov.b	@(tx_fifo,er1),r3l
	mov.b	r3l,@tdr0
	bclr	#7,@ssr0
	inc.w	#1,r1
	bclr	#1,r1h            ; tx buffer 512
	mov.w	r1,e6

        rts


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

tx_fifo_set_n:
	push.l	er1
	sub.l	er1,er1

	mov.w	r6,r1
        mov.b   @tx_buf,r2l
	mov.b	r2l,@(tx_fifo,er1) ; r2l contains tx data
	inc.w	#1,r6
	bclr	#1,r6h             ; tx buffer 512

	pop.l	er1
        rts

tx2_fifo_set_n:
	push.l	er1
	sub.l	er1,er1

	mov.w	r0,r1
        mov.b   @tx2_buf,r2l
	mov.b	r2l,@(tx2_fifo,er1) ; r2l contains tx data
	inc.w	#1,r0
	bclr	#1,r0h             ; tx buffer 512
	pop.l	er1

        rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI Receive
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rx_midi_check:



	cmp.w	r4,e4		;r4: rx2_top, e4: rx2_end
	beq	_next_rx
	sub.l	er1,er1
	mov.w	e4,r1           ;rx data address
	mov.b	@(rx2_fifo,er1),r3h	; rx data -> [r3h]
	inc.w	#1,r1
	bclr	#1,r1h          ;rx buffer 512
	mov.w	r1,e4	
        btst    #7,r3h          ; detecting status or data / msb => inverting
        beq     after_second2   ; jump when msb is zero
	cmp.b	#h'F0,r3h       ; channel voice data < 11110000 = sysex
	bls	no_special2
	bra	_next_rx
        
no_special2:
	mov.b	r3h,@sb2	; keep status byte
	mov.b	#0,r1l			; clear r1l -> @fsm
	and.b	#h'F0,r3h       ; masking the midi ch data
	mov.b	#h'C0,r1h	; uploading program change status
	cmp.b	r3h,r1h         ; detecting program change
	beq	mark_2byte2
	mov.b	#h'D0,r1h	; uploading control change status
	cmp.b	r3h,r1h         ; detecting control change
	beq	mark_2byte2
	bra	mark_3byte2
mark_2byte2:
	bset	#is_2byte,r1l   ; bit set 10000000
	mov.b	r1l,@fsm2
	bra	_next_rx
mark_3byte2:
	bset	#is_3byte,r1l   ; bit set 01000000
	mov.b	r1l,@fsm2
	bra	_next_rx
after_second2:	         	; we have rx data in [r3h]
	mov.b	@fsm2,r1l
	btst	#is_2byte,r1l   ; 
        beq     check_3byte2

	mov.b	@sb2,r3l        ; send pgm status
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	r3h,r3l         ; send value
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

        sub.b   r3l,r3l
        bset    #0,r3l
        mov.b   r3l,@pgm_flag

	bra	_next_rx
check_3byte2:
	btst	#has_byte2,r1l
	bne	send_3byte2
	mov.b	r3h,@byte2_2
	bset	#has_byte2,r1l
	mov.b	r1l,@fsm2
	bra	_next_rx
send_3byte2:
	mov.b	@sb2,r3l        ;status byte
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	@byte2_2,r3l     ;cc number
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	r3h,r3l
        mov.b   r3l,@tx_buf         
	jsr	@tx_fifo_set

	bclr	#has_byte2,r1l
	mov.b	r1l,@fsm2

_next_rx:
	cmp.w	r5,e5		;r5: rx_top, e5: rx_end
	beq	_end_rx
	sub.l	er1,er1
	mov.w	e5,r1
	mov.b	@(rx_fifo,er1),r3h	; rx data -> [r3h]
	inc.w	#1,r1
	bclr	#1,r1h                 ;rx buffer 512
	mov.w	r1,e5	
        btst    #7,r3h          ;detecting status or data
        beq     after_second    ;jump when detecting data
	cmp.b	#h'F0,r3h
	bls	no_special

	rts

no_special:
	mov.b	r3h,@sb
	sub.b	r1l,r1l			; clear r1l -> @fsm
	and.b	#h'F0,r3h
	mov.b	#h'C0,r1h	
	cmp.b	r3h,r1h
	beq	mark_2byte
	mov.b	#h'D0,r1h	
	cmp.b	r3h,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 [r3h]
	mov.b	@fsm,r1l
	btst	#is_2byte,r1l
        beq     check_3byte
	mov.b	@sb,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx2_fifo_set

	mov.b	r3h,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx2_fifo_set

        rts

check_3byte:
	btst	#has_byte2,r1l
	bne	send_3byte
	mov.b	r3h,@byte2
	bset	#has_byte2,r1l
	mov.b	r1l,@fsm

        rts

send_3byte:
	mov.b	@sb,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx2_fifo_set

	mov.b	@byte2,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx2_fifo_set

	mov.b	r3h,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx2_fifo_set

	bclr	#has_byte2,r1l
	mov.b	r1l,@fsm
_end_rx:

        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI ReceiveNormal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rx_midi_check_n:



	cmp.w	r4,e4		;r4: rx2_top, e4: rx2_end
	beq	_next_rx
	sub.l	er1,er1
	mov.w	e4,r1           ;rx data address
	mov.b	@(rx2_fifo,er1),r3h	; rx data -> [r3h]
	inc.w	#1,r1
	bclr	#1,r1h          ;rx buffer 512
	mov.w	r1,e4	
        btst    #7,r3h          ; detecting status or data / msb => inverting
        beq     after_second2   ; jump when msb is zero
	cmp.b	#h'F0,r3h       ; channel voice data < 11110000 = sysex
	bls	no_special2
	bra	_next_rx
        
no_special2_n:
	mov.b	r3h,@sb2	; keep status byte
	mov.b	#0,r1l			; clear r1l -> @fsm
	and.b	#h'F0,r3h       ; masking the midi ch data
	mov.b	#h'C0,r1h	; uploading program change status
	cmp.b	r3h,r1h         ; detecting program change
	beq	mark_2byte2
	mov.b	#h'D0,r1h	; uploading control change status
	cmp.b	r3h,r1h         ; detecting control change
	beq	mark_2byte2
	bra	mark_3byte2
mark_2byte2_n:
	bset	#is_2byte,r1l   ; bit set 10000000
	mov.b	r1l,@fsm2
	bra	_next_rx
mark_3byte2_n:
	bset	#is_3byte,r1l   ; bit set 01000000
	mov.b	r1l,@fsm2
	bra	_next_rx
after_second2_n:	         	; we have rx data in [r3h]
	mov.b	@fsm2,r1l
	btst	#is_2byte,r1l   ; 
        beq     check_3byte2

	mov.b	@sb2,r3l        ; send pgm status
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	r3h,r3l         ; send value
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

        sub.b   r3l,r3l
        bset    #0,r3l
        mov.b   r3l,@pgm_flag

	bra	_next_rx
check_3byte2_n:
	btst	#has_byte2,r1l
	bne	send_3byte2
	mov.b	r3h,@byte2_2
	bset	#has_byte2,r1l
	mov.b	r1l,@fsm2
	bra	_next_rx
send_3byte2_n:
	mov.b	@sb2,r3l        ;status byte
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	@byte2_2,r3l     ;cc number
        mov.b   r3l,@tx_buf
	jsr	@tx_fifo_set

	mov.b	r3h,r3l
        mov.b   r3l,@tx_buf         
	jsr	@tx_fifo_set

	bclr	#has_byte2,r1l
	mov.b	r1l,@fsm2

_next_rx_n:
	cmp.w	r5,e5		;r5: rx_top, e5: rx_end
	beq	_end_rx
	sub.l	er1,er1
	mov.w	e5,r1
	mov.b	@(rx_fifo,er1),r3h	; rx data -> [r3h]
	inc.w	#1,r1
	bclr	#1,r1h                 ;rx buffer 512
	mov.w	r1,e5	
        btst    #7,r3h          ;detecting status or data
        beq     after_second    ;jump when detecting data
	cmp.b	#h'F0,r3h
	bls	no_special

	rts

no_special_n:
	mov.b	r3h,@sb
	sub.b	r1l,r1l			; clear r1l -> @fsm
	and.b	#h'F0,r3h
	mov.b	#h'C0,r1h	
	cmp.b	r3h,r1h
	beq	mark_2byte
	mov.b	#h'D0,r1h	
	cmp.b	r3h,r1h
	beq	mark_2byte
	bra	mark_3byte
mark_2byte_n:
	bset	#is_2byte,r1l
	mov.b	r1l,@fsm

	rts

mark_3byte_n:
	bset	#is_3byte,r1l
	mov.b	r1l,@fsm

	rts

after_second_n:		; we have rx data in [r3h]
	mov.b	@fsm,r1l
	btst	#is_2byte,r1l
        beq     check_3byte
	mov.b	@sb,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx_fifo_set

	mov.b	r3h,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx_fifo_set

        rts

check_3byte_n:
	btst	#has_byte2,r1l
	bne	send_3byte
	mov.b	r3h,@byte2
	bset	#has_byte2,r1l
	mov.b	r1l,@fsm

        rts

send_3byte_n:
	mov.b	@sb,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx_fifo_set

	mov.b	@byte2,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx_fifo_set

	mov.b	r3h,r3l
        mov.b   r3l,@tx2_buf
	jsr	@tx_fifo_set

	bclr	#has_byte2,r1l
	mov.b	r1l,@fsm
_end_rx_n:

        rts

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

       mov.l   #h'0fdf10,er2           ; ram start addr for 3052 
       mov.w   #h'1fe0,r1              ; clear 1fe0 bites

       mov.b   #0,r0l

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


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

input_enable:
	mov.b	#b'00000000,r0l
	mov.l	#32,er1

_enable_input:
	mov.l	@(ptdir,er1),er2
	mov.b	r0l,@er2
        jsr     @wait_1msec
	sub.l	#4,er1
	bne	_enable_input
	mov.l	@(ptdir,er1),er2
	mov.b	r0l,@er2
        jsr     @wait_1msec

;; output for port8
	mov.b	#b'11111111,r0l
	mov.b	r0l,@pdir8

        jsr     @wait_1msec
	rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;SCI init 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;sci_init0:

 ;       mov.b   #b'00100000,r0l         ; IRQ5 enable
 ;       mov.b   r0l, @ier
 ;       rts


sci_init:
        mov.b   #b'00000000,r0l         ; sci0 runs for high speed data stream
        mov.b   r0l,@scr0
        mov.b   #b'00000000,r0l
        mov.b   r0l,@smr0
        mov.b   #19,r0l                 ; set the baud rate #24=31250 #19=38400
        mov.b   r0l,@brr0
        mov.w   #1000,r0

_sci0_wait:
        dec.w   #1,r0
        bne     _sci0_wait
        mov.b   @ssr0,r0l               ; (dummy read)
        mov.b   #0,r0l
        mov.b   r0l,@ssr0
        mov.b   #b'00001000,r0l         ; wdt priority UP.
        mov.b   r0l,@ipra               ; 
	rts

sci_init2:
        mov.b   #b'00000000,r0l         ; sci1 runs for midi i/o 
        mov.b   r0l,@scr1
        mov.b   #b'00000000,r0l
        mov.b   r0l,@smr1
        mov.b   #24,r0l                 ; set the baud rate #24=31250 #19=38400
        mov.b   r0l,@brr1
        mov.w   #1000,r0
_sci1_wait2:
        dec.w   #1,r0
        bne     _sci1_wait2
        mov.b   @ssr1,r0l                ; (dummy read)
        mov.b   #0,r0l
        mov.b   r0l,@ssr1
        mov.b   #b'00001100,r0l
        mov.b   r0l,@iprb               ; SCI1-int priority UP !
        rts



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;SCI init Normal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;sci_init0_n:

 ;       mov.b   #b'00100000,r0l         ; IRQ5 enable
 ;       mov.b   r0l, @ier
 ;       rts


sci_init_n:
        mov.b   #b'00000000,r0l         ; sci0 runs for high speed data stream
        mov.b   r0l,@scr0
        mov.b   #b'00000000,r0l
        mov.b   r0l,@smr0
        mov.b   #24,r0l                 ; set the baud rate #24=31250 #19=38400
        mov.b   r0l,@brr0
        mov.w   #1000,r0

_sci0_wait_n:
        dec.w   #1,r0
        bne     _sci0_wait
        mov.b   @ssr0,r0l               ; (dummy read)
        mov.b   #0,r0l
        mov.b   r0l,@ssr0
        mov.b   #b'00001000,r0l         ; wdt priority UP.
        mov.b   r0l,@ipra               ; 
	rts

sci_init2_n:
        mov.b   #b'00000000,r0l         ; sci1 runs for midi i/o 
        mov.b   r0l,@scr1
        mov.b   #b'00000000,r0l
        mov.b   r0l,@smr1
        mov.b   #24,r0l                 ; set the baud rate #24=31250 #19=38400
        mov.b   r0l,@brr1
        mov.w   #1000,r0
_sci1_wait2_n:
        dec.w   #1,r0
        bne     _sci1_wait2
        mov.b   @ssr1,r0l                ; (dummy read)
        mov.b   #0,r0l
        mov.b   r0l,@ssr1
        mov.b   #b'00001100,r0l
        mov.b   r0l,@iprb               ; SCI1-int priority UP !
        rts







;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; MIDI tx/rx start !
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

midi_start:
        mov.b   #b'01110000,r0l         
        mov.b   r0l,@scr0
        mov.b   #b'01110000,r0l         ; 01100000 sci no transmittion
        mov.b   r0l,@scr1
        andc    #b'01111111,ccr         ; interrupt enable

	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_50msec:
	push.l	er1
	push.l	er2
        mov.l   #50,er1
_wait_3:
        jsr     @wait_1msec
        sub.l   #1,er1
        bne     _wait_3
	pop.l	er2
	pop.l	er1
        rts

wait_20msec:
	push.l	er1
	push.l	er2
        mov.l   #20,er1
_wait_4:
        jsr     @wait_1msec
        sub.l   #1,er1
        bne     _wait_4
	pop.l	er2
	pop.l	er1
        rts

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

wait_5msec:
	push.l	er1
	push.l	er2
        mov.l   #5,er1
_wait_6:
        jsr     @wait_1msec
        sub.l   #1,er1
        bne     _wait_6
	pop.l	er2
	pop.l	er1
        rts

wait_1msec:
	push.l	er2
        mov.l   #2048,er2
_wait_7:
        sub.l   #1,er2
        bne     _wait_7
	pop.l	er2
        rts


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

midi_channel_set:

	push.w	r1

	mov.b	@pdat5,r1l        ;loading the port data
	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

	pop.w	r1

        rts

control_number_set:

	push.w	r2

	mov.b	@pdatA,r3l        ;loading port data
        and.b   #b'01111111,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

        cmp.b   #0, r3l             ;detecting zero
        bne     ccstatus_out

        mov.b   #69,r3l            ;preset #69
        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

	pop.w	r2
	rts

switch_preset:

	push.w	r1

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

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

	mov.b	r1l,@swptn

	pop.w	r1
	rts



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

load_sw_num:

        push.l  er0
        push.l  er1
        push.l  er2
        push.l  er3

        mov.b   @swptn,r3l
        cmp.b     #0,r3l
        beq        sw_00
        cmp.b     #1,r3l
        beq        sw_01
        cmp.b     #2,r3l
        beq        sw_02
        cmp.b     #3,r3l
        beq        sw_03
        cmp.b     #4,r3l
        beq        sw_04
        cmp.b     #5,r3l
        beq        sw_05
        cmp.b     #6,r3l
        beq        sw_06
        cmp.b     #7,r3l
        beq        sw_07
        cmp.b     #8,r3l
        beq        sw_08
        cmp.b     #9,r3l
        beq        sw_09
        cmp.b     #10,r3l
        beq        sw_10
        cmp.b     #11,r3l
        beq        sw_11
        cmp.b     #12,r3l
        beq        sw_12
        cmp.b     #13,r3l
        beq        sw_13
        cmp.b     #14,r3l
        beq        sw_14
        cmp.b     #15,r3l
        beq        sw_15

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

        bra         detect_end

sw_01:

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

num_data_load01:
 
        mov.b   @(swnum01,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load01

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

sw_data_load01:

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

        cmp.l   #31,er0
        ble     sw_data_load01
              
        bra         detect_end

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

        bra         detect_end

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

        bra         detect_end

sw_04:

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

num_data_load04:
 
        mov.b   @(swnum04,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load04

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

sw_data_load04:

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

        cmp.l   #31,er0

        ble     sw_data_load04
              
        bra         detect_end

sw_05:

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

num_data_load05:
 
        mov.b   @(swnum05,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load05

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

sw_data_load05:

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

        cmp.l   #31,er0
        ble     sw_data_load05

        bra         detect_end

sw_06:

        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      

        bra         detect_end

sw_07:

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

num_data_load07:
 
        mov.b   @(swnum07,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load07

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

sw_data_load07:

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

        cmp.l   #31,er0
        ble     sw_data_load07
      
        bra         detect_end

sw_08:

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

num_data_load08:

        mov.b   #b'11110000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum08,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load08

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

sw_data_load08:

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

        cmp.l   #31,er0
        ble     sw_data_load08

        bra         detect_end

sw_09:

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

num_data_load09:

        mov.b   #b'01100000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum09,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load09

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

sw_data_load09:

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

        cmp.l   #31,er0
        ble     sw_data_load09
      
        bra         detect_end

sw_10:

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

num_data_load10:

        mov.b   #b'11110000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum10,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load10

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

sw_data_load10:

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

        cmp.l   #31,er0
        ble     sw_data_load10
      
        bra         detect_end

sw_11:

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

num_data_load11:

        mov.b   #b'11000000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum11,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load11

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

sw_data_load11:

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

        cmp.l   #31,er0
        ble     sw_data_load11      

        bra         detect_end

sw_12:

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

num_data_load12:

        mov.b   #b'11100000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum12,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load12

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

sw_data_load12:

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

        cmp.l   #31,er0
        ble     sw_data_load12
   
        bra         detect_end

sw_13:

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

num_data_load13:

        mov.b   #b'00010000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum13,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load13

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

sw_data_load13:

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

        cmp.l   #31,er0
        ble     sw_data_load13
      
        bra         detect_end

sw_14:

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

num_data_load14:

        mov.b   #b'11000000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum14,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load14

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

sw_data_load14:

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

        cmp.l   #31,er0
        ble     sw_data_load14

        bra         detect_end

sw_15:

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

num_data_load15:

        mov.b   #b'00110000,r2l
        mov.b   r2l,@ext_port
 
        mov.b   @(swnum15,er0), r1h
        mov.b   r1h, @(setcnt,er0)
        add.l   #1,er0

        cmp.l   #31,er0
        ble     num_data_load15

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

sw_data_load15:

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

        cmp.l   #31,er0
        ble     sw_data_load15
      
        bra         detect_end

detect_end:


        pop.l	er3
        pop.l	er2
        pop.l	er1
        pop.l	er0

        rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;CPLD matrix switch control out from port 8  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

control_out:

	push.w	r1

       sub.w     r1,r1

       mov.b   @swptn, r1l
       and.b	 #h'0F,r1l         ;msb 4bit clear
       cmp.b     #0,r1l
       beq        out_0000
       cmp.b     #1,r1l
       beq        out_0001
       cmp.b     #2,r1l
       beq        out_0011
       cmp.b     #3,r1l
       beq        out_0111
       cmp.b     #4,r1l
       beq        out_1111
       cmp.b     #5,r1l
       beq        out_1110
       cmp.b     #6,r1l
       beq        out_1100
       cmp.b     #7,r1l
       beq        out_0110
       cmp.b     #8,r1l
       beq        out_0000
       cmp.b     #9,r1l
       beq        out_0000
       cmp.b     #10,r1l
       beq        out_1111
       cmp.b     #11,r1l
       beq        out_0000
       cmp.b     #12,r1l
       beq        out_0000
       cmp.b     #13,r1l
       beq        out_0001
       cmp.b     #14,r1l
       beq        out_0011
       cmp.b     #15,r1l
       beq        out_1100

out_0000:
            mov.b  #b'0000,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_0001:
            mov.b  #b'0010,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_0011:
            mov.b  #b'0011,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_0111:
            mov.b  #b'1011,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_1111:
            mov.b  #b'1111,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_1110:
            mov.b  #b'1101,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_1100:
            mov.b  #b'1100,r1h
            mov.b  r1h,r1l
            bra      output_signal

out_0110:
            mov.b  #b'1001,r1h
            mov.b  r1h,r1l
            bra      output_signal

output_signal:

        and.b   #b'00001111,r1l
	mov.b	r1l,@pdat8
        mov.b   r1l,@outputs

	pop.w	r1

        rts


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; WDT init
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

wdtinit:

        push.l  er0

        mov.b   @tcsr,r0l
        mov.w   #h'a507,r0     ; interval timer
        mov.w   r0,@tcsr       ; 1/4096

        pop.l   er0

        rts


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

int_rx_error:
        bclr    #5,@ssr0
        bclr    #4,@ssr0
        rte
int_rx_full:
	push.w	r1
	push.l	er0
        btst    #6,@ssr0
        bclr    #6,@ssr0
	sub.l	er0,er0
	mov.w	r5,r0
        mov.b   @rdr0,r1l
	mov.b	r1l,@(rx_fifo,er0)
	inc.w	#1,r5
	bclr	#1,r5h     ;full scale 512
        pop.l   er0
        pop.w   r1
        rte

int_rx2_error:
        bclr    #5,@ssr1
        bclr    #4,@ssr1
        rte
int_rx2_full:
	push.w	r1
	push.l	er0
        btst    #6,@ssr1
        bclr    #6,@ssr1
	sub.l	er0,er0
	mov.w	r4,r0
        mov.b   @rdr1,r1l
	mov.b	r1l,@(rx2_fifo,er0)
	inc.w	#1,r4
	bclr	#1,r4h      ;full scale 512
        pop.l   er0
        pop.w   r1
        rte

int_wdt:
        push.w  r1
        push.w  r2
        sub.w   r1,r1
        sub.w   r2,r2

        mov.b   @pdatB,r2l

        shlr    r2l
        shlr    r2l
        shlr    r2l
        shlr    r2l                    ;shift MSB 4bit to LSB

        mov.b   #4,r1h
        mulxu.b r1h,r2
        add.b   #1,r2l                 ;42ms is minimum value

        sub.b   r1h,r1h

        mov.b   @tcsr,r1l              ;upload tcsr status
     
        sub.b   r2h,r2h
        mov.b   @counter_64,r2h        ;r2h is 64 stage counter
        inc.b   r2h             
        cmp.b   r2l,r2h         
        bgt     timer_stop

        mov.b   r2h,@counter_64        ;full scale = 42ms * 64
        
        mov.w   #h'a527,r1             ;clear overfloor flag
        mov.w   r1,@tcsr               ;set tcsr
        nop
        nop
        nop
        
        pop.w   r2
        pop.w   r1

        rte

timer_stop:

        sub.b   r2l,r2l
        bset    #0,r2l
        mov.b   r2l,@swtrig             ;trigger flag on

        sub.b   r2h,r2h                 
        mov.b   r2h,@counter_64         ;clear the counter

        mov.w   #h'a507,r1              ;clear overfloor flag / stop timer
        mov.w   r1,@tcsr                ;set tcsr

        pop.w   r2
        pop.w   r1

        rte

        .end



