Выкладываю как есть дабы не пропало. Программа для AT89C51 для управления компьютерным CD-ROM. Типа аудио плеер. Делал очень давно, путем тупого перевода с ассемблера. Работала на ура.
Код:
'CD-ROM Player 'YDE 2009 Dim A As Byte Config Lcd = 16 * 2 'configure lcd screen Config Lcdpin = Pin , Db4 = P2.4 , Db5 = P2.5 , Db6 = P2.6 , Db7 = P2.7 , E = P2.0 , Rs = P2.3 ' variable data Dim Al As Byte , Bl As Byte , I As Byte Dim Packet_size As Byte 'start_track 'end_track 'current_track 'next_track 'toc_track 'toc_M 'toc_S 'toc_F 'toc_M_next 'toc_S_next 'toc_F_next 'start_M 'start_S 'start_F 'end_M 'end_S 'end_F 'next_M 'next_S 'next_F 'audio_status 'over_track Dim Packet_tab(15) As Byte 'Dim Packet_cmd As Byte 'Position data 35H Ata_nreset Alias P3.0 ' Ata Reset Ata_ndiow Alias P3.1 Ata_ndior Alias P3.2 Ata_intrq Alias P2.2 ' * * 'data bus Ata_data_ls Alias P1 Ata_data_ms Alias P0 Ata_addr Alias P2 Status_reg_err Alias Al.0 Status_reg_idx Alias Al.1 Status_reg_corr Alias Al.2 Status_reg_drq Alias Al.3 Status_reg_dsc Alias Al.4 Status_reg_df Alias Al.5 Status_reg_drdy Alias Al.6 Status_reg_bsy Alias Al.7 Error_reg_amnf Alias Al.0 Error_reg_tk0nf Alias Al.1 Error_reg_abrt Alias Al.2 Error_reg_mcr Alias Al.3 Error_reg_idnf Alias Al.4 Error_reg_mc Alias Al.5 Error_reg_unc Alias Al.6 Error_reg_res Alias Al.7 Main: Cls 'clear the LCD display Lcd "Hello world." 'display this at the top line Lowerline 'Home Upper Lcd "init" 'display this at the top line Gosub Init_ata_device Cls 'clear the LCD display Lcd "Y.D.E. HёБїЗє!" 'display this at the top line. Lowerline 'Home Upper Lcd "Open CD" 'display this at the top line Gosub Open_cd Do Loop '****************************************** read_cycle: Ata_data_ls = 255 'уст порты в 1 для чтения Ata_data_ms = 255 Reset Ata_ndior Al = Ata_data_ls 'считываем Bl = Ata_data_ms Set Ata_ndior Return read_cycle_ls: Ata_data_ls = 255 Reset Ata_ndior Al = Ata_data_ls Set Ata_ndior Return write_cycle: Ata_data_ls = Al Ata_data_ms = Bl Reset Ata_ndiow Waitms 1 'nop Set Ata_ndiow Return write_cycle_ls: Ata_data_ls = Al Reset Ata_ndiow Waitms 1 'nop Set Ata_ndiow Return wait_irq: Set Ata_intrq If Ata_intrq = 0 Then Goto Wait_irq Return '****************************************** ' al = cmd '****************************************** set_cmd_register: Ata_addr = &B11110000 Gosub Write_cycle_ls Return '****************************************** ' data register '****************************************** ' ret: al = ls bl = ms get_data: Ata_addr = &B00010000 Gosub Read_cycle Return ' al = ls bl = ms set_data: Ata_addr = &B00010000 Gosub Write_cycle Return ' al = ls set_data_ls: Ata_addr = &B00010000 Gosub Write_cycle_ls Return '****************************************** ' status register '****************************************** get_status_register: Ata_addr = &B11110000 Gosub Read_cycle_ls Return bsy_wait: ' nop ' nop ' nop ' nop Waitms 4 Gosub Get_status_register If Status_reg_bsy = 1 Then Goto Bsy_wait Return bsy_drdy_wait: ' nop ' nop ' nop ' nop Waitms 100 ' Gosub Delay_100000us Gosub Get_status_register If Status_reg_bsy = 1 Then Goto Bsy_drdy_wait If Status_reg_drdy = 0 Then Goto Bsy_drdy_wait Return drq_wait: ' nop ' nop ' nop ' nop Waitms 4 Gosub Get_status_register If Status_reg_bsy = 1 Then Goto Drq_wait If Status_reg_drq = 0 Then Goto Drq_wait Return ndrq_wait: ' nop ' nop ' nop ' nop Waitms 4 Gosub Get_status_register If Status_reg_bsy = 1 Then Goto Drq_wait If Status_reg_drq = 1 Then Goto Drq_wait Return '****************************************** ' device/head register '****************************************** get_devhead_register: Ata_addr = &B11010000 Gosub Read_cycle_ls Return set_devhead_register: Ata_addr = &B11010000 Gosub Write_cycle_ls Return '****************************************** ' cylinder register '****************************************** get_cyl_high_register: Ata_addr = &B10110000 gosub read_cycle_ls return get_cyl_low_register: Ata_addr = &B10010000 gosub read_cycle_ls return set_cyl_high_register: Ata_addr = &B10110000 gosub write_cycle_ls return set_cyl_low_register: Ata_addr = &B10010000 gosub write_cycle_ls return '****************************************** ' работа с пакетами '****************************************** do_packet_cmd: ' clr packet tab For I = 0 To 15 'очищаем пакет Packet_tab(i) = 0 Next I ' mov r0,#packet_tab ' mov r7,#16 'init_pck_l: ' mov @r0,#0 ' inc r0 ' djnz r7,init_pck_l ' send packet command gosub ndrq_wait Al = &H0A0 gosub set_cmd_register Return send_packet: gosub drq_wait I = 0 Send_packet_l: Al = Packet_tab(i) Incr I Bl = Packet_tab(i) Incr I Gosub Set_data 'записываем в CD Rom If I < 15 Then Goto Send_packet_l 'mov r7,packet_size Gosub Wait_irq gosub get_status_register Return '****************************************** ' error register '****************************************** Get_error_register: Ata_addr = &B00110000 Gosub Read_cycle_ls Return '****************************************** ' init ATA device routines.. ' also detects the device during the process of initing it. '****************************************** init_ata_device: ' do hard reset.. ' nb/ you have a wait a bit after pulling the reset back high. if you ' Dont , Then Bsy Flag Will Falsey Pass. I Havent Figured Out A Way ' yet to determine when the device controller is busy during hard reset ' Reset Ata_nreset Waitms 100 'acall delay_100000us Set Ata_nreset Wait 2 Gosub Bsy_wait 'select device 0 ' The Device Will Now Respond To Commands Now Gosub Get_devhead_register ' setb acc.4 Reset Al.4 ' Set Device To 0 Gosub 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. gosub bsy_wait gosub get_cyl_low_register ' cjne a,#14h,init_device_s_error gosub get_cyl_high_register ' cjne a,#0ebh,init_device_s_error Goto 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 Al = &H90 Gosub Set_cmd_register Gosub Bsy_wait Gosub Get_error_register ' jb acc.0,init_device_c1 ' sjmp $ init_device_c1: return '****************************************** ' открыть трей '****************************************** Open_cd: ' acall stop_play_cmd Gosub Do_packet_cmd 'очищаем пакет Packet_tab(0) = &B00011011 'загружаем команду работы с треем(лотком) ' mov packet_4,#02h Packet_tab(4) = &H02 'команда выдвинуть трей (остальные нули) Gosub Send_packet 'отправляем пакет ' mov next_track,#1 ' jmp main_loop Return