⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 final_target.a51

📁 8051控制CDROM驱动
💻 A51
📖 第 1 页 / 共 2 页
字号:
  jb    STATUS_REG_BSY,drq_wait  jb    STATUS_REG_DRQ,drq_wait  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; main routines;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; misc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;terminate_with_error:  setb  F_ERROR  sjmp  $; clocks data out of buffer until all done (DRQ goes low);skip_rest_of_packet:  acall get_status_register  jnb   STATUS_REG_DRQ,skip_rest_of_packet_d  acall get_data  sjmp  skip_rest_of_packetskip_rest_of_packet_d:  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; init ATA device routines..;; also detects the device during the process of initing it.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;init_ata_device:; do hard reset..;; nb/ you have a wait a bit after pulling the reset back high. if you; don't, then bsy flag will falsey pass. i haven't figured out a way; yet to determine when the device controller is busy during hard reset;  clr   ATA_nRESET  acall delay_100000us  setb  ATA_nRESET  mov   r5,#2  acall delay  acall bsy_wait;select device 0;;the device will now respond to commands now;  acall get_devhead_register  clr   ATA_DATA_LS.4             ;set device to 0  acall set_devhead_register; test for device signature to determine if it's 'packet command' device; if it's not a packet command, then it's probably a harddisk or; something, and we can't continue.;; we have to check this inorder to know if we can issue the 'identify; packet device' ATA command.;  acall bsy_wait  acall get_cyl_low_register  cjne  a,#14h,init_device_s_error  acall get_cyl_high_register  cjne  a,#0ebh,init_device_s_error  sjmp  init_device_s_doneinit_device_s_error:  ajmp  terminate_with_errorinit_device_s_done:; running self diagonistics..; nb/ this is the first ATA command we send;  mov   a,#90h  acall set_cmd_register  acall bsy_wait  acall get_error_register  jb    acc.0,init_device_c1  ajmp  terminate_with_errorinit_device_c1:  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ATAPI identify packet device;; this ATA/ATAPI command is mandatory for CDROM (and like) devices, as it; will enable the DRDY flag. without this command, we won't be able to; issue any commands (ATA or packet).;; nb/ older ATA standards, DRDY goes high immediately after BSY goes low; during reset. .. not so for CDROM devices ;);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;identify_packet_device:;identify device cmd;  mov   a,#2h                 ;set byte count registers  acall set_cyl_high_register ;maximum transfer length = 0200h  clr   a                     ;nb/ on the few devices i've tested, this  acall set_cyl_low_register  ;cmd automatically sets these registers.                              ;but i'll set it for consistency ;)  mov   a,#0a1h  acall set_cmd_register  acall wait_irq; get general config word;  acall get_data  clr   a  jb    acc.0,identify_packet_device_c2  jb    acc.1,identify_packet_device_c2  mov   a,#6identify_packet_device_c2:  jb    acc.0,identify_packet_device_c3  jnb   acc.1,identify_packet_device_c3  mov   a,#8identify_packet_device_c3:  mov   packet_size,a  acall skip_rest_of_packet  acall bsy_drdy_wait  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;do_packet_cmd:; clr packet table;  mov   r0,#packet_tab  mov   r7,#16init_pck_l:  mov   @r0,#0  inc   r0  djnz  r7,init_pck_l; send packet command;  acall ndrq_wait  mov   a,#0a0h  acall set_cmd_register  retsend_packet:  acall drq_wait  mov   r0,#packet_tab  mov   r7,#packet_sizesend_packet_l:  mov   a,@r0  inc   r0  push  acc  mov   a,@r0  inc   r0  mov   b,a  pop   acc  acall set_data  djnz  r7,send_packet_l  acall wait_irq  acall get_status_register  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; test unit ready ATAPI command;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;test_unit_ready_cmd:  acall do_packet_cmd  acall send_packet  jnb   STATUS_REG_ERR,test_unit_ready_d  clr   c  rettest_unit_ready_d:  setb  c  retwait_for_ready_state:  mov   r2,#2wait_for_ready_state_l:  mov   r5,#1  acall delay  acall test_unit_ready_cmd  jnc   wait_for_ready_state_l  dec   r2  cjne  r2,#0,wait_for_ready_state_l  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Table of Contents command;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;read_toc_cmd:  mov   a,#0ffh               ;set byte counter register  acall set_cyl_low_register  ;(set it to full on.. it doesn't matter coz  acall set_cyl_high_register ;DRQ controls the feed)  acall do_packet_cmd  mov   packet_cmd,#43h  mov   packet_1,#00000010b   ;MSF=1  mov   packet_7,#0ffh        ;allocation length  mov   packet_8,#0ffh        ;(again, set it to full on)  acall send_packet  jb    STATUS_REG_DRQ,read_toc_cmd_rread_toc_cmd_e:  ajmp  terminate_with_error; read header;read_toc_cmd_r:  acall get_data       ;data length  acall get_data       ;get track limits  mov   start_track,a; read track descriptors;read_toc_cmd_l2:  acall get_data   ;get ADR and control fields  acall get_data   ;get track number  mov   tmp0,a  acall get_data  mov   tmp1,b  acall get_data  mov   tmp2,a  mov   tmp3,b; if start track, then record start position;  mov   a,tmp0  cjne  a,start_track,read_toc_cmd_i0  mov   start_M,tmp1  mov   start_S,tmp2  mov   start_F,tmp3read_toc_cmd_i0:;if the last track, then record as end position;  cjne  a,#0aah,read_toc_cmd_i1  mov   end_M,tmp1  mov   end_S,tmp2  mov   end_F,tmp3read_toc_cmd_i1:  acall bsy_wait  jb    STATUS_REG_DRQ,read_toc_cmd_l2  setb  c  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; play MSF cd cmd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;play_entire_cd_cmd:  acall do_packet_cmd  mov   packet_cmd,#47h  mov   packet_3,start_M  mov   packet_4,start_S  mov   packet_5,start_F  mov   packet_6,end_M  mov   packet_7,end_S  mov   packet_8,end_F  acall send_packet  jnb   STATUS_REG_ERR,play_audio_cmd_d  ajmp  terminate_with_errorplay_audio_cmd_d:  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read sub channel cmd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;read_subchan_cmd:  mov   a,#04h                ;set byte counter register  acall set_cyl_low_register  ;= 4 bytes  acall set_cyl_high_register ;  acall do_packet_cmd  mov   packet_cmd,#42h  mov   packet_1,#00000010b  ;MSF=1  mov   packet_2,#01000000b  ;SubQ=1  mov   packet_3,#01h        ;format=01  (current position)  mov   packet_8,#04h        ;allocation length (4 bytes)  acall send_packet  jb    STATUS_REG_DRQ,read_subchan_cmd_rread_subchan_cmd_e:  mov   audio_status,#0ffh  ret;read sub-channel header;read_subchan_cmd_r:  acall get_data   ;get audio status  mov   audio_status,b  acall get_data   ;sub channel data length (will be zero).. ignore  acall skip_rest_of_packet  ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; program entry point;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;start:  mov   sp,#STACK_START  ;set stack positionstart_over:  clr   F_ERROR  clr   F_PLAYING  acall init_ata_device  acall identify_packet_device  setb  F_PLAYING  mov   r5,#1  acall delaymain_loop:  acall wait_for_ready_state  acall read_toc_cmd  acall play_entire_cd_cmdplay_loop:  mov   c,play_blink  mov   F_PLAYING,c  jnc   play_loop_c1  clr   play_blink  sjmp  play_loop_c2play_loop_c1:  setb  play_blinkplay_loop_c2:  mov   r5,#1  acall delay  acall read_subchan_cmd  mov   a,audio_status  cjne  a,#11h,play_loop_end ;if playing, then loop, else start over  sjmp  play_loopplay_loop_end:  clr   F_PLAYING  sjmp  main_loopend

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -