Forum
Tutorial: How to put inline assembly functions into ZX Basic - Printable Version

+- Forum (https://www.boriel.com/forum)
+-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12)
+--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11)
+---- Forum: How-To & Tutorials (https://www.boriel.com/forum/forumdisplay.php?fid=13)
+---- Thread: Tutorial: How to put inline assembly functions into ZX Basic (/showthread.php?tid=428)

Pages: 1 2


Tutorial: How to put inline assembly functions into ZX Basic - britlion - 02-16-2012

Finally finished this, and got it working.

http://goo.gl/Iw32U


Re: Tutorial: How to put inline assembly functions into ZX B - boriel - 02-16-2012

Hey!!! Amazing!! Thanks! 8)


Re: Tutorial: How to put inline assembly functions into ZX B - slenkar - 02-16-2012

I never got around to learning assembly, Smile


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-16-2012

Well, I'm recommending ZX Basic as a way of learning - you can do it a little bit at a time, rather than having to do everything in assembly.


Re: Tutorial: How to put inline assembly functions into ZX B - LCD - 02-17-2012

Do you allow me to put a Copy of this cool Doc in Spectrum profi Club magazine? Big Grin


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-18-2012

Of course, LCD. If you can make it look better formatted!


Re: Tutorial: How to put inline assembly functions into ZX B - LCD - 02-18-2012

britlion Wrote:Of course, LCD. If you can make it look better formatted!
Thanks! Sure I will reformat it, thats no problem!

Edit: By the way, sorry for being off topic, but I did my mirroring function in Boriels BASIC a little bit different (without a table):
Code:
function mirror(dowedoit as ubyte, number as ubyte) as ubyte
    dim result as ubyte
    if dowedoit then
        result=(number&1)<<7|(number&2)<<5|(number&4)<<3|(number&8)<<1|(number&16)>>1|(number&32)>>3|(number&64)>>5|(number&128)>>7
    Else
        result=number
    end if
    return result
end Function
Anyway, optimising the routines is not the topic here. Your tutorial is great!


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-19-2012

Yes - that looks like it would work, but it's a LOT harder to understand. I deliberately kept it as easy to read for Sinclair Basic users as possible, such as keeping "REM" rather than ' and using LET everywhere...

Also stuck to using BAND rather than & - and the basic and the machine code use very very nearly the same algorithm, so it's easier to see what the assembly is using.


Re: Tutorial: How to put inline assembly functions into ZX B - LCD - 02-20-2012

britlion Wrote:Yes - that looks like it would work, but it's a LOT harder to understand. I deliberately kept it as easy to read for Sinclair Basic users as possible, such as keeping "REM" rather than ' and using LET everywhere...

Also stuck to using BAND rather than & - and the basic and the machine code use very very nearly the same algorithm, so it's easier to see what the assembly is using.

Thats why I wrote its off Topic. Thats my art of coding, hard to understand, not suitable for tutorials, but working and very fast.
Wink
I do not use the LET command, but you are right, BAND is easier to understand for novices than &, I just used it because it is shorter and fits better in a line of code.
You inspired me to learn a bit more assembly.


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-20-2012

You should see what I'm working on now. Probably way too ambitious to finish. But I did 12 pages this evening...

http://goo.gl/4jPd5


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-20-2012

LCD Wrote:
Code:
function mirror(dowedoit as ubyte, number as ubyte) as ubyte
    dim result as ubyte
    if dowedoit then
        result=(number&1)<<7|(number&2)<<5|(number&4)<<3|(number&8)<<1|(number&16)>>1|(number&32)>>3|(number&64)>>5|(number&128)>>7
    Else
        result=number
    end if
    return result
end Function
Though if I was going to, I'd say why bother with a new variable? :mrgreen:

Code:
function mirror(dowedoit as ubyte, number as ubyte) as ubyte
   if dowedoit then
      number=(number&1)<<7|(number&2)<<5|(number&4)<<3|(number&8)<<1|(number&16)>>1|(number&32)>>3|(number&64)>>5|(number&128)>>7
   end if
   return number
end Function

That said, if you read the behemoth assembly that makes. Ouch. Hopping on and off the stack like crazy! Not to mention a lot of very expensive reads and writes to (IX+7) - which cost 19 T states each. I wonder if my original beginners algorithm is faster!

Anyway, I think my suggested optimized version is pretty tight:

Code:
function fastcall mirror (dowedoit as uByte, number as uByte) as uByte
asm
   pop hl
   pop bc
   AND A
   LD A,B
   RET Z
   ld b,8
   ld c,a
   XOR A
        
   mirrorLoop:
      RR C
      RLA  
   DJNZ mirrorLoop
   jp (hl)        
end asm
END FUNCTION



Re: Tutorial: How to put inline assembly functions into ZX B - boriel - 02-20-2012

I was in fact planning an ebook (PDF free & hard cover), for ZX Basic compiler. Big Grin
But it's a huge task, and English is not my mother tongue! Tongue


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-20-2012

boriel Wrote:I was in fact planning an ebook (PDF free & hard cover), for ZX Basic compiler. Big Grin
But it's a huge task, and English is not my mother tongue! Tongue

Yes. yes it is. Working on it...

At least some of it. No doubt I'll have time shortages again.


Re: Tutorial: How to put inline assembly functions into ZX B - LCD - 02-20-2012

britlion Wrote:
LCD Wrote:
Code:
function mirror(dowedoit as ubyte, number as ubyte) as ubyte
    dim result as ubyte
    if dowedoit then
        result=(number&1)<<7|(number&2)<<5|(number&4)<<3|(number&8)<<1|(number&16)>>1|(number&32)>>3|(number&64)>>5|(number&128)>>7
    Else
        result=number
    end if
    return result
end Function
Though if I was going to, I'd say why bother with a new variable? :mrgreen:

Code:
function mirror(dowedoit as ubyte, number as ubyte) as ubyte
   if dowedoit then
      number=(number&1)<<7|(number&2)<<5|(number&4)<<3|(number&8)<<1|(number&16)>>1|(number&32)>>3|(number&64)>>5|(number&128)>>7
   end if
   return number
end Function

That said, if you read the behemoth assembly that makes. Ouch. Hopping on and off the stack like crazy! Not to mention a lot of very expensive reads and writes to (IX+7) - which cost 19 T states each. I wonder if my original beginners algorithm is faster!
:oops:
I overseen it... It was my mirroring function from my unfinished fractal picture decompressor which I adopted to match yours, mine had no dowedoit, so it was:
Code:
function MirrorByte(num as ubyte) as ubyte
    return (num&1)<<7|(num&2)<<5|(num&4)<<3|(num&8)<<1|(num&16)>>1|(num&32)>>3|(num&64)>>5|(num&128)>>7
end function
Your original beginners function was not faster, it was in fact slower because multiplication and division is allways slower than bitshifting. I'm happy that boriel included it as it is a big help in optimizing programs, so you could use SHR and SHL in place of >> and <<. With this your code will match the ASM version much better, and work faster.
britlion Wrote:Anyway, I think my suggested optimized version is pretty tight:

Code:
function fastcall mirror (dowedoit as uByte, number as uByte) as uByte
asm
   pop hl
   pop bc
   AND A
   LD A,B
   RET Z
   ld b,8
   ld c,a
   XOR A
        
   mirrorLoop:
      RR C
      RLA  
   DJNZ mirrorLoop
   jp (hl)        
end asm
END FUNCTION
It is!!!
Much faster than both compiled codes.

The books looks very good by the way!!! My compliments!


Re: Tutorial: How to put inline assembly functions into ZX B - britlion - 02-20-2012

Ah - then you'd need one that just looks like this, I think:


Code:
function fastcall mirror (number as uByte) as uByte
asm
   ld b,8
   ld c,a
   XOR A
mirrorLoop:
      RR C
      RLA
DJNZ mirrorLoop
end asm
END FUNCTION

I haven't tested it, mind. Just typed it here. Feels right, though Smile