Последний раз редактировалось 0xDEAD; 25.01.2023 в 02:05.
Спасибо goodboy, диапазон #0000-#FFFF можно было представить в десятичном виде, потому что я думаю не все читатели статьи пока понимают, что FFFF в десятичном представлении это 65535, между прочим создатели журнала ZX Ревю тоже частенько упускали этот момент, возможно для экономии бумаги - предполагая что читатель читал все номера журнала и сориентируется. Я честно говоря сам долго догонял - вот статья с программой, в конце табличка с программой, а что с табличкой делать не понятно, так она ещё и в шестнадцатеричном виде представлена, перерыв весь журнал понял потом и даже разобрался в структуре написание программы в машинном коде! Правда об этом Я хотел позднее написать!
- - - Добавлено - - -
Дело в том, что уважаемый 0xDEAD, что программы в машинном коде и ассемблере отличаются - это первое! Второе: Ассемблер - это программа имеющая, доступ не ко всем командам процессора, а вот машинный код - совсем другое дело, даёт полный доступ абсолютно ко всем командам процессора, которые представлены в соответствующей литературе, описывающей команды процессора Z80! Как Вы ещё получите доступ к машинному коду, если не через POKE и PEEK?
Последний раз редактировалось alex8418; 25.01.2023 в 02:27.
Лучше учитесь читать в шестнадцатеричном виде числа, понятнее будет всё в дальнейшем.
А любопытно чем они отличаются?
Ассемблер это не программа, это представление команд процессора в виде, доступном(более понятном) для чтения человеком.
А то, что вы называете ассемблером, это всего навсего компилятор, да и то, актуальные версии компиляторов, как правило, понимают недокументированные команды процессора
Последний раз редактировалось LW; 25.01.2023 в 02:37.
Цифра 16 - это бит 4 значения, которое идет в порт. Этот бит переключает ПЗУ бейсика 48 или 128 (0 - 128, 1 - 48). Поскольку команда OUT реализована именно в 48м бейсике, то вывод в порт значений, где бит 4 равен нулю, подключит вместо 48го, который должен был остаться, 128й бейсик в неожиданном месте исполнения программы. В результате произойдет сбой.
Можно 128, а можно (и лучше) набрать команду usr0 из 128го бейсика. В результате попадаешь в 48й, но 128К ОЗУ при этом не заблокировано (оно блокируется, если перейти в 48й бейсик из главного меню).
Программирование (не отладка/анализ существующих программ, а составление новых!) в машинном коде сродни особо тяжелой форме мазохизма. Этим можно заняться, составляя какие-нибудь ооочень коротенькие программы на десяток команд, чтобы развлечься и получить развитие. Но для практической цели, т.е. для составления сколько-нибудь сложных и полезных программ или игр, совершенно бессмысленно. Если уж программировать на Спектруме - то на ассемблере.
И вообще, в машинном коде лучше программировать не из бейсика, а из хорошего отладчика с дизассемблером, такого, как STS. Там не надо мучаться переводить из шестнадцатеричной системы в десятичную и обратно. И еще там сразу можно посмотреть, что получилось "напрограммировать", исполнить его пошагово и т.д.
Reobne(25.01.2023)
Неожиданно вся соответствующая литература описывает команды процессора мнемониками ассемблера и только потом расшифровкой ))
И даже если использовать древнейшие трансляторы ассемблера, даже в этом случае любую недокументированную команду можно набить как DEFB байт, байт,...
Также как это обычно делают программы для спектрума - загрузкой кодового блока и передачей ему управления. Загрузка в самом простом виде выполняется загрузкой файла кода из команд бейсика. В болееизвращённомпродвинутом - кодовый блок загрузчика впихивается в тело бейсик программы. Ну и естественно структура загрузчика зависит от того с ленты или диска производится загрузка.
Напротив если будете программировать в ассемблере под zx, забудьте как выглядят адреса и мнемоники в десятичном виде )) Практически все мониторы-отладчики и прочие используют шестнадцатеричное представление, поскольку оно намного удобнее для работы с маш-кодом.
Ну и немного в тему страниц памяти.
Запись в порт #7FFD (32765) имеет битовую структуру: %00BRSnnn,
где nnn - номер страницы (биты 0-2 (0-7): изначально как правило 0),
S - номер экрана (бит 3 (8): 0 - стандартный стр.5 , 1 - дополнительный стр.7),
R - номер ПЗУ ( бит 4 (16): 1 - BASIC 48 , 0 - BASIC 128 ),
B - блокировка 128 K ( бит 5 (32): 0 - доступно , 1 - заблокировано) - если заблокировать, то не разблокируется до перезагрузки.
старшие биты 6,7 ставить в 0 ( в пентагоне, кае и других клонах могут использоваться для дополнительной памяти)
В карте процессора страницы следуют:
#0000 - #3FFF ( 0 -16383) - ПЗУ
#4000 - #7FFF (16384 - 32767) - 5
#8000 - #BFFF (32768 - 49151) - 2
#C000 - #FFFF (49152 - 65535) - окно
Если воткнуть в окно скажем 5-ю или 2-ю страницу, то она будет доступна сразу по двум адресам и по своему стандартному расположению и по окну.
Запись в порт в Z80 на ассемблере производится командами:
out (c),a ( есть также out(c),reg , где reg = a,b,c,d,e,h,l )
out (n),a где n - короткий адрес порта. (не следует использовать для #7FFD)
В случае OUT (C),A и подобными на самом деле запись A ведётся в порт с адресом в регистровой паре BC
а в случае OUT (n),A старший байт адреса порта берется из самого A, то есть значение регистра A засылается в порт с адресом (A)*256+n
В былые времена наплодили много программ, демок и т.п. использующих короткую адресацию по #xxFD вместо #7FFD, в результате на многих компах (с расширением памяти выше 128 особенно) эти программы вылетали со скрипом ))
Последний раз редактировалось Dart Alver; 26.01.2023 в 04:27.
Barmaley_m(30.01.2023)
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Спасибо за объемлющие ответы по теме машинных кодов для машины 128 килобайт, пользователям: Dart Alver, Barmaley_m, и даже пользователю LW; хорошо было бы посмотреть живые примеры применения оператора OUT 32765! Получилось, что тема переродилась из программирования на 48 килобайт машине в программирование на 128 килобайт машине! Ну это не страшно, исправим!
- - - Добавлено - - -
Dart Alver в этих строках Вы ошибки не допустили? Непонятна формула %00BRSnnn и какие такие значения a,b,c,d,e,h,l присваиваемые reg?
- - - Добавлено - - -
Команда POKE понимает только десятичные числа и работает в встроенном BASIC спектрума, не требуя загрузки дополнительного ПО в машину! А почему тогда представление команд и компилятор имеет одно и тоже название? (НО КОМПИЛЯТОР - ЭТО ЖЕ ПРОГРАММА?)
Хмм. Ну пожалуй про reg кривовато написал малость, не так надо было
out (c),a ( есть также out(c),reg , где reg = a,b,c,d,e,h,l )
а просто
out(c),reg , где reg = a,b,c,d,e,h,l
reg здесь это имя регистра (это не переменная а просто обозначение что параметром может быть один из регистров). Просто сократил чтобы не писать весь список : out (c),b , out (c),e и т.п.
также как ld reg1,reg2 - куча различных инструкций с разными регистрами в качестве аргументов.
А что непонятно в формуле %00BRSnnn ?
Знак % означает число в двоичном виде. Соответственно всё что в него входит - это соответствующие биты числа
Например этот код выставит по адресу #C000 страницу памяти с номером 7 :
- - - Добавлено - - -Код:ld bc,#7FFD ld a,#17 out (c),a ; #17 = %00010111 -> 7-я страница (nnn=7), экран в 5-й странице (S=0), ; ПЗУ BASIC 48 (R=1), порт не блокируется (B=0)
Хоть я уже бейсик позабыл напрочь, но если вам так нужен беспонтовый пример чего можно делать из бейсика, то вот :
Для работы примера нужно каким либо граф-редактором предварительно создать на диске 6 файлов скриншотов с расширением C (CODE) длиной 6912 байт : "scr0","scr1","scr3","scr4",scr6","scr7Код:10 CLEAR 45055 20 DATA 0,1,3,4,6,7 30 RESTORE 20 40 GO SUB 1000 : RANDOMIZE USR 15619 : REM : LOAD "scr0" CODE 49152 50 GO SUB 1000 : RANDOMIZE USR 15619 : REM : LOAD "scr1" CODE 49152 60 GO SUB 1000 : RANDOMIZE USR 15619 : REM : LOAD "scr3" CODE 49152 70 GO SUB 1000 : RANDOMIZE USR 15619 : REM : LOAD "scr4" CODE 49152 80 GO SUB 1000 : RANDOMIZE USR 15619 : REM : LOAD "scr6" CODE 49152 90 GO SUB 1000 : RANDOMIZE USR 15619 : REM : LOAD "scr7" CODE 49152 200 DATA 33,0,192,17,0,64,1,0,27,237,176,201 210 RESTORE 200 220 FOR i=45056 TO 45056+11 230 READ a : POKE i,a 240 NEXT i 300 RESTORE 20 310 FOR i=0 TO 5 320 GO SUB 1000 330 RANDOMIZE USR 45056 340 PAUSE 0 : NEXT i 350 GO TO 300 1000 READ a : OUT 32765,a+16 : RETURN
Програмка тупо грузит экраны по страницам памяти, создаёт совсем маленькую подпрограмку в кодах:
которая копирует со страницы в область отображаемого экрана.Код:ld hl,#C000 ; 33,0,192 ld de,#4000 ; 17,0,64 ld bc,#1B00 ; 1,0,27 ldir ; 237,176 ret ; 201
А потом циклически запускает эту програмку (новый запуск по нажатию любой клавиши), переключая страницы командой бейсика OUT.
Barmaley_m(01.04.2023)
я бы ещё и `теневой` экран задействовал, так сказать для показа всего функционала.
а данные на страницы универсальней грузить в цикле, переменную можно добавить в имя файла.
load "scr"+str$ A code
...........
именно для basic128 out вообще не нужен, достаточно занести номер страницы в (23388) и он сам её выставит
Последний раз редактировалось goodboy; 29.01.2023 в 12:48.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)