diff --git a/include/apple2.dd.h b/include/apple2.dd.h index 26d7734..ed799e7 100644 --- a/include/apple2.dd.h +++ b/include/apple2.dd.h @@ -189,6 +189,7 @@ extern int apple2_dd_decode(apple2dd *); extern int apple2_dd_encode(apple2dd *); extern int apple2_dd_insert(apple2dd *, FILE *, int); extern int apple2_dd_position(apple2dd *); +extern int apple2_dd_sector_num(int, int); extern vm_8bit apple2_dd_read(apple2dd *); extern vm_8bit apple2_dd_switch_rw(apple2dd *); extern void apple2_dd_eject(apple2dd *); diff --git a/include/apple2.enc.h b/include/apple2.enc.h index 61ec499..9d41925 100644 --- a/include/apple2.enc.h +++ b/include/apple2.enc.h @@ -62,8 +62,8 @@ extern int apple2_enc_4n4(vm_segment *, int, vm_8bit); extern int apple2_enc_sector(vm_segment *, vm_segment *, int, int); extern int apple2_enc_sector_header(vm_segment *, int, int, int); -extern int apple2_enc_track(vm_segment *, vm_segment *, const int *, int, int); -extern vm_segment *apple2_enc_dos(vm_segment *, const int *); +extern int apple2_enc_track(int, vm_segment *, vm_segment *, int, int); +extern vm_segment *apple2_enc_dos(int, vm_segment *); extern vm_segment *apple2_enc_nib(vm_segment *); #endif diff --git a/src/apple2.dd.c b/src/apple2.dd.c index 97054ea..62a8dbd 100644 --- a/src/apple2.dd.c +++ b/src/apple2.dd.c @@ -14,16 +14,6 @@ #include "apple2.enc.h" #include "apple2.h" -static int sector_dos33[] = { - 0x0, 0x7, 0xe, 0x6, 0xd, 0x5, 0xc, 0x4, - 0xb, 0x3, 0xa, 0x2, 0x9, 0x1, 0x8, 0xf, -}; - -static int sector_prodos[] = { - 0x0, 0x8, 0x1, 0x9, 0x2, 0xa, 0x3, 0xb, - 0x4, 0xc, 0x5, 0xd, 0x6, 0xe, 0x7, 0xf, -}; - /* * Create a new disk drive. We do not create a memory segment for the * drive right away, as the size of said data can be variable based on @@ -59,6 +49,42 @@ apple2_dd_create() return drive; } +int +apple2_dd_sector_num(int type, int sect) +{ + static const int dos33[] = { + 0x0, 0x7, 0xe, 0x6, 0xd, 0x5, 0xc, 0x4, + 0xb, 0x3, 0xa, 0x2, 0x9, 0x1, 0x8, 0xf, + }; + + static const int prodos[] = { + 0x0, 0x8, 0x1, 0x9, 0x2, 0xa, 0x3, 0xb, + 0x4, 0xc, 0x5, 0xd, 0x6, 0xe, 0x7, 0xf, + }; + + const int *sectab; + + // Booooo + if (sect < 0 || sect > 15) { + return 0; + } + + switch (type) { + case DD_DOS33: + sectab = dos33; + break; + + case DD_PRODOS: + sectab = prodos; + break; + + case DD_NIBBLE: + return sect; + } + + return sectab[sect]; +} + /* * Insert a "disk" into the drive, such that a disk is delivered to us * through a FILE stream. Return an error code if the disk format is @@ -123,11 +149,8 @@ apple2_dd_encode(apple2dd *drive) break; case DD_DOS33: - drive->data = apple2_enc_dos(drive->image, sector_dos33); - break; - case DD_PRODOS: - drive->data = apple2_enc_dos(drive->image, sector_prodos); + drive->data = apple2_enc_dos(drive->image_type, drive->image); break; default: diff --git a/src/apple2.enc.c b/src/apple2.enc.c index ba479d6..08fe44e 100644 --- a/src/apple2.enc.c +++ b/src/apple2.enc.c @@ -39,7 +39,7 @@ static vm_8bit gcr62[] = { * 3.2 and 3.1 (which use 5-and-3 encoding). */ vm_segment * -apple2_enc_dos(vm_segment *src, const int *sectab) +apple2_enc_dos(int type, vm_segment *src) { vm_segment *dest; int i, doff = 0; @@ -58,7 +58,7 @@ apple2_enc_dos(vm_segment *src, const int *sectab) // away with just using tracks-and-sectors. In particular, DOS 3.3 // has 35 tracks of 4096 bytes each. for (i = 0; i < 35; i++) { - doff += apple2_enc_track(dest, src, sectab, doff, i); + doff += apple2_enc_track(type, dest, src, doff, i); } return dest; @@ -105,7 +105,7 @@ apple2_enc_nib(vm_segment *src) * written into dest. */ int -apple2_enc_track(vm_segment *dest, vm_segment *src, const int *sectab, +apple2_enc_track(int sectype, vm_segment *dest, vm_segment *src, int doff, int track) { int toff = track * ENC_DTRACK; @@ -119,7 +119,7 @@ apple2_enc_track(vm_segment *dest, vm_segment *src, const int *sectab, } for (sect = 0; sect < 16; sect++) { - soff = toff + (ENC_DSECTOR * sectab[sect]); + soff = toff + (ENC_DSECTOR * apple2_dd_sector_num(sectype, sect)); // Each sector has a header with some metadata, plus some // markers and padding. diff --git a/tests/apple2.dd.c b/tests/apple2.dd.c index f68acac..ae72638 100644 --- a/tests/apple2.dd.c +++ b/tests/apple2.dd.c @@ -323,3 +323,20 @@ Test(apple2_dd, map) vm_segment_free(seg); } + +Test(apple2_dd, sector_num) +{ + static const int dos33[] = { + 0x0, 0x7, 0xe, 0x6, 0xd, 0x5, 0xc, 0x4, + 0xb, 0x3, 0xa, 0x2, 0x9, 0x1, 0x8, 0xf, + }; + + static const int prodos[] = { + 0x0, 0x8, 0x1, 0x9, 0x2, 0xa, 0x3, 0xb, + 0x4, 0xc, 0x5, 0xd, 0x6, 0xe, 0x7, 0xf, + }; + + for (int i = 0; i < 16; i++) { + cr_assert_eq(apple2_dd_sector_num(DD_DOS33, i), dos33[i]); + } +} diff --git a/tests/apple2.enc.c b/tests/apple2.enc.c index 20d6bf1..4e475f4 100644 --- a/tests/apple2.enc.c +++ b/tests/apple2.enc.c @@ -93,7 +93,7 @@ Test(apple2_enc, dos) FILE *fp = fopen("../../build/karateka.dsk", "r"); vm_segment_fread(seg, fp, 0, _140K_); - enc = apple2_enc_dos(seg, sectab); + enc = apple2_enc_dos(DD_DOS33, seg); cr_assert_neq(enc, NULL); @@ -197,7 +197,7 @@ Test(apple2_enc, track) vm_segment_copy_buf(seg, f_sector, i * ENC_DSECTOR, 0, 256); } - apple2_enc_track(dest, seg, sectab, 0, 0); + apple2_enc_track(DD_DOS33, dest, seg, 0, 0); for (i = 0; i < ENC_ETRACK_HEADER; i++) { cr_assert_eq(vm_segment_get(dest, i), 0xff);