;;; ;;; ATAPI CD-ROM Contorler ver 2.6 ;;; 2004/05/30 UENO Tomohiro ;;; ;;; for ATMEL AVRStudio 4.07 ;;; ;;; Device Micro computer : ATMEL AVR 90S8515 with external Xtal 4MHz ;;; LCD Panel ; SUNLIKE SC1602BS*B / Noritake CU16025ECPB-W6J .include "8515def.inc" .def tmp = R16 .def tmp2 = R17 .def ata_addr = R18 .def ata_data = R19 .def atapi_data_low = R20 .def atapi_data_high = R21 .def counter = R22 .def play_flag = R23 .def close_play_flag = R24 .def lcd_track = R25 .def lcd_minute = R26 .def lcd_second = R27 .def total_track = R00 .def total_minute = R01 .def total_second = R02 .def total_frame = R03 .def track = R04 .def minute = R05 .def second = R06 .def frame = R07 .def playing_track = R08 .def playing_minute = R09 .def playing_second = R10 .def playing_frame = R11 .def audio_status = R12 .def sense_key = R13 .def asc = R14 .def ascq = R15 ;;;lcd .equ lcd_e = 5 ; portB .equ lcd_rs = 4 ; portB ;;; atapi ;;; data_low : PORTD ;;; data_high : PORTC .equ dior = 6 ; portB .equ diow = 7 ; portB .equ atapi_reset = 3 ; portA .equ time_buf = 0x60 ;;; button .equ eject_button = 7 .equ foward_button = 6 .equ rewind_button = 5 .equ play_button = 4 rjmp reset ; 1 $000 reset vector reti ; 2 $001 INT0 reti ; 3 $002 INT1 reti ; 4 $003 TIMER1 CAPT reti ; 5 $004 TIMER1 COMPA reti ; 6 $005 TIMER1 COMPB reti ; 7 $006 TIMER1 OVF1 reti ; 8 $007 TIMER1 OVF0 reti ; 9 $008 SPISTC reti ;10 $009 UART RX reti ;11 $00A UART UDRE reti ;12 $00B UART TX reti ;13 $00C ANA_COMP RESET: ldi tmp, high(RAMEND) out SPH, tmp ldi tmp, low(RAMEND) out SPL,tmp rcall wait_10us ; portA initialize ldi tmp,0x0f ; output out DDRA,tmp ldi tmp,0xff ; no pullup out PORTA,tmp ; portB initialize ldi tmp,0xff ; output out DDRB,tmp ldi tmp,0x00 ; no pullup out PORTB,tmp ; portC initialize ldi tmp,0x00 ; output out DDRC,tmp ldi tmp,0xff ; no pullup out PORTC,tmp ; portD initialize ldi tmp,0x00 ; output out DDRD,tmp ldi tmp,0x00 ; no pullup out PORTD,tmp sbi PORTB,lcd_e sbi PORTB,diow sbi PORTB,dior sbi PORTA,atapi_reset rcall lcd_init rcall reset_sequense rcall identify_packet_device rcall wait_1s ldi play_flag,0 ldi close_play_flag,0 media_check: rcall lcd_clear ldi tmp,'D' rcall lcd_put ldi tmp,'i' rcall lcd_put ldi tmp,'s' rcall lcd_put ldi tmp,'c' rcall lcd_put ldi tmp,' ' rcall lcd_put ldi tmp,'c' rcall lcd_put ldi tmp,'h' rcall lcd_put ldi tmp,'e' rcall lcd_put ldi tmp,'c' rcall lcd_put ldi tmp,'k' rcall lcd_put ldi tmp,'i' rcall lcd_put ldi tmp,'n' rcall lcd_put ldi tmp,'g' rcall lcd_put ldi counter,0 tray_check_loop: sbis PINA,eject_button rjmp do_eject rcall wait_10ms rcall wait_10ms rcall request_sense cpi ata_data,0x28 breq tray_check_loop cpi ata_data,0x29 breq tray_check_loop cpi ata_data,0 breq toc_check inc counter cpi counter,250 brne tray_check_loop rcall lcd_clear ldi tmp,'N' rcall lcd_put ldi tmp,'o' rcall lcd_put ldi tmp,' ' rcall lcd_put ldi tmp,'D' rcall lcd_put ldi tmp,'i' rcall lcd_put ldi tmp,'s' rcall lcd_put ldi tmp,'c' rcall lcd_put rjmp tray_check_loop do_eject: rcall lcd_clear ldi tmp,'E' rcall lcd_put ldi tmp,'j' rcall lcd_put ldi tmp,'e' rcall lcd_put ldi tmp,'c' rcall lcd_put ldi tmp,'t' rcall lcd_put rcall open_tray clr close_play_flag do_eject_loop: in tmp,PINA cbr tmp,0x7f ; eject button cpi tmp,0 brne PC+3 rcall close_tray rjmp media_check in tmp,PINA cbr tmp,0xef ; play button cpi tmp,0 brne PC+4 rcall close_tray ldi close_play_flag,1 rjmp media_check rcall get_disk_status cpi ata_data,0x70 breq tray_check_loop cpi ata_data,0x71 breq do_eject_loop cpi ata_data,0x00 breq do_eject_loop cpi ata_data,0x30 breq do_eject_loop toc_check: rcall read_toc mov tmp,total_track inc tmp rcall get_time_table ; total track time table rcall play mov tmp,close_play_flag cpi tmp,0 breq PC+3 clr close_play_flag rjmp PC+2 rcall stop ldi tmp,1 mov playing_track,tmp put_play_number: rcall lcd_clear mov tmp,total_track rcall lcd_put_decimal ldi tmp,' ' rcall lcd_put ldi tmp,'t' rcall lcd_put ldi tmp,'r' rcall lcd_put ldi tmp,'k' rcall lcd_put ldi tmp,' ' rcall lcd_put ldi tmp,' ' rcall lcd_put mov tmp,total_minute rcall lcd_put_decimal ldi tmp,':' rcall lcd_put mov tmp,total_second rcall lcd_put_decimal ldi tmp,':' rcall lcd_put mov tmp,total_frame rcall lcd_put_decimal ldi tmp,0x40 rcall lcd_pos ldi tmp,'P' rcall lcd_put ldi tmp,'l' rcall lcd_put ldi tmp,'a' rcall lcd_put ldi tmp,'y' rcall lcd_put ldi tmp,' ' rcall lcd_put mov tmp,playing_track rcall lcd_put_decimal ldi lcd_track,0xff ldi lcd_minute,0xff ldi lcd_second,0xff button_check: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;put play time sbrs play_flag,0 rjmp put_play_time_skip rcall read_sub_channel mov tmp,audio_status cpi tmp,0x11 breq PC+4 ldi tmp,1 mov playing_track,tmp rjmp stop_playing mov playing_track,track rcall print_play_number put_play_time_skip: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eject sbic PINA,7 rjmp skip_eject sbis PINA,7 rjmp PC-1 rjmp do_eject skip_eject: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ff sbic PINA,6 rjmp skip_ff cpi play_flag,1 breq PC+11 cp playing_track,total_track breq skip_ff inc playing_track cpi play_flag,0 breq PC+3 rcall stop rcall play sbis PINA,6 rjmp PC-1 rjmp put_play_number ldi counter,0 rcall wait_10ms sbis PINA,6 rjmp PC+2 rjmp PC-14 inc counter cpi counter,50 brne PC-6 loop_ff: push minute push second mov tmp,track rcall get_time_table pop tmp add second,tmp pop tmp add minute,tmp inc second inc second inc second inc second mov tmp,second cpi tmp,60 brlo PC+4 subi tmp,60 mov second,tmp inc minute rcall play_sub rcall read_sub_channel rcall print_play_number sbis PINA,6 rjmp loop_ff skip_ff: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;rw sbic PINA,5 rjmp skip_rw cpi play_flag,1 breq PC+11 mov tmp,playing_track cpi tmp,1 breq PC+2 dec playing_track sbis PINA,5 rjmp PC-1 rcall wait_10ms rcall wait_10ms rcall wait_10ms rjmp put_play_number ldi counter,0 rcall wait_10ms sbis PINA,5 rjmp PC+2 rjmp PC+5 inc counter cpi counter,50 brne PC-6 rjmp loop_rw tst minute brne PC+7 mov tmp,second cpi tmp,1 brge PC+5 ldi tmp,1 cp playing_track,tmp breq PC+2 dec playing_track rcall stop rcall play sbis PINA,5 rjmp PC-1 rjmp put_play_number loop_rw: tst minute brne PC+14 mov tmp,second cpi tmp,3 brge PC+11 clr second ldi tmp,1 clr minute clr second clr frame rcall print_play_number sbis PINA,5 rjmp PC-1 rcall play rjmp put_play_number push second push minute mov tmp,lcd_track rcall get_time_table pop tmp add minute,tmp pop tmp add second,tmp mov tmp,second cpi tmp,60 brlo PC+4 subi tmp,60 mov second,tmp inc minute mov tmp,second cpi tmp,3 brlt PC+4 subi tmp,3 mov second,tmp rjmp PC+12 mov tmp,minute cpi tmp,0 brne PC+6 rcall stop rcall play sbis PINA,5 rjmp PC-1 rjmp put_play_number dec minute ldi tmp,-3+60 add second,tmp rcall play_sub rcall read_sub_channel rcall print_play_number mov playing_track,lcd_track sbis PINA,5 rjmp loop_rw skip_rw: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;play sbic PINA,4 rjmp skip_play cpi play_flag,0 brne stop_playing rcall play sbis PINA,4 rjmp PC-1 rjmp skip_play stop_playing: rcall stop sbis PINA,4 rjmp PC-1 rjmp put_play_number skip_play: rjmp button_check ; ; read ATA register ; read_ata_register: sbr ata_addr,0xe0 out PORTB,ata_addr rcall wait_10us cbi PORTB,dior rcall wait_10us in ata_data,PIND sbi PORTB,dior rcall wait_10us ret ; ; write ATA register ; write_ata_register: ldi tmp,0xff out DDRD,tmp sbr ata_addr,0xe0 out PORTB,ata_addr out PORTD,ata_data rcall wait_10us cbi PORTB,diow sbi PORTB,diow ldi tmp,0x00 out DDRD,tmp rcall wait_10us ret ; ; read ATA data register ; read_atapi: ldi ata_addr,0xf0 out PORTB,ata_addr rcall wait_1ms cbi PORTB,dior rcall wait_1ms in atapi_data_high,PINC in atapi_data_low,PIND sbi PORTB,dior rcall wait_1ms ret ; ; write ATA data register ; write_atapi: ldi tmp,0xff out DDRD,tmp out DDRC,tmp ldi ata_addr,0xf0 out PORTB,ata_addr out PORTC,atapi_data_high out PORTD,atapi_data_low rcall wait_10us cbi PORTB,diow sbi PORTB,diow ldi tmp,0x00 out DDRD,tmp out DDRC,tmp rcall wait_10us ret ; ; reset CD-ROM ; reset_sequense: rcall wait_10ms cbi PORTA,atapi_reset rcall wait_10ms sbi PORTA,atapi_reset rcall wait_1ms rcall wait_1ms ldi ata_addr,0x0e rcall read_ata_register sbrc ata_data,7 rjmp PC-3 ldi ata_addr,0x0e ldi ata_data,0xe0 rcall write_ata_register rcall wait_1ms ldi ata_addr,0x0e ldi ata_data,0x02 rcall write_ata_register ldi ata_addr,0x0e rcall read_ata_register sbrc ata_data,7 rjmp PC-3 ret ; ; wait until device can start sending answer data ; check_waiting_data_from_device: ldi ata_addr,0x12 rcall read_ata_register cbr ata_data,0xfc cpi ata_data,0x02 brne PC-4 ldi ata_addr,0x0e rcall read_ata_register cbr ata_data,0x77 cpi ata_data,0x08 brne PC-4 ret ; ; wait until ATAPI command execution has finished ; check_command_transfer_end: ldi ata_addr,0x0e rcall read_ata_register sbrc ata_data,0 rjmp sense_error mov tmp,ata_data cbr tmp,0x37 cpi tmp,0x40 ; if not (BSY=0 and DRDY=1 and DRQ=0) then retry brne check_command_transfer_end ldi ata_addr,0x12 rcall read_ata_register mov tmp,ata_data cbr tmp,0xf8 cpi tmp,0x03 ; fi not (REL=0 and I/O=1 and C/D=1) then retry brne check_command_transfer_end ret ; ; identify packet device ; identify_packet_device: ; device selection protocol ldi ata_addr,0x0e rcall read_ata_register andi ata_data,0x88 cpi ata_data,0x00 brne PC-4 ldi ata_addr,0x16 ldi ata_data,0x00 rcall write_ata_register nop ldi ata_addr,0x0e rcall read_ata_register andi ata_data,0x88 cpi ata_data,0x00 brne PC-4 rcall lcd_clear ldi tmp,'-' rcall lcd_put ldi tmp,'D' rcall lcd_put ldi tmp,'e' rcall lcd_put ldi tmp,'v' rcall lcd_put ldi tmp,'i' rcall lcd_put ldi tmp,'c' rcall lcd_put ldi tmp,'e' rcall lcd_put ldi tmp,'-' rcall lcd_put ldi tmp,0x40 rcall lcd_pos ldi ata_addr,0x16 ldi ata_data,0x00 rcall write_ata_register ldi ata_addr,0x17 ldi ata_data,0xa1 rcall write_ata_register ldi ata_addr,0x0e rcall read_ata_register andi ata_data,0x88 cpi ata_data,0x08 brne PC-4 ldi counter,0 identify_packet_device_loop: rcall read_atapi cpi counter,27 brcs PC+7 cpi counter,27+8 brcc PC+5 mov tmp,atapi_data_high rcall lcd_put mov tmp,atapi_data_low rcall lcd_put inc counter brne identify_packet_device_loop ;;; set features command ldi ata_addr,0x0e ldi ata_data,0x0a rcall write_ata_register ldi ata_addr,0x11 ldi ata_data,0x03 rcall write_ata_register ldi ata_addr,0x12 ldi ata_data,0x01 rcall write_ata_register ldi ata_addr,0x16 ldi ata_data,0x00 rcall write_ata_register ldi ata_addr,0x17 ldi ata_data,0xef rcall write_ata_register ret ; ; send atapi packet command ; send_atapi_command_packet: ldi ata_addr,0x0e rcall read_ata_register sbrc ata_data,7 rjmp PC-3 ldi ata_addr,0x0e ldi ata_data,0x0a rcall write_ata_register ldi ata_addr,0x11 ldi ata_data,0x00 rcall write_ata_register ldi ata_addr,0x13 ldi ata_data,0x00 rcall write_ata_register ldi ata_addr,0x14 ldi ata_data,0xff rcall write_ata_register ldi ata_addr,0x15 ldi ata_data,0xff rcall write_ata_register ldi ata_addr,0x16 ldi ata_data,0x00 rcall write_ata_register ldi ata_addr,0x17 ldi ata_data,0xa0 rcall write_ata_register ldi ata_addr,0x12 rcall read_ata_register cbr ata_data,0xf8 cpi ata_data,0x01 brne PC-4 ldi ata_addr,0x0e rcall read_ata_register cbr ata_data,0x77 cpi ata_data,0x08 brne PC-4 ret ; ; request sense ; request_sense: rcall send_atapi_command_packet ;;; test unit ready ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall send_atapi_command_packet ;;; request sense ldi atapi_data_low ,0x03 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,18 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_waiting_data_from_device ldi ata_data,0 ; set return value = 0 ldi ata_addr,0x10 rcall read_atapi ;0/1 rcall read_atapi ;2/3 cbr atapi_data_low,0xf0 mov ata_data,atapi_data_low rcall read_atapi ;4/5 rcall read_atapi ;6/7 rcall read_atapi ;8/9 rcall read_atapi ;10/11 rcall read_atapi ;12/13 cpi atapi_data_low,0x28 brne PC+2 mov ata_data,atapi_data_low cpi atapi_data_low,0x29 brne PC+2 mov ata_data,atapi_data_low rcall read_atapi ;14/15 rcall read_atapi ;16/17 ret ; ; get disk status ; return value: ata_data, 0x71=tray is opened ; get_disk_status: rcall send_atapi_command_packet ;;; mode_sense ldi atapi_data_low ,0x5a ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x0d ; cdrom pages ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,8+8 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall read_atapi rcall read_atapi push atapi_data_low rcall read_atapi rcall read_atapi rcall read_atapi rcall read_atapi rcall read_atapi rcall read_atapi pop ata_data ret ; ; open tray ; open_tray: rcall send_atapi_command_packet ;;; prevent/allow medium removal ldi atapi_data_low ,0x1e ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall send_atapi_command_packet ;;; start/stop unit ldi atapi_data_low ,0x1b ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x02 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_command_transfer_end ldi play_flag,0 ret ; ; close tray ; close_tray: rcall send_atapi_command_packet ;;; prevent/allow medium removal ldi atapi_data_low ,0x1e ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall send_atapi_command_packet ;;; start/stop unit ldi atapi_data_low ,0x1b ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x03 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_command_transfer_end ldi play_flag,0 ret ; ; read toc ; read_toc: rcall send_atapi_command_packet ;;; prevent/allow medium removal ldi atapi_data_low ,0x43 ldi atapi_data_high,0x02 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0xff rcall write_atapi ldi atapi_data_low ,0xff ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_waiting_data_from_device ldi tmp,1 mov playing_track,tmp ldi tmp,0 mov total_track,tmp ldi YH,high(time_buf) ldi YL,low(time_buf) rcall read_atapi rcall read_atapi loop_read_toc: rcall read_atapi mov audio_status,atapi_data_high rcall read_atapi mov track,atapi_data_low rcall read_atapi mov minute,atapi_data_high rcall read_atapi mov second,atapi_data_low mov frame,atapi_data_high ldi tmp,0xaa cp track,tmp breq PC+11 ldi tmp,0x0f and audio_status,tmp ldi tmp,0x00 cp audio_status,tmp brne PC-16 st Y+,minute st Y+,second st Y+,frame inc total_track rjmp loop_read_toc mov total_minute,minute mov total_second,second mov total_frame,frame rcall check_command_transfer_end ret ; ; return track MSF ; get_time_table: dec tmp push tmp2 ldi tmp2,0 ldi YH,high(time_buf) ldi YL,low(time_buf) add YL,tmp adc YH,tmp2 add YL,tmp adc YH,tmp2 add YL,tmp adc YH,tmp2 ld minute,Y+ ld second,Y+ ld frame,Y+ pop tmp2 ret ; ; play track ; play: mov tmp,playing_track rcall get_time_table mov playing_minute,minute mov playing_second,second mov playing_frame,frame rcall play_sub ldi play_flag,1 ret play_sub: rcall send_atapi_command_packet ;;; play_audio_msf ldi atapi_data_low ,0x47 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 mov atapi_data_high,minute rcall write_atapi mov atapi_data_low ,second mov atapi_data_high,frame rcall write_atapi mov atapi_data_low ,total_minute mov atapi_data_high,total_second rcall write_atapi mov atapi_data_low ,total_frame ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_command_transfer_end ret print_play_number: cp track,lcd_track breq PC+6 mov lcd_track,track ldi tmp,0x45 rcall lcd_pos mov tmp,track rcall lcd_put_decimal cp minute,lcd_minute breq PC+8 mov lcd_minute,minute ldi tmp,0x48 rcall lcd_pos mov tmp,minute rcall lcd_put_decimal ldi tmp,':' rcall lcd_put cp second,lcd_second breq PC+8 mov lcd_second,second ldi tmp,0x4b rcall lcd_pos mov tmp,second rcall lcd_put_decimal ldi tmp,':' rcall lcd_put ldi tmp,0x4e rcall lcd_pos mov tmp,frame rcall lcd_put_decimal ret ; ; pause ; pause: ; tmp=0/1 : pause/resume push tmp rcall send_atapi_command_packet ;;; pause/resume ldi atapi_data_low ,0x4B ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi pop tmp mov atapi_data_low ,tmp ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_command_transfer_end ret ; ; read sub channel ; read_sub_channel: rcall send_atapi_command_packet ;;; read sub-channel ldi atapi_data_low ,0x42 ldi atapi_data_high,0x02 rcall write_atapi ldi atapi_data_low ,0x40 ldi atapi_data_high,0x01 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0xff rcall write_atapi ldi atapi_data_low ,0xff ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_waiting_data_from_device rcall read_atapi mov audio_status,atapi_data_high rcall read_atapi rcall read_atapi rcall read_atapi mov track,atapi_data_low rcall read_atapi rcall read_atapi rcall read_atapi mov minute,atapi_data_high rcall read_atapi mov second,atapi_data_low mov frame,atapi_data_high ret ; ; stop CD ; stop: rcall send_atapi_command_packet ;;; play_audio_msf ldi atapi_data_low ,0x4e ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_command_transfer_end ldi play_flag,0 ret ; ; sense error code ; sense_error: rcall send_atapi_command_packet ;;; request sense ldi atapi_data_low ,0x03 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,18 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi ldi atapi_data_low ,0x00 ldi atapi_data_high,0x00 rcall write_atapi rcall check_waiting_data_from_device ldi ata_addr,0x10 rcall read_atapi ;0/1 rcall lcd_put_hex rcall read_atapi ;2/3 mov sense_key,atapi_data_low rcall read_atapi ;4/5 rcall read_atapi ;6/7 rcall read_atapi ;8/9 rcall read_atapi ;10/11 rcall read_atapi ;12/13 mov asc,atapi_data_low mov ascq,atapi_data_high rcall read_atapi ;14/15 rcall read_atapi ;16/17 ret ; ; print error code (sense_key,asc,ascq) ; print_error: ldi tmp,0x40 rcall lcd_pos ldi tmp,'E' rcall lcd_put ldi tmp,'r' rcall lcd_put ldi tmp,'r' rcall lcd_put ldi tmp,'o' rcall lcd_put ldi tmp,'r' rcall lcd_put ldi tmp,' ' rcall lcd_put mov tmp,sense_key rcall lcd_put_hex mov tmp,asc rcall lcd_put_hex mov tmp,ascq rcall lcd_put_hex ; rjmp PC ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; LCD (SUNLIKE SC1602BS-B) initialize ; lcd_init: ldi counter,0x250 rcall wait_1ms dec counter brne PC-2 ldi tmp,0x03 rcall lcd_control_out rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms ldi tmp,0x03 rcall lcd_control_out rcall wait_1ms ldi tmp,0x03 rcall lcd_control_out rcall wait_1ms ldi tmp,0x02 rcall lcd_control_out ldi tmp,0x28 rcall lcd_control ldi tmp,0x0c rcall lcd_control ldi tmp,0x06 rcall lcd_control ldi tmp,0x01 rcall lcd_control rcall lcd_clear ret ; ; LCD screen clear and move position (0,0) ; lcd_clear: ldi tmp,0x01 rcall lcd_control ret ; ; LCD move position : (0,0)=0x00, (0,1)=0x01, (1,0)=0x40 ; lcd_pos: sbr tmp,0x80 rcall lcd_control ret ; ; LCD put character ; lcd_put: push tmp swap tmp rcall lcd_data_out pop tmp rcall lcd_data_out ret ; ; LCD put number in hex ; lcd_put_hex: ldi tmp2,7 push tmp swap tmp cbr tmp,0xf0 sbr tmp,0x30 cpi tmp,0x3a brcs PC+2 add tmp,tmp2 rcall lcd_put pop tmp cbr tmp,0xf0 sbr tmp,0x30 cpi tmp,0x3a brcs PC+2 add tmp,tmp2 rcall lcd_put ret ; ; LCD put number in decimal ; lcd_put_decimal: mov tmp2,tmp ldi tmp,0 lcd_put_decimal_loop: cpi tmp2,10 brlo lcd_put_decimal_skip subi tmp2,10 inc tmp rjmp lcd_put_decimal_loop lcd_put_decimal_skip: sbr tmp,0x30 rcall lcd_put mov tmp,tmp2 sbr tmp,0x30 rcall lcd_put ret lcd_control: push tmp swap tmp rcall lcd_control_out pop tmp rcall lcd_control_out rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms ret lcd_control_out: cbr tmp,0x10 ;rs sbr tmp,0xe0 ;e,dior,diow out PORTB,tmp rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms cbi PORTB,lcd_e sbi PORTB,lcd_e rcall wait_1ms ret lcd_data_out: sbr tmp,0xf0 ;rs,e,dior,diow out PORTB,tmp rcall wait_1ms cbi PORTB,lcd_e sbi PORTB,lcd_e ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; wait 1 second ; wait_1s: push tmp ldi tmp,250 wait_1s_a: rcall wait_1ms dec tmp brne wait_1s_a ldi tmp,250 wait_1s_b: rcall wait_1ms dec tmp brne wait_1s_b ldi tmp,250 wait_1s_c: rcall wait_1ms dec tmp brne wait_1s_c ldi tmp,250 wait_1s_d: rcall wait_1ms dec tmp brne wait_1s_d pop tmp ret ; ; wait 1 ms ; wait_1ms: push tmp ldi tmp,255 wait_1ms_loop: nop nop nop nop nop nop nop nop nop nop nop nop nop nop dec tmp brne wait_1ms_loop pop tmp ret ; ; wait 10 us ; wait_10us: push tmp ldi tmp,10 nop dec tmp brne PC-2 pop tmp ret ; ; wait 10 ms ; wait_10ms: rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms rcall wait_1ms ret