mirror of
https://github.com/AntKrotov/oberon-07-compiler.git
synced 2026-10-05 09:45:47 +00:00
MSP430: изменено размещение программ в ПЗУ; исправлены примеры
This commit is contained in:
1 parent
e4023cde2e
commit
160e4a5454
11 files changed
+47
-77
No files matched your search
Binary file not shown.
+1
-1
@@ -1,2 +1,2 @@
|
||||
for %%f in (samples\MSP430\*.ob07) do Compiler.exe %%f msp430 -rom 4096 -ram 128
|
||||
for %%f in (samples\MSP430\*.ob07) do Compiler.exe %%f msp430 -rom 2048 -ram 128
|
||||
@pause
|
||||
+5
-12
@@ -424,16 +424,14 @@ SYSTEM.
|
||||
------------------------------------------------------------------------------
|
||||
Структура ПЗУ (RОM)
|
||||
|
||||
начало -> |код|свободная область|спец. данные|векторы прерываний| <- конец
|
||||
начало -> | свободная область | код | данные | векторы прерываний | <- конец
|
||||
|
||||
Компилятор поддерживает размер ПЗУ 2048..24576 байт. В верхних адресах
|
||||
располагается таблица векторов прерываний (64 байта), адреса 0FFC0H..0FFFFH.
|
||||
Непосредственно перед ней размещаются специальные данные. Программный
|
||||
код начинается с адреса (10000H - размер_ПЗУ), этот адрес является также и
|
||||
точкой входа в программу. Между кодом и спец. данными может оставаться
|
||||
свободное пространство. Если размер ПЗУ больше, чем указан при компиляции,
|
||||
то перед кодом будет свободная область. Таким способом можно зарезервировать
|
||||
нижние сегменты флэш-памяти для записи во время выполнения программы.
|
||||
Непосредственно перед ней размещаются данные (таблица типов, строки,
|
||||
множества) и перед данными - программный код. Адрес начала кода совпадает с
|
||||
точкой входа в программу (вектор сброса). Если размер ПЗУ больше, чем размер
|
||||
программы, то перед кодом останется свободная область.
|
||||
|
||||
==============================================================================
|
||||
MODULE MSP430
|
||||
@@ -533,11 +531,6 @@ TYPE
|
||||
Сбросить биты bits регистра SR.
|
||||
|
||||
|
||||
PROCEDURE GetFreeFlash (VAR address, size: INTEGER)
|
||||
Получить адрес и размер свободной области Flash/ROM
|
||||
(между кодом и данными).
|
||||
|
||||
|
||||
PROCEDURE Delay (n: INTEGER)
|
||||
Задержка выполнения программы на 1000*n тактов,
|
||||
но не менее чем на 2000 тактов.
|
||||
|
||||
+1
-10
@@ -17,9 +17,7 @@ CONST
|
||||
bsl = iv - 2;
|
||||
sp = bsl - 2;
|
||||
empty_proc = sp - 2;
|
||||
free_size = empty_proc - 2;
|
||||
free_adr = free_size - 2;
|
||||
bits = free_adr - 272;
|
||||
bits = empty_proc - 272;
|
||||
bits_offs = bits - 32;
|
||||
types = bits_offs - 2;
|
||||
|
||||
@@ -111,13 +109,6 @@ PROCEDURE [code] ClrSR* (bits: SET)
|
||||
0C112H, 2; (* BIC 2(SP), SR *)
|
||||
|
||||
|
||||
PROCEDURE GetFreeFlash* (VAR address, size: INTEGER);
|
||||
BEGIN
|
||||
SYSTEM.GET(free_adr, address);
|
||||
SYSTEM.GET(free_size, size)
|
||||
END GetFreeFlash;
|
||||
|
||||
|
||||
PROCEDURE [code] Delay* (n: INTEGER)
|
||||
4035H, 124, (* MOV #124, R5 *)
|
||||
(* L2: *)
|
||||
|
||||
@@ -106,12 +106,10 @@ END trap;
|
||||
|
||||
PROCEDURE main;
|
||||
CONST
|
||||
seg_adr = 0FC00H; (* адрес сегмента для стирания и записи (ДОЛЖЕН БЫТЬ СВОБОДНЫМ!) *)
|
||||
seg_adr = 0F800H; (* адрес сегмента для стирания и записи (ДОЛЖЕН БЫТЬ СВОБОДНЫМ!) *)
|
||||
|
||||
VAR
|
||||
adr, x, i: INTEGER;
|
||||
|
||||
free: RECORD address, size: INTEGER END;
|
||||
adr, x, i, entry: INTEGER;
|
||||
|
||||
BEGIN
|
||||
(* инициализация регистров порта P1 *)
|
||||
@@ -124,11 +122,12 @@ BEGIN
|
||||
|
||||
ASSERT(seg_adr MOD 512 = 0); (* адрес сегмента должен быть кратным 512 *)
|
||||
|
||||
MSP430.GetFreeFlash(free.address, free.size);
|
||||
(* получить адрес используемой части флэш-памяти
|
||||
(совпадает с точкой входа в программу) *)
|
||||
SYSTEM.GET(0FFFEH, entry);
|
||||
|
||||
(* проверить, свободен ли сегмент *)
|
||||
ASSERT(free.address <= seg_adr);
|
||||
ASSERT(seg_adr + 511 <= free.address + free.size);
|
||||
ASSERT(seg_adr + 511 < entry);
|
||||
|
||||
Write(seg_adr, 0, FERASE); (* стереть сегмент *)
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ BEGIN
|
||||
IF priority = 24 THEN (* прерывание от таймера A *)
|
||||
SYSTEM.GET(TACTL, x); (* взять регистр TACTL *)
|
||||
IF TAIFG * x = TAIFG THEN (* прерывание было *)
|
||||
SYSTEM.PUT(TACTL, x - TAIFG); (* сбросить флаг прерывания и обновить регистр TACTL *)
|
||||
inv_bits(P1OUT, REDLED); (* изменить состояние светодиода *)
|
||||
inv_bits(P1OUT, GREENLED); (* изменить состояние светодиода *)
|
||||
SYSTEM.PUT(TACTL, x - TAIFG) (* сбросить флаг прерывания и обновить регистр TACTL *)
|
||||
END
|
||||
END
|
||||
END int;
|
||||
@@ -108,8 +108,8 @@ BEGIN
|
||||
(* инициализация регистров таймера A *)
|
||||
SYSTEM.PUT(TAR, 0);
|
||||
SYSTEM.PUT(TACCTL0, CCIE + CAP);
|
||||
SYSTEM.PUT(TACCR0, 1000);
|
||||
SYSTEM.PUT(TACTL, TAIE + MC0 + TASSEL0)
|
||||
SYSTEM.PUT(TACCR0, 0FFFFH);
|
||||
SYSTEM.PUT(TACTL, TAIE + MC0 + MC1 + TASSEL1 + ID0 + ID1)
|
||||
END main;
|
||||
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ BEGIN
|
||||
ELSIF priority = 24 THEN (* прерывание от таймера A *)
|
||||
SYSTEM.GET(TACTL, x); (* взять регистр TACTL *)
|
||||
IF TAIFG * x = TAIFG THEN (* прерывание было *)
|
||||
SYSTEM.PUT(TACTL, x - TAIFG); (* сбросить флаг прерывания и обновить регистр TACTL *)
|
||||
inv_bits(P1OUT, GREENLED); (* изменить состояние светодиода *)
|
||||
SYSTEM.PUT(TACTL, x - TAIFG) (* сбросить флаг прерывания и обновить регистр TACTL *)
|
||||
END
|
||||
END
|
||||
END int;
|
||||
@@ -129,8 +129,8 @@ BEGIN
|
||||
(* инициализация регистров таймера A *)
|
||||
SYSTEM.PUT(TAR, 0);
|
||||
SYSTEM.PUT(TACCTL0, CCIE + CAP);
|
||||
SYSTEM.PUT(TACCR0, 1500);
|
||||
SYSTEM.PUT(TACTL, TAIE + MC0 + TASSEL0);
|
||||
SYSTEM.PUT(TACCR0, 0FFFFH);
|
||||
SYSTEM.PUT(TACTL, TAIE + MC0 + MC1 + TASSEL1 + ID0 + ID1);
|
||||
|
||||
(* инициализация регистров сторожевого таймера *)
|
||||
set_bits(IE1, WDTIE);
|
||||
|
||||
@@ -192,7 +192,7 @@ BEGIN
|
||||
|
||||
C.Ln;
|
||||
C.String("Akron Oberon Compiler v"); C.Int(UTILS.vMajor); C.String("."); C.Int2(UTILS.vMinor);
|
||||
C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) 2021-01-17");
|
||||
C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) 2021-01-18");
|
||||
C.StringLn("Copyright (c) 2018-2021, Anton Krotov");
|
||||
|
||||
IF inname = "" THEN
|
||||
|
||||
+20
-31
@@ -1651,7 +1651,7 @@ PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIO
|
||||
VAR
|
||||
i, adr, heap, stack, TextSize, TypesSize, bits, n, val: INTEGER;
|
||||
|
||||
Code, Data, Bss, Free: RECORD address, size: INTEGER END;
|
||||
Code, Data, Bss: RECORD address, size: INTEGER END;
|
||||
|
||||
ram, rom: INTEGER;
|
||||
|
||||
@@ -1679,11 +1679,6 @@ BEGIN
|
||||
CHL.PushInt(Labels, 0)
|
||||
END;
|
||||
|
||||
FOR i := 0 TO LEN(mem) - 1 DO
|
||||
mem[i] := 0
|
||||
END;
|
||||
|
||||
TypesSize := CHL.Length(IL.codes.types) * 2;
|
||||
CodeList := LISTS.create(NIL);
|
||||
RelList := LISTS.create(NIL);
|
||||
REG.Init(R, Push, Pop, mov, xchg, NIL, NIL, {R4, R5, R6, R7}, {});
|
||||
@@ -1692,11 +1687,19 @@ BEGIN
|
||||
translate(chkSTK IN options.checking);
|
||||
epilog;
|
||||
|
||||
Code.address := 10000H - rom;
|
||||
Code.size := Fixup(Code.address, IntVectorSize + TypesSize);
|
||||
Data.address := Code.address + Code.size;
|
||||
TypesSize := CHL.Length(IL.codes.types) * 2;
|
||||
Data.size := CHL.Length(IL.codes.data);
|
||||
Data.size := Data.size + Data.size MOD 2;
|
||||
IF ODD(Data.size) THEN
|
||||
CHL.PushByte(IL.codes.data, 0);
|
||||
INC(Data.size)
|
||||
END;
|
||||
Code.size := Fixup(0, IntVectorSize + TypesSize + Data.size);
|
||||
Code.address := 10000H - (IntVectorSize + TypesSize + Data.size + Code.size);
|
||||
IF Code.address < 10000H - rom THEN
|
||||
ERRORS.Error(203)
|
||||
END;
|
||||
Code.size := Fixup(Code.address, IntVectorSize + TypesSize + Data.size);
|
||||
Data.address := Code.address + Code.size;
|
||||
TextSize := Code.size + Data.size;
|
||||
|
||||
IF Code.address + TextSize + MAX(IL.codes.dmin - Data.size, IntVectorSize + TypesSize) > 10000H THEN
|
||||
@@ -1729,13 +1732,11 @@ BEGIN
|
||||
|
||||
adr := Data.address;
|
||||
|
||||
FOR i := 0 TO CHL.Length(IL.codes.data) - 1 DO
|
||||
FOR i := 0 TO Data.size - 1 DO
|
||||
mem[adr] := CHL.GetByte(IL.codes.data, i);
|
||||
INC(adr)
|
||||
END;
|
||||
|
||||
adr := 10000H - IntVectorSize - TypesSize;
|
||||
|
||||
FOR i := TypesSize DIV 2 - 1 TO 0 BY -1 DO
|
||||
PutWord(CHL.GetInt(IL.codes.types, i), adr)
|
||||
END;
|
||||
@@ -1752,11 +1753,6 @@ BEGIN
|
||||
END
|
||||
END;
|
||||
|
||||
Free.address := Code.address + TextSize;
|
||||
Free.size := rom - (IntVectorSize + TypesSize + TextSize);
|
||||
|
||||
PutWord(Free.address, adr);
|
||||
PutWord(Free.size, adr);
|
||||
PutWord(4130H, adr); (* RET *)
|
||||
PutWord(stack, adr);
|
||||
PutWord(0001H, adr); (* bsl signature (adr 0FFBEH) *)
|
||||
@@ -1765,23 +1761,16 @@ BEGIN
|
||||
PutWord(LabelOffs(IV[i]) * 2, adr)
|
||||
END;
|
||||
|
||||
WR.Create(outname);
|
||||
|
||||
HEX.Data(mem, Code.address, TextSize);
|
||||
HEX.Data(mem, 10000H - IntVectorSize - TypesSize, IntVectorSize + TypesSize);
|
||||
HEX.End;
|
||||
|
||||
WR.Close;
|
||||
|
||||
INC(TextSize, IntVectorSize + TypesSize);
|
||||
INC(TextSize, IntVectorSize + TypesSize + Code.address MOD 16);
|
||||
INC(Bss.size, StkReserve + RTL.VarSize);
|
||||
|
||||
WR.Create(outname);
|
||||
HEX.Data(mem, Code.address - Code.address MOD 16, TextSize);
|
||||
HEX.End;
|
||||
WR.Close;
|
||||
|
||||
C.Dashes;
|
||||
C.String(" rom: "); C.Int(TextSize); C.String(" of "); C.Int(rom); C.String(" ("); C.Int(TextSize * 100 DIV rom); C.StringLn("%)");
|
||||
IF Free.size > 0 THEN
|
||||
C.String( " "); C.Int(Free.size); C.String(" bytes free (0");
|
||||
C.Hex(Free.address, 4); C.String("H..0"); C.Hex(Free.address + Free.size - 1, 4); C.StringLn("H)")
|
||||
END;
|
||||
C.Ln;
|
||||
C.String(" ram: "); C.Int(Bss.size); C.String(" of "); C.Int(ram); C.String(" ("); C.Int(Bss.size * 100 DIV ram); C.StringLn("%)")
|
||||
END CodeGen;
|
||||
|
||||
@@ -42,9 +42,7 @@ CONST
|
||||
bsl = iv - 2;
|
||||
sp = bsl - 2;
|
||||
empty_proc* = sp - 2;
|
||||
free_size = empty_proc - 2;
|
||||
free_adr = free_size - 2;
|
||||
bits = free_adr - 272;
|
||||
bits = empty_proc - 272;
|
||||
bits_offs = bits - 32;
|
||||
DataSize* = iv - bits_offs;
|
||||
types = bits_offs - 2;
|
||||
@@ -378,18 +376,18 @@ BEGIN
|
||||
(* _error (modNum, modName, err, line: INTEGER) *)
|
||||
IF rtl[_error].used THEN
|
||||
Label(rtl[_error].label);
|
||||
Word2(4114H, 2); (* MOV 2(SP), R4; R4 <- modNum *)
|
||||
Word2(4115H, 4); (* MOV 4(SP), R5; R5 <- modName *)
|
||||
Word2(4116H, 6); (* MOV 6(SP), R6; R6 <- err *)
|
||||
Word2(4117H, 8); (* MOV 8(SP), R7; R7 <- line *)
|
||||
Word1(5321H); (* ADD #2, SP *)
|
||||
Word1(4134H); (* POP R4; R4 <- modNum *)
|
||||
Word1(4135H); (* POP R5; R5 <- modName *)
|
||||
Word1(4136H); (* POP R6; R6 <- err *)
|
||||
Word1(4137H); (* POP R7; R7 <- line *)
|
||||
Word2(4211H, sp); (* MOV sp(SR), SP *)
|
||||
Word1(1207H); (* PUSH R7 *)
|
||||
Word1(1206H); (* PUSH R6 *)
|
||||
Word1(1205H); (* PUSH R5 *)
|
||||
Word1(1204H); (* PUSH R4 *)
|
||||
Word2(4214H, sp); (* MOV sp(SR), R4 *)
|
||||
Word2(4414H, trap); (* MOV trap(R4), R4 *)
|
||||
Word1(1284H); (* CALL R4 *)
|
||||
Word2(1294H, trap); (* CALL trap(R4) *)
|
||||
Word2(04032H, 0F0H) (* MOV CPUOFF+OSCOFF+SCG0+SCG1, SR *)
|
||||
END;
|
||||
|
||||
|
||||
Reference in new issue
Block a user