6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 10:52 pm

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: Wasting time
PostPosted: Sun Nov 05, 2023 7:48 am 
Offline
User avatar

Joined: Fri Nov 05, 2021 1:06 pm
Posts: 20
I keep getting cycle times for short delay wrong. So I finally went for some macros and helper subroutines. Certainly done thousands of times before. Perhaps useful, perhaps incorrect, just let me know ;-)

edit:

Code:
;   nop.inc
;------------------------------------------------------------------------------
;   remarks:
;       - nop1 is possible on a 65c02 using unused opcodes
;         (see http://www.6502.org/tutorials/65c02opcodes.html)
;------------------------------------------------------------------------------
.macro nop2
    nop                     ; 2
.endmacro

.macro nop3
    jmp *+3                 ; 3
.endmacro

.macro nop4
    nop                     ; 2
    nop                     ; 2
.endmacro

.macro nop5
    nop                     ; 2
    jmp *+3                 ; 3
.endmacro

.macro nop6
    nop                     ; 2
    nop                     ; 2
    nop                     ; 2
.endmacro

.macro nop7
    php                     ; 3     
    plp                     ; 4
.endmacro

.macro nop8
    nop                     ; 2
    nop                     ; 2
    nop                     ; 2
    nop                     ; 2
.endmacro

.macro nop9
    php                     ; 3     
    plp                     ; 4
    nop                     ; 2
.endmacro

.macro nop10
    php                     ; 3     
    bit tmp0                ; 3
    plp                     ; 4
.endmacro

.macro nop11
    php                     ; 3     
    nop                     ; 2
    nop                     ; 2
    plp                     ; 4
.endmacro

.macro nop12
    jsr _nop12
.endmacro

.macro nop13
    php                     ; 3     
    nop                     ; 2
    nop                     ; 2
    nop                     ; 2
    plp                     ; 4
.endmacro

.macro nop14
    jsr _nop14
.endmacro

.macro nop15
    php                     ; 3     
    nop                     ; 2
    nop                     ; 2
    nop                     ; 2
    nop                     ; 2
    plp                     ; 4
.endmacro

.macro nop16
    jsr _nop16
.endmacro

.macro nop17
    php                     ; 3     
    plp                     ; 4
    php                     ; 3     
    bit tmp0                ; 3
    plp                     ; 4
.endmacro

.macro nop18
    jsr _nop18
.endmacro

.macro nop19
    jsr _nop19
.endmacro

.macro nop20
    jsr _nop20
.endmacro


Code:
;   nop.s
_nop20:
    nop                     ; 2
_nop18:
    nop                     ; 2
_nop16:
    nop                     ; 2
_nop14:
    nop                     ; 2
_nop12:
    rts                     ; 6 + 6

_nop19:
    php                     ; 3     
    plp                     ; 4
    rts                     ; 6 + 6


Code:
;    delay.s
;------------------------------------------------------------------------------
;   nice hack, changes N, Z and C 
;
;   credits:
;       - https://www.pagetable.com/?p=669

_delay20:
    .byte $c9               ; 2     cmp #
_delay19:
    .byte $c9               ; 2     cmp #
_delay18:
    .byte $c9               ; 2     cmp #
_delay17:
    .byte $c9               ; 2     cmp #
_delay16:
    .byte $c9               ; 2     cmp #
_delay15:
    .byte $c5               ; 3     cmp zp   
    nop                     ; 2
    rts                     ; 6 + 6


Last edited by tius on Mon Nov 06, 2023 6:34 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Sun Nov 05, 2023 8:24 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
For longer delays, see Bruce's ingenious one at viewtopic.php?p=92070#p92070 .

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Sun Nov 05, 2023 9:01 am 
Offline
User avatar

Joined: Fri Nov 05, 2021 1:06 pm
Posts: 20
GARTHWILSON wrote:
For longer delays, see Bruce's ingenious one at viewtopic.php?p=92070#p92070 .

Amazing!


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Sun Nov 05, 2023 10:54 am 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
For extra-long time wasting, I've been using the following implementation: https://github.com/bbbradsmith/6502vdelay - it's pretty accurate, but at some point I felt it would be better to redesign my code to use VIA timers so that my MPU can do something meaningful until the interval passes. :)

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Sun Nov 05, 2023 10:27 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
For accurate delays, reference to a hardware timer is better.  If you have a VIA in your system, you have two timers at your disposal with potentially sub-microsecond resolution, and interrupt capabilities.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Mon Nov 06, 2023 6:11 am 
Offline
User avatar

Joined: Fri Nov 05, 2021 1:06 pm
Posts: 20
Many thanks to everyone for the good advice! I have edited the post accordingly.


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Mon Nov 06, 2023 8:17 am 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 591
Location: Michigan, USA
Here's an untested 65C02 "cycle-accurate" delay sub-system I'd like to use for serial protocol experiments. The minimum delay is 24 cycles and you can adjust the upper limit by changing the number of cycles used in the timing loop (the 'dloop' constant). Determine the loop size by multiplying the largest delay you require (in microseconds) by the clock (1, 2, 3, 4, 8, etc.) then divide by 65536. Use the integer result + 1 for the 'dloop' value.

Cheerful regards, Mike

Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;    file: serial_test.s                                      ~
;  author: Mike McLaren, K8LH                                 ~
;    date: 06-Nov-23 (last rev 09-Nov-23)                     ~
;                                                             ~
;                                                             ~
;     asm: CA65 v2.13.3                                       ~
;                                                             ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.debuginfo +
.setcpu "65C02"

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  65C02 delayCy() sub-system macro inserts 3 instructions    ~
;  and calls the 'uloop' 16-bit counter subroutine.           ~
;                                                             ~
;  24 cycles minimum to dloop*65536+23 cycles maximum.        ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.define cyc .byte $03       ; new 65C02 single-cycle opcode

clock   := 8                ; 1, 2, 3, 4, 8, etc. (clock)
usecs   := clock            ; cycles/microsecond multiplier
msecs   := clock*1000       ; cycles/millisecond multiplier
dloop   := 13               ; timing loop size (minimum 9)

.macro  delayCy cycles
       .if (cycles < 24) || (cycles > dloop*65536+23)
         .error "delayCy() range error"
       .endif
        lda #>(((cycles-24)/dloop)+1).mod 256 ;             (2)
        ldy #<(((cycles-24)/dloop)+1).mod 256 ;             (2)
        jsr uloop-((cycles-24).mod dloop)     ;             (6)
.endmac

.org $F000
;**************************************************************
;  example delayCy() code

port_b  := $6100

start:
        delayCy(100*msecs)  ; delay 100-msecs
test2:
        delayCy(8*usecs-13) ; 8-usecs minus 13 cycles
        lda port_b          ;                               (4)
        eor #%00000001      ; toggle b0 bit                 (2)
        sta port_b          ; precise 125-kHz intervals     (4)
        bra test2           ;                               (3)

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  65C02 delayCy() sub-system 16-bit counter subroutine       ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       .repeat (dloop-1)    ; insert all (cycles-24)%dloop
        cyc                 ; single-cycle entry points
       .endrep              ;
;       cyc                 ; (cycles-24)%dloop == 8 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 7 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 6 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 5 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 4 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 3 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 2 entry  (1)
;       cyc                 ; (cycles-24)%dloop == 1 entry  (1)
uloop:
        dey                 ; decrement 16-bit lo byte      (2)
        bne uloop-dloop+5   ; zero? no, branch, else        (2)(3)
        dec A               ; decrement 16-bit hi byte      (2)
        bne uloop-dloop+9   ; zero? no, branch, else        (2)(3)
        rts                 ; exit                          (6)
;
;  alternative: Bruce Clark's single-loop 16-bit counter
;
        cpy #1              ; set or clear carry            (2)
        dey                 ; decrement lo byte             (2)
        sbc #0              ; decrement hi byte, or not     (2)
        bcs uloop-dloop+9   ; done? no, branch, else        (2)(3)
        rts                 ; exit                          (6)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.segment "VECTS"
.org $FFFA
       .word start          ; NMI
       .word start          ; RESET
       .word start          ; IRQ



Last edited by Michael on Thu Nov 09, 2023 4:08 pm, edited 10 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Mon Nov 06, 2023 9:09 am 
Offline
User avatar

Joined: Fri Nov 05, 2021 1:06 pm
Posts: 20
Dear Mike, I have not used the Kowalski Simulator yet. But I have had good experiences with a simple logic analyzer to check the serial timing. If I have understood your setup correctly, you have full control over the external clock on your hardware and could perhaps do the analysis via a free AVR port?


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Tue Nov 07, 2023 11:59 pm 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 591
Location: Michigan, USA
I took a stab at a "cycle accurate" short delay macro below (still using 65C02 single-cycle nop's). I wonder what a "cycle-accurate" version using straight 6502 code (minus the impossible 1-cycle delay) would look like?

Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;    file: serial_test_2.s                                    ~
;  author: Mike McLaren, K8LH                                 ~
;    date: 07-Nov-23                                          ~
;                                                             ~
;                                                             ~
;     asm: CA65 v2.13.3                                       ~
;                                                             ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.debuginfo +
.setcpu "65C02"

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  65C02 "short delay" macro generates 0 to 9 bytes per call  ~
;  and produces 'cycle-accurate' delays of 0 to 1285 cycles.  ~
;                                                             ~
;  1285.00-usecs @  1-MHz      () destroys X register         ~
;   642.50-usecs @  2-MHz                                     ~
;   321.25-usecs @  4-MHz                                     ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.define cyc  .byte $03      ; new 65C02 single-cycle opcode

clock   := 2                ; 1, 2, 4, 8, 16 (MHz clock)
usecs   := clock            ; cycles/microsecond multiplier

.macro  delay cycles
       .local loop
       .if (cycles < 0) || (cycles > 1285)
         .error "delay() range error"
       .endif
       .if (cycles > 5)
          ldx #(((cycles-1)/5).mod 256)  ;                  (2)
          loop:
            dex             ;                               (2)
            bne loop        ;                               (2)(3)
         .repeat ((cycles-1) .mod 5)
            cyc             ; 65C02 single-cycle 'nop'      (1)
         .endrep            ;
       .else
         .repeat (cycles)
            cyc             ; 65C02 single-cycle 'nop'      (1)
         .endrep
       .endif
.endmac

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


.org $F000
;**************************************************************
;   in-line short delay code examples

port_b  := $6100

start:
        delay(100*usecs)    ; 100-usecs
        delay(32)           ; 32 cycles
test2:
        delay(20*usecs-13)  ; 20-usecs minus 13 cycles
        lda port_b          ;                               (4)
        eor #%00000001      ; toggle b0 bit                 (2)
        sta port_b          ; precise 50-kHz intervals      (4)
        bra test2           ;                               (3)


.segment "VECTS"
.org $FFFA
        .word start         ; NMI
        .word start         ; RESET
        .word start         ; IRQ



Last edited by Michael on Wed Nov 08, 2023 3:43 pm, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Wed Nov 08, 2023 12:02 pm 
Offline
User avatar

Joined: Fri Nov 05, 2021 1:06 pm
Posts: 20
Michael wrote:
I took a stab at a "cycle accurate" short delay macro below (still using 65C02 single-cycle nop's). I wonder what a "cycle-accurate" version using straight 6502 code (minus the impossible 1-cycle delay) would look like?

Hi Mike, I was pointed to https://bisqwit.iki.fi/utils/nesdelay.php (see post #1). It looks to me as if there is already an optimal solution for every kind of delay. I have therefore switched to other ways of wasting time in the meantime ;-)

Just a small note: It might be useful to use a separate macro for 65c02 single-cycle-nop and make it configurable. For example, my system uses $03 to access the extended memory.


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Wed Nov 08, 2023 1:02 pm 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 591
Location: Michigan, USA
tius wrote:
Michael wrote:
I took a stab at a "cycle accurate" short delay macro below (still using 65C02 single-cycle nop's). I wonder what a "cycle-accurate" version using straight 6502 code (minus the impossible 1-cycle delay) would look like?

Hi Mike, I was pointed to https://bisqwit.iki.fi/utils/nesdelay.php (see post #1). It looks to me as if there is already an optimal solution for every kind of delay. I have therefore switched to other ways of wasting time in the meantime ;-)

Just a small note: It might be useful to use a separate macro for 65c02 single-cycle-nop and make it configurable. For example, my system uses $03 to access the extended memory.

That site is pretty neat but it gave me a macro with over 113,000 lines.


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Wed Nov 08, 2023 6:17 pm 
Offline
User avatar

Joined: Fri Nov 05, 2021 1:06 pm
Posts: 20
Michael wrote:
That site is pretty neat but it gave me a macro with over 113,000 lines.

This is what happens when computers write code instead of humans :D


Top
 Profile  
Reply with quote  
 Post subject: Re: Wasting time
PostPosted: Wed Nov 08, 2023 7:08 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
tius wrote:
Michael wrote:
That site is pretty neat but it gave me a macro with over 113,000 lines.

This is what happens when computers write code instead of humans :D

...or the code is written by humans who don’t know assembly language.  :shock:

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 19 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: