Hey, buddy! Ya got the time?

Started by BigDumbDinosaur, December 11, 2007, 04:09 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

BigDumbDinosaur

In most operating environments, the kernel (kernal for you Commodorians) implements a way to generate an arbitrary time delay.  For example, in UNIX or Linux the sleep(x) kernel call will suspend program execution for approximately X seconds.  Unfortunately, Commodore didn't see fit to implement a sleep() function in their kernal.  Yes, it's possible to use the jiffy "clock" but it's about as stable as a three-legged elephant with epilepsy, especially when frequent serial bus activity occurs.

Fortunately, the hardware resources needed to set up a stable and repeatable sleep() function are already available.  All that is needed is a little assembly language code.  There are two parts to the following program: a setup function that is run only once and the delay function itself.


       *=$0B00                ;assembles into cassette buffer
;
cia2   =$dd00                 ;CIA #2 base address
d2tod  =cia2+8                ;time of day (TOD) clock
d2todt =d2tod+0               ;TOD seconds/10 (BCD)
d2icr  =cia2+13               ;interrupt control/source
d2cra  =cia2+14               ;control register A
d2crb  =cia2+15               ;control register B
;
;=======================================
;
;function jump table
;
sleep  jmp tdl                ;delay function $0B00
;
;=======================================
;
setup  lda #%00000100         ;setup function $0B03
       sta d2icr              ;no TOD interrupts
;
;execute next 3 lines on PAL machines only
;
       lda d2cra              ;control register A
       ora #%10000000         ;50 Hz power only!!!
       sta d2cra              ;set frequency
;
       lda d2crb              ;control register B
       and #%01111111         ;setting time, not alarm
       sta d2crb
       lda d2todt             ;nudge the clock
       sta d2todt
       rts
;
;=======================================
;
;time delay function -- load .X with delay in seconds.
;
tdl    ldy #10                ;0.1 sec delay counter
;
tdl01  lda d2todt             ;TOD tenths
;
tdl02  cmp d2todt             ;wait until...
       beq tdl02              ;it changes
;
       dey                    ;step 0.1 sec counter
       bne tdl01              ;repeat
;
       dex                    ;step 1.0 sec counter
       bne tdl                ;repeat
;
       rts
;
;


To perform the setup from BASIC, code as follows:

BANK 15;SYS DEC("0B03")

To call sleep() from BASIC:

BANK 15;SYS DEC("0B00"),,TD

where TD is the delay period in seconds (0=256 seconds).

This code can be ported to the C-64.  Simply find a new home for it, such as the 64's cassette buffer at $033C (828) and change the SYS addresses accordingly.  To pass the time delay in 64 mode POKE it into location 781.
x86?  We ain't got no x86.  We don't need no stinking x86!