• avatar n1k-o
  • 1
го я создал!
  • avatar sq
  • 0
Ага!
  • avatar sq
  • 1
Официаль объявляем победителем — Олежеьку n1k-o !

Он и объявляет следующую игру!

И ждём диплома от nodeus !)
  • avatar n1k-o
  • 1
Ну, хоть где-то мне повезло :) Ну, что, я могу начинать новый топик?
  • avatar aa-dav
  • 0
Тогда еще добавка из последнего:
Добавил поддержку локальных меток — начинаются с точки и по факту разворачиваются внутри парсера в lastGlobalLabel.thisLocalLabel таким образом можно обратится к метке из любой точки программы по полному имени, но в пределах одной процедуры можно обращаться по короткому имени. При этом создание символов через = не засчитывается как глобальная метка после которой локальные будут соединятся с ней — только прямые объявления меток.
Добавил ключевое слово ds x [ y ] которое создаёт массив размером x слов заполненных значением y (если не указано — 0).
Для краткости и понятности вызова процедур ввёл 4 псевдоинструкции:

call arg
; эквивалентно следующему:
[ sp ] =+2 pc
pc = arg

ret
; эквивалентно
pc = [ sp ]

; а так же для быстрых вызовов:

qcall arg
; эквивалентно
r4 =+2 pc
pc = arg

qret
; эквивалентно
pc = r4

В силу того как парсером обрабатываются коды условий типа @nz @z — их можно присовокуплять к этим инструкциям точно так же как к обычным. Однако надо помнить, что если адрес процедуры есть не прямая метка (addr16), а содержимое регистра, то call (как и qcall) неприменима, т.к. первой инструкцией в ней должна быть [ sp ] =+1 pc, поэтому косвенные переходы по крайней мере пока надо расписывать полностью.
Так же PORT_CONSOLE теперь еще работает на ввод возвращая или 0 или символ последней нажатой клавиши (пока по сути обёртка над kbhit/getch без учёта какой то виртуальной архитектуры).
Так же еще кучу багов вымел как в виртуальной машине так и в ассемблере.
В общем теперь возможно написать такую программу:

PORT_CONSOLE    = $FFFF
    sp  = $FF00

    pc  = start

; string_input
; in: r0 - string buffer
;     r1 - max buffer size
; out: 
string_input  r3  = r0    ; remember beginning
.loop    r2  =? [ PORT_CONSOLE ]
    pc  = .loop @z
    r2  <?> 13
    pc  = .end @z  ; if CR
    r2  <?> 8
    pc  = .backsp @z  ; if BS
    r1  =? r1
    pc  = .overfl @z  ; if buffer overflow
    ; accept symbol
    [ PORT_CONSOLE ] = r2
    r1  =-1 r1
    [ r0 ]  = r2
    r0  =+1 r0
    pc  = .loop    ; continue input
    ; backspace
.backsp    r0  <?> r3
    pc  = .loop @z  ; ignore del at start of line
    [ PORT_CONSOLE ] = r2
    [ PORT_CONSOLE ] = 32  ; erase prev symbol at (windows) console...
    [ PORT_CONSOLE ] = r2
    r1  =+1 r1
    r0  =-1 r0
    pc  = .loop
    ; overflow
.overfl    pc  = .loop ; just continue
    ; end
.end    [ r0 ]  = 0
    ret

; string_print
; in: r0 - string buffer
string_print  r1  =? [ r0 ]
    ret @z
    r0  =+1 r0
    [ PORT_CONSOLE ] = r1
    pc  = string_print

; string_len  
; in:  r0 - string buffer
; out:  r0 - length of the string
string_len  r1  = 0
.loop    r2  = [ r0 ]
    pc  = .end @z
    r0  =+1 r0
    r1  =+1 r1
    pc  = .loop
.end    r0  = r1
    ret

start    
    r0  = msg1
    call  string_print
    r0  = buf
    r1  = 10
    call  string_input
    [ PORT_CONSOLE ] = 10

    r0  = msg2
    call   string_print
    r0  = buf
    call  string_print
    r0  = CrLf
    call  string_print

    dw  0
buf    ds  12 $AAAA
msg1    dw  "Enter command: " 0
msg2    dw  "You entered this text: " 0
CrLf    dw  13 10 0

Программа выведет приглашение ввести с клавиатуры текст в буфер ограниченный десятью символами и выведет потом введённый текст в консоль же.
В принципе это уже приближается к реальному машинописанию на реальном ассемблере, можно писать достаточно сложные программы и почувствовать отклик от них.

И ощущения от архитектуры двоякие.
С одной стороны сам ассемблерный код несмотря на сильно упрощенный синтаксис и крайнюю схожесть с человекочитаемыми операторами из сишечки всё равно выглядит как стена ассемблерного и плохосчитываемого кода. :D Какой то революции человекочитаемого ассемблера не случилось.
С другой стороны мозг реально разгружен когда _пишешь_ на этом ассемблере по сравнению с классикой — не нужно как в Z80 на том же спектруме постоянно задумываться над тем как и куда перекинуть результаты из аккумулятора или HL, во что развернуть проверку регистровой пары на достижение нуля, какие там есть двухбайтовые инструкции на которых можно сэкономить и т.п.

8<=============

А виртуальной машины пока еще нет чтобы эффектами меряться. Да и много чего нет — инструкции в АЛУ даже вводятся по мере того как появляются в них потребности. Это в свою очередь интересно тем, что как только видно что какая то инструкция часто нужна, то берешь и вводишь её — например move with flags update которая пишется в этом синтаксисе как =? и перемещает данное обновляя флаги S и Z обычно не встречается, но тут сразу попросилась разгружать циклы для asciiz-строк.
укочал, но времени смотреть пока нет

для наглядности взял бы ты сырцы покороче от какого-нибудь спековского эффекта и переписал на своём
  • avatar sq
  • 2
Обогнал C-Jeff'а!
нет, это на сабж в целом
Это на мой вопрос?
ойсложнафсё...
румынский генштаб не разобрался )
Если мне нужно программировать для Profi в CP/M? И при этом мне нужно запустить скомпилированную программу из командной строки с определенными параметрами? Это возможно?
  • avatar VBI
  • 2

ну вот так, уже руки отваливаются :)
  • avatar n1k-o
  • 1

Пробовал еще разок :)
  • avatar aa-dav
  • 1
круто, у меня тоже был Кворум 64к и я даже уже знал про то что он совместим с CP/M за счёт дополнительных 16Кб ОЗУ и особых режимов памяти, но техническую информацию об этом так и не смог найти в своё время. спасибо за ссылку!
  • avatar oisee
  • 1
Был у меня Кворум 64k, но про его суперспособности я и не знал :)
Вот поделились видео ZORK1 на Кворуме (клон спектрума).
Я не знаю английского. В русскоязычные играл, но под CP/M нет таких. Хотя можно попробовать перевести. Только вот построение фраз (команд) останется на английская манер.
  • avatar oisee
  • 0
Кросота =) Прошёл?


ZORK 1 и 3 запущенные на Spectrum Profi :)