📄 drivers.asm
字号:
mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin mov a, dpl cjne a, #(xilinx_bitstream_location + 11968) & 255, xd_loop1 mov a, dph cjne a, #(xilinx_bitstream_location + 11968) >> 8, xd_loop1 setb xilinx_din_pin mov dpl, #0 ljmp return_addrget_next_byte: inc dptr clr a movc a, @a+dptr retno_bitstream: setb c mov dpl, #1 ljmp return_addr ;download a bitstream to the xilinx chip. ;return DPL=0 if ok, DPL=1 if an erroralt_xdownload: mov dptr, #xilinx_alt_bitstream_location - 1 acall get_next_byte cjne a, #0xFF, no_bitstream ;fill byte acall get_next_byte cjne a, #0x04, no_bitstream ;preamble, upper 4 bits of length acall get_next_byte cjne a, #0xE8, no_bitstream ;next 8 bits of length acall get_next_byte cjne a, #0x06, no_bitstream ;next 8 bits of length acall get_next_byte cjne a, #0xF8, no_bitstream ;lower 4 bits length, fill bits ;reset the xilinx chip... also resets the STA013 and flash lcall rst_devices ;wait for 3ms for the xilinx chip to be ready ;at 7.3728 MHz / 12, that's 1843 instruction cycles djnz r0, * ;512 cycles djnz r0, * ;512 cycles djnz r0, * ;512 cycles mov r0, #153 ;1 cycle djnz r0, * ;306 cycles setb xilinx_din_pin setb xilinx_cclk_pin mov dptr, #xilinx_alt_bitstream_locationalt_xd_loop1: clr a movc a, @a+dptr inc dptr rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin rrc a mov xilinx_din_pin, c clr xilinx_cclk_pin setb xilinx_cclk_pin mov a, dpl cjne a, #(xilinx_alt_bitstream_location + 11969) & 255, alt_xd_loop1 mov a, dph cjne a, #(xilinx_alt_bitstream_location + 11969) >> 8, alt_xd_loop1 setb xilinx_din_pin mov dpl, #0 ljmp return_addrpm2_cout_dot: mov a, #'.' ljmp coutsta013_init: acall pm2_cout_dot ;read the STA013 ident register mov r4, #1 acall sta013_read jc sta013_init1 cjne r3, #0xAC, sta013_init0 sjmp sta013_init2sta013_init0: mov a, r3 lcall phexsta013_init1: mov a, #'*' lcall pm2_cout ;read the STA013 ident register mov r4, #1 acall sta013_read jc sta013_error cjne r3, #0xAC, sta013_errorsta013_init2: acall pm2_cout_dot ;check to see if the sta013 data file is loaded into memory mov dptr, #sta013_config_location acall check_data_file jc sta013_error acall pm2_cout_dot ;now attempt to download the config data ;to the STA013 chip acall pm2_cout_dot acall sta013_config acall pm2_cout_dot mov r4, #20 mov r3, #1 acall sta013_write ;mute on jc sta013_error setb mute_is_on acall pm2_cout_dot mov r4, #114 mov r3, #1 acall sta013_write ;run command jc sta013_error ;acall pm2_cout_dot ;mov r4, #19 ;mov r3, #1 ;acall sta013_write ;begin play ;jc sta013_error ;acall pm2_cout_dot ;mov r4, #20 ;mov r3, #0 ;acall sta013_write ;mute off ;jc sta013_error ;acall pm2_cout_dot clr c mov dpl, #0 ljmp return_addrsta013_error: setb c mov dpl, #1 ljmp return_addrsta013_config: mov dptr, #sta013_config_location acall get_16_bits ;r6/r7 has cksum addr mov a, r6 anl a, #11111110b mov r6, acfgloop:acall get_8_bits ;get the address mov r4, a acall get_8_bits ;get the data byte mov r3, a acall sta013_write ;send this byte to its address mov a, r4 add a, #240 jnz cfgloop2 ;delay at least 60 us if the write was a soft reboot cmd mov r5, #200 djnz r5, *cfgloop2: mov a, r6 cjne a, dpl, cfgloop ;send all the bytes mov a, r7 cjne a, dph, cfgloop ret ;checks for a data file in memory @dptr. The test ;is simple... the first 2 bytes are the location of ;the file's last two bytes, that are a simple 16 bit ;checksum of all the data bytescheck_data_file: acall get_16_bits ;r6/r7 has cksum addr clr a mov r0, a ;r0/r1 will hold the computed cksum mov r1, ackloop: acall get_8_bits ;get each byte add a, r0 ;add it to the cksum mov r0, a clr a addc a, r1 mov r1, a mov a, r6 cjne a, dpl, ckloop ;check all the data bytes mov a, r7 cjne a, dph, ckloop acall get_8_bits ;get cksum lsb mov b, r0 cjne a, b, ckfail acall get_8_bits ;get cksum msb mov b, r1 cjne a, b, ckfail clr c retckfail: setb c mov a, #'!' lcall cout ljmp 0 retget_8_bits: clr a movc a, @a+dptr inc dptr retget_16_bits: acall get_8_bits mov r6, a acall get_8_bits mov r7, a ret ;allow the main program to call the read and write routinessta013_rd: acall sta013_read clr a addc a, #0 ljmp return_addrsta013_wr: acall sta013_write clr a addc a, #0 mov dpl, a ljmp return_addr ;read a byte from the sta013 at address r4 and return it ;in r3. Carry cleared if success, set for failsta013_read: acall i2c_start mov a, #10000110b acall i2c_write ;wr device addr, wr cmd jc s013r3 mov a, r4 acall i2c_write ;wr addr of data to read jc s013r3 acall i2c_stop acall i2c_start mov a, #10000111b ;wr device addr, rd cmd acall i2c_write jc s013r3 acall i2c_read mov r3, a clr cs013r3: ajmp i2c_stop ;write a byte in r3 to the sta013 at address r4 ;Carry cleared if success, set for failsta013_write: acall i2c_start mov a, #10000110b acall i2c_write jc s013w3 mov a, r4 acall i2c_write jc s013w3 mov a, r3 acall i2c_writes013w3: ajmp i2c_stop ;i2c stop doesn't change carry bit ;read the mpeg header and return is packed into a 32 bit intsta013_read_header: mov r6, #1 acall i2c_start mov a, #10000110b acall i2c_write ;wr device addr, wr cmd jc s013_rdhdr_err inc r6 mov a, #0x40 acall i2c_write ;wr addr of data to read jc s013_rdhdr_err inc r6 acall i2c_stop acall i2c_start mov a, #10000111b ;wr device addr, rd cmd acall i2c_write jc s013_rdhdr_err inc r6 acall i2c_read ;read SYNC_STATUS acall i2c_ack mov r1, a acall i2c_read ;read ANCCOUNT_L (ignore) acall i2c_ack acall i2c_read ;read ANCCOUNT_H (ignore) acall i2c_ack acall i2c_read ;read HEAD_H acall i2c_ack mov b, a acall i2c_read ;read HEAD_M acall i2c_ack mov dph, a acall i2c_read ;read HEAD_L mov dpl, a acall i2c_stop mov a, r1 ljmp return_addrs013_rdhdr_err: acall i2c_stop mov a, #255 mov b, a mov dph, a mov dpl, r6 ljmp return_addri2c_read: ;reads i2c bus into acc, send ack bit from Carry rlc a mov r5, #8 setb sda_pin nopi2cr: nop setb scl_pin nop nop mov c, sda_pin rlc a nop clr scl_pin djnz r5, i2cr; mov sda_pin, c; nop; nop; setb scl_pin; nop; nop; clr scl_pin reti2c_write: ;writes acc to i2c bus, return ack bit in Carry mov r5, #8i2cw: rlc a mov sda_pin, c nop setb scl_pin nop clr scl_pin djnz r5, i2cw rlc a setb sda_pin nop setb scl_pin nop mov c, sda_pin clr scl_pin reti2c_start: setb sda_pin setb scl_pin nop nop clr sda_pin nop nop clr scl_pin reti2c_stop: clr sda_pin nop nop setb scl_pin nop nop setb sda_pin reti2c_ack: clr sda_pin nop nop setb scl_pin nop nop clr scl_pin retdly: nop nop nop nop nop nop nop nop ret shutdown: mov r0, #250sd2: clr shutdown_pin setb shutdown_pin djnz r0, sd2 ljmp return_addr;*************************************************************;** **;** USER Interface **;** **;*************************************************************;.equ event_next, 1;.equ event_play_pause, 2;.equ event_prev, 3;.equ event_random, 4;.equ event_vol_up, 5;.equ event_vol_down, 6;.equ event_inc, 7;.equ event_dec, 8;.equ event_plnext, 9;.equ event_plprev, 10;.equ event_up, 11;.equ event_down, 12;.equ event_left, 13;.equ event_right, 14;.equ event_enter, 15;.equ event_fwd, 16;.equ event_rev, 17 ;return the next pending "event" in DPL (zero for none)get_next_event: clr ea mov a, event_queue_tail cjne a, event_queue_head, nxtevt2 setb ea mov dpl, #0 ;no events pending ljmp return_addrnxtevt2: inc a cjne a, #event_queue_size, nxtevt3 clr anxtevt3: mov event_queue_tail, 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 movx a, @dptr ;read the event byte from queue setb ea mov dpl, a ljmp return_addr ;push an event in R4 back into the event queue. This ;will probably be called when the main program got an ;event that is can't process now, but will be able to ;process in the near future.put_back_event: ;TODO: this version should "try harder" than add_new_event. ;add_new_event should be changed to always leave a couple ;free slots on the queue. ;FIXME: this adds it back into the end of the queue, when ;it ought to be "pushed" onto the front. clr ea mov a, event_queue_head inc a cjne a, #event_queue_size, pbe_2 clr apbe_2: cjne a, event_queue_tail, pbe_3 ;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. setb ea ljmp return_addrpbe_3: 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, r4 movx @dptr, a ;put the event byte into event queue setb ea ljmp return_addr;this will eventually be run from an interrupt routine (timer0);so that "events" will be detected automatically and added to;the queue.update_events:wait: ljmp return_addrread_buttons: clr a retread_buttons_c: acall read_buttons
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -