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

📄 ispcd-romv1.a51

📁 8051 Control IDE CD-Rom
💻 A51
📖 第 1 页 / 共 2 页
字号:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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,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
  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:
  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_CD,check_cd_o
  mov   r2,#1
;
wait_for_ready_state_l:
  acall delay_100000us
  acall delay_100000us
  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_cd_o:
  acall stop_play_cmd
  call  CLR_SCREEN
  MOV     R5,#10
  CALL    LCD_DELAY
  MOV     DPTR,#LMESS11         ; Open Door
  MOV     A,#1
  CALL    LCD_PRINT
  MOV     DPTR,#LMESS12         ; Wait....
  MOV     A,#2
  CALL    LCD_PRINT
  acall do_packet_cmd
  mov   packet_cmd,#11011b
  mov   packet_4,#02h
  acall send_packet
  mov   r5,#1
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; read sub channel cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_subchan_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,#42h
  mov   packet_1,#00000010b  ;MSF=1
  mov   packet_2,#01000000b  ;SubQ=1
  mov   packet_3,#01h        ;format=01  (current position)
  mov   packet_7,#0ffh       ;allocation length
  mov   packet_8,#0ffh       ;(set it to full on)
  acall send_packet
  jb    STATUS_REG_ERR,read_subchan_cmd_e
  jb    STATUS_REG_DRQ,read_subchan_cmd_r
  ret

read_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 get_data   ;format code, ADR, cntl (ignore)
  acall get_data
  mov   current_track,a

read_cmd:
  cjne  a,end_track,calc_next_track_1
  sjmp  calc_next_track_2

calc_next_track_1:
  jc    calc_next_track_2
  mov   a,start_track

calc_next_track_2:
  mov   next_track,a
  MOV     R5,#10
  CALL    LCD_DELAY
  MOV     DPTR,#LMESS13        ; Playing Track
  MOV     A,#1
  CALL    LCD_PRINT
  mov   a,current_track
  MOV  POSITION,#14
  CALL SHOW_DIG1

; skip absolute address pos
  acall get_MSF_field

;  CALL    LCD_PRINT
  MOV     A,#0C0H
  CALL    WCOM

;  acall lcd_home2
  acall get_MSF_field
  acall print_MSF_field_lcd

  acall skip_rest_of_packet
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Table of Contents command
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_toc_cmd:
  CALL   CLR_SCREEN
  MOV     R5,#10
  CALL    LCD_DELAY
  MOV     DPTR,#LMESS15        ; Reading TOC
  MOV     A,#1
  CALL    LCD_PRINT
  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_ERR,read_toc_cmd_e
  jb    STATUS_REG_DRQ,read_toc_cmd_r
  setb  c
  ret
read_toc_cmd_e:
  clr   c
  ret

; 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     R5,#10
  CALL    LCD_DELAY
  MOV     DPTR,#LMESS14        ; Track Range
  MOV     A,#2
  CALL    LCD_PRINT

  mov   a,start_track
  MOV  POSITION,#11
  CALL SHOW_DIG2

  mov   a,end_track
  MOV  POSITION,#14
  CALL SHOW_DIG2

  MOV  a,end_track             ;
  inc  a                       ; Save Last Track & Plus One
  mov  over_track,a            ;


;
; read track descriptors
;
read_toc_cmd_l2:
  acall get_data   ;skip ADR and control fields

  acall get_data   ;get track number
  mov   toc_track,a

  acall get_MSF_field

; if start track, then record start position
;
  mov   a,toc_track
  cjne  a,start_track,read_toc_cmd_i0
  mov   start_M,toc_M
  mov   start_S,toc_S
  mov   start_F,toc_F
read_toc_cmd_i0:

;if the last track, then record as end position
;
  cjne  a,#0aah,read_toc_cmd_i1
  mov   end_M,toc_M
  mov   end_S,toc_S
  mov   end_F,toc_F
read_toc_cmd_i1:

;if next track, then record next position
;
  cjne  a,next_track,read_toc_cmd_i2
  mov   next_M,toc_M
  mov   next_S,toc_S
  mov   next_F,toc_F
read_toc_cmd_i2:

  acall bsy_wait
  jb    STATUS_REG_DRQ,read_toc_cmd_l2
  setb  c
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; stop/play command
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stop_play_cmd:
  acall do_packet_cmd
  mov   packet_cmd,#4eh
  acall send_packet
  ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; play MSF cd cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
play_entire_cd_cmd:
  call  CLR_SCREEN
  MOV     R5,#10
  CALL    LCD_DELAY
  MOV     DPTR,#LMESS13        ; Playing Track
  MOV     A,#1
  CALL    LCD_PRINT
  mov     a,next_track
  MOV     POSITION,#14
  CALL    SHOW_DIG1

  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
  clr   c
  ret
play_audio_cmd_d:
  setb  c
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; program entry point
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
  mov   sp,#STACK_START
  CLR   LCD_EN
  mov   next_track,#1
  mov   toc_M_next,#0
  mov   toc_S_next,#0
  mov   toc_F_next,#0

  acall set_LCD            ; Init & Set LCD to 4bit
  mov   r5,#2
  acall delay

start_over:
  acall init_ata_device
  acall identify_packet_device
  mov   r5,#1
  acall delay
;  SETB  ATA_INTRQ

main_loop:
  acall wait_for_ready_state
  acall read_toc_cmd
  jnc   main_loop

play_cd:
  jnb   PLAY_KEY,main_play
  jnb    EJECT_CD,unload_cd
  jmp   play_cd

main_play:
  mov   r5,#1
  CALL  CLR_SCREEN
  acall play_entire_cd_cmd    ;orignal play cd
  jnc   main_loop
  mov   r5,#1
  acall delay
  CALL  CLR_SCREEN

play_loop:
  acall read_subchan_cmd
  mov   a,audio_status
  cjne  a,#11h,play_stopped  ;if at end then loop
  mov   a,toc_M
  cjne  a,toc_M_next,play_loop_end_cmp
  mov   a,toc_S
  cjne  a,toc_S_next,play_loop_end_cmp
  mov   a,toc_F
  cjne  a,toc_F_next,play_loop_end_cmp
  sjmp  play_stopped

play_loop_end_cmp:
  mov   toc_M_next,toc_M
  mov   toc_S_next,toc_S
  mov   toc_F_next,toc_F
  acall delay_100000us
;
  jnb   NEXT_TRK,play_next_track    ;
  jnb   EJECT_CD,unload_cd          ;
  jnb   Pause_key,Pause_cd
  jnb   STOP_KEY,stop_cd
  jnb   PREVIOUS_TRK,play_previous_track  ;
  sjmp  play_loop

stop_cd:
  acall stop_play_cmd
  mov   next_track,#1
  sjmp  main_loop

play_stopped:
  mov   next_track,#1
  sjmp   play_normal

play_previous_track:
  mov   a,next_track
  dec   a
  cjne  a,#0,play_track_a
  mov   next_track,end_track
  sjmp  play_normal

play_track_a:
  mov   next_track,a
  sjmp  play_normal

play_next_track:
  mov   a,next_track
  inc   a
  cjne  a,over_track,play_track_a
  mov   next_track,#1
  sjmp  play_normal

play_normal:
  acall stop_play_cmd
  acall read_toc_cmd
  jnc   main_loop
  mov   start_M,next_M
  mov   start_S,next_S
  mov   start_F,next_F
  sjmp  main_play

unload_cd:
  acall stop_play_cmd
  call  CLR_SCREEN
  MOV     R5,#10
  CALL    LCD_DELAY
  MOV     DPTR,#LMESS11         ; Open Door
  MOV     A,#1
  CALL    LCD_PRINT
  MOV     DPTR,#LMESS12         ; Wait....
  MOV     A,#2
  CALL    LCD_PRINT
  acall do_packet_cmd
  mov   packet_cmd,#11101011b
  mov   packet_4,#02h
  acall send_packet
  mov   next_track,#1
  jmp   main_loop

Pause_cd:
  mov   r5,#10
  CALL  LCD_DELAY
  MOV   DPTR,#LMESS13A       ; Pause CD
  MOV   A,#1
  CALL  LCD_PRINT
  mov     a,next_track
  MOV     POSITION,#12
  CALL    SHOW_DIG1
  acall   do_packet_cmd
  mov     packet_cmd,#4bh
  mov     packet_8,#00h
  acall   send_packet
  acall delay_100000us
  acall delay_100000us
Pause_Loop:
  jnb     Pause_key,resume_cd
  jmp     Pause_loop
Resume_cd:
  acall   do_packet_cmd
  mov     packet_cmd,#4bh
  mov     packet_8,#01h
  acall   send_packet
  jmp     Play_loop_end_cmp
;                    0123456789012345
LMESS1:       DB    " CD-Rom Player  ",0
LMESS2:       DB    "  Version 5.0   ",0
;
LMESS3:       DB    "Initing         ",0
LMESS4:       DB    "                ",0
;
LMESS5:       DB    "Time   :        ",0
;
LMESS6:       DB    "  Identifying   ",0
;
LMESS7:       DB    "   Close Door   ",0
LMESS8:       DB    "   Waiting...   ",0
;
LMESS9:       DB    "   Reading CD   ",0
LMESS10:      DB    "   Waiting...   ",0
;
LMESS11:      DB    "   Open Door    ",0
LMESS12:      DB    "   Waiting...   ",0
;
LMESS13:      DB    "Playing Track   ",0
;
LMESS13A:     DB    "Pause Track     ",0
;
LMESS14:      DB    "TrackRange   -  ",0
;
LMESS15:      DB    "Reading TOC     ",0
;
LMESS16:      DB    " Please Insert  ",0
LMESS17:      DB    "   Audio CD     ",0
end


⌨️ 快捷键说明

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