?? isr.asi
字號:
inc dptr movx a, @dptr mov r3, a inc dptr movx a, @dptr ;read the number of words into r4/r5 mov r4, a inc dptr movx a, @dptr mov r5, aplay_dma: ;now let's map the block with the MP3 data to 0x9000 mov dptr, #dram_page_cfg + (0x09 * 2) mov a, r2 movx @dptr, a inc dptr mov a, r3 movx @dptr, a ;finally, we're done with the memory management stuff, and ;we can now set up the DMA transfer and start it. mov dptr, #dma_mp3_src clr a movx @dptr, a ;write LSB of src addr inc dptr mov a, #0x90 movx @dptr, a ;write MSB of src addr mov dptr, #dma_mp3_count mov a, r4 movx @dptr, a ;write LSB of length inc dptr mov a, r5 movx @dptr, a ;write MSB of length clr a mov dptr, #dma_mp3_go movx @dptr, a ;begin the transfer ;now the DMA is happening... in all likelyhood, the STA013 has ;already asserted its DATA_REQ signal by the time we could get ;through all that work to set up the DMA transfer. If the ;latency of this code ever gets to be a problem, the FPGA ;will probably have to be changed to double buffer STA013 ;DMA requests, which would allow 0.1 second latency for the ;fastest MP3 (320 kbps) !! mov dptr, #num_blks_played movx a, @dptr add a, #1 ;increment "num_blks_played" movx @dptr, a inc dptr movx a, @dptr addc a, #0 movx @dptr, a pop acc pop dph pop dpl pop psw reti;*****************************************************************;** **;** IDE Interface **;** **;***************************************************************** ;int0 is connected to the xilinx chip. There are ;many possible interrupt sources that could generate ;this interruptint0_isr: push psw push dpl push dph push acc mov psw, #00001000b ;set reg bank1 (0x08 to 0x0F)int0_loop: mov dptr, #irq_ident movx a, @dptr ;jb acc.0, int0_ide_dma jb acc.1, int0_mp3_dma ;this shouldn't happen, as we're not using hardware memcpy yet ;mov dptr, #irq_memcpy_ack ;movx @dptr, a pop acc pop dph pop dpl pop psw reti ;when we get here, a DMA transfer from the IDE drive has ;been completedint0_ide_dma: mov dptr, #irq_dma_ide_ack movx @dptr, a pop acc pop dph pop dpl pop psw reti ;int1 is connected to the IDE drive... when we get an ;interrupt, the drive has finished a command.int1_isr: push psw push dpl push dph mov psw, #00001000b ;set reg bank1 (0x08 to 0x0F) mov r7, a ;we might need to start a new command, or we might be in the ;middle of a read request and the drive is now ready to begin ;transfering data, either way we need to read the IDE status ;register to clear the interrupt and find out what's up. mov dptr, #ide_status movx a, @dptr mov a, r7 pop dph pop dpl pop psw reti;*****************************************************************;** **;** Timer and Pushbuttons **;** **;*****************************************************************.equ t2_reload, 53248 ;approx 50 Hztimer_setup: clr et2 mov t2con, #0 ;timer2 = 16 bit auto reload mov rcap2l, #t2_reload & 255 mov rcap2h, #t2_reload >> 8 mov tl2, #t2_reload & 255 mov th2, #t2_reload >> 8 clr pb_state_next clr pb_state_play clr pb_state_prev clr pb_state_rand mov pb_count_v_up, #0 mov pb_count_v_dn, #0 setb et2 ;enable the timer2 interrupt setb tr2 ;start the timer rettimer2_isr: push psw mov psw, #00001000b ;set reg bank1 (0x08 to 0x0F) mov r7, a mov r6, dpl mov r5, dph mov r4, b clr tf2 clr hc165_load_pin nop setb hc165_load_pin noppb_prev: jb hc165_data_pin, pb_prev_up jnb pb_state_prev, pb_prev_press sjmp pb_prev_endpb_prev_press: setb pb_state_prev mov a, #event_previous acall add_new_event sjmp pb_prev_endpb_prev_up: clr pb_state_prevpb_prev_end: clr hc165_clk_pin setb hc165_clk_pinpb_play: jb hc165_data_pin, pb_play_up jnb pb_state_play, pb_play_press sjmp pb_play_endpb_play_press: setb pb_state_play mov a, #event_play_pause acall add_new_event sjmp pb_play_endpb_play_up: clr pb_state_playpb_play_end: clr hc165_clk_pin setb hc165_clk_pinpb_rand: jb hc165_data_pin, pb_rand_up jnb pb_state_rand, pb_rand_press sjmp pb_rand_endpb_rand_press: setb pb_state_rand mov a, #event_random acall add_new_event sjmp pb_rand_endpb_rand_up: clr pb_state_randpb_rand_end: clr hc165_clk_pin setb hc165_clk_pinpb_v_dn: jb hc165_data_pin, pb_v_dn_up inc pb_count_v_dn mov a, pb_count_v_dn dec a jz pb_v_dn_press add a, #256 - 12 jnc pb_v_dn_end mov pb_count_v_dn, #1pb_v_dn_press: mov a, #event_vol_down acall add_new_event sjmp pb_v_dn_endpb_v_dn_up: mov pb_count_v_dn, #0pb_v_dn_end: clr hc165_clk_pin setb hc165_clk_pinpb_next: jb hc165_data_pin, pb_next_up jnb pb_state_next, pb_next_press sjmp pb_next_endpb_next_press: setb pb_state_next mov a, #event_next acall add_new_event sjmp pb_next_endpb_next_up: clr pb_state_nextpb_next_end: clr hc165_clk_pin setb hc165_clk_pinpb_v_up: jb hc165_data_pin, pb_v_up_up inc pb_count_v_up mov a, pb_count_v_up dec a jz pb_v_up_press add a, #256 - 12 jnc pb_v_up_end mov pb_count_v_up, #1pb_v_up_press: mov a, #event_vol_up acall add_new_event sjmp pb_v_up_endpb_v_up_up: mov pb_count_v_up, #0pb_v_up_end:timer: mov a, ide_timeout_count add a, #1 ;increment ide timeout subb a, #0 ;but don't go over 255 mov ide_timeout_count, a mov dptr, #sw_timer_tick movx a, @dptr add a, #252 jc timer_inc add a, #5 movx @dptr, a ljmp timer_endtimer_inc: clr a movx @dptr, a mov dptr, #sw_timer_mask movx a, @dptr mov dptr, #sw_timer mov r1, #0xfftimer_loop: cjne r1, #7, timer_cont mov dptr, #sw_timer_mask movx @dptr, a sjmp timer_clocktimer_cont: inc r1 rr a jb acc.7, timer_enabled ;flag is set inc dptr inc dptr sjmp timer_looptimer_enabled: mov b, a movx a, @dptr ;decrement counter add a, #255 movx @dptr, a mov r2, a inc dptr movx a, @dptr addc a, #255 movx @dptr, a inc dptr jnz timer_next ;check for end of count mov a, r2 jnz timer_next mov a, #event_timer_base ;fire event add a, r1 mov r2, dpl mov r3, dph acall add_new_event mov dpl, r2 mov dph, r3 mov a, b anl a, #0x7f ;clear flag sjmp timer_looptimer_next: mov a, b sjmp timer_looptimer_clock: mov dptr, #clock_tick movx a, @dptr add a, #1 movx @dptr, a jnc timer_end inc dptr movx a, @dptr addc a, #0 movx @dptr, a inc dptr movx a, @dptr addc a, #0 movx @dptr, a inc dptr movx a, @dptr addc a, #0 movx @dptr, atimer_end: mov b, r4 mov dph, r5 mov dpl, r6 mov a, r7 pop psw reti.equ event_next, 1.equ event_play_pause, 2.equ event_previous, 3.equ event_random, 4.equ event_vol_up, 5.equ event_vol_down, 6; we use events 10 - 17 for timers 0 - 7.equ event_timer_base, 10 ;put a new event (in Acc) into the event queue. This is ;intended (someday) to be called only from within the ;interrupt routinesadd_new_event: mov r0, a mov a, event_queue_head inc a cjne a, #event_queue_size, addevt2 clr aaddevt2:cjne a, event_queue_tail, addevt3 ;if we get here, the event queue is full and we are not ;able to add another event to it, so this event will ;just get discarded... hopefully is wasn't too important. retaddevt3:mov event_queue_head, a add a, #event_queue & 255 ;add Acc + event_queue mov dpl, a mov dph, #event_queue >> 8 ;assume event queue in 256 byte area mov a, r0 movx @dptr, a ;put the event byte into event queue ret
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -