Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Fast way to rotate a char?
2017-01-04 08:32
Rudi
Account closed

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

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

Example:

a char (and the bits can be random):
10110010 byte 1..
11010110 byte 2.. etc..
00111001
01010110
11011010
10110101
00110011
10110100
after "rotation" (rows and columns are swapped):
11001101
01011000
10100111
11111111
00101000
01010101
11011010
00100110
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?

-Rudi
 
... 105 posts hidden. Click here to view all posts....
 
2017-01-04 09:06
Axis/Oxyron

Registered: Apr 2007
Posts: 91
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 09:07
ChristopherJam

Registered: Aug 2004
Posts: 1359
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)
        lda#$xx
        ora t{j}2,x
        ora t{j}3,y
        sta $xxxx


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


    ldx byte6
    ldy byte7
    for j in range(8)
        lda#$xx
        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 09:26
Rudi
Account closed

Registered: May 2010
Posts: 125
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 09:51
ChristopherJam

Registered: Aug 2004
Posts: 1359
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 09:51
Axis/Oxyron

Registered: Apr 2007
Posts: 91
Challenge accepted. ;o)
2017-01-04 10:13
Shadow
Account closed

Registered: Apr 2002
Posts: 355
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 11:12
Axis/Oxyron

Registered: Apr 2007
Posts: 91
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}
tya
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 12:24
Axis/Oxyron

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

Registered: Aug 2004
Posts: 1359
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 12:55
Cruzer

Registered: Dec 2001
Posts: 1048
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 | 13 - 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
Advanced
Users Online
Guests online: 269
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 No Bounds  (9.6)
6 Comaland 100%  (9.6)
7 Uncensored  (9.6)
8 The Ghost  (9.6)
9 Wonderland XIV  (9.6)
10 Bromance  (9.6)
Top onefile Demos
1 Party Elk 2  (9.7)
2 Cubic Dream  (9.6)
3 Copper Booze  (9.5)
4 Rainbow Connection  (9.5)
5 TRSAC, Gabber & Pebe..  (9.5)
6 Onscreen 5k  (9.5)
7 Dawnfall V1.1  (9.5)
8 Quadrants  (9.5)
9 Daah, Those Acid Pil..  (9.5)
10 Birth of a Flower  (9.5)
Top Groups
1 Booze Design  (9.3)
2 Nostalgia  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Graphicians
1 Sulevi  (10)
2 Mirage  (9.8)
3 Lobo  (9.7)
4 Mikael  (9.7)
5 Archmage  (9.7)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.054 sec.