Hello, 1) I want to place assembly code in my C code. The problem with using SRC is that I would have to rename the file MyAsm.SRC to MyAsm.A51 and then (remove C code from project) include A51 code in the project... before finally recompiling the whole project. Is there any way to just add assembly code without using SRC? What about the '__asm' keyword? Where do I get more info on this? 2) The Cx51 User Manual (Pg124) states that the Interrupt function will save SFR, ACC, B, DPL, DPH etc 'when required' to stack (and later pop it). How do I disable this feature so I can manually do the PUSHing and POPing? If this is not possible then is it possible to instruct Keil to 'save all' registers regardless of need? Regards, KC
"1) I want to place assembly code in my C code. The problem with using SRC is that I would have to rename the file MyAsm.SRC to MyAsm.A51 and then (remove C code from project) include A51 code in the project... before finally recompiling the whole project. Is there any way to just add assembly code without using SRC?" No you don't! You need to re-read the manual and follow the instructions carefully: You just need to check the 'Generate Assembler SRC' and 'Assemble SRC' options - that's all! "How do I disable this feature so I can manually do the PUSHing and POPing?" You shouldn't be doing that sort of thing in 'C'! If this is really what you need to do, then this a job for assembler, not 'C'.
Hi Ken, that SRC thing is just a help for you to build the structure of a function. You just do it once, just typing in the function with its parameters and return value, use the parameters in the function in a simple (dummy) way, then you get assembly code, that declares the segments etc. and shows you where you will find your parameters. This is done once. You "steal" that assembly code mand do all the programming in assembler, never use the SRC pragma again. For example, if you want to write an assembly module that handles an LCD display, you first set up a "Prototyping C-source" lcd_prot.c that looks like this:
#pragma SRC bit lcd_busy( void ) { return 1; } void lcd_out( unsigned char out_byte, unsigned char ram ) { if (ram) { out_byte++; } } void lcd_outchar( unsigned char out_byte ) { out_byte++; } void lcd_outinstr( unsigned char out_byte ) { out_byte++; } void lcd_clear( void ) { unsigned char byte; byte++; } void lcd_init( void ) { unsigned char byte; byte++; }
; c:\c51\proj\Test\lcd.SRC generated from: c:\c51\proj\Test\lcd.c NAME LCD ?PR?lcd_busy?LCD SEGMENT CODE ?PR?_lcd_out?LCD SEGMENT CODE ?PR?_lcd_outchar?LCD SEGMENT CODE ?PR?_lcd_outinstr?LCD SEGMENT CODE ?PR?lcd_clear?LCD SEGMENT CODE ?XD?lcd_clear?LCD SEGMENT XDATA OVERLAYABLE ?PR?lcd_init?LCD SEGMENT CODE ?XD?lcd_init?LCD SEGMENT XDATA OVERLAYABLE ?PR?_lcd_gotoxy?LCD SEGMENT CODE ?PR?lcd_clreol?LCD SEGMENT CODE ?XD?lcd_clreol?LCD SEGMENT XDATA OVERLAYABLE PUBLIC lcd_clreol PUBLIC _lcd_gotoxy PUBLIC lcd_init PUBLIC lcd_clear PUBLIC _lcd_outinstr PUBLIC _lcd_outchar PUBLIC _lcd_out PUBLIC lcd_busy RSEG ?XD?lcd_clreol?LCD byte?545: DS 1 ; #pragma SRC ; #pragma LARGE ; ; bit lcd_busy( void ) { RSEG ?PR?lcd_busy?LCD lcd_busy: ; SOURCE LINE # 4 ; return 1; ; SOURCE LINE # 5 SETB C ; } ; SOURCE LINE # 6 ?C0001: RET ; END OF lcd_busy [...]
"that SRC thing is just a help for you to build the structure of a function." Well, that's certainly a very good way to write C51-compatible assembler functions, but it is by no means the sole purpose of this facility! Having said that, I still doubt the wisdom of what Ken is suggesting!
Hello, Thank You All. The problem is that I need to do some manual saving of registers to stack. However with interrupts.. I dont know in advance which register are being saved. Is there any way to disable Keil from doing this register saving? Will it make any difference if I write the ISR totally in Assembly? Regards, KC
Will it make any difference if I write the ISR totally in Assembly? if you do that EVERYTHING including register saves (do not forget the PSW) is up to you, nothing is automatic. Usually a bank swotch ("using") is a better solution if you use several registers. Erik
"The problem is that I need to do some manual saving of registers to stack." But why??? C51 guarantees that it will preserve registers through an interrupt function. As I said before, if you really do need so do this, then you should do it entirely in assembler - as Erik said, that guarantees that you are totally in control of everything that goes on (and, therefore, to blame for anything that goes wrong!!)