The routine at $217E miscalculates the 10000s digit of a number. Instead of
repeatedly trying to subtract 10000 to determine the digit, it subtracts 10100
(and then checks whether the result is still 10100 or greater).
The numbers that MR WACKER asks the class to multiply are supposed to be
between 32 and 99 (to ensure that the answer has exactly 4 digits), but because
of a bug in the routine at $253E, the numbers are actually between 0 and 67.
Dereliction of dinner duty
During dinner, the teacher on duty is supposed to walk up and down between the
table (at x-coordinate 54) and the middle of the bench (at x-coordinate 42) in
the dinner hall for a while before dinner actually starts. However, the x- and
y-coordinates of that second location are the wrong way round in command list
$B8, which means the teacher instead walks up and down between the
table in the dinner hall and the bottom of the staircase (at x-coordinate 17)
that leads up to the staff room.
BOY WONDER often takes a step back just before firing his catapult, which
results in his animation appearing somewhat jerky. Likewise, ANGELFACE also
often steps back just before throwing a punch, making his animation appear
somewhat jerky too.
The reason for this is that the continual subcommand routines that make BOY
WONDER fire occasionally ($2CA5) and ANGELFACE hit occasionally ($270D) do
not drop the return address from the stack after deciding to go ahead with the
fire/hit action. This means that they return to the middle of the
character-handling routine at $3B5E, which then has the opportunity of moving
them midstride before they begin the fire/hit action on the next pass through
that routine.
The jerky animation can be fixed by reversing the midstride check in the
routines at $270D and $2CA5:
If a teacher gives lines to ERIC for jumping, hitting or firing his catapult
while EINSTEIN is blaming either ERIC or BOY WONDER for writing on the
blackboard, the same teacher will then go on to give lines to ANGELFACE for
writing on the blackboard.
Why is the bully unfairly punished for this misdemeanour? It boils down to a
careless use of temporary variables in page 0. The routine at $0A58 stores
the character number of the boy that EINSTEIN will blame for writing on the
blackboard at $C0, then makes EINSTEIN blame that boy, and finally picks up
the character number of the blamed boy from $C0 and passes it to the routine
at $2552 to decide who should get lines.
Now, if the teacher spots ERIC jumping, hitting or firing while EINSTEIN is
blaming ERIC or BOY WONDER for writing on the blackboard, the routine at
$191B uses $C0 to temporarily store the character number of the teacher,
thus overwriting the character number of the boy EINSTEIN is telling tales on.
All this means that by the time the routine at $1DB7 is invoked to give
someone lines for writing on the blackboard, it defaults to giving ANGELFACE
lines because it doesn't recognise the teacher's character number at $C0 (see
the section of code at $1DFC).
To make the routine at $191B use $C3 instead of $C0 for storing the
teacher's character number:
When a teacher is in the Map Room, he faces the wall instead of the class while
speaking. This is because command list $80 sends the teacher up to the
map, but does not turn him round before starting the class.
Hidden accusers
Occasionally during gameplay you might hear something like a truncated sound
effect, and perhaps even also see ERIC's lines total increase at the same time
for no apparent reason.
One likely explanation for this phenomenon is that a teacher is giving lines
while off screen. The reason that can happen is that the routine at $1DB7
does not check whether the teacher is on screen before adding lines to ERIC's
total or starting the lines-giving sound effect. But then, when it calls the
routine at $2043 to display the lines message box above the teacher's head,
that routine does check whether the teacher is on screen and returns
early (without displaying the lines message box or pausing to give the
accompanying sound effect time to play) if he isn't.
A step too far
If a teacher is going to teach a class in the Exam Room, he faces the wrong way
at the doorway when telling the kids to sit down.
The reason for this behaviour is that the x-coordinate of the top of the
staircase is defined, in the fifth entry of the table at $4454, as 76. This
means that when the teacher has reached the bottom of the staircase, his
x-coordinate is 69, which is one to the left of the x-coordinate of the Exam
Room doorway at 70, as defined in command list $84. So after arriving
at x-coordinate 69, the teacher turns round and moves one step forward to reach
his destination.
One possible fix for this is to make the teacher's destination x-coordinate 69
instead of 70:
Another possible (and perhaps better) fix is to define the x-coordinate of the
top of the staircase leading down to the Exam Room as 77 instead of 76. This
makes sense because 77 matches the x-coordinate used in the Spectrum version
and by the routine at $34B5 that moves ERIC one step down a staircase, and is
also 7 cells to the right of the bottom of the staircase, which is defined as
70 in the fourth entry of the table at $4440 (7 cells being the height of the
staircase).
When a character is looking for ERIC, if he has to go down a staircase on the
left side of the skool, he will start at x-coordinate 12 instead of the usual
13, which makes him appear to be walking inside the staircase instead of on it.
Similarly, if the character looking for ERIC has to go down a staircase
on the right side of the skool, he will start at x-coordinate 77 instead of the
usual 76, which produces a similar effect.
The reason has more to do with the way characters other than ERIC are animated
when going down a staircase than it has to do with the x-coordinates of the
tops of the staircases themselves. When ERIC proceeds from one step to the
next, he moves midstride first, and then drops to the step below as he finishes
his stride. But the other characters - in contrast to ERIC and to their
counterparts in the ZX Spectrum version - move midstride as they drop to the
step below, and then finish their stride on that step before moving to the next
one. It's this drop-first-and-finish-the-stride-later technique that accounts
for the anomalous appearance.
Luckily, changing this technique to match ERIC's requires just a few POKEs that
modify the relevant section of code at $0D37:
Jump back to compute the character's next x-coordinate.
POKE 3383,165 ($0D37,$A5)
POKE 3385,133 ($0D39,$85)
POKE 3386,173 ($0D3A,$AD)
POKE 3387,230 ($0D3B,$E6)
The staircase saga continues
In Double staircases above we took the approach of modifying the
staircase descent technique of a character who is looking for ERIC in order to
fix an animation bug. But what if a character is not looking for ERIC? In that
case, it's the routine at $13F3 that takes care of any trip down a staircase.
And not so luckily this time, a rather larger set of POKEs is required to
modify the relevant section of code:
Update the SRB for the character's new animatory state and location.
POKE 5132,9 ($140C,$09)
POKE 5133,165 ($140D,$A5)
POKE 5134,71 ($140E,$47)
POKE 5135,208 ($140F,$D0)
POKE 5136,2 ($1410,$02)
POKE 5137,230 ($1411,$E6)
POKE 5138,251 ($1412,$FB)
POKE 5139,76 ($1413,$4C)
POKE 5140,147 ($1414,$93)
POKE 5141,19 ($1415,$13)
POKE 5142,230 ($1416,$E6)
POKE 5143,38 ($1417,$26)
POKE 5144,165 ($1418,$A5)
POKE 5145,71 ($1419,$47)
POKE 5146,240 ($141A,$F0)
POKE 5147,2 ($141B,$02)
POKE 5148,198 ($141C,$C6)
POKE 5149,251 ($141D,$FB)
POKE 5150,76 ($141E,$4C)
POKE 5151,46 ($141F,$2E)
POKE 5152,50 ($1420,$32)
With that change out of the way, it now makes sense to adjust the x-coordinates
of the tops of the staircases in the tables at $4440 and $4454, for optimal
compatibility with the new technique:
POKE 17472,12 ($4440,$0C)
POKE 17476,12 ($4444,$0C)
POKE 17504,77 ($4460,$4D)
POKE 17508,77 ($4464,$4D) (this is the same POKE as was used in
A step too far)
Initial non-playtimes
Unlike the ZX Spectrum version, the C64 version of the game does not always
start on a playtime: two of the entries in the table of initial lesson numbers
at $4650 are classroom periods.
What's interesting is that the non-playtime lesson numbers in this table - $0C
and $3D - would be playtimes if the main timetable at $5D00 were exactly the
same as the one in the ZX Spectrum version. This strongly suggests that these
initial non-playtimes are not intentional.
Invisibility range
The routine at $0BAC, which is used to calculate the coordinate ranges within
which a character can be seen, does not always compute the minimum x-coordinate
correctly. The most obvious consequence of this miscalculation is that ERIC can
flagrantly violate the skool rules in front of a teacher, without getting
lines, when he's to the right of that teacher and in one of the following
locations:
on the top floor with x-coordinate < 47 (to the left of the blue shield in the Reading Room)
on the middle floor with x-coordinate < 28 (to the left of the front seat in the White Room)
Specifically, in these situations ERIC's horizontal visibility range is
calculated as [x, x+10] (where 'x' is ERIC's x-coordinate) instead
of [x−10, x+10], which means any teacher to his left is effectively
unable to see him.
In contrast to those situations where ERIC's horizontal visibility range is
reduced from [x−10, x+10] to [x, x+10] (see Invisibility range),
there are other situations in which the upper bound of that range is increased
from x+10 to x+13 for MR CREAK in particular. This means, for example, that
when MR CREAK is at x-coordinate 34 in the White Room waiting for EINSTEIN to
tell tales, he can see ERIC (and give him lines for hitting, firing etc.) even
if he's standing in the White Room doorway 13 spaces away at x-coordinate 21.
The reason for this is as follows. When the check is made whether ERIC should
be given lines, his visibility range is calculated by the routine at $0BAC,
and the minimum and maximum y- and x-coordinates of that range are stored at
$73, $74, $75 and $76. Then the routine at $0E59 checks whether any of the
teachers are in that range. It does this by calling the routine at $0D67 for
each teacher in turn: MR WACKER first, then MR ROCKITT, then MR WITHIT, and
finally MR CREAK. But the routine at $0D67 is rather careless with the
maximum x-coordinate. For each teacher checked, the maximum x-coordinate at $76
is incremented if that teacher's x-coordinate is at least equal to the minimum
x-coordinate. So by the time MR CREAK is checked, the maximum x-coordinate of
ERIC's visibility range has increased by up to 3.
In addition, for each teacher checked by the routine at $0D67, the maximum
y-coordinate at $74 is incremented if that teacher is within the x-coordinate
range and has a y-coordinate at least equal to the minimum y-coordinate. So in
very specific (and unlikely) situations, MR CREAK's superior vision can extend
vertically as well as horizontally.
Off by one
The skool region data tables for the top floor, middle floor
and bottom floor are the same as those in the ZX Spectrum version, but
they are interpreted differently: each x-coordinate they contain is the maximum
x-coordinate of the current region rather than the minimum x-coordinate of the
next region along.
One obvious consequence of this is that ERIC is considered to be inside the
head's study (and will be given lines accordingly) even when he's standing just
outside the doorway.
The disappearing pellet
If a pellet bounces off a teacher's head on the top floor of the skool, it will
disappear before it reaches the top of the screen. The reason for this is that
the routine at $31EA (which updates the display) ignores the first ten bytes
of the screen refresh buffer at $4008, which correspond to the top two rows
of the screen. This means that anything at y-coordinate 0 or 1 is never drawn.
Leaps of faith
If you've spent any time in the Exam Room knocking boys out in order to jump on
them and thence to the shields, but been left wondering whether this method is
actually reliable, rest assured that in fact it most certainly is not.
The reason is that the routine at $1640, which checks whether ERIC is
standing on a boy, is rather careless with ERIC's x-coordinate. The routine
stores this x-coordinate at $D3, and then enters a loop to compare the value
stored there with the x-coordinate of each boy whose y-coordinate is one more
than ERIC's (i.e. underneath him). The problem is that the value at $D3 is
either decremented or incremented by one on each pass through the loop
depending on the boy's x-coordinate relative to ERIC's. So the comparison works
for the first boy checked, but is off by one for the next boy, then possibly
off by two for the next boy after that, and so on.
The following POKEs fix the section of code at $166B to make the x-coordinate
comparisons consistent:
When a teacher is close (but not too close!) to the left edge of the visible
play area and either gives lines or reveals a safe combination letter, the
8-cell-wide message box above his head may be drawn with the leftmost one or
two cell columns missing.
The reason for this lies in how the routine at $2043 computes the
x-coordinate of sprite #1, which holds the contents of the leftmost three cell
columns (24 pixel columns) of the message box. In the following discussion, we
will use T to denote the teacher's play area x-coordinate (0-95), S to denote
the play area x-coordinate of the leftmost column of the skool on screen (0, 8,
16, 24...56), and S' to denote the play area x-coordinate of the leftmost
column of the skool off screen (40, 48, 56, 64...96, i.e. S+40).
When S>T−4 (meaning there is a gap of one, two or three cell columns
between the teacher and the left edge of the visible play area), the
x-coordinate of sprite #1 is set to 32. This puts a 1-cell-wide gap between the
message box and the left edge of the visible play area. (Remember that sprite
x-coordinates 0-23 and 344-512 are outside the visible area of the screen, and
only x-coordinates 24-343 are within it.)
But when S<=T−4, the x-coordinate of sprite #1 is set to
8(T−S−3). This means that, in particular, when S=T−4 (meaning
there is a gap of exactly four cell columns between the teacher and the left
edge of the visible play area), the x-coordinate of sprite #1 is set to 8,
which means the leftmost two cell columns of the message box are not visible.
And when S=T−5 (meaning there is a gap of exactly five cell columns
between the teacher and the left edge of the visible play area), the
x-coordinate of sprite #1 is set to 16, which means the leftmost cell column of
the message box is not visible.
So much for the left side of the screen. What about when a teacher is close to
the right edge of the visible play area? It turns out that the message box is
not exactly ideally placed in that situation either.
When S'<=T+5 (meaning there is a gap of one or two cell columns between the
teacher and the right edge of the visible play area), the x-coordinate of
sprite #1 is set to 256. This puts a 3-cell-wide gap between the message box
and the right edge of the visible play area, which means it's nowhere near
being centred over the teacher's head.
In summary, it's as if the routine at $2043 assumes that the x-coordinate of
the left edge of visible area of the screen, as far as sprites are concerned,
is 0 instead of 24.
POKE 8297,0 ($2069,$00) - sets the x-coordinate of sprite #1 to
8(T−S) when S<=T−4 or S'>T+5, which roughly centres the
message box above the teacher's head.
POKE 8305,3 ($2071,$03) - sets the minimum x-coordinate of sprite #1
to 24 instead of 32 (used when S>T−4), which pushes the message box up
against the left edge of the visible play area.
POKE 8310,35 ($2076,$23) - sets the maximum x-coordinate of sprite #1
to 280 instead of 256 (used when S'<=T+5), which pushes the message box up
against the right edge of the visible play area.
Broken bookcase
The bottom of the bookcase on the left in the Revision Library seems to have
been vandalised since it was first used in the ZX Spectrum version:
To restore the bookcase to something close to its former glory:
POKE 24597,255 ($6015,$FF)
POKE 24853,0 ($6115,$00)
POKE 25109,0 ($6215,$00)
POKE 25365,0 ($6315,$00)
POKE 25621,0 ($6415,$00)
POKE 25877,0 ($6515,$00)
POKE 26133,0 ($6615,$00)
POKE 26389,0 ($6715,$00)
These POKEs also affect the sofa and the window on the left in the staff room
(specifically the tiles at (3,9), (8,11) and (9,11)), but in a way that can be
overlooked for the sake of the bookcase:
Before
After
Nearly there, but something is still not quite right with the books on the
bottom shelf on the right-hand side:
To fix them:
POKE 25814,85 ($64D6,$55)
POKE 26070,171 ($65D6,$AB)
POKE 26326,87 ($66D6,$57)
POKE 26582,175 ($67D6,$AF)
Miss and hit
ERIC can be knocked out by BOY WONDER's catapult pellet even when he's sitting
on the floor or is already lying on the floor (and the pellet should really fly
straight over his head instead). The best way to reproduce this bug is to stand
(or sit) in BOY WONDER's line of fire in a classroom while everyone's waiting
for the teacher to show up for the lesson.
All play and no work
In lesson $E3 (MR ROCKITT - EXAM ROOM), little boys 4-8 head
off to the White Room in accordance with their personal timetables, but no
teacher ever arrives to start the lesson.
POKE 34531,134 ($86E3,$86) (sends MR CREAK to the White Room)
Waiting for EINSTEIN
Before wiping the board and getting a lesson under way, ERIC's teacher will
wait for EINSTEIN to sit down first: see $0B3B. This makes sense at the
beginning of a lesson, but that same routine is called several times during the
course of a lesson (see $0A58) to check whether ERIC is present, which means
that the teacher will also stop whatever he's doing and wait for EINSTEIN to
sit down before continuing on those occasions too. This is not really
noticeable except during lessons where there is no question-and-answer session
taking place between the teacher and the swot, and the teacher is pacing up and
down in front of the blackboard instead. During those lessons, the call to
$0B3B is made each time the teacher has reached the point where he is just
about to turn round; if EINSTEIN is not sitting in a chair at that time
(because ERIC has pushed him out of his seat, for example), the teacher will
wait until EINSTEIN is back in his seat before turning round.
This phenomenon can be made more readily reproducible and observable by using
the following POKEs:
POKE 7349,20 ($1CB5,$14) (to lengthen the delay before a
dethroned character rises)
POKE 2850,0 ($0B22,$00) (to make every lesson a
non-question-and-answer lesson)
WACKER's number blindness
If ERIC has exactly 10000 lines, MR WACKER will come rushing to ERIC's side and
say "YOU HAVE OVER 10000 LINES TO WRITE ERIC...". Does the headmaster not know
how to count, or does he actually think that 10000 > 10000? Either way, this is
poor form for a maths teacher.
POKE 7538,233 ($1D72,$E9) (keeps MR WACKER at bay until ERIC's lines
total exceeds 10000)
MR ROCKITT as a boy
In lesson $E5 (REVISION LIBRARY), MR ROCKITT paces up and down
in the Exam Room like a little boy, waiting for a teacher who never arrives.
POKE 34021,188 ($84E5,$BC) (sends MR ROCKITT to the staff room)
Misspelt element
'Phosphorous' (at $4EBC) is misspelt; it should be 'Phosphorus'.
MR CREAK and the empty class
Lesson $E6 (REVISION LIBRARY) has MR CREAK teaching an empty
class in the Reading Room.
POKE 34534,188 ($86E6,$BC) (sends MR CREAK to the staff room)
Share a chair
If ERIC hits a character who is sitting on a chair, and then quickly sits in
the chair just vacated, ERIC will not be pushed out of the chair when the
character rises and takes his seat again.
800 LINES BOY WONDER - NOW WHERE ARE YOU?
In lesson $EC (MR WACKER - WHITE ROOM), BOY WONDER is in the
Revision Library (on his own, as it happens). However, if EINSTEIN tells on BOY
WONDER for writing on the board, MR WACKER will still give lines to the absent
tearaway. (Perhaps the ceiling in the White Room conducts sound well enough for
BOY WONDER to hear the admonition.) The same thing may also happen in lesson
$ED (MR WITHIT - WHITE ROOM), when BOY WONDER is once again in
the Revision Library (this time accompanied by ANGELFACE).