	NOLIST
;	This file is part of picide, ATA(PI) interface to PIC18 family MCUs.
;	Copyright (C) 2004-5 Toby Thain, toby@telegraphics.com.au

;	This program is free software; you can redistribute it and/or modify
;	it under the terms of the GNU General Public License as published by  
;	the Free Software Foundation; either version 2 of the License, or
;	(at your option) any later version.

;	This program is distributed in the hope that it will be useful,
;	but WITHOUT ANY WARRANTY; without even the implied warranty of
;	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;	GNU General Public License for more details.

;	You should have received a copy of the GNU General Public License  
;	along with this program; if not, write to the Free Software
;	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
	LIST

	TITLE picide
	SUBTITLE "Main program"

;; Version history
;; 16-Oct-2004: 0.1 - started by Toby
;; 23-Feb-2005: 1.0 - public release under GPL

; this module contains the PIC reset & interrupt vectors, and main program.

; main program currently:
; - initialises RS232 and IDE
; - probes one or two ATA(PI) devices (master, and slave if attached)
; - does some drive commands (read 1 sector from each device)

#include "defs.inc"
#include "idecmd.inc"
#include "atapidefs.inc"

	extern init_rs232,putch,getch
	extern dumpsec

	extern init_ide,ide_identify,ide_idle
	extern ide_lbacmd,ide_rdata,ide_wdata
	extern ide_probe,ide_atapiiddev,ide_checkerr
	extern idecmd,seccnt,feat,lba0,lba8,lba16,lba24
	extern atapi_read10,atapi_readcd,atapi_reqsense,atapi_modesense,atapi_zeropkt
	extern atapi_readcapacity,atapi_checkerr,atapipkt

	extern putdec,putdec16,puthex,dec16

	global stop,devtype,tick1khz

;;; DATA -------------------------------------------------

	udata_acs

probecnt res 1	; # devices to probe
errcode	res 1
devtype	res 2	; device types, two entries
temp	res 2
tick1khz res 3	; 1kHz interrupt driven tick count (if used)

;;; RESET vector --------------------------------------------
	org 0
	
	bra start

;;; MAIN PROGRAM -----------------------------------------------
	org 0x40

start:	clrf INTCON	; disable all interrupts

	; initialise serial and IDE
	call init_rs232
	call init_ide	; returns # of possible devices in W (1 or 2)
	movwf probecnt

	_puts "\r\nPIC START\r\n\0"
	
	; probe one or both attached IDE devices

	clrf devtype+0
	clrf devtype+1

	movlw IDE_DRVHEAD_LBA|IDE_DEVICE1 ; default value for drive/head sel
	movwf lba24		; select device 1
	btfss probecnt,1	; probe two?
	  bra probe0
	; probe device 1
	_puts "1: \0"
	call ide_probe		; leaves device type in Wreg
	movwf devtype+1
probe0:	; probe device 0
	bcf lba24,DEVBIT	; select device 0
	_puts "0: \0"
	call ide_probe		; leaves device type in Wreg
	movwf devtype+0

	_puts "\r\nReady\r\n\0"
	
	movlw IDE_DRVHEAD_LBA	; default value for drive/head sel
	movwf lba24		; select drive 0
	movf devtype+0,w
	rcall trydevice		; do something with it

	bsf lba24,DEVBIT	; select device 1
	movf devtype+1,w
	rcall trydevice		; do something with it

	; we're finished.
	bra stop

;---------------------------------------------------------
trydevice:
	; do something with this device
	; device type in W
	; expects lba24 to be initialised with device select

	xorlw DEV_ATA	; is it ATA?
	bnz notata	; no...

; ----- ATA device
	; set up sector address (LBA)
	; lba24 already set up
	clrf lba16
	clrf lba8
	clrf lba0

	; log what we're about to do
	_puts "ATA Read Sec=0x\0"	
	movf lba16,w
	call puthex
	movf lba8,w
	call puthex
	movf lba0,w
	call puthex
	_crlf

	; set up sector count
	movlw 1
	movwf seccnt

	movlw IDE_CMD_READ
	call ide_lbacmd
	addlw 0
	bnz goterr

	movlw 0	; 256 words, seccnt already set
	call ide_rdata
	call ide_checkerr	; always check error
	addlw 0
	bnz goterr

	; dump the sector data, just to prove we did it
	_crlf
	movlw 32
	call dumpsec

	return	; done with ATA device 


notata:	xorlw DEV_ATAPI ^ DEV_ATA	; is it ATAPI?
	bnz dunno	; nope. give up.

; ----- ATAPI device
	; ...try to read sector 16
	movlw 16
	movwf ATAPI_LBA0
	clrf ATAPI_LBA8
	clrf ATAPI_LBA16

retryread:
	call atapi_zeropkt

	; log what we're doing
	_puts "\r\nATAPI Read Sec=0x\0"
	movf ATAPI_LBA16,w
	call puthex
	movf ATAPI_LBA8,w
	call puthex
	movf ATAPI_LBA0,w
	call puthex
	_crlf

	; read one sector
	movlw 1
	movwf ATAPI_LEN0

	call atapi_read10
	xorlw ATAPI_RETRY	; retry suggested?
	bnz noretry
	
	_puts "Retrying...\r\n\0"
	bra retryread
	
noretry:
	xorlw ATAPI_RETRY	; restore error
	bnz goterr
	
	; now dump sector data
	movlw 2048/16
	call dumpsec

	return	; done with ATAPI device

dunno:	_puts "No device??\r\n\0"
	return

;---------------------------------------------------------
goterr:	_puts "Error. \0"
stop:	_puts "\r\nSTOP.\r\n\0"
	clrwdt
	bra $-2

;---------------------------------------------------------
	end

