📄 cdc_fw_v13_asm.asm
字号:
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 + -