timeout = set_timer_ms(500);
while(true){
- status = ide_reg_status;
+ status = devide_readb(ide_reg_status);
if((status & (IDE_STATUS_BUSY | IDE_STATUS_ERROR | bits)) == bits)
return true;
#if defined(__SDCC_z80) || defined(__SDCC_z180) || defined(__SDCC_gbz80) || defined(__SDCC_r2k) || defined(__SDCC_r3k)
/* sdcc sadly unable to figure this out for itself yet */
p = ((uint8_t *)&blk_op.lba)+3;
- ide_reg_lba_3 = (*(p--) & 0x0F) | ((drive == 0) ? 0xE0 : 0xF0); // select drive, start loading LBA
- ide_reg_lba_2 = *(p--);
- ide_reg_lba_1 = *(p--);
- ide_reg_lba_0 = *p;
+ devide_writeb(ide_reg_lba_3, (*(p--) & 0x0F) | ((drive == 0) ? 0xE0 : 0xF0)); // select drive, start loading LBA
+ devide_writeb(ide_reg_lba_2, *(p--));
+ devide_writeb(ide_reg_lba_1, *(p--));
+ devide_writeb(ide_reg_lba_0, *p);
#else
- ide_reg_lba_3 = ((blk_op.lba >> 24) & 0xF) | ((drive == 0) ? 0xE0 : 0xF0); // select drive, start loading LBA
- ide_reg_lba_2 = (blk_op.lba >> 16);
- ide_reg_lba_1 = (blk_op.lba >> 8);
- ide_reg_lba_0 = blk_op.lba;
+ devide_writeb(ide_reg_lba_3, ((blk_op.lba >> 24) & 0xF) | ((drive == 0) ? 0xE0 : 0xF0)); // select drive, start loading LBA
+ devide_writeb(ide_reg_lba_2, (blk_op.lba >> 16));
+ devide_writeb(ide_reg_lba_1, (blk_op.lba >> 8));
+ devide_writeb(ide_reg_lba_0, blk_op.lba);
#endif
if(!devide_wait(IDE_STATUS_READY))
return 0;
- ide_reg_sec_count = 1;
- ide_reg_command = blk_op.is_read ? IDE_CMD_READ_SECTOR : IDE_CMD_WRITE_SECTOR;
+ devide_writeb(ide_reg_sec_count, 1);
+ devide_writeb(ide_reg_command, blk_op.is_read ? IDE_CMD_READ_SECTOR : IDE_CMD_WRITE_SECTOR);
if(!devide_wait(IDE_STATUS_DATAREQUEST))
return 0;
/* check drive has a cache and was written to since the last flush */
if(blk_op.blkdev->driver_data & (FLAG_WRITE_CACHE | FLAG_CACHE_DIRTY)
== (FLAG_WRITE_CACHE | FLAG_CACHE_DIRTY)){
- ide_reg_lba_3 = ((drive == 0) ? 0xE0 : 0xF0); // select drive
+ devide_writeb(ide_reg_lba_3, ((drive == 0) ? 0xE0 : 0xF0)); // select drive
if(!devide_wait(IDE_STATUS_READY)){
udata.u_error = EIO;
return -1;
}
- ide_reg_command = IDE_CMD_FLUSH_CACHE;
+ devide_writeb(ide_reg_command, IDE_CMD_FLUSH_CACHE);
if(!devide_wait(IDE_STATUS_READY)){
udata.u_error = EIO;
/* The innermost part of the transfer routines has to live in common memory */
/* since it must be able to bank switch to the user memory bank. */
/****************************************************************************/
+#ifndef IDE_REG_INDIRECT
COMMON_MEMORY
void devide_read_data(void) __naked
jp map_kernel ; else map kernel then return
__endasm;
}
-
+#endif
Define DEVICE_IDE if IDE hardware is present on your platform.
Define IDE_8BIT_ONLY if the system implements only half of the 16-bit data
- bus (eg N8VEM Mark IV).
-
- If the IDE registers appear in one contiguous block then define IDE_REG_BASE
- and either IDE_REG_CS0_FIRST or IDE_REG_CS1_FIRST.
-
- If the IDE registers appear in two non-contiguous blocks then define both
- IDE_REG_CS0_BASE and IDE_REG_CS1_BASE.
-
- If neither of these is suitable just define the address of each register
- ie IDE_REG_DATA, IDE_REG_ERROR, etc.
+ bus (eg n8vem-mark4).
+
+ Define IDE_REG_INDIRECT if the IDE registers are not directly addressable on
+ your platform. If you do not define IDE_REG_INDIRECT then IDE registers
+ should be directly addressable by CPU I/O operations.
+
+ If IDE_REG_INDIRECT is defined you will need to provide devide_readb() and
+ devide_writeb() to access the IDE registers. You will need to define
+ suitable values for each register (ide_reg_data, ide_reg_error etc) to be
+ passed to these functions. You will also need to provide devide_read_data()
+ and devide_write_data() to transfer sectors. See zeta-v2's PPIDE device code
+ for an example of how to do this.
+
+ If IDE_REG_INDIRECT is not defined: If the IDE registers appear in one
+ contiguous block then define IDE_REG_BASE and either IDE_REG_CS0_FIRST or
+ IDE_REG_CS1_FIRST. If the IDE registers appear in two non-contiguous blocks
+ then define both IDE_REG_CS0_BASE and IDE_REG_CS1_BASE. If neither of these
+ is suitable just define the address of each register ie IDE_REG_DATA,
+ IDE_REG_ERROR, etc.
*/
void devide_init(void);
+#ifdef IDE_REG_INDIRECT
+uint8_t devide_readb(uint8_t regaddr);
+void devide_writeb(uint8_t regaddr, uint8_t value);
+#else /* not IDE_REG_INDIRECT */
+#define devide_readb(r) (r)
+#define devide_writeb(r,v) do { r = v; } while(0)
+
#ifdef IDE_REG_BASE
#ifdef IDE_REG_CS0_FIRST
#define IDE_REG_CS0_BASE (IDE_REG_BASE+0x00)
#define IDE_REG_CS0_BASE (IDE_REG_BASE+0x08)
#define IDE_REG_CS1_BASE (IDE_REG_BASE+0x00)
#endif
-#endif
+#endif /* IDE_REG_BASE */
#ifdef IDE_REG_CS0_BASE
#define IDE_REG_ALTSTATUS (IDE_REG_CS0_BASE + 0x06)
#define IDE_REG_CONTROL (IDE_REG_CS0_BASE + 0x06)
#endif
+
#ifdef IDE_REG_CS1_BASE
#define IDE_REG_DATA (IDE_REG_CS1_BASE + 0x00)
#define IDE_REG_ERROR (IDE_REG_CS1_BASE + 0x01)
#define IDE_REG_COMMAND (IDE_REG_CS1_BASE + 0x07)
#endif
+#endif /* IDE_REG_INDIRECT */
+
/* IDE status register bits */
#define IDE_STATUS_BUSY 0x80
#define IDE_STATUS_READY 0x40
#define FLAG_CACHE_DIRTY 0x40
#define FLAG_WRITE_CACHE 0x80
-
extern bool devide_wait(uint8_t bits);
extern void devide_read_data(void);
extern uint8_t devide_transfer_sector(void);
extern int devide_flush_cache(void);
+#ifndef IDE_REG_INDIRECT
#ifdef IDE_REG_ALTSTATUS
__sfr __at IDE_REG_ALTSTATUS ide_reg_altstatus;
#endif
__sfr __at IDE_REG_SEC_COUNT ide_reg_sec_count;
__sfr __at IDE_REG_STATUS ide_reg_status;
#endif
+#endif /* IDE_REG_INDIRECT */
#endif
kputs("IDE reset\n");
/* reset both drives */
- ide_reg_devhead = 0xE0; /* select master */
- ide_reg_control = 0x06; /* assert reset, no interrupts */
+ devide_writeb(ide_reg_devhead, 0xE0); /* select master */
+ devide_writeb(ide_reg_control, 0x06); /* assert reset, no interrupts */
devide_delay();
- ide_reg_control = 0x02; /* release reset, no interrupts */
+ devide_writeb(ide_reg_control, 0x02); /* release reset, no interrupts */
devide_delay();
}
#endif
#ifdef IDE_8BIT_ONLY
/* set 8-bit mode -- mostly only supported by CF cards */
- ide_reg_devhead = select;
+ devide_writeb(ide_reg_devhead, select);
if(!devide_wait(IDE_STATUS_READY))
return;
- ide_reg_features = 0x01; /* Enable 8-bit PIO transfer mode (CFA feature set only) */
- ide_reg_command = IDE_CMD_SET_FEATURES;
+ devide_writeb(ide_reg_features, 0x01); /* Enable 8-bit PIO transfer mode (CFA feature set only) */
+ devide_writeb(ide_reg_command, IDE_CMD_SET_FEATURES);
#endif
/* confirm drive has LBA support */
return;
/* send identify command */
- ide_reg_devhead = select;
- ide_reg_command = IDE_CMD_IDENTIFY;
+ devide_writeb(ide_reg_devhead, select);
+ devide_writeb(ide_reg_command, IDE_CMD_IDENTIFY);
/* allocate temporary sector buffer memory */
buffer = (uint8_t *)tmpbuf();