English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 13 January 2021, 12:02   #1
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
CIA TOD Rollover

Editing post as my problem has now changed.

Can anyone explain why I get occasional silly values when reading the CIA B TOD clock?

When reading it at the start and end of a function, I occasionally get bad values, with the finish time being less than the end time, or even the finish time being zero sometimes.

More details in post 4 below.

Last edited by Ernst Blofeld; 13 January 2021 at 14:38.
Ernst Blofeld is offline  
Old 13 January 2021, 12:51   #2
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,062
Read once in this order: high (latch activated), middle, low byte (latch deactivated).
a/b is offline  
Old 13 January 2021, 12:57   #3
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by a/b View Post
Read once in this order: high (latch activated), middle, low byte (latch deactivated).
Ooooh... that explains why I couldn't find anything when I searched.

Thank you.
Ernst Blofeld is offline  
Old 13 January 2021, 13:31   #4
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
It's strange though, that I'm occasionally getting start times that are greater than my end times...

Code:
In Profiler_EndFunction: startTime 65532 > finishTime 0
In Profiler_EndFunction: startTime 192250 > finishTime 192000
In Profiler_EndFunction: startTime 258555 > finishTime 258304
In fact, how can I have a finish time of zero?

(edit - the low byte of all the finishTimes is zero, if that's a clue)

Code:
ULONG GetCurrentTime(void) {
    ULONG hi = ciab->ciatodhi;		// latch activated
    ULONG mid = ciab->ciatodmid;
    ULONG low = ciab->ciatodlow;	// latch deactivated

    return (hi << 8 | mid) << 8 | low;
}
ciab is
volatile struct CIA * ciab = CIAB;
where CIAB is
#define CIAB ((volatile struct CIA *) 0xbfd000UL)


The generated assembly looks sensible, to me:

Code:
00002c0a <GetCurrentTime>:
ULONG GetCurrentTime(void) {
    2c0a:	move.l d2,-(sp)
    ULONG hi = ciab->ciatodhi;		// latch activated
    2c0c:	move.b bfda00 <gcc8_c_support.c.62367fe7+0xbdadad>,d0
    ULONG mid = ciab->ciatodmid;
    2c12:	move.b bfd900 <gcc8_c_support.c.62367fe7+0xbdacad>,d2
    ULONG low = ciab->ciatodlow;	// latch deactivated
    2c18:	move.b bfd800 <gcc8_c_support.c.62367fe7+0xbdabad>,d1
    ULONG hi = ciab->ciatodhi;		// latch activated
    2c1e:	andi.l #255,d0
    return (hi << 8 | mid) << 8 | low;
    2c24:	lsl.l #8,d0
    2c26:	or.b d2,d0
    2c28:	lsl.l #8,d0
}
    2c2a:	or.b d1,d0
    2c2c:	move.l (sp)+,d2
    2c2e:	rts

Last edited by Ernst Blofeld; 13 January 2021 at 14:20.
Ernst Blofeld is offline  
Old 13 January 2021, 15:57   #5
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,570
Do you have OS running? TOD is reset periodically by system.
Toni Wilen is offline  
Old 13 January 2021, 16:08   #6
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by Toni Wilen View Post
Do you have OS running? TOD is reset periodically by system.
No, I've taken over the system, I believe correctly. The only interrupts that should be running are a copper one for my screen flipping and a ports one for the keyboard, which I believe only uses cia a.

Code:
void TakeSystem(void) {
	Forbid(); // forbid multitasking

	ActiView = GfxBase->ActiView; // save current view

	// Save current interrupts and DMA settings.
    systemADKCON = custom->adkconr;
    systemINTENA = custom->intenar;
    systemDMACON = custom->dmaconr;

	// The VBR is stored in a different place on 68010s and above.
    if ((SysBase->AttnFlags & AFF_68010)) {
		UWORD getVBR [] = {
			0x4e7a, 0x0801,     // movec.l vbr, d0
			0x4e73              // rte
		};

		VBR = (APTR *) Supervisor((void *) getVBR);
	}

    // Save system interrupt handers.
    for (int i = 0; i < 6; i++)
        systemInterruptHandlers[i] = VBR[25 + i];

	WaitForVerticalBlank(); WaitForVerticalBlank();

	custom->dmacon = DMAF_MASTER | DMAF_BLITHOG | DMAF_ALL; // clear all DMA channels

	// Set all colours to black.
	for (int a = 0; a <= 31; a++)
		custom->color[a] = 0x000;

	LoadView(NULL); // has side effect of enabling VERTB

	WaitTOF(); WaitTOF();

	WaitForVerticalBlank(); WaitForVerticalBlank();

	OwnBlitter();
	WaitForBlitter();

    custom->intena = INTF_INTEN | INTF_ALL; // disable all interrupts
    custom->intreq = INTF_INTEN | INTF_ALL; // clear any interrupts that were pending
}
Ernst Blofeld is offline  
Old 13 January 2021, 17:18   #7
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
At the moment I don't believe this is a problem with my code, because when the problem occurs the low byte of the is always zero. I could imagine something overwriting the variable on the stack, but only the lowest byte?

I've changed the code that detects the problem to the following:

Code:
    if (startTime > finishTime)
        * (WORD *) 0xdff180UL = 0xfff;
So that you get a white flash on the screen when it happens. On my set up this happens on around the 12th and 16th frames.

I've attached the executable in case anyone wants to have a look.
Attached Files
File Type: zip a.mingw.zip (28.7 KB, 144 views)
Ernst Blofeld is offline  
Old 13 January 2021, 17:28   #8
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,570
ALARM bit is set (CRB bit 7).
Reading TOD when ALARM bit is set won't latch the TOD but returns "live" TOD. (EDIT: which is undocumented feature)
Toni Wilen is offline  
Old 13 January 2021, 17:41   #9
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
I had just found this: https://eab.abime.net/showpost.php?p...8&postcount=14
But Toni already posted

Last edited by ross; 13 January 2021 at 19:43. Reason: removed a silly question :D
ross is offline  
Old 13 January 2021, 17:47   #10
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by Toni Wilen View Post
ALARM bit is set (CRB bit 7).
Reading TOD when ALARM bit is set won't latch the TOD but returns "live" TOD. (EDIT: which is undocumented feature)
Thanks Toni.

I'm now clearing the ALARM bit,

Code:
    ciab->ciacrb = CIACRBF_ALARM;
in my init code, but not seeing any difference. Am I doing it right?
Ernst Blofeld is offline  
Old 13 January 2021, 19:28   #11
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Like this?

Code:
    ciab->ciacrb &= ~CIACRBF_ALARM;
This seems to work, but it's hard to find good documentation and examples. This control register is not like the interrupt control registers, it should be read then a modified value written back to it?
Ernst Blofeld is offline  
Old 13 January 2021, 19:52   #12
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,570
Most CIA registers are normal read/write. Interrupt register is special.
Toni Wilen is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Possible CIA problem bwldrbst support.Hardware 8 05 July 2020 09:29
CIA interrupts... bloodline Coders. System 6 18 January 2018 10:33
CIA-A TOD clock source with genlock mark_k support.WinUAE 25 13 February 2014 20:30
example of a CIA timer interrupt in assembler using cia.resource Apollo Coders. Asm / Hardware 3 05 July 2013 08:40
CIA test Toni Wilen Coders. General 13 03 March 2007 22:14

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 08:07.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08404 seconds with 14 queries