+Lee Stewart Posted September 26, 2012 Author Share Posted September 26, 2012 Here's a shorter version ... ... I think my 'pause' code is much clearer than TI Forth's PAUSE. Do I get a prize? Mais oui! Very nice, indeed. There are at least 4 TI Forth words that list to the display that use PAUSE . I guess your definition could be worked into 2 of them. The other 2 are, unfortunately, part of the resident vocabulary as is PAUSE , of course. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 26, 2012 Author Share Posted September 26, 2012 A bit of an update: ... Lee, would you mind stress-testing the following Math words: */ UM* /MOD */MOD UM/MOD ... Mark I'd be happy to. I see Rod lurking. I'm sure he'll get in on it, as well. ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted September 26, 2012 Share Posted September 26, 2012 Yeah! The more the merrier! Go Rod! Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 26, 2012 Author Share Posted September 26, 2012 Mais oui! Very nice, indeed. There are at least 4 TI Forth words that list to the display that use PAUSE . I guess your definition could be worked into 2 of them. The other 2 are, unfortunately, part of the resident vocabulary as is PAUSE , of course. ...lee Mark... It works quite well! : pause break? begin key? -1 = until ; Now, it can be used in other words that list to the display screen. Of course, that might mean hoisting it into the resident vocabulary. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 27, 2012 Author Share Posted September 27, 2012 (edited) Floating Point Math Library--- OK...Regarding my conversion/adaptation of the MDOS floating point library, I have pretty much cleaned out the MDOS-dependent taskframe stuff, which reduced the object file size by 310 bytes to 5882 bytes. A cursory run-through tells me I probably cannot reduce it by more than another 250-300 bytes by removing replicated inline code to a handful of short subroutines. I am not sure I am clever or masochistic enough to squeeze more out of it. I am not sure the loss in some speed is worth the 250-300 bytes saved, however. One section of code that gets executed about 50 times throughout the library is the following: MOV *R1+,*R2+ MOV *R1+,*R2+ MOV *R1+,*R2+ MOV *R1,*R2 The best I could come up with for that is BL @R1$2 ... R1$2 MOV *R1+,*R2+ MOV *R1+,*R2+ MOV *R1+,*R2+ MOV *R1,*R2 RT If I figured it correctly, that saves 4 bytes per call for a total of about 200 bytes. I haven't worked out how much slower that is. ...lee Edited September 27, 2012 by Lee Stewart 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 27, 2012 Author Share Posted September 27, 2012 Floating Point Math Library--- The routines included in the adapted MDOS library are FCOMP..........Floating Point Compare FSUB...........Floating Point Subtract FADD...........Floating Point Add FMULT..........Floating Point Multiply FDIV...........Floating Pont Divide PWR............Floating Point Power EXP............Floating Point ex LOG............Floating Point ln(x) SQR............Floating Point sqr(x) COS............Floating Point cos(x) SIN............Floating Point sin(x) TAN............Floating Point tan(x) ATN............Floating Point atn(x) GRI............Floating Point Greatest Integer CFI............Convert Floating Point to Integer CIF............Convert Integer to Floating Point CSINT..........Convert String to Integer CSN............Convert String to Floating Point CNS............Convert Floating Point to String At the moment, I have left unchanged the passing of parameters through registers instead of through FAC and ARG. I may change that because FAC and ARG are used inside the routines. Of course, the internal uses do not have to be the 834Ah and 835Ch locations used by the console. I'm torn. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 27, 2012 Author Share Posted September 27, 2012 Floating Point Math Library--- Scratchpad (8300h-83FFh) use is as follows: 834Ah.......FAC 8354h.......Float Divisor (currently, not used for FP error return as with console routines) 835Ch.......ARG 836Ch.......EXP 836Eh.......SIGN 83A0h.......WSG (FP workspace) These can all be changed unless we want to pass the parameters both ways through FAC and ARG as the console routines do. ...lee Quote Link to comment Share on other sites More sharing options...
Rod Van Orden Posted September 28, 2012 Share Posted September 28, 2012 hi.... I see you guys have been busy....! I have been at jury duty..... Tomorrow I'll have a look at those math words... Right now it's beer time. Rod Quote Link to comment Share on other sites More sharing options...
Willsy Posted September 28, 2012 Share Posted September 28, 2012 Floating Point Math Library--- Scratchpad (8300h-83FFh) use is as follows: 834Ah.......FAC 8354h.......Float Divisor (currently, not used for FP error return as with console routines) 835Ch.......ARG 836Ch.......EXP 836Eh.......SIGN 83A0h.......WSG (FP workspace) These can all be changed unless we want to pass the parameters both ways through FAC and ARG as the console routines do. ...lee Does the memory footprint above indicate how the original code is currently written, or is it your proposed memory footprint? From post #41 in this thread, here's the TF PAD footprint: Scratchpad usage is from >8300 to >835B inclusive, as follows: $8300 - $831F - Workspace registers. TF only uses one register file. $8320 - $8325 - DOCOL $8326 - $832B - NEXT $832C - $8331 - EXIT $8332 - $8339 - bridge routine to jump to an address in bank 1 $833A - $833F - bridge routine to return to the calling routine in bank 0 $8340 - $8349 - get speech synth status subroutine $834A - $834B - data read from speech synth $834C - $8353 - ISR despatcher for ISR in bank 1 $8354 - $835B - ISR return subroutine So, there's some overlap starting at FAC (>834A). Also >8354. That's not the end of the world though! Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 28, 2012 Author Share Posted September 28, 2012 Does the memory footprint above indicate how the original code is currently written, or is it your proposed memory footprint? From post #41 in this thread, here's the TF PAD footprint: Scratchpad usage is from >8300 to >835B inclusive, as follows: $8300 - $831F - Workspace registers. TF only uses one register file. $8320 - $8325 - DOCOL $8326 - $832B - NEXT $832C - $8331 - EXIT $8332 - $8339 - bridge routine to jump to an address in bank 1 $833A - $833F - bridge routine to return to the calling routine in bank 0 $8340 - $8349 - get speech synth status subroutine $834A - $834B - data read from speech synth $834C - $8353 - ISR despatcher for ISR in bank 1 $8354 - $835B - ISR return subroutine So, there's some overlap starting at FAC (>834A). Also >8354. That's not the end of the world though! My tentative memory footprint is a confabulation of MDOS and TI-99/4A scratchpad RAM. The only thing I did was to force FAC and ARG to the 4A's locations. The rest falls out of converting the MDOS F000h-based locations. If I did nothing but a one-to-one correspondence, the map would be the locations in parentheses below: 834Ah(8380h).......FAC 8354h(838Ah).......Float Divisor 835Ch(83C6h).......ARG 836Ch(83D6h).......EXP 836Eh(83D8h).......SIGN 83A0h(same ).......WSG (FP workspace) I felt it would be useful to keep FAC and ARG where the 4A has them to maximize our options, I don't think it matters where we actually put them, particularly if we don't use the MDOS register-passing style for I/O of parameters. Using the 4A's method would save some space in the library's footprint, but probably not enough to warrant forcing the 4A's method if another would otherwise be better. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 28, 2012 Author Share Posted September 28, 2012 Floating Point Math Library--- If we stay with the MDOS calling scheme, the following mechanism should work: * REF FPMLIB entry point for floating point math library (FPML) FPLWS EQU >83A0 FPML workspace FPLLNK DATA FPLWS,FPMLIB new workspace and branchpoint * * set up registers with input parameters (R0-R5) * R0 = FPML subroutine # * R1 = pointer to result * R2 = parameter #1 * R3 = parameter #2 * R4 = parameter #3 * R5 = parameter #4 * BLWP @FPLLNK * * error returned in R0 and result at address passed to FPML in R1 * If we decide to use the old 4A way of doing business, the I/O parameters would be as described in the Editor/Assembler Manual, using FAC, ARG and other scratchpad-RAM addresses. And, the call would be done in the familiar way: * BLWP @FPLLNK DATA <subroutine #> * At this point, as I said earlier, I'm torn. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 1, 2012 Author Share Posted October 1, 2012 Floating Point Math Library--- I'm trying to figure out the easiest way to test this library without writing an AL test harness! The easiest method that came to me is straight from Rube Goldberg! AORG the library to 2700h (above E/A utilities). Load the object file with E/A into low memory expansion, where it fits neatly behind the E/A utilities. Save the memory image from 2700h-3DF5h to a program file. This requires either (1) copying all 5878 bytes to VDP RAM and using the SAVE subroutine of the disk DSR or (2) using Classic99's memory-dump option, extracting the correct memory range to another TI file and editing the FDR to force it to a "PROGRAM" file. Start TurboForth. Use a custom TF word to use the LOAD subroutine of the disk DSR to load the memory image (5878 bytes) into VDP RAM. Copy the image from VDP RAM to 2700h and update FFAILM. Test to my heart's content! (3) is pretty easy because I have already written ALC to do the first option for another situation. It's loading the memory image after TF is started that will be dicey because there's not enough space in VDP RAM (951 bytes!) to fit the image. I guess I could save the image as 7 files of 840 bytes each. Anybody got a better idea? ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 1, 2012 Share Posted October 1, 2012 It's loading the memory image after TF is started that will be dicey because there's not enough space in VDP RAM (951 bytes!) to fit the image. I guess I could save the image as 7 files of 840 bytes each. Anybody got a better idea? ...lee Well, if you have no open blocks (and you don't, because block files are ALWAYS closed after being accessed) then you can use the entire 6K of VDP RAM that is associated with the block buffers. So, you could load the program image file over the block buffers with no problems. After loading, when you return from your AL program to TF, just do an EMPTY-BUFFERS. Thinking about it, EMPTY-BUFFERS probably isn't even necessary... Whilst the block buffers are in VDP, the buffer 'slot' pointers and status (the stuff that tells TF what block is in what buffer, and if the block is clean or dirty) is all in CPU RAM, and you won't be clobbering that at all. So, I say go load over the top of the block buffers in VDP. Panic not. You'll be fine! The block buffers in VDP start at >1C20 and end at >341F. Good luck! Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 1, 2012 Share Posted October 1, 2012 If we decide to use the old 4A way of doing business, the I/O parameters would be as described in the Editor/Assembler Manual, using FAC, ARG and other scratchpad-RAM addresses. And, the call would be done in the familiar way: * BLWP @FPLLNK DATA <subroutine #> * At this point, as I said earlier, I'm torn. ...lee I personally have no problem with leaving the old idioms behind. Since you're soliciting opinions on the interface, I'll throw my tuppence worth in! Placing the Radix 100 numbers into scratch pad is not a good idea. Why? Because the R100 number will almost certainly exist elsewhere, so copying them from one place to another is just a waste of processor cycles! Take TF as an example (I can't cite TIF because I haven't used FP in TIF). In TF I implemented a seperate floating point stack. You're familiar with the implementation so I'll not wax on too much about it, except to say that a large part of the implementation is concerned with simply copying R100 numbers to FAC and ARG, and copying the results back again, which of course poses a serious performance penalty. The TI FP implementations work in their rather awkward manner purely down to the architecural limits of an un-expanded console. There's only VDP and scratchpad. The TI engineers had nothing else to work with. However, we have an opportunity to move away from that very awkward, and inefficient interface. I personally strongly advocate passing pointers to the R100 numbers to the FP routines (via CPU registers). Then no copying of R100 arguments is required. The FP software can process them in-situ. Much much more efficient. In the case of TF, these FP arguments would be in the 32K somewhere, not in pad. However, by passing pointers to the FP arguments, there's nothing to stop a user of the FP routines having his FP data in PAD if he wants to; if he's working with a cartridge in an un-expanded console, for example. In terms of the extra performance that using PAD gives, I believe the time saved not copying FP strings around will nullify the performance gain of hosting the FP strings in PAD! And anyway, if performance is a concern, go ahead and use PAD! If the FP software uses pointers then you have that flexibility! The use of VDP for FP calculations is a definate no-no, and will result in visitations in the dead of night by angry pitch-fork weilding 4A die-hards. They're a nasty bunch when they're riled . So, I'd rather see something like: LI R7,<pointer to FP arg1> LI R8,<pointer to FP arg2> BLWP @FPLLNK DATA function_code There's my tuppence worth, for what it's worth! Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 1, 2012 Share Posted October 1, 2012 Anybody got a better idea? ...lee You could write the assembly code using the TF assembler , then just load it from blocks in source form. Later you could BSAVE it for faster loading. The nice thing about assembler in Forth (as I know you know) is that you can test your assembly straight from the keyboard, just like any other Forth word. Sure, you can crash the thing real hard with assembly, but hey, that's the fun of it! Also, I find the edit/save/assemble/load/test/damn/power-off/power-on/load cycle a real PITA. I think I'm spoiled by Forth! Does your TI have a load interrupt switch fitted? TF initialises the load interrupt vector to point to TF so that you can reboot your console in the event of assembly armageddon, without recourse to the power switch. This has the advantage of leaving CPU RAM (the 32K) pretty much intact allowing post-mortems for seriously hard to debug assembly routines! Of course, when doing all this development stuff in Classic99 it's a lot easier, too! In TI994W (Fred Kaal) you can issue a LOAD interrupt from the drop-down menus. I don't think you can in Classic99 (yet?) but I guess it would be a relatively simple feature for Tursi to add. Note to Tursi, in case he's reading this: Probably more useful to have a button in the debugger, rather than in a menu? The empty space under the breakpoints list box might a suitable place? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 1, 2012 Author Share Posted October 1, 2012 ... So, I say go load over the top of the block buffers in VDP. Panic not. You'll be fine! The block buffers in VDP start at >1C20 and end at >341F. Good luck! Cool! That ought to do the job. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 1, 2012 Author Share Posted October 1, 2012 ... The FP software can process them in-situ. The difficulty with working in situ is that for FAC, at least, the FP routines use 9 bytes of FAC(!) to accommodate a rounding digit. I haven't analyzed the library closely enough to see whether a similar practice affects ARG. ... The use of VDP for FP calculations is a definate no-no, and will result in visitations in the dead of night by angry pitch-fork weilding 4A die-hards. They're a nasty bunch when they're riled . Nowhere did I suggest using VDP RAM. I am avoiding that like the plague. ...lee Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 1, 2012 Author Share Posted October 1, 2012 You could write the assembly code using the TF assembler , then just load it from blocks in source form. Later you could BSAVE it for faster loading. I definitely thought of that, but translating 6 KB of ALC to TF-ALC is a daunting prospect. ... Does your TI have a load interrupt switch fitted? No. ... Of course, when doing all this development stuff in Classic99 it's a lot easier, too! In TI994W (Fred Kaal) you can issue a LOAD interrupt from the drop-down menus. I don't think you can in Classic99 (yet?) but I guess it would be a relatively simple feature for Tursi to add. Note to Tursi, in case he's reading this: Probably more useful to have a button in the debugger, rather than in a menu? The empty space under the breakpoints list box might a suitable place? Classic99, indeed, has both a debugger menu option and a button (F12) for load interrupt. ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 1, 2012 Share Posted October 1, 2012 Ah yes! F12! Of course! Quote Link to comment Share on other sites More sharing options...
Rod Van Orden Posted October 1, 2012 Share Posted October 1, 2012 Lee: I just started looking at the five math words mentioned in #77 and #78. I have a simple question here....just wondering..... when you use UM* and set things up like: 10 20 UM* shouldn't the result be at the top of the data stack? Rod Quote Link to comment Share on other sites More sharing options...
slinkeey Posted October 1, 2012 Share Posted October 1, 2012 Depends on how much beer you consumed. Quote Link to comment Share on other sites More sharing options...
Willsy Posted October 1, 2012 Share Posted October 1, 2012 Lee: I just started looking at the five math words mentioned in #77 and #78. I have a simple question here....just wondering..... when you use UM* and set things up like: 10 20 UM* shouldn't the result be at the top of the data stack? Rod In your particular example, you're multiplying 20 by 10. Result = 200. The top stack item is the high word (i.e. the top 16 bits) of the 32 bit result (all 0), the next item on the stack being the lower word. Here's another example: 199 465 um* .s Gives: 26999 1 <TOP That's (1*65536)+26999=92535 Another example: 9900 761 um* .s Gives: -2740 114 <TOP Well, the -2740 is 62796 displayed as a signed value (try -2740 U.) So, that's (114*65536)+62796=7533900 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 1, 2012 Author Share Posted October 1, 2012 What he said! ...lee Quote Link to comment Share on other sites More sharing options...
Rod Van Orden Posted October 2, 2012 Share Posted October 2, 2012 Thanks, guys! I just finished straightening out all my files. I'm good now. I'll do some other examples and put up the results. Rod Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 2, 2012 Author Share Posted October 2, 2012 ... Lee, would you mind stress-testing the following Math words: */ UM* /MOD */MOD UM/MOD ... Mark */ works fine. As expected out-of-range and divide-by-zero answers are garbage numbers. Well, division by zero gives -1 but that can obviously also be a legitimate answer. I guess that in Forth you need to know what to expect. There's no way to get feedback from the math function that there was an error like there is with the FP package. It would probably slow things down. ...lee 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.