Omnimaga: The Coders Of Tomorrow
Welcome, Guest. Please login or register.
 
Omnimaga: The Coders Of Tomorrow
22 May, 2013, 08:18:36 *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   home   news downloads projects tutorials misc forums rules new posts irc about Login Register  
+-OmnomIRC

You must Register, be logged in and have at least 40 posts to use this shout-box! If it still doesn't show up afterward, it might be that OmnomIRC is disabled for your group or under maintenance.

Note: You can also use an IRC client like mIRC, X-Chat or Mibbit to connect to an EFnet server and #omnimaga.

Pages: 1 [2] 3 4 5   Go Down
  Print  
Author Topic: Prizm Useful Routines -- post here! -  (Read 3978 times) Bookmark and Share
0 Members and 1 Guest are viewing this topic.
calc84maniac
Epic z80 roflpwner
Coder Of Tomorrow
LV11 Super Veteran (Next: 3000)
*
Offline Offline

Gender: Male
Last Login: 20 May, 2013, 21:27:24
Date Registered: 28 August, 2008, 05:09:05
Location: Right behind you.
Posts: 2735


Total Post Ratings: +373

View Profile
« Reply #15 on: 27 May, 2011, 00:58:18 »
0

Alright I have a conversion from C to asm. It is get pixel and is as fast as possible and can be no more optimized. Unless gcc automatically handles the zero extension which I'll have to check.
Is it just me or does this routine not handle multiplying by 2 to index the array?
Logged

"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman
z80man
Casio Traitor
LV8 Addict (Next: 1000)
********
Offline Offline

Gender: Male
Last Login: 04 September, 2012, 19:42:33
Date Registered: 26 December, 2010, 10:02:50
Location: City 17
Posts: 966


Total Post Ratings: +83

View Profile
« Reply #16 on: 27 May, 2011, 01:52:55 »
0

Alright I have a conversion from C to asm. It is get pixel and is as fast as possible and can be no more optimized. Unless gcc automatically handles the zero extension which I'll have to check.
Is it just me or does this routine not handle multiplying by 2 to index the array?
That is a very valid concern there. I was just umm testing you to see if you would umm catch it Tongue Unless your image buffer was 256 colors there would be a failure. Routine now fixed. I'll disassemble the results to see how gcc handles inline functions so I can optimize it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
short GetPixel(short x, short y)
{
    MOV.W (width),R2          ;get screen width of 384 * 2
    MOV.L (VRAM),R3           ;get VRAM buffer location, usually 0xA8000000, but uses pre-initialized global variable just in case.
    MULU.W R2,R5              ;unsigned 16 bit multiplication
    SHLL R4                   ;single left bit shift which multiplies R4 by 2. Also used to fill slot before the MAC load
    STS MACL,R2               ;load result of multiplication into R2
    ADD R3,R2                 ;add VRAM base address to resulting y value
    ADD R4,R2                 ;add modified x value to to the already added y and VRAM base
    MOV.W @R2,R0              ;Load word from what's at R2 into R0. Sign extension
    RTS                       ;delayed branch and return. Note, R0 not touched because the result of the previous instruction is still be loaded
    EXTU.W R0                 ;safe to touch R0 now. Get rid of that pesky sign extension. May remove later if gcc handles this step on its own
    align.4
    width: word 384 * 2
    VRAM: long VRAM_address   ;global variable that was initialized earlier to correct address.
}
Logged


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)
calc84maniac
Epic z80 roflpwner
Coder Of Tomorrow
LV11 Super Veteran (Next: 3000)
*
Offline Offline

Gender: Male
Last Login: 20 May, 2013, 21:27:24
Date Registered: 28 August, 2008, 05:09:05
Location: Right behind you.
Posts: 2735


Total Post Ratings: +373

View Profile
« Reply #17 on: 27 May, 2011, 04:20:40 »
0

I made a little optimization that takes advantage of the move with offset:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
short GetPixel(short x, short y)
{
    MOV.W (width),R2          ;get screen width of 384 * 2
    MOV.L (VRAM),R0           ;get VRAM buffer location, usually 0xA8000000, but uses pre-initialized global variable just in case.
    MULU.W R2,R5              ;unsigned 16 bit multiplication
    SHLL R4                   ;single left bit shift which multiplies R4 by 2. Also used to fill slot before the MAC load
    STS MACL,R2               ;load result of multiplication into R2
    ADD R4,R2                 ;add modified x value to to the scaled y offset
    MOV.W @(R0,R2),R0         ;Load word from R2 offsetted from the VRAM base into R0. Sign extension
    RTS                       ;delayed branch and return. Note, R0 not touched because the result of the previous instruction is still be loaded
    EXTU.W R0                 ;safe to touch R0 now. Get rid of that pesky sign extension. May remove later if gcc handles this step on its own
    align.4
    width: word 384 * 2
    VRAM: long VRAM_address   ;global variable that was initialized earlier to correct address.
}
Logged

"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman
z80man
Casio Traitor
LV8 Addict (Next: 1000)
********
Offline Offline

Gender: Male
Last Login: 04 September, 2012, 19:42:33
Date Registered: 26 December, 2010, 10:02:50
Location: City 17
Posts: 966


Total Post Ratings: +83

View Profile
« Reply #18 on: 27 May, 2011, 08:41:10 »
0

Nice job catching that there calc84. Sometimes I forget possible optimizations when I don't have the full instruction set in front of me.
btw on the instructions that you replaced, I wanted to know if you're aware of the hidden slow down when you try to access a register when the previous instruction loaded data from memory into it. The code is fine, but I was just wondering if it was by luck you had it formatted that way or if you knew the whole time because you seem to be very skilled with Super H asm.
Logged


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)
calc84maniac
Epic z80 roflpwner
Coder Of Tomorrow
LV11 Super Veteran (Next: 3000)
*
Offline Offline

Gender: Male
Last Login: 20 May, 2013, 21:27:24
Date Registered: 28 August, 2008, 05:09:05
Location: Right behind you.
Posts: 2735


Total Post Ratings: +373

View Profile
« Reply #19 on: 27 May, 2011, 14:31:16 »
0

Nice job catching that there calc84. Sometimes I forget possible optimizations when I don't have the full instruction set in front of me.
btw on the instructions that you replaced, I wanted to know if you're aware of the hidden slow down when you try to access a register when the previous instruction loaded data from memory into it. The code is fine, but I was just wondering if it was by luck you had it formatted that way or if you knew the whole time because you seem to be very skilled with Super H asm.
I've gotten pretty used to ARM9 assembly at this point, which has similar memory load and multiplication delays. I studied up on SH3 when we started learning about the Prizm a while back (and personally I like ARM better, but that might just be me)

Edit: just for the lulz, here's how I might do this in ARM assembly:

1
2
3
4
5
6
7
GetPixel:
    ldr r2,=VRAM        @buffer = VRAM;
    add r3,r1,r1,lsl #2 @temp = y*3;
    add r3,r0,r3,lsl #7 @temp = x+temp*128;
    add r3,r2,r3,lsl #1 @temp = buffer+temp*2;
    ldrh r0,[r3]        @return *temp;
    bx lr
« Last Edit: 27 May, 2011, 14:41:03 by calc84maniac » Logged

"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman
AngelFish
This is my custom title
Administrator
LV12 Extreme Poster (Next: 5000)
*
Offline Offline

Gender: Male
Last Login: Today at 02:07:40
Date Registered: 15 August, 2010, 09:18:54
Posts: 3188


Total Post Ratings: +218

View Profile
« Reply #20 on: 15 June, 2011, 00:20:16 »
0

Here are a couple small routines someone might find useful.

Switch register banks:

1
2
3
4
stc sr, r8
mov.l 1f, r9
or r9, r8
ldc r8, sr

1 byte ASCII number -> Hex (r4 and r5 contain the high and low nibbles respectively)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
xor r7,r7
Start:
add r7,r4
add #0xE0,R4
mov #0x3A,r6
cmp/hs r4,r6
bf/s Start
mov #0xFF,r7
shll2 r4
shll2 r4
          /* Loop is unrolled here for speed, but you could easily loop back to the beginning for this after storing r4 to a safe register. */
xor r7,r7
Start2:
add r7,r5
add #0xE0,R5
mov #0x3A,r6
cmp/hs r5,r6
bf/s Start
mov #0xFF,r7
add r5,r4
rts
mov r4,r1

« Last Edit: 15 June, 2011, 07:58:27 by Qwerty.55 » Logged

∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ
z80man
Casio Traitor
LV8 Addict (Next: 1000)
********
Offline Offline

Gender: Male
Last Login: 04 September, 2012, 19:42:33
Date Registered: 26 December, 2010, 10:02:50
Location: City 17
Posts: 966


Total Post Ratings: +83

View Profile
« Reply #21 on: 15 June, 2011, 07:48:51 »
0

Just as a note you might want to keep your routines C compliant in their register usage that way other C coders can embed them in their programs. Such as on the first make sure you push r8 and r9 on the stack beforehand and on the second routine remember that args are passed in r4-r7 then stack and return data is in r0 and r1. There are a few exceptions when it comes to structs but for the most part it is pretty general. Leaving the routines the way they are now will force C coders to modify them which they may not be experienced enough to do.
Logged


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)
AngelFish
This is my custom title
Administrator
LV12 Extreme Poster (Next: 5000)
*
Offline Offline

Gender: Male
Last Login: Today at 02:07:40
Date Registered: 15 August, 2010, 09:18:54
Posts: 3188


Total Post Ratings: +218

View Profile
« Reply #22 on: 15 June, 2011, 07:57:54 »
0

Well, the first routine is for ASM coders to access the banked registers that GCC doesn't touch, so it wouldn't really have much use for C coders (except to crash their code). The second routine is quite simple to fix. Just add "mov r4,r1" to the end of the code, with appropriate replacement of rts.

EDIT: changed.
« Last Edit: 15 June, 2011, 07:58:41 by Qwerty.55 » Logged

∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ
z80man
Casio Traitor
LV8 Addict (Next: 1000)
********
Offline Offline

Gender: Male
Last Login: 04 September, 2012, 19:42:33
Date Registered: 26 December, 2010, 10:02:50
Location: City 17
Posts: 966


Total Post Ratings: +83

View Profile
« Reply #23 on: 15 June, 2011, 08:02:05 »
0

So the first routine switches the mode from privileged to user it appears. I do have one question, how would you get back to privileged mode then if the instructions to access the SR are disabled?
Logged


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)
AngelFish
This is my custom title
Administrator
LV12 Extreme Poster (Next: 5000)
*
Offline Offline

Gender: Male
Last Login: Today at 02:07:40
Date Registered: 15 August, 2010, 09:18:54
Posts: 3188


Total Post Ratings: +218

View Profile
« Reply #24 on: 15 June, 2011, 08:06:19 »
0

No, it switches the register set that's currently swapped in. The Processor has two register sets in Privileged mode: Regular and banked (which map to r8-r15). The GCC doesn't use the banked registers, so they're free to the ASM programmer to mess with. I doubt the OS uses them much either with the probable exception of error handling.

Needless to say, I love abusing the banked registers  Tongue
« Last Edit: 15 June, 2011, 08:07:47 by Qwerty.55 » Logged

∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ
z80man
Casio Traitor
LV8 Addict (Next: 1000)
********
Offline Offline

Gender: Male
Last Login: 04 September, 2012, 19:42:33
Date Registered: 26 December, 2010, 10:02:50
Location: City 17
Posts: 966


Total Post Ratings: +83

View Profile
« Reply #25 on: 15 June, 2011, 20:11:05 »
0

No, it switches the register set that's currently swapped in. The Processor has two register sets in Privileged mode: Regular and banked (which map to r8-r15). The GCC doesn't use the banked registers, so they're free to the ASM programmer to mess with. I doubt the OS uses them much either with the probable exception of error handling.

Needless to say, I love abusing the banked registers  Tongue
That could be useful for the ex based instructions on my 83+ emulator. I currently store the z80 registers in the r8-r15 range so I would just have to preserve the non-shadowed registers.
Logged


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)
Ashbad
Guest
« Reply #26 on: 07 September, 2011, 02:31:28 »
0

Here's a few routines I'm using, thanks to Qwerty for giving me some input on the Random ones (made because rand and srand didn't work for me due to linking errors):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
int GetKeyNB() {
    int key;
    key = PRGM_GetKey();
    if (key == KEY_PRGM_MENU)
GetKey(&key);
    return key;
}

void GetKeyHold(int key) {
while(GetKeyNB() != key) { }
while(GetKeyNB() != KEY_PRGM_NONE) { }

}

void GetKeyWaitNone() {
while(GetKeyNB() != KEY_PRGM_NONE) { }
}

unsigned short RandomShort() {
unsigned short retshort = 0;
int*cur_stack = 0;
int cur_stackv = 0;
for(int i = 0; i < 16; i--) {
retshort = retshort << 1;
cur_stack = GetStackPtr();
cur_stackv = *(RTC_GetTicks() + cur_stack);
retshort = retshort | (cur_stackv % 0xFFFFFFFF);
}
return retshort;
}

unsigned int RandomInt() {
unsigned int retint = 0;
int*cur_stack = 0;
int cur_stackv = 0;
for(int i = 0; i < 32; i--) {
retint = retint << 1;
cur_stack = GetStackPtr();
cur_stackv = *(RTC_GetTicks() + cur_stack);
retint = retint | (cur_stackv % 0xFFFFFFFF);
}
return retint;
}

unsigned char RandomChar() {
unsigned char retchar = 0;
int*cur_stack = 0;
int cur_stackv = 0;
for(int i = 0; i < 8; i--) {
retchar = retchar << 1;
cur_stack = GetStackPtr();
cur_stackv = *(RTC_GetTicks() + cur_stack);
retchar = retchar | (cur_stackv % 0xFFFFFFFF);
}
return retchar;
}
« Last Edit: 07 September, 2011, 03:13:36 by Ashbad » Logged
z80man
Casio Traitor
LV8 Addict (Next: 1000)
********
Offline Offline

Gender: Male
Last Login: 04 September, 2012, 19:42:33
Date Registered: 26 December, 2010, 10:02:50
Location: City 17
Posts: 966


Total Post Ratings: +83

View Profile
« Reply #27 on: 07 September, 2011, 06:54:43 »
0

You might want to run a test on those random routines due to a possible issue with the RTC. The problem is that the RTC ticks only 64 times a second so if you're calling that same routines multiple times in quick succession there may be some repetition. In Simon's random routine he used a static seed to contribute to the result which increased randomness. 
Logged


List of stuff I need to do before September:
1. Finish the Emulator of the Casio Prizm (in active development)
2. Finish the the SH3 asm IDE/assembler/linker program (in active development)
3. Create a partial Java virtual machine  for the Prizm (not started)
4. Create Axe for the Prizm with an Axe legacy mode (in planning phase)
5. Develop a large set of C and asm libraries for the Prizm (some progress)
6. Create an emulator of the 83+ for the Prizm (not started)
7. Create a well polished game that showcases the ability of the Casio Prizm (not started)
SimonLothar
LV4 Regular (Next: 200)
****
Offline Offline

Last Login: 20 March, 2013, 17:01:25
Date Registered: 16 February, 2011, 08:25:46
Location: Krautland
Posts: 122


Total Post Ratings: +33

View Profile
« Reply #28 on: 07 September, 2011, 18:42:13 »
0

In Simon's random routine he used a static seed to contribute to the result which increased randomness.
I did not invent the random routine you referred to. It uses the same algorithm as the one of the old CASIO SDK or the hitachi compiler's libraries (I only translated it to C). Therefor I think you are right. The randomness must be well balanced.
Logged

I'll be back.
Ashbad
Guest
« Reply #29 on: 09 September, 2011, 00:55:22 »
0

So, here I finally made a new routine that seems *really* random.  When I didrectly used it in my map generating routine to take the result of this routine seeded with 0 and mod 6, the tile output showed no patterns whatsoever.  However, I attained it by keeping the RTCtimer at bay for a *long*, *random*, time.  Anyways, the routine on it's own, which can even seed itself or get seeded by the RTC_GetTicks:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unsigned short random(int extra_seed) {
int seed = 0;
int seed2 = 0;
for(int i = 0; i < 32; i++ ){
seed <<= 1;
seed |= (RTC_GetTicks()%2);
}
for(int i = 0; i < 32; i++ ){
seed2 <<= 1;
seed2 |= (RTC_GetTicks()%16);
}
seed ^= seed2;
    seed = (( 0x41C64E6D*seed ) + 0x3039);
seed2 = (( 0x1045924A*seed2 ) + 0x5023);
extra_seed = (extra_seed)?(( 0xF201B35C*extra_seed ) + 0xD018):(extra_seed);
seed ^= seed2;
if(extra_seed){ seed ^= extra_seed; }
    return ((seed >> 16) ^ seed) >> 16;
}


It basically gets one bit from the timer at a time for the first seed, and then the second, "darker" seed (higher chance of filled bits), each bit gets 4 oppertunities to be seeded with a 1.  It then goes through the standard wacky operations to fill in the bitfield better, xors the available seeds together, and returns them as a short.  Very loosly based on simon's routine.

It's random *depending on how it's used*.  If you use it every now and then, it will be *surely* random, if you seed it with RTC_GetTicks or another varying number (even with a seed of 0 it will still be random, though).  In loops, it's fixed by slowing down operation in tradeoff for randomiscity:


1
2
3
4
for(int i = 0; i < 3600; i++) {
(*(map+i)).natural_cell = random(random(RTC_GetTicks()))%6;
OS_InnerWait_ms(random(0)%64);
}


As you see above, the actual random value is seeded by another random value that is not seeded, which worked really well.  For the OS_InnerWait_ms, I have it wait for an unseeded random time, mod 64 (so it won't wait a very long time, and since the RTC timer increments 64 times a second, it should give it long enough to increment in usual cases.

All because of a rand() and srand() linking error Smiley fun night spent.
Logged
Pages: 1 [2] 3 4 5   Go Up
  Print  
 
Jump to:  

Powered by EzPortal
Powered by MySQL Powered by SMF 1.1.18 | SMF © 2013, Simple Machines Powered by PHP
Page created in 0.318 seconds with 30 queries.
Skin by DJ Omnimaga edited from SMF default theme with the help of tr1p1ea.
All programs, games and songs avaliable on this website are property of their respective owners.
Best viewed in Opera, Firefox, Chrome and Safari with a resolution of 1024x768 or above.