[Coladam] Timers in SmartBasic

Richard F. Drushel drushel at apk.net
Sun Aug 19 14:19:30 EDT 2007

On Sun, August 19, 2007 6:50 am, Payton Byrd wrote:

> Can anyone point me to a reference online or share some code that allows the
> tracking of time by second in SmartBasic?  I suspect EOS will be involved, but
> I can't find the relevant information.

     Hi Payton, EOS isn't involved in time tracking (except for some
global variables to store day, month, and year, for file I/O).

     SmartBASIC 1.x implements a system clock natively, using the 60 Hz VDP
NMI as the trigger.  It links into the NMI vector at 038H.  It just counts
NMIs, rolls over the seconds field when it gets to 60, keeps rolling over all
the fields up through year as needed.

     If you want something for vanilla SmartBASIC 1.0, then the same thing
can be done, but you have to raise LOMEM to reserve room for the machine
code, then POKE it in.

     To install such code "hot", you have to disable the NMI long enough to
POKE it, then restart the NMI.  The typical way was to POKE a RETN instruction
at 038H and wait long enough for an NMI to have occurred and the RETN to be
executed.  While NMI means "Non-Maskable Interrupt", and implies that you
ought not be able to turn it off, the ADAM actually requires a handshake back
to the VDP (which is generating the NMI) in order to get the next NMI cycle to
occur.  This handshake is a read of VDP register 8 IIRC.  So, putting a RETN
straightaway without a prior read register 8 will effectively stop the NMIs
until you get around to reading register 8.

     Anyways, once the NMIs are off, you can POKE a JMP nnnn instruction at
038H, where nnnn is the start address of your clock routine.  POKE in your
new code, which must then JMP xxxx back into whatever code you patched over
back at 038H.  You need to disassemble what is already there in order to
find out where to jump back to.  Also, since the JMP nnnn will wipe out 3
bytes of existing machine code, you have to make sure that you add those
instructions to the end of your clock routine, right before you JMP xxxx.

     Once the patch is in place, you can then CALL READ_REGISTER (I
don't have the absolute address handy, it will be in te 64xxx range) and
that will restart NMIs and your clock as well.

     Note that anything else that disables NMIs will make your clock stop!
ADAMnet I/O, especially disk or tape I/O, turns off NMIs, so eventually
your clock will drift from the real clock time.  A graphic way to show this
is to start blinking text with the FLASH command, then type CATALOG.  The
flashing text will freeze until the I/O is complete, then resume once it
starts printing the file listing.

     I can dig up the actual SmartBASIC 1.x assembly code for the software
clock if you like.  It is not complicated Z80 code at all.  I would have to
back-port it to SmartBASIC 1.0 if you actually wanted to use it there; or,
I could leave that as an exercise for the reader :-)

     *Dr. D.*

Richard F. Drushel, Ph.D.            | "They fell:  for Heaven to them no hope
Department of Biology                |  imparts / Who hear not for the beating
Case Western Reserve University      |  of their hearts."
Cleveland, Ohio  44106-7080  U.S.A.  |         -- Edgar Allan Poe, "Al-Aaraaf"

More information about the Coladam mailing list