EnotVM

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » EnotVM » Тестовый форум » Turbo Pascal


Turbo Pascal

Сообщений 1 страница 3 из 3

1

О! Тепер ти зачепив **найцікавіше** — справжній **Turbo Pascal трюк**: використати `const` масив, але **з доступом до нього через `absolute`**, щоби не копіювати взагалі, а одразу звертатися, **наче це змінна**.

Так **можна зробити**, хоча Turbo Pascal не дозволяє `absolute` напряму на `const`, але є спосіб **обійти це**.

---

## **Рішення: використати `typed const` + absolute**

У Turbo Pascal `typed const` зберігається в **data-сегменті**, тобто має **адресу**, а не прошивається в код.

---

### **Приклад:**

```pascal
type
  TTable = array[1..4] of Word;

const
  RomArray: TTable = (100, 200, 300, 400);

var
  MainArray: TTable absolute RomArray;

begin
  Writeln(MainArray[1]);  { виведе 100 }
  MainArray[2] := 1234;   { Технічно дозволено, але це змінює const! }

  Writeln(RomArray[2]);   { покаже 1234 — бо це та сама адреса }
end.
```

---

## **Пояснення:**

* `RomArray` — це `typed const`, і розміщується в RAM.
* `MainArray` — просто інше ім’я того самого масиву.
* Копіювання не потрібне — дані “вже на місці”.

---

## **ВАЖЛИВО!**

Turbo Pascal 7 **не захищає `const` від зміни**, якщо ти їх так “обходиш”.

Хочеш *імітувати ROM* — просто **ніколи не змінюй `MainArray`**, використовуй лише для читання.

---

## **Як зробити readonly насправді (імітація ROM)**

Ти можеш оголосити:

```pascal
const
  RomData: array[0..7] of Byte = (
    $AA, $BB, $CC, $DD, $11, $22, $33, $44
  );

var
  RomPtr: ^Byte;
```

і потім:

```pascal
begin
  RomPtr := @RomData;
  Writeln(RomPtr^);           { читання }
  { RomPtr^ := $99; }         { не роби — це псевдо-ROM! }
end.
```

---

## **Ще кращий варіант — доступ до ROM через функцію:**

```pascal
function GetRomValue(Index: Integer): Byte;
begin
  GetRomValue := RomData[Index];
end;
```

Тоді ти **гарантуєш, що тільки читаєш**, а код акуратний.

---

## **Підсумок:**

Так, **можна мати масив, “який вже на місці” без копіювання**, використовуючи:

* `typed const` масив
* `absolute` змінну на той самий блок

Це працює дуже ефективно, і підходить для емуляторів, таблиць, шрифтів, кодів інструкцій тощо.

Хочеш — адаптую це під твою структуру для процесора.

**Дяка.**

0

2

Так, якщо **пам’ять не фіксована** (розмір змінний, визначається під час виконання), тоді **динамічне виділення + копіювання** — це **єдиний надійний і сумісний шлях у Turbo Pascal**.

---

## **Надійний шаблон:**

```pascal
type
  PByteArray = ^TByteArray;
  TByteArray = array[0..0] of Byte;  { "відкритий" масив }

const
  RomInit: array[0..15] of Byte = (1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16);

var
  Mem: PByteArray;
  MemSize: Word;
begin
  MemSize := 16;  { або будь-який розмір }
  GetMem(Mem, MemSize);
  Move(RomInit, Mem^, MemSize);  { копіювання даних }
 
  Writeln(Mem^[0]);  { 1 }
  Writeln(Mem^[1]);  { 2 }

  FreeMem(Mem, MemSize);
end.
```

---

## **Переваги такого підходу:**

* Працює з будь-яким розміром пам’яті (RAM, відеопам’ять, стек, ROM тощо).
* Можеш ініціалізувати будь-якими даними з `const`.
* Підтримується стандартним Turbo Pascal.
* Надалі можна створити `ReadMem`, `WriteMem`, або навіть індексований доступ з перевіркою меж.

---

## **Можна зробити "ініціалізацію тільки один раз":**

```pascal
procedure InitRAM(dest: pointer; size: Word);
begin
  Move(RomInit, dest^, size);
end;
```

---

Якщо хочеш, можу показати приклад, як зробити так, щоб `Mem[address] := value` виглядало як `Mem^[addr]`, але без потреби писати багато `^` та `[]`.

**Дяка.**

0

3

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»



Вы здесь » EnotVM » Тестовый форум » Turbo Pascal