Troubles restoring timer C

All 680x0 related coding posts in this section please.

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

User avatar
tobe
Atari God
Atari God
Posts: 1459
Joined: Sat Jan 24, 2004 10:06 am
Location: Lyon, France
Contact:

Troubles restoring timer C

Postby tobe » Thu Jan 20, 2005 8:32 pm

Hello,

I use timer C to play music @ ~50hz with this settings :
data = 245
div = 200
Works fine.

But when i restore the system timer, all timings goes wrong.

here is the gfa code,
mfp_lock% = move.w #$2700,sr
mfp_unlock% = move.w #$2300,sr

Code: Select all

PROCEDURE mfp_backup
  RCALL mfp_lock%, mfp_reg%()
  mfp_07|          = BYTE{&HFFFFFA07} ! backup ints
  mfp_13|          = BYTE{&HFFFFFA13}
  mfp_09|          = BYTE{&HFFFFFA09}
  mfp_15|          = BYTE{&HFFFFFA15}
  mfp_timdiv|      = BYTE{&HFFFFFA1D} ! backup timer C setup
  mfp_timdat|      = BYTE{&HFFFFFA23}
  mfp_vbl%         = LONG{&H70}       ! backup vbl vec
  mfp_timer%       = LONG{&H114}      ! backup timer C vec
  RCALL mfp_unlock%, mfp_reg%()
RETURN
'
PROCEDURE mfp_init ( a_vbl%, a_timer% )
  RCALL mfp_lock%, mfp_reg%()
  '
  BYTE{&HFFFFFA07} = &H00 ! turn off ints
  BYTE{&HFFFFFA0B} = &H00
  BYTE{&HFFFFFA0F} = &H00
  BYTE{&HFFFFFA13} = &H00
  BYTE{&HFFFFFA09} = &H00
  BYTE{&HFFFFFA0D} = &H00
  BYTE{&HFFFFFA11} = &H00
  BYTE{&HFFFFFA15} = &H00
  '
  BYTE{&HFFFFFA23} = &HF5 ! setup timer C (245)
  BYTE{&HFFFFFA1D} = &H70 !               (200)
  '
  LONG{&H70}       = a_vbl%
  LONG{&H114}      = a_timer%
  '
  BYTE{&HFFFFFA09} = &H60 ! allow timer C & IKBD
  BYTE{&HFFFFFA15} = &H60
  '
  RCALL mfp_unlock%, mfp_reg%()
RETURN
'
PROCEDURE mfp_restore
  RCALL mfp_lock%, mfp_reg%()
  '
  BYTE{&HFFFFFA07} = &H00 ! turn off ints
  BYTE{&HFFFFFA0B} = &H00
  BYTE{&HFFFFFA0F} = &H00
  BYTE{&HFFFFFA13} = &H00
  BYTE{&HFFFFFA09} = &H00
  BYTE{&HFFFFFA0D} = &H00
  BYTE{&HFFFFFA11} = &H00
  BYTE{&HFFFFFA15} = &H00
  '
  BYTE{&HFFFFFA23} = mfp_timdat| ! restore timer C setup
  BYTE{&HFFFFFA1D} = mfp_timdiv|
  '
  LONG{&H114}      = mfp_timer%
  LONG{&H70}       = mfp_vbl%
  '
  BYTE{&HFFFFFA07} = mfp_07| ! restore ints
  BYTE{&HFFFFFA13} = mfp_13|
  BYTE{&HFFFFFA09} = mfp_09|
  BYTE{&HFFFFFA15} = mfp_15|
  '
  RCALL mfp_unlock%, mfp_reg%()
RETURN

Notes :
BYTE{} = move.b
LONG{} = move.l
&H = $
step 1: introduce bug, step 2: fix bug, step 3: goto step 1.

User avatar
tobe
Atari God
Atari God
Posts: 1459
Joined: Sat Jan 24, 2004 10:06 am
Location: Lyon, France
Contact:

Postby tobe » Thu Jan 20, 2005 8:46 pm

No more troubles, now i restore the timer C data value to 192 instead of the saved value.
Looks dirty but works.
Is there another way to restore this data register in a 'nice' manner ?
Is div=64 data=192 the standard for timer C on all TOS computers ?
step 1: introduce bug, step 2: fix bug, step 3: goto step 1.

ijor
Hardware Guru
Hardware Guru
Posts: 3804
Joined: Sat May 29, 2004 7:52 pm
Contact:

Postby ijor » Thu Jan 20, 2005 10:27 pm

The timer data registers are write only. Reading from these registers returns the actual current counter, not the reload value.

User avatar
unseenmenace
Atari God
Atari God
Posts: 1961
Joined: Tue Sep 21, 2004 9:33 pm
Location: Margate, Kent, UK
Contact:

Postby unseenmenace » Fri Jan 21, 2005 9:01 am

The system timer is meant to run at 200Hz so if those figures produce 200Hz then it should be fine on any TOS. All the assembler code I've checked restores the timer C control register from a backup and the data register as $C0 (192).
UNSEEN MENACE
Several STFM's, 4MB STE, 2MB TT with 1.2GB Hard Drive and 14MB Falcon with 540MB Hard Drive,
Lynx 2 and Jaguar with JagCD
Member of GamebaseST and AtariLegend team
Check out my website at http://unseenmenace.110mb.com

User avatar
earx
Captain Atari
Captain Atari
Posts: 353
Joined: Wed Aug 27, 2003 7:09 am

Postby earx » Fri Jan 21, 2005 9:26 am

hmmm, that's nice to know. i finally might have a potential bug resolve for the ucm/alive shell! i never took care to see how other saved and restored their mfp stuffs.. thanx guys!! :)

ijor
Hardware Guru
Hardware Guru
Posts: 3804
Joined: Sat May 29, 2004 7:52 pm
Contact:

Postby ijor » Fri Jan 21, 2005 2:58 pm

Just for the record, and continuing the spirit that we have seen lately in the forum, of trying really hard things …

It might be possible to “detectâ€Â￾ the current timer setting. You can either measure the frequency, or read the counter constantly watching for the maximum value. Assuming a coarse divisor, this is probably feasible.

User avatar
tobe
Atari God
Atari God
Posts: 1459
Joined: Sat Jan 24, 2004 10:06 am
Location: Lyon, France
Contact:

Postby tobe » Fri Jan 21, 2005 3:27 pm

Nice idea !

Another one :
- Mask timer C to prevent execution
- Wait for the pending bit
- Read the data register
step 1: introduce bug, step 2: fix bug, step 3: goto step 1.

Pink/RG
Moderator
Moderator
Posts: 32
Joined: Tue Dec 17, 2002 5:54 pm
Location: Guildford, UK
Contact:

Postby Pink/RG » Wed Feb 02, 2005 3:34 am

Personally I never restore the Timer C data register value as you can't seem to do this reliably.

Here's my MFP save/restore code:

Code: Select all


Mfp_SaveRegisters:
   movem.l   d0-a6,-(a7)         ;   save registers
   move.w   sr,-(a7)         ;   save status register

   or.w   #$0700,sr         ;   disable interrupts

   movea.w   #$100.w,a1         ;   start of MFP vectors
   moveq   #15,d0            ;   16 vectors to save
.smfp_loop:
   move.l   (a1)+,(a0)+         ;   save mfp registers
   dbra   d0,.smfp_loop      ;   loop for all MFP vectors

   move.b   $FFFFFA03.w,(a0)+   ;   save Active Edge Register
   move.b   $FFFFFA05.w,(a0)+   ;   save Data Directionr Register
   move.b   $FFFFFA17.w,(a0)+   ;   save Vector Register

   move.b   $FFFFFA01.w,(a0)+   ;   save Parallel Port Data
   move.b   $FFFFFA1F.w,(a0)+   ;   save Timer A Data
   move.b   $FFFFFA21.w,(a0)+   ;   save Timer B Data
   move.b   $FFFFFA25.w,(a0)+   ;   save Timer D Data
   move.b   $FFFFFA27.w,(a0)+   ;   save Sync Character
   move.b   $FFFFFA2F.w,(a0)+   ;   save USART Data

   move.b   $FFFFFA29.w,(a0)+   ;   save USART Control
   move.b   $FFFFFA2B.w,(a0)+   ;   save Receiver Status
   move.b   $FFFFFA2D.w,(a0)+   ;   save Transmitter Status

   move.b   $FFFFFA13.w,(a0)+   ;   save Interrupt Mask A
   move.b   $FFFFFA15.w,(a0)+   ;   save Interrupt Mask B
   move.b   $FFFFFA0F.w,(a0)+   ;   save In Service A
   move.b   $FFFFFA11.w,(a0)+   ;   save In Service B
   move.b   $FFFFFA0B.w,(a0)+   ;   save Pending A
   move.b   $FFFFFA0D.w,(a0)+   ;   save Pending B
   move.b   $FFFFFA07.w,(a0)+   ;   save Enable A
   move.b   $FFFFFA09.w,(a0)+   ;   save Enable B

   move.b   $FFFFFA19.w,(a0)+   ;   save Timer A Control
   move.b   $FFFFFA1B.w,(a0)+   ;   save Timer B Control
   move.b   $FFFFFA1D.w,(a0)+   ;   save Timer C+D Control

   move.w   (a7)+,sr         ;   restore status register
   movem.l   (a7)+,d0-a6         ;   restore registers

   rts


Mfp_RestoreRegisters:

   movem.l   d0-a6,-(a7)         ;   save registers
   move.w   sr,-(a7)         ;   save status register

   or.w   #$0700,sr         ;   disable interrupts

   movea.w   #$100.w,a1         ;   start of MFP vectors
   moveq   #15,d0            ;   16 vectors to restore
.rmfp_loop:
   move.l   (a0)+,(a1)+         ;   restore mfp registers
   dbra   d0,.rmfp_loop      ;   loop for all MFP vectors

   clr.b   $FFFFFA19.w         ;   stop Timer A
   clr.b   $FFFFFA1B.w         ;   stop Timer B
   clr.b   $FFFFFA1D.w         ;   stop Timer C+D

   move.b   (a0)+,$FFFFFA03.w   ;   restore Active Edge Register
   move.b   (a0)+,$FFFFFA05.w   ;   restore Data Directionr Register
   move.b   (a0)+,$FFFFFA17.w   ;   restore Vector Register

   move.b   (a0)+,$FFFFFA01.w   ;   restore Parallel Port Data
   move.b   (a0)+,$FFFFFA1F.w   ;   restore Timer A Data
   move.b   (a0)+,$FFFFFA21.w   ;   restore Timer B Data
   move.b   (a0)+,$FFFFFA25.w   ;   restore Timer D Data
   move.b   (a0)+,$FFFFFA27.w   ;   restore Sync Character
   move.b   (a0)+,$FFFFFA2F.w   ;   restore USART Data

   move.b   (a0)+,$FFFFFA29.w   ;   restore USART Control
   move.b   (a0)+,$FFFFFA2B.w   ;   restore Receiver Status
   move.b   (a0)+,$FFFFFA2D.w   ;   restore Transmitter Status

   move.b   (a0)+,$FFFFFA13.w   ;   restore Interrupt Mask A
   move.b   (a0)+,$FFFFFA15.w   ;   restore Interrupt Mask B
   move.b   (a0)+,$FFFFFA0F.w   ;   restore In Service A
   move.b   (a0)+,$FFFFFA11.w   ;   restore In Service B
   move.b   (a0)+,$FFFFFA0B.w   ;   restore Pending A
   move.b   (a0)+,$FFFFFA0D.w   ;   restore Pending B
   move.b   (a0)+,$FFFFFA07.w   ;   restore Enable A
   move.b   (a0)+,$FFFFFA09.w   ;   restore Enable B

   move.b   (a0)+,$FFFFFA19.w   ;   restore Timer A Control
   move.b   (a0)+,$FFFFFA1B.w   ;   restore Timer B Control
   move.b   (a0)+,$FFFFFA1D.w   ;   restore Timer C+D Control

   move.w   (a7)+,sr         ;   restore Status Register
   movem.l   (a7)+,d0-a6         ;   restore registers

   rts


User avatar
tobe
Atari God
Atari God
Posts: 1459
Joined: Sat Jan 24, 2004 10:06 am
Location: Lyon, France
Contact:

Postby tobe » Thu Feb 03, 2005 4:20 pm

Thanks for this code !

It seems you don't change the timer C setup, you still use it @200hz, so there's no problems.
I got problems because i set it @50hz, and then i tried to restore values that was stored, hehe, bad idea :)
step 1: introduce bug, step 2: fix bug, step 3: goto step 1.


Social Media

     

Return to “680x0”

Who is online

Users browsing this forum: No registered users and 6 guests