Modifying Super Extended Color BASIC

On a recent project I needed to read and write unsigned double byte values from memory. The standard version of BASIC does not include such commands so they must be accomplished using multiple commands. For reading a two byte value this is usually how it is done: <pre> 10 A = PEEK(&H6000)<em>256+PEEK(&H6001) </pre> Variable A will now contain an unsigned two byte value starting from $6000. This is an example of writing a two byte value: <pre> 10 A=RND(65535) 20 POKE &H6000,A/256 30 POKE &H6001,256</em>(A/256-INT(A/256)) </pre> It turns out all this math was causing my recent project to slow down to unacceptable levels. So I had the idea of rewriting the Super Extended Color BASIC commands LPEEK and LPOKE to perform double byte reads and writes. Looking thru the commented source disassembly, I discovered that if it was acceptable to completely replace the functionality of the commands I had 27 bytes for LPEEK and 45 bytes for LPOKE to work with.

So I took the code from regular PEEK and and placed it where LPEEK was and change the opcode to read two bytes instead of one. This caused a problem, the standard return from a function subroutine converts the D register to a signed value from -32767 to 32766. I wanted an unsigned result from 0 to 65535. In the LIST command I discovered a bit of code that prints the line number to do exactly what I wanted. <pre> 0050 00001 fpa0 equ $50 002B 00002 binval equ $2b 00003 00004 # Modify LPEEK to return two bytes (unsigned) 00005 org $e573 E573 17D1CA 00006 lbsr $b740 convert FPA0 to integer in register X E576 EC84 00007 ldd ,x read two bytes E578 DD50 00008 std fpa0 convert Reg D to FP and return E57A C690 00009 ldb #$90 E57C 43 00010 coma E57D BDBC86 00011 jsr $bc86 E580 39 00012 rts </pre> The new LPOKE function needed to read two comma separated values from the program and write the value to the address. <pre> 00014 # Modify LPOKE to store two bytes (unsigned) 00015 org $e545 E545 17D1F5 00016 lbsr $b73d eval expression return in X E548 9F2B 00017 stx binval store address in binval E54A BDB26D 00018 jsr $b26d syntax check for a comma E54D 17D1ED 00019 lbsr $b73d eval expression return in X E550 1F10 00020 tfr x,d transfer value to D E552 9E2B 00021 ldx binval load address E554 ED84 00022 std ,x store value in address E556 39 00023 rts </pre> After overlaying this code onto SECB, I now have a double byte version of PEEK and POKE. Soon I discovered I had a new slow down. I was filling buffers with the same byte, over and over. Like this: <pre> 10 FOR X = &H6000 TO &H64FF 20 POKE X, &H55 30 NEXT X </pre> This turned out to be a slow method of filling memory. I needed a new command to quickly accomplish the same thing. I began looking for another command in SECB that I could replace. I decided to replace HPAINT. <pre> 00025 # Modify HPAINT to be a memory fill command 00026 # Example: HPAINT &H7400, &H2300, &H80 00027 # Write byte $80 to buffer in $7400 to $96FF 00028 org $ebf5 EBF5 17CB45 00029 lbsr $b73d eval expression return in X EBF8 9F2B 00030 stx binval store address in binval EBFA BDB26D 00031 jsr $b26d syntax check for a comma EBFD 17CB3D 00032 lbsr $b73d eval expression return in X EC00 3410 00033 pshs x EC02 BDB26D 00034 jsr $b26d syntax check for a comma EC05 BDB70B 00035 jsr $b70b eval expression return in B EC08 9E2B 00036 ldx binval EC0A 3520 00037 puls y 00038 loop EC0C E780 00039 stb ,x+ EC0E 313F 00040 leay -1,y EC10 26FA 00041 bne loop EC12 39 00042 rts 00043 end </pre> To test it I wrote this screen saver:


10 WIDTH 32:CLS
20 HPAINT &H3FF+RND(512),RND(128),127+RND(128)
30 GOTO 20