26 May 2003, 14:46 | #1 |
I Identify as an Ewok
Join Date: Jul 2001
Location: North Lincolnshire
Age: 45
Posts: 2,356
|
How to write a Delay in Assembler
I've decided to play around with the LED to make it flash on and off using bit 1 of the CIA register $BFE001. It works great in debug when you step through the code but the problem is that the LED flashes too fast when you run it properly. It just flickers away instead of flashing. So basically how would you go about putting a decent delay in so that it flashes on then waits half a second before flashing off again. I tried a simple loop that counted down from 50 to 0 but that made no difference. I then tried 50000 but it still didn't slow the thing down. Darn assembler, it's too fast.
Any ideas? BTW I'm still a bit of a beginner with assembler so keep it simple. |
26 May 2003, 14:52 | #2 |
Registered User
Join Date: Sep 2002
Location: Germany
Posts: 349
|
Maybe this:
Bynary count: clr.b d0 loop: move.b d0,(a2) ;supposing a2 is address where LEDs are represented add.b #1,d0 move.l #100,d2 bsr pause bra loop ;Pause function (assuming 4 us for each instr.) ;holds execution for as many ms as is the value of d2 pause: move.l #11,d3 innerloop: sub.l #1,d3 bne innerloop ; 8 * 11 = 84 sub.l #1,d2 nop bne pause ; 84 + 16 = 100 ret source: http://www.experts-exchange.com/Prog..._20078051.html |
26 May 2003, 15:09 | #3 |
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,505
|
<code snipped removed>
urghh... |
26 May 2003, 16:13 | #4 | |
I Identify as an Ewok
Join Date: Jul 2001
Location: North Lincolnshire
Age: 45
Posts: 2,356
|
Quote:
I'll try that code out Amiger but it looks a bit long-winded. I was hoping for some sort of Wait instruction. I guess there isn't one. |
|
26 May 2003, 17:44 | #5 |
Junior Member
Join Date: Apr 2001
Location: In the cellar. With your mum.
Age: 49
Posts: 404
|
Use VBlanks, but don't ask me how (it's been over 10 years...)
Basically a vblank occurs when the monitor strobe reaches the last line on the screen. Make your code wait until it reaches the last line (guess: line 255) and then return to the start of the loop. This will guarantee perfect timing. Note that Vblanks occur every 50th of a second, so maybe you should just keep track of vblanks and blink the led after 50 vblanks (ie after 1 second). Ofcourse, if the goal is to have other code running at the same time, you could either put all the code within a vblank loop, or use interrupts (ie assign some code to an interrupt that keeps track of the time, and makes the led blink whenever a second has passed). |
26 May 2003, 22:03 | #6 |
2 contact me: email only!
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,182
|
Why you would want to do this is beyond me but here you go:
move.l #10-1,d0 ;flash 10 times .flash bchg #1,$bfe001 bsr _wait dbf d0,.flash rts _wait move.l #50-1,d0 ;waits 1 second on PAL .wait bsr _waitvb dbf d0,.wait rts _waitvb ;waits 1/50th of a second .1 btst #0,(_custom+vposr+1) beq .1 .2 btst #0,(_custom+vposr+1) bne .2 rts Formatting is a bit up the spout as the system removes all the indenting - hope you can follow it! |
26 May 2003, 22:17 | #7 |
Global Moderator
Join Date: Mar 2001
Location: UK
Age: 46
Posts: 6,160
|
You can use the CODE tag to preserve formatting:
Code:
move.l #10-1,d0 ;flash 10 times .flash bchg #1,$bfe001 bsr _wait dbf d0,.flash rts _wait move.l #50-1,d0 ;waits 1 second on PAL .wait bsr _waitvb dbf d0,.wait rts _waitvb ;waits 1/50th of a second .1 btst #0,(_custom+vposr+1) beq .1 .2 btst #0,(_custom+vposr+1) bne .2 rts |
26 May 2003, 23:22 | #8 |
Junior Member
Join Date: Apr 2001
Location: In the cellar. With your mum.
Age: 49
Posts: 404
|
Holy cow
Not trying to vaunt my skills here, but dang that's still easy to understand.
Is other asm code (86x, PPC) as easy tor read/write, or is this only on Amiga (tm) again? |
27 May 2003, 00:23 | #9 | |
I Identify as an Ewok
Join Date: Jul 2001
Location: North Lincolnshire
Age: 45
Posts: 2,356
|
Brilliant. It works perfectly. I had to change a few things to get it to compile under Devpac 3 but it worked in the end. I also reduced the wait from 50 frames down to 30 frames to speed up the blinking. Quote:
Here is the finished executable program which makes you think your Amiga has crashed: Thanks for your help. |
|
27 May 2003, 03:14 | #10 | |
2 contact me: email only!
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,182
|
Re: Holy cow
Quote:
I cannot follow C64 code either, it looks terrible. 68000 is just so elegant if well written... BTW my example above was just typed out quickly without testing it, so it behaves a little strangely as d0 is destroyed in the subroutines - should use a different register like d1/d2 or save the value... This should fix it: Code:
_wait move.l d0,-(sp) ;save d0 move.l #50-1,d0 ;waits 1 second on PAL .wait bsr _waitvb dbf d0,.wait move.l (sp)+,d0 ;restore d0 rts |
|
27 May 2003, 08:03 | #11 | |
Registered User
Join Date: Sep 2002
Location: Germany
Posts: 349
|
Quote:
|
|
22 July 2003, 02:39 | #12 | ||
Zone Friend
|
Quote:
Quote:
Definitely no experts in (simple) mathematics (but I think they're going to beat me in calculus without problems ) |
||
22 July 2003, 08:16 | #13 |
Registered User
Join Date: Sep 2002
Location: Germany
Posts: 349
|
Maths isn't easy to understand sometimes... I think there's a tricky solution way for this formula...
Seems to be a competent web page I found there, sorry, Steve... |
22 July 2003, 14:24 | #14 | |
I Identify as an Ewok
Join Date: Jul 2001
Location: North Lincolnshire
Age: 45
Posts: 2,356
|
Quote:
|
|
26 April 2018, 14:59 | #15 |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
This is my 2 cents code, it waits for 3 seconds:
Code:
START: move.l #(50*3)-1,d0 ; blank occurs every 1/50th seconds, ; therefore must multiply with x seconds ; (value in the example is set to 3) LOOP: .v_blank move.l $dff004, d1 and.l #$0001ff00,d1 cmp.l #255<<8,d1 bne.s .v_blank .v_blank_after move.l $dff004, d1 and.l #$0001ff00,d1 cmp.l #255<<8,d1 beq.s .v_blank_after dbra d0,LOOP rts |
26 April 2018, 16:48 | #16 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
Poor DOS, nobody likes dos.library
Code:
dos.library/Delay dos.library/Delay NAME Delay -- Delay a process for a specified time SYNOPSIS Delay( ticks ) D1 void Delay(ULONG) FUNCTION The argument 'ticks' specifies how many ticks (50 per second) to wait before returning control. INPUTS ticks - integer BUGS Due to a bug in the timer.device in V1.2/V1.3, specifying a timeout of zero for Delay() can cause the unreliable timer & floppy disk operation. This is fixed in V36 and later. |
26 April 2018, 22:43 | #17 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
It always depends on what you want to do.
OS-friendly code: use timer.device or dos.library/Delay. Take over the system: wait for raster-lines, VERTB-interrupts or use the CIA timers In any case, NEVER write a busy loop, which depends on CPU speed! |
27 April 2018, 02:26 | #18 |
Zone Friend
Join Date: Apr 2005
Location: London
Posts: 1,176
|
In this case, the delay is almost 15 years.
|
27 April 2018, 02:31 | #19 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
Wow, didn't notice that ...
|
22 May 2018, 03:37 | #20 |
Knight Of The Kingdom
Join Date: Feb 2016
Location: It's a bald world!
Posts: 179
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
output delay? | jharrison | support.WinUAE | 16 | 01 February 2009 23:16 |
input delay | hexaae | support.WinUAE | 6 | 15 January 2009 13:04 |
Keyboard delay | glue | support.WinUAE | 4 | 09 January 2008 22:54 |
Minimize delay in WinUAE? | Photon | support.WinUAE | 7 | 06 December 2005 21:19 |
Print Delay | Unregistered | support.WinUAE | 0 | 11 August 2002 22:02 |
|
|