What's really weird is that apparently Matthew only uses label names that are exactly five letters long.
Repton 3 "Now" Screen H
Re: Repton 3 "Now" Screen H
Think I did use meaningful label names at first and settled on five characters to keep the source length down and trying to impose some sort of order on it.
Must have got stuck towards the end creating label names not thinking it would be looked at by anyone other than me.
Re: Repton 3 "Now" Screen H
It's been very interesting to read through, and start remembering what things mean! Even when the names don't make sense to me, I have to make an association somehow.Rocketeer wrote: ↑Fri Aug 20, 2021 8:21 pm Think I did use meaningful label names at first and settled on five characters to keep the source length down and trying to impose some sort of order on it.
Must have got stuck towards the end creating label names not thinking it would be looked at by anyone other than me.
I guess you also run into source length problems if you use names that are too long, and sticking to five characters mitigates that.
Re: Repton 3 "Now" Screen H
So we never really got to the bottom of exactly what causes this, but it still happens in the new version Matthew released today, so I looked into it some more.
To recap - if you hold down a key while the intro tune plays, then the game runs significantly faster than it does if you don't hold down a key during the intro tune. This seems to apply on multiple versions of the game, in several different emulators, and on real hardware.
I captured traces from beebjit of running the Repton Thru Time game (Repton_Thru_time_D1S2_80T_HG3_ABA748C2_1.hfe). I launched the game, waited a bit to let the disc activity end, then pressed space to start, then after the level loads, I immediately ran all the way to the right, then all the way to the left, then activated the status screen - the emulator runs quite slowly when logging a trace so it was easy to ensure that there were no dead frames in this period, I had the next key pressed before the game was ready for it. I did this twice with a normal start, just tapping Space; and another two times holding down a key (X) while the intro tune was playing. In the normal start cases, the time on the status screen read 9920; in the cases where I'd been holding a key, it said 9926, saving 6 ticks out of 80 (>5%).
The traces are a bit unwieldy, but using some makeshift tools I was able to crop them to just the period from JINGL being called up to when BEGIN is called, and isolate the traces for each IRQ handled in those periods. The thing that jumps out in the results is that when no key was being held during the intro tune, there are a lot more keyboard scans going on in the interrupt handler. In particular 0xF065 (keyboardInterruptRoutine) gets called over 300 more times (336 vs 31). In addition, there are just fewer interrupts in general - even accounting for the slightly shorter execution time, the delta is more than I'd expect.
My guess is that the operating system is somehow stuck in the "auto repeat" keyboard mode, and is not doing its usual scanning for newly-pressed keys - perhaps it's masked them in software as it has its own IER-like variable; or maybe it's disabled the hardware interrupt. But I don't feel this is the complete answer as I don't understand why there is such a different number of vsync events, for example, or 100Hz events in general. The elapsed time difference was not that high - something like 200,000 instructions out of over 5,000,000 - so the number of vsyncs or 100Hz interrupts or ADC conversions etc should only have changed by 5%-10%.
It's interesting that this looks more and more like a general issue rather than a bug in Repton 3, and I wonder how many other games are suffering large numbers of unneeded keyboard interrupts - as clearly Repton 3 works fine with these interrupts (somehow) disabled.
It's late and I've run out of steam without getting to a full answer, but I thought I'd share the results in case anyone else wants to have a closer look. I've put a zip here (https://drive.google.com/file/d/1Xmj4S2 ... drive_link) containing the four trace files, cropped to just the period between calling JINGL (to play the intro tune) and BEGIN (to display the status screen). Two of them were taken without holding a key during JINGL, the other two were taken with a key being held down.
Also here's my summary of IRQ behaviour for the case where no key was held down. The list at the bottom shows key addresses I'm looking for and their names, and how many times they were hit during interrupt servicing. Above that is a sorted list of sequences of these addresses being hit during interrupt servicing - this is a bit more erratic but maybe gives an idea of what order things happen in.
And here's the summary for the case where I was holding a key during the intro tune:
To recap - if you hold down a key while the intro tune plays, then the game runs significantly faster than it does if you don't hold down a key during the intro tune. This seems to apply on multiple versions of the game, in several different emulators, and on real hardware.
I captured traces from beebjit of running the Repton Thru Time game (Repton_Thru_time_D1S2_80T_HG3_ABA748C2_1.hfe). I launched the game, waited a bit to let the disc activity end, then pressed space to start, then after the level loads, I immediately ran all the way to the right, then all the way to the left, then activated the status screen - the emulator runs quite slowly when logging a trace so it was easy to ensure that there were no dead frames in this period, I had the next key pressed before the game was ready for it. I did this twice with a normal start, just tapping Space; and another two times holding down a key (X) while the intro tune was playing. In the normal start cases, the time on the status screen read 9920; in the cases where I'd been holding a key, it said 9926, saving 6 ticks out of 80 (>5%).
The traces are a bit unwieldy, but using some makeshift tools I was able to crop them to just the period from JINGL being called up to when BEGIN is called, and isolate the traces for each IRQ handled in those periods. The thing that jumps out in the results is that when no key was being held during the intro tune, there are a lot more keyboard scans going on in the interrupt handler. In particular 0xF065 (keyboardInterruptRoutine) gets called over 300 more times (336 vs 31). In addition, there are just fewer interrupts in general - even accounting for the slightly shorter execution time, the delta is more than I'd expect.
My guess is that the operating system is somehow stuck in the "auto repeat" keyboard mode, and is not doing its usual scanning for newly-pressed keys - perhaps it's masked them in software as it has its own IER-like variable; or maybe it's disabled the hardware interrupt. But I don't feel this is the complete answer as I don't understand why there is such a different number of vsync events, for example, or 100Hz events in general. The elapsed time difference was not that high - something like 200,000 instructions out of over 5,000,000 - so the number of vsyncs or 100Hz interrupts or ADC conversions etc should only have changed by 5%-10%.
It's interesting that this looks more and more like a general issue rather than a bug in Repton 3, and I wonder how many other games are suffering large numbers of unneeded keyboard interrupts - as clearly Repton 3 works fine with these interrupts (somehow) disabled.
It's late and I've run out of steam without getting to a full answer, but I thought I'd share the results in case anyone else wants to have a closer look. I've put a zip here (https://drive.google.com/file/d/1Xmj4S2 ... drive_link) containing the four trace files, cropped to just the period between calling JINGL (to play the intro tune) and BEGIN (to display the status screen). Two of them were taken without holding a key during JINGL, the other two were taken with a key being held down.
Also here's my summary of IRQ behaviour for the case where no key was held down. The list at the bottom shows key addresses I'm looking for and their names, and how many times they were hit during interrupt servicing. Above that is a sorted list of sequences of these addresses being hit during interrupt servicing - this is a bit more erratic but maybe gives an idea of what order things happen in.
Code: Select all
gfoot@turtle ~/Documents/beebjit_win_0.9.8/reptontraces
$ cat results1.txt
1 system VIA, 100Hz, ACIA, ADC end conversion
1 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, user VIA, ADC end conversion
1 system VIA, 100Hz, system VIA, ADC end conversion, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, user VIA
1 system VIA, 100Hz, system VIA, ADC end conversion, user VIA, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
1 system VIA, 100Hz, system VIA, vsync, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, ADC end conversion
1 system VIA, scan keyboard, keyboardInterruptRoutine, keyPressedInterrupt
2 system VIA, 100Hz, system VIA, ADC end conversion, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, system VIA, vsync
3 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, system VIA, ADC end conversion
3 system VIA, 100Hz, user VIA, system VIA, ADC end conversion, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
12 system VIA, 100Hz, system VIA, ADC end conversion, ACIA
14 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, system VIA, vsync
16 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, ADC end conversion
16 system VIA, 100Hz, user VIA, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
17 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, user VIA
18 system VIA, 100Hz, system VIA, vsync, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
23 system VIA, 100Hz, system VIA, ADC end conversion, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
344 system VIA, 100Hz, ACIA
394 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
402 user VIA
434 system VIA, vsync
832 system VIA, ADC end conversion
f065 337 keyboardInterruptRoutine
dd4c 53 user VIA
de4a 67 ADC end conversion
dd0b 487 system VIA
ddcc 391 100Hz
f00f 1 keyPressedInterrupt
ef13 336 keyboardTimerInterrupt
dd15 47 vsync
dca9 391 ACIA
de78 1 scan keyboard
dd6f 0 speech
Code: Select all
gfoot@turtle ~/Documents/beebjit_win_0.9.8/reptontraces
$ cat results2.txt
1 system VIA, 100Hz, system VIA, ADC end conversion, system VIA, vsync, ACIA
1 system VIA, 100Hz, system VIA, ADC end conversion, user VIA, ACIA
1 system VIA, 100Hz, user VIA, ACIA, ADC end conversion
2 system VIA, 100Hz, system VIA, vsync, system VIA, ADC end conversion, ACIA
2 system VIA, 100Hz, user VIA, system VIA, ADC end conversion, ACIA
3 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt, ADC end conversion
4 system VIA, 100Hz, ACIA, ADC end conversion
5 system VIA, 100Hz, system VIA, ADC end conversion, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
14 system VIA, 100Hz, system VIA, vsync, ACIA
18 system VIA, 100Hz, user VIA, ACIA
21 system VIA, 100Hz, system VIA, ADC end conversion, ACIA
142 system VIA, 100Hz, ACIA, keyboardInterruptRoutine, keyboardTimerInterrupt
384 user VIA
416 system VIA, vsync
616 system VIA, 100Hz, ACIA
807 system VIA, ADC end conversion
f065 31 keyboardInterruptRoutine
dd4c 37 user VIA
de4a 42 ADC end conversion
dd0b 334 system VIA
ddcc 272 100Hz
f00f 0 keyPressedInterrupt
ef13 31 keyboardTimerInterrupt
dd15 28 vsync
dca9 272 ACIA
de78 0 scan keyboard
dd6f 0 speech
- scarybeasts
- Posts: 1052
- Joined: Tue Feb 06, 2018 7:44 am
- Contact:
Re: Repton 3 "Now" Screen H
Hmm very interesting.gfoot wrote: ↑Sun Sep 10, 2023 1:25 am To recap - if you hold down a key while the intro tune plays, then the game runs significantly faster than it does if you don't hold down a key during the intro tune. This seems to apply on multiple versions of the game, in several different emulators, and on real hardware.
When the game is running normally, the "slowness" comes from MOS 1.2 doing key checking in the 10ms timer interrupt:
Code: Select all
DE31 LDA &EC ;check if key has been pressed
DE33 ORA &ED ;
DE35 AND &0242 ;(this is 0 if keyboard is to be ignored, else &FF)
DE38 BEQ &DE3E ;if 0 ignore keyboard
DE3A SEC ;else set carry
DE3B JSR &F065 ; Call keyboard handler centisecond interupt
MOS does the check if it thinks a key is down. It's presumably checking to see if the key has been released, and doing autorepeat / buffer handling.
When the game is running faster due to the long key press during the intro tune, MOS does not think a key is down (even when it is), so it skips the extra handling.
I'm not sure, but I think the culprit is an OSBYTE called by Repton 3 at $2F84 mid-way through the intro tune:
Code: Select all
*************************************************************************
* *
* OSBYTE A6-FF ENTRY POINT *
* *
* READ/ WRITE SYSTEM VARIABLE OSBYTE NO. +&190 *
* *
*************************************************************************
Code: Select all
[ITRP] 2F7E: LDA #$B2 [A=00 X=05 Y=FC S=FF F= Z 1 ]
[ITRP] 2F80: LDX #$00 [A=B2 X=05 Y=FC S=FF F= 1 N]
[ITRP] 2F82: LDY #$00 [A=B2 X=00 Y=FC S=FF F= Z 1 ]
[ITRP] 2F84: JSR $FFF4 [A=B2 X=00 Y=00 S=FF F= Z 1 ]
Cheers
Chris
- MillieTD83
- Posts: 179
- Joined: Mon Aug 24, 2009 6:53 pm
- Location: Thetford, UK
- Contact:
Re: Repton 3 "Now" Screen H
If this helps... I've experienced something a little similar playing Bonecruncher. Holding down space or return while moving for some reason speeds up Bono a tiny bit.
REPEAT PRINT'"FOZZY!!!!! ";:UNTIL FALSE
BBC Master 128 w/MultiOS, PiTubeDirect, Econet, Datacentre+CF-IDE interface, Gotek
BBC Master 128 w/MultiOS, PiTubeDirect, Econet, Datacentre+CF-IDE interface, Gotek
- Diminished
- Posts: 1252
- Joined: Fri Dec 08, 2017 9:47 pm
- Contact:
Re: Repton 3 "Now" Screen H
I think Chris may be right about this (surprising no-one). If I NOP out the JSR &FFF4 here and then repeat gfoot's experiment, I get 9920 (±1) consistently, regardless of whether I held down a key or not.scarybeasts wrote: ↑Sun Sep 10, 2023 3:32 am This writes $0242, which is the keyboard semaphore. I think you corrupt MOS state if you do that while there's a key down. And weirdness follows.
(If you want to play along at home, the disc image we're using is this one.)
Looking at the original source, the keyboard semaphore gets written in a couple of places in that intro code (B.CTRLM):
Code: Select all
950 .CTRLM
960 LDX#&FF:TXS
970 JSRDIABL
980 LDA#0:STAuserp
990 LDA#178:LDX#&FF
1000 LDY#0:JSROSB <---- here
1010 JSRTYLER
1020 JSRINRUP
1030 JSRSETUP
1040 ASLA:TAX
1050 LDAaddrs+1,X:PHA
1060 LDAaddrs,X:PHA:RTS
1070 .addrs
1080 EQUWCABIN-1:EQUWHIGHR-1
1090 EQUWGAMES-1
1100 .CABIN
1110 JSRROTAT
1120 JSRFILES
1130 JSREXORS
1140 JSRDIREC
1150 JMPCTRLM
1160 .LYIAR
1170 JSRROTAT
1180 JMPCTRLM
1190 .HIGHR
1200 JSRROTAT
1210 JSRCYPHR:BCCLYIAR
1220 INCuserp
1230 .GAMES
1240 JSRJINGL
1250 LDAtunes:BEQwaits
1260 LDX#100:JSRDELAY
1270 .waits
1280 LDA#178:LDX#0:LDY#0:JSROSB <---- and here
1290 JSRROTAT
1300 JSRTYLER
1310 JSRINRUP
1320 JSRSHEET
Re: Repton 3 "Now" Screen H
Indeed that does sound like a possible cause. I'd like to understand more about the effect this is actually having on the number of different types of interrupts though as I find that unexpected - things like causing a lot more 100Hz interrupts to occur, just seem odd - unless my analysis was wrong there!
Also regarding whether it should be fixed to always run the slow way, or always run the fast way, it's an interesting one. Presumably the levels were designed to be run the slow way. But in some configurations this level is actually impossible, as far as I can see, unless you find some way of reducing this interrupt overhead - either this cheat, or a hardware change (like removing the ADC? emulating a Master?), or something else.
At least in beebjit 0.9.8 I can't do better than the attached hand-edited replay capture - I'm pretty sure all control inputs are timed ahead of the corners, yet I'm still several squares behind. So it feels like if there's a way to force the keyboard into "fast" mode when it's intentionally disabled, it would seem a good thing to do!
Also regarding whether it should be fixed to always run the slow way, or always run the fast way, it's an interesting one. Presumably the levels were designed to be run the slow way. But in some configurations this level is actually impossible, as far as I can see, unless you find some way of reducing this interrupt overhead - either this cheat, or a hardware change (like removing the ADC? emulating a Master?), or something else.
At least in beebjit 0.9.8 I can't do better than the attached hand-edited replay capture - I'm pretty sure all control inputs are timed ahead of the corners, yet I'm still several squares behind. So it feels like if there's a way to force the keyboard into "fast" mode when it's intentionally disabled, it would seem a good thing to do!
Code: Select all
./beebjit.exe -0 ../beeb/discs/hfe/Repton_Thru_Time_D1S2_80T_HG3_ABA748C2_1.hfe -replay ../beeb/caps/test.cap -debug -commands "breakat 42384000;fast;c;fast;c"
- Attachments
-
- reptonthrutime_now_h_edited.cap.zip
- (779 Bytes) Downloaded 13 times
Re: Repton 3 "Now" Screen H
Just completed "Now" on the new Repton 3 Redux (see BBC Micro Games Archive)
Happy to report the time glitch in this version is not present
(Either that, or I'm just very good )
Happy to report the time glitch in this version is not present
(Either that, or I'm just very good )
REPTON 2 IS ENDED