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

📄 cdc_fw_v13_asm.asm

📁 一个利用51单片机实现对的简易功能的控制cd-rom的程序
💻 ASM
📖 第 1 页 / 共 5 页
字号:
bsy_drdy_wait:
  nop
  nop
  nop
  nop
  call delay_100000us
  call get_status_register
  jb    STATUS_REG_BSY,bsy_drdy_wait
  jnb   STATUS_REG_DRDY,bsy_drdy_wait
  ret

drq_wait:
  nop
  nop
  nop
  nop
  call get_status_register
  jb    STATUS_REG_BSY,drq_wait
  jnb   STATUS_REG_DRQ,drq_wait
  ret

ndrq_wait:
  nop
  nop
  nop
  nop
  call get_status_register
  jb    STATUS_REG_BSY,drq_wait
  jb    STATUS_REG_DRQ,drq_wait
  ret
IO_CoD_Wait:

  call get_sector_c_register
  jnb acc.0,IO           ;check CoD
  sjmp io_cod_wait
 IO:
  jnb acc.1,io_cod_wait
  ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; misc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

terminate_with_error:
 setb DISP_E
 mov LED_W,#0FFH
 mov LED_D,#0H
 mov LED_W,#01111111B
 mov LED_D,#11101011B ;o.
 clr DISP_E
 mov r5,#2h
 call delay
  ret
  sjmp  $

; clocks data out of buffer until all done (DRQ goes low)
;
skip_rest_of_packet:
  call get_status_register
  jnb   STATUS_REG_DRQ,skip_rest_of_packet_d
  call get_data
  sjmp  skip_rest_of_packet
skip_rest_of_packet_d:
  ret
;skip_rest_of_packet2:
;  call get_status_register
;  jnb   STATUS_REG_DRQ,skip_rest_of_packet_d2
;  call set_data
;  sjmp  skip_rest_of_packet2
;skip_rest_of_packet_d2:
;  ret  

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; init ATA device routines..
;
; also detects the device during the process of initing it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
init_ata_device:
 clr ea
; 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
  call delay_100000us
  setb  ATA_nRESET
  ;mov   r5,#2
  
  ;call delay
  call hjhy
  call S_space
  call s_MCU_ST
  call bsy_wait
  

;select device 0
;
;the device will now respond to commands now
;
  call get_devhead_register
  clr   acc.4             ;set device to 0
  call 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.
;
  call bsy_wait
  call get_cyl_low_register
  cjne  a,#14h,init_device_s_error_L
  call get_cyl_high_register
  cjne  a,#0ebh,init_device_s_error_h
  sjmp  init_device_s_done
init_device_s_error:
  ;ajmp  terminate_with_error_ini
init_device_s_error_ini:
 setb DISP_E
 mov LED_W,#11111101B
 MOV LED_D,#11110111B  ;A. 
 CLR DISP_E
 sjmp $

init_device_s_error_H:
 setb DISP_E
 mov LED_W,#11111101B
 MOV LED_D,#11110110B  ;H. 
 CLR DISP_E
 call s_IDE_error
 sjmp $
init_device_s_error_L:
 setb DISP_E
 mov LED_W,#11111101B
 MOV LED_D,#10111000B  ;L. 
 CLR DISP_E
 call s_IDE_error
 sjmp $
init_device_s_done:
; running self diagonistics..
; nb/ this is the first ATA command we send
;
  mov   a,#90h
  call set_cmd_register

  call bsy_wait
  mov a,#0 
  call get_error_register
  jb    acc.0,init_device_c1
  ajmp  terminate_with_error_ini_s_done
terminate_with_error_ini_s_done:
 setb DISP_E
 mov LED_W,#11111101B
 MOV LED_D,#11001111B  ;d. 
 CLR DISP_E
 sjmp $
init_device_c1:
 setb DISP_E
 mov LED_W,#11111110B
 MOV LED_D,#10000110B  ;1. 
 CLR DISP_E
 
  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:
 clr ea
;identify device cmd
;
  mov   a,#2h                 ;set byte count registers
  call set_cyl_high_register ;maximum transfer length = 0200h
  clr   a                     ;nb/ on the few devices i've tested, this
  call set_cyl_low_register  ;cmd automatically sets these registers.
                              ;but i'll set it for consistency ;)
  mov   a,#0a1h
  call set_cmd_register
  call wait_irq

; get general config word
;
  call get_data
  clr   a
  jb    acc.0,identify_packet_device_c2
  jb    acc.1,identify_packet_device_c2
  mov   a,#6
identify_packet_device_c2:
  jb    acc.0,identify_packet_device_c3
  jnb   acc.1,identify_packet_device_c3
  mov   a,#8
identify_packet_device_c3:
  mov   packet_size,a

  call skip_rest_of_packet
  call bsy_drdy_wait
 call s_start 
 setb DISP_E
 mov LED_W,#11111101B
 MOV LED_D,#11011011B  ;2. 
 CLR DISP_E
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
do_packet_cmd:
 clr ea
; clr packet table
  mov   r0,#packet_tab
  mov   r7,#16
init_pck_l:
  mov   @r0,#0
  inc   r0
  djnz  r7,init_pck_l
; send packet command
;  call IO_CoD_wait
  call ndrq_wait
  mov   a,#0a0h
  call set_cmd_register
  ret


send_packet:
   call drq_wait
   mov   r0,#packet_tab
  ;mov   r7,#packet_size
   mov r7,#06h
send_packet_l:

  mov   a,@r0
  inc   r0
  push  acc
  mov   a,@r0
  inc   r0
  mov   b,a
  pop   acc
  call set_data
  djnz  r7,send_packet_l
  call wait_irq
  call get_status_register

  ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;action cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ACT_CMD:
  clr ea
  mov   a,#16h                ;set byte counter register
  call set_cyl_low_register  ;= 16 bytes
  call set_cyl_high_register ;
  call do_packet_cmd
  mov   packet_cmd,#5ah
  mov   packet_1,#08H  ;
  mov   packet_2,#01  ;PC and page Code
  mov   packet_7,#0ffh        ;allocation length
  mov   packet_8,#0ffh        ;allocation length 
  call send_packet
  jb    STATUS_REG_DRQ,act_ok
  sjmp act_cmd
  
 act_ok:
  call skip_rest_of_packet
  ret
  
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; test unit ready ATAPI command
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
test_unit_ready_cmd:
  clr ea
  call do_packet_cmd
  call send_packet
  jnb   STATUS_REG_ERR,test_unit_ready_d
  clr   c
  ret
test_unit_ready_d:
  setb  c
  ret

wait_for_ready_state:
  mov   r2,#2
wait_for_ready_state_l:
  ;mov   r5,#1
  ;call delay
  call test_unit_ready_cmd
  jnc   wait_for_ready_state_l
  dec   r2
  cjne  r2,#0,wait_for_ready_state_l

  setb DISP_E
  mov LED_W,#11111011B
  MOV LED_D,#11001111B  ;3. 
  CLR DISP_E
  ret

  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Table of Contents command
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_toc_cmd:
  call s_x          ;关显示音量
  mov sense_code,#001h
  clr ea
  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_r
read_toc_cmd_e:
  ;acall read_toc_cmd
  ajmp  terminate_with_error_R

terminate_with_error_R:
 setb DISP_E
 mov LED_W,#11111011B
 MOV LED_D,#11111001B  ;E. 
 CLR DISP_E
 mov r5,#1h
 call delay
 ret
 sjmp $

; read header
;
read_toc_cmd_r:
  acall get_data       ;data length
  acall get_data       ;get track limits
  mov   start_track,a
  mov   end_track,b
  mov a,next_track
  cjne a,end_track,read_toc_cmd_l2
  sjmp read_toc_cmd_l2_end
; 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
;  record MSF position,ready for play
  mov   a,tmp0
  cjne a,next_track,read_toc_cmd_i0_p
  mov   start_M,tmp1
  mov   start_S,tmp2
  mov   start_F,tmp3
read_toc_cmd_i0_P:                  ;next_track不是最后一曲
  inc next_track
  cjne a,next_track,read_toc_cmd_i0_3  ;是下一曲吗?是--继续
  mov n_m,tmp1
  mov n_s,tmp2
 read_toc_cmd_i0_3:
  cjne  a,#0aah,read_toc_cmd_i1_2
  mov   end_M,tmp1
  mov   end_S,tmp2
  mov   end_F,tmp3
 read_toc_cmd_i1_2:
  dec next_track
  acall bsy_wait
  jb    STATUS_REG_DRQ,read_toc_cmd_l2
  setb  c
  ret

read_toc_cmd_l2_end:
  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

  mov   a,tmp0
 cjne a,next_track,read_toc_cmd_i0_end
  mov   start_M,tmp1
  mov   start_S,tmp2
  mov   start_F,tmp3
 read_toc_cmd_i0_end:
  cjne  a,#0aah,read_toc_cmd_i1_2_end
  mov   end_M,tmp1
  mov   end_S,tmp2
  mov   end_F,tmp3
  mov n_s,end_s
  mov n_m,end_m
 read_toc_cmd_i1_2_end:
  acall bsy_wait
  jb    STATUS_REG_DRQ,read_toc_cmd_l2_end
  setb  c
  ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; play MSF cd cmd;按MSF格式播放CD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
play_entire_cd_cmd:
  clr ea
  call 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
  call send_packet
  jnb   STATUS_REG_ERR,play_audio_cmd_d
  ajmp  terminate_with_error
play_audio_cmd_d:
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; read sub channel cmd;CD播放状态信息
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_subchan_cmd:
  clr ea
  mov   a,#016h                ;set byte counter register
  call set_cyl_low_register  ;= 16 bytes
  call set_cyl_high_register ;

  call 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,#016h       ;allocation length (16 bytes)
  call send_packet
  jb    STATUS_REG_DRQ,read_subchan_cmd_r
read_subchan_cmd_e:
  mov   audio_status,#0ffh
  ret

;read Current Audio track,MSF
read_subchan_cmd_r:
  call get_data       ;get audio status
  mov   audio_status,b
  call get_data       ;sub channel data length (will be zero).. ignore
  call get_data       ;data format,adr/fiel
  call get_data       ;current track ,index track
  mov current_track,a
  call get_data       ;M
  mov current_M,b  
  call get_data       ;SF
  mov current_S,a
  mov current_F,b
  call skip_rest_of_packet
  ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; mode sense cmd;CD-ROM状态信息
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mode_sense_cmd:
  clr ea
  mov   a,#16h                ;set byte counter register
  call set_cyl_low_register  ;= 16 bytes
  call set_cyl_high_register ;
  call do_packet_cmd
  mov   packet_cmd,#5ah
  mov   packet_1,#00H  ;
  mov   packet_2,#01H  ;PC and page Code
  mov   packet_7,#0ffh        ;allocation length
  mov   packet_8,#0ffh        ;allocation length 
  call send_packet
  jb    STATUS_REG_DRQ,mode_sense_cmd_r

mode_sense_cmd_e:
  setb DISP_E
 mov LED_W,#11110111B
 MOV LED_D,#11101101B  ;S. 
 CLR DISP_E
  jmp mode_sense_cmd
  ;mov  media_type,#0ffh
  ret
;read Current CD-ROM Media Type Code
mode_sense_cmd_r:
  call get_data   ;mode Data length
  call get_data   ;Medium Type
  mov media_type,a
  call skip_rest_of_packet
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;mode sense read 0E page;读音频控制页
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mode_sense_cmd_0e:
  clr ea
  mov   a,#016h                ;set byte counter register
  call set_cyl_low_register  ;= 16 bytes
  call set_cyl_high_register ;
  call do_packet_cmd
  mov   packet_cmd,#5ah
  mov   packet_1,#000H  ;
  mov   packet_2,#00eH  ;PC and page Code
  mov   packet_7,#000h        ;allocation length
  mov   packet_8,#018h        ;allocation length 
  call send_packet
  jb    STATUS_REG_DRQ,mode_sense_cmd_r_0e
  jmp   mode_sense_cmd_0e
 mode_sense_cmd_r_0e:
   mov r7,#12
   mov r1,#0B0h
   get_audio_data_loop:
   acall get_data
   mov @r1,a
   inc r1
   mov @r1,b
   inc r1
   djnz r7,get_audio_data_loop
   mov r0,#0C1h
   mov volume_1,@r0
   mov r0,#0C3h
   mov volume_2,@r0
   call skip_rest_of_packet
   mov sense_code,#0eh
   setb ea
   ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;mode select(10)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mode_select_cmd:
  clr ea
  mov   a,#0FFh                ;set byte counter register
  call set_cyl_low_register  ;= 16 bytes
  call set_cyl_high_register ;
  call do_packet_cmd
  mov   packet_cmd,#55h
  mov   packet_1,#10H  ;
  mov   packet_2,#000H  ;PC and page Code
  mov   packet_7,#000h        ;allocation length
  mov   packet_8,#018h        ;allocation length 
  call send_packet
  jb  STATUS_REG_DRQ,mode_select_cmd_r
  jmp mode_select_cmd
 mode_select_cmd_r:
  setb ea
  ret
  
mode_sense_10:
  mov a,sense_code
  cjne a,#00eh,ms0e
  ret  
ms0e:
  call mode_sense_cmd_0e
  ret  
v_change:

  mov a,44h
  cjne a,#11h,v_tc1        ;11h=volume +
  jmp volume_inc
  v_tc1:
   cjne a,#99h,v_tc2       ;99h=volume -
   jmp volume_dec
  
  v_tc2:
   
   ret
   
volume_inc:
  mov a,volume_1
  cjne a,#245,v_inc
  call set_v  
  ret
 v_inc:
  jc vup10
  call set_v  
  ret
 vup10:
  mov a,volume_1
  addc a,#10 
  call set_v
  ret
volume_dec:
  mov a,volume_1
  cjne a,#11,v_dec
  mov a,#0
  call set_v
  ret
 v_dec:
  jnc v_dn10

⌨️ 快捷键说明

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