+DZ-Jay Posted April 1 Share Posted April 1 Is there a way to make IntyBASIC perform signed-division by powers of 2? Even for signed 16-bit variables, the generated assembly code uses "logical shift" instead of "arithmetic shift" operations, which do not propagate the sign. -dZ. Quote Link to comment Share on other sites More sharing options...
artrag Posted April 1 Share Posted April 1 no, the manual is clear about it Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 1 Author Share Posted April 1 8 minutes ago, artrag said: no, the manual is clear about it Thanks, I must have missed that. I think this is clearly a flaw. Other then busting out an ASM directive, is there a way to coerce the compiler into issuing a SAR instruction, perhaps with some convoluted IntyBASIC construct? dZ. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 2 Author Share Posted April 2 Oh, darn! I just realized that I encountered this problem two years ago when I started my project, and I had solved it. I had completely forgotten it. Here's a handy macro. Not optimal, but what can you do. '' ======================================================================== '' '' SignedPow2Division(val, div) '' '' Divides a signed number by a power of two, retaining its sign. '' '' '' '' Arguments: '' '' val: The value to divide. '' '' div: The divisor. Must be a power of two constant. '' '' '' '' Output: '' '' The signed value "val" divided by power of two "div". '' '' ======================================================================== '' DEF FN SignedPow2Division(val, div) = (((((val) / (div)) Xor ($8000 / (div))) - ($8000 / (div))) AND $FFFF) If anybody has be better way, let me know. -dZ. 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 2 Author Share Posted April 2 And to give credit where it's due: I got that solution from an example provided by @intvnut. The "accel" program in the "contrib" folder of the IntyBASIC distribution did that trick to retain the sign when dividing by 4, and I just generalized it into a macro for any power of 2. -dZ. Quote Link to comment Share on other sites More sharing options...
Walter Ives Posted April 25 Share Posted April 25 On 4/1/2023 at 3:01 PM, artrag said: no, the manual is clear about it On 4/1/2023 at 3:12 PM, DZ-Jay said: I think this is clearly a flaw. It's documented, so it's a feature. WJI 1 1 Quote Link to comment Share on other sites More sharing options...
Walter Ives Posted April 25 Share Posted April 25 On 4/2/2023 at 4:23 AM, DZ-Jay said: Other then busting out an ASM directive, is there a way to coerce the compiler into issuing a SAR instruction, perhaps with some convoluted IntyBASIC construct? ... Oh, darn! I just realized that I encountered this problem two years ago when I started my project, and I had solved it. I had completely forgotten it. Here's a handy macro. Not optimal, but what can you do. '' ======================================================================== '' '' SignedPow2Division(val, div) '' '' Divides a signed number by a power of two, retaining its sign. '' '' '' '' Arguments: '' '' val: The value to divide. '' '' div: The divisor. Must be a power of two constant. '' '' '' '' Output: '' '' The signed value "val" divided by power of two "div". '' '' ======================================================================== '' DEF FN SignedPow2Division(val, div) = (((((val) / (div)) Xor ($8000 / (div))) - ($8000 / (div))) AND $FFFF) If anybody has be better way, let me know. Cute. The XOR clears the residual sign bit, the subtraction sets the propagated sign bits and that final AND $FFFF tells you who's paying attention. Although THREE general-purpose software divides (two of which are the same!) is a steep price to pay for an operation that could be easily done with a few native shifts, if your function is fast enough to work for you it's fast enough. You should probably let less experienced readers know that they can improve performance somewhat by sacrificing the elegance of the function for a subroutine that cuts the number of those divides. As to ASM directives: that's what they're for and it's no shame to use them, especially when using a primitive compiler. K&R would agree. WJI 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted April 25 Author Share Posted April 25 1 hour ago, Walter Ives said: Cute. The XOR clears the residual sign bit, the subtraction sets the propagated sign bits and that final AND $FFFF tells you who's paying attention. Although THREE general-purpose software divides (two of which are the same!) is a steep price to pay for an operation that could be easily done with a few native shifts, if your function is fast enough to work for you it's fast enough. You should probably let less experienced readers know that they can improve performance somewhat by sacrificing the elegance of the function for a subroutine that cuts the number of those divides. As to ASM directives: that's what they're for and it's no shame to use them, especially when using a primitive compiler. K&R would agree. WJI As primarily an assembly language programmer, I feel no shame in using assembly code. My concern here is in building tutorials for new IntyBASIC programmers, some of which may want to make games for the IntyBASIC competition which forbids non BASIC code. But for anybody paying attention, the down-and-dirty solution would be to shift arithmetically right, once per power of two. Each SAR (Shift Arithmetically Right) instruction takes a secondary argument directing either one or two shifts, so you will need to use more than one for more than one power of 2. Here is an example of dividing 8-bit variable "MyVar" by 4: ASM MVI var_MYVAR, R0 ; Get the value ASM SAR R0, 2 ; Divide by 4 (2^2) ASM MVO R0, var_MYVAR ; Store the result dZ. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.