I found certain problem with 6502 target processor using SDCC. I tried three versions of this compiler, and problem exists botn on Windows 8 and on Ubuntu Linux 20.04 (I use the version for Windows by WINE, because I have not updated Linux).
Version 4.2.0 64-bit:
The problem not exists in this version, but this version has probably hardcoded the program area and data area in memory. The data is in the 0x800.
The compiler ignores the "code-loc", "code-size" and "data-loc" parameters.
If the program in C has not syntax errors, the compiler does not emit any messages.
Version 4.3.0 64-bit and Version 4.4.0 32-bit (the final 64-bit version for Windows not exists yet).
If I compile the same code, the compiler emit such warnings:
SomeFile.c:16: warning 283: function declarator with no prototype
The line is the begining of function, for instance "void main()". The compiler creates the *.ihx file and the program seems be working, but the program is not usable, when contains multiplication.
In version 4.3.0 and 4.4.0, the multiplication if two integers generates mistakes and the program does not work correctly. Also, there are alco calculate errors and mistakes when using floating point numbers.
A em developing the 6502c2 emulator "for education and entertainment" and I very detaily anayzed the emulator working assumin, that there is bugs in the instruction interpretation.
I tested the miultiplication algorithm alone found in the SDCC\src\mos6502_mulint.s file by creating small prgram using this code and my emulator multiplies correctly.
There is problem in passing the numbers from my code into library code.
Because the e-mail system can refuse mail containing any attachments, I below write the test program, which illustrates the problem in multiplication:
****************************************************************************************************
#define mem_swap 0x8000
#define uchar unsigned char
#define _char ((char volatile *)0)
#define _uchar ((uchar volatile *)0)
#define _schar ((schar volatile *)0)
float N[10];
int TI[10];
void main()
{
_uchar[mem_swap + 128] = 0x88;
TI[0] = 14; // 0E 00
TI[1] = 45; // 2D 00
//The multiplication result should be 76 02
_uchar[mem_swap + 128] = 0xA1;
TI[2] = TI[0] * TI[1];
_uchar[mem_swap + 128] = 0xA2;
uchar * C = TI;
_uchar[mem_swap + 0x10] = C[ 0];
_uchar[mem_swap + 0x11] = C[ 1];
_uchar[mem_swap + 0x12] = C[ 2];
_uchar[mem_swap + 0x13] = C[ 3];
_uchar[mem_swap + 0x14] = C[ 4];
_uchar[mem_swap + 0x15] = C[ 5];
_uchar[mem_swap + 0x16] = C[ 6];
_uchar[mem_swap + 0x17] = C[ 7];
_uchar[mem_swap + 0x18] = C[ 8];
_uchar[mem_swap + 0x19] = C[ 9];
_uchar[mem_swap + 0x1A] = C[10];
_uchar[mem_swap + 0x1B] = C[11];
_uchar[mem_swap + 128] = 0xFF;
while(1)
{
}
}
****************************************************************************************************
The test process and reproducng problem should be following:
1. Compile the code as C file by this command: sdcc -mmos6502 --code-loc 0x0800 --code-size 0x6000 --data-loc 0x9000 File.c
2. Run the *.ihx file in any 6502 emulator/simulator.
3. By running, skip instructions until the byte in the address 0x8080 (mem_swap constant + 128) will have the 0x88 value
4. Observe and analyse the execution especially between taking valu 0xA1 in mem_swap+128 and taking value 0xA2. Between the two moments, the multiplication is performed.
5. After multiplication calculating, there will be written the numbers in the memory from the address 0x8010 (mem_swap+16). Tou should see the source values and multiplied value written by two bytes per value ad the int type consists of tho bytes.
How to solve the varnings in the 4.4.0 version in 6502 and how to solve the problem in multiplication?
This means as following: Run the code without watching or following anything until the 0x8080 gets the 0x88 value. After this event, observe the running code.
The warning is because that main, when without parameters should be declared
main( void ). Just put thatvoidthere.Now, I found, that the
--data-locparameter makes the problem. If I ommit the parameter, the compiled program works correctly, if I compile with--data-loc 0x9000, the problem exists in 4.4.0.Here is the another example, that illustrates the same problem, which exists both in 4.2.0 and 4.4.0.
I analyzed the case, when compiled using this command line:
sdcc -mmos6502 --code-loc 0x0800 --code-size 0x6000 --data-loc 0x9000 FileProg.cWith the parameter, between
_uchar[mem_swap + 128] = 0xA4;and_uchar[mem_swap + 128] = 0xA5;the program writes the jump address into 0x0000, but jumps into address stored at the 0x9000 byte. These jump causes jam.Without the parameter
--data-loc 0x9000, the code works good.In the conclusion, the
--data-loc 0x9000used to enforce specified read/write area for temporary data seems not work correctly, especially, when the compiler user zero-page addressing.--data-locwill move the near data (zero page in 6502 speak) start address. On standard 6502 valid values are between 0 and 0xff. In practice 0xc0 is likely the max as the compiler needs some zero page locations to work properly.to move where far data (i.e. 16-bit addresses) is stored you need to use
--xram-locThe above is not properly described in the docs and should be fixed. A quick inspection of the .lk files generated during compilation should clarify the issue.
Last edit: Gabriele Gorla 2024-12-06
SDCC should complain when the --data-loc value is above 0xFF.
i added a note in the documentation on how to correctly use --data-loc and --xram-loc in [r15153]
Related
Commit: [r15153]