Jump to content

TheBF

+AtariAge Subscriber
  • Posts

    4,470
  • Joined

  • Last visited

Everything posted by TheBF

  1. Which validates the government secret that all electronic devices operate on smoke because once that smoke comes out they don't work anymore. If someone could figure out how to put the smoke back inside... they'd be rich.
  2. ANS Forth shortest quine just for fun.
  3. Yes it is that E/A cartridge and disks that I used. Now moving from BASIC to 9900 Assembler, interacting politely with the BASIC "internals" is not trivial. I had some hardware background in me so it was not totally magic. But the group here is the best of the best for TI-99 coding so that can no doubt provide some training wheels. I might...(maybe) still the have code I wrote on a 35 year our floppy disk. I will see what I can find. To give you some high-level background you are going make some specific sub-routines in Assembler like: position the cursor at (x,y) maybe print text at (x,y) coordinates on the screen write a bunch of text to the screen in multiple places (which will could use the cursor sub-routine and print sub-routine) The you will call them by the name you give them from BASIC. Pretty cool.
  4. I read it as the addressing range is the parameter that determines the record type and 64Kbytes was the range of 8 bit machines. This would put the 9900 in that camp too. (barring writing an extended version to capture SAMS memory) Anyway. If your decoder was set up for record type 00 then we were on the same page all along. From what I can see the MaxForth IntelHEX output file is compliant.
  5. I see a source of confusion in this document I linked you to. Intel Hex Format (interlog.com) It is using record type 02. My encoder is the using record type 00. Wikipedia has a fuller explanation of each record type. My apologies. I did not know about the extended record types when I found this document. I thought IntelHEX was one thing.
  6. My mistake. Summing these bytes is used only to initialize the CHKSUM variable. As I built the loader program I began to understand what Randy's code was doing on the encoding side. The code above was used for an integer argument. It is split into two bytes and the bytes are added together. The resulting byte is then added to the checksum. 34 years ago I didn't take the time to figure this out. I just used the program. In CAMEL99 Forth this becomes: SPLIT + (SPLIT is a code word that I made to solve some problem in the Graphics code way back when. It has a reciprocal called FUSE, which fuses two bytes into an integer.)
  7. This was the reason that I learned Assembler. I had made a database with a formatted screen for all the fields. Even in XB formatting the screen was painful. (and wasn't old enough to collect pension) My mind was blown when I got it working in Assembler and it flashed on the screen "instantly".
  8. Record type 0 has a byte sized count so it's length is limited to 255. Randy's encoder is reading memory a byte at time and outputting the byte value to the record. From Wikipedia: "Programs that create HEX records typically use line termination characters that conform to the conventions of their operating systems. For example, Linux programs use a single LF (line feed, hex value 0A) character to terminate lines, whereas Windows programs use a CR (carriage return, hex value 0D) followed by a LF."
  9. From what I can see this file complies with DATA record type "00" Randy's code seems to be the simplest version that only handle record type 00 and 01. "Special names are sometimes used to denote the formats of HEX files that employ specific subsets of record types. For example: I8HEX (aka HEX-80) files use only record types 00 and 01" https://en.wikipedia.org/wiki/Intel_HEX
  10. Interesting. The encoder that I am using is a hand me down from the MaxForth development system but Randy, the author, died in 2022 so we can't ask him. It is possible that there is a dependancy in his code for Motorola 6811 CPU. A byte order thing would not surprise me given the 9900's personality. I see he does the checksum computation at the byte level by taking each byte in a integer adding them together and adding that sum to the CHKSUM. DUP >< FF AND OVER FF AND + CHKSUM +! There are a number of data length options for IntelHEX. In the Wikipedia article it shows what looks like extensions for larger word size for new CPUs. What I know is that this program output a file that worked perfectly with an old EPROM burner that I had so I had no reason to question it. I may be able to find my old 68hc11 dev board and get a sample output of the same data from this code. I will review the spec too and see if it gives me any insights. On we go.
  11. I supposed it's worth showing how I made the file. I used a little fill memory loop and then used my OUTFILE library to capture the output of INTELHEX to a file. Here is the "script". INCLUDE DSK1.OUTFILE INCLUDE DSK2.INTELHEX \ FILLMEMORY HEX : FILLMEM ( ADDR #cells -- ) 0 DO I OVER ! CELL+ LOOP ; HEX 2000 1000 FILLMEM S" DSK2.4KHEXDUMP" MAKE-OUTPUT 2000 1000 INTELHEX CLOSE-OUTPUT Is not perfect because it has one empty line at the top so I just loaded it into the editor and removed the top line and re-saved.
  12. So LOADHEX is not a speed demon. 27 seconds to parse and load a 4K test file to memory. I think a big part of speed is in the word >NUMBER which is written for double number conversion. If we wrote a bespoke 16 bit number convertor we might get it a bit faster. But I am ok with it. The alternative is to do what @VORTICON did and write the output to a binary file that the file system can inhale. Hmmm. INHALE might be good name for that file function.
  13. Ok this took me longer to get working than it should have but here is an Intel HEX loader. I got a bit cheeky. Since the data consists of lines of text we need some kind of parser. I wondered if could use the approach we see in string words that take address,length pairs and return a new string pair. So the secret of this method is CHOP. CHOP takes a string and CHOPs at an index but it returns both the chopped string AND the remaining string underneath. \ renamed for clarity of purpose : LEFT$ ( addr len n -- addr len' ) NIP ; : RIGHT$ ( addr len m -- addr' len') /STRING ; : CHOP ( addr len n -- addr1 len1 addr2 len2 ) >R \ we need n twice, use return stack 2DUP R@ LEFT$ \ substring 2SWAP R> RIGHT$ \ "RIGHT$" is remainder 2SWAP ; \ substring back on top ; Armed with this powerful tool we can make field "tags" that chop the correct number of bytes from the string and convert them to a number. : $VAL ( addr len -- n) NUMBER? ABORT" Bad number" ; : <?START> ( addr len -- addr' len') 1 CHOP DROP C@ [CHAR] : <> ABORT" Start code not found" ; : <RECLEN> ( addr len -- addr' len' n ) 2 CHOP $VAL ; : <ADDRESS> ( addr len -- addr' len' n ) 4 CHOP $VAL ; : <RECTYPE> ( addr len -- addr' len' n ) 2 CHOP $VAL ; : <DATA> ( addr len -- addr' len' n ) 4 CHOP $VAL ; \ This is the last tag. It consumes the string. : </CHKSUM> ( addr len -- n ) $VAL CHKSUM ! ; This becomes our little language for parsing the lines of text. I think this is a very different way to make a parser that we might see in another language. This all culminates with LOADHEX that reads an IntelHEX file and loads it into memory per the addresses in the file. It's a bit like TI object code but with only one function. ie: put these numbers in memory. The rest was just getting the whole thing organized into a loop structure. Again I resorted to the double WHILE construct because we need to test two conditions. Is the file empty and is this the "end of data: record. The entire file is here. I have not implemented computing the checksum on the file data as it is read. I should be able to use Randy's code from the IntelHEX encoder to make that work and add the calculation to the <DATALINE> tag. That's a follow up job.
  14. You been keeping us all legit on Atariage since 2011 Lee.
  15. I may be wrong but I see the data fields as unsigned integers. I parse four digits of text and convert them to an integer.
  16. Cool! Typically this program would load the file into memory, so you might be able to make a simpler version that doesn't need an output file. It just reads the address field and puts each data word into sequential memory "cells". I had to travel today for business but I am doing a Forth version called HEXLOAD.
  17. If you think of the screen as a text buffer but in VDP RAM you could copy it from there with VMBR I made a block file editor that worked that way.
  18. I proposed the idea of using Intel HEX format for transforming binary files to a Pascal program over in another thread. I reached back into my archive and found the program I used to get the a binary image of my MaxForth programs sent to the terminal. I would send this code to Maxforth over RS232. Then I would turn on the file capture on the terminal and type something like HEX 0 2000 INTELHEX to capture an 8K of RAM at address >0000. Then I could send the intelHEX file to my ROM burner. Ah.. the good old days. The output from the program is in the video. I am working on a parser and loader so that I can transfer data to my hardware TTY Forth. Here is the code for Camel99 Forth. IntelHEXdump.mp4
  19. Really cool. Is TI-99 playing the music in the background?
  20. Those are pretty nice upgrades Lee. I suspect you will save a few cycles in the overall operation without that SYSTEM table. How big was that SYSTEM table?
  21. This picture from wikipedia tells nicely how to decode intelHEX. (I am gonna do one in Forth now for myself. ) I just read that it this goes back to 1973 so it fits well with our hobby. File example[edit] This example shows a file that has four data records followed by an end-of-file record: :10010000214601360121470136007EFE09D2190140 :100110002146017E17C20001FF5F16002148011928 :10012000194E79234623965778239EDA3F01B2CAA7 :100130003F0156702B5E712B722B732146013421C7 :00000001FF Start code Byte count Address Record type Data Checksum
  22. An alternative that might be work is to convert your binary files to Intel HEX format. Intel Hex Format (interlog.com) Intel HEX is a text version of a binary file. I used to use it to send binary data FROM embedded boards to the terminal in the past. I might be able to make a tool for TI-99 to convert a binary file to intel hex. Then you would need a converter in PASCAL to convert the other way.
  23. I made the mistake of trying to use the Camel99 Linker. Homemade software. Amateur coder. What can I say. Anyway I had to dig in and make external references work properly. Turns out I had not tested that functionality enough. Currently I only can handle relocatable code. AORG programs may not be possible with this method. (?) Explanation: All the DEF references in a "library" become words in the DEFS vocabulary when the object file is linked. The DEFS words become Forth CONSTANTs. They just return the entry address of the external code, where it sits in TI-99 low RAM after linking. When your program has REF to an external DEF the object code, it has strings embedded in it at the end that are "tagged" with a '3' if it is a RELOCATABLE reference. Like this: 30016VFILL 30026VMBW After the '3' the next 4 chars are a number which is the offset in memory (from the current load point) where there is a missing address. The next 6 characters are the text name of the missing program. Using Forth's FIND function, which we restrict to looking only in the DEFS vocabulary, we get the missing address and store it (with !) in low RAM at the offset+BASE-MEM. Simple! Here is the business end of the code for TAG 3 written "linker Forth" This made it pretty simple to create the functionality once I got my head around it. : RELOCATE ( addr -- addr') BASE-MEM + ; : ?REF 0= IF CR CR ." ? External REF not loaded" CR ." >>> " PAD COUNT TYPE ABORT THEN ; : FIND-EXT ONLY DEFS FIND \ search only the defs vocabulary ONLY FORTH ALSO DEFS ; \ restore normal searching : TAG3 PARSE# RELOCATE >R \ External address to Rstack GETLABEL PAD PLACE \ store label in PAD PAD FIND-EXT NIP ?REF \ check the dictionary PAD COUNT EVALUATE \ evaluate DEF word to generate the address ( defaddr ) R> ! \ store the def addr in Extern memory ; So here is LINKERIII. It still does not let you save a binary version of your program but you can explore and run sub-routines and programs and change data in your assembly language programs all from within Camel99 Forth. CAMEL99-ITC/UTILS/LINKER at master · bfox9900/CAMEL99-ITC (github.com) And here is a video of how you might use it.
  24. This might too ambitious but this xfer program says it is an Xmodem transfer program in Pascal. Ureal what you can find on Github. pascal_sources/comm/xfer10.zip at master · codersclub/pascal_sources (github.com) Files in this archive: XFER.PAS Main source code file. Contains constant definitions, CRC calculation code and command line parameter processing. SXRX.INC Include file for XFER.PAS. Contains functions to send and receive Xmodem. XFER10.DOC This documentation file. XFER.EXE The complete compiled version, in case you don't have the IBMCOM unit or Turbo Pascal.</PRE>
×
×
  • Create New...