+retroclouds Posted July 26, 2011 Share Posted July 26, 2011 hhm..... I have 2 questions: * What registers are used by the compiler generated program? Are all 16 registers used or are some of them "free" for own use? * What (scratchpad) memory is used by the compiler generated program? Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2334655 Share on other sites More sharing options...
insomnia Posted July 27, 2011 Author Share Posted July 27, 2011 OK, the multiply bug was more involved than the earlier ones, but here you go: In gcc-4.4.0/gcc/config/tms9900/tms9900.md. remove lines 1455 through 1484 (the "mulhisi3", and "*multhisi" patterns). Replace them with this: (define_insn "mulhisi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (mult:SI (match_operand:HI 1 "register_operand" "r,r") (match_operand:HI 2 "general_operand" "rR>,Q")))] "" { /* When both input operands are registers, we may need to swap them. */ if(REG_P(operands[1]) && REG_P(operands[2])) { /* Check for forms like: r0 = r1 * r0 */ if(REGNO(operands[0]) == REGNO(operands[2])) { /* Swap operands, otherwise we will emit code like: mov r1, r0 mpy r0, r0 instead of: mpy r1, r0 */ rtx temp = operands[1]; operands[1] = operands[2]; operands[2] = temp; } } if(REGNO(operands[0]) != REGNO(operands[1])) { output_asm_insn("mov %1, %0", operands); } output_asm_insn("mpy %2, %0", operands); return(""); } [(set_attr "length" "2,3")]) The original code was an attempt to force the register allocator to use registers which were most convenient for the MPY instruction. Obviously,that didn't work out so well. This new code is less aggressive, accepting any register choice GCC may make. It also works in all optimization levels. An optional MOV instruction is now used to prepare for the multiply if the register allocator is not kind. Moving on to questions... * What registers are used by the compiler generated program? Are all 16 registers used or are some of them "free" for own use? GCC will attempt to make maximum use of all 16 registers, so there's no guarantee that there any lying around unused. If you have an assembly routine you would like to interface with C code, the information needed for that should be shown in earlier posts. If you would like more detailed information (calling convention, register usage and allocation order, etc) I'd be happy to let you know. I have a document I've been neglecting which should include all this stuff. * What (scratchpad) memory is used by the compiler generated program? GCC (or any compiler) is basically an engine to convert source code into assembly. That means you have complete control over what memory is used, and for what purpose. So unlike Basic, Java or Forth (I presume), there is no other code working behind the scenes you need to be aware of. All of the machine's resources are available to you, and any other limitations are of your own making. In the example code I've posted earlier, the registers are located at >8300 by the ctr0 code. Except for what's used by the registers, all of scratchpad memory is available. If you wanted to, you could put the registers elsewhere in scratchpad or 8-bit memory with no impact on the C code. You can store data anywhere in the system you like (like Lucien did in his bricks code). Using the linker, you can build your code to run from anywhere in memory. You could even put (small bits of) code into scratchpad and run from there for that extra performace boost (as I believe was done in Parsec). Remember, C was originally designed to write device drivers and operating systems, so the sky's the limit here. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2335027 Share on other sites More sharing options...
+retroclouds Posted July 27, 2011 Share Posted July 27, 2011 Thanks for the update. Good to know that there is no memory used, except for the registers. Reason I'm asking is because I'm toying with the idea of interfacing my spectra2 assembly library with C code. No rush though, first need to get the next release out and wanna get myself confident with C Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2335131 Share on other sites More sharing options...
insomnia Posted August 8, 2011 Author Share Posted August 8, 2011 OK, it's patch time again. This patch includes the fixes for all bugs mentioned here since the last patch release in addition to a few I found on my own. The same patch and build directions used before are used for this one too. Here's the changes in this release: Fixed a bug with byte initializers, it was handling negative values wrongly Fixed multiply bug, it was using the wrong registers Changed frame pointer from R8 to R9. Frame was being lost Byte reads from memory were assumed to be copied into register's LSB. Fixed a problem with AND improperly modifying input values. Fixed a bug where R11 was not saved if used as a data register. Modified output to use hex values for all constants and addresses I've also packaged up an ELF to EA5 converter and an example program made to run as an EA5 image. The program does the same useless flashing text thing that the cart example did. This was done to make the differences easier to spot. The changes made to the EA5 crt0 are a bit safer than the one used in the cart version (this one better handles zero size sections). I'll probably release a new version of the cart tool and example sometime soon which incorporates these changes. The next thing on my list is to update all the documentation. Everything I've posted so far is still valid, but there are probably holes where some subjects need more description. I also need to put together a library for the missing 32- but functions (multiply, divide, modulus, shift). These functions are already written and tested for the most part, so releasing them should be quick and easy. Finally, I need to make my V9T9 disk management tool ready for public consumption. It currently works, and the disk images it creates were used to test the EA5 converter, but it's super hacky at the moment. Once I spruce it up a bit and turn it into a useful tool, I can send it out the door. As always, the gory details are on my blog for those who are interested. gcc-4.4.0-tms9900-1.4-patch.tar.gz elf2ea5.tar.gz hello_ea5.tar.gz 1 Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2343991 Share on other sites More sharing options...
lucien2 Posted August 8, 2011 Share Posted August 8, 2011 I've also packaged up an ELF to EA5 converter Great, thanks! Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2344433 Share on other sites More sharing options...
lucien2 Posted August 20, 2011 Share Posted August 20, 2011 I found 2 new bugs. void vdp_copy_from_sys(int index, char* src, int size) { char* end = src + size; VDP_ADDRESS_REG = index; VDP_ADDRESS_REG = (char)(index >> | VDP_WRITE_FLAG; while(src < end) VDP_WRITE_DATA_REG = *src++; } void main() { int i=0; char c; FAC=0x900; gpl_link(0x18); FAC=0xB00; gpl_link(0x4A); while(1) { interrupts(); if(key_scan(&c)) { c=random_byte(26)+65; vdp_copy_from_sys(i,&c,1); i++; if(i>=32*24)i=0; gpl_link(0x34); } } } Code generated for the call of "vdp_copy_from_sys" ("i" is in R9): movb r9, @>8C02 INCORRECT mov r9, r2 ori r2, >4000 movb r2, @>8C02 movb r1, @>8C00 inc r9 ci r9, >2FF If I comment the line "c=random_byte(26)+65;" ("i" is in R2): mov r2, r1 swpb r1 CORRECT movb r1, @>8C02 mov r2, r1 ori r1, >4000 movb r1, @>8C02 movb r3, @>8C00 inc r2 ci r2, >2FF And the other bug, with the assembler. gplws equ 0x83E0 def kscan kscan lwpi gplws bl @>E lwpi >8300 b *r11 If I put "gplws equ 0x83E0" after the "kscan" routine, there is no error message, but "kscan" does not work anymore. Here is the complete source: UTILS.zip Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2353327 Share on other sites More sharing options...
lucien2 Posted August 21, 2011 Share Posted August 21, 2011 I found another bug with the assembler. I think this one should be easier to correct. The STST instruction can't be assembled. The error message is "Error: missing comma separator". I could not find the string "STST" or "LWPI" in the "complete_files" folder, where are the assembler instructions in the source? Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2354113 Share on other sites More sharing options...
lucien2 Posted August 22, 2011 Share Posted August 22, 2011 I could not find the string "STST" or "LWPI" in the "complete_files" folder, where are the assembler instructions in the source? Ok, I searched in the GCC source, but it's in the BINUTILS source. I see that in the "parse_table level_4" structure there is "{parse_type_8a, "stst"}". So, here is "parse_type_8a": static void parse_type_8a(struct buffer *buffer, disassemble_info *info, char *text) { // |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| // register, count |Opcode | 0|Register | info->fprintf_func (info->stream, "%s r%d", text, buffer->opcode & 0xF); } It seems correct, why is it waiting for a comma? Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2354768 Share on other sites More sharing options...
insomnia Posted August 23, 2011 Author Share Posted August 23, 2011 Actually, the code that you found was in the disassembler, which isn't much help. What you want is line 722 of binutils-2.19.1/gas/config/tc-tms9900.c Change that line to { "stst", 0x02C0, {ARG_REGISTER, ARG_NONE}}, and you are back in business. The error you were seeing was due to the fact that this instruction was falsely insisting upon a second argument for STST. Something like this would have made it happy: stst r0, >0000 It also seems like there is a problem with the SBO, SBZ and TB instructions. During the assembly process, the bit offsets are being reduced by half. They are currently using constants in the same way as JMP, which is wrong. I need to add a new constant type for these CRU instructions for correct operation. At least LDCR and STCR look right. I haven't had a chance to look at your other issues yet, but I should have some answers for you tomorrow. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2355332 Share on other sites More sharing options...
lucien2 Posted August 23, 2011 Share Posted August 23, 2011 Actually, the code that you found was in the disassembler, which isn't much help. What you want is line 722 of binutils-2.19.1/gas/config/tc-tms9900.c Thanks! I only checked the first file where it founds "stst". I haven't had a chance to look at your other issues yet, but I should have some answers for you tomorrow. There's no hurry, I'm not blocked with these ones. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2355381 Share on other sites More sharing options...
insomnia Posted March 15, 2012 Author Share Posted March 15, 2012 Well, after a really long time without any signs of life from this project, it's patch time. A big "thank you" goes out to Lucien. A lot of the updates here are a direct result of the effort he put into making Rush Hour. He did a great job wading through all the brokenness to make a functional game. Now it's time for everyone to benefit from that work. New Binutils fixes in this release: STST was incorrectly looking for two arguments SBO, SBZ and TB incorrectly using constants EQU'ed symbols sometimes replaced using wrong endianness GCC fixes: Fixed several word-to-byte conversion errors Fixed "unrecognizable instruction" for zero comparison operations Made optimizations for most comparison operations Improved correctness of condition flag handling Switch statements now work properly Fixed divison and modulus, operands were used in wrong order Fixed subtract, operands were occasionally used in wrong order Fixed stack frame corruption when local variables are in use Added optimizations for forms like (int Y)=((int)(char X))<<N The patch and build procedures are the same as always. Development notes are on my blog for those who are interested. Things are shaping up pretty well so far. (Yes it is taking forever, sorry about that.) I don't see any obvious holes to fill, or optimizations yet to do. At this point, I just need to exercize the compiler with larger programs and increase test coverage. If anyone finds a problem, or sees an area where improvements can be made, please let me know. I'm continuing to work on related projects (disk management tool, libc library, documentation). There's still lots to do, so these updates will keep coming. binutils-2.19.1-tms9900-1.3-patch.tar.gz gcc-4.4.0-tms9900-1.5-patch.tar.gz 3 Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2484308 Share on other sites More sharing options...
sometimes99er Posted March 15, 2012 Share Posted March 15, 2012 Great work. (int y) = ((int)(charx))<<8 sra r2, 8 12+2*8+4=32 sla r2, >8 12+2*8+4=32 total: 64 clocks, 4 bytes Sorry for some maybe stupid questions. And sorry for not posting on your blog. So "charx" must be something between >00 and >FF. Right ? Looking at the first instruction, being SRA (Shift Right Arithmetic), I assume "charx" is represented in memory as a word (looking at the code it's in R2 at that stage) like something between >00xx and >FFxx ? SRA fills vacated bit positions with original MSB (Most Significant Bit). So "SRA R2,8" would turn >00xx into >0000, and >FFxx would be >FFFF ? But wouldn't that make (int)(charx) wrong ? - Shouldn't >FF00 be turned into >00FF ? Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2484321 Share on other sites More sharing options...
lucien2 Posted March 15, 2012 Share Posted March 15, 2012 Well, after a really long time without any signs of life from this project, it's patch time. Wonderful! At this point, I just need to exercize the compiler with larger programs and increase test coverage. Count on me for that. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2484361 Share on other sites More sharing options...
insomnia Posted March 15, 2012 Author Share Posted March 15, 2012 So "charx" must be something between >00 and >FF. Right ? Looking at the first instruction, being SRA (Shift Right Arithmetic), I assume "charx" is represented in memory as a word (looking at the code it's in R2 at that stage) like something between >00xx and >FFxx ? SRA fills vacated bit positions with original MSB (Most Significant Bit). So "SRA R2,8" would turn >00xx into >0000, and >FFxx would be >FFFF ? But wouldn't that make (int)(charx) wrong ? - Shouldn't >FF00 be turned into >00FF ? The example was written assuming the values are in currently in registers, and doesn't use correct C syntax. The idea was to use shorthand and c-like pseudocode to get the idea across quickly. A real-life example would look something like this: void do_something() { char x; int y; ... y=((int)x)<<4; ... } You're right X must be a value between >00 and >FF, and if the X value is in memory, it need not occupy a full word. Once copied into a register (using MOVB or something) the value will be stored in the high byte. What you wrote would be true for unsigned values, but not for signed ones. >FFxx in a register can be interpreted as either (char)(-1) or (unsigned char)(255) >FFFF is (int)(-1) >00FF would be (int)(255) There are optimizations for both of these, but I only used an example for signed values since the timings are the same and only differ by the SRA or SRL instruction. The initial implementation would produce this code: * Assume x has a value of -4 (>FC), and is stored in r2 as >FCxx * y = (-4)<<4 = -4 * 16 = -64 = >FFC0 sra r2, 8 * Convert to signed integer (r2=FFFC) sla r2, 4 * Left shift converted value (r2=FFC0) The optimization emits this code: * Assume x has a value of -4 (>FC), and is stored in r2 as >FCxx * y = (-4)<<4 = -4 * 16 = -64 = >FFC0 sra r2, 4 * Shift into final position (r2=FFCx) andi r2, >FFF0 * Mask unknown bits (r2=FFC0) And finally, for unsigned values: * Assume x has a value of 252 (>FC), and is stored in r2 as >FCxx * y = 252<<4 = 252 * 16 = 4032 = >0FC0 srl r2, 4 * Shift into final position (r2=0FCx) andi r2, >FFF0 * Mask unknown bits (r2=0FC0) Since fewer bit shifts are required, the optimized code runs faster (I figure about 33% faster on average), but uses one additional code word. 1 Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2484414 Share on other sites More sharing options...
sometimes99er Posted March 15, 2012 Share Posted March 15, 2012 Very clear explanation. Thanks. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2484450 Share on other sites More sharing options...
lucien2 Posted March 18, 2012 Share Posted March 18, 2012 (edited) I think a "small" tutorial to install GCC on Windows is missing. Here is one: 1. Install Cygwin http://cygwin.com/setup.exe I chose the mirror "ftp://ftp.uni-kl.de"that is more than 10 times faster than the first mirror in the list "http://mirrors.163.com" 2. Choose the following Cygwin options ("bin" checkbox, the source is not necessary) (54MB) Category "Devel" - gcc-core - libiconv - make - patchutils Category "Libs" - libgmp-devel - libmpfr-devel Category "Interpreters" - m4 3. Download the GCC 4.4.0 sources (60MB) ftp://ftp.gwdg.de/pu...c-4.4.0.tar.bz2 4. Download the Binutils 2.19.1 sources (15MB) http://ftp.gnu.org/g...-2.19.1.tar.bz2 5. Run Cygwin to create your home directory (\cygwin\home\yourname) 6. Extract the source files to your home directory You can use "tar" in the Cygwin console: Put the .tar.bz2 files in your home directory $ tar xvfj gcc-4.4.0.tar.bz2 $ tar xvfj binutils-2.19.1.tar.bz2 7. Extract the patches Put binutils-2.19.1-tms9900-1.3-patch.tar.gz in the binutils-2.19.1 folder Put gcc-4.4.0-tms9900-1.5.patch.tar.gz in the gcc-4.4.0 folder $ cd ~/binutils-2.19.1 $ tar xvfz binutils-2.19.1-tms9900-1.3-patch.tar.gz $ cd ~/gcc-4.4.0 $ tar xvfz gcc-4.4.0-tms9900-1.5.patch.tar.gz 8. Build binutils and gcc as explained earlier in this thread Patching the original files: $ cd ~/binutils-2.19.1 $ patch -p1 < binutils-2.19.1-tms9900-1.3.patch $ cd ~/gcc-4.4.0 $ patch -p1 < gcc-4.4.0-tms9900-1.5.patch Building binutils $ cd ~/binutils-2.19.1 $ ./configure --target tms9900 --prefix /home/yourname/binutils $ make all $ make install Building GCC $ cd ~/gcc-4.4.0 $ ./configure --target=tms9900 --prefix=/home/yourname/gcc --enable-languages=c $ make all-gcc $ make install There are some errors during "make install", you can ignore them 9. Replace the i686 assembler (/bin/as) with the tms9900 assembler - Rename /bin/as.exe to something like /bin/i686-as.exe - Copy tms9900-as.exe from ~/binutils/bin to /bin/as.exe If you don't want to do all these steps, I prepared a compiled version (26MB) http://lb3.one/public/TI99-GCC-1.5.zip Here is how you install it: 1. Install Cygwin (22MB) http://cygwin.com/setup.exe Choose the second mirror in the list Choose the following options (bin checkbox): Category "Devel", "make" Category "Libs", "libmpfr-devel" 2. Run Cygwin to create your home directory 3. Extract "TI99-GCC-1.5.zip" to your home directory "cygwin/home/yourname" 4. Copy "/cygwin/home/yourname/binutils/bin/tms9900-as.exe" to "cygwin/bin/as.exe" To try it, change the paths in "~/RUSH_HOUR/Makefile" from "/home/-" to "/home/yourname" and type this at the Cygwin console: $ cd ~/RUSH_HOUR $ make It creates "rush_our.ea5.bin" and "rush_hour.c.bin" in the "cygwin/home/yourname/RUSH_HOUR" directory. The .c.bin file is a cartridge binary ready to use. The .ea5.bin must be converted to the TIFILE format with Ti99Dir To check the generated assembly code, type this: $ ~/gcc/libexec/gcc/tms9900/4.4.0/cc1 -O2 main.c Edited October 10, 2016 by lucien2 3 Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2485813 Share on other sites More sharing options...
lucien2 Posted April 17, 2012 Share Posted April 17, 2012 How do you put a single quote in a string constant? With the TI assembler, you have to double it. GCC doubles it for the GNU assembler, but the assembler gives this error: Junk at end of line, first unrecognized character is `'' Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2502912 Share on other sites More sharing options...
insomnia Posted July 16, 2012 Author Share Posted July 16, 2012 Well, it's patch time again. First off, an aplogy to Lucien for not responding earlier, but the short answer for "how to use a single quote?" is "you can't". There was a bug in binutils which prevented its use. I tried to be clever and allow either TI-style or C-style strings in the assembly code, but did a terrible job of it. The parser always treated escaped single quotes as the end of the string, which causes some frustration, to put it mildly. Fortunately, that's all been fixed in the latest patch. So here's the official changelog for binutils: Fixed bug prohibiting the use of single quotes in a string Strings my be in either TI-style 'stuff' or C-style "stuff" TI-style strings follow E/A text rules C-style strings may include standard escape codes "example\n" And the other things fixed in GCC: Fixed comparison against +-1 and +-2, they got broken in 1.5 Prevented incorrect use of fake PC register for real work Improved AND operations to use fewer setup instructions Fixed incorrect long-to-char conversions Fixed post-increment pointers which live on the stack Added optimization for setting byte quantities to zero Added optimization for (int)X = (unsigned char)((int)X) Removed double-counting space for saved registers on the stack Reduced overhead needed for multiply instructions Fixed bug causing structures to be loaded into registers Structures used as function arguments now passed by reference Fixed more bugs causing bad int-to-char conversions Work has kept me pretty busy lately, but progress continues. As always, if anyone finds problems or has suggestions, please let me know binutils-2.19.1-tms9900-1.4-patch.tar.gz gcc-4.4.0-tms9900-1.6-patch.tar.gz 3 Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2560042 Share on other sites More sharing options...
lucien2 Posted July 22, 2012 Share Posted July 22, 2012 Thanks for the update! I had this warning with the compilation of the assembler: "assignment discards qualifiers from pointer target type". Even if it's only a warning, it did not compile. I had to replace the line 470 of "tc-tms9900.c" from "input_line_pointer = p;" to "input_line_pointer = (char*)p;". The was also a bug with the address of a stack frame slot "@>XX(r10)" in the function "display_at_multiline" in "lib.c". It saves 5 registers on the stack (mov rX,*r10+), then it overwrites the last one at r10+8 with a "mov r15,@>8(r10)". I replaced the function "tms9900_get_saved_reg_size" from "tms9900.c" with this one, from the 1.5 version, and it replaced "mov r15,@>8(r10)" with "mov r15,@>A(r10)". static int tms9900_get_saved_reg_size(void) { int idx = 0; int size = 0; while(nvolregs[idx] != 0) { int regno = nvolregs[idx]; if ((regno == HARD_LR_REGNUM && !current_function_is_leaf) || df_regs_ever_live_p (regno)) { size += 2; } idx++; } return(size); } The only other bug I found is in "main.c" from RUSH_HOUR. If I replace x and y of the struct "point_cursor" from "char" to "int", the function "move_block" does not work correctly anymore. Apart from these problems, all the other bugs seem to be fixed. I recompiled all my GCC programs and carefully tried them. lb sources.zip 1 Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2564334 Share on other sites More sharing options...
+retroclouds Posted August 19, 2012 Share Posted August 19, 2012 (edited) Would this be something that could be compiled for the TMS9900 and work with the CF7+ ? You'd need to include your own sector read/write routine. http://ultra-embedded.com/?fat_filelib Edited August 19, 2012 by retroclouds Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2581070 Share on other sites More sharing options...
JamesD Posted August 22, 2012 Share Posted August 22, 2012 Would this be something that could be compiled for the TMS9900 and work with the CF7+ ? You'd need to include your own sector read/write routine. http://ultra-embedded.com/?fat_filelib GCC is rather large and slow. Even if you could squeeze the compiler into memory (which I'm pretty sure you can't), you probably wouldn't have enough memory to compile anything. Even if you could, it would take forever to compile anything. Many C compilers from the pre-multi-mega/gigabyte days used multi-stage compilers to fit into small memory. They parsed in one module, and generated code in another and those compilers were smaller. To be honest, I'd rather use a cross compiler and have the better compiler. You can probably compile, link, and transfer the executable over to the TI faster than the TI could compile. The only reason I see to have a native compiler is just to say it exists and that's more of an ego thing than practical. Going slightly off topic... There are better compilers than GCC now anyway and GCC is gradually going to be replaced on other platforms. Apple is already pulling their support from GCC and migrating to LLVM over the next few years for it's dev tool. LLVM is about 3x faster than GCC, and has a better code optimizer. Someone would need to port the 9900 code generator to use it though. I think right now time would be best spent working out the kinks in GCC given it's stage of development, but somewhere down the road an LLVM code generator might be a worthwhile project. You still wouldn't be able to have a native version. http://llvm.org/ If you really want a native compiler, something like SDCC would probably be a better place to start since it has a smaller code base. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2583868 Share on other sites More sharing options...
TheMole Posted October 1, 2012 Share Posted October 1, 2012 Hi All, My name is Danny, I'm new to this forum but when growing have used a TI extensively until as late as 1996 when I got my first "real" PC. As of late I've been working on integrating a Sega master system VDP into a TI-99/4A. The master system VDP is identical to a TMS9918A software-wise, but implements a new mode (called "mode 4") that is closely related to graphics I, with the added benefit of hardware scrolling and up to 16 colors per tile. The first step towards this has been implementing mode 4 support in the ti99/sim emulator (I use Linux, and found this code base easier to start from than MESS) and writing some programs on the TI that activate and use mode 4. I've made some progress and things look ok. My main problem though is lack of assembler knowledge. So, I've compiled gcc with the patches found in this thread and everything looks ok. I compiled the hello world example, which again seemed to work fine. But when I try to run the resulting cartridge image in ti99/sim and choose the 2nd option ("HELLO"), it basically takes me back to the home screen. Every program I've tried to compile exhibits the same behavior. I tried the cart in Classic99 through wine (by renaming the file to helloC.BIN) but it doesn't even show up in the menu there. Any ideas what I might be doing wrong? Using Ubuntu 12.04 and the latest patches found in this thread. Thanks, D. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2609891 Share on other sites More sharing options...
lucien2 Posted October 1, 2012 Share Posted October 1, 2012 That's strange. I just compiled and ran the 3 "hello world" examples from posts #1, #64 and #79 without problem. Which versions did you patch? gcc 4.4.0 and binutils 2.19.1? Could you post the source and the generated objects? So, I can compare with mine. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2610028 Share on other sites More sharing options...
TheMole Posted October 2, 2012 Share Posted October 2, 2012 Yes, I'm using the exact versions of gcc and binutils, the patches also applied cleanly so I don't think that's the problem. It might very well be that this is a bug in ti99/sim, but I don't know how to load the resulting .cart file into either MESS or Classic99 (through wine). I'm rather "new" to this modern-day TI development thing . I'm compiling this example, and I've attached the output files (main.o, hello.elf & hello.cart) /* Define macros to access VDP registers These macros can be used as if they were variables. This makes things easier to read and we don't have a lot of typecasts troughout the code. Read data register located at address >8800 Write data register located at address >8C00 Address register located at address >8C02 */ #define VDP_READ_DATA_REG (*(volatile char*)0x8800) #define VDP_WRITE_DATA_REG (*(volatile char*)0x8C00) #define VDP_ADDRESS_REG (*(volatile char*)0x8C02) /* Flags used during VDP access */ #define VDP_READ_FLAG 0x00 #define VDP_WRITE_FLAG 0x40 #define VDP_REG_FLAG 0x80 /* Location of the screen in VDP memory. This is the based on the VDP configuration set by the TI firmware */ #define VDP_SCREEN_ADDRESS 0 /*========================================================================== * vdp_copy_from_sys *========================================================================== * Description: Copy data from system memory to VDP memory * * Parameters : index - Starting index into VDP memory * src - Address of source data in system memory * size - Number of bytes to copy * * Returns : Nothing */ static void vdp_copy_from_sys(int index, char* src, int size) { /* Find the address of the end of the source data */ volatile char* end = src + size; /* Set the address in VDP to which we will copy. We must do this in two parts. The first part: Write the low byte of the VDP address and include a flag informing VDP we will soon be writing data */ VDP_ADDRESS_REG = index | VDP_WRITE_FLAG; /* The second part: Write the high byte of the VDP address. After this, the VDP will be ready to have data written into it's memory */ VDP_ADDRESS_REG = (char)(index >> ; /* Copy data to VDP memory via VDP data write register Keep copying until we hit the end of the source data */ while(src < end) VDP_WRITE_DATA_REG = *src++; } /*========================================================================== * display_at *========================================================================== * Description: Display a text string at a specified location on the screen * * Parameters : row - Screen row for display * column - Screen column for display * text - Text to display * * Returns : Nothing */ static void display_at(unsigned int row, unsigned int column, char* text) { int size; /* Size of text string to display */ int offset; /* Offset into screen buffer */ char *ptr = text; /* Pointer to a character in "text" */ /* Find length of display text C strings are ended by a zero byte, so look for that */ size = 0; while(text[size] != 0) size++; /* Convert row and column to screen offset. There are 32 columns per row */ offset = row * 32 + column; /* Copy text to the screen, which lies in VDP memory */ vdp_copy_from_sys(offset + VDP_SCREEN_ADDRESS, text, size); } /*========================================================================== * main *========================================================================== * Description: Entry point for program * * Parameters : None * * Returns : Nothing */ void main() { /* Display flashing text at the center of the screen We will do this by displaying text, then spaces, then text again. To keep things simple, we will use the character set defined by the TI firmware. Unfortunately, it only defines symbols and uppercase letters. Keep that in mind if you change the displayed text This loop will never exit. Since the interrupts have been disabled in the setup code, the console must be reset to exit the loop */ while(1) { display_at(12, 10, "HELLO WORLD!"); display_at(12, 10, " "); } } hello_ti.zip Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2610578 Share on other sites More sharing options...
lucien2 Posted October 2, 2012 Share Posted October 2, 2012 I ran your cartridge with classic99 and ti99sim under windows without problem. With classic99, you said it does not show in the menu. The TI99 boot menu or the classic99 cartridge menu? It shows in the cartridge menu only if you declare it in classic99.ini. Otherwise the menu "Cartridge / User / Open" works fine if you rename it "helloc.bin". I tried ti99sim for the first time. You must also rename it "helloc.bin" and run "convert-ctg hello.bin" without the "C", then it says "1 bank of ROM at 6000, 1 bank of ROM at 7000". If you type "convert-ctg helloc.bin", it says "GROMS: 3" and does not work. Quote Link to comment https://forums.atariage.com/topic/164295-gcc-for-the-ti/page/4/#findComment-2610620 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.