Mistrial subtraction
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).
POKE 8613,16 ($21A5,$10)
POKE 8637,16 ($21BD,$10)
Low product values
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.
POKE 16961,42 ($4241,$2A)
A pair of jerks
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:
POKE 10000,144 ($2710,$90) (ANGELFACE)
POKE 11438,144 ($2CAE,$90) (BOY WONDER)
The bully and the blackboard
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:
POKE 6522,195 ($197A,$C3)
POKE 6531,195 ($1983,$C3)
The wall most stared at
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.
wmsa
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.
stf
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:
POKE 16564,69 ($40B4,$45)
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).
POKE 17508,77 ($4464,$4D)
Double staircases
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:
$0D37 LDA $FB Pick up the character's y-coordinate from $FB.
$0D39 STA $AD Copy the character's y-coordinate to $AD.
$0D3B INC $AD Increment the y-coordinate at $AD.
$0D3D JMP $0D0F 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:
$140A LSR A Is the character midstride?
$140B BCC $1416 Branch if not.
$140D LDA $47 Pick up the direction indicator from $47.
$140F BNE $1413 Branch if going upstairs.
$1411 INC $FB Increment the y-coordinate if going downstairs.
$1413 JMP $1393 Move the character from the midstride position.
$1416 INC $26 Move the character midstride.
$1418 LDA $47 Pick up the direction indicator from $47.
$141A BEQ $141E Branch if going downstairs.
$141C DEC $FB Decrement the y-coordinate if going upstairs.
$141E JMP $322E 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:
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.
POKE 3075,207 ($0C03,$CF)
POKE 3110,207 ($0C26,$CF)
POKE 3118,207 ($0C2E,$CF)
MR CREAK's superior vision
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.
csv
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.
obo
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:
$166B DEC $D3 Decrement the comparison x-coordinate (C) at $D3.
$166D LDA $FC Pick up the character's x-coordinate from $FC.
$166F CMP $D3 Compare the character's x-coordinate with C−1.
$1671 INC $D3 Reset the x-coordinate at $D3 back to C.
$1673 BCC $168E Branch if the character's x-coordinate is less than C−1.
$1675 LDA $D3 Pick up the comparison x-coordinate (C) from $D3.
$1677 ADC #00 Add 1 to it.
$1679 CMP $FC Is the character's x-coordinate greater than C+1?
$167B BCC $168E Branch if so.
POKE 5745,230 ($1671,$E6)
POKE 5746,211 ($1672,$D3)
POKE 5747,144 ($1673,$90)
POKE 5748,25 ($1674,$19)
POKE 5749,165 ($1675,$A5)
POKE 5751,105 ($1677,$69)
POKE 5752,0 ($1678,$00)
Misplaced message box
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:
bookcase1
To restore the bookcase to something close to its former glory:
bookcase2
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:
Nearly there, but something is still not quite right with the books on the bottom shelf on the right-hand side:
books1
To fix them:
books2
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).