How best to introduce a timed-delay whilst in Supervisor mode
Posted: Mon Mar 08, 2021 1:24 pm
Hello gurus!
I am researching how best to re-code a software timing loop within the NET device driver that is currently tied to the CPU clock in such a way as to duplicate the intended timing effect in a reliable way inside an emulator such as QPC, QEmuLator, uQLX etc.
This is part of the on-going QLUB Adapter project, which already off-loads 99% of the timing-sensitive NET driver code to the microcontroller firmware, leaving behind only the (non-timing critical) Access layer code plus a small routine used by the NET driver to repeat the last operation (in dd/nd/nd_rept) without the help of the IOSS Scheduler Loop - the call itself being made by the NET Access layer in a few specific situations - and thus already in Supervisor mode, but with Interrupts still enabled.
On the surface, this code fragment appears to remain the same across all the TK2 NET driver versions, even for QXL and (S)GC, where it can't possibly maintain the intended timing as it was originally designed for on a basic QL. That said, some external patching routine might update the relevant loop constants before the routine gets called on those platforms.
I made an attempt in the ND-Q68 NET driver to rewrite these, but there was able to rely on its 40MHz CPU clock to more or less reproduce the intended timings. Under an emulator however, the clock cycle-timings become even more abstract and it is this that I am trying to correct as I modify the NET driver to integrate fully with the QLUB Adapter.
Here's the (annotated) extract of the routine which is called under the following situations (all in Supervisor mode, Interrupts enabled, without using the IOSS 'retry' mechanism):
a) When an NETO channel is closed - to attempt repeatedly to send the final packet for c.25 seconds before giving-up.
b) When an Nx channel attempts to send or receive the next 'request packet' to the remote FSERVE host.
So, in short, we need a different way to measure time if we are to duplicate this 'manual NET operation retry' over c25 secs - or until the op completes - plus the (less important) delay before testing the keyboard for BRK, but without recourse to the (unknown) CPU cycle timings when run under an emulator.
Any ideas?
I am researching how best to re-code a software timing loop within the NET device driver that is currently tied to the CPU clock in such a way as to duplicate the intended timing effect in a reliable way inside an emulator such as QPC, QEmuLator, uQLX etc.
This is part of the on-going QLUB Adapter project, which already off-loads 99% of the timing-sensitive NET driver code to the microcontroller firmware, leaving behind only the (non-timing critical) Access layer code plus a small routine used by the NET driver to repeat the last operation (in dd/nd/nd_rept) without the help of the IOSS Scheduler Loop - the call itself being made by the NET Access layer in a few specific situations - and thus already in Supervisor mode, but with Interrupts still enabled.
On the surface, this code fragment appears to remain the same across all the TK2 NET driver versions, even for QXL and (S)GC, where it can't possibly maintain the intended timing as it was originally designed for on a basic QL. That said, some external patching routine might update the relevant loop constants before the routine gets called on those platforms.
I made an attempt in the ND-Q68 NET driver to rewrite these, but there was able to rely on its 40MHz CPU clock to more or less reproduce the intended timings. Under an emulator however, the clock cycle-timings become even more abstract and it is this that I am trying to correct as I modify the NET driver to integrate fully with the QLUB Adapter.
Here's the (annotated) extract of the routine which is called under the following situations (all in Supervisor mode, Interrupts enabled, without using the IOSS 'retry' mechanism):
a) When an NETO channel is closed - to attempt repeatedly to send the final packet for c.25 seconds before giving-up.
b) When an Nx channel attempts to send or receive the next 'request packet' to the remote FSERVE host.
Code: Select all
nd_rept
...
move.w #2500,d7 try 2500 times in all (about 25 seconds)
tst.b nd_dest(a0) is it send broadcast?
bne.s ndr_try ... no
lsr.w #1,d7 check immediately *** I.e. we start to check the keyboard on each iteration for a BCAST, but only after the first 5secs or so for other NET operations.
*
ndr_try
jsr (a2) do operation *** the entry address to the required NET routine was passed in a2
beq.s ndr_rts ... done
blt.s ndr_tbrk try again if 'Not Complete' - the usual return from the physical NET code that would normally trigger an IOSS 'retry' later
move.w #1499,d0 otherwise wait 7ms *** This 7ms timing (plus the time that each physical NET operation attempt may take before timing-out) needs re-coding
dbra d0,*
ndr_tbrk
cmp.w #2000,d7 wait about 5-6 seconds before checking for BRK (unless a BCAST)
bgt.s ndr_tend
*
bsr.s nd_break check break *** a simple call to MT.HDOP/IPCOM to read two rows of the keyboard and return NZ if BRK detected
bne.s ndr_abort
ndr_tend
dbra d7,ndr_try
ndr_abort
...
Any ideas?