17 October to 21 October 2025
Here's my disassembly diary for this part of my project to document The Sentinel on the BBC Micro. You can click on the following links to jump to a specific day in the diary:
- 17 October 2025 - Document PerformHyperspace, UpdatePlayerEnergy and DeleteObject, rename sentinelHasWon, reach one-third progress
- 19 October 2025 - Rename numberOfEnemies and maxNumberOfEnemies, start analysing IRQHandler
- 20 October 2025 - Document duplicate tile data code in GetTileViewAngles, document use of SHEILA addresses for hardware scrolling, document ResetScreenAddress
- 21 October 2025 - Identify screen-scrolling routines at ScrollPlayerView and ShowScreenBuffer, document ShowBufferBlock, ShowBufferRow and ShowBufferColumn, reach 35% progress
Please note that this diary is a dump of my thoughts as I disassembled and documented The Sentinel, and as such it contains lots of mistakes and dead ends and misinterpretations. This diary is all about the journey, rather than the destination; for the latter, see the finished product.
17 October 2025
===============
See all the GitHub commits and diffs for 17 October 2025.
Start documenting PerformHyperspace.
This calls sub_C2127, which affects the player's energy, so change to UpdatePlayerEnergy. It gets the energy levels for an object type from L2140, so rename this to objectTypeEnergy.
Document UpdatePlayerEnergy.
Also, we need to talk about death. There isn't any death in the Sentinel - if you lose a level then you get absorbed, but you come back to have another go. The instructions don't mention death at all, so let's remove any mention of death from the comments, and rename the playerIsDead flag to sentinelHasWon. After all, we don't know who's the baddie here; perhaps the player is a virus and the Sentinel is a protector? Who knows...
Also in PerformHyperspace we call sub_C1ED8, which deletes an object, so rename to DeleteObject and document.
Finish off PerformHyperspace, though there are a few flags and calls in there that need explaining: sub_C5FF6, sub_C1200, L0C4C, L0CDE, L0C63.
I'm also unsure of which category to put PerformHyperspace in, same with UpdatePlayerEnergy. We might need a new one for "gameplay" or "tactics" or something like that.
And I just noticed, while looking through the categories, that I FORGOT to mark SetTileShape as done in the progress sheet: it's still in there as sub_C2C4E and not done yet.
So change it to Done... and that means we have reached exactly 33.3%, so...
>>> I have now broken through the 33.33% barrier <<<
Nice! That's one-third, a proper milestone. So we just need to do that again, twice, and we're done.
"Just"...
19 October 2025
===============
See all the GitHub commits and diffs for 19 October 2025.
Some variable renaming to make things a bit clearer:
- enemyCount -> numberOfEnemies
- maxEnemyCount -> maxNumberOfEnemies
Let's look at IRQHandler next.
It gets called exactly 50 times a second, triggered by the User VIA timer 1 counting down from 19,998 (i.e. from 20,000, as 2 ticks are for the latching process).
It does various things:
sub_C37D1, sub_C3832, sub_C3889 and sub_C38B2 do hardware scrolling of the screen by changing the screen address.
The last one contains various byte-copying code, so this looks like it might copy from a buffer into screen memory after scrolling, i.e. when panning the screen?
(We already identified sub_C3889 as copying from the buffer to the screen.)
So does non-zero L0CC1 mean "pan screen by one pixel"? And is L0CC1 therefore a pixel counter for panning, as sub_C37D1 decrements the value of L0CC1?
This is how the sub_C37D1 and DisplayIconBuffer routines get called:
IRQHandler > sub_C37D1 > sub_C3832 > sub_C3889 DisplayIconBuffer > sub_C3889
DisplayIconBuffer is called from other places too, to update the icon row.
sub_C3832 is called from just one other place.
Needs more thought, obviously!
20 October 2025
===============
See all the GitHub commits and diffs for 20 October 2025.
Add some more categories to headers:
- DrawTitleObject, category = Title screen.
- All L140x variables, as they are only mentioned in DrawTitleObject so they are also to do with the title screen, so category = Title screen.
The code at C28A4 is very close to the code in GetTileData, so copy over the comments.
Now look for SHEILA+&xx for hardware scrolling.
Specifically, SHEILA+&00 and SHEILA+&01 set the 6845 R12 and R13 registers (screen start address). These routines contain references:
Document the SHEILA code in these and we'll come back to naming the routines later.
21 October 2025
===============
See all the GitHub commits and diffs for 21 October 2025.
Name the routines that scroll the screen and copy the screen buffer into screen memory to implement the scrolling player view.
Let's call the buffer for the main screen area the "view screen buffer" (as it buffers the screen data for the player's scrolling landscape view).
This is to go alongside the icon screen buffer for the icon/scanner on the top row.
So, speculatively renaming the routines, we get:
- sub_C130C -> ResetScreenAddress
- sub_C37D1 -> ScrollPlayerView
- sub_C3832 -> DisplayViewBuffer
- C384F -> DisplayBufferColumn (not called, but insert header for clarity)
- sub_C3889 -> DisplayBufferRow
- sub_C38B2 -> DisplayBufferBlock
So the interrupt handler does this to implement the scrolling view:
IRQHandler > ScrollPlayerView > DisplayViewBuffer > DisplayBufferColumn > DisplayBufferBlock DisplayBufferRow > DisplayBufferBlock DisplayIconBuffer > DisplayBufferRow > DisplayBufferBlock
Now we just have to document the routines.
Document DisplayBufferBlock, DisplayBufferRow and DisplayBufferColumn.
>>> I have now broken through the 35% barrier <<<