Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user Sharakmir ! (Registered 2017-12-13) You are not logged in 
CSDb User Forums

Forums > C64 Coding > Fast way to rotate a char?
2017-01-04 09:32

Registered: May 2010
Posts: 100
Fast way to rotate a char?

Im not talking about rol or ror, but swap bits so that they are rotated 90 degrees:


a char (and the bits can be random):
10110010 byte 1..
11010110 byte 2.. etc..
after "rotation" (rows and columns are swapped):
is it possible to use lookup tables for this or would that lookup table be too big?
or other lookuptable for getting and setting bits?

... 99 posts hidden. Click here to view all posts....
2017-01-04 10:06

Registered: Apr 2007
Posts: 83
Depends on resolution. In multicolor/2x2 you can do it with 4 bit-tables, just like you would do a 2xn chunky-FX. In hires things get complicated. The shift/rol method is a good starting point. Perhaps the Amiga C2P techniques based on merges would be faster. Not sure, yet.
2017-01-04 10:07

Registered: Aug 2004
Posts: 707
Sounds like a coding challenge!

Should be doable with 64 tables and 464 cycles, with neither source nor destination in zero page. But that's a lot of RAM.. Oswald's concept's a lot saner. Maybe fastest routine in under 4k code+tables would be interesting to hunt for?

    ldx byte0
    ldy byte1
    for j in range(8)
        lda t{j}0,x
        ora t{j}1,y
        sta $xxxx

    ldx byte2
    ldy byte3
    for j in range(8)
        ora t{j}2,x
        ora t{j}3,y
        sta $xxxx

    ldx byte4
    ldy byte5
    for j in range(8)
        ora t{j}4,x
        ora t{j}5,y
        sta $xxxx

    ldx byte6
    ldy byte7
    for j in range(8)
        ora t{j}6,x
        ora t{j}7,y
        sta $xxxx
(table ij copies a bit from location i to location j, clearing the rest)
2017-01-04 10:26

Registered: May 2010
Posts: 100
Interesting ideas. I think I understand Oswalds code.
Quoting ChristopherJam
Sounds like a coding challenge!
Feel free to make it a coding challenge.
2017-01-04 10:51

Registered: Aug 2004
Posts: 707
Haha, googling C2P leads back to csdb (Identify this doughnut).

Looks like Michiel's swapping-two-address-bits-at-a-time technique at http://stackoverflow.com/questions/1667591/rotating-a-bitmap-90.. ?

Going to have to think about efficient ways to swap low nybble of one byte with high nybble of another now..
2017-01-04 10:51

Registered: Apr 2007
Posts: 83
Challenge accepted. ;o)
2017-01-04 11:13

Registered: Apr 2002
Posts: 314
Is it just my spatial thinking that is a bit off now, or is your original example wrong? To me it doesn't seem like a correct 90 degree rotation is done, it looks like it's mirrored as well?
2017-01-04 12:12

Registered: Apr 2007
Posts: 83
Got a first version running using Amiga style merges (328 cycles). Code still looks ugly and unoptimized.

The used tables are 256 bytes each and filled as follows:

lsrtab1: and #$aa, lsr
lsrtab2: and #$cc, lsr, lsr
lsrtab4: lsr, lsr, lsr, lsr
asltab1: and #$55, asl
asltab2: and #$33, asl, asl
asltab4: asl, asl, asl, asl

Code is using Dreamass-style macros.
src & dst are memory locations of the source and dest char.
tmp1 & tmp2 are 8 byte zp-arrays each.

;28 cycles mem->zp
;26 cycles zp->zp
;28 cycles zp->mem
#macro MERGE(src1, src2, mask1, mask2, bittab1, bittab2, dst1, dst2)
lax {src1}
ldy {src2}
and #{mask1}
ora {bittab1},y
sta {dst1}
and #{mask2}
ora {bittab2},x
sta {dst2}

.MERGE(src+0, src+1, $aa, $55, lsrtab1, asltab1, tmp1+0, tmp1+1)
.MERGE(src+2, src+3, $aa, $55, lsrtab1, asltab1, tmp1+2, tmp1+3)
.MERGE(src+4, src+5, $aa, $55, lsrtab1, asltab1, tmp1+4, tmp1+5)
.MERGE(src+6, src+7, $aa, $55, lsrtab1, asltab1, tmp1+6, tmp1+7)
.MERGE(tmp1+0, tmp1+2, $cc, $33, lsrtab2, asltab2, tmp2+0, tmp2+2)
.MERGE(tmp1+1, tmp1+3, $cc, $33, lsrtab2, asltab2, tmp2+1, tmp2+3)
.MERGE(tmp1+4, tmp1+6, $cc, $33, lsrtab2, asltab2, tmp2+4, tmp2+6)
.MERGE(tmp1+5, tmp1+7, $cc, $33, lsrtab2, asltab2, tmp2+5, tmp2+7)
.MERGE(tmp2+0, tmp2+4, $f0, $0f, lsrtab4, asltab4, dst+0, dst+4)
.MERGE(tmp2+1, tmp2+5, $f0, $0f, lsrtab4, asltab4, dst+1, dst+5)
.MERGE(tmp2+2, tmp2+6, $f0, $0f, lsrtab4, asltab4, dst+2, dst+6)
.MERGE(tmp2+3, tmp2+7, $f0, $0f, lsrtab4, asltab4, dst+3, dst+7)

The code still looks pretty unoptimized. I think reordering merges can save some loads/stores to the tmp-arrays. Also SAX or AXS could come handy here.

If you are interested in the basic concept of this kind of C2p read here: http://www.lysator.liu.se/~mikaelk/doc/c2ptut/
2017-01-04 13:24

Registered: Apr 2007
Posts: 83
Damn, should have asked Graham. He used nearly exactly my C2P code in the hidden-part of Deus Ex Machina.
2017-01-04 13:27

Registered: Aug 2004
Posts: 707
Sweet. I thought I had an approach that would take ~360 cycles, but it appears I've made a mistake somewhere, so it's both slower than yours *and* broken..

(was going to do a three skews rotation, with ROL tables for the first and third passes, and swap macros for shuffling bits down in the middle pass)

I'll ponder more after dinner.
2017-01-04 13:55

Registered: Dec 2001
Posts: 920
Wow, that's some sick, slick code, Axis. No way I can understand it right now, but I'll look into it if I ever get the need. Did we determine the resolution btw? I'm guessing singlecolor, since you can't do a lossless rotation of a multicolor char, unless it's 2x2.
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Users Online
E$G/I-IokutO ForcE
Guests online: 41
Top Demos
1 Uncensored  (9.7)
2 Edge of Disgrace  (9.7)
3 Coma Light 13  (9.6)
4 The Shores of Reflec..  (9.6)
5 Lunatico  (9.6)
6 Comaland 100%  (9.5)
7 Incoherent Nightmare  (9.5)
8 Wonderland XII  (9.5)
9 Comaland  (9.5)
10 Wonderland XIII  (9.5)
Top onefile Demos
1 Pandemoniac Part 2 o..  (9.6)
2 FMX Music Demo  (9.6)
3 Daah, Those Acid Pil..  (9.5)
4 Dawnfall V1.1  (9.5)
5 Synthesis  (9.5)
6 Dawnfall  (9.4)
7 Treu Love [reu]  (9.4)
8 Field Sort  (9.4)
9 KAOS 64  (9.3)
10 One-Der  (9.2)
Top Groups
1 Oxyron  (9.4)
2 Booze Design  (9.4)
3 Censor Design  (9.3)
4 Crest  (9.3)
5 The Judges  (9.3)
Top Graphicians
1 Mirage  (9.8)
2 JonEgg  (9.7)
3 Archmage  (9.7)
4 Jok  (9.7)
5 Veto  (9.7)

Home - Disclaimer
Copyright © No Name 2001-2017
Page generated in: 1.081 sec.