FAQ  •  Register  •  Login

Tutorial: How to put inline assembly functions into ZX Basic

<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Thu Feb 16, 2012 1:32 pm

Tutorial: How to put inline assembly functions into ZX Basic

Finally finished this, and got it working.

http://goo.gl/Iw32U
<<

boriel

Site Admin

Posts: 1463

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Thu Feb 16, 2012 2:05 pm

Re: Tutorial: How to put inline assembly functions into ZX B

Hey!!! Amazing!! Thanks! 8)
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Thu Feb 16, 2012 2:22 pm

Re: Tutorial: How to put inline assembly functions into ZX B

I never got around to learning assembly, :)
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Thu Feb 16, 2012 5:03 pm

Re: Tutorial: How to put inline assembly functions into ZX B

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.
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Fri Feb 17, 2012 4:07 pm

Re: Tutorial: How to put inline assembly functions into ZX B

Do you allow me to put a Copy of this cool Doc in Spectrum profi Club magazine? :D
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Sat Feb 18, 2012 7:35 pm

Re: Tutorial: How to put inline assembly functions into ZX B

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

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Sat Feb 18, 2012 9:33 pm

Re: Tutorial: How to put inline assembly functions into ZX B

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!
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Sun Feb 19, 2012 10:09 pm

Re: Tutorial: How to put inline assembly functions into ZX B

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.
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Mon Feb 20, 2012 12:19 am

Re: Tutorial: How to put inline assembly functions into ZX B

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.
;)
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.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Feb 20, 2012 2:01 am

Re: Tutorial: How to put inline assembly functions into ZX B

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
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Feb 20, 2012 9:07 am

Re: Tutorial: How to put inline assembly functions into ZX B

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
Last edited by britlion on Mon Feb 20, 2012 10:18 am, edited 1 time in total.
<<

boriel

Site Admin

Posts: 1463

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Mon Feb 20, 2012 10:06 am

Re: Tutorial: How to put inline assembly functions into ZX B

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

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Feb 20, 2012 10:19 am

Re: Tutorial: How to put inline assembly functions into ZX B

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


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

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

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Mon Feb 20, 2012 12:05 pm

Re: Tutorial: How to put inline assembly functions into ZX B

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!
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Feb 20, 2012 12:25 pm

Re: Tutorial: How to put inline assembly functions into ZX B

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 :)
Next

Return to How-To & Tutorials

Who is online

Users browsing this forum: No registered users and 4 guests

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO