; ====================================================================
;
; designed for one device only (set to master)
;
; design references:
CODE_BASE	equ	00h
STACK_START	equ	3fh

;ctrl bus
;
;  7   6   5   4   3   2   1   0
;+DA2+DA1+DA0+CS0+CS1+---+---+---+
;| X | X | X | X | X |   |   |   |
;+---+---+---+---+---+---+---+---+
;
ATA_ADDR	reg	p2

;ctrl

ATA_nDIOR	reg	p3.6      ;read strobe
ATA_nDIOW	reg	p3.4      ;write strobe
ATA_nRESET	reg	p3.2     ;reset
ATA_INTRQ	reg	p3.7      ;irq

;data bus
ATA_data_LS	reg	p0
ATA_data_MS	reg	p1

; variable data
;

packet_size     	equ  	08h
start_track		equ	09h
tmp0 		equ	0ah
tmp1		equ	0bh
tmp2		equ	0ch
tmp3		equ	0dh
start_M		equ	0eh
start_S		equ	0fh
start_F		equ	10h
end_M		equ	11h
end_S		equ	12h
end_F		equ	13h
total_M		equ	14h
total_S		equ 	15h
audio_status	equ	16h
end_track		equ	17h
playing_track	equ	18h


packet_tab	equ	70h
packet_cmd	equ	70h
packet_1		equ	71h
packet_2		equ	72h
packet_3		equ	73h
packet_4		equ	74h
packet_5		equ	75h
packet_6		equ	76h
packet_7		equ	77h
packet_8		equ	78h
packet_9		equ	79h
packet_10		equ	7ah
packet_11		equ	7bh
packet_12		equ	7ch
packet_13		equ	7dh
packet_14		equ	7eh
packet_15		equ	7fh

	org	CODE_BASE
	ajmp	start

;  db 'Copyright (C) 2000 Jason Nunn <jsno@downunder.net.au>.'

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; atomic routines
;
; Nb/ code assumes 1us clock cycle (12Mhz xtal clock)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

delay_100000us:
  	mov   	r7,#0c8h
delay_100000us_l0:
  	mov   	r6,#0f8h
delay_100000us_l1:
  	djnz  	r6,delay_100000us_l1
  	nop
  	djnz  	r7,delay_100000us_l0
  	ret

;r5 = seconds
delay:
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	acall 	delay_100000us
  	djnz  	r5,delay
  	ret

read_cycle:
  	mov   	ATA_data_LS,#0ffh
  	mov   	ATA_data_MS,#0ffh
  	clr   	ATA_nDIOR
  	mov   	a,ATA_data_LS
  	mov   	b,ATA_data_MS
  	setb  	ATA_nDIOR
  	ret

read_cycle_ls:
  	mov   	ATA_data_LS,#0ffh
  	clr   	ATA_nDIOR
  	mov   	a,ATA_data_LS
  	setb  	ATA_nDIOR
  	ret

write_cycle:
  	mov   	ATA_data_LS,a
  	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:
  	setb  	ATA_INTRQ
  	jnb   	ATA_INTRQ,wait_irq
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; cylinder register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_cyl_high_register:
  	mov   	ATA_ADDR,#10101000b
  	acall 	read_cycle_ls
  	ret

get_cyl_low_register:
  	mov   	ATA_ADDR,#10001000b
  	acall 	read_cycle_ls
  	ret

set_cyl_high_register:
  	mov   	ATA_ADDR,#10101000b
  	acall 	write_cycle_ls
  	ret

set_cyl_low_register:
  	mov   	ATA_ADDR,#10001000b
  	acall 	write_cycle_ls
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; a = cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_cmd_register:
  	mov   	ATA_ADDR,#11101000b
  	acall 	write_cycle_ls
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; data register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; ret: a = ls  b = ms
get_data:
  	mov   	ATA_ADDR,#00001000b
  	acall 	read_cycle
  	ret

; a = ls  b = ms
set_data:
 	mov   	ATA_ADDR,#00001000b
  	acall 	write_cycle
  	ret

; a = ls
set_data_ls:
  	mov   	ATA_ADDR,#00001000b
  	acall 	write_cycle_ls
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; device/head register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_devhead_register:
  	mov   	ATA_ADDR,#11001000b
  	acall 	read_cycle_ls
  	ret

set_devhead_register:
  	mov   	ATA_ADDR,#11001000b
  	acall 	write_cycle_ls
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; error register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ERROR_REG_AMNF	reg	acc.0
ERROR_REG_TK0NF	reg	acc.1
ERROR_REG_ABRT	reg	acc.2
ERROR_REG_MCR	reg	acc.3
ERROR_REG_IDNF	reg	acc.4
ERROR_REG_MC		reg	acc.5
ERROR_REG_UNC	reg	acc.6
ERROR_REG_RES		reg	acc.7

get_error_register:
  	mov   	ATA_ADDR,#00101000b
  	acall 	read_cycle_ls
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sector register's
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_sector_c_register:
  	mov   	ATA_ADDR,#01001000b
  	acall 	read_cycle_ls
  	ret

get_sector_n_register:
  	mov   	ATA_ADDR,#01101000b
  	acall 	read_cycle_ls
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; status register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STATUS_REG_ERR	reg	acc.0
STATUS_REG_IDX	reg	acc.1
STATUS_REG_CORR	reg	acc.2
STATUS_REG_DRQ	reg	acc.3
STATUS_REG_DSC	reg	acc.4
STATUS_REG_DF		reg	acc.5
STATUS_REG_DRDY	reg	acc.6
STATUS_REG_BSY	reg	acc.7

get_status_register:
  	mov   	ATA_ADDR,#11101000b
  	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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

terminate_with_error:
  	sjmp  	$

; 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 data 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
  	clr   	p0.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:
  	ajmp  	terminate_with_error
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
  	ajmp  	terminate_with_error
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 ;)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
identify_packet_device:

;identify device cmd
;
  	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   	b,#6
identify_packet_device_c2:
  	jb    	acc.0,identify_packet_device_c3
  	jnb   	acc.1,identify_packet_device_c3
  	mov   	b,#8
identify_packet_device_c3:
  	mov   	packet_size,b

  	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

  	acall 	ndrq_wait
  	mov   	a,#0a0h
  	acall 	set_cmd_register
  	ret

; send packet command
;

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
  	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
  	acall 	delay
  	acall 	test_unit_ready_cmd
 	jnc   	wait_for_ready_state_l
  	dec   	r2
  	cjne  	r2,#0,wait_for_ready_state_l
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Table of Contents command
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_toc_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,#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:
  	ajmp  	terminate_with_error

; 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
; 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
; if playing track, then record start position
;
  	mov   	a,tmp0
  	cjne  	a,#0aah,read_toc_cmd_i3
  	mov   	total_M,tmp1
  	mov   	total_S,tmp2
 	 jmp	read_toc_cmd_i1

read_toc_cmd_i3:
 	cjne  	a,playing_track,read_toc_cmd_i1
  	mov   	start_M,tmp1
  	mov   	start_S,tmp2
  	mov   	start_F,tmp3

  	acall 	get_data   ;get ADR and control fields
  	acall 	get_data   ;get track number
  	acall	get_data
  	mov   	end_M,b
  	acall 	get_data
  	mov   	end_S,a
  	mov   	end_F,b
   
read_toc_cmd_i1:
 	acall 	bsy_wait
  	jb    	STATUS_REG_DRQ,read_toc_cmd_l2
	acall	tram_uart_data
 	setb  	c
  	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; play MSF cd cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
play_cmd:
	jnb	UART_cmd_play,play_end
  	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
	mov	a,#0
play_end:

  	ret


;------------------------------------------------------------------------
UART_cmd_play		reg	acc.0
UART_cmd_pause		reg	acc.1
UART_cmd_Resume	reg	acc.2
UART_cmd_Stop		reg	acc.3
UART_cmd_Eject		reg	acc.4
UART_cmd_close		reg	acc.5
UART_cmd_track		reg	acc.7

Stop_cmd:		
	jnb	UART_cmd_Stop,Stop_end
  	acall 	do_packet_cmd
  	mov   	packet_cmd,#1bh
  	mov   	packet_4,#00h
  	acall 	send_packet
	mov	a,#0
Stop_end:
  	ret

Pause_cmd:		
	jnb	UART_cmd_pause,Pause_end
  	acall 	do_packet_cmd
  	mov   	packet_cmd,#4bh
  	acall 	send_packet
	mov	a,#0
Pause_end:
  	ret

Resume_cmd:		
	jnb	UART_cmd_Resume,Resume_end
  	acall 	do_packet_cmd
  	mov   	packet_cmd,#4bh
  	mov   	packet_8,#01h
  	acall 	send_packet
	mov	a,#0
Resume_end:
  	ret

Track_num:
	jnb	UART_cmd_track,Track_num_end
	anl	a,#7fh
	mov	playing_track,a
	acall	read_toc_cmd	
	mov	a,#0
Track_num_end:
	ret

Eject_door_cmd:		
  	jnb	UART_cmd_Eject,Eject_door_end
	acall 	do_packet_cmd
 	mov   	packet_cmd,#1bh
  	mov   	packet_4,#02h
  	acall 	send_packet
	mov	a,#0
Eject_door_end:
  	ret 

close_door_cmd:		
	jnb	UART_cmd_close,close_door_end
 	acall 	do_packet_cmd
  	mov   	packet_cmd,#1bh
 	mov   	packet_4,#03h
  	acall 	send_packet
	mov	a,#0
	ajmp	start
close_door_end:
	ret
;=====================================
;=========   串列接收等待副程式   =========
;=====================================

wait_uart_data:
	jnb	ri,wait_uart_data
	clr	ri
	mov	a,sbuf
	acall	ckeck_uart
	ret

;=====================================
;========   串列傳送等待副程式   ==========
;=====================================

tram_uart_wait:
	jbc	ti,tram_ok
	jmp	tram_uart_wait
tram_ok:	
	ret


;=====================================
;========   串列傳輸初始化副程式   ========
;=====================================
initial_uart:
	mov	tmod,#20h	;
	mov	th1,#0fdh		;傳輸速率 9600 bps
	mov	scon,#050h	;設定串列傳輸 mode 1
	setb	ea		;致能中斷源
	setb	es		;致能串列埠
	setb	tr1		;致能 timer 1
	ret
;=====================================
;===========   Uart 掃描副程式   ===========
;=====================================
ckeck_uart:					
	acall	Track_num
	acall	play_cmd
	acall	Pause_cmd
	acall	Resume_cmd	
	acall	Stop_cmd
	acall	Eject_door_cmd
	acall	close_door_cmd
	ret

;=====================================
;===========   串列傳送副程式   ===========
;=====================================
tram_uart_data:

	mov	sbuf,end_track
	acall	tram_uart_wait
  	acall 	delay_100000us

	acall	song_time
	mov	a,end_M
	subb	a,start_M
	mov	sbuf,a
	acall	tram_uart_wait
  	acall 	delay_100000us

	mov	a,end_S
	subb	a,start_S
	subb	a,#3
	mov	sbuf,a
	acall	tram_uart_wait
  	acall 	delay_100000us

	mov	sbuf,total_M
	acall	tram_uart_wait
  	acall 	delay_100000us
	mov	sbuf,total_S
	acall	tram_uart_wait
	ret	

song_time:
	mov	a,end_S
	mov	b,start_S
	div	ab
	jz	sub_time_1
	ret
sub_time_1:
	dec	end_M
	mov	a,end_S
	add	a,#3ch
	mov	end_S,a
	ret		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; program entry point
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

start:
 	 mov   	sp,#STACK_START  ;set stack position
start_over:
  	acall 	init_ata_device
  	acall 	identify_packet_device
  	mov   	r5,#1
  	acall 	delay
  	acall 	wait_for_ready_state
  	acall 	initial_uart
   	acall 	read_toc_cmd
main_loop:
 	acall	wait_uart_data
	acall	wait_uart_data
play_loop:
	jnb	ri,play_loop
	clr	ri
	mov	a,sbuf
	acall	ckeck_uart
	jmp	play_loop
	
	end
	
