vak: (Default)
[personal profile] vak posting in [community profile] besm6
Сейчас к периферийным регистрам можно обращаться из Паскаля через указатели. К примеру, код:
program test();
var
src, dst: @integer;
begin
src := ptr(77755B);
dst := ptr(77756B);
repeat
dst@ := src@
until false;
end.
превращается в:
    c2:  10 010 0000  xta (8)        ; =77755
01 000 0050 atx 050(1) ; src
c3: 10 010 0001 xta 1(8) ; =77756
01 000 0051 atx 051(1) ; dst
c4: 01 23 00050 wtc 050(1) ; src@
00 010 0000 xta
c5: 01 23 00051 wtc 051(1) ; dst@
00 000 0000 atx
c6: 00 30 00004 uj 4
00 22 00000 utc
Команда WTC выполняет косвенное обращение к периферийному регистру через указатель. При этом нужно выделять память на указатели.

Есть более эффективный способ, если чуть улучшить линкер в юниксном стиле. Объявляем внешнюю структуру, которая по адресам сооветствует расположению периферийных регистров. Обращение к полям этой структуры будет превращаться в чтение/запись регистров. При этом будет использоваться команда UTC, чуть более эффективная, и не нужна дополнительная память на указатели. Пример:
program test(gpio);
var
gpio: record { периферийные регистры блока GPIO }
unused0, { 77750 - на будущее }
unused1, { 77751 }
unused2, { 77752 }
unused3, { 77753 }
CNEN, { 77754 - маска отслеживаемых пинов }
CNIE, { 77755 - вкл. прерывание по изменению сигнала }
PORT, { 77756 - запись - выдача, чтение - прием }
TRIS: integer { 77757 - направление данных }
end;
begin
repeat
gpio.PORT := gpio.CNIE
until false;
end.
Результат:
    c2:  00 22 77750  utc 77750
00 010 0005 xta 5 ; gpio.CNIE
c3: 00 22 77750 utc 77750
00 000 0006 atx 6 ; gpio.PORT
c4: 00 30 00002 uj 2
00 22 00000 utc
Надо только научить линкер привязывать внешние common-блоки к фиксированным адресам, но это нетрудно.

Date: 2019-06-05 04:41 pm (UTC)
x86128: (Default)
From: [personal profile] x86128
Протестировал на железе работу Паскаля.
При достижении конца программы, она перезапускается.

С ком-портом нормально, а вот для vga нужны битовые операции, а с ними какие-то странности.
Пользуюсь тем хитрым типом union
type
    union = record
        case integer of
            0: (i:integer);
            1: (s:set of 0..47)
        end;


Вот такой процедурой пытаюсь выдать точку:
procedure plot_xy(x,y: integer);
var
    addr, bit: integer;
    pix: union;
begin
    addr := (x div 8) + 40 * y;
    bit  := 40 + x mod 8;

    vga_al@ := addr;
    pix.i   := vga_data@;
    pix.s   := pix.s + [bit];

    vga_al@   := addr;
    vga_data@ := pix.i;
end;


Но ставятся биты как-то странно, с "дырками" когда перебираешь x от 0 до 7.
Завтра буду смотреть внимательно еще раз.
В первом приближении показалось, что при определенных вызовах этой процедуры из разных мест кода (из цикла, не из цикла, из под условия) как-то целые аргументы портятся. Буду изучать.

Date: 2019-06-06 05:05 am (UTC)
x86128: (Default)
From: [personal profile] x86128
Нашел, кажется,
вот такое выражение считается неправильно, где bit и x integer

bit := 40 + (x mod 8);

Причем bit := x mod 8;
Edited Date: 2019-06-06 09:25 am (UTC)

Date: 2019-06-06 09:38 am (UTC)
x86128: (Default)
From: [personal profile] x86128
Хорошо грабли были запрятаны.

Дело в том, что у целых чисел в экспоненте стоит всегда 064 (в старших разрядах), поэтому в этом выражении:

bit := 40 + (x mod 8)

когда X приходил из ком-порта в старших разрядах был 0-лик до той поры пока к нему не применить операцию сложения или вычитания. Как применишь так в ответе мусор.
Любопытно что операции умножения эти биты не трогают.

Переделал немного UART чтобы при чтении байта читалось 064 в старших разрядах а принтяй байт в младших и все сразу же заработало.

Из питона посылаются случайные координаты:
Там где линии алгоритм Брезенхейма (точнее его частный случай, но на Паскале)
Пример №1 https://youtu.be/1qtg4VCXjYU
Пример №2 https://youtu.be/62jhjpRayWc

Любопытно, но похоже в нашем Паскале нет "else".

Date: 2019-06-07 03:34 am (UTC)
x86128: (Default)
From: [personal profile] x86128
Вот такой код надо закодить:
plotLine(x0,y0, x1,y1)
  if abs(y1 - y0) < abs(x1 - x0)
    if x0 > x1
      plotLineLow(x1, y1, x0, y0)
    else
      plotLineLow(x0, y0, x1, y1)
    end if
  else
    if y0 > y1
      plotLineHigh(x1, y1, x0, y0)
    else
      plotLineHigh(x0, y0, x1, y1)
    end if
  end if

и сходу не получилось... ну это ладно попробую еще раз.

Добавление 064 можно избежать, если сделать например на мадлене те самые peek/poke c AOX , а на оборудовании не использовать биты с 40 по 48-й.

Date: 2019-06-07 04:57 am (UTC)
x86128: (Default)
From: [personal profile] x86128
Ох уж этот паскаль.
procedure pltln(x0, y0, x1, y1: integer);
begin
    if abs(y1 - y0) < abs(x1 - x0) then
        if x0 > x1 then
            pltlo(x1, y1, x0, y0)
        else
            pltlo(x0, y0, x1, y1)
    else
        if y0 > y1 then
            plthi(x1, y1, x0, y0)
        else
            plthi(x0, y0, x1, y1)
end;


Date: 2019-06-07 05:05 am (UTC)
x86128: (Default)
From: [personal profile] x86128
Еще есть такой вопрос:
Как можно инициализировать массив:
var
   data: array[0..9] of integer = (10,20,30,40,50,60,71,80,90,91);

Ошибку выдает.
Error 103: Required token not found: SEMICOLON
00001 23 1 data: array[0..9] of integer = (10,20,30,40,50,60,71,80,90,91);
^^^^^ 0
IN 216 LINES 1 ERRORS
Edited Date: 2019-06-07 05:09 am (UTC)

Date: 2019-06-07 06:16 am (UTC)
x86128: (Default)
From: [personal profile] x86128
А если несколько массивов надо инициализировать то как будет выглядеть?

Profile

Сообщество любителей БЭСМ-6

January 2026

S M T W T F S
    123
45678910
11121314151617
18192021222324
2526272829 3031

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 8th, 2026 06:55 am
Powered by Dreamwidth Studios