Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C64 TOD AM/PM switching

219 views
Skip to first unread message

Paul Förster

unread,
Jan 15, 2014, 3:05:48 PM1/15/14
to
Hi,

does a real C64 switch the AM/PM flag of the TODs (bit 7 of dc0b &
dd0b) at 01:00:00.0 and 13:00:00.0? Vice, at least the Mac port, does!

I would expect the switches to take place at 12:00:00.0 twice a day,
i.e. noon and midnight. Is Vice broken or does a real C64 exhibit the
same strange behavior? If so, why at 1 o'clock? Historical reasons? The
net has nothing about switching at 1 o'clock. Whereever I look, I
always find information about switching at 12 o'clock. Looked at
Wikipedia (Article "12 hour clock"), etc., which is very interesting by
the way.

Can anybody confirm this strange behavior of the CIA clocks on the real thing?

Thanks in advance.
--
cul8er

Paul
paul.f...@gmx.net

rusure

unread,
Jan 16, 2014, 8:23:28 AM1/16/14
to
When the CIA TOD clocks are initiated to the
range of 01:00:00:0 to 12:59:59:0, the clocks
remain in the proper range. The AM or PM
settings are denoted by whether the high
order hour bit is set or clear. When the
hour is set to $12, the C128D system sets
the hour high order bit. When the hour
is set to $92, the high order bit is
cleared. The following program runs on my
C128D. The first two instructions should
be discarded on a C64 and the C128
routine at B8c2 prints the hexidecimal
character equivalents of the accumulator
contents. The clock rolls over from
11:59:59;9 to 92:00:00:0 and from
91:59:59:9 to 12:00:00:0. It is highly
likely that the program will function
much the same way on a "real" C64.

1300 A2 00 LDX #$00
1302 8E 00 FF STX $FF00
1305 A0 11 LDY #$11
1307 8C 0B DC STY $DC0B
130A A0 59 LDY #$59
130C 8C 0A DC STY $DC0A
130F A0 53 LDY #$53
1311 8C 09 DC STY $DC09
1314 A0 00 LDY #$00
1316 8C 08 DC STY $DC08
1319 A9 0D LDA #$0D
131B A0 03 LDY #$03
131D 20 D2 FF JSR $FFD2
1320 B9 08 DC LDA $DC08,Y
1323 20 C2 B8 JSR $B8C2
1326 A9 3A LDA #$3A
1328 88 DEY
1329 10 F2 BPL $131D
132B A5 91 LDA $91
132D 30 EA BMI $1319
132F 60 RTS

rusure

unread,
Jan 16, 2014, 3:00:45 PM1/16/14
to
On Thursday, January 16, 2014 6:23:28 AM UTC-7, rusure wrote:
> On Wednesday, January 15, 2014 1:05:48 PM UTC-7, Paul Förster wrote:
>
> > Hi,
> > does a real C64 switch the AM/PM flag of the TODs (bit 7 of dc0b & dd0b) at 01:00:00.0 and 13:00:00.0? Vice, at least the Mac port, does! I would expect the switches to take place at 12:00:00.0 twice a day, i.e. noon and midnight. Is Vice broken or does a real C64 exhibit the same strange behavior? If so, why at 1 o'clock? Historical reasons? The net has nothing about switching at 1 o'clock. Whereever I look, I always find information about switching at 12 o'clock. Looked at Wikipedia (Article "12 hour clock"), etc., which is very interesting by the way
> > Can anybody confirm this strange behavior of the CIA clocks on the real thing?
> >
> > Thanks in advance.
> > --
> > cul8er
> >
> > Paul
> > handle paul.foerster ISP gmx.net
I have uploaded to the URL listed below a movie of the TOD clock running from 11:59::50:0 to 92:00:??:? and from 91:59:50:0 to 12:59:??:? The movie shows the TOD running on my C128D in C64 mode. I have replaced the jsr to the C128 hex routine with something that prints a BCD byte in the accumulator. I have skipped the storage of #0 in $ff00 at the beginning of the program.


https://drive.google.com/file/d/0B80L9cEZ8YnvZVI0ZHFuU3pOTHc/edit?usp=sharing

Paul Förster

unread,
Jan 16, 2014, 4:01:23 PM1/16/14
to
Hi rusure,

On 2014-01-16 13:23:28 +0000, rusure said:
> The clock rolls over from
> 11:59:59;9 to 92:00:00:0 and from
> 91:59:59:9 to 12:00:00:0.

so you confirm this to run on a *real* 128(D)?

> It is highly
> likely that the program will function
> much the same way on a "real" C64.

leaving aside the hexout routine at B8C2, yes, I feel it *should* work
the same. But I asked for physical proof, as Vice (Mac) flips the AM/PM
bit at 01:00:00 and 13:00:00 instead of 00:00:00 and 12:00:00 (all 24
hour notation), which is sort of strange.
--
cul8er

Paul
paul.f...@gmx.net

Paul Förster

unread,
Jan 16, 2014, 4:07:46 PM1/16/14
to
Hi rusure,

On 2014-01-16 20:00:45 +0000, rusure said:
> I have uploaded to the URL listed below a movie of the TOD clock
> running from 11:59::50:0 to 92:00:??:? and from 91:59:50:0 to
> 12:59:??:? The movie shows the TOD running on my C128D in C64 mode. I
> have replaced the jsr to the C128 hex routine with something that
> prints a BCD byte in the accumulator. I have skipped the storage of #0
> in $ff00 at the beginning of the program.
>
> https://drive.google.com/file/d/0B80L9cEZ8YnvZVI0ZHFuU3pOTHc/edit?usp=sharing

very interesting. So the bit gets flipped at 00:00:00 and 12:00:00 and
not 01:00:00 and 13:00:00. So I take it that Vice (Mac) has a bug here.
It flips the bit at the latter two points of time. :-(

Thanks very much.
--
cul8er

Paul
paul.f...@gmx.net

rusure

unread,
Jan 16, 2014, 6:24:09 PM1/16/14
to
On Thursday, January 16, 2014 2:07:46 PM UTC-7, Paul Förster wrote:
> Hi rusure,
>
>
>
> On 2014-01-16 20:00:45 +0000, rusure said:
>
> > I have uploaded to the URL listed below
> > a movie of the TOD clock running from 11:59::50:0 to 92:00:??:? and from 91:59:50:0
> > to 12:59:??:? The movie shows the TOD
> > running on my C128D in C64 mode. I have
> > replaced the jsr to the C128 hex routine
> > with something that prints a BCD byte in
> > the accumulator. I have skipped the
> > storage of #0 in $ff00 at the beginning
> > of the program.
> >
> > https://drive.google.com/file/d/0B80L9cEZ8YnvZVI0ZHFuU3pOTHc/edit?usp=sharing
>
> very interesting. So the bit gets flipped at
> 00:00:00 and 12:00:00 and not 01:00:00 and
> 13:00:00. So I take it that Vice (Mac) has
> a bug here.

The high order hour bit can be clear. or set.
The Commodore TOD hour byte can only "properly" (i'm making up this jargon as I write this)
assume values of $01 to $12 when the high order
bit is clear and $81 to $92 when the high order
bit is set. The hour byte "flips" (your
jargon) to $92 when the hour byte is set to
$12 and to $12 when the hour byte is set to
$92. From $11:$59:$59:$09 the TOD rolls over
to $92:$00:$00:$00 and from $91:$59:$59:$09 to $12:$00:$00:$00. You may be able to set the
TOD to improper values but I can't predict
the TOD's behavior when you do something
wrong. It may be useful to download the video
and view it in slow motion at the times when
the hour high order bit flips. The Mac TOD
behavior may be the result of a different
TOD philosophy rather than a bug.

rusure

unread,
Jan 16, 2014, 7:50:36 PM1/16/14
to
On Thursday, January 16, 2014 2:07:46 PM UTC-7, Paul Förster wrote:


> very interesting. So the bit gets flipped at 00:00:00 and 12:00:00 and
> not 01:00:00 and 13:00:00. So I take it that Vice (Mac) has a bug here.
> It flips the bit at the latter two points of time. :-(
> Thanks very much.
> --
> cul8er
>
> Paul
> handle paul.foerster ISPgmx.net

Below is a URL for an image containg captured frames from
the TOD movie I made earlier today. The frames contain
the instant when the AM/PM hour high irder bit flips.

https://drive.google.com/file/d/0B80L9cEZ8Ynvb0xsbGRiblUwc0U/edit?usp=sharing

Frank Buss

unread,
Jan 17, 2014, 11:03:34 AM1/17/14
to
Paul Förster wrote:
> Hi,
>
> does a real C64 switch the AM/PM flag of the TODs (bit 7 of dc0b & dd0b)
> at 01:00:00.0 and 13:00:00.0? Vice, at least the Mac port, does!

I wrote a test program, see below, binary here:

http://www.frank-buss.de/c64/tod.prg

Output on Vice 2.4 on Windows:

WRITE/READ/ROLLOVER: 11 / 11 / 12
WRITE/READ/ROLLOVER: 12 / 92 / 01
WRITE/READ/ROLLOVER: 91 / 91 / 92
WRITE/READ/ROLLOVER: 92 / 12 / 81

And on a real C64:

WRITE/READ/ROLLOVER: 11 / 11 / 92
WRITE/READ/ROLLOVER: 12 / 92 / 81
WRITE/READ/ROLLOVER: 91 / 91 / 12
WRITE/READ/ROLLOVER: 92 / 12 / 01

It is a bug in Vice, someone should file a bug report for the
Sourceforge project.

But another interesting effect: why does it invert the AM/PM flag, when
I write 12/92?

The program:

10 deffnb(x)=int(x/10)*16+x-int(x/10)*10
20 h=11:gosub1000
30 h=12:gosub1000
40 h=91:gosub1000
50 h=92:gosub1000
60 end
1000 print"write/read/rollover:";h;"/ ";
1010 poke56331,fnb(h)
1020 poke56330,fnb(59)
1030 poke56329,fnb(58)
1040 poke56328,fnb(00)
1060 x=peek(56328)
1070 x=peek(56331):gosub2000:print" / ";
1080 y=peek(56328)
1090 if x=peek(56331) then goto1080
1100 x=peek(56331):gosub2000
1110 print
1120 return
2000 y=int(x/16):gosub3000
2010 y=x-y*16
3000 print chr$(y+48);
3010 return

--
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss

Paul Förster

unread,
Jan 17, 2014, 2:27:52 PM1/17/14
to
Hi Frank,

On 2014-01-17 16:03:34 +0000, Frank Buss said:
now that is an interesting read! Thanks. :) Here's what I got on Vice
2.4 on the Mac which corresponds to what you found on Vice 2.4 on
Windows:

write/read/rollover: 11 / 11 / 12
write/read/rollover: 12 / 92 / 01
write/read/rollover: 91 / 91 / 92
write/read/rollover: 92 / 12 / 81

So, I conclude: Flipping the AM/PM bit back and fourth *should* happen
when going from 11:59:59.0 to 12:00:00.0 twice a day and not on 1
o'clock.

The only reason I see for inverting the AM/PM bit when writing 12 & 92
is that maybe they thought that most people think of 12 o'clock as noon
and not midnight. The computer loses its time anyway when switched off
so most people will set the clock to 12 PM rather than to 12 AM, still
entering 12 and not setting the AM/PM flag properly. Far fewer people
are awake during night than during day after all. Just a wild guess.
There's no other technical or logical reason.

Thanks for this short, but very insightful program. Actually, I was
about to write something similar this weekend but you did it before I
could. So, thanks very much. :-)
--
cul8er

Paul
paul.f...@gmx.net

Paul Förster

unread,
Jan 17, 2014, 3:25:34 PM1/17/14
to
Hi rusure,

> When the CIA TOD clocks are initiated to the
> range of 01:00:00:0 to 12:59:59:0, the clocks
> remain in the proper range. The AM or PM
> settings are denoted by whether the high
> order hour bit is set or clear. When the
> hour is set to $12, the C128D system sets
> the hour high order bit. When the hour
> is set to $92, the high order bit is
> cleared.

hmmm, sorry, maybe I'm dumb or something but I still don't get the idea
behind this special handling of clearing or setting the bit IF the hour
is set to $12 or $92. As your demos and Frank Busse's program
demonstrates, the clock ranges from between $12:$00 and $11:$59 for AM
and between $92:$00 and $91:$59 for PM and rolls over accordingly. So
far so good.

But then, what's the point in inverting the AM/PM bit if the hour is
set to $12 (effectively making it $92) or $92 (effectively making it
$12). If I set it to $12, then I mean 12 AM. And if I set it to $92,
then I explicitly mean 12 PM. So manipulating the bit in any way does
not make sense at all. So what's the idea behind that scheme?

Sorry, I don't live in 12-hour-clock country, so I have a hard time
understanding that specific oddity. I live in 24-hour-clock country
(Switzerland) and for me, the 12-hour-clock day ranges from 12 AM
(midnight!) to 11:59 AM (1 min. before noon!) and 12 PM (noon!) to
11:59 PM (1 min. before midnight!). If this is really the case (as I
learned during childhood), then flipping the bit explicitly (sic!) if I
set the TOD to one of the two 12 hours doesn't make sense at all as it
would teleport me to the other side of the world immediately. Not that
I would have any objection had Commodore indeed invented teleportation.
But it's definitely not working by setting a TOD to the wrong 12 hour
cycle.

So, I get the "how" but not the "why". :-( Why is that? It requires
unnecessary special treatment when setting the clock to one of the two
"twelves"...
--
cul8er

Paul
paul.f...@gmx.net

Paul Förster

unread,
Jan 17, 2014, 4:16:17 PM1/17/14
to
Hi Frank,

On 2014-01-17 16:03:34 +0000, Frank Buss said:
> But another interesting effect: why does it invert the AM/PM flag, when
> I write 12/92?

I think I have the solution to that oddity. As far as I know, you're
German, as I was (I'm Swiss now). So we, originating from 24-hour-land,
cannot understand that strange behavior per se. For us, it's illogical.
However, I talked to my wife about that. She is born Swiss but spent
her first 8 years of life in London because her dad was the Swiss
ambassador in London at that time.

So I asked her to not think about it long but intuitively tell me what
she would set the clock to if she was to set it to 12 (noon!). Her
answer was kind of surprising as she immediately said she'd set the
clock to 12 AM. She knows that this is logically not correct but still
would do it. Hence the English people seem to refer to 12 AM for noon
and hence 12 PM for midnight. I don't know how Americans handle it but
the British seem to handle it that way. As a consequence, I see the
automatic bit flipping as an automatic corrective action that Commodore
did to account for this everyday language oddity. It would also explain
why I have such difficulty to understand that effect that rusure
appears to see as the most natural thing in the world.

Frank, does that help you?
--
cul8er

Paul
paul.f...@gmx.net

Frank Buss

unread,
Jan 17, 2014, 4:33:57 PM1/17/14
to
Paul F�rster wrote:
>
> Frank, does that help you?

Not really, because in my test program I set the time to 12:59:58, not
12:00:00. Maybe ask your wife how she would set a digital clock to 12:30
PM :-)

Paul Förster

unread,
Jan 17, 2014, 6:49:52 PM1/17/14
to
Hi Frank,

On 2014-01-17 21:33:57 +0000, Frank Buss said:
> Not really, because in my test program I set the time to 12:59:58, not
> 12:00:00. Maybe ask your wife how she would set a digital clock to 12:30
> PM :-)

that's the point. We cannot nail it by mathematical logic and
correctness, but rather by how rusure and my wife see the world, i.e.
everyday language use in English speaking territories. rusure said,
setting the hour to between 01 and 12 sets the PM flag only if 12 is
used, which also equals your output from the real machine, otherwise it
leaves the flag untouched. Then, if you set the hour to between 01 and
12 (meaning 13 to 00), you'd have to set the flag explicitly, also
clearing the flag internally as a result if set to 12, thus making it
AM again at midnight. This also matches your output.

This is kind of intuitive if you look at the world the way described by
rusure and my wife, i.e. people having grown up with this view of the
world.

So I wrote this small routine just a few minutes ago to be fed with
hours 00..23 (BCD) to spit out the hour for the TOD to be set with:

d2000 2014
.> 2000 a9 00 lda #$00
.> 2002 d0 04 bne $2008
.> 2004 a9 92 lda #$92
.> 2006 d0 0a bne $2012
.> 2008 f8 sed
.> 2009 c9 13 cmp #$13
.> 200b 90 05 bcc $2012
.> 200d 38 sec
.> 200e e9 12 sbc #$12
.> 2010 09 80 ora #$80
.> 2012 d8 cld
.> 2013 60 rts

load A (in $2001) with anything between 00 and 23 and let it run. After
completion, A should be:

01..11 => 01..11
12 => 12, which then internally should flip to 92
13..23 => 81..91
00 => 92, which then internally should flip to 12

Feed the result to the TOD's hour register and *theoretically*, the
AM/PM flag should be correct at all times. You could combine this with
your BASIC program to check for all 24 hours of the day. Just poke the
hour in BCD to 8193 and then sys 8192. Then read the result, which is
BCD again of course.
--
cul8er

Paul
paul.f...@gmx.net

rusure

unread,
Jan 18, 2014, 3:23:03 AM1/18/14
to
On Friday, January 17, 2014 1:25:34 PM UTC-7, Paul Förster wrote:
> Hi rusure,

> I still don't get the idea behind this special
> handling of clearing or setting the bit IF the
> hour is set to $12 or $92. As your demos and
> Frank Busse's program demonstrates, the clock
> ranges from between $12:$00 and $11:$59 for AM
> and between $92:$00 and $91:$59 for PM and
> rolls over accordingly. So far so good.

I think this behavor is a result of some sloppy TOD coding. The TOD program most likely flips the high order bit, the first instant after
the hour byte contents is changed to either $12 or $92. Whether the clock rolled over while changing the hour byte to $12/$92 or if hour was set to $12/$92 is probably not a concern of the TOD programming.

I have discovered another TOD oddity. The program was modified to load the hour, minute, and second TOD registers every half minute. The 10ths register was loaded every minute. The TOD clock advances once a minute every minute after the 10ths register is read. The TOD clock does not advance on the half minute when the 10ths isn't loaded, Somewhere in the TOD Bermuda triangle, the clock continues ticking even if the ticking for the registers is suspended.

Let's postpone a discussion of the advisability of toggling between standard and saving time in the autumn and fall. In addition I'll postpone why for some Christmas falls on January 7th rather than on December 25th.

Paul Förster

unread,
Jan 18, 2014, 5:26:34 AM1/18/14
to
Hi rusure,

On 2014-01-18 08:23:03 +0000, rusure said:
> I think this behavor is a result of some sloppy TOD coding. The TOD
> program most likely flips the high order bit, the first instant
> afterthe hour byte contents is changed to either $12 or $92. Whether
> the clock rolled over while changing the hour byte to $12/$92 or if
> hour was set to $12/$92 is probably not a concern of the TOD
> programming.

it doesn't appear to me as an oddity anymore if I look at it through
your eyes. This also explains what you said initially about the bit
flipping behavior which I didn't understand at first. 1-12 is AM and
the other 1-12 is PM. It's just that simple. You set the clock
accordingly and it does an internal correction on both twelves to make
it "mathematically" correct where the last hour of the 1-12 cycle
belongs to the next cycle already as far as the flag is concerned.

> I have discovered another TOD oddity. The program was modified to load
> the hour, minute, and second TOD registers every half minute. The
> 10ths register was loaded every minute. The TOD clock advances once a
> minute every minute after the 10ths register is read. The TOD clock
> does not advance on the half minute when the 10ths isn't loaded,
> Somewhere in the TOD Bermuda triangle, the clock continues ticking even
> if the ticking for the registers is suspended.

this is documented behavior. IIRC, I found that in "Mapping the
Commodore 64". Bottom line it says there, once you access the hour
register, the min, sec and 10th registers are not updated from the
internal (still ticking!) CIA registers anymore until you access the
10th register. So, reading the hour should make it stop updating min,
sec and 10th but the internal CIA clock should continue to tick away.
Reading the 10th then at an arbitrary time later should make the
registers being updated with the new time from the internal registers
again. That's also why you always have to read or write the 10th
register if you touch the hour register.
--
cul8er

Paul
paul.f...@gmx.net

dott.Piergiorgio

unread,
Jan 18, 2014, 8:50:06 AM1/18/14
to
Il 17/01/2014 21:25, Paul Förster ha scritto:

> Sorry, I don't live in 12-hour-clock country, so I have a hard time
> understanding that specific oddity. I live in 24-hour-clock country
> (Switzerland) and for me, the 12-hour-clock day ranges from 12 AM
> (midnight!) to 11:59 AM (1 min. before noon!) and 12 PM (noon!) to 11:59
> PM (1 min. before midnight!).

perhaps there's another oddity. a Swiss coder, perhaps ? :D

Anyway, because the TOD clock in PAL 64s wasn't correctly timed for
50hz, was imprecise even by _Italian_ standards ;)

Best regards from Italy,
dott. Piergiorgio.

Paul Förster

unread,
Jan 18, 2014, 10:28:37 AM1/18/14
to
Hi dott. Piergiogio,

On 2014-01-18 13:50:06 +0000, dott.Piergiorgio said:
> Anyway, because the TOD clock in PAL 64s wasn't correctly timed for
> 50hz, was imprecise even by _Italian_ standards ;)

no prob here. Just set bit 7 in $dc0e/$dd0e to get PAL frequency. To
keep things simple, determine from $02a6 whether you're on a PAL (=1)
or NTSC (=0) machine. Then it should run pretty accurate.
--
cul8er

Paul
paul.f...@gmx.net

Paul Förster

unread,
Jan 18, 2014, 10:45:30 AM1/18/14
to
Hi Frank, hi rusure,

I finally set up my real C64 again so I could do some testing myself. I
heavily modified your program for testing with Vice initially, then the
real machine and a Turbo Chameleon 64. Yet, thanks very much for your
initial version. The program outputs a table with four columns:

1. column ("24hr"): hour to be tested (decimal)
2. column ("Wr"):   hour written to TOD register (BCD)
3. column ("Rd"):   hour read from TOD register (BCD) immediately after
writing the value in column 2 to see the conversion between AM/PM, if
any.
4. column ("Nx"):   next hour (BCD) after the hour switch

Note: You may select the CIA (1 or 2) to be checked in line 10. You may
also play with the hour range (0..23) to be printed in line 140 or "rem
out" or delete the line completely to see the full 24 hour range.
Values in the table having bit 7 set (i.e. starting with digits 8 or 9)
have the PM bit set, all other values are AM!

Output on a real C64:
CIA# 1
24hr: Wr => Rd => Nx
--------------------
  0 : 92 => 12 => 01   <= Switch from 00 to 01 (24-hour notation)
  1 : 01 => 01 => 02
  2 : 02 => 02 => 03
 11 : 11 => 11 => 92
 12 : 12 => 92 => 81   <= Switch from 12 to 13 (24-hour notation)
 13 : 81 => 81 => 82
 14 : 82 => 82 => 83
 23 : 91 => 91 => 12

ready.

I added a small routine which calculates the correct 12 hour BCD number
including AM/PM flag from a 00-23 hour BCD number:

2000 a9 00     lda #$00  ; input hour (range 00..23)
2002 d0 04     bne $2008
2004 a9 92     lda #$92
2006 d0 0a     bne $2012
2008 f8        sed
2009 c9 13     cmp #$13
200b 90 05     bcc $2012
200d 38        sec
200e e9 12     sbc #$12
2010 09 80     ora #$80
2012 d8        cld       ; A=hour (range 01..12 with AM/PM bit)

Here's an example of the BASIC program run in Vice 2.4 on a Mac running
Mavericks:

CIA# 1
24hr: Wr => Rd => Nx
--------------------
  0 : 92 => 12 => 81   <= wrong next hour
  1 : 01 => 01 => 02
  2 : 02 => 02 => 03
 11 : 11 => 11 => 12
 12 : 12 => 92 => 01   <= wrong next hour
 13 : 81 => 81 => 82
 14 : 82 => 82 => 83
 23 : 91 => 91 => 92

ready.

Ok, now for the Chameleon part:
The program won't run there at all! Why? It gets stuck in line 350.
Since the hour does not advance at all in the current core (8i),
peeking the new hour reveals the same value as the previous hour which
is already stored in variable x. So, no chance to advance. The
consequence is that the program will show the title, and the values for
the first three columns but never make it to the last column. So you
may either press R/S here or delete line 350 completely to see the
table (without values column 4!) on a Chameleon.

That should conclude my initial testing. Integration into my RTC
read/write code can now begin. :-)

Thanks very much to you guys. :-)
--
cul8er

Paul
paul.f...@gmx.net

Source of the TOD test program:

10 cs=1
20 c(1)=56320
30 c(2)=56576
40 for i=0 to 21
50 read p
60 poke 8192+i,p
70 next
80 def fn b(x)=int(x/10)*16+x-int(x/10)*10
90 print chr$(14);
100 print "CIA#";cs
110 print "24hr: Wr => Rd => Nx"
120 print "--------------------"
130 for i=0 to 23
140 if i>2 and i<11 or i>14 and i<23 then next
150 poke 8193,fn b(i)
160 sys 8192
170 h=peek(2)
180 gosub 210
190 next
200 end
210 if i<10 then print " ";
220 print i;": ";
230 x=h
240 gosub 400
250 print " => ";
260 poke c(cs)+11,h
270 poke c(cs)+10,fn b(59)
280 poke c(cs)+9,fn b(59)
290 poke c(cs)+8,fn b(08)
300 x=peek(c(cs)+8)
310 x=peek(c(cs)+11)
320 gosub 400
330 print " => ";
340 y=peek(c(cs)+8)
350 if x=peek(c(cs)+11) then 340
360 x=peek(c(cs)+11)
370 gosub 400
380 print
390 return
400 y=int(x/16)
410 gosub 430
420 y=x-y*16
430 print chr$(y+48);
440 return
450 data 169, 35, 208, 4, 169, 146
460 data 208, 10, 248, 201, 19, 144
470 data 5, 56, 233, 18, 9, 128, 216
480 data 133, 2, 96

dott.Piergiorgio

unread,
Jan 18, 2014, 1:14:18 PM1/18/14
to
well, if a Swiss says is a pretty accurate timing.... :D ;)

(for non-european ppl: the standard stereotypical joke on swiss ppl is
that they're fixated on precise timing, timetables &c.)

Paul Förster

unread,
Jan 18, 2014, 1:43:36 PM1/18/14
to
On 2014-01-18 18:14:18 +0000, dott.Piergiorgio said:
> well, if a Swiss says is a pretty accurate timing.... :D ;)

but I'm not born that way. I have Swiss citizenship for about 14
months. I was born German and have been for about 45 years. So there's
no obsession by heritage in my blood line. :-P

So, just do it and grab your favorite stop-watch. :-P
--
cul8er

Paul
paul.f...@gmx.net

dott.Piergiorgio

unread,
Jan 18, 2014, 4:26:22 PM1/18/14
to
naahh.. I grab my favorite mandolino :P :D

Greg King

unread,
Jan 18, 2014, 10:08:57 PM1/18/14
to
On Saturday, January 18, 2014 10:45:30 AM UTC-5, Paul Förster wrote:
>
> Source of the TOD test program:
>
> 10 cs=1
> 20 c(1)=56320
> 30 c(2)=56576
> 40 for i=0 to 21
> 50 read p
> 60 poke 8192+i,p
> 70 next
> 80 def fn b(x)=int(x/10)*16+x-int(x/10)*10

Here are two efficient BASIC functions that convert between binary and BCD:

10 rem binary to binary-coded decimal
20 def fnd(b)=int(b/10)*6+b
30 rem decimal to binary
40 def fnb(d)=d-int(d/16)*6

Paul Förster

unread,
Jan 19, 2014, 7:31:05 AM1/19/14
to
> naahh.. I grab my favorite mandolino :P :D

Cheers! :)

Paul Förster

unread,
Jan 19, 2014, 7:42:51 AM1/19/14
to
Hi Greg,

On 2014-01-19 03:08:57 +0000, Greg King said:
> Here are two efficient BASIC functions that convert between binary and BCD:
> 10 rem binary to binary-coded decimal
> 20 def fnd(b)=int(b/10)*6+b
> 30 rem decimal to binary
> 40 def fnb(d)=d-int(d/16)*6

cool! Thanks. :)
--
cul8er

Paul
paul.f...@gmx.net

rusure

unread,
Jan 21, 2014, 11:10:15 PM1/21/14
to
Just for the record, I have never allowed a TOD to run for more than 10 minutes. I only use TODs to delay program progress. This typically needs a clock to run for minutes at the most. Most frequently, all I need for a clock to run is for periods of seconds or less. TOD hour bytes and AM/PM flags just are not considered by my programs. The JIFFY clock ticks off time in JIFFIES. I have never had a watch that conforms to JIFFY clock standards. I don't have intuition for time periods measured in JIFFIES, I just don't use the JIFFY clock.

Paul Förster

unread,
Jan 22, 2014, 1:52:40 PM1/22/14
to
Hi rusure,
the TOD is both, a 12 AM/PM clock *and* a timer and has alarm. So the
TOD can run normal day time while one can still use the timer and/or
alarm. You can control which one you use by setting or clearing bit 7
in the TOD control register. So there's no reason to not use the TOD
clock as a normal clock which is way more accurate than TI$, or TI
respectively, the latter being the Jiffy junk. :-)

And yes, just like you, I don't know of any clock in the world that
ticks in Jiffies. I wonder why Commodore ever did that.
--
cul8er

Paul
paul.f...@gmx.net

rusure

unread,
Jan 26, 2014, 2:50:42 PM1/26/14
to
On Wednesday, January 22, 2014 11:52:40 AM UTC-7, Paul Förster wrote:
yes, just like you, I don't know of any clock in the world that ticks in Jiffies. I wonder why Commodore ever did that.
> --
> cul8er
> Paul
>
As you discovered in another thread, converting between hours, minutes, seconds, & JIFFYs and a 3 byte JIFFY clock is nontrivial in machine language. I may have a TRANSACTOR article, at the bottom of my Commodore Bermuda triangle, for the multiplication and division in ML needed for the chores. It's the kind of thing that could be in C(OMMODORE?)= HACKING on the FRIDGE. I don't recall seeing a resolution of your attempts to locate the routines used by BASIC for the conversions.

For the TOD, you need to deal with a flaky AM/PM flag and converting between digital and BCD. All in all, the TOD is far easier to deal with than the JIFFY clock. I think its kind of strange that the TOD minute and second bytes range from $00 to $59, & the tenths byte ranges from $00 to $09, while, aside the AM/PM flag, the TOD hour byte doesn't range from $00 to $11 but rather from $01 to $12.

Paul Förster

unread,
Jan 27, 2014, 1:31:38 PM1/27/14
to
Hi rusure,

On 2014-01-26 19:50:42 +0000, rusure said:
> aside the AM/PM flag, the TOD hour byte doesn't range from $00 to $11
> but rather from $01 to $12.

no, that's understandable aner perfectly logical. It reflects the use
of time in everyday language of English speaking countries. Have a look
at Wikipedia and search for 12-hour-clock.
--
cul8er

Paul
paul.f...@gmx.net

addre...@invalid.invalid

unread,
Feb 1, 2014, 4:00:01 AM2/1/14
to
Unless it is a PAL SX-64 for example. Or a PAL 64 run in the US, or
something used $2A6 for its own purpose, etc. Unfortunately many programs
do just what you wrote and then fail badly under some less common
conditions. This buggy thinking is even present in VICE (sic!) No, TOD
frequency is *NOT* one-to-one bound to PAL/NTSC variants of the system.
Reliable determining the right setup for the TODs is much more complex than
checking $02a6 flag! I had to deal with it some time ago, fixing badly
written soft piece (by myself ;-)
--
SD!

Paul Förster

unread,
Feb 1, 2014, 1:09:25 PM2/1/14
to
Hi SD!,

btw., what does SD stand for?

On 2014-02-01 09:00:01 +0000, <addre...@invalid.invalid> said:
> Reliable determining the right setup for the TODs is much more complex than
> checking $02a6 flag! I had to deal with it some time ago, fixing badly
> written soft piece (by myself ;-)

some anonymous guy provided me with this code. It runs fine on a Turbo
Chameleon 64 in turbo and normal mode:

tv_system := $02a6
sei
turbo_reliable_norm_detection:
: lda $d011
bmi :- ;wait for a line number <256 (RST8 = 0)
: lda $d011
bpl :- ;wait for line 256 (RST8 = 1)
lda #8
: cmp $d012 ;wait for either line 264 or line 8
bne :-
lda $d011 ;and check RST8 to find out which one it was.
bpl ntsc_detected
pal_detected:
lda #1
bne no_ntsc_patch
ntsc_detected:
lda #0
no_ntsc_patch:
sta tv_system
--
cul8er

Paul
paul.f...@gmx.net

SD!

unread,
Feb 1, 2014, 8:23:51 PM2/1/14
to
Paul Förster <paul.f...@gmx.net> wrote:
> Hi SD!,
>
> btw., what does SD stand for?

Shortest variant of my old handle.

> On 2014-02-01 09:00:01 +0000, <addre...@invalid.invalid> said:
>> Reliable determining the right setup for the TODs is much more complex than
>> checking $02a6 flag! I had to deal with it some time ago, fixing badly
>> written soft piece (by myself ;-)
>
> some anonymous guy provided me with this code. It runs fine on a Turbo
> Chameleon 64 in turbo and normal mode:
>
> tv_system := $02a6
> sei
> turbo_reliable_norm_detection:

Good, but as I tried to express - determining video system (even in a more
reliable manner than checking $02a6) doesn't help initialising TODs
properly and we talk about those here. I once wrote a piece that does when
I had to fix my own TOD depending program to work reliably on every (real)
64 compatible machine.

--
SD!

Paul Förster

unread,
Feb 2, 2014, 3:16:30 AM2/2/14
to
Hi SD,

On 2014-02-02 01:23:51 +0000, SD! said:
> Good, but as I tried to express - determining video system (even in a more
> reliable manner than checking $02a6) doesn't help initialising TODs
> properly and we talk about those here. I once wrote a piece that does when
> I had to fix my own TOD depending program to work reliably on every (real)
> 64 compatible machine.

would you publish or send me that code? I'd be too curious to see how
it works. If you prefer to keep it secret, then you can still send it
to me and I promise to not give it away.
--
cul8er

Paul
paul.f...@gmx.net

Frank Buss

unread,
Feb 2, 2014, 5:08:06 AM2/2/14
to
But shouldn't be too difficult. First measure the number of phi2 cycles
for one tenth TOD second. As Paul wrote, it is easy to check if it is a
PAL or NTSC machine, so you know the phi2 clock frequency. With this you
can calculate the real time for one tenth TOD second and then check if
the 50 Hz or 60 Hz setting is right (you have to do this, because it is
possible that a NTSC machine is used with a a 50 Hz power supply and
vice versa).

SD!

unread,
Feb 2, 2014, 4:56:14 AM2/2/14
to
There isn't much secret stuff about the eight bit machines these days ;-) I
shall find the code once back at the repo enabled place (I come back
tomorrow evening) but the idea is quite simple once you understand that PAL
vs NTSC is *NOT* bound to TOD clock frequency[*]. Then you only need to
determine somehow what it actually is. How? I went the route of setting the
frequency flag to either of the two values and comparing the resulting TOD
accuracy against another timing resource over a predefined period of time.
If it runs accurately the flag is set correctly. If it runs faster (or
slower - depending on the initial flag setting), you missed the ball and
have to toggle the flag. The drawback is that because the TOD's granularity
is relatively low at only tenths of a second and the difference between
possible frequencies isn't huge in this context either, it means that you
have to "waste" sizeable amount of time upon initialisation. AFAIR I got
reliable results at about one second. The good news is that you have to do
it only once ;-)
--
SD!

[*] - as I wrote earlier, this is such a widely spread misconception that
the majority of TOD using programs has been written with this in mind.
Splinters of this bug is even present in VICE! The truth is that in a plain
C-64 TOD clock is derived from mains frequency, which happens to be 50Hz
when the machine is run in a "PAL country" and 60Hz when the machine is run
in an "NTSC country". Now, /usually/ a machine run in a "PAL country" will
be of PAL video norm (VIC, clocks, etc.). Vice-versa: /usually/ a machine
run in an "NTSC country" will be of NTSC video norm. Usually... But nothing
prevents running PAL machine in the US (60Hz on a PAL computer) or NTSC
machine in the EU (50Hz on an NTSC computer), does anything? Also nothing
should prevent your program from running correctly on an SX-64, should
anything? But the funny part is that the SX does NOT derive TOD clock from
the power lines... uh-oh... and if we depend on the PAL/NTSC buggy approach
then we are fried because no matter what the country you run the machine in
and no matter what its video norm is - TOD frequency is /always/ the same
(60Hz) there.

SD!

unread,
Feb 2, 2014, 10:48:51 AM2/2/14
to
On 2014-02-02 10:08:06 +0000, Frank Buss said:


>>> some anonymous guy provided me with this code. It runs fine on a Turbo
>>> Chameleon 64 in turbo and normal mode:
>>>
>>> tv_system := $02a6
>>> sei
>>> turbo_reliable_norm_detection:
>>
>> Good, but as I tried to express - determining video system (even in a more
>> reliable manner than checking $02a6) doesn't help initialising TODs
>> properly and we talk about those here. I once wrote a piece that does when
>> I had to fix my own TOD depending program to work reliably on every (real)
>> 64 compatible machine.
>
> But shouldn't be too difficult.

Sure it isn't ;-)

> First measure the number of phi2 cycles
> for one tenth TOD second. As Paul wrote, it is easy to check if it is a
> PAL or NTSC machine, so you know the phi2 clock frequency.

Why phi2? Unless you meant the TIMA/TIMB timers, that is..

> With this you can calculate the real time for one tenth TOD second
> and then check if the 50 Hz or 60 Hz setting is right

If you want to do this with CPU cycle counting you have to take into
account that those are not fully reliable with VIC stealing them under
some circumstances. Meaning you still have to account for VIC's RASTER
stuff or you have to disable the VIC's output. The first seemed too
much of a burden to me (given all possible situations) the second is
not what I ever wanted as I wanted the checking routine to be part of a
library and be as little "invasive" as possible. Flicking the screen
didn't fit into my set of objectives. You may also try counting cycles
with TIMA/TIMB timers of the CIA but you'd probably have to chain them
and possibly try to save their setup if you want to be "non-invasive".
All that adds on bytes in the routine. Hence I went the route of
counting full rasters and it works well but uses IMHO too much time
(about a second) to get reliable result. Then there is the idea of
doing it the other way around, which I was too lazy to implement and
test yet ;-) I mean instead of counting full rasters and checking how
long it takes to complete a predefined set of them - count TODTENs and
see how many rasterlines you use for one. This should be much faster as
I imagine being able to get reliable output in up to two TODTENs, which
would be one fifth of the time needed now - quite acceptable.

> (you have to do this, because it is
> possible that a NTSC machine is used with a a 50 Hz power supply and
> vice versa).

Actually it is about the mains frequency rather than PSU ;-) but I am
sure you know it.

Also - as I wrote in the previous post - because you want the program
to run correctly on every SX too, don't you? ;-)

--
SD!

SD!

unread,
Feb 2, 2014, 10:52:34 AM2/2/14
to
Actually I found an older version checked out on my laptop... it is the
one that counts full rasters. I still haven't implemented the "other
way around" variant.


;******************************************************
.export tod_init

.import pal_ntsc_check
.include "c64.i"

; Reliable initialisation of TOD clock by Silver Dream ! / W.F.M.H.
; takes account of possible differences in TOD ticks frequencies
; supplied to the CIA chips
; INPUTS: none
; RETURNS: detected frequency in A
; REGISTERS AFFECTED: A, X, Y

;//
tod_init:
php ; store the status register so that we don't change too many things
sei ; it may be better to take care of NMIs too (we don't do it for now)

jsr pal_ntsc_check
cmp #$01
beq pal_wait_50_rasters
ntsc_wait_60_rasters:
ldx #60
bne reset_tod
pal_wait_50_rasters:
ldx #50

reset_tod:
; set TOD tick frequency to 50Hz
lda CIACRA
ora #$80
sta CIACRA

; we want to set the clock rather than alarm time
lda CIACRB
and #$7f ; we clear bit 7 of CIACRB
sta CIACRB ; so that writing to TOD sets clock rather than alarm time

; reset all registers to zero
lda #$00
sta TODHRS ; here it latches to stop counting
sta TODMIN
sta TODSEC
sta TODTEN ; latch released here

count_rasters:
bit SCROLY
bpl count_rasters
: bit SCROLY
bmi :-
dex
bne count_rasters

lda TODTEN
bne ticks_60hz

ticks_50hz:
lda CI2CRA
ora #$80
sta CI2CRA
lda #50
bne finish

ticks_60hz:
lda CIACRA
and #$7f
sta CIACRA
lda CI2CRA
and #$7f
sta CI2CRA
lda #60

finish:
plp
rts
;/
;*******************************************************

--
SD!

Paul Förster

unread,
Feb 3, 2014, 4:16:30 PM2/3/14
to
Hi SD!,

On 2014-02-02 15:52:34 +0000, SD! said:
> Actually I found an older version checked out on my laptop... it is the
> one that counts full rasters. I still haven't implemented the "other
> way around" variant.

what do you mean by "older" version? Is there a "new" version? ;-)

> sei ; it may be better to take care of NMIs too (we don't do it for now)
[..]

thanks very much for the code. Wow! It took me 2 minutes to understand,
what your code does (at least I hope so), but it took me a whole day to
understand the concept, thanks also to your explanation in your other
post. I'm getting old. :(

Well, at least I *think* I understood it. Let me summarize to see if I
really understood it correctly:

- determine the model type NTSC/PAL by checking raster lines
- set CIA1 to the thus determined frequency and reset it to 00:00:00.0
- count raster lines
- check if 1/10 of a second has passed after counting a fixed cycle number
- if yes, the TOD has been initialized to the wrong value,
if no, the TOD has been set correctly

What I don't understand is that this still sets the CIA frequency in
relation to the number of raster lines counted, which is an absolute
value inside the computer but bears no relation to the mains frequency.
So, why doesn't (or shouldn't) it set the CIA frequency to always 50 Hz
on a PAL machine and 60 Hz on an NTSC machine. I just don't get it... :(

Also, shouldn't I set the NMI vector to a dummy "rti" during the
checks? Ok, admittedly, it's hard to hit the RESTORE key in exactly
those few microseconds. :)

Did I really get it? I'm not so sure after all...
--
cul8er

Paul
paul.f...@gmx.net

SD!

unread,
Feb 3, 2014, 5:54:43 PM2/3/14
to
On 2014-02-03 21:16:30 +0000, Paul Förster said:

>> Actually I found an older version checked out on my laptop... it is the
>> one that counts full rasters. I still haven't implemented the "other
>> way around" variant.
>
> what do you mean by "older" version? Is there a "new" version? ;-)

Yes, even two ;-)

>> sei ; it may be better to take care of NMIs too (we don't do it for now)
> [..]
>
> thanks very much for the code. Wow! It took me 2 minutes to understand,
> what your code does (at least I hope so), but it took me a whole day to
> understand the concept, thanks also to your explanation in your other
> post. I'm getting old. :(

Or my explanations were not up to snuff...

> Well, at least I *think* I understood it. Let me summarize to see if I
> really understood it correctly:
>
> - determine the model type NTSC/PAL by checking raster lines

Right - this becomes our independent timing resource but we have to
know what is its period, meaning whether we are run on a PAL or NTSC
machine.

> - set CIA1 to the thus determined frequency and reset it to 00:00:00.0

Actually I set it always to 50Hz. Just to save on bytes - I have always
the same setting, no matter what the video norm is and don't have to
account for it later on.

> - count raster lines

Yes, actually count full rasters to be precise.

> - check if 1/10 of a second has passed after counting a fixed cycle number

Not really. We expect that 50 full rasters (on PAL) or 60 full rasters
(on NTSC) take (with adequate accuracy) exactly one second. This means
that during that time TODTEN should wrap to 00 and this is the value
that we should get IF the 50Hz value set previously was actually
correct. So - in other words - what we check is whether TOD shows the
correct value of one second after one "wall clock" second. The "wall
clock" second we time with either 50 or 60 full rasters, depending on
the video norm.

> - if yes, the TOD has been initialized to the wrong value,

If we got one second (+/- 0.05s) from TOD (TODTEN at $00) then we were
initially right and the tick frequency is indeed 50Hz.

> if no, the TOD has been set correctly

IF we got something else than one second (TODTEN != $00) after one
second (and some nanoseconds) "wall clock" - it means that TOD is not
accurate, which has to be caused by the fact that the supplied
frequency is NOT 50Hz as we initially assumed. If it is not 50, then it
has to be 60Hz then.

> What I don't understand is that this still sets the CIA frequency in
> relation to the number of raster lines counted,

No, it doesn't. Initially it sets it to 50Hz, regardless of the video
norm. Later on it doesn't relate the set frequency to the video norm
either.

> which is an absolute value inside the computer but bears no relation
> to the mains frequency.

As I tried to explain before - to verify the accuracy of the TOD we
need another, trusted timing resource. One we know the accuracy and can
trust it. There aren't many of them available in the 64. We can count
CPU cycles, either with code or with TIMA/TIMB timers or (what I did
here) we can time one second with full rasters. We know that 50 full
rasters on PAL will take one second and the same second will pass
during 60 full rasters on an NTSC system. The PAL vs. NTSC is checked
/only/ to give us proper number of full rasters to count in order to
time one second.

> So, why doesn't (or shouldn't) it set the CIA frequency to always 50 Hz
> on a PAL machine and 60 Hz on an NTSC machine. I just don't get it... :(

Because PAL C-64/128 machine can be run in the US and while still being
PAL, will have 60Hz TOD ticks frequency supplied. If you set your TOD
to 50Hz - you are out of luck.

Because every SX-64, even PAL one will always have 60Hz supplied to the
TOD. No matter where you run it.

That's what I wrote before. Combine it with the fact that the given
routine does *NOT* set the frequency in relation to the video norm and
you should be on the right page.

> Also, shouldn't I set the NMI vector to a dummy "rti" during the
> checks? Ok, admittedly, it's hard to hit the RESTORE key in exactly
> those few microseconds. :)

RESTORE is not the only source of NMIs. Yes, you should. To be on the
safe side. Especially that the number of microseconds you have a chance
to get NMI is slightly above 1000 ;-) But in any case you don't want to
enter /any/ race condition. AFAIR that's one of the enhancements I did
in the "newer" version.

> Did I really get it? I'm not so sure after all...

You did well :-) Hope I cleared the remaining parts. Did I? Please let me know.


P. S. Maybe this thread will eventually motivate me to finish the other
version of the routine... ;-)

--
SD!

Paul Förster

unread,
Feb 5, 2014, 3:07:09 PM2/5/14
to
Hi Frank,

On 2014-02-02 10:08:06 +0000, Frank Buss said:
> But shouldn't be too difficult. First measure the number of phi2 cycles
> for one tenth TOD second. As Paul wrote, it is easy to check if it is a
> PAL or NTSC machine, so you know the phi2 clock frequency. With this you
> can calculate the real time for one tenth TOD second and then check if
> the 50 Hz or 60 Hz setting is right (you have to do this, because it is
> possible that a NTSC machine is used with a a 50 Hz power supply and
> vice versa).

finally a concept, my old brain can immediately grasp. :)
--
cul8er

Paul
paul.f...@gmx.net

Paul Förster

unread,
Feb 23, 2014, 4:00:02 PM2/23/14
to
Hi SD!,

ok, some delay in the thread on my part. :(

On 2014-02-03 22:54:43 +0000, SD! said:
>> what do you mean by "older" version? Is there a "new" version? ;-)
> Yes, even two ;-)

is there a way to make you post an update here? ;-)

> Or my explanations were not up to snuff...

no, your explanations are pretty good. I'm just getting old -- definitly. :(

> Actually I set it always to 50Hz. Just to save on bytes - I have always
> the same setting, no matter what the video norm is and don't have to
> account for it later on.

ok, I see. You only correct it later in the routine if needed. After
all, it need some initial setting, even if it was the wrong one.

> Yes, actually count full rasters to be precise.

what do you mean by full rasters? Is there a way to see if a raster
line is drawn only to a specific position so I could, in theory,
manipulate one single arbitrary position on screen in a different
graphics mode for example even if the graphics mode before and after
that position is different? Just curious...

>> - check if 1/10 of a second has passed after counting a fixed cycle number
> Not really. We expect that 50 full rasters (on PAL) or 60 full rasters
> (on NTSC) take (with adequate accuracy) exactly one second. This means
> that during that time TODTEN should wrap to 00 and this is the value
> that we should get IF the 50Hz value set previously was actually
> correct. So - in other words - what we check is whether TOD shows the
> correct value of one second after one "wall clock" second. The "wall
> clock" second we time with either 50 or 60 full rasters, depending on
> the video norm.

ah, so you actually check the complete opposite of what I said. You
don't check whether a defined number of rasters have passed in a
certain time frame, but rather whether a defined time frame has passed
has passed after a certain number of rasters.

>> What I don't understand is that this still sets the CIA frequency in
>> relation to the number of raster lines counted,
> No, it doesn't. Initially it sets it to 50Hz, regardless of the video
> norm. Later on it doesn't relate the set frequency to the video norm
> either.

this is the point I just don't get. You count rasters which are video
norm dependent but yet you don't relate to the video norm.

> As I tried to explain before - to verify the accuracy of the TOD we
> need another, trusted timing resource. One we know the accuracy and can
> trust it. There aren't many of them available in the 64. We can count
> CPU cycles, either with code or with TIMA/TIMB timers or (what I did
> here) we can time one second with full rasters. We know that 50 full
> rasters on PAL will take one second and the same second will pass
> during 60 full rasters on an NTSC system. The PAL vs. NTSC is checked
> /only/ to give us proper number of full rasters to count in order to
> time one second.

I'd love to see CPU cycle counting code which would take the VIC
stealing cycles into account without disabling the screen. :)

> Because PAL C-64/128 machine can be run in the US and while still being
> PAL, will have 60Hz TOD ticks frequency supplied. If you set your TOD
> to 50Hz - you are out of luck.

ok, got that bit. :)

> Because every SX-64, even PAL one will always have 60Hz supplied to the
> TOD. No matter where you run it.

and how did Commodore make sure that the TOD did not run too fast in
PAL country on an SX-64 then?

> RESTORE is not the only source of NMIs. Yes, you should. To be on the
> safe side. Especially that the number of microseconds you have a chance
> to get NMI is slightly above 1000 ;-) But in any case you don't want to
> enter /any/ race condition. AFAIR that's one of the enhancements I did
> in the "newer" version.

please post. :) Setting the NMI vector to point to an rti is trivial.
Did you do anything else?

> You did well :-) Hope I cleared the remaining parts. Did I? Please let me know.

I'm not 100% sure yet. At least I hope I finally got the concept that
you measure the time taken to pass a predefined number of rasters
rather than the other way around as I initially thought would be the
case.

> P. S. Maybe this thread will eventually motivate me to finish the other
> version of the routine... ;-)

yes, I hope so too. :) After all, this is quite interesting. You
probably noticed on the TC64 mailing list that I did the RTC read/write
code there. That's also why I asked for a way to set TI/TI$ in another
thread here. The idea and code you provided are included in that code
to also set the TOD properly on any system, not only the TC64, to keep
the code more flexible.
--
cul8er

Paul
paul.f...@gmx.net

SD!

unread,
Feb 26, 2014, 6:20:09 PM2/26/14
to
On 2014-02-23 21:00:02 +0000, Paul Förster said:

> ok, some delay in the thread on my part. :(

NP.

>>> what do you mean by "older" version? Is there a "new" version? ;-)
>> Yes, even two ;-)
>
> is there a way to make you post an update here? ;-)

Provided that I finish that - sure.

>> Actually I set it always to 50Hz. Just to save on bytes - I have always
>> the same setting, no matter what the video norm is and don't have to
>> account for it later on.
>
> ok, I see. You only correct it later in the routine if needed. After
> all, it need some initial setting, even if it was the wrong one.

Exactly. If it's the right one - leave it. If it was wrong - change it.
It doesn't matter which one you choose for the start. I chose 50
because statistically in my location this one should be more often
correct AND because it supposedly requires less time/code to get
accurate readout.

>> Yes, actually count full rasters to be precise.
>
> what do you mean by full rasters?

Hm - full raster is a full raster ;-) How should I explain this? That's
one full set of all rasterlines that the machine is capable of
generating. All visible and all invisible rasterlines. Or, in other
words, a number of rasterlines, after generating which the machine
returns again to line #%000000000 (note the nine bits - ninth, #8 is
visible in SCROLY. #0-#7 are visible in RASTER register).

> Is there a way to see if a raster line is drawn only to a specific
> position so I could, in theory, manipulate one single arbitrary
> position on screen in a different graphics mode for example even if the
> graphics mode before and after that position is different? Just
> curious...

I am not sure what you mean. If I understand correctly, you just
invented "raster effects" ;-) All raster effects are based on
manipulating what the machine displays at specific position of the
screen (aka raster). But that seems somewhat too obvious so I am not
sure if I understood the question correctly.

>>> What I don't understand is that this still sets the CIA frequency in
>>> relation to the number of raster lines counted,
>>
>> No, it doesn't. Initially it sets it to 50Hz, regardless of the video
>> norm. Later on it doesn't relate the set frequency to the video norm
>> either.
>
> this is the point I just don't get. You count rasters which are video
> norm dependent but yet you don't relate to the video norm.

Contrary to the popular belief, computer's video norm is completely
unrelated to TODTICKS frequency. That's the whole point of the code I
posted, and this discussion from the very beginning (of my
involvement)! Those are two unrelated variables. And I don't relate
them in any way either. I use the video norm NOT to set the CIA's TOD
parameter but to get a reliable external timer resource. I need to
measure a predefined amount of time and I need a trusted resource. VIC
can give me the CIA independent timing information and it does.
Initially I don't know whether it generates 50 or 60 full rasters per
second though. This is very similar to the fact that I don't know
whether CIA's TOD is being fed with 50 or 60 Hz TODTICKS frequency. But
unlike with CIA, with VIC I can verify if it (VIC) runs 50 or 60 Hz
(even if it is different than what CIA runs on). That's where the video
norm verification comes in handy: no matter what else, PAL VIC will
generate 50 rasters per second and NTSC VIC will do 60 so I can always
get the accurate one second I need to check TOD's accuracy.

> I'd love to see CPU cycle counting code which would take the VIC
> stealing cycles into account without disabling the screen. :)

You can possibly do this for a specific application but for a generic
one - no... I wouldn't even try ;-)


> and how did Commodore make sure that the TOD did not run too fast in
> PAL country on an SX-64 then?

Actually (I haven't checked the SX's KERNAL for that but) I believe
that SX TODs runs always accurate after power-up. The most problems are
with regular 64s being run in PAL countries. Regular 64s derive
TODTICKS frequency from the mains frequency (which happens to be 50Hz
in PAL countries) and CIAs are initially set to 60Hz. So - to answer
your question - they ensured the accuracy of SX-64 TODs by both
initialising CIAs to 60Hz AND supplying always 60Hz, regardless of the
mains frequency. They didn't do the same in regular C64/128s though.

>> RESTORE is not the only source of NMIs. Yes, you should. To be on the
>> safe side. Especially that the number of microseconds you have a chance
>> to get NMI is slightly above 1000 ;-) But in any case you don't want to
>> enter /any/ race condition. AFAIR that's one of the enhancements I did
>> in the "newer" version.
>
> please post. :) Setting the NMI vector to point to an rti is trivial.
> Did you do anything else?

AFAIR no. And I can't now recall any other method that would handle
/all/ NMIs better. True, it still leaves a chance to skew the results
if the NMIs happen fast enough but at some point one has to learn the
difference between possibility and probability and only account for
what is probable unless there is a feasible method to cover all cases
;-)

>> You did well :-) Hope I cleared the remaining parts. Did I? Please let me know.
>
> I'm not 100% sure yet. At least I hope I finally got the concept that
> you measure the time taken to pass a predefined number of rasters
> rather than the other way around as I initially thought would be the
> case.

Yes, that's the case here. The other method I wrote of is supposed to
do the opposite: get one TODTEN (the lowest TOD granularity) and see
where your rasterbeam is after that.

>> P. S. Maybe this thread will eventually motivate me to finish the other
>> version of the routine... ;-)
>
> yes, I hope so too. :) After all, this is quite interesting. You
> probably noticed on the TC64 mailing list

TC64 mailing list? I don't think I attend it. Need to check what and
where it is.

> that I did the RTC read/write code there. That's also why I asked for a
> way to set TI/TI$ in another thread here. The idea and code you
> provided are included in that code to also set the TOD properly on any
> system, not only the TC64, to keep the code more flexible.

As I wrote some time ago - I myself got badly bitten by this buggy
approach of checking video norm in order to initialise TOD. And I never
noticed the problem until people started using the program on real
hardware in various parts of the globe rather than on VICE where the
same thought path has been used: the emulated TODTICKS frequency is
chosen according to what the video norm is selected (arrghhh...)! Since
then I check it always properly rather than ass-u-me ;-)

--
SD!

Paul Förster

unread,
Feb 27, 2014, 1:17:48 PM2/27/14
to
Hi SD!,

On 2014-02-26 23:20:09 +0000, SD! said:
> Provided that I finish that - sure.

ok, I know that statement. It means never. ;)

> Hm - full raster is a full raster ;-) How should I explain this? That's
> one full set of all rasterlines that the machine is capable of
> generating. All visible and all invisible rasterlines. Or, in other
> words, a number of rasterlines, after generating which the machine
> returns again to line #%000000000 (note the nine bits - ninth, #8 is
> visible in SCROLY. #0-#7 are visible in RASTER register).

ah, so a "full raster" means one complete screen including ALL lines. I
always thought the word raster refers to a single pixel line. :) Slight
misunderstanding on my part, sorry.

> I am not sure what you mean. If I understand correctly, you just
> invented "raster effects" ;-) All raster effects are based on
> manipulating what the machine displays at specific position of the
> screen (aka raster). But that seems somewhat too obvious so I am not
> sure if I understood the question correctly.

I mean draw pixel line n to pixel column x, switch graphics mode and
display some other stuff for that line and then, when the drawing
reaches pixel column y (y>x of course) then switch back to the graphics
mode before pixel column y, thus "opening" a vertical "window" if you
want. Maybe I just invented raster effects. But hey, I'm not an expert
here. :)

> Contrary to the popular belief, computer's video norm is completely
> unrelated to TODTICKS frequency. That's the whole point of the code I
> posted, and this discussion from the very beginning (of my
> involvement)! Those are two unrelated variables. And I don't relate
> them in any way either. I use the video norm NOT to set the CIA's TOD
> parameter but to get a reliable external timer resource. I need to
> measure a predefined amount of time and I need a trusted resource. VIC
> can give me the CIA independent timing information and it does.
> Initially I don't know whether it generates 50 or 60 full rasters per
> second though. This is very similar to the fact that I don't know
> whether CIA's TOD is being fed with 50 or 60 Hz TODTICKS frequency. But
> unlike with CIA, with VIC I can verify if it (VIC) runs 50 or 60 Hz
> (even if it is different than what CIA runs on). That's where the video
> norm verification comes in handy: no matter what else, PAL VIC will
> generate 50 rasters per second and NTSC VIC will do 60 so I can always
> get the accurate one second I need to check TOD's accuracy.

wonderful explanation. And it took me "only" a few weeks to understand. :(

> You can possibly do this for a specific application but for a generic
> one - no... I wouldn't even try ;-)

I think I saw some code
(http://www.6502.org/source/general/clockfreq.htm) to determine the
clock frequency on any 6502 based system. But then, that one definitly
doesn't take VIC stealing cycles into account, so one has to switch off
the screen and not send the result to some serial terminal. But hey,
wouldn't that be one of the last big adventures for you these days to
write a routine which doesn't require the screen being switched off? :)
If I knew what you know and could do what you can do I would really be
tempted. I for one am still learning this stuff (never did much
assembly stuff in my life), even after about 30 years, so I guess this
is far too big for me.

> AFAIR no. And I can't now recall any other method that would handle
> /all/ NMIs better. True, it still leaves a chance to skew the results
> if the NMIs happen fast enough but at some point one has to learn the
> difference between possibility and probability and only account for
> what is probable unless there is a feasible method to cover all cases
> ;-)

well, one could build a robot to cut the NMI line on flipping a bit in
some C64 status register and soldering it back together afterwards...
Well, sort of. :P

> TC64 mailing list? I don't think I attend it. Need to check what and
> where it is.

sorry, I mistook you for someone else. Don't bother.

> As I wrote some time ago - I myself got badly bitten by this buggy
> approach of checking video norm in order to initialise TOD. And I never
> noticed the problem until people started using the program on real
> hardware in various parts of the globe rather than on VICE where the
> same thought path has been used: the emulated TODTICKS frequency is
> chosen according to what the video norm is selected (arrghhh...)! Since
> then I check it always properly rather than ass-u-me ;-)

well, your ideas (and code) help me set up the TC64 the correct way, so
it's real hardware, though the C64 is emulated in an FPGA core. Without
the TC64 I would never even have thought about writing such code. Why
should I? :)

Anyway, a big thank you for both the ideas/concepts and the code. The
sources of the TC64 RTC read/write code bears the proper credit. :)
--
cul8er

Paul
paul.f...@gmx.net

SD!

unread,
Feb 27, 2014, 5:13:58 PM2/27/14
to
On 2014-02-27 18:17:48 +0000, Paul Förster said:

>> Provided that I finish that - sure.
>
> ok, I know that statement. It means never. ;)

;-) might as well be.

> ah, so a "full raster" means one complete screen including ALL lines. I
> always thought the word raster refers to a single pixel line. :) Slight
> misunderstanding on my part, sorry.

NP. It's "raster", which consists of -> "rasterlines". So you actually
thought "raster line".

> I mean draw pixel line n to pixel column x, switch graphics mode and
> display some other stuff for that line and then, when the drawing
> reaches pixel column y (y>x of course) then switch back to the graphics
> mode before pixel column y, thus "opening" a vertical "window" if you
> want. Maybe I just invented raster effects. But hey, I'm not an expert
> here. :)

You can easily open "horizontal windows" - meaning you can easily
change whatever you want at specific vertical position - that's what
VIC has registers for as well as raster IRQ capabilities. If you want
to open "vertical windows" meaning to change things at specific
horizontal position - that's also possible but much more difficult. One
has to do cycle counting in order to get the specific horizontal
position and even then the granularity is substantially lower. I think
you can address screen position at multiples of eight pixels
horizontally. But don't quote me for that - it's been some time since I
counted cycles for raster effects last time ;-)

>> You can possibly do this for a specific application but for a generic
>> one - no... I wouldn't even try ;-)
>
> I think I saw some code
> (http://www.6502.org/source/general/clockfreq.htm) to determine the
> clock frequency on any 6502 based system. But then, that one definitly
> doesn't take VIC stealing cycles into account, so one has to switch off
> the screen and not send the result to some serial terminal.

But if we talk about 6502 systems with VIC then.. unlike TODTICKS
frequency, CPU clock frequency actually IS related to the video norm in
a 1:1 relation. PHI0 (the one that goes into CPU) is derived from
DOTCLOCK by VIC chip. And depending on what video norm the machine (VIC
version and crystals' frequencies) is - it will be either something
close to 1.02MHz on an NTSC machine and about 0.98MHz on a PAL machine.

> But hey, wouldn't that be one of the last big adventures for you these
> days to write a routine which doesn't require the screen being switched
> off? :)

Well, I have already written one that doesn't require turning off the
screen: the one I posted. And I have some other, more rewarding
adventures still in mind ;-)

> If I knew what you know and could do what you can do I would really be
> tempted. I for one am still learning this stuff (never did much
> assembly stuff in my life), even after about 30 years, so I guess this
> is far too big for me.

The problem would be that if you want a generic routine, it has to be
machine state agnostic. So it should run correctly with screen on,
screen off, sprites on, sprites off, sprites standing, moving,
whatever. It is IMHO not worth to even try or the code to handle all
possible cases will grow too far. Much more promising to me seems the
approach with checking where the raster beam is after one TODTEN. It
would require only about one tenth of the time I need to detect the
frequency now. That would be already quite bearable. And wouldn't
require turning off the screen either :-0

>> As I wrote some time ago - I myself got badly bitten by this buggy
>> approach of checking video norm in order to initialise TOD. And I never
>> noticed the problem until people started using the program on real
>> hardware in various parts of the globe rather than on VICE where the
>> same thought path has been used: the emulated TODTICKS frequency is
>> chosen according to what the video norm is selected (arrghhh...)! Since
>> then I check it always properly rather than ass-u-me ;-)
>
> well, your ideas (and code) help me set up the TC64 the correct way, so
> it's real hardware, though the C64 is emulated in an FPGA core. Without
> the TC64 I would never even have thought about writing such code. Why
> should I? :)
>
> Anyway, a big thank you for both the ideas/concepts and the code. The
> sources of the TC64 RTC read/write code bears the proper credit. :)

You are very much welcome. Glad I could help.

--
SD!

Paul Förster

unread,
Feb 28, 2014, 1:23:49 PM2/28/14
to
Hi SD!,

On 2014-02-27 22:13:58 +0000, SD! said:
> You can easily open "horizontal windows" - meaning you can easily
> change whatever you want at specific vertical position - that's what
> VIC has registers for as well as raster IRQ capabilities. If you want
> to open "vertical windows" meaning to change things at specific
> horizontal position - that's also possible but much more difficult. One
> has to do cycle counting in order to get the specific horizontal
> position and even then the granularity is substantially lower. I think
> you can address screen position at multiples of eight pixels
> horizontally. But don't quote me for that - it's been some time since I
> counted cycles for raster effects last time ;-)

oh well, I'm not good at cycle counting. :) I guess I can be pretty
happy if I manage to get a horizontal window open without the usual
pixel jitter at its start and end. :)

> But if we talk about 6502 systems with VIC then.. unlike TODTICKS
> frequency, CPU clock frequency actually IS related to the video norm in
> a 1:1 relation. PHI0 (the one that goes into CPU) is derived from
> DOTCLOCK by VIC chip. And depending on what video norm the machine (VIC
> version and crystals' frequencies) is - it will be either something
> close to 1.02MHz on an NTSC machine and about 0.98MHz on a PAL machine.

yes, I know what you mean. But let's say I switch off the screen, would
that generic counting algorithm then work properly or would it still be
disturbed by some event similar to the VIC stealing cycles? I would
really love to see code that actually measures the processor speed
rather than code that just computes the cycles depending on the VIC.
Just out of curiosity...

> Well, I have already written one that doesn't require turning off the
> screen: the one I posted. And I have some other, more rewarding
> adventures still in mind ;-)

understandable. :)

> The problem would be that if you want a generic routine, it has to be
> machine state agnostic. So it should run correctly with screen on,
> screen off, sprites on, sprites off, sprites standing, moving,
> whatever. It is IMHO not worth to even try or the code to handle all
> possible cases will grow too far. Much more promising to me seems the
> approach with checking where the raster beam is after one TODTEN. It
> would require only about one tenth of the time I need to detect the
> frequency now. That would be already quite bearable. And wouldn't
> require turning off the screen either :-0

maybe a good challenge for Frank Buss? ;-)

> You are very much welcome. Glad I could help.

the pleasure is mine. Glad you helped me. :)
--
cul8er

Paul
paul.f...@gmx.net

SD!

unread,
Mar 1, 2014, 8:12:59 AM3/1/14
to
On 2014-02-28 18:23:49 +0000, Paul Förster said:

>> You can easily open "horizontal windows" - meaning you can easily
>> change whatever you want at specific vertical position - that's what
>> VIC has registers for as well as raster IRQ capabilities. If you want
>> to open "vertical windows" meaning to change things at specific
>> horizontal position - that's also possible but much more difficult. One
>> has to do cycle counting in order to get the specific horizontal
>> position and even then the granularity is substantially lower. I think
>> you can address screen position at multiples of eight pixels
>> horizontally. But don't quote me for that - it's been some time since I
>> counted cycles for raster effects last time ;-)
>
> oh well, I'm not good at cycle counting. :) I guess I can be pretty
> happy if I manage to get a horizontal window open without the usual
> pixel jitter at its start and end. :)

Move the jitter into HBLANK range for a quick'n dirty fix like in the
early eighties. Or use one of the cycle counting/NOP stepping routines
to get a fully stable and predictable IRQ like in the late eghties.
But.. that jitter is not always bad.. I recall one game (Ballblazer I
think..) where I always wondered how it would feel like if the jitter
was gone. And I always concluded that it would be worse then :-)

>> But if we talk about 6502 systems with VIC then.. unlike TODTICKS
>> frequency, CPU clock frequency actually IS related to the video norm in
>> a 1:1 relation. PHI0 (the one that goes into CPU) is derived from
>> DOTCLOCK by VIC chip. And depending on what video norm the machine (VIC
>> version and crystals' frequencies) is - it will be either something
>> close to 1.02MHz on an NTSC machine and about 0.98MHz on a PAL machine.
>
> yes, I know what you mean. But let's say I switch off the screen, would
> that generic counting algorithm then work properly or would it still be
> disturbed by some event similar to the VIC stealing cycles? I would
> really love to see code that actually measures the processor speed
> rather than code that just computes the cycles depending on the VIC.
> Just out of curiosity...

Do you mean you want to verify the CPU clock? But if not VIC then what
would you want to compare it to? You have to have some timer.resource
available, don't you? You posted a link to a piece of code that counts
cycles depending on another known frequency (frequency of NMIs there).
You can use the same code. Just set your own something to trigger NMIs
at a stable rate, replace "send:" with appropriate output handling (JMP
$FFD2 for example) and there you are. :-)

--
SD!

Paul Förster

unread,
Mar 1, 2014, 1:20:47 PM3/1/14
to
Hi SD!,

On 2014-03-01 13:12:59 +0000, SD! said:
> Move the jitter into HBLANK range for a quick'n dirty fix like in the
> early eighties. Or use one of the cycle counting/NOP stepping routines
> to get a fully stable and predictable IRQ like in the late eghties.
> But.. that jitter is not always bad.. I recall one game (Ballblazer I
> think..) where I always wondered how it would feel like if the jitter
> was gone. And I always concluded that it would be worse then :-)

I couldn't see it in Ballblazer (at least on the C64 longplay on
YouTube) but found it in LCP
(http://www.youtube.com/watch?v=SkTgX1mGmDg) when the user is typing
something on the top left where the typing area ends.

> Do you mean you want to verify the CPU clock? But if not VIC then what
> would you want to compare it to? You have to have some timer.resource
> available, don't you? You posted a link to a piece of code that counts
> cycles depending on another known frequency (frequency of NMIs there).
> You can use the same code. Just set your own something to trigger NMIs
> at a stable rate, replace "send:" with appropriate output handling (JMP
> $FFD2 for example) and there you are. :-)

I was thinking about about the TOD. We just talked about setting it to
the right input frequency. Power grid frequency is pretty accurate
these days, so I thought about having the TOD do the timing, after
setting it up correctly and turning the VIC off of course. Of course,
the longer the period of measurement, the more accurate the result will
be.
--
cul8er

Paul
paul.f...@gmx.net

SD!

unread,
Mar 6, 2014, 6:30:13 PM3/6/14
to
On 2014-03-01 18:20:47 +0000, Paul Förster said:

>> Move the jitter into HBLANK range for a quick'n dirty fix like in the
>> early eighties. Or use one of the cycle counting/NOP stepping routines
>> to get a fully stable and predictable IRQ like in the late eghties.
>> But.. that jitter is not always bad.. I recall one game (Ballblazer I
>> think..) where I always wondered how it would feel like if the jitter
>> was gone. And I always concluded that it would be worse then :-)
>
> I couldn't see it in Ballblazer (at least on the C64 longplay on YouTube)

Try on a real machine ;-)

>> Do you mean you want to verify the CPU clock? But if not VIC then what
>> would you want to compare it to? You have to have some timer.resource
>> available, don't you? You posted a link to a piece of code that counts
>> cycles depending on another known frequency (frequency of NMIs there).
>> You can use the same code. Just set your own something to trigger NMIs
>> at a stable rate, replace "send:" with appropriate output handling (JMP
>> $FFD2 for example) and there you are. :-)
>
> I was thinking about about the TOD. We just talked about setting it to
> the right input frequency. Power grid frequency is pretty accurate
> these days, so I thought about having the TOD do the timing, after
> setting it up correctly and turning the VIC off of course. Of course,
> the longer the period of measurement, the more accurate the result will
> be.

I didn't analyse too deep the source you provided the link for, but CIA
#2 has its interrupt line connected to CPU's NMI. So if you handle TOD
alarm correctly, you might be able to generate NMIs at 10Hz rather than
the 450 used originally. If that's enough of a frequency you'll be able
to tell us once you adapt the routine ;-)

--
SD!

Paul Förster

unread,
Mar 10, 2014, 4:35:05 PM3/10/14
to
Hi SD!,

On 2014-03-06 23:30:13 +0000, SD! said:
> Try on a real machine ;-)

I see. :)

> I didn't analyse too deep the source you provided the link for, but CIA
> #2 has its interrupt line connected to CPU's NMI. So if you handle TOD
> alarm correctly, you might be able to generate NMIs at 10Hz rather than
> the 450 used originally. If that's enough of a frequency you'll be able
> to tell us once you adapt the routine ;-)

hmmm, interesting idea. I'm almost tempted to do that. :-)
--
cul8er

Paul
paul.f...@gmx.net

0 new messages