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.