LIST 41 ============================================================================ ;##### RAM Map ##### dseg org 0000h rx_fifo ds 2048 tx_fifo ds 2048 rx_top ds 2 rx_end ds 2 tx_top ds 2 tx_end ds 2 rsb ds 1 dcb ds 1 channel ds 1 keyno ds 1 buff ds 1 timer ds 2 led ds 1 ad ds 1 ad_old ds 6 ad_buff ds 1 ad_timer ds 1 ;##### I/O Map ##### cseg sio_a equ 0018h sio_b equ 001ah pio_a equ 001ch pio_b equ 001eh ;##### MACRO ##### io_set macro @1,@2 ld a,@2 out (@1+1),a endm io_put macro @1,@2 ld a,@2 out (@1+0),a endm ;##### RESET ##### org 0000h ld sp,09fffh di jp main ;##### INT / NMI ##### org 0020h dw _midi_ _midi_: ex af,af' exx ld de,(rx_top) ld a,10000000b or d ld h,a ld l,e in a,(sio_a+0) ld (hl),a inc de res 3,d ld (rx_top),de exx ex af,af' ei reti org 0066h retn ;##### Main ##### main: ld hl,08000h ld a,0a0h _ram_clear_loop: ld (hl),0 inc hl cp h jr nc,_ram_clear_loop io_set pio_a,0cfh ; Mode 3 io_set pio_a,11111111b ; 0:Out / 1:In io_set pio_a,007h ; Interrupt Disable io_set pio_b,0cfh ; Mode 3 io_set pio_b,00010000b ; 0:Out / 1:In io_set pio_b,007h ; Interrupt Disable io_set sio_b,00011000b ; Channel Reset B io_set sio_b,00000100b ; Resister Point = 4 io_set sio_b,11000100b ; Mode io_set sio_b,00000001b ; Resister Point = 1 io_set sio_b,00000000b ; Interrupt Mode io_set sio_b,00000010b ; Resister Point = 2 io_set sio_b,20h ; Vector Address io_set sio_a,00011000b ; Channel Reset A io_set sio_a,00000100b ; Resister Point = 4 io_set sio_a,11000100b ; Mode io_set sio_a,00000001b ; Resister Point = 1 io_set sio_a,00010000b ; Interrupt Mode io_set sio_a,00000101b ; Resister Point = 5 io_set sio_a,01101000b ; Transmit Start io_set sio_a,00000011b ; Resister Point = 3 io_set sio_a,11000001b ; Receive Start im 2 ei in a,(sio_a+0) ; dummy read ld a,00000000b ld (led),a out (pio_b),a xor a ld (ad),a call ad_start loop: call living_led call tx_data_check call rx_data_check call ad_check jr loop tx_data_check: ld de,(tx_end) ld hl,(tx_top) and a ; CY <-- 0 sbc hl,de ret z io_set sio_a,00000000b ; Resister Point = 0 in a,(sio_a+1) bit 2,a ret z ld a,10001000b or d ld h,a ld l,e ld a,(hl) out (sio_a),a inc de res 3,d ld (tx_end),de ret tx_fifo_set: ld de,(tx_top) ld a,10001000b or d ld h,a ld l,e ld (hl),b inc de res 3,d ld (tx_top),de ret rx_data_check: ld de,(rx_end) ld hl,(rx_top) and a ; CY <-- 0 sbc hl,de ret z ld a,10000000b or d ld h,a ld l,e ld b,(hl) inc de res 3,d ld (rx_end),de bit 7,b jr z,50$ ; running ld a,b cp 0f8h ret nc cp 0f0h jr c,10$ xor a ld (rsb),a ret 10$: ld a,b and 00001111b ld (channel),a ld a,b and 11110000b ld (rsb),a xor a ld (dcb),a ret 50$: ld a,(rsb) cp 0 ret z cp 0c0h ret z cp 0d0h ret z ld a,(dcb) cp 0 jr nz,90$ inc a ld (dcb),a ld a,b ld (keyno),a ret 90$: xor a ld (dcb),a ld a,(rsb) cp 090h ret nz ld a,b ld (buff),a ld b,090h ; MIDI Channel = [1] fixed !!! call tx_fifo_set ld a,(keyno) ld b,a call tx_fifo_set ld a,(buff) ld b,a call tx_fifo_set ret living_led: ld a,(timer+0) inc a ld (timer+0),a cp 0 ret nz ld a,(timer+1) inc a and 01111111b ld (timer+1),a cp 30 jr z,_led_on cp 45 jr z,_led_off ret _led_on: ld a,(led) and 00000001b or 00100000b ld (led),a out (pio_b),a ret _led_off: ld a,(led) and 00000001b and 11011111b ld (led),a out (pio_b),a ret ad_check: ld a,(ad_timer) inc a ld (ad_timer),a cp 50 ret c xor a ld (ad_timer),a in a,(pio_b) bit 4,a ret z in a,(pio_a) srl a ld c,a ld a,(ad) ld l,a ld h,0 ld de,ad_old add hl,de ld a,(hl) cp c jr z,_ad_next ld a,c ld (hl),a ld (ad_buff),a ld a,(ad) or 0d0h ld b,a call tx_fifo_set ld a,(ad_buff) ld b,a call tx_fifo_set _ad_next: ld a,(ad) inc a ld (ad),a cp 6 jr nz,ad_start xor a ld (ad),a ad_start: ld a,(led) and 00100000b ld c,a ld a,(ad) or c out (pio_b),a or 00001000b out (pio_b),a nop and 11110111b out (pio_b),a ld (led),a ret ============================================================================