Skip to content

Commit 47c657d

Browse files
committed
HFEv3: Fix and simplify opcode handling
This reworking also naturally allows OP_Rand to follow OP_SkipBits, as required for non-byte-sized weak regions.
1 parent e8c0942 commit 47c657d

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

src/image/hfe.c

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ struct track_header {
6060
uint16_t len;
6161
};
6262

63-
/* HFEv3 opcodes. The 4-bit codes have their bit ordering reversed. */
63+
/* HFEv3 opcodes. Bit order is reversed to match raw HFE bit order. */
6464
enum {
65-
OP_nop = 0, /* 0: no effect */
66-
OP_index = 8, /* 1: index mark */
67-
OP_bitrate = 4, /* 2: +1byte: new bitrate */
68-
OP_skip = 12, /* 3: +1byte: skip 0-8 bits in next byte */
69-
OP_rand = 2 /* 4: flaky byte */
65+
OP_Nop = 0x0f, /* Nop */
66+
OP_Index = 0x8f, /* Index mark */
67+
OP_Bitrate = 0x4f, /* +1 byte: new bitrate */
68+
OP_SkipBits = 0xcf, /* +1 byte: skip 1-7 bits in following byte */
69+
OP_Rand = 0x2f /* Random byte (or bits, if following OP_skip) */
7070
};
7171

7272
static void hfe_seek_track(struct image *im, uint16_t track);
@@ -231,12 +231,17 @@ static uint16_t hfe_rdata_flux(struct image *im, uint16_t *tbuf, uint16_t nr)
231231
uint32_t bc_c = bc->cons, bc_p = bc->prod, bc_mask = bc->len - 1;
232232
uint32_t ticks = im->ticks_since_flux;
233233
uint32_t ticks_per_cell = im->ticks_per_cell;
234-
uint32_t y = 8, todo = nr;
234+
uint32_t y, todo = nr;
235235
uint8_t x;
236236
bool_t is_v3 = im->hfe.is_v3;
237237

238-
while ((uint32_t)(bc_p - bc_c) >= 3*8) {
239-
ASSERT(y == 8);
238+
for (;;) {
239+
240+
if ((uint32_t)(bc_p - bc_c) < 3*8) {
241+
y = 8;
242+
goto out;
243+
}
244+
240245
if (im->cur_bc >= im->tracklen_bc) {
241246
ASSERT(im->cur_bc == im->tracklen_bc);
242247
im->tracklen_ticks = im->cur_ticks;
@@ -245,42 +250,38 @@ static uint16_t hfe_rdata_flux(struct image *im, uint16_t *tbuf, uint16_t nr)
245250
bc_c = (bc_c + 256*8-1) & ~(256*8-1);
246251
continue;
247252
}
253+
248254
y = bc_c % 8;
249-
x = bc_b[(bc_c/8) & bc_mask] >> y;
250-
if (is_v3 && (y == 0) && ((x & 0xf) == 0xf)) {
255+
x = bc_b[(bc_c/8) & bc_mask];
256+
bc_c += 8 - y;
257+
im->cur_bc += 8 - y;
258+
259+
if (is_v3 && ((x & 0xf) == 0xf)) {
251260
/* V3 byte-aligned opcode processing. */
252-
switch (x >> 4) {
253-
case OP_nop:
254-
case OP_index:
261+
switch (x) {
262+
case OP_Nop:
263+
case OP_Index:
255264
default:
256-
bc_c += 8;
257-
im->cur_bc += 8;
258-
y = 8;
259265
continue;
260-
case OP_bitrate:
261-
x = _rbit32(bc_b[(bc_c/8+1) & bc_mask]) >> 24;
266+
case OP_Bitrate:
267+
x = _rbit32(bc_b[(bc_c/8) & bc_mask]) >> 24;
262268
im->ticks_per_cell = ticks_per_cell =
263269
(sampleclk_us(2) * 16 * x) / 72;
264-
bc_c += 2*8;
265-
im->cur_bc += 2*8;
266-
y = 8;
267-
continue;
268-
case OP_skip:
269-
x = (_rbit32(bc_b[(bc_c/8+1) & bc_mask]) >> 24) & 7;
270-
bc_c += 2*8 + x;
271-
im->cur_bc += 2*8 + x;
272-
y = x;
273-
x = bc_b[(bc_c/8) & bc_mask] >> y;
274-
break;
275-
case OP_rand:
276270
bc_c += 8;
277271
im->cur_bc += 8;
272+
continue;
273+
case OP_SkipBits:
274+
x = (_rbit32(bc_b[(bc_c/8) & bc_mask]) >> 24) & 7;
275+
bc_c += 8 + x;
276+
im->cur_bc += 8 + x;
277+
continue;
278+
case OP_Rand:
278279
x = rand();
279280
break;
280281
}
281282
}
282-
bc_c += 8 - y;
283-
im->cur_bc += 8 - y;
283+
284+
x >>= y;
284285
im->cur_ticks += (8 - y) * ticks_per_cell;
285286
while (y < 8) {
286287
y++;

0 commit comments

Comments
 (0)