Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tutorial: How to put inline assembly functions into ZX Basic
#1
Finally finished this, and got it working.

http://goo.gl/Iw32U
Reply
#2
Hey!!! Amazing!! Thanks! 8)
Reply
#3
I never got around to learning assembly, Smile
Reply
#4
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.
Reply
#5
Do you allow me to put a Copy of this cool Doc in Spectrum profi Club magazine? Big Grin
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#6
Of course, LCD. If you can make it look better formatted!
Reply
#7
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!
Reply
#8
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.
Reply
#9
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.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#10
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
Reply
#11
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
Reply
#12
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
Reply
#13
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.
Reply
#14
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!
Reply
#15
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
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)