English Amiga Board


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

 
 
Thread Tools
Old 12 March 2014, 13:26   #1
Brannigan
Registered User
 
Brannigan's Avatar
 
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
Question Saving and restoring register

I'm trying to learn 68k assembler and would need some help regarding memory access. I want to save the interrupt enable register, disable interrupts and when I'm done restore the original value. I have done it by storing the value in a data register and restoring from this register. That works fine.
But I want to store the value in the memory. Not that I need to. I have heaps of spare registers but it's good for learning. However, after reading back the value from memory, the value of d6 doesn't match the value i got when just storing INTENAR in a data register (i used a "move INTENAR,d5"). Can someone point out what I'm doing wrong?

Here is the code I'm using:

INTENA equ $dff09a
INTENAR equ $dff01c

; save
move.l #intena_old,a0
move.l INTENAR,(a0)

; restore
move.l intena_old,d6
move d6,INTENA

; data
EVEN
intena_old:
dc.l 0
Brannigan is offline  
Old 12 March 2014, 14:10   #2
Apollo
Registered User
 
Apollo's Avatar
 
Join Date: Sep 2008
Location: Germany
Age: 49
Posts: 139
If you want to _set_ the bits in INTENA you need to set the highest bit to 1.

for example enabling the vertical blank interrupt (bit #6) you have to write %1000000000100000 to INTENA => highest bit is set so all other set bits would be set in the register.
If you want to clear the vertical blank bit you would write %0000000000100000 => highest bit is cleared, so bit number 6 would be cleared.

Usually you write $7fff ( = %0111111111111111) to INTENA (clearing all bits) and then you OR your stored value (from INTENAR) with $8000 (=%1000000000000000) which would set the highest bit in the once stored value and write it back to INTENA.

I hope this explanation is understandable.

Last edited by Apollo; 12 March 2014 at 14:16.
Apollo is offline  
Old 12 March 2014, 14:21   #3
Apollo
Registered User
 
Apollo's Avatar
 
Join Date: Sep 2008
Location: Germany
Age: 49
Posts: 139
and: custom registers are 16 bit, so you should work only with 'move.w' in this case.
Apollo is offline  
Old 12 March 2014, 14:30   #4
Brannigan
Registered User
 
Brannigan's Avatar
 
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
This is just a small section of my code but I just wrote down here what was related to the save/restore problem I'm facing. After reading INTENAR I'm disabling the interrupts by doing move #$7fff,INTENA. And before restoring INTENA I'm setting bit 15 by OR:ing with $8000.
Brannigan is offline  
Old 12 March 2014, 14:38   #5
Brannigan
Registered User
 
Brannigan's Avatar
 
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
Quote:
Originally Posted by Apollo View Post
and: custom registers are 16 bit, so you should work only with 'move.w' in this case.
That solved the problem! Thanks for the help! Make sense why d6 looked so funny in the debug view. If I use move without a suffix, does it default to word? Or will the assembler try to guess what you want to accomplish? Is there any situations when you don't want to use the suffix? Personally, I think it's good to use because you can see what happens. And you might avoid mistakes that I just did...

Here is the modified code. Is there any ways to optimize the code?

INTENA equ $dff09a
INTENAR equ $dff01c

; save
move.l #intena_old,a0
move.w INTENAR,(a0)
move #$7fff,INTENA

; restore
move.w intena_old,d6
or #$8000,d6
move.w d6,INTENA

; data
EVEN
intena_old:
dc.w 0
Brannigan is offline  
Old 12 March 2014, 16:06   #6
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,866
Quote:
Originally Posted by Brannigan View Post
If I use move without a suffix, does it default to word?
Yes, but it's still generally good practice to always write the suffix. Makes things more readable.

Quote:
Originally Posted by Brannigan View Post
Is there any situations when you don't want to use the suffix?
A few; moveq is one, because it's always 32 bits. Same for lea. You simply can't use those in any other sizes, even though an assembler might actually accept the wrong suffixes.

Quote:
Originally Posted by Brannigan View Post
Is there any ways to optimize the code?
Not much, and unless the code is executed in a tight loop, it's not very important, either.

Code:
INTENA equ $dff09a
INTENAR equ $dff01c

; save
    move.w  INTENAR,intena_old
    move.w  #$7fff,INTENA

; restore
    move.w  intena_old,d6
    or.w    #$8000,d6
    move.w  d6,INTENA

; data

intena_old
    dc.w    0
Thorham is offline  
Old 12 March 2014, 16:07   #7
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,553
Quote:
Originally Posted by Brannigan View Post
If I use move without a suffix, does it default to word?
True, for those instructions which support this operation size.


Quote:
Is there any situations when you don't want to use the suffix?
When there is only a single operation size, like with MOVEQ, you can leave it out. Also you might want to leave out the suffix for branch instructions, when you want the assembler to generate the optimal size (in case your assembler supports that).


Quote:
Personally, I think it's good to use because you can see what happens. And you might avoid mistakes that I just did...
I agree.

EDIT: Thorham was faster... sorry for some double information.
phx is offline  
Old 12 March 2014, 16:31   #8
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
Quote:
Originally Posted by Brannigan View Post
If I use move without a suffix, does it default to word?
This is dependent on the used assembler and its (default) settings, there is no guarantee that it defaults to word! Most assemblers use word as default but DevPac uses .l if memory serves me right. So always write the suffix!

Quote:
Here is the modified code. Is there any ways to optimize the code?

INTENA equ $dff09a
INTENAR equ $dff01c

; save
move.l #intena_old,a0
move.w INTENAR,(a0)
move #$7fff,INTENA

; restore
move.w intena_old,d6
or #$8000,d6
move.w d6,INTENA

; data
EVEN
intena_old:
dc.w 0
Use an address register for the custom register so you can use indirect addressing which is faster and shorter, e.g.
lea $dff000,a6
move.w $1c(a6),d0 ; same as move.w $dff01c,d0

Also use pc-relative addressing which is shorter and faster as well:

move.l #intena_old,a0 -> lea intena_old(pc),a0

Same for the restore part:
move.w intena_old,d6 -> move.w intena_old(pc),d6

For things like startup codes optimising isn't really necessary but it's good to know what's possible.
StingRay is offline  
Old 12 March 2014, 17:59   #9
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,553
Quote:
Originally Posted by StingRay View Post
This is dependent on the used assembler and its (default) settings, there is no guarantee that it defaults to word! Most assemblers use word as default but DevPac uses .l if memory serves me right. So always write the suffix!
That would be fatal. Of course Devpac defaults to .w, like all M680x0 assemblers I have seen.
There are options to control the default inner and outer displacement size in 020+ addressing modes, though.

A ColdFire assembler certainly defaults to .l.
phx is offline  
Old 12 March 2014, 18:26   #10
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
Quote:
Originally Posted by phx View Post
That would be fatal. Of course Devpac defaults to .w, like all M680x0 assemblers I have seen.
There definitely were assemblers which defaulted to .l which made me waste quite some hours a long long time ago to when I was asked to debug someone's source and just couldn't get it to run properly because it expected .l as default.
StingRay is offline  
Old 13 March 2014, 01:58   #11
Brannigan
Registered User
 
Brannigan's Avatar
 
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
Quote:
Originally Posted by StingRay View Post
For things like startup codes optimising isn't really necessary but it's good to know what's possible.
Exactly! Everything is new and what I'm doing at the moment isn't very complicated (saving/restoring system status and setting up a copper list) but I bet it will get more complicated soon. I will look into PC relative addressing and using the LEA instruction later. Seems like i's more flexible. I'm using ASM-One 1.20.
Brannigan 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
Restoring an Amiga 3000... Ze_ro New to Emulation or Amiga scene 40 13 August 2012 15:31
Hints on restoring mouseball appreciated.. Turran support.Hardware 6 25 June 2012 16:10
Problem restoring HDF on a CF KONEY support.WinUAE 20 06 August 2009 21:55
[Bug]1st frame black when restoring gamestate NoX1911 support.WinUAE 11 22 July 2006 21:04
Action Replay IV - ParaDoX. Restoring screen problems redblade support.Apps 17 28 December 2004 08:33

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 10:05.

Top

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