Subject: Linking to assembler routines in Quetzalcoatl. (Updated 14jun1999) http://www.kdef.com/geek/vic The current release of Quetzalcoatl 2.04a doesn't support relocatable assembler modules. That means you can't link the runtime library (written in assembler) with another module also written in assembler. If you're writing your entire program in assembler, this obviously isn't a problem! However if you want to call your own assembler routine from 'C' you'll need to add it to the runtime library; this will be your 'hacked' copy of the runtime library you'll use just for your own programs needing those routines. (Don't worry; when relocatable assembler is supported you can move it to its own file.) This is how you can call your assembler routine from 'C': > But how do i acces my new defined routine ???? > e.g. i define > foo: > lda #32 > sta $400 > rts > how do i call foo in my c-proggy ? The short answer: Declare it in the asm file as "foo()": rather than foo: (Note the quotes!) The long answer: The compiler uses name mangling for external functions. The name of the function is followed by two brackets, containing one character for each parameter type. If the function returns a value it contains one character for that value. The exception to this are voids, for which the character is omitted. upl_void: 'v'; upl_byte: 'b'; upl_char: 'c'; upl_boolean: 'B'; upl_ushort: 'u'; upl_short: 's'; Pointers are prefixed by '*': So for example this function: char fred(short X, boolean Y) has the mangled name "fred(sB)c" Another example: short strlen(char *Name) has the mangled name "fred(*c)s" Even simpler: void fred(void) has the mangled name "fred()" Declare the external declaration in your C file or its header: void fred(void); Use it as per normal: void main(void) { cout << "Hi there\n"; fred(); // Use it as per normal. } Now in the assembler file give it this label: "fred()": lda #'a' sta 42 rts The version with the parameters is kind of messy (because you need to set up the stack frame as described in uplrtime.asm). Anyway, when you link all the modules together the linker will automatically resolve the external references" This would be bad (it means you forgot to include your hacked runtime library): (In this example I hacked pointers.c to call fred) 10:49 F:\q>quetzal pointers.c Quetzalcoatl C/UPL 6502 Cross Compiler 2.0a4 (ALPHA) I: Module pointers. Segment Sizes: Code: 279 bytes. Data: 33 bytes. I: Module uplrtime. Segment Sizes: Code: 1437 bytes. Data: 0 bytes. E: Undefined external symbol fred() found in module pointers. E: Errors were found, and so no executable was created. This would be good; you remembered: 10:49 F:\q>quetzal pointers.c uplrtime.asm Quetzalcoatl C/UPL 6502 Cross Compiler 2.0a4 (ALPHA) I: Target is Generic Commodore. I: Module pointers. Segment Sizes: Code: 279 bytes. Data: 33 bytes. I: Module uplrtime. Segment Sizes: Code: 1438 bytes. Data: 0 bytes. I: Executable starts at address 4096, and is 1750 bytes long. I: Success! Saved executable pointers.bin. Entry point at 5615. I: To run the executable on a VIC-20/C64 load it and type SYS 5615. > How do I write a program entirely in assembler? ie. no C? Easy! Call the entry point main: eg. 10:40 F:\q>type test.asm ; Test Program ; main: org 0x1000 ; Origin specified in hex lda #'a' brk end ; Tells assembler to end here 10:40 F:\q> quetzal test.asm Quetzalcoatl C/UPL 6502 Cross Compiler 2.0a4 (ALPHA) I: Module test. Segment Sizes: Code: 3 bytes. Data: 0 bytes. I: Executable starts at address 4096, and is 3 bytes long. I: Success! Saved executable test.bin. Entry point at 0. I: To run the executable on a VIC-20/C64 load it and type SYS 0. Ignore the SYS 0 comment; The '0' means no entry point was defined by the C compiler. SYS 4096 instead (that's the 0x1000 in decimal; your origin). END.