diff -Naur spediv_v0.2c/divide.c spediv_v0.2d/divide.c --- spediv_v0.2c/divide.c 2007-02-05 00:50:14.000000000 +0100 +++ spediv_v0.2d/divide.c 2007-07-28 16:08:23.000000000 +0200 @@ -165,6 +165,18 @@ return (s+DISK.s*(h+c*DISK.h)-1); } +// LBA geometry -> CHS doubleword +int lba2chs(int drive, int lba) { + int c,h,s; + + lba++; + s=lba%DISK.s; + h=(lba/DISK.s)%DISK.h; + c=(lba/DISK.s)/DISK.h; + + return (h<<24)|(c<<8)|s; +} + void divide_eeprom_save() { int i,fd; @@ -376,7 +388,7 @@ // IN wrapper int divide_port_in(int portl) { - int data, drive; + int data, drive, lba, chs; drive = divide_active_drive; switch (portl) { @@ -385,7 +397,31 @@ if ( DISK.buffer_ptr < DISK.buffer_len ) { data = DISK.buffer[DISK.buffer_ptr]; DISK.buffer_ptr++; - if (!(DISK.buffer_ptr&0x1FF)) DISK.port_AB--; + if (!(DISK.buffer_ptr&0x1FF)) { + DISK.port_AB--; + if (DISK.buffer_ptr>0x200) { + // LBA or CHS? + if (DISK.port_BB & 0x40) + lba = ((DISK.port_BB & 0x0F) << 24) | (DISK.port_B7 << 16) | (DISK.port_B3 << 8) | DISK.port_AF; + else + lba = chs2lba(drive, (DISK.port_B7 << 8) | DISK.port_B3, DISK.port_BB & 0x0F, DISK.port_AF); + lba++; + if (DISK.port_BB & 0x40) { + DISK.port_BB&=0xF0; + DISK.port_BB|=((lba>>24)&0x0F); + DISK.port_B7=((lba>>16)&0xFF); + DISK.port_B3=((lba>>8)&0xFF); + DISK.port_AF=(lba&0xFF); + } else { + chs = lba2chs(drive, lba); + DISK.port_BB&=0xF0; + DISK.port_BB|=((chs>>24)&0x0F); + DISK.port_B7=((chs>>16)&0xFF); + DISK.port_B3=((chs>>8)&0xFF); + DISK.port_AF=(chs&0xFF); + } + } + } // readed whole buffer? if (DISK.buffer_ptr >= DISK.buffer_len) @@ -431,7 +467,7 @@ // OUT wrapper void divide_port_out(int portl, byte data) { int i, drive, part; - int lba, tlba; + int lba, tlba, chs; long size; drive = divide_active_drive; @@ -610,7 +646,7 @@ DISK.buffer_ptr = 0; DISK.buffer_len = 0; DISK.cmd = DIVIDE_WRITE_BUFF; - DISK.nsec = 0; + DISK.nsec = -1; DISK.in_port_BF &= (STATUS_CLR_BSY & STATUS_CLR_DF & STATUS_CLR_ERR); DISK.in_port_BF |= (STATUS_SET_DRDY | STATUS_SET_DRQ); break; @@ -632,13 +668,15 @@ // if is stored whole sector write it to disk if (DISK.buffer_len == 512) { - // LBA or CHS? - if (DISK.port_BB & 0x40) - lba = ((DISK.port_BB & 0x0F) << 24) | (DISK.port_B7 << 16) | (DISK.port_B3 << 8) | DISK.port_AF; - else - lba = chs2lba(drive, (DISK.port_B7 << 8) | DISK.port_B3, DISK.port_BB & 0x0F, DISK.port_AF); - lba+=DISK.nsec; + if (DISK.nsec>-1) lba=DISK.nsec; + else { + // LBA or CHS? + if (DISK.port_BB & 0x40) + lba = ((DISK.port_BB & 0x0F) << 24) | (DISK.port_B7 << 16) | (DISK.port_B3 << 8) | DISK.port_AF; + else + lba = chs2lba(drive, (DISK.port_B7 << 8) | DISK.port_B3, DISK.port_BB & 0x0F, DISK.port_AF); + } // write n-th sector to disk tlba=lba; if (tlba < DISK.mbr.len) { @@ -657,13 +695,27 @@ } DISK.buffer_len=0; DISK.port_AB--; - DISK.nsec++; + if (DISK.port_BB & 0x40) { + DISK.port_BB&=0xF0; + DISK.port_BB|=((lba>>24)&0x0F); + DISK.port_B7=((lba>>16)&0xFF); + DISK.port_B3=((lba>>8)&0xFF); + DISK.port_AF=(lba&0xFF); + } else { + chs = lba2chs(drive, lba); + DISK.port_BB&=0xF0; + DISK.port_BB|=((chs>>24)&0x0F); + DISK.port_B7=((chs>>16)&0xFF); + DISK.port_B3=((chs>>8)&0xFF); + DISK.port_AF=(chs&0xFF); + } lba++; + DISK.nsec=lba; } // we are done with writing? if (!DISK.port_AB) { DISK.cmd=0; - DISK.nsec=0; + DISK.nsec=-1; DISK.in_port_BF &= STATUS_CLR_DRQ; } break; diff -Naur spediv_v0.2c/divide.h spediv_v0.2d/divide.h --- spediv_v0.2c/divide.h 2005-07-25 11:23:12.000000000 +0200 +++ spediv_v0.2d/divide.h 2007-07-28 10:25:32.000000000 +0200 @@ -21,7 +21,7 @@ #ifndef DIVIDE_H #define DIVIDE_H -#define DIVIDE_VERSION "v0.2a" +#define DIVIDE_VERSION "v0.2d" void divide_init(); void divide_exit();