![]() |
![]() |
#1 |
Registered User
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
|
![]()
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 |
![]() |
![]() |
#2 |
Registered User
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. |
![]() |
![]() |
#3 |
Registered User
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.
|
![]() |
![]() |
#4 |
Registered User
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.
|
![]() |
![]() |
#5 | |
Registered User
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
|
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 |
|
![]() |
![]() |
#6 | |
Computer Nerd
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 48
Posts: 3,866
|
Yes, but it's still generally good practice to always write the suffix. Makes things more readable.
Quote:
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 |
|
![]() |
![]() |
#7 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,553
|
True, for those instructions which support this operation size.
Quote:
Quote:
EDIT: Thorham was faster... sorry for some double information. |
||
![]() |
![]() |
#8 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
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:
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. ![]() |
|
![]() |
![]() |
#9 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,553
|
Quote:
![]() There are options to control the default inner and outer displacement size in 020+ addressing modes, though. A ColdFire assembler certainly defaults to .l. |
|
![]() |
![]() |
#10 |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
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.
|
![]() |
![]() |
#11 |
Registered User
Join Date: Jan 2014
Location: Melbourne, Australia
Posts: 40
|
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.
|
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
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 |
|
|