📄 cdpaul.txt
字号:
mov ATA_DATA_MS,b
clr ATA_nDIOW
nop
setb ATA_nDIOW
ret
write_cycle_ls:
mov ATA_DATA_LS,a
clr ATA_nDIOW
nop
setb ATA_nDIOW
ret
wait_irq:
; mov r5,#1
; acall delay
setb ATA_INTRQ
jnb ATA_INTRQ,wait_irq
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; cylinder register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_cyl_high_register:
mov ATA_ADDR,#10110000b
acall read_cycle_ls
ret
get_cyl_low_register:
mov ATA_ADDR,#10010000b
acall read_cycle_ls
ret
set_cyl_high_register:
mov ATA_ADDR,#10110000b
acall write_cycle_ls
ret
set_cyl_low_register:
mov ATA_ADDR,#10010000b
acall write_cycle_ls
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; a = cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_cmd_register:
mov ATA_ADDR,#11110000b
acall write_cycle_ls
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; data register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ret: a = ls b = ms
get_data:
mov ATA_ADDR,#00010000b
acall read_cycle
ret
; a = ls b = ms
set_data:
mov ATA_ADDR,#00010000b
acall write_cycle
ret
; a = ls
set_data_ls:
mov ATA_ADDR,#00010000b
acall write_cycle_ls
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; device/head register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_devhead_register:
mov ATA_ADDR,#11010000b
acall read_cycle_ls
ret
set_devhead_register:
mov ATA_ADDR,#11010000b
acall write_cycle_ls
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; error register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ERROR_REG_AMNF bit acc.0
ERROR_REG_TK0NF bit acc.1
ERROR_REG_ABRT bit acc.2
ERROR_REG_MCR bit acc.3
ERROR_REG_IDNF bit acc.4
ERROR_REG_MC bit acc.5
ERROR_REG_UNC bit acc.6
ERROR_REG_RES bit acc.7
get_error_register:
mov ATA_ADDR,#00110000b
acall read_cycle_ls
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sector register's
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_sector_c_register:
mov ATA_ADDR,#01010000b
acall read_cycle_ls
ret
get_sector_n_register:
mov ATA_ADDR,#01110000b
acall read_cycle_ls
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; status register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STATUS_REG_ERR bit acc.0
STATUS_REG_IDX bit acc.1
STATUS_REG_CORR bit acc.2
STATUS_REG_DRQ bit acc.3
STATUS_REG_DSC bit acc.4
STATUS_REG_DF bit acc.5
STATUS_REG_DRDY bit acc.6
STATUS_REG_BSY bit acc.7
get_status_register:
mov ATA_ADDR,#11110000b
acall read_cycle_ls
ret
bsy_wait:
nop
nop
nop
nop
acall get_status_register
jb STATUS_REG_BSY,bsy_wait
ret
bsy_drdy_wait:
nop
nop
nop
nop
acall delay_100000us
acall get_status_register
jb STATUS_REG_BSY,bsy_drdy_wait
jnb STATUS_REG_DRDY,bsy_drdy_wait
ret
drq_wait:
nop
nop
nop
nop
acall get_status_register
jb STATUS_REG_BSY,drq_wait
jnb STATUS_REG_DRQ,drq_wait
ret
ndrq_wait:
nop
nop
nop
nop
acall get_status_register
jb STATUS_REG_BSY,drq_wait
jb STATUS_REG_DRQ,drq_wait
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; misc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
skip_device_fields:
acall get_data
djnz r7,skip_device_fields
ret
; 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_packet
skip_rest_of_packet_d:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MSF routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_MSF_field:
acall get_data
mov toc_M,b
acall get_data
mov toc_S,a
mov toc_F,b
ret
print_MSF_field_lcd:
; MOV DPTR,#LMESS5 ; Time
; MOV A,#2
; CALL LCD_PRINT
;Print_MSF_field_lcd:
mov a,toc_M
MOV POSITION,#5
CALL SHOW_DIG2
mov a,#':'
Mov b,#7
Call LCDP2
MOV A,toc_S
MOV POSITION,#8
CALL SHOW_DIG2
ret
;print_MSF_field_lcd:
; MOV DPTR,#LMESS5 ; Time
; MOV A,#2
; CALL LCD_PRINT
;Print_MSF_field_lcd:
; mov a,toc_M
; MOV POSITION,#5
; CALL SHOW_DIG2
; MOV A,toc_S
; MOV POSITION,#8
; CALL SHOW_DIG2
; ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; init ATA device routines..
;
; also detects the device during the process of initing it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
init_ata_device:
acall CLR_SCREEN
MOV R5,#10
CALL LCD_DELAY
MOV DPTR,#LMESS3 ; Initing
MOV A,#1
CALL LCD_PRINT
; 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
; setb acc.4
clr acc.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_done
init_device_s_error:
sjmp $
init_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
sjmp $
init_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 ;)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print_device_ansi_lcd:
acall get_data
xch a,b
acall wdata
mov a,b
acall wdata
djnz r6,print_device_ansi_lcd
ret
identify_packet_device:
Call CLR_SCREEN
MOV R5,#10
CALL LCD_DELAY
MOV DPTR,#LMESS6 ; Identifying
MOV A,#1
CALL LCD_PRINT
MOV A,#0C0H
CALL WCOM
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
jb acc.0,identify_packet_device_c2
jb acc.1,identify_packet_device_c2
mov packet_size,#6
sjmp identify_packet_device_c3
identify_packet_device_c2:
jb acc.0,identify_packet_device_c3
jnb acc.1,identify_packet_device_c3
mov packet_size,#8
identify_packet_device_c3:
; skip next 26 words
;
mov r7,#26
acall skip_device_fields
; get model number
;
mov r6,#20
acall print_device_ansi_lcd
acall skip_rest_of_packet
acall bsy_drdy_wait
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
do_packet_cmd:
; 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
;
acall ndrq_wait
mov a,#0a0h
acall set_cmd_register
ret
send_packet:
acall drq_wait
mov r0,#packet_tab
mov r7,packet_size
send_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
mov packet_cmd,#00h
acall send_packet
clr c
jnb STATUS_REG_ERR,test_unit_ready_d
ret
test_unit_ready_d:
setb c
ret
;
wait_for_ready_state:
Reading_CD:
call CLR_SCREEN
MOV R5,#10
CALL LCD_DELAY
MOV DPTR,#LMESS9 ; Insert Audio CD
MOV A,#1
CALL LCD_PRINT
MOV DPTR,#LMESS10 ; Waiting.......
MOV A,#2
CALL LCD_PRINT
wait_for_ready_state_restart:
jnb EJECT_Key,Check_Tray_Status
mov r2,#1
;
wait_for_ready_state_l:
acall delay_100000us
acall delay_100000us
acall delay_100000us
acall test_unit_ready_cmd
jnc wait_for_ready_state_restart
dec r2
cjne r2,#0,wait_for_ready_state_l
ret
Check_Tray_Status:
lcall mode_sense_cmd
mov a,mediatype
cjne a,#71h,open_tray
MOV R5,#10
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -