![]() |
|
A Fast(er) Plot Routine for Boriel Basic - Printable Version +- Boriel Basic Forum (https://forum.boriel.com) +-- Forum: Compilers and Computer Languages (https://forum.boriel.com/forumdisplay.php?fid=12) +--- Forum: ZX Basic Compiler (https://forum.boriel.com/forumdisplay.php?fid=11) +---- Forum: How-To & Tutorials (https://forum.boriel.com/forumdisplay.php?fid=13) +---- Thread: A Fast(er) Plot Routine for Boriel Basic (/showthread.php?tid=2647) |
A Fast(er) Plot Routine for Boriel Basic - tubz74 - 2025-10-28 I orginally posted this on SpectrumComputing Forum - copied here in case anyone wants to play with it :-) Hi Hope this helps someone else :-) I saw a post by Andy Dansby who writes at https://zxspectrumcoding.wordpress.com/ He has created a fast plot routine, (hellaplot), so I thought I'd try and convert it to a Boriel Basic (BB) subroutine, just for fun and learning - and as it was a single routine. I had to do a little bit of reading, but also had to ask for help from the BB telegram community, as to begin with the code was crashing the emulator. Turns out it was a simple fix when you know how - FASTCALL was needed when passing parameters for ASM to use from a SUB routine. Andy's code needs the x/y locations in DE, so I had to do a little bit to get them set up like this - I assume there might be some more efficiency if different registers were used as BB passes from the subroutine call, the first parameter into A, and the second parameter is the second item on the stack (the first being the return address). When I started, xPos was the first parameter, and yPos the second (as I like x,y), but this meant to get them into DE, took another load (POP DE, LD E with D, LD D with A, compared to POP DE, LD E with A) So some "non exact" timings - plot included as the library in BB takes about 15 seconds to fill up the screen with "points". Andy's one takes 5 seconds to do the same. As far as Andy's code goes, I understand the comments, but not exactly how it works :-) Anyway, code below : SUB FASTCALL HellaPrint(yPos as UBYTE, xPos as UBYTE) ' HellaPrint prints an x,y pixel ' 0,0 is top left ' Original code by Andy Lansby ' https://zxspectrumcoding.wordpress.com/ ' yPos is first, as it save a LD instruction when putting xPos and yPos into DE ASM JP START ; Put this in as it's like this on the Wiki ASM desciption - can it be avoided? X_PositionBits: defb 128,64,32,16,8,4,2,1 ; Might there be a quicker way to do the above, so it's not needed every time the program is run? or does it not work like this and is created once at compile time? START: ; plot d = x-axis, e = y-axis ; A contains the yPos, xPos is on stack. POP HL ; Pops the return address into HL POP DE ; xPos is on the stack, and it needs to be in D LD E, A ; A has our first paramter (yPos), load it into E. D should be Xpos, E should be yPos PUSH HL ; Puts the return address back onto stack ... ; 166 T states per pixel XOR A ; reset A to 0 and flags to default LD A,E ; load Y plot point RRA ; rotate Right --- divide in half SCF ; turn on Carry flag- RRA ; rotate right with the carry flag OR A ; set flag S on - C flag off RRA ; rotate Right --- divide in half LD L,A ; temp store in L XOR E ; XOR the Y value AND %11111000 ; mask out bottom 3 bits XOR E ; XOR the Y value LD H,A ; store High byte LD A,D ; load X plot point XOR L ; XOR the temp value AND %00000111 ; mask out unwanted bits XOR D ; XOR the X value RRCA ; divide by 2 RRCA ; divide by 4 RRCA ; divide by 8 LD L,A ; store Low byte ; now we have the full address ; now use LUT to find which bit to set LD A,D ; load X plot point AND %00000111 ; mask out unwanted bits ; use a LUT to quickly find the bit position for the X position LD DE,X_PositionBits ; load LUT address into DE ADD A,E ; Add A to E to get offset into table LD E,A ; E now points to the LUT entry LD A,(DE) ; load answer into A ; output to screen OR (HL) ; or with contents of address HL LD (HL),A ; load address HL with Answer from A END ASM END SUB |