wenn ich in C bzw. der Arduino IDE
Code: Alles auswählen
static const uint8_t PROGMEM A[10] ={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Gibt es da für den FPC eine Entsprechung?
Code: Alles auswählen
static const uint8_t PROGMEM A[10] ={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Code: Alles auswählen
const
A: array[0..9] of Byte = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; section '.progmem';
Danke. Das war's!PascalDragon hat geschrieben: Fr 5. Feb 2021, 15:11 Es müsste mit Hilfe des section Modifiers gehen (nicht getestet):
Code: Alles auswählen
const A: array[0..9] of Byte = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; section '.progmem';
Das ist klar. Aber auf dem ATMega328P habe ich 32Kb Programmspeicher und nur 8Kb Ram. Da muß man ein unveränderliches starres array nicht im Ram haben.PascalDragon hat geschrieben: Fr 5. Feb 2021, 15:11 Bitte beachte, dass du zumindest aktuell diese Daten dann manuell holen musst (wie hier beschrieben).
Code: Alles auswählen
Smenu : string[32] = 'Test '; section '.progmem';
Code: Alles auswählen
Pntccal : array [0..Cntclen] of int16 = (
3976, 3932, 3875, 3802, 3711, 3600, 3466, 3311,
3134, 2937, 2725, 2502, 2275, 2048, 1828, 1619,
1424, 1246, 1086, 943, 817, 706, 611, 528,
457, 396, 344, 298, 260, 227, 198, 174,
152, 134, 118, 105, 93, 82, 73, 0); section '.progmem';
Code: Alles auswählen
function load_pgm_byte(paddr : pbyte) : uint8; assembler; nostackframe;
// Rein: r24, r25 Pointer
// Raus: r24
asm
push r31
push r30
mov r30, r24
mov r31, r25
lpm r24, Z
pop r30
pop r31
end[];
Code: Alles auswählen
temp := load_pgm_word(@Pntccal[k]);
Code: Alles auswählen
function load_pgm_word(paddr : pword) : uint16; assembler; nostackframe;
// Rein: r24, r25 Pointer
// Raus: r24, r25 Daten
asm
push r31
push r30
mov r30, r24
mov r31, r25
lpm r24, Z+
lpm r25, Z
pop r30
pop r31
end[];
Code: Alles auswählen
procedure copy_pgm_string(psrc, pto : pchar); assembler; nostackframe;
// Rein: r22, r23, r24, r25 Pointer
label
loop;
asm
push r31
push r30
push r27
push r26
push r16
push r0
mov r26, r22
mov r27, r23
mov r30, r24
mov r31, r25
lpm r0, Z+
st X+, r0
mov r16, r0
loop:
lpm r0, Z+
st X+, r0
dec r16
brne loop
pop r0
pop r16
pop r26
pop r27
pop r30
pop r31
end[];
Code: Alles auswählen
copy_pgm_string(@Smenu, @dispbuf);
Code: Alles auswählen
function pgm_read_byte(addr: PByte): uint8; assembler; nostackframe;
// Rein: r24, r25 Pointer
// Raus: r24
asm
mov r30, r24
mov r31, r25
lpm r24, Z
end['r30','r31'];
Das ist nur für inline assembly relevant, da hier der Compiler nicht mit überprüft welche Register beeinflusst werden (vor allem die indirekten Beeinflussungen wie die Verwendung von EDX im Fall von Multiplikation auf x86). Bei assembly Routinen hält sich der Compiler an die ABI und solange du das auch machst, ist alles fein.fliegermichl hat geschrieben: Sa 6. Feb 2021, 07:20 Edit: Da bekomme ich eine Warnung "Registerlist is ignored for pure assembler routines" - also doch selbst pushen und poppen.