Commodore 128 Alive!

Commodore 128 => Tips & tricks => Topic started by: BigDumbDinosaur on December 11, 2007, 04:09 PM

Title: Hey, buddy! Ya got the time?
Post by: BigDumbDinosaur on December 11, 2007, 04:09 PM
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.
EhPortal 1.34 © 2025, WebDev