English Amiga Board


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

 
 
Thread Tools
Old 16 June 2015, 15:55   #21
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 3,304
Quote:
Originally Posted by StingRay View Post
I never said that and it's not a problem either for me. System has been killed hence clock stops. If someone doesn't like that he should stick to 100% system-friendly software only.
Yes, that is what I meant. Kill the system means kill it (incl. clock) but then you don`t go back to it. On the other hand there is start from WB and "take over the system" with later restoration. So you can work on WB which is as stable as before you took over the system.
daxb is offline  
Old 16 June 2015, 17:24   #22
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
You're right. Sorry. I exchanged load and save.
phx is offline  
Old 17 June 2015, 04:55   #23
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 779
phx,

Thanks for verifying that, because it made me doubt my own understanding of the system.

Initially I thought that 'move.w #$b,$1c(a0)' was some kind of patch for the unix time data, but then after rechecking the offset it was not patching a word in that region, you cleared that up nicely, but I still don't fully understand how DoIO() works.


EDIT:

Anyone who knows,

Is there some way to preserve tab formatting in the vBulletin editor (advanced mode) when editing a post? It's driving me nuts, have to remove and insert a fresh paste of the whole source between the code tags every time before saving.

Last edited by modrobert; 17 June 2015 at 08:11.
modrobert is offline  
Old 17 June 2015, 16:05   #24
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 779
After some brief testing, my routine seems to work OK. Here is the relevant code I've added to startup.i.

Code:
	move.l	$4.w,a6
	move.l	a6,a5				; execbase in a5
	lea     battresname(pc),a1		; battclock.resource
	jsr     -498(a6)			; OpenResource()
	movea.l d0,a4				; battclockbase in a4
	move.l	a4,d0				; hmm...
	bne.b   .battok
	bra	.fail
.battok	moveq	#$28,d0				; want 40 bytes allocated
	move.l	#$10001,d1			; MEMF_ANY, MEMF_CLEAR?
	jsr	-198(a6)			; AllocMem()
	move.l	d0,a3				; allocated mem in a3
	tst.l	d0
	beq	.fail
	move.l	d0,a1
	lea	timerdevname(pc),a0
	moveq	#0,d0
	move.l	d0,d1
	jsr	-444(a6)			; OpenDevice()
	move.l	d0,d6
	ext.w	d6				; byte to word
   	ext.l	d6				; word to long, d6 equals 0?
   	bne.b   .fail
	moveq	#0,d0
	move.b	d0,8(a3)			; start building IORequest		
	move.b	d0,9(a3)
	suba.l	a1,a1
	move.l	a1,$a(a3)
	move.l	a1,$e(a3)
	clr.l	$24(a3)
	movea.l	a4,a6				; battclockbase in a4
	jsr	-12(a6)				; ReadBattClock()
	move.l	d0,$20(a3)			; unix time in d0
	move.w	#$b,$1c(a3)			; io_Command = TR_SETSYSTIME
	movea.l a3,a1
	movea.l	a5,a6				; execbase in a5
	jsr	-456(a6)			; DoIO()
	movea.l	a3,a1
	jsr	-450(a6)			; CloseDevice()
	movea.l	a3,a1
	moveq	#$28,d0				; free the 40 bytes
	jsr	-210(a6)			; FreeMem()
.fail
; snip
rts

battresname    dc.b    'battclock.resource',0
timerdevname    dc.b    'timer.device',0
I have also attached the whole test intro with source code, just run 'intro' in the 'bin' folder to check it. The included source startup_rtc.i is StingRay's code with my added RTC restore routine.

NOTE: The source code is converted to compile with Devpac (had to add some directives, change a few instructions, etc.).
Attached Files
File Type: lha intro.lha (40.3 KB, 152 views)
modrobert is offline  
Old 18 June 2015, 11:15   #25
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Very good. There is just one disadvantage: you need an RTC and at least OS2.0(?) for battclock.resource.

Maybe it also works without RTC, by remembering the system time and resetting the TOD to zero at the beginning of your program. At the end you will set the system time to the saved timeval + the new TOD count. As long as your code doesn't mess with the TOD, and as long as the OS and the interrupts are disabled, I see no reason why that shouldn't work.

At the start of your program, get SysTime and reset TOD:
Code:
; a6 = TimerDevice
        lea     timval,a0
        jsr     -66(a6)                 ; GetSysTime

        ; disable interrupts, take over system
        ; ...

        ; reset TOD
        lea     $bfe001,a0              ; CIA-A
        moveq   #0,d0
        move.b  d0,$a00(a0)             ; TODHI 
        move.b  d0,$900(a0)             ; TODMID
        move.b  d0,$800(a0)             ; TODLO
At the end of your program, use the TOD to set the new SysTime:
Code:
        lea     $bfe001,a0
        moveq   #0,d0
        move.b  $a00(a0),d0             ; TODHI
        lsl.w   #8,d0
        move.b  $900(a0),d0             ; TODMID
        lsl.l   #8,d0
        move.b  $800(a0),d0             ; TODLO

        ; restore system, enable interrupts
        ; ...
; a6 = TimerDevice
; d0 = TOD count since start
        lea     timeval,a0
        add.l   TV_MICRO(a0),d0
        divu    TD_TODHERTZ(a6),d0
        move.l  d0,d1
        ext.l   d0
        add.l   d0,TV_SECS(a0)
        swap    d1
        ext.l   d1
        move.l  d1,TV_MICRO(a0)

; set system time, pass timeval to TR_SETSYSTIME
; ...
phx is offline  
Old 18 June 2015, 12:24   #26
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 779
Isn't the TOD frozen when you disable all interrupts (#$7FFF / %0111111111111111)?

I thought that was the reason "time stand still" when running intro.

EDIT:

Think I get it now, after staring at your code a bit more. I confused TOD with the system time due to the abbreviation "Time Of Day", but it's actually counting HSYNC events.

The interrupt handler updating the system time by dividing ticks is disabled while TOD keeps running, right?

Can you explain the TV_MICRO part of the code?

Last edited by modrobert; 18 June 2015 at 20:39.
modrobert is offline  
Old 18 June 2015, 21:18   #27
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by modrobert View Post
Think I get it now, after staring at your code a bit more. I confused TOD with the system time due to the abbreviation "Time Of Day", but it's actually counting HSYNC events.
That's CIA-B, IIRC. The CIA-A TOD counts 50 or 60Hz ticks. The ticks per second can be read from the TimeDevice structure TD_TODHERTZ.

Quote:
The interrupt handler updating the system time by dividing ticks is disabled while TOD keeps running, right?
Yes, I hope so. Nobody stopped the CIA-TOD.
I didn't test this code myself. It was just an idea I had when reading your solution.

Quote:
Can you explain the TV_MICRO part of the code?
After reading the 24-bit TOD (number of ticks since program start) to d0 this value has to be converted into a timval structure, i.e. split into seconds and microseconds. At the same time it is added to the timeval which we have read at program start with GetSysTime.
After the ticks have been added you can use this timeval to set your new system time (DoIO, TR_SETSYSTIME).
phx is offline  
Old 19 June 2015, 09:55   #28
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 779
I was too lazy to implement all of your code, and wasn't sure how exactly, so what I did was testing your theory using a breakpoint in the MonAm debugger (love that thing).

Added this code right before entering the intro.

Code:
        lea     $bfe001,a0              ; CIA-A
        moveq   #0,d0
        move.b  d0,$a00(a0)             ; TODHI 
        move.b  d0,$900(a0)             ; TODMID
        move.b  d0,$800(a0)             ; TODLO
...and this when exiting the intro.

Code:
        lea     $bfe001,a0
        moveq   #0,d0
        move.b  $a00(a0),d0             ; TODHI
        lsl.w   #8,d0
        move.b  $900(a0),d0             ; TODMID
        lsl.l   #8,d0
        move.b  $800(a0),d0             ; TODLO
What I got was d0 = 592 (#$250) after 11.94 seconds of running the intro, timing it with my wrist watch.

So, assuming 50Hz for my PAL system.

592/50 = 11.84 seconds

Looks like a winner, the error margin most likely my stop watch reaction time, hehe.

Last edited by modrobert; 19 June 2015 at 10:00.
modrobert is offline  
Old 31 July 2015, 16:55   #29
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,604
Don't know if I'm too late, seems you already got a few replies.

The hardware has a TOD clock since the first A1000, which means you're up the wrong track if you try to use any lib function that isn't present in 1.2. Another clue is that a battery has nothing at all to do with a TOD clock chip. BattClock is a strange name for a lib.

TOD clock doesn't stop just because you turn off the interrupts... that would make it pretty useless It's a simple hardware counter.

So why is the Workbench clock incorrect? Because WB function to show time just increments the values it read once. Maybe it will read them again if you wait a minute. Maybe something unrelated triggers a re-read. Either way you have to trigger the re-read of the clock chip. timer.device GetSysTime followed by SetSysTime looks like it should update the local system TOD values, but it could be that you also have to find out how to trigger the WB to update its on-screen time value, in a WB 1.2+ compatible way if you want to support all Amigas.

It could be that GetSysTime() gives you the incorrect WB values again. I use this for the clock display in AsmTwo, which seems to work.

Code:
TODtick:	;->d0.l, 1 tick=1/50 sec
	bsr.s TOD
	move.w TODData+6(PC),d0
	mulu #3000,d0		;<<10-(<<4+<<3) *3 (add)
	add.l TODData+8(PC),d0
	RTS
	
TOD:	MOVEM.L D1-A6,-(SP)	;sys clock minutes since 00:00 -> d0.
	move.l DOSBASE(A4),A6
	lea TODData(PC),a2	;pokes 3 longs
	move.l a2,d1
	jsr -192(a6)		;DateStamp
	move.l 4(a2),d0		;div by 60 to get mm.hh.L
	MOVEM.L (SP)+,D1-A6
	RTS
TODData:blk.l 3,0

Last edited by Photon; 31 July 2015 at 17:03.
Photon is offline  
Old 31 July 2015, 17:28   #30
Wepl
Moderator
 
Wepl's Avatar
 
Join Date: Nov 2001
Location: Germany
Posts: 866
Quote:
Originally Posted by modrobert View Post
When using real hardware disabling the system for a long period of time pretty much screws up networking and other stuff in my running OS anyway (AmIRC times out, iBrowse bugs out, SMBFS hangs which includes DOPUS due to directory refresh, etc.) no matter how hard you try to restore to previous state when exiting the code, so even if it seems correct in theory it still compromises the running OS unless you do it briefly. The goal here for me is to be able to to test code without rebooting my A1200 when doing code changes during development, and StingRay's startup code works well as long as I keep it under a minute or so (except for the system time problem).
Why not using WHDLoad

it uses (you have to open timer.device before):
Code:
_SetClockLoad	move.l	a6,-(a7)

		move.l	(gl_execbase,GL),a6
		jsr	(_LVOForbid,a6)

		lea	(_battclock),a1
		jsr	(_LVOOpenResource,a6)
		tst.l	d0
		beq	.fail
		move.l	d0,a6
		jsr	(_LVOReadBattClock,a6)
		move.l	(gl_execbase,GL),a6
		tst.l	d0
		beq	.fail
		
		move.l	(gl_timerio,GL),a1
		move.l	d0,(IOTV_TIME+TV_SECS,a1)
		clr.l	(IOTV_TIME+TV_MICRO,a1)
		move.w	#TR_SETSYSTIME,(IO_COMMAND,a1)
		jsr	(_LVODoIO,a6)
		
.fail		jsr	(_LVOPermit,a6)

		move.l	(a7)+,a6
		rts
Wepl is offline  
Old 31 July 2015, 19:28   #31
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,604
Yes, you would have come across this before Your way should update the clock in WB. But... WHDLoad has set 2.0 as minimum kickstart version to support. In this case I think it can be done with the same functions in just timer.device?

Anyway, the TOD clock circuit keeps on ticking and giving correct time if you read it, for as long as the machine is on, on any Amiga ever made.

If you have an expansion with battery, the expansion clock chip keeps time also when power is off.

Last edited by Photon; 31 July 2015 at 19:42.
Photon is offline  
Old 31 July 2015, 20:06   #32
Wepl
Moderator
 
Wepl's Avatar
 
Join Date: Nov 2001
Location: Germany
Posts: 866
I would think it is feasible to restore the clock only on OS 2+.
I doubt that somebody cares about the clock on Kick 1.2/3 (are there really people using 1.3 besides to put a floppy in the drive?).
Wepl is offline  
Old 01 August 2015, 21:25   #33
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,604
Well, why create a completely unnecessary dependency just to read and set the TOD clock? It only takes one to affect the whole program, and if it's put in a startup source without thinking it affects all programs using it.
Photon is offline  
Old 04 August 2015, 01:43   #34
modrobert
old bearded fool
 
modrobert's Avatar
 
Join Date: Jan 2010
Location: Bangkok
Age: 56
Posts: 779
Photon and Wepl,

Thanks for the suggestions.

BTW: In case you missed it, there were already three solutions prior to your suggestions in the thread.

1) Mask the specific interrupt bit to allow timers (works on any version, but Toni objected, not safe). [by phx]

Code:
move.w    #$7FF7,d0            ; %0111111111110111 (#$8 bit not set)
2) Using battclock.resource to restore system time from RTC after intro finishes (works with RTC on 2.0 and up). [by modrobert]

3) Clearing TOD counter before intro, and then correcting system time after intro based on TOD counter on exit (works on any version, provided the intro leaves TOD counters alone). [by phx]

As an added bonus I disassembled the 'setclock' binary from WB 3.1 with comments (and it compiles bit perfect compared to original with 'vasm').

Last edited by modrobert; 05 August 2015 at 00:27.
modrobert is offline  
Old 04 August 2015, 19:11   #35
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,604
Yeah, I noticed, just added another way that I thought was right. I.e. Read and set TOD clock with timer.device in the universal way, if possible. Both after turning ints on again. (I think you misinterpreted 3) )

I found an old source that says it's a command "ClockLoad" disassembled. Bit crap but if it helps.

It just seems a basic function and it's all about which functions nudge WB's own functions to update it.
Photon is offline  
Old 04 October 2015, 20:10   #36
dissident
Registered User
 
Join Date: Sep 2015
Location: Germany
Posts: 260
clock problem

Hi,

I’m the coder of Copper-rulez-AGAin.lha (Aminet).

daxb you are right. A demo that returns to the workbench shouldn’t affect the RTC. Well, I didn’t care about this fact and I was caught .

To all members of this discussion: It was a pleasure to read because of its high quality stuff. I’ve learned a lot.

Good work modrobert . Your sourcecode helped me to understand how to use the battery clock resource and the timer device. BTW, I’ve optimized and expanded your code a little bit:

Code:
move.l	$4.w,a6
move.l	a6,a5			; execbase in a5
lea     battresname(pc),a1      ; battclock.resource
jsr 	 -498(a6)		; OpenResource()
movea.l	d0,a4		        ; battclockbase in a4
move.l	a4,d0			; hmm...
beq.b  .fail
.battok	
moveq	#$28,d0		        ; want 40 bytes allocated (size of 						; timer-request-structure)
move.l	#$10001,d1		; MEMF_ANY, MEMF_CLEAR?
jsr	-198(a6)		; AllocMem()
move.l	d0,a3		        ; allocated mem in a3
tst.l	d0
beq	.fail
move.l	d0,a1
lea	timerdevname(pc),a0
moveq	#0,d0			; Unit 0 = UNIT_MICROHZ
moveq 	#0,d1			; No flags
jsr	-444(a6)		; OpenDevice()
tst.l	d0			; equal 0 ?
bne.b   .fail
moveq	#0,d0			; start building IORequest / 							; TimerRequest structure
move.b	d0,8(a3)		; LN_Type = NULL		
move.b	d0,9(a3)		; LN_Pri = NULL
move.l	d0,$a(a3)		; LN_Name = No pointer
move.l	d0,$e(a3)		; MN_ReplyPort = No pointer
movea.l	a4,a6			; battclockbase in a4
move.l 	d0,$24(a3)		; TV_micro =0 microseconds 
jsr	-12(a6)		        ; ReadBattClock()
movea.l	a3,a1
move.l	d0,$20(a3)		; TV_secs = unix time in seconds
beq.b	.no_sys_time_refresh    ; Equal 0 (Invalid value) ?
movea.l	a5,a6			; execbase in a5
move.w	#$b,$1c(a3)		; IO_Command = TR_SETSYSTIME
jsr	-456(a6)		; DoIO()
.no_sys_time_refresh
movea.l a3,a1
jsr	-450(a6)		; CloseDevice()
movea.l	a3,a1
moveq	#$28,d0		        ; free the 40 bytes
jmp	-210(a6)		; FreeMem()
.fail
rts

battresname     dc.b    'battclock.resource',0
timerdevname   dc.b    'timer.device',0

But the battery clock resource has a bug. Working with OS 3.0 on a real A1200 without a RTC the return value of OpenResource() is always nonzero. Apart from this behaviour OpenResource() returns a zero when working on a MiST. Thats's were my fixed demo aborted with the error message "Can't find battery backed up clock". The behaviour of this function call seems to be different on original hardware and on a MiST which doesn't have a RTC.

So it's better to use PHX's solution for refreshing the system time.
PHX, I've also checked your startup code using the TOD and expanded it. Good idea to use the TOD directly in addition to the system .
The TOD must not be set to zero and messed up this way. You can also get the difference from TOD before and after the demo/intro. But a TOD overflow must be checked. Because TOD runs independently from any interrupts they can be all turned off.

Code:
  
  move.l  $4.w,a6            ;Execbase
  lea     timer_request_struc(pc),a1 ;Timer-request-structure
  moveq   #0,d0              ;Unit 0 (UNIT_MICROHZ) & Null for entrys in struc
  move.b  d0,8(a1)           ;LN_Type: Entry type = Null
  move.b  d0,9(a1)           ;LN_Pri: Priority of the structure = Null
  moveq   #0,d1              ;No Flags for device
  move.l  d0,$a(a1)          ;LN_Name: No name for the structure
  lea     timer_device_name(pc),a0 ;Pointer to name of Timer-Device
  move.l  d0,$e(a1)          ;MN_ReplyPort: No Reply-Port
  jsr     -444(a6)           ;OpenDevice()
  tst.l   d0
  bne.s   open_timer_device_error
  lea     timer_request_struc(pc),a1
  move.w  #$a,$1c(a1)        ;IO_Command = TR_GETSYSTIME
  jsr     -456(a6)           ;DoIO()
  jsr     -120(a6)           ;Disable()

;Take over the machine...

  move.l  #$bfe001,a4        ;CIA-A base adress
  moveq   #0,d0
  move.b  $a00(a4),d0        ;TOD-clock bits 23-16
  swap    d0                 ;Shift bits to the right position
  move.b  $900(a4),d0        ;TOD-clock bits 15-8
  lsl.w   #8,d0              ;Shift bits to the right position
  move.b  $800(a4),d0        ;TOD-clock bits 7-0
  move.l  d0,TOD_time_save   ;Save time before demo/intro starts

  movem.l d0-d7/a0-a6,-(a7)
  bsr     demo               ;start demo/intro
  movem.l (a7)+,d0-d7/a0-a6

  move.l  TOD_time_save(pc),d0 ;Time before starting demo/intro
  moveq   #0,d1
  move.b  $a00(a4),d1        ;TOD-clock Bits 23-16
  swap    d1
  move.b  $900(a4),d1        ;TOD-clock Bits 15-8
  lsl.w   #8,d1
  move.b  $800(a4),d1        ;TOD-clock Bits 7-0
  cmp.l   d0,d1              ;TOD overflow?
  bge.s   no_TOD_overflow    ;No -> skip
  move.l  #$ffffff,d2        ;Max TOD value
  sub.l   d0,d2              ;Difference until overflow
  add.l   d2,d1              ;+ value after overflow
  bra.s   TOD_okay
  CNOP 0,4                   ;Longword alignment for 68020+
no_TOD_overflow
  sub.l   d0,d1              ;Get normal difference without overflow
TOD_okay
  move.l  d1,TOD_time_save   ;Save period of demo/intro

;Restore system...

  move.l  $4.w,a6            ;Execbase
  jsr     -126(a6)           ;Enable()
  move.l  TOD_time_save(pc),d0 ;Period of demo/intro
  moveq   #0,d1
  move.b  212(a6),d1         ;Get VBlankFrequency
  lea     timer_request_struc(pc),a1
  divu.w  d1,d0              ;Calculate seconds
  move.w  #$b,$1c(a1)        ;IO_command = TR_SETSYSTIME
  move.l  d0,d1              ;Save seconds in d1
  ext.l   d0                 ;Word to longword
  add.l   d0,$20(a1)         ;TV_SECS: Set Unix-Time seconds
  swap    d1                 ;Remainder of division
  mulu.w  #10000,d1          ;*10000 = µs
  add.l   d1,$24(a1)         ;TV_MICRO: Set Unix-Time microseconds
  jmp     -456(a6)           ;DoIO()
  CNOP 0,4
open_timer_device_error
  rts

  CNOP 0,4
TOD_time_save		DC.L 0

timer_request_struc	DS.B 40

timer_device_name	DC.B "timer.device",0
  EVEN
I fixed my demo with this way using the TOD clock. And now it works fine on a MiST. (Thanks to kolla for his support ). The fixed version of Copper-rulez-AGAin.lha is uploaded on Aminet.

Quote:
Very good. There is just one disadvantage: you need an RTC and at least OS2.0(?) for battclock.resource
PHX, I think I've got a solution for OS 1.x systems with a RTC. I found this little C sourcecode for calculating UNIX time for PCs:

Code:
/** Konvertiert gegliederte UTC-Angaben in Unix-Zeit.
 * Parameter und ihre Werte-Bereiche:
 * - jahr [1970..2038]
 * - monat [1..12]
 * - tag [1..31]
 * - stunde [0..23]
 * - minute [0..59]
 * - sekunde [0..59]
 */
long unixzeit(int jahr, int monat, int tag,
              int stunde, int minute, int sekunde)
{
  const short tage_seit_jahresanfang[12] = /* Tage seit Jahresanfang ohne Tage des aktuellen Monats und ohne Schalttag */
    {0,31,59,90,120,151,181,212,243,273,304,334};

  int schaltjahre = ((jahr-1)-1968)/4
                  - ((jahr-1)-1900)/100
                  + ((jahr-1)-1600)/400;

  long tage_seit_1970 = (jahr-1970)*365 + schaltjahre
                      + tage_seit_jahresanfang[monat-1] + tag-1;

  if ( (monat>2) && (jahr%4==0 && (jahr%100!=0 || jahr%400==0)) )
    tage_seit_1970 += 1; /* +Schalttag, wenn jahr Schaltjahr ist */

  return sekunde + 60 * ( minute + 60 * (stunde + 24*tage_seit_1970) );
}
The PC uses as a start date 01.01.1970 00:00:00 instead of 01.01.1978 00:00:00 like the amiga. Care must be taken when calculating the leap years. Use 1976 instead of 1968. The distance between the start year and the previous leap year should be 2 years or there will be a wrong UNIX time.

After analysing SetClock1.2 & 1.3 and ReadBattClock() in ROM I wrote this RTC-handler. It checks if a RTC is available, reads the RTC, converts the date/time to amiga UNIX time and sets the system time. As a bonus I've included an alternative subroutine to seek&reset the RTC.

More information about the OKI RTC can be found here:
http://www.amigawiki.de/lib/exe/fetch.php?media=dearts:m6242b_oki_datasheet.pdf
Attached Files
File Type: s RTC-Handler.s (11.6 KB, 141 views)
dissident is offline  
Old 05 October 2015, 14:39   #37
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by dissident View Post
The TOD must not be set to zero and messed up this way. You can also get the difference from TOD before and after the demo/intro. But a TOD overflow must be checked.
Yes. That might be a better solution.

Quote:
After analysing SetClock1.2 & 1.3 and ReadBattClock() in ROM I wrote this RTC-handler.
As far as I can see it only works with MSM6242B RTCs, but not with the RICOH RTCs in an A3000 or A4000. The RICOH has a slightly different register layout (weekday has moved, for example).
phx is offline  
Old 05 October 2015, 20:50   #38
dissident
Registered User
 
Join Date: Sep 2015
Location: Germany
Posts: 260
Quote:
As far as I can see it only works with MSM6242B RTCs, but not with the RICOH RTCs in an A3000 or A4000. The RICOH has a slightly different register layout (weekday has moved, for example).
phx you're right. I checked the sheet of the RICOH clock. The weekday register has a different position and the content of the control registers D-F is also different.
So my RTC-handler would fail there. I didtn't think OKI and RICOH are so incompatible to each other. Thanks for this hint.

Anyway the A3000 had OS2.0 and the A4000 OS 3.0 with the battery clock resource. So we can control the RTC by the OS.
dissident is offline  
Old 06 October 2015, 16:31   #39
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,516
Quote:
Originally Posted by dissident View Post
I’ve optimized and expanded your code a little bit
It has small bug, leaks memory if OpenDevice() fails and I guess D0=0 return code probably would be good idea too.

Quote:
But the battery clock resource has a bug. Working with OS 3.0 on a real A1200 without a RTC the return value of OpenResource() is always nonzero.
This was interesting note. I just checked and it happens because clock address range has floating data bus when there is no clock chip connected causing resource clock type detection code to mistakenly detect it.

I guess it can only happen with real 68020 CPU (or 100% cycle sequence accurate clone) because returned data from floating bus depends on what CPU fetched previously.
Toni Wilen is offline  
Old 07 October 2015, 18:42   #40
dissident
Registered User
 
Join Date: Sep 2015
Location: Germany
Posts: 260
Quote:
It has small bug, leaks memory if OpenDevice() fails and I guess D0=0 return code probably would be good idea too.
Yes, Toni a more precise error handling would be better.

Quote:
I just checked and it happens because clock address range has floating data bus when there is no clock chip connected causing resource clock type detection code to mistakenly detect it.
Good to know. If I understand it correctly the clock chip detection of the clock resource is fooled by random values. Would that error also happen with my code?

Code:
  move.l  #$dc0000,a0        ;RTC base address
  moveq   #1,d0              ;Set HOLD-Bit in Control D-register
  move.b  d0,$37(a0)         ;to prevent register-carry during
                             ;reading by freezing counter pulse
  nop                        ;Prevent parallel execution on the 68060
  move.b  $37(a0),d1         ;Check if Control D-register exists
  and.b   #$f,d1             ;Mask out unimportant bits
  cmp.b   d1,d0              ;Read = Write?
  bne.s   no_RTC_found
Or should be several checks a better way for a detection?

Code:
  moveq   #1,d0              ;Reset RTC-Counter
  move.b  d0,$3f(a0)         ;Set RSET-Bit in Control F-register
  nop                        ;Prevent parallel execution on the 68060
  move.b  $3f(a0),d1         ;1st check: Read to check whether
                             ;Control F register exists
  moveq   #$f,d2
  and.b   d2,d1              ;Only Bits 0-3
  cmp.b   d1,d0              
  bne.s   reg_check_failed   ;Read <> Write -> skip
  moveq   #5,d0              ;Reset RTC-Counter, set 24 hours
  move.b  d0,$3f(a0)
  nop                        ;Prevent parallel execution on the 68060
  move.b  $3f(a0),d1         ;2nd Control F register check
  and.b   d2,d1              ;Only Bits 0-3
  cmp.b   d1,d0              
  bne.s   reg_check_failed   ;Read <> Write -> skip
  moveq   #4,d0              ;Set 24 hours
  move.b  d0,$3f(a0)
  nop                        ;Prevent parallel execution on the 68060
  move.b  $3f(a0),d1         ;3rd Control F register check
  and.b   d2,d1              ;Only Bits 0-3
  cmp.b   d1,d0              
  bne.s   reg_check_failed   ;Read <> Write -> skip
dissident 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
startup/system takeover sidewinder Coders. General 15 28 February 2016 16:33
time clock prob a2000 source Hardware mods 11 07 August 2011 13:16
A1200 Real Time Clock Eclipse support.Hardware 4 22 March 2011 02:18
App to update Amiga System time from web time?? DDNI request.Apps 2 31 December 2007 07:21
Reading the Real Time Clock girv Coders. General 5 04 September 2007 18:30

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 03:53.

Top

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