Skip to content

Commit 8370186

Browse files
JoeMattclaude
andcommitted
Improve counter/timer accuracy (TOM HC, JERRY PIT reads)
- Replace rand() stub for TOM Horizontal Count (HC) register with deterministic halfline-based approximation. HC is now updated in TOMExecHalfline() to 0 at even halflines and HP/2 at odd halflines. This fixes non-deterministic behavior and gives the Object Processor's CONDITION_SECOND_HALF_LINE branch a meaningful value. - Implement JERRY timer register reads (JPIT1-JPIT4 at F10036-F1003D). Both byte and word reads now return the current prescaler/divider values instead of silently returning 0. Refs #62 Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 2f9c817 commit 8370186

2 files changed

Lines changed: 36 additions & 3 deletions

File tree

src/jerry.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,24 @@ uint8_t JERRYReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/)
384384
// F10038 R xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider
385385
// F1003A R xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler
386386
// F1003C R xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider
387+
// F10036 R xxxxxxxx xxxxxxxx JPIT1 - timer 1 pre-scaler
388+
// F10038 R xxxxxxxx xxxxxxxx JPIT2 - timer 1 divider
389+
// F1003A R xxxxxxxx xxxxxxxx JPIT3 - timer 2 pre-scaler
390+
// F1003C R xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider
387391
else if ((offset >= 0xF10036) && (offset <= 0xF1003D))
388392
{
389-
/* Unhandled timer read (BYTE) */
393+
uint16_t value;
394+
395+
switch (offset & 0xFE)
396+
{
397+
case 0x36: value = JERRYPIT1Prescaler; break;
398+
case 0x38: value = JERRYPIT1Divider; break;
399+
case 0x3A: value = JERRYPIT2Prescaler; break;
400+
case 0x3C: value = JERRYPIT2Divider; break;
401+
default: value = 0; break;
402+
}
403+
404+
return (offset & 0x01) ? (value & 0xFF) : (value >> 8);
390405
}
391406
else if (offset >= 0xF14000 && offset <= 0xF14003)
392407
{
@@ -426,7 +441,13 @@ uint16_t JERRYReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/)
426441
// F1003C R xxxxxxxx xxxxxxxx JPIT4 - timer 2 divider
427442
else if ((offset >= 0xF10036) && (offset <= 0xF1003D))
428443
{
429-
/* Unhandled timer read (WORD) */
444+
switch (offset)
445+
{
446+
case 0xF10036: return JERRYPIT1Prescaler;
447+
case 0xF10038: return JERRYPIT1Divider;
448+
case 0xF1003A: return JERRYPIT2Prescaler;
449+
case 0xF1003C: return JERRYPIT2Divider;
450+
}
430451
}
431452
else if (offset == 0xF10020)
432453
return jerryPendingInterrupt;

src/tom.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,9 +732,20 @@ void TOMExecHalfline(uint16_t halfline, bool render)
732732
uint32_t * TOMCurrentLine = 0;
733733
uint16_t topVisible;
734734
uint16_t bottomVisible;
735+
uint16_t hp = GET16(tomRam8, HP);
735736

736737
halfline &= 0x07FF;
737738

739+
// Update HC to approximate position within the scanline.
740+
// Even halflines = start of scanline (HC near 0),
741+
// odd halflines = midpoint of scanline (HC near HP/2).
742+
// This is not cycle-accurate but gives the OP and games a
743+
// meaningful value instead of the previous rand() stub.
744+
if (halfline & 0x01)
745+
SET16(tomRam8, HC, (hp > 0 ? (hp + 1) / 2 : 0));
746+
else
747+
SET16(tomRam8, HC, 0);
748+
738749
if (halfline & 0x01) // Execute OP only on even halflines (non-interlaced only!)
739750
// Execute OP only on even halflines (skip higher resolutions for now...)
740751
return;
@@ -919,7 +930,8 @@ uint16_t TOMReadWord(uint32_t offset, uint32_t who)
919930
return data;
920931
}
921932
else if (offset == 0xF00004)
922-
return rand() & 0x03FF;
933+
// Return the current HC value from tomRam8 (updated each halfline)
934+
return GET16(tomRam8, HC);
923935
else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE + 0x20))
924936
return GPUReadWord(offset, who);
925937
else if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE + 0x1000))

0 commit comments

Comments
 (0)