Monday, 23rd June 2008
qarnos — author of the superb Aether 3D engine — has been lending a hand with the BBC BASIC graphics API and contributed a large amount of very useful code.
First up is some code to clip 16-bit line coordinates down to 8-bit coordinates. This allows for lines to be partially (or completely) off the screen.
He's also written a fast ellipse drawing and filling routine. The ellipses are also clipped to the viewport and are filled with an 8×8 pixel pattern.
The graphics viewport can be redefined using the VDU 24,left;top;right;bottom; command as demonstrated in the above example.
GCOL can also be used to set a plotting mode; either plotting the specified colour directly, performing a logical operation (OR, AND, EOR) or inverting the existing colour.
All but the last of the above screenshots are the result of running BBC BASIC on a TI-83+ SE at 15MHz. The final screenshot is running at the regular 6MHz.
Thursday, 12th June 2008
Work has been keeping me busy recently, but I've tried to set aside a small amount of time each evening to reclaim some sanity and do a little work on BBC BASIC. Not much progress has been made, but there has been some at least.
On the left is the program running on an 83+ SE at 15MHz, on the right on the regular 83+ at 6MHz. If you really wanted to do 3D in BBC BASIC you could probably get away with writing some of the more expensive operations — such as transforming/projecting vertices in batches — in assembly, but that would sort of go against the whole point of trying to write a program to test the speed of BASIC.
Here's the rather naïve code:
10 *REFRESH OFF 20 DIM p%(15) 30 fps%=0 40 lfps%=0 50 fpst%=TIME+100 60 REPEAT 70 rX=TIME/300 80 rY=TIME/400 90 SrX=SIN(rX) 100 CrX=COS(rX) 110 SrY=SIN(rY) 120 CrY=COS(rY) 130 pt%=0 140 FOR x=-1TO1STEP2 150 FOR y=-1TO1STEP2 160 FOR z=-1TO1STEP2 170 tX=y*CrX-x*SrX 180 tY=-x*CrX*SrY-y*SrX*SrY-z*CrY 190 tZ=3-x*CrX*CrY-y*SrX*CrY+z*SrY 200 p%(pt%)=tX*40/tZ+48 210 pt%=pt%+1 220 p%(pt%)=tY*40/tZ+32 230 pt%=pt%+1 240 NEXT 250 NEXT 260 NEXT 270 CLG 280 PRINTTAB(10,0)lfps%" FPS" 290 MOVE p%(0),p%(1) 300 DRAW p%(4),p%(5) 310 DRAW p%(12),p%(13) 320 DRAW p%(8),p%(9) 330 DRAW p%(0),p%(1) 340 DRAW p%(2),p%(3) 350 DRAW p%(6),p%(7) 360 DRAW p%(14),p%(15) 370 DRAW p%(10),p%(11) 380 DRAW p%(2),p%(3) 390 MOVE p%(4),p%(5) 400 DRAW p%(6),p%(7) 410 MOVE p%(12),p%(13) 420 DRAW p%(14),p%(15) 430 MOVE p%(8),p%(9) 440 DRAW p%(10),p%(11) 450 *REFRESH 460 fps%=fps%+1 470 IF TIME>fpst% THEN lfps%=fps%:fps%=0:fpst%=TIME+100 480 UNTIL INKEY(0)<>-1 490 *REFRESH ON 500 END
I have also added support for the COLOUR statement (for changing the text foreground and background colour) and copy key editing.
Copy key editing, as demonstrated in the screenshot on the right, lets you break the text input cursor into two parts - a write cursor (which is left behind on the line you were editing) and a read cursor, which can be positioned anywhere on the screen. Pressing the copy key (in this case, XTθn) reads a character under the read cursor and writes it to the write cursor, then increments both.
One feature that's a bit more fun is the support of device files. This is a way of accessing external devices as if they were files. For example, by opening the file AT.DEV you can read and write bytes using the AT protocol (used by AT and PS/2 keyboards and mice) using BBC BASIC's built-in file manipulation routines.
You could use this to do something useful, or could just use this to flash the LED on a keyboard back and forth.
10 keyb%=OPENOUT"AT.DEV" 20 DATA 2,4,1,4,-1 : REM LED flash pattern (-1 terminated). 30 REPEAT 40 READ l% 50 REPEAT 60 PROC_setled(l%) 70 PROC_pause(30) 80 READ l% 90 UNTIL l%=-1 100 RESTORE 110 UNTIL FALSE 120 END 130 : 140 DEF PROC_flushin 150 REPEAT 160 IF EXT#keyb% d%=BGET#keyb% 170 UNTIL NOT EXT#keyb% 180 ENDPROC 190 : 200 DEF PROC_setled(l%) 210 BPUT#keyb%,&ED 220 PROC_flushin 230 BPUT#keyb%,l% 240 PROC_flushin 250 ENDPROC 260 : 270 DEF PROC_pause(t%) 280 start%=TIME 290 REPEAT UNTIL TIME >= start%+t% 300 ENDPROC
Tuesday, 3rd June 2008
Richard Russell has kindly supplied the project with the BBC BASIC relocatable modules — compiled object files which can be relocated to any memory address by a linker — which means that BBC BASIC can now be configured to run on the TI's hardware.
The tools to relocate the modules run under CP/M, which means that rather trying to integrate the relocation into the build process (which would be a little awkward) I'm going to relocate the modules to a fixed base address and inject the resulting binary file directly into the application.
BBC BASIC will reside from &4100. From &4000..&40FF is a jump table, which BASIC uses to interact with the host. As the addresses of the host interface entry points will change as the code changes, and I don't wish to keep on relinking BASIC in CP/M, a fixed jump table makes life a lot easier. BASIC jumps to a predetermined fixed address in the jump table, which redirects - via a second jump - to the real entry point.
I think I've implemented all of the main host interface entry points, though some — notably those involved in file I/O — need making more robust. I don't currently reserve any memory for BASIC's scratch area, which means that the TI-OS can (and does) decide to overwrite it at inconvenient moments. Even though TI provided us with at least three different 768-byte buffers (the exact size of BBC BASIC's scratch area), none of them are aligned to a 256 byte boundary.