Jump to content

jedimatt42

Members
  • Content Count

    3,431
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by jedimatt42

  1. It's just a casual conversation time... feel free to host something in time frame that works for you. Maybe that also works for other like minded people.
  2. For the Sunday times, set the 'My Location' field on the form here: https://www.timetemperature.com/time-tools-advanced/utc-2020091303pm-us-oregon-pacific-12.html and you should get the time you need. For the Saturday times, do the same here: https://www.timetemperature.com/time-tools-advanced/utc-2020091911am-us-oregon-pacific-12.html They alternate every week to try and provide options...
  3. I have with all the same markings, and it only gives me a black & white picture from the 4A composite output. I only tried it on one console... and then stuck it in a drawer. But, more importantly, I don't recall seeing a door like that in Tunnels of Doom.
  4. Just an update on my progress, as it has been a couple months almost... I have restructured the ROM to be 128k. I have moved all the code into ROM - no longer copying 8k of libti99 up into expansion ram. And removed a number of pre-allocations to stack as needed. So now the system only uses the lower expansion ram. There is about 4k of stack space. If detected, SAMS mapping is turned on and the first 8 pages are mapped into the 32k lower and upper expansion in sequence. And I have created an API table in bank_0. -- So, I'd like to describe the approach and welcome criticism. Loading PROGRAM images that have a ForceCommand header is performed by searching device/directories specified by the PATH environment variable. If the file matching the name is found, and it is a PROGRAM and the first word is 0xFCFC then it'll load. The program image is not a split EA5 binary. It would be more like a cartridge image, but on the TI file system as a PROGRAM file. When loaded, up to the first 24k will be loaded into 0xA000 -> 0xFFFF, including the 8 word header. The last word in the header is the program entry address. Basically the gcc calling convention is used. But this is pretty easy to cope with from raw assembly in my opinion. So I'll describe in terms of assembly... When your program is called with a BL, the cartridge will be in bank_0, so the API indirection table is available. R11 will be the return address to resume into the cartridge. R1 will be the address of command parameter string - if you type HELLO /B WORLD, and your program is HELLO, then R1 will be the address of "/B WORLD" (which will be a zero terminated string) R10 will be the stack pointer - to put an int on the stack: AI R10,-2, mov yourthing,*R10 Programs are responsible for popping the stack on the way out.. So when you return to cartridge space, it is expected that R10 is the same as when your program was entered. R1 should be an integer return value set to 0 if the program ran without error, or non-zero if an error was encountered. Workspace Pointer will be 0x8300. The API in the cartridge is callable using data in the table starting at 0x6080. 0x6080 is the address of the address of the system call routine ( to enter into the bank switching world of the cartridge space. ) then the table consists of a function address and bank address pair. An equate file, and gcc header file will be provided. But for instance, the first entry in the API is the terminal output fc_tputs - table entry 0x6082 So, to call that, do something like: DECT R10 ; push R11 on the stack MOV R11,*R10 ... LI R0,>6082 ; load API index into R0 LI R1,MSG ; set R1 points to the c-string to send to the terminal display LI R11,>6080 ; call the api BL *R11 ... MOV *R10,R11 ; pop from the stack and restore R11 INCT R10 CLR R1 ; set program to return 0 to force command RT ; return to force command API functions are likely to use most, or all the registers. You are free to stash registers you need to preserve on the stack, or use a different workspace, or whatever other TMS9900 assembly techniques you like. API parameters are passed as R1 - R9. R0 is the API index you'd like to call. R10 must be a stack space ( grows down ). The stack space can be the same stack space given when the PROGRAM was executed. I am working on API calls to make sure they are useful.. and to provide access to things like the current device/directory, and where the program was found and executed from. And current display attributes will be needed to be available. The header as I've defined it, is 4 words... 1st is just a ForceCommand flag. 2nd is either 0x0000, or the number of SAMS pages that should be loaded from the program image... 3rd is a promise from your program, if 0xFCFC then ForceCommand will not reset the screen when your program returns. If anything else, then the previous display mode will be re-established. The 4th word in the header is the entry point address of your program. Most of this is implemented, but it's proof of concept level right now... There are i's to cross and t's to dot , but that's the plan... For gcc programs, it is even easier, you just include my header file for the api, and call the functions.
  5. On the 4A, I do not believe you can span records in a single INPUT statement. You just get an error if your input statement expects more data items than was read in the record. We are encouraged to put more than one value in a record. Using INTERNAL instead of DISPLAY, fields are strongly encoded and decoded without the ambiguities of being text.. in DISPLAY mode, PRINT #1:A,B,C produces a record with a single value in it, the string that contains A B and C well formatted with the padding and spacing denoted by the ',' but the comma does not appear in that string. The 4A has a buffer of memory to hold the complete record for input or output, letting the application layer ( TI BASIC ) manipulate the data within the record. I can imagine that on a inherently serial platform the unit of input and output might be the 'register' or 'field' ... reading the TI-95 manual, it doesn't program like basic, but IO units seem to be a register ( single variable ) --- ( that is a big leap on my part from very high level documentation ) What is the unit of input and output for the CC-40's IO commands? I suppose it is in your code somewhere.
  6. I believe TIFILES origin is from XMODEM transfers in the terminal emulation software, to send a file up to a BBS, and then be able to get it back. We do have tools for manipulating TIFILES and moving things from cross assemblers or plain text, etc into or out of TIFILES.. so that might be a bonus. Treating records as opaque, I support native files on linux in TIPI with some rules... I never defined a mechanism to request a new file be created in native mode though... That is a feature classic99 supports. It is handy where possible to unburden data from archaic container formats...
  7. Back in the late 80s, my most prized was Mechatronics XB II Plus. I don't physically have one anymore. It seems special, and rare, and full of potential. The same day I bought that, I bought the Mechatronics Gram Karte for my PEB... So generally none of my cartridges received use after that.
  8. Here is a public doc on TIFILES... I stand on the shoulders of giants... http://ti99-geek.nl/Doc/Ti99_dsk1_fdr.html under his main site: http://ti99-geek.nl -> Documentation -> Comparison of a file descriptor record (FDR) and a TIFILES header
  9. Oh, you mentioned file naming concerns... For TIPI, where I store on a linux partition, but it would work for exFAT or vFAT.. I have these rules: https://github.com/jedimatt42/tipi/wiki/File-name-rules basically '.' is a device or directory separator. So filenames cannot have '.' in them. A lot of internal code uses space to pad file names on the 4A, so a name cannot have spaces in it either. On the 'FAT' side, if a file was named 'TEST.TXT', I report it to the 4A as 'TEST/TXT' and if the 4A requests 'TEST/TXT' or 'TEST\TXT' the FAT side would look for 'TEST.TXT' The TIFILES header supports having a file name embedded in the header. Some tools don't use that. I find managing files on a hosted filesystem, you want to be able to rename the file on the sd card or whatever, and have that stick... This was @Tursi model, to give credit where it is due. Only tangable difference, is that classic99 doesn't emulate 3rd party directory extensions to disk devices. So, having a '.' in a filename after the first dot in the device name is not ambiguous and it allows it.
  10. I don't have the CC-40 manuals, but looking at the CC-40 basic reference card, the BASIC 'open' statement has identical concerns of file type as the 4A. the 'RESTORE' command is what I was refering to as RESET earlier, a seek operation. Random access is called 'RELATIVE'. Variable record files must be opened in 'SEQUENTIAL' mode. Then you have commands OLD and SAVE. On the 4A, those work with a whole different type of file... I'm assuming the CC-40 doesn't issue on OPEN and do a bunch of READ and WRITE the same as PRINT and LINPUT. On the 4A those OLD and SAVE work with PROGRAM image file types ( instead of DISPLAY|INTERNAL FIXED|VARIABLE ) If you used TIFILES, we might find there is a level of interoperability... such as a database file could have a more robust data entry model on the 4A, and the the data file moved the CC-40 with a smaller read oriented client. Although, who knows if the string representation of numbers is compatible, or the INTERNAL representations..
  11. Yes, by default each print statement would go to a separate record.. Classic99, js99er emulators work with TIFILES. my TIPI device, and Fred Kaal's HDX device use them for a TI file system on modern computer connected to the 4A. - This is like what you are doing with files on FAT... you just need to have some pre-amble to cope with the file mode. And yes, if you open a file that is not a match for the type & record length, an error is required.
  12. TIFILES File Header Byte Content Comment 0 0x07 Contains the length of the TIFILES string 1-7 'TIFILES' Contains the literal string 'TIFILES' by means of identification 8-9 Length in sectors Number of 256 byte sectors of the file, big endian 10 File type Not the same as the PAB Bit 0 Fixed (0) or Variable (1) Bit 1-3 Not used Bit 4 Protected (meant to prevent copying, largely ignored by 3rd party software.) Bit 5 Not used Bit 6 Display (0) or Internal (1) Bit 7 Data (0) or Program Image (1) 11 Records per Sector number of records per sector for record based files 12 Bytes in last sector Used to determine the true end of the file (0 indicates 256 bytes in last sector) 13 Record length The length per record, as in the PAB 14-15 Number records Number of records in the file if fixed, or number of sectors in the file if variable. Little Endian, which is unusual for the machine and inconsistent with the length field! Here, this is stolen from a Google Doc @Tursi shared with me. That first 128 byte header of a TIFILES file, where we only use 16 bytes
  13. Yes, in TIPI which uses TIFILES, there is a 128 byte header that captures that file type, record length, and other meta data about the file. On a real floppy disk, this is part of the 'directory structure' called a File Descriptor Record. The attached file was a complete 'TIFILES' file, what we call a FIAD... Let me find the TIFILES format specification... Oh, for grins, I switched the commas to space-colon-space to see, as I hadn't heard of that before... as I said before the software like TI BASIC worries about interpreting the structure within a record (such as what is a field) and the storage device just treats it opaquely. 00000000 07 54 49 46 49 4c 45 53 00 02 80 01 c2 fe 02 00 |.TIFILES........| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000080 03 20 31 20 03 20 31 20 03 20 31 20 0d 20 2e 38 |. 1 . 1 . 1 . .8| 00000090 34 31 34 37 30 39 38 34 38 20 0a 22 20 20 20 20 |414709848 ." | 000000a0 74 65 73 74 22 03 20 32 20 03 20 34 20 0d 20 31 |test". 2 . 4 . 1| 000000b0 2e 34 31 34 32 31 33 35 36 32 20 0d 20 2e 39 30 |.414213562 . .90| 000000c0 39 32 39 37 34 32 36 38 20 0a 22 20 20 20 20 74 |92974268 ." t| 000000d0 65 73 74 22 03 20 33 20 03 20 39 20 0d 20 31 2e |est". 3 . 9 . 1.| 000000e0 37 33 32 30 35 30 38 30 38 20 0d 20 2e 31 34 31 |732050808 . .141| 000000f0 31 32 30 30 30 38 31 20 0a 22 20 20 20 20 74 65 |1200081 ." te| 00000100 73 74 22 03 20 34 20 04 20 31 36 20 03 20 32 20 |st". 4 . 16 . 2 | 00000110 0d 2d 2e 37 35 36 38 30 32 34 39 35 33 20 0a 22 |.-.7568024953 ."| 00000120 20 20 20 20 74 65 73 74 22 03 20 35 20 04 20 32 | test". 5 . 2| 00000130 35 20 0d 20 32 2e 32 33 36 30 36 37 39 37 38 20 |5 . 2.236067978 | 00000140 0d 2d 2e 39 35 38 39 32 34 32 37 34 37 20 0a 22 |.-.9589242747 ."| 00000150 20 20 20 20 74 65 73 74 22 03 20 36 20 04 20 33 | test". 6 . 3| 00000160 36 20 0d 20 32 2e 34 34 39 34 38 39 37 34 33 20 |6 . 2.449489743 | 00000170 0d 2d 2e 32 37 39 34 31 35 34 39 38 32 20 ff 00 |.-.2794154982 ..| 00000180 0a 22 20 20 20 20 74 65 73 74 22 03 20 37 20 04 |." test". 7 .| 00000190 20 34 39 20 0d 20 32 2e 36 34 35 37 35 31 33 31 | 49 . 2.64575131| 000001a0 31 20 0d 20 2e 36 35 36 39 38 36 35 39 38 37 20 |1 . .6569865987 | 000001b0 0a 22 20 20 20 20 74 65 73 74 22 03 20 38 20 04 |." test". 8 .| 000001c0 20 36 34 20 0d 20 32 2e 38 32 38 34 32 37 31 32 | 64 . 2.82842712| 000001d0 35 20 0d 20 2e 39 38 39 33 35 38 32 34 36 36 20 |5 . .9893582466 | 000001e0 0a 22 20 20 20 20 74 65 73 74 22 03 20 39 20 04 |." test". 9 .| 000001f0 20 38 31 20 03 20 33 20 0d 20 2e 34 31 32 31 31 | 81 . 3 . .41211| 00000200 38 34 38 35 32 20 0a 22 20 20 20 20 74 65 73 74 |84852 ." test| 00000210 22 04 20 31 30 20 05 20 31 30 30 20 0c 20 33 2e |". 10 . 100 . 3.| 00000220 31 36 32 32 37 37 36 36 20 0d 2d 2e 35 34 34 30 |16227766 .-.5440| 00000230 32 31 31 31 30 39 20 0a 22 20 20 20 20 74 65 73 |211109 ." tes| 00000240 74 22 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 |t"..............| 00000250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| This is the entire thing, where each of your values is a record... it ends up being much more compact, because the comma used to specify that tabular shape with all the spaces. 0000 - 007F is the 128 byte TIFILES header, there is a 'fe' in there that is the record length... 0080 - 0017F is the first 256 byte sector. You can see it packed in all of the data for I=1 to 5, and part of I=6... since each value was written as a seperate record. If this was FIXED instead of Variable, each record is simply the length specified when opened. The records should be null padded. A Fixed file supports random access, as the starting point for each record is the record number * the record-length. Variable records do not allow random access on the 4A. As you have to traverse it like a linked list. RESET is allowed on both, but again for Variable, RESET is only allowed to seek back to the beginning. By contrast, for a FIXED record file, it may seek to any record number.
  14. 100 OPEN #2:"DSK1.TESTTEXT",OUTPUT,VARIABLE 254 130 FOR I=1 TO 10 150 PRINT #2:I,I^2,SQR(I),SIN(I),""" test""" 160 NEXT I 170 CLOSE #2 That is my translation to TI BASIC on the 4A. Here is the resulting output file in TIFILES format: TESTTEXT Using xdt99 suite's xdm99.py -P to dump it to text we see: 1 1 1 .8414709848 " test" 2 4 1.414213562 .9092974268 " test" 3 9 1.732050808 .1411200081 " test" 4 16 2 -.7568024953 " test" 5 25 2.236067978 -.9589242747 " test" 6 36 2.449489743 -.2794154982 " test" 7 49 2.645751311 .6569865987 " test" 8 64 2.828427125 .9893582466 " test" 9 81 3 .4121184852 " test" 10 100 3.16227766 -.5440211109 " test" A hexdump of one of the sectors in the TIFILES file looks like: 00000080 42 20 31 20 20 20 20 20 20 20 20 20 20 20 20 20 |B 1 | 00000090 31 20 20 20 20 20 20 20 20 20 20 20 20 20 31 20 |1 1 | 000000a0 20 20 20 20 20 20 20 20 20 20 20 20 2e 38 34 31 | .841| 000000b0 34 37 30 39 38 34 38 20 20 22 20 20 20 20 74 65 |4709848 " te| 000000c0 73 74 22 42 20 32 20 20 20 20 20 20 20 20 20 20 |st"B 2 | 000000d0 20 20 20 34 20 20 20 20 20 20 20 20 20 20 20 20 | 4 | 000000e0 20 31 2e 34 31 34 32 31 33 35 36 32 20 20 20 2e | 1.414213562 .| 000000f0 39 30 39 32 39 37 34 32 36 38 20 20 22 20 20 20 |9092974268 " | 00000100 20 74 65 73 74 22 42 20 33 20 20 20 20 20 20 20 | test"B 3 | 00000110 20 20 20 20 20 20 39 20 20 20 20 20 20 20 20 20 | 9 | 00000120 20 20 20 20 31 2e 37 33 32 30 35 30 38 30 38 20 | 1.732050808 | 00000130 20 20 2e 31 34 31 31 32 30 30 30 38 31 20 20 22 | .1411200081 "| 00000140 20 20 20 20 74 65 73 74 22 ff 00 00 00 00 00 00 | test".......| 00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| So, the records are 0x42 or 66 characters long. The numbers are well padded cause of the meaning of ',' , and you can see we got 3 records in one sector.
  15. Because it is Variable, the records are not padded... if it was FIXED then they are all padded to the fixed size. The default DISPLAY vs INTERNAL mode means the string form of the values will be written to the record, and take however much space that takes.. I'll attempt to 4A basic that, and capture the resulting output file.
  16. Fairly high level: http://aa-ti994a.oratronik.de/GPL_Interface_Specification_for_the_99_4_Disk_Peripheral_V2_0_03_28_1983.pdf Ok, reviewing that and the docs next to it in the developer resource sticky thread, I'm amazed TIPI works... The storage structure I described is better understood as TIFILES format FIADs, but I can't find where I learned how the internal storage is defined. I suspect, empirical data. I have this code as part of TIPI that works with Variable Record files stored as TIFILES: https://github.com/jedimatt42/tipi/blob/master/services/ti_files/VariableRecordFile.py I would expect the CC-40 to work in units of records with the hex bus interface, and the device treat what is inside a record as opaque. I could be horribly wrong, but you are far enough along to tell already. [email protected]
  17. On the 4A, records are stored in 256 byte block chunks. Variable record based files have a maximum specifiable record length of 254, due to the structure of the block. The first by of a record is the length byte, followed by up to 254 bytes of content for the record. If the next record will not fit in the block, then the length byte is 0xFF ( 255 ) which indicates to skip the remainder of the block and find the next record in the next block. It is common on the 4A to use a DISPLAY VARIABLE 80 file for text. There is no line separator innate in these files, as the record structure serves to separate lines. 1 line per record. Programs, or programming languages can structure these as data... a Display type file used by TI BASIC will use commas to separate fields in a record. An Internal type file knows the length of each internal field datum as either the type is flagged in the first byte of the field, and if it is a string, there is a length again before the content of the string. But all that is within the record and not a concern of the storage device on the 4A. I'd expect the CC-40 borrowed a lot of storage device vs. BASIC separation of responsibilities, given the hex-bus storage devices were meant to work with the 4A filesystem concepts. There are a documents that details all of this for the 4A... I will go find the link to.
  18. You could connect a PI, like the Pi Zero, directly to the TI bus, skipping my little adapter.. but you'd have to ditch linux on the PI, and write a full bootable program. Linux is too asynchronous with no timing guarantees. I designed TIPI to be easy to write. Skipping the PI altogether, there is the SDD99 project under development... but it has no ETA as of yet.
  19. A better MSX example would be :
  20. I'm a 'no news is good news' sort of person... The meet up is still on even if the thread is not bumped... Even if I can't make it, I'll find a way to get someone else to start it. The goal is a no fan-fare, relaxed, easy, and consistent meet up that can be taken for granted.
  21. Trying to bring this conversation back to the correct thread:
  22. @Nick99 - the above thread is maybe poorly named, but it is about developing software on the Geneve. Not TIPI usage. The issue you posted is a usage issue. So I'm referencing it, and answering it here. The problem you stated, in short, is that you have a ROMPAGE mode error using a TI Floppy Controller in a Geneve, and you are mystified by the TIPI disk mapping not working when at a CRU base that is not prior to the floppy controller... You have multiple problems: 1st, the TI Disk Controller does not work in ROMPAGE mode on a Geneve. That has been my experience, and the people that claim to know, only have vague memories. It seems no one curated documentation of what does and doesn't work with a Geneve. 2nd, the TI Disk Controller DSR is not designed to pass control on to high CRU addressed devices even if it did work in ROMPAGE mode. If you want TIPI disk mapping, you will need to run the TIPI at CRU base address >1000 as this is the only CRU address base below the floppy controller's >1100 address base. Geneve or otherwise.. that's how to TI architecture works.
  23. seems like it isn't just my terminal: https://github.com/msys2/MSYS2-packages/issues/1124 in bash, changing the term type seems to help... export TERM=xterm
  24. Yep, so I pressed backspace after the 'o' in hello, and then sent the output to hexdump... the backspace took, the 'o' is gone, but the display decoding is all buggered. So.. not sure how to capture what is being sent, other than turning on byte level tracing of TIPI messages... so... maybe someday... I'd rather finish working the API for ForceCommand, which encapsulates the terminal handling code, and fix it there, and then rebuild a working telnet on top of that API...
×
×
  • Create New...