+TheBF Posted June 13 Share Posted June 13 1 hour ago, FarmerPotato said: @TheBF Thanks! That's a nice binary tree. I should study other data structures in there. Ya it's pretty tidy. For the life of me I have never been smart enough to know why I would need a binary tree for data. I guess the speed of searching is valuable? 1 hour ago, FarmerPotato said: For Word processing: I'm not doing a general binary tree--no pointers. The one feature from Heapsort is the fixed-memory space, in place tree manipulation. My "pointers" are just integers, and LEFT, RIGHT, UP are just integer math, since the tree is predictably laid out as 2^n cells per layer. To traverse does not require recursion or a stack. It's like a mouse-in-the-maze right hand wall follower. . The node content is just a pointer into a block buffer. In operations, only pointers are swapped--to compact the tree or insert. OK so it's a doubly linked list I guess. I have been noodling that kind of thing too. So you keep the text in block buffer "records" and the word processor goes through an array of links in RAM? Are the strings in the block buffers held in fixed length records? 1 hour ago, FarmerPotato said: Box Diagrams Need General Binary Trees In a different algorithm, my hierarchy diagram box and lines drawing code, I do use a general binary tree. (Here I also pass xt's --for the style to draw the box or line.) In C, I implemented the drawing algorithm with two stacks, two while loops, no recursion. My Forth code for that is ugly and I can take hints from this nice tree implementation. In my box diagram drawing code, I use the names DLINK and RLINK instead of LEFT/RIGHT. Left links point down in the printout. Right go.. well, right! (Across the page.) Here is a recursive line drawing function written by the late Dr. C. H. Ting that I have used for years. Not the fastest but pretty small. CODE word could speed up the 2ROT, 4DUP and the mid-point computation ( + 1+ 2/ ) DECIMAL : 2ROT ( d1 d2 d3 -- d2 d3 d1) S" 2>R 2SWAP 2R> 2SWAP" EVALUATE ; IMMEDIATE : 4DUP S" 4TH 4TH 4TH 4TH" EVALUATE ; IMMEDIATE : LINE ( x1 y1 x2 y2 -- ) \ ANS version of Dr. Ting's recursive line. R.I.P. 4DUP ROT - ABS >R - ABS R> \ compute dx dy MAX 2 < IF 2DROP PLOT EXIT THEN \ nothing do, get out 4DUP ROT + 1+ 2/ >R \ compute mid points + 1+ 2/ R> 2DUP 2ROT RECURSE RECURSE ; 3 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted June 14 Author Share Posted June 14 That's more sophisticated than my drawing! : DRAWEDGE ( Len --) ASCII + EMIT 2- 0 DO ASCII - EMIT LOOP ASCII + EMIT ; +-------+ +-------+ | FORTH |---| STACK | +-------+ +-------+ The data structure has right-links and down-links. A first pass assigns the boxes to columns and finds the max width of each column. The second pass prints everything. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted June 14 Share Posted June 14 Ah. I completely misunderstood. That's an interesting approach. The DOS Forth I have, HsForth uses a data structure to hold the upper left corner x,y and the lower left corner x,y. From that data it draws the box. It's overkill as is for TI-99 but the idea is interesting. It might look like this in TI-FORTH : MAKE-WINDOW ( fg bg upperrow leftcol bottomrow rightcol -- ) <BUILDS , , , , , , DOES> ; You pass that data structure to >WB and it does all the magic of drawing the window with a border and setting EMIT, PAGE and key to work only in that window. There are other words to change the border characters from the default double line characters we saw in DOS. 3 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted August 19 Author Share Posted August 19 (edited) Geneve 2020 project is active again! With the Leakseeker, I've corrected my build faults. Got chips back in. Now I see correct instruction stream on the bus, (though it doesn't get past the RS232 polling loop.) But there is no workspace. The first RAM footprint--I was looking for shorts under there and ruined some pads. (Leak seeker now tells me: not even close.) To boot anything requires RAM in the low numbered pages. I can populate another bank and bodge wire the chip select pin. New lesson learned: don't install chips that aren't necessary yet. Leave even the tiny ones until absolutely necessary. The thing that absorbed a flying molten solder ball was an LS138 (surface mount) to decode external instruction like RSET. That was probably while I was trying to reflow the RAM. For testing, I could have left that LS138 empty. Just pull the RSET output high. (RSET is a soft reset instruction. The user button hard-resets the CPU and the 9901. RSET goes to the external bus and a flip flop.) Edited August 20 by FarmerPotato 6 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted August 19 Author Share Posted August 19 Observed: when there's no RAM on the data bus for the 99105 to read, it sees the last value of the address bus. (multiplexed AD pins.) Something has a "bus keeper" behavior. This: LWPI >8000 LI R12,>1300 !No RAM! ... TB 23 JEQ ... Reads the *address* of R12 as the value of R12. So >8018 (WP+24) for the CRU base, add 23 (>2E after shift) get >8046. That's a parallel address where TB is undefined. It reads a 0. But hey, no shorts! 5 Quote Link to comment Share on other sites More sharing options...
Jimhearne Posted August 19 Share Posted August 19 2 minutes ago, FarmerPotato said: Observed: when there's no RAM on the data bus for the 99105 to read, it sees the last value of the address bus. (multiplexed AD pins.) Something has a "bus keeper" behavior. That's just the capacitance on the data bus, when the bus is switched from address to data, if there is nothing driving the bus it just floats and stays at the last value for a bit.. 5 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted August 20 Share Posted August 20 (edited) On 8/19/2024 at 11:56 AM, FarmerPotato said: Observed: when there's no RAM on the data bus for the 99105 to read, it sees the last value of the address bus. (multiplexed AD pins.) Something has a "bus keeper" behavior. This: LWPI >8000 LI R12,>1300 !No RAM! ... TB 23 JEQ ... Reads the *address* of R12 as the value of R12. So >8018 (WP+24) for the CRU base, add 23 (>2E after shift) get >8046. That's a parallel address where TB is undefined. It reads a 0. But hey, no shorts! Last time I had no shorts the lady at the Safeway told me I had to go home. 😎 Edited August 29 by TheBF typo 6 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted August 26 Author Share Posted August 26 Broken things list: 1. Code wasn't running correctly and it wasn't entirely my logic probe. Found another short last night, this time underneath a PLCC eeprom socket. So more SMT rework... yuck. Bit A13 is shorted to A14. LDCR became JH and LI R12,>2106 became >0106. Those PLCC SMD sockets are the biggest troublemakers of all. Liking my plan (above) to redesign using through-hole EEPROM. 2. Forth interpreter now has SYSTEM abstracted for 4A and Geneve ?KEY, EMIT etc. but there's LOAD, locks up in ERROR and WARNING. There is no blocks file (which will first map directly to EEPROM and RAM). 3. *Still* did not receive a LS259 whose package matches the wide footprint I designed in. I swear the OnSemi part had the old SO footprint when I picked it. Kludging a NS package on the pad, is likely to make a nasty short from A2 to ground via. (DON'T put ground vias next to any other pins!!!) Reluctant to begin anew with PCB copy #3. Got a couple of ideas from the beautiful Permanent Solderless Breadboard Projects 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted August 27 Share Posted August 27 7 hours ago, FarmerPotato said: Broken things list: 1. Code wasn't running correctly and it wasn't entirely my logic probe. Found another short last night, this time underneath a PLCC eeprom socket. So more SMT rework... yuck. Bit A13 is shorted to A14. LDCR became JH and LI R12,>2106 became >0106. Those PLCC SMD sockets are the biggest troublemakers of all. Liking my plan (above) to redesign using through-hole EEPROM. 2. Forth interpreter now has SYSTEM abstracted for 4A and Geneve ?KEY, EMIT etc. but there's LOAD, locks up in ERROR and WARNING. There is no blocks file (which will first map directly to EEPROM and RAM). 3. *Still* did not receive a LS259 whose package matches the wide footprint I designed in. I swear the OnSemi part had the old SO footprint when I picked it. Kludging a NS package on the pad, is likely to make a nasty short from A2 to ground via. (DON'T put ground vias next to any other pins!!!) Reluctant to begin anew with PCB copy #3. Got a couple of ideas from the beautiful Permanent Solderless Breadboard Projects I can't remember which Forth you ended up using. Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted August 28 Author Share Posted August 28 On 8/26/2024 at 8:06 PM, TheBF said: I can't remember which Forth you ended up using. It started as McCann Software Forth for Geneve. I don't have the TI Forth source (it's out there right?) but I think it is pretty close. The Forth kernel is just under 8K. Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 28 Share Posted August 28 2 hours ago, FarmerPotato said: I don't have the TI Forth source (it's out there right?) Yes. It is listed and annotated by me in “Appendix O” in my second edition of the TI Forth Manual referenced in the pinned “TI-99/4a development resources” in this forum. Here are copies of the original source disks: TIForthSource.zip ...lee 1 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted August 28 Share Posted August 28 That's very cool. Was this dis-assembled from TI-Forth or did someone get the files from TI? Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 28 Share Posted August 28 13 minutes ago, TheBF said: That's very cool. Was this dis-assembled from TI-Forth or did someone get the files from TI? As I recall, the disks were distributed to TI-99/4A user groups by TI when they put TI Forth into the public domain in December, 1983. I certainly never disassembled it. The original disks were labelled “03NOV82” and “08DEC82”. The first had ASMSRC, ASMSRC1, ASMSRC2, and ASMSRC3. The second had BOOT, DRIVER, UTILEQU, UTILROM, and UTILRAM. ...lee 2 2 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted August 29 Share Posted August 29 7 hours ago, FarmerPotato said: It started as McCann Software Forth for Geneve. I don't have the TI Forth source (it's out there right?) but I think it is pretty close. The Forth kernel is just under 8K. And the McCann Software Forth was a further development of TI Forth, and was then further developed into Forth+ 3 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted August 29 Author Share Posted August 29 (edited) So LeakSeeker was indicating a short right under the PLCC socket... the last thing I want to mess with again. I realized as I was building the Leakseeker--I have a bench DMM that gives mOhms. I used the new probes on it. Probe tips on solder pad contribute 250 mOhm. This is the journey of two parallel traces, continuous from CPU to ext bus driver. Testing for A13 A14 short Measuring between close pairs of pins or vias Probes add ~250 Signal AD13 AD14 mOhms CPU pin 18 17 550 (gold) CPU sock 18 17 550 CPU back 18 17 500 CPU via . . 460 573 via 16 17 360 ROM via . . 300 ROM pad . . 270 (better contact) ROM sock D13 D14 260 (very good contact) next via . . 340 about 1" of trace RAM1 pad D13 D14 410 (good solder on pad) RAM2 pin " " 470 RAM3 pad " " 500 driver via 600 poor contact driver pad 13 12 580 pretty good contact The 573 is the latch to demultiplex Address from AD. I tried to remove some solder. I tried hot air. I removed the whole socket. There's the blob. New resistance: 515000 mOhms 515 kOhms CPU appears to be damaged -- unable to drive AD13 low. Swapping to the previous CPU fixed that. No response from ROMs during ROMEN. Silent FFFF. Continuity checked out everywhere... Edited September 1 by FarmerPotato kOhms 6 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted September 5 Author Share Posted September 5 The current CPU schematic, moved to a PEB card. In thru-hole, except for the 3 512K SRAMs. It is too cramped for routing. This is a rehearsal for doing another wire-wrap build. 5 Quote Link to comment Share on other sites More sharing options...
stevee671 Posted September 5 Share Posted September 5 18 hours ago, FarmerPotato said: The current CPU schematic, moved to a PEB card. In thru-hole, except for the 3 512K SRAMs. It is too cramped for routing. This is a rehearsal for doing another wire-wrap build. What if you off loaded some of that to a daughter board? 1 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted September 6 Author Share Posted September 6 1 hour ago, stevee671 said: What if you off loaded some of that to a daughter board? Yeah. The memory probably. I can't replace the surface mount RAM with THT reasonably. They have to be 16 bits wide. These RAM chips are 2(6K x 16. In THT I could use 2 or 4 big 512K x 8. And those cost much more. Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted September 17 Author Share Posted September 17 On 8/28/2024 at 11:23 PM, FarmerPotato said: So LeakSeeker was indicating a short right under the PLCC socket... the last thing I want to mess with again. I realized as I was building the Leakseeker--I have a bench DMM that gives mOhms. I used the new probes on it. Probe tips on solder pad contribute 250 mOhm. This is the journey of two parallel traces, continuous from CPU to ext bus driver. Testing for A13 A14 short Measuring between close pairs of pins or vias Probes add ~250 Signal AD13 AD14 mOhms CPU pin 18 17 550 (gold) CPU sock 18 17 550 CPU back 18 17 500 CPU via . . 460 573 via 16 17 360 ROM via . . 300 ROM pad . . 270 (better contact) ROM sock D13 D14 260 (very good contact) next via . . 340 about 1" of trace RAM1 pad D13 D14 410 (good solder on pad) RAM2 pin " " 470 RAM3 pad " " 500 driver via 600 poor contact driver pad 13 12 580 pretty good contact The 573 is the latch to demultiplex Address from AD. I tried to remove some solder. I tried hot air. I removed the whole socket. There's the blob. New resistance: 515000 mOhms 515 kOhms CPU appears to be damaged -- unable to drive AD13 low. Swapping to the previous CPU fixed that. No response from ROMs during ROMEN. Silent FFFF. Continuity checked out everywhere... Progress with hardware bugs. It runs code! Initializes the 9902, sets two LED bits to move state from RED to AMBER (no LED change observed), then loops waiting for CTS in. Going to test/debug serial next. Data bus (FFFF) problem went away when I removed the LS612. Afraid that I fried it. Don't need it yet. Maybe double-check the loading on the data bus. Must be a bad solder joint still under the EEPROM. A1 was stuck 0 on both (even/odd bytes). When I press down on the chips there, it "sticks" but comes loose again overnight. Very, very carefully, soldered the LS259 that caused so much trouble before--footprint is the D size, chips only come in NS (narrow). It is just barely possible to center the chip, then bridge the pins to the pads. Trouble was an A2 via next to the GND pin. Used a tiny wire, so no short this time. 2 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted September 17 Author Share Posted September 17 On 8/28/2024 at 2:32 PM, Lee Stewart said: Yes. It is listed and annotated by me in “Appendix O” in my second edition of the TI Forth Manual referenced in the pinned “TI-99/4a development resources” in this forum. Thank you, thank you, thank you. I'm getting very familiar with tracing through Forth execution (Classic 99). Spent a lot of my free time building a debug window and making it pretty. Has screen divided into 3 windows. One window scrolls the name of the NEXT word. Another shows registers and stacks. NEXT also checks that IP and code field are at a valid address. Still have not debugged BOOT (I first removed 3 LOAD). QERROR crashes in TYPE. I made the error messages built-in, like TI Forth "message". When I solve that, I can switch the SYSTEM table to call serial port versions of ?KEY and EMIT. Put the kernel in ROM, and RAM at 8300 up. One tricky thing: I need HERE to point into RAM, though the kernel is in ROM. Not sure yet how to change DP, CURRENT and CONTEXT for that. 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 18 Share Posted September 18 (edited) 10 hours ago, FarmerPotato said: One tricky thing: I need HERE to point into RAM, though the kernel is in ROM. Not sure yet how to change DP, CURRENT and CONTEXT for that. DP is a "user" variable. (Just means it can be made thread safe but FigForth never did multi-threading out of the box) So if you want to point the dictionary to >A000 here is the incantation: HEX A000 DP ! So you setup everything that needs "settin' up" in the boot up code running in ROM and then move DP to RAM. That's covers the dictionary. But... the "user" variables are in a block of memory (user area) pointed to by a register or a variable. That should be copied into RAM as well first. I should think you would put that "user area" at >A000 and the set DP beyond that. In Camel99 I created two variables that hold the addresses that I want the system to boot with. They are called ORGDP ie: the start Dictionary pointer and ORGLAST which holds the name field of the last word in the in dictionary ie: where word searching starts. Here is the warm boot code for setting the dictionary and CONTEXT and CURRENT in my system ORGDP @ DP ! ORGLAST @ LATEST ! LATEST DUP CONTEXT ! CURRENT ! For clarity CONTEXT and CURRENT are pointers to pointers. So we record the address of the variable LATEST in the variables CONTEXT and CURRENT. Clear as mud? Edited September 18 by TheBF typo 3 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 18 Share Posted September 18 By the way I made a cooperative multi-tasker for FbForth that should move to TI-Forth pretty easily. \ MULTI99.FTH for FbFORTH 27 APR2021 Brian Fox \ Derived from COOPTASK.MAX for MaxForth 68HC11 B Fox 1992 \ Forth multi-tasker using a single workspace with separate \ data stack, return stack and user area for each task. 21 LOAD \ needs the Assembler FORTH DEFINITIONS 1 CONSTANT TRUE 0 CONSTANT FALSE \ PID (process I.D.) is the base address of a user area \ original name was MYSElf. Already used in FigForth so changed to ME ASM: ME ( -- PID) SP DECT, UP *SP MOV, ;ASM ASM: UP! ( addr -- ) *SP+ UP MOV, ;ASM ME CONSTANT USER0 \ USER0 is the primary Forth task \ add these user variables to FbFORTH HEX 6E USER RSAVE \ temp storage for RP register 70 USER TFLAG \ flag for awake or asleep 72 USER TLINK \ link to next task 74 USER JOB \ copy of running XT ( *** CALL INIT-MULTI ONCE before multi-tasking ***) : INIT-MULTI ( -- ) USER0 UP! \ reset root user-pointer register ME TLINK ! \ round robin links to ME TRUE TFLAG ! ; \ mark my task flag as AWAKE \ Coventional Forth context switcher ASM: YIELD ( -- ) RP DECT, SP *RP MOV, \ Rpush SP RP DECT, IP *RP MOV, \ Rpush IP RP 6E @(UP) MOV, \ RP -> LOCAL RSAVE BEGIN, 72 @(UP) UP MOV, \ switch context 70 @(UP) R0 MOV, \ test this tflag for zero NE UNTIL, \ until a task is awake 6E @(UP) RP MOV, \ restore RP this task RP *+ IP MOV, \ pop this task's IP RP *+ SP MOV, \ pop this task's SP ;ASM \ run NEXT \ 833A CONSTANT 'NEXT \ for patching SINGLE HEX 80 CONSTANT USTACKS \ 20 cells per stack per task USTACKS 2 * CONSTANT USIZE \ FbForth USER area + STACKS DECIMAL \ compute address of a USER variable in any PID \ Editors note: LOCAL is clever. Comes from early Forth \ multi-tasking systems. Usage: TASK1 RSAVE LOCAL @ : LOCAL ( PID uvar -- addr) ME - + ; : SLEEP ( PID -- ) FALSE SWAP TFLAG LOCAL ! ; : WAKE ( PID -- ) TRUE SWAP TFLAG LOCAL ! ; HEX \ compute base address of the local stacks in a PID : TASK-SP0 ( PID -- addr) USIZE + 40 - ; : TASK-RP0 ( PID -- addr) USIZE + 2- ; \ used to push values onto a local return stack : TASK-RP-- ( PID -- ) -2 SWAP RSAVE LOCAL +! ; : TASK>R ( n PID -- ) DUP TASK-RP-- RSAVE LOCAL @ ! ; : INIT-USER ( PID -- PID) DUP USIZE FF FILL \ init whole user area for debugging USER0 OVER 80 CMOVE ; \ copy USER0's user variables : SET-RP0 ( PID -- PID) DUP TASK-RP0 OVER RSAVE LOCAL ! ; : SET-SP0 ( PID -- PID) DUP TASK-SP0 OVER TASK>R ; \ add PID to round-robin list : LINK-TASK ( PID -- PID) TLINK @ ( -- pid previous) OVER TLINK ! ( -- pid ) OVER TLINK LOCAL ! ; : FORK ( PID -- ) INIT-USER \ copy USER0 into a new task SET-RP0 \ set this RP0 LINK-TASK \ insert into round robin SET-SP0 \ set this SP0 SLEEP \ don't wake me up yet :) ; : ASSIGN ( XT PID -- ) OVER OVER JOB LOCAL ! \ keep a copy for restarting TASK>R ; \ push PFA onto local rstack DECIMAL INIT-MULTI ( setup the USER0 for mult-tasking) 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted September 18 Share Posted September 18 (edited) 16 hours ago, TheBF said: Here is the warm boot code for setting the dictionary and CONTEXT and CURRENT in my system ORGDP @ DP ! ORGLAST @ LATEST ! LATEST DUP CONTEXT ! CURRENT ! I don’t know about how CAMELL99 Forth handles vocabularies, but in TI Forth and fbForth, LATEST is not a user variable. It returns the last-defined word’s nfa in the CURRENT vocabulary: : LATEST CURRENT @ @ ; CONTEXT and CURRENT each point to a vocabulary name link field (actually, the pfa of the word invoking the vocabulary), which, in turn, points to the name field of their respective that vocabulary’s last-defined word. This would be the code for TI Forth and fbForth: ORGDP @ DP ! \ set DP ( HERE ) to original DP FORTH DEFINITIONS \ set CONTEXT and CURRENT to the FORTH vocabulary ORGLAST @ \ get the original last FORTH definition CONTEXT @ ! \ set FORTH’s latest-definition pointer to ORGLAST “CURRENT @ !” is redundant because it points to the same vocabulary as CONTEXT in the above code. ...lee Edited September 18 by Lee Stewart CORRECTIONS 1 & 2 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted September 18 Share Posted September 18 3 hours ago, Lee Stewart said: I don’t know about how CAMELL99 Forth handles vocabularies, but in TI Forth and fbForth, LATEST is not a user variable. It returns the last-defined word’s nfa in the CURRENT vocabulary: : LATEST CURRENT @ @ ; CONTEXT and CURRENT each point to vocabulary name fields, which, in turn, point to the name fields of their respective last-defined words. This would be the code for TI Forth and fbForth: ORGDP @ DP ! \ set DP ( HERE ) to original DP FORTH DEFINITIONS \ set CONTEXT and CURRENT to the FORTH vocabulary ORGLAST @ \ get the original last FORTH definition CONTEXT @ ! \ set FORTH’s latest-definition pointer to ORGLAST “CURRENT @ !” is redundant because it points to the same vocabulary as CONTEXT in the above code. ...lee Thanks. I can use this to trim some fat. Out of the box Camel Forth had no vocabulary support just a variable LATEST that held the NFA of of the last defined word. It was meant to be a minimal system. I messed around and shoehorned wordlists etc. into the system. I always new it could be simplified but it worked so I didn't mess with it once I got it working. More work for me. 2 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted September 18 Author Share Posted September 18 I'm confused by the dictionary pointers because I learned ANS dialect for VOCABULARY. I haven't sat down to learn how it used to work. I saw that FORTI relied on VOCABULARY. Between VOICE: and FINIS you have note compiling words A AA B BB ... FF GG , which otherwise would be hex constants. So I wrote that in ANS once and tested it on ... MeCrisp Forth. 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.