I've been trying to implement a version of _MemSet which would accept a 16-bit rather than 8-bit value in ez80 assembly (for 16-bit graphics), but I can't figure out how to efficiently copy the 16-bit values over to the memory addresses, seeing as AFAIK there are no 16-bit registers on the 84+CE. Does anyone know what the best way to do this is?
There is no efficient way to do it; the silly solution is really the only way :p
Untested: http://www.rafb.me/results/TTUU4u95.html
MateoConLechuga wrote:
There is no efficient way to do it; the silly solution is really the only way :p


That's kind of annoying; too bad that the .sil instruction modifier doesn't follow the naÏve assumption of how it works and instead just messes up your code :p

Runer112 wrote:


Cool! I never knew about ldir.
Also do you mind if I use this in an open-source library? Would you prefer GPL?
Since I made the code publicly available with the intention of anyone being able to use it in whatever context, it wouldn't be right to slap a GPL (copyleft) license on it. If you wanted to explicitly add a license to it, The Unlicense seems appropriate.
Wait; shouldn't ld.s be able to do this sort of thing? It loads from 24-bit memory addresses, but only loads 16 bits of data, thus making the code significantly less complicated (and if this is the case, sorry about my question being poorly worded)
goose121 wrote:
Wait; shouldn't ld.s be able to do this sort of thing? It loads from 24-bit memory addresses, but only loads 16 bits of data, thus making the code significantly less complicated (and if this is the case, sorry about my question being poorly worded)

Yes, you can disable interrupts and change mbase. It's generally not any faster though; although you can test it if you want. (I imagine it will be slower actually).
I think I've found a fairly nice way of doing this, that's relatively short and readable; the only thing I'm not really as sure about is performance, because I'm not familiar with the performance characteristics of the instructions

Code:

; Args:
;  hl: dest pointer
;  de: value (deh is ignored)
;  bc: count of **VALUES** to be written (NOT BYTES)
; Returns:
;  de: value
;  hl: dest + 2 * count
_memset16:
        ld (hl), d
        inc hl
        ld (hl), e
        cpi
        jp pe, _memset16        ; pe == bc was non-zero
        ret
Could you do a 24 bit load with HL but only increment HL by two and then manually do the last two bytes?
An ldir-based approach has more overhead than your code, goose121, but has much better write speed once it gets going. For a size of 1 or 2, the performance difference is a wash. But for anything more, ldir becomes significantly faster.

Here's an ldir-based routine with the same inputs as yours:

Code:
; Args:
;  hl: dest pointer
;  de: value (deu is ignored)
;  bc: count of **VALUES** to be written (NOT BYTES)
_memset16:
    ld (hl),e
    inc hl
    ld (hl),d
    cpi
    ret po
    ex de,hl
    ld hl,-2
    add hl,de
    sla c
    rl b
    ldir
    ret


And here's a performance analysis (assuming the code is running in and setting RAM): https://docs.google.com/spreadsheets/d/1RXcLQeM45hNBisYvZfzsOMc4g0GDSSYhm-dIzBdh938/edit?usp=sharing
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
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 vote in polls in this forum

 

Advertisement