PDA

Просмотр полной версии : Тема для всяких глупых вопросов



Страницы : [1] 2 3

NEO SPECTRUMAN
09.07.2020, 16:04
Собственно было бы не плохо сделать тему прилепленной


ну и первый глупый вопрос собственно от меня

какой режим IO портов AY-ка нужно выставлять по дефолту?
для большей совместимости со всякими там девайсами притуленными к AY
на ввод?
или на вывод?

Barmaley_m
16.07.2020, 23:42
Какова бы ни была аппаратура, она обычно разрабатывалась так, чтобы при сбросе системы не мешать работе бейсика, TR-DOS и прочего ПО, которое об этой аппаратуре ничего не знает. Ведь специальное ПО для инициализации AY и работы с этой аппаратурой можно было запустить только после пуска бейсика и TR-DOS. И, если бы автор схемы нарушил условие её работоспособности при сбросе - то он бы быстро это заметил и поправил.

Соответственно, после сброса инициализировать ничего не надо, а если инициализировать - то в тот же режим, который устанавливается при сбросе AY.

izzx
11.08.2020, 09:55
Подскажите, пожалуйста, какой утилитой на ZX снять образ дискетки со сбойными секторами и порушенной структурой файлов? Считать как есть, пропуская битые секторы, желательно в TRD, чтобы потом поковырять на PC. Хотел с помощью WDC, но он ругается на диск.

SoftLight
11.08.2020, 10:08
Подскажите, пожалуйста, какой утилитой на ZX снять образ дискетки со сбойными секторами
Это смотря какой ZX. Вот обучалово на Пентево: https://www.youtube.com/watch?v=YkA3jEqLNb8
А еще есть Floppy Disk Reaper (http://speccy-live.untergrund.net/2014/12/floppy-disk-ripper-firmware-zx-and-pc-tools/).

Если снимать образ на PC, то вариантов побольше. Из свежайшего есть прекрансный Spectrum Archive Reader (https://zx-pk.ru/threads/31601-spectrum-archive-reader-programma-dlya-chteniya-tr-dos-diskov.html).

izzx
11.08.2020, 10:43
Это смотря какой ZX
Scorpion GMX.

Вспомнил что fatall вроде даёт пропускать сбойные секторы. А Ещё?
А ещё на PC может есть утилиты которые автоматом создают системные секторы 1-9? Просканировали образ, нашли файлы ).

Dwa83
24.08.2020, 10:26
Кто может подсказать? Проблема вот в чём: если при написании проги не юзать страницы в коде, то у меня компиль создаёт SNA для 48. И всё бы ничего, но страницы больше не переключаются, как будто уже включена "защёлка". Приходится писать костыль типа
PAGE 1
DEFB 0
чтобы сразу создавался снапшот для 128, где состояние порта #7ffd явно указывается.
Вроде бы в буфере принтера при режиме 128 используется дополнительная системная переменная - копия порта, но там значение нормальное %00000000 (подключена страница 0, видеостраница - 5 банк, пзу - бейсик 128, и защёлка в нуле). Чего я не учёл при сохранении SNA?

Black Cat / Era CG
24.08.2020, 13:58
А может это особенности эмуля, он ест 48 сна и автоматом выбирает 48 модель.

Dwa83
24.08.2020, 14:07
Я об этом не подумал, щас попробую с другим(Звучит как: Мой молодой человек такой-то и такой-то.. ааа.. щас попробую с другим))))

- - - Добавлено - - -

Нет, на эмузвине то же самое, что-то не так с форматом sna(щас попробую 48)

Black Cat / Era CG
24.08.2020, 14:11
В сна вроде прописывается модель, тогда поведение эмулей логично в принципе.

Dwa83
24.08.2020, 15:02
Нет попробовл разно

void ZX_SNA_Saver::FillStandartRAM(ByteVector & ram, unsigned int start)
{
ram.insert(ram.end(), 6144, 0); //Данные экрана
ram.insert(ram.end(), 768, 56); //Данные атрибутов
//23296
//ram.insert(ram.end(), 256, 0); //Буфер принтера(или если 128, доп область переменных)
ram.insert(ram.end(), 89, 0); //Буфер принтера(или если 128, доп область переменных)
ram.push_back(16); // копия порта
ram.insert(ram.end(), 166, 0); //Буфер принтера(или если 128, доп область переменных)
//23388 = копия порта
//Системные переменные


- - - Добавлено - - -


В сна вроде прописывается модель
Где в 48 формате это прописывается?
гдето в
mas.push_back(6); //Флаги прерываний
mas.push_back(0); //Регистр регенерации динамической памяти R?
Кто-то ведь работал плотно со снапшотами

void ZX_SNA_Saver::FillHeader(ByteVector & mas, unsigned int start)
{
//Заполним заголовок sna(27 байт)
mas.push_back(63); //регистр I

mas.push_back(0); //HL'
mas.push_back(0);
mas.push_back(0); //DE'
mas.push_back(0);
mas.push_back(32); //BC'
mas.push_back(23);
mas.push_back(68); //AF'
mas.push_back(0);

mas.push_back(168); //HL
mas.push_back(16);
mas.push_back(185); //DE
mas.push_back(92);
mas.push_back(0); //BC
mas.push_back(0);
mas.push_back(58); //IY
mas.push_back(92);
mas.push_back(0); //IX
mas.push_back(0);

mas.push_back(6); //Флаги прерываний
mas.push_back(0); //Регистр регенерации динамической памяти R

mas.push_back(116); //AF
mas.push_back(0);
mas.push_back((start - 2) % 256); //SP
mas.push_back((start - 2) / 256);

mas.push_back(1); //Режим прерываний
mas.push_back(7); //Цвет бордюра

}

- - - Добавлено - - -


В сна вроде прописывается модель
В сна 128 порт задаётся явно, в 48 хз где, в этом и вопрос

- - - Добавлено - - -

Или 48к снапшоты изначально с заглушкой доп памяти?

- - - Добавлено - - -

Может в режиме 128 в области доп переменных ещё что-то нужно, а у меня там нули?

- - - Добавлено - - -

Пока не критично конечно, но надо исправлять

- - - Добавлено - - -

Никто не знает?(что сомнительно) или реально эмули видя 48 заглушают память? так не должнож быть

- - - Добавлено - - -

Стопудняк проблема в одном бите, но я не знаю в каком

goodboy
24.08.2020, 15:16
реально эмули видя 48 заглушают память?
точнее эмулируют именно 48ую модель.
вообще именно SNA - неудачный формат. при сохранении PC пишется в стек,
а если стек в данных (что частенько встречается в программах) они будут запороты

shurik-ua
24.08.2020, 15:54
можешь попробовать создать нужный тебе SNA файл - первые 27 + 49152 байта как из 48-го снапшота - затем добавляешь 2 байта PC, 1 байт Состояние порта #7FFD и 1 байт Выбор ПЗУ TR-DOS (0 - неактивно, 1 - активно)
итого должен получиться файл по размеру обычного SNA-48 плюс 4 байта.

вот (http://speccy.info/SNA)

Dwa83
24.08.2020, 16:23
создает 48й снап, а эмулятор при его загрузке автоматом включает 48ю модель.
А зачем они это сделали? понимаю, что вопрос к разработчикам..

- - - Добавлено - - -

Но ведь загружаяе 48(не имея доп банок памяти в файле), можно ведь оставить заглушку(бит) в нуле! это у всех эмулей?

- - - Добавлено - - -

Что-то тут не так

- - - Добавлено - - -

или функция прерывания что-то делает стандартная? дак тем более у меня 128 бэйсик пзу тогда тоже делает... нипаняяяятна

- - - Добавлено - - -

Я подозреваю, что где-то я в сохранении сна косяк допустил

- - - Добавлено - - -

Это конечно не критично, но даже сна48 должен сохранять возможность переключения банок, даже если это ни к чему не приведёт

- - - Добавлено - - -

Это конечно не критично, но даже сна48 должен сохранять возможность переключения банок, даже если это ни к чему не приведёт


можешь попробовать создать нужный тебе SNA файл - первые 27 + 49152 байта как из 48-го снапшота - затем добавляешь 2 байта PC, 1 байт Состояние порта #7FFD и 1 байт Выбор ПЗУ TR-DOS (0 - неактивно, 1 - активно)
итого должен получиться файл по размеру обычного SNA-48 плюс 4 байта.
Оно так всё и есть, по размеру всё сохраняется... ну сам вот посмотри


#include <ZX_SNA_Saver.h>
#include <fstream.h>



bool ZX_SNA_Saver::SaveSna(GensCompiler & compiler, AnsiString filename)
{
ByteVector ram;
unsigned int start = compiler.GetStartAddress();

FillStandartRAM(ram, start);

//Определим 128k или 48k
bool is128 = false;
for (int i = 0; i < 8; i++)
if (i != 2) is128 |= compiler.BynaryCodeSize(i) > 0;

//банк 5
if (compiler.BynaryCodeSize(5) > 0)
{
for (unsigned int i = 0; i < compiler.BynaryCodeSize(5); i++)
{
if (i < 0xC000)
ram[i] = compiler.GetCodeByte(5,i);
else
{
ShowMessage("Внимание! Данные в банке 5 вышли за пределы #FFFF и будут обрезаны.");
break;
}
}

if (compiler.BynaryCodeSize(5) + 0x4000 > start - 2)
ShowMessage("Внимание! Начало основного кода перекрывает данные в банке 5.");
}

//банк 2
if (start <= 0x4000)
ShowMessage("Внимание! Область стека перекрывает ПЗУ.");

for (unsigned int i = 0; i < compiler.BynaryCodeSize(2); i++)
{
if (start + i <= 0xFFFF)
ram[start + i - 0x4000] = compiler.GetCodeByte(2,i);
else
{
ShowMessage("Внимание! Основной код вышел за пределы #FFFF и будет обрезан.");
break;
}
}

//банк 0
if (compiler.BynaryCodeSize(0) > 0)
{
if (start + compiler.BynaryCodeSize(2) >= 0xC000)
ShowMessage("Внимание! Данные в банке 0 перекрывают основной код.");

for (unsigned int i = 0; i < compiler.BynaryCodeSize(0); i++)
{
if (i < 0x4000)
ram[i + 0xC000 - 0x4000] = compiler.GetCodeByte(0,i);
else
{
ShowMessage("Внимание! Данные в банке 0 вышли за пределы #FFFF и будет обрезан.");
break;
}
}
}

ByteVector sna;
FillHeader(sna, start);

if (!is128)
{
//Запишем в стек адрес старта
ram[start - 2 - 16384] = start % 256;
ram[start - 1 - 16384] = start / 256;
}

for (int i = 0; i < 0xC000; i++) sna.push_back(ram[i]);



//Если 128k
if (is128)
{
sna.push_back(start % 256); //Регистровая пара PC
sna.push_back(start / 256);
sna.push_back(16); //Состояние порта #7FFD
sna.push_back(0); //ПЗУ TR-DOS (0 - неактивно, 1 - активно)

// Банки 1 3 4 6 7
this->Addpage(compiler, sna, 1);
this->Addpage(compiler, sna, 3);
this->Addpage(compiler, sna, 4);
this->Addpage(compiler, sna, 6);
this->Addpage(compiler, sna, 7);
}

//Сохраним снимок
ofstream file;
file.open(filename.c_str(), ios::out | ios::binary);
for (unsigned int i = 0; i < sna.size(); i++)
{
file.write(&sna[i], 1);
}
file.close();

return true;
}


void ZX_SNA_Saver::FillHeader(ByteVector & mas, unsigned int start)
{
//Заполним заголовок sna(27 байт)
mas.push_back(63); //регистр I

mas.push_back(0); //HL'
mas.push_back(0);
mas.push_back(0); //DE'
mas.push_back(0);
mas.push_back(32); //BC'
mas.push_back(23);
mas.push_back(68); //AF'
mas.push_back(0);

mas.push_back(168); //HL
mas.push_back(16);
mas.push_back(185); //DE
mas.push_back(92);
mas.push_back(0); //BC
mas.push_back(0);
mas.push_back(58); //IY
mas.push_back(92);
mas.push_back(0); //IX
mas.push_back(0);

mas.push_back(6); //Флаги прерываний
mas.push_back(0); //Регистр регенерации динамической памяти R

mas.push_back(116); //AF
mas.push_back(0);
mas.push_back((start - 2) % 256); //SP
mas.push_back((start - 2) / 256);

mas.push_back(1); //Режим прерываний
mas.push_back(7); //Цвет бордюра

}

void ZX_SNA_Saver::FillStandartRAM(ByteVector & ram, unsigned int start)
{
ram.insert(ram.end(), 6144, 0); //Данные экрана
ram.insert(ram.end(), 768, 56); //Данные атрибутов
//23296
//ram.insert(ram.end(), 256, 0); //Буфер принтера(или если 128, доп область переменных)
ram.insert(ram.end(), 89, 0); //Буфер принтера(или если 128, доп область переменных)
ram.push_back(16); // копия порта
ram.insert(ram.end(), 166, 0); //Буфер принтера(или если 128, доп область переменных)
//23388 = копия порта
//Системные переменные

//KSTATE
ram.push_back(255);
ram.insert(ram.end(), 3, 0);
ram.push_back(255);
ram.insert(ram.end(), 3, 0);

ram.push_back(0); //LAST_K
ram.push_back(35); //REPDEL
ram.push_back(5); //PEPPER

ram.insert(ram.end(), 5, 0); //DEFADD..TVDATA

//STRMS
ram.push_back(1); //-3
ram.push_back(0);
ram.push_back(6); //-2
ram.push_back(0);
ram.push_back(11); //-1
ram.push_back(0);
ram.push_back(1); //0
ram.push_back(0);
ram.push_back(1); //1
ram.push_back(0);
ram.push_back(6); //2
ram.push_back(0);
ram.push_back(16); //3
ram.push_back(0);
ram.insert(ram.end(), 24, 0); //4 и далее
ram.push_back(0); //CHARS
ram.push_back(60);
ram.push_back(64); //RASP
ram.insert(ram.end(), 3, 0); //PIP,ERR NR,FLAGS
ram.push_back(33); //TV FLAG
ram.push_back(80); //ERR SP
ram.push_back(255);
ram.insert(ram.end(), 9, 0); //LIST SP..SUBPPC
ram.push_back(56); //BORDCR
ram.insert(ram.end(), 2, 0); //Е_РРС
ram.push_back(203); //VARS
ram.push_back(92);
ram.insert(ram.end(), 2, 0); //DEST
ram.push_back(182); //CHANS
ram.push_back(92);
ram.push_back(182); //CURCHL
ram.push_back(92);
ram.push_back(203); //PROG
ram.push_back(92);
ram.insert(ram.end(), 2, 0); //NXTLIN
ram.push_back(202); //DATADD
ram.push_back(92);
ram.push_back(204); //E_LINE
ram.push_back(92);
ram.push_back(204); //K_CUR
ram.push_back(92);
ram.insert(ram.end(), 4, 0); //СН_АDD,X_PTR
ram.push_back(206); //WORKSP
ram.push_back(92);
ram.push_back(206); //STKBOT
ram.push_back(92);
ram.push_back(206); //STKEND
ram.push_back(92);
ram.push_back(0); //BREG
ram.push_back(146); //MEM
ram.push_back(92);
ram.push_back(16); //FLAGS2
ram.push_back(2); //DF_SZ
ram.insert(ram.end(), 12, 0); //S_TOP..SEED
ram.push_back(109); //FRAMES
ram.push_back(2);
ram.push_back(0);
ram.push_back(88); //UDG
ram.push_back(255);
ram.insert(ram.end(), 2, 0); //COORDS
ram.push_back(33); //P_POSN
ram.push_back(0); //PR_CC
ram.push_back(91); //NOT_USED
ram.push_back(5); //ЕСНО_Е
ram.push_back(23);
ram.push_back(0); //DF_CC
ram.push_back(64);
ram.push_back(252); //DFCCL
ram.push_back(80);
ram.push_back(33); //S_POSN
ram.push_back(24);
ram.push_back(5); //SPONSL
ram.push_back(23);
ram.push_back(1); //SCR_CT
ram.push_back(56); //ATTR_P
ram.push_back(0); //MASK_P
ram.push_back(56); //ATTR_T
ram.push_back(0); //MASK_T
ram.push_back(0); //P_FLAG
ram.insert(ram.end(), 30, 0); //МЕМВОТ
ram.insert(ram.end(), 2, 0); //NMIADD

//RAMTOP
ram.push_back((start - 1) % 256);
ram.push_back((start - 1) / 256);

ram.insert(ram.end(), 2, 255); //P_RAMT

//Карта микродрайва + CHANS
ram.push_back(244);
ram.push_back(9);
ram.push_back(168);
ram.push_back(16);
ram.push_back(75);
ram.push_back(244);
ram.push_back(9);
ram.push_back(196);
ram.push_back(21);
ram.push_back(83);
ram.push_back(129);
ram.push_back(15);
ram.push_back(196);
ram.push_back(21);
ram.push_back(82);
ram.push_back(244);
ram.push_back(9);
ram.push_back(196);
ram.push_back(21);
ram.push_back(80);
ram.push_back(128);
ram.push_back(128);
ram.push_back(13);
ram.push_back(128);

//заполним нулями
ram.insert(ram.end(), 41778, 0);
}




void ZX_SNA_Saver::Addpage(GensCompiler & compiler, ByteVector & sna, int page)
{
if (compiler.BynaryCodeSize(page) > 16384 )
ShowMessage("Внимание! Код в банке "+IntToStr(page)+" привысил размер #4000 и будет обрезан.");

for (unsigned int i = 0; i < 16384; i++)
{
if (i < compiler.BynaryCodeSize(page))
sna.push_back(compiler.GetCodeByte(page,i));
else
sna.push_back(0);
}
}

Dwa83
24.08.2020, 16:46
Но ведь эмули со временем начали понимать формат 128. Заглушку оставили(бит порта)?

- - - Добавлено - - -

или на "старое"было плевать? А можно ведь сделать игру, которая вмещается в 48, но использует 128 формат(переключение экранов)

- - - Добавлено - - -

Вообще я жду ответ на вопрос: Эмуляторы , видя 48 снапшот, ставят бит заглушки?

Black Cat / Era CG
24.08.2020, 16:48
Не. Они переключаются на 48 модель.

Dwa83
24.08.2020, 16:50
Даже если они уже 128?

- - - Добавлено - - -


Не. Они переключаются на 48 модель.
В каком случае?
Что им не даёт не трогать этот бит?

Black Cat / Era CG
24.08.2020, 16:54
В каком случае?
Что им не даёт не трогать этот бит?
В случае, если получают 48 сна на вход. Не знаю, что им мешает :)

Dwa83
24.08.2020, 16:57
Ну, значит костыль, в ненужной банке, вопрос исчерпан(нверное)
А вообще хорошо бы было, если бы создатели эмулей, при приёме в своё лоно 48к, не ставили заглушку

Black Cat / Era CG
24.08.2020, 17:02
Хрессу вот ваще никогда машину не переключает. Значит все-таки разные эмуляторы бывают, а не только спекулятор :)

Dwa83
24.08.2020, 17:40
Не знаю, что им мешает
Так может разрабы увидят, и оставят маленький всем нужный битик в положении использованитя переключений

Black Cat / Era CG
24.08.2020, 17:41
Так может разрабы увидят, и оставят маленький всем нужный битик в положении использованитя переключений
Тогда надо хотя бы перечислить, в каких эмуляторах это проверялось. Как я уже сказал, Хрессу так не делает. В Анриле не проверял. Другими не пользуюсь за ненадобностью.

Dwa83
24.08.2020, 17:58
Тогда надо хотя бы перечислить, в каких эмуляторах это проверялось

Eone 1.8
Fuse 1.1.1
EmuZwin 2.8(хотя он 2.7)
Хрессу не нашёл годного

Black Cat / Era CG
24.08.2020, 18:04
Хрессу не нашёл годного
А его просто сложно собрать в кучку.
Авторы перечисленных эмуляторов ниче не увидят, так что увы :)

Dwa83
24.08.2020, 19:35
Просто вот код


org 32768
di

ld a,%00010111
call SET_PAGE_MODE_A




call INIT_TABLE

;--------
ld ix,LINE_TABLE
ld b,24
fs push bc
call PRINT_32_SPRITE
ld de,lt_size
add ix,de
pop bc
djnz fs
;--------




strt

col ld bc,384
right push bc

call SWAP_SCREEN
call SCROLL2

ld ix,LINE_TABLE
ld b,24
nxt_ln push bc
call PRINT_NEXT_SPRITE
pop bc
ld de,lt_size
add ix,de
djnz nxt_ln
call DRAW


pop bc
dec bc
ld a,b
or c
jr nz,right
call INIT_TABLE
ld hl,416
ld (col+1),hl
jr strt



mar_y defb 143
old_y defb 143
mar_vel defw #1e00
vel_dn defb #0f

;----------------------------
update
ld hl,(mar_vel)
ld de,#c0
and a
sbc hl,de
ld a,h
or l
jr nz,upd1
ld hl,#1e00
upd1 ld (mar_vel),hl


ld a,(mar_vel+1)
ld b,a
ld a,(vel_dn)
ld d,a
ld a,(mar_y)
ld (old_y),a
add a,d
sub b
ld (mar_y),a
ret


;---------------------------------
;Первая инициализация таблицы: экранныe адресa, адреса начала строк уровня
INIT_TABLE
ld ix,LINE_TABLE
ld b,0
nxt_line
push bc
ld de,LEVEL
call ADDR_AFTER255

ld (IX+line_ptr),e
ld (IX+line_ptr+1),d

call NEXT_LINE_PTR
pop bc

call SCR_ADDR
ld (IX+print_addr),l
ld (IX+print_addr+1),h
ld (IX+attr_addr),e
ld (IX+attr_addr+1),d

ld de,lt_size
add ix,de
inc b
ld a,24
cp b
jr nz,nxt_line
ret

;---------------------------------
;Печать спрайта из ленты
PRINT_NEXT_SPRITE
ld l,(IX+ribbon_ptr)
ld h,(IX+ribbon_ptr+1)
nxt_rib
ld a,(hl) ;номер спрайта
cp 255 ;конец ленты?
jr nz,no_endrib
;конец
dec (IX+ribbon_cnt)
call z,NEXT_LINE_PTR ;счётчик обнулился, следующая лента
ld l,(IX+ribbon_start)
ld h,(IX+ribbon_start+1)
ld (IX+ribbon_ptr),l
ld (IX+ribbon_ptr+1),h
jr nxt_rib
no_endrib
;в A номер спрайта
inc hl
ld b,(hl)
ld l,a
ld h,0
push hl
;ld de,spr_attribs
;add hl,de
;ld a,(hl)
ld l,(IX+attr_addr)
ld h,(IX+attr_addr+1)
S_AA set 7,h
ld (hl),b
pop hl

add hl,hl
add hl,hl
add hl,hl ;x8
ld de,sprites
add hl,de ;адрес спрайта

ld e,(IX+print_addr)
ld d,(IX+print_addr+1)
S_PA set 7,d
ld b,8
nxt_b ld a,(hl)
ld (de),a
inc hl
inc d
djnz nxt_b

ld l,(IX+ribbon_ptr)
ld h,(IX+ribbon_ptr+1)
inc hl
inc hl
ld (IX+ribbon_ptr),l
ld (IX+ribbon_ptr+1),h

ret

;---------------------------------
;Печать 32 спрайта из ленты c первого знакоместа
PRINT_32_SPRITE
ld l,(IX+ribbon_ptr)
ld h,(IX+ribbon_ptr+1)
ld d,(IX+print_addr+1)
set 7,d
ld a,(IX+print_addr)
and 224
ld e,a

ld b,32
P32S1 push bc

P32S2 ld a,(hl) ;номер спрайта
cp 255 ;конец ленты?
jr nz,P32S3
;------
push de ;экранный адрес
dec (IX+ribbon_cnt)
call z,NEXT_LINE_PTR ;счётчик обнулился, следующая лента
ld l,(IX+ribbon_start) ;возьмём начало текущей ленты
ld h,(IX+ribbon_start+1)
pop de
;------
jr P32S2
P32S3
;в A номер спрайта
inc hl
ld b,(hl) ;атрибут спрайта
push hl ;ribbon_ptr

ld l,a
ld h,0

push hl ;номер спрайта
;push de ;экранный адрес

ld a,e
and 31
ld c,a ;номер знакоместа
;ld de,spr_attribs
;add hl,de
;ld b,(hl) ;атрибут спрайта
ld h,(IX+attr_addr+1)
set 7,h ;переключимся на 7 банку
ld a,(IX+attr_addr)
and 224
or c ;смешение адреса атрибута по х
ld l,a
ld (hl),b ;атрибут на экран

;pop de ;экранный адрес
pop hl ;номер спрайта

add hl,hl
add hl,hl
add hl,hl ;x8
push de ;экранный адрес
ld de,SPRITES
add hl,de ;адрес спрайта
pop de ;экранный адрес

push de ;экранный адрес
ld b,8
P32S4 ld a,(hl)
ld (de),a
inc hl
inc d
djnz P32S4

pop de ;экранный адрес
inc de

pop hl ;ribbon_ptr
inc hl
pop bc
djnz P32S1

ld (IX+ribbon_ptr),l
ld (IX+ribbon_ptr+1),h
ret

;---------------------------------
;Заполнение данных ленты из указателя линии уровня и его сдвиг
NEXT_LINE_PTR
ld l,(IX+line_ptr)
ld h,(IX+line_ptr+1)

ld b,(hl)



ld de,RIBBONS
call ADDR_AFTER255

ld (IX+ribbon_ptr),e
ld (IX+ribbon_ptr+1),d
ld (IX+ribbon_start),e
ld (IX+ribbon_start+1),d
inc hl
ld a,(hl)
ld (IX+ribbon_cnt),a
inc hl
ld (IX+line_ptr),l
ld (IX+line_ptr+1),h
ret
;---------------------------------
;адрес после разделителя 255 по номеру b
ADDR_AFTER255

xor a
cp b
ret z
nxt_de ld a,(de)
inc de
cp 255
jr nz,nxt_de
djnz nxt_de
ret

;---------------------------------
;сдвиг экрана
SCROLL
ld hl,(S_SRC)
ld de,(S_DST)
ld bc,6911
ldir
ret

;---------------------------------
;сдвиг экрана2
SCROLL2
S_SRC ld hl,#4001 ;10
ld (S_SRC1+1),hl ;16
S_DST ld hl,#C000 ;10
ld de,16 ;10
add hl,de ;11
ld (S_DST1+1),hl ;16
ld (SAVE_SP+1),sp ;20
ld b,216 ;7 = 100

S_SRC1 LD SP,0 ;10
POP HL ;10
POP DE ;10
POP AF ;10
POP IX ;14
POP IY ;14
EXX ;4
POP HL ;10
POP DE ;10
POP BC ;10
LD (S_SRC2+1),SP ;20 = 122

S_DST1 LD SP,0 ;10
PUSH BC ;11
PUSH DE ;11
PUSH HL ;11
EXX ;4
PUSH IY ;15
PUSH IX ;15
PUSH AF ;11
PUSH DE ;11
PUSH HL ;11

ld hl,32 ;10
add hl,sp ;11
LD (S_DST2+1),hl ;16 = 147

S_SRC2 LD SP,0 ;10
POP HL ;10
POP DE ;10
POP AF ;10
POP IX ;14
POP IY ;14
EXX ;4
POP HL ;10
POP DE ;10
POP BC ;10
LD (S_SRC1+1),SP ;20 = 122

S_DST2 LD SP,0 ;10
PUSH BC ;11
PUSH DE ;11
PUSH HL ;11
EXX ;4
PUSH IY ;15
PUSH IX ;15
PUSH AF ;11
PUSH DE ;11
PUSH HL ;11

ld hl,32 ;10
add hl,sp ;11
LD (S_DST1+1),hl ;16 = 147

djnz S_SRC1 ;13 551 / 32 = 17.2


SAVE_SP ld sp,0 ;10
;~119126 тактов (ldir ~ 145152 тактов - дольше на 21,8%)
ret

;---------------------------------
SCR_ADDR
;адрес 31ого знакоместа линии
ld a,b
and %00011000
or %01000000 ;+16384
ld h,a
ld a,b
rrca
rrca
rrca
ld d,a ;для расчёта атрибутов
or %00011111 ;+31
ld l,a

;адрес атрибутов этого знакоместа
ld e,l ;уже частично посчитано
ld a,d
and %00000011
or %01011000 ;+22528
ld d,a

ret

;---------------------------------
;Бинд страницы B
BIND_PAGE_B
DI
LD B,A
LD A,(#5B5C)
AND 248
OR B
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
;EI
RET

;--------------------------
;Переключение экранов
SWAP_SCREEN
;DI
LD A,(#5B5C)
xor 8
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
;EI

ld a,(S_SRC+2)
xor 128
ld (S_SRC+2),a
ld a,(S_DST+2)
xor 128
ld (S_DST+2),a

ld a,(S_PA+1)
xor 8 ;SET 6,D <-> SET 7,D
ld (S_PA+1),a
ld a,(S_AA+1)
xor 8 ;SET 6,H <-> SET 7,H
ld (S_AA+1),a

ld a,(A_P1+1)
xor 8 ;SET 6,H <-> SET 7,H
ld (A_P1+1),a



RET

;--------------------------
;Переключение экранов
SET_PAGE_MODE_A
;DI
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
;EI
RET
;--------------------------
DOWN INC H
LD A,H
AND #07
RET NZ
LD A,L
ADD A,#20
LD L,A
RET C
LD A,H
SUB #08
LD H,A
RET

;---------------------------
ADR_PIX
LD A,E ;E-Y
AND A
RRA
SCF
RRA
AND A
RRA
XOR E
AND #F8
XOR E
OR #40
LD H,A
A_P1 set 7,h
LD A,D
RLCA
RLCA
RLCA
XOR E
AND #C7
XOR E
RLCA
RLCA
LD L,A
RET
;----------------------------
DRAW
call update

ld a,(old_y)
ld e,a
ld d,32
call ADR_PIX
ld de,FON_SRC
call DRAW_SRC


ld a,(mar_y)
ld e,a
ld d,40
call ADR_PIX
call COPY_FON

ld de,MARIO
call DRAW_SRC


ret


;----------------------------
DRAW_SRC
ld b,32
DS1 ld a,(de)
ld (hl),a
inc hl
inc de
ld a,(de)
ld (hl),a
dec hl
inc de
call DOWN
djnz DS1
ret
;----------------------------
COPY_FON
push hl
ld de,FON_SRC
ld b,32
CF1 ld a,(hl)
ld (de),a
inc hl
inc de
ld a,(hl)
ld (de),a
dec hl
inc de
call DOWN
djnz CF1
pop hl
ret


LINE_TABLE DEFS 288,0

LINE_ptr equ 0 ;2 - указывает на текущую свёрнутую ленту в линии уровня
ribbon_ptr equ 2 ;2 - адрес текущего номера спрайта в ленте
ribbon_start equ 4 ;2 - начальный адрес текущей ленты
print_addr equ 6 ;2 - адрес знакоместа
attr_addr equ 8 ;2 - адрес атрибутов
ribbon_cnt equ 10 ;1 - счётчик количества повторяющихся лент

lt_size equ 11 ;количество байт в данных линии


LEVEL
DEFB 11,19,8,1,11,17,8,2,11,29,8,1,11,16,8,2,11,29,8,1, 11,16,8,2,11,29,8,1,11,7,8,3,11,6,8,2,11,25,255
DEFB 11,18,9,1,12,1,10,1,11,15,9,1,12,2,10,1,11,27,9,1, 12,1,10,1,11,14,9,1,12,2,10,1,11,27,9,1,12,1,10,1, 11,14,9,1,12,2,10,1,11,27,9,1,12,1,10,1,11,5,9,1,1 2,3,10,1,11,4,9,1,12,2,10,1,11,24,255
DEFB 11,9,8,1,11,8,13,1,15,1,14,1,11,7,8,3,11,5,13,1,15 ,2,14,1,11,17,8,1,11,9,13,1,15,1,14,1,11,6,8,3,11, 5,13,1,15,2,14,1,11,17,8,1,11,9,13,1,15,1,14,1,11, 6,8,3,11,5,13,1,15,2,14,1,11,17,8,1,11,9,13,1,15,1 ,14,1,11,5,13,1,15,3,14,1,11,4,13,1,15,2,14,1,11,1 3,29,1,31,1,11,9,255
DEFB 11,8,9,1,12,1,10,1,11,16,9,1,12,3,10,1,11,24,9,1,1 2,1,10,1,11,16,9,1,12,3,10,1,11,24,9,1,12,1,10,1,1 1,16,9,1,12,3,10,1,11,24,9,1,12,1,10,1,11,43,30,1, 11,9,255
DEFB 11,8,13,1,15,1,14,1,11,16,13,1,15,3,14,1,11,24,13, 1,15,1,14,1,11,16,13,1,15,3,14,1,11,24,13,1,15,1,1 4,1,11,16,13,1,15,3,14,1,11,24,13,1,15,1,14,1,11,4 3,32,1,11,9,255
DEFB 11,198,32,1,11,9,255
DEFB 11,22,3,1,11,57,2,8,11,3,2,3,3,1,11,14,3,1,11,11,2 ,3,11,4,2,1,3,2,2,1,11,56,27,2,11,8,32,1,11,9,255
DEFB 11,22,4,1,11,57,2,8,11,3,2,3,4,1,11,14,4,1,11,11,2 ,3,11,4,2,1,4,2,2,1,11,56,28,2,11,8,32,1,11,9,255
DEFB 11,187,27,3,11,8,32,1,11,9,255
DEFB 11,187,28,3,11,8,32,1,11,9,255
DEFB 11,186,27,4,11,8,32,1,11,9,255
DEFB 11,186,28,4,11,8,32,1,11,9,255
DEFB 11,185,27,5,11,8,32,1,11,4,36,3,11,2,255
DEFB 11,185,28,5,11,8,32,1,11,4,2,3,11,2,255
DEFB 11,16,3,1,11,3,2,1,3,1,2,1,3,1,2,1,11,21,5,1,11,9, 5,1,11,18,2,1,3,1,2,1,11,14,2,1,11,5,2,2,11,4,3,1, 11,2,3,1,11,2,3,1,11,5,2,1,11,10,2,2,11,6,27,1,11, 2,27,1,11,10,27,2,11,2,27,1,11,12,2,2,3,1,2,1,11,1 2,27,6,11,8,32,1,11,4,33,1,2,1,34,1,11,2,255
DEFB 11,16,4,1,11,3,2,1,4,1,2,1,4,1,2,1,11,21,6,1,11,9, 6,1,11,18,2,1,4,1,2,1,11,14,2,1,11,5,2,2,11,4,4,1, 11,2,4,1,11,2,4,1,11,5,2,1,11,10,2,2,11,6,28,1,11, 2,28,1,11,10,28,2,11,2,28,1,11,12,2,2,4,1,2,1,11,1 2,28,6,11,8,32,1,11,4,33,1,2,1,34,1,11,2,255
DEFB 11,38,5,1,11,6,7,1,11,9,7,1,11,77,27,2,11,2,27,2,1 1,8,27,3,11,2,27,2,11,26,27,7,11,8,32,1,11,3,36,1, 2,3,36,1,11,1,255
DEFB 11,2,20,1,11,35,6,1,11,6,7,1,11,2,20,1,11,6,7,1,11 ,39,20,1,11,37,28,2,11,2,28,2,11,4,20,1,11,3,28,3, 11,2,28,2,11,26,28,7,11,4,20,1,11,3,32,1,11,3,2,5, 11,1,255
DEFB 11,1,21,1,26,1,23,1,11,24,5,1,11,8,7,1,11,6,7,1,11 ,1,21,1,26,1,23,1,11,5,7,1,11,38,21,1,26,1,23,1,11 ,35,27,3,11,2,27,3,11,2,21,1,26,1,23,1,11,1,27,4,1 1,2,27,3,11,5,5,1,11,14,5,1,11,1,27,8,11,3,21,1,26 ,1,23,1,11,2,32,1,11,3,2,2,35,1,2,2,11,1,255
DEFB 11,1,22,1,18,1,24,1,11,13,20,1,11,10,6,1,11,8,7,1, 11,6,7,1,11,1,22,1,18,1,24,1,11,5,7,1,11,6,20,1,11 ,31,22,1,18,1,24,1,11,13,20,1,11,21,28,3,11,2,28,3 ,11,2,22,1,18,1,24,1,11,1,28,4,11,2,28,3,11,3,20,1 ,11,1,6,1,11,14,6,1,11,1,28,8,11,3,22,1,18,1,24,1, 11,2,32,1,11,3,2,2,35,1,2,2,11,1,255
DEFB 21,1,26,1,18,1,25,1,23,1,11,7,16,3,11,1,21,1,26,1, 23,1,11,5,16,1,11,3,7,1,11,8,7,1,11,2,16,1,11,3,7, 1,21,1,26,1,18,1,25,1,23,1,11,4,7,1,11,1,16,3,11,1 ,21,1,26,1,23,1,11,5,16,1,11,17,16,1,11,5,21,1,26, 1,18,1,25,1,23,1,11,7,16,3,11,1,21,1,26,1,23,1,11, 5,16,1,11,13,27,4,16,2,27,4,21,1,26,1,18,1,25,1,27 ,5,11,2,27,4,11,1,21,1,26,1,23,1,7,1,11,3,16,1,11, 10,7,1,27,9,11,2,21,1,26,1,18,1,25,1,23,1,11,1,27, 1,11,3,2,2,35,1,2,2,11,1,255
DEFB 22,1,18,3,24,1,11,6,17,1,18,3,19,1,22,1,18,1,24,1, 11,4,17,1,18,1,19,1,11,2,7,1,11,8,7,1,11,1,17,1,18 ,1,19,1,11,2,7,1,22,1,18,3,24,1,11,4,7,1,17,1,18,3 ,19,1,22,1,18,1,24,1,11,4,17,1,18,1,19,1,11,15,17, 1,18,1,19,1,11,4,22,1,18,3,24,1,11,6,17,1,18,3,19, 1,22,1,18,1,24,1,11,4,17,1,18,1,19,1,11,12,28,4,18 ,2,28,4,22,1,18,3,28,5,11,2,28,4,19,1,22,1,18,1,24 ,1,7,1,11,2,17,1,18,1,19,1,11,9,7,1,28,9,11,2,22,1 ,18,3,24,1,11,1,28,1,11,3,2,2,35,1,2,2,19,1,255
DEFB 0,69,11,2,0,15,11,3,0,64,11,2,0,53,255
DEFB 1,69,11,2,1,15,11,3,1,64,11,2,1,53,255


RIBBONS
DEFB 0,16,1,16,255
DEFB 16,16,17,16,255
DEFB 30,16,30,16,255
DEFB 9,48,10,48,255
DEFB 25,48,26,48,255
DEFB 6,38,7,38,0,38,8,38,255
DEFB 22,38,23,38,0,38,24,38,255
DEFB 27,46,28,38,0,38,29,46,255
DEFB 2,47,3,47,255
DEFB 0,40,4,47,255
DEFB 5,47,0,40,255
DEFB 0,40,0,40,255
DEFB 0,56,0,56,255
DEFB 0,40,18,47,255
DEFB 21,47,0,40,255
DEFB 19,47,20,47,255
DEFB 2,44,3,44,255
DEFB 0,47,4,44,255
DEFB 0,32,0,32,255
DEFB 5,44,0,47,255
DEFB 11,44,12,44,255
DEFB 0,47,13,44,255
DEFB 13,44,0,32,255
DEFB 14,44,0,47,255
DEFB 0,32,14,36,255
DEFB 15,32,0,32,255
DEFB 0,32,15,32,255
DEFB 31,40,32,40,255
DEFB 33,40,34,40,255
DEFB 0,40,14,61,255
DEFB 14,61,0,40,255
DEFB 37,60,0,40,255
DEFB 38,42,0,40,255
DEFB 30,16,0,0,255
DEFB 0,7,30,16,255
DEFB 0,7,0,7,255
DEFB 35,42,36,42,255




SPRITES
DEFB 0,0,0,0,0,0,0,0
DEFB 64,65,65,65,81,94,65,65
DEFB 0,3,7,31,31,31,57,119
DEFB 0,192,224,224,244,190,222,254
DEFB 0,7,15,31,31,127,127,63
DEFB 0,16,176,240,250,254,254,252
DEFB 0,127,3,115,115,115,115,115
DEFB 0,255,240,246,246,246,246,246
DEFB 0,254,0,86,46,86,46,86
DEFB 85,128,32,135,15,142,14,134
DEFB 86,1,5,193,225,113,113,241
DEFB 0,0,0,0,0,7,63,255
DEFB 0,0,0,0,0,224,252,255
DEFB 1,3,7,15,31,63,127,255
DEFB 128,192,224,240,248,252,254,255
DEFB 2,7,7,7,55,50,48,48
DEFB 0,0,192,48,15,1,1,126
DEFB 65,65,129,129,1,1,3,126
DEFB 27,13,6,7,0,0,0,0
DEFB 255,191,28,192,243,126,28,0
DEFB 191,127,61,131,199,255,60,0
DEFB 248,252,254,254,248,96,0,0
DEFB 115,115,115,115,115,115,0,0
DEFB 246,246,246,246,246,246,0,0
DEFB 46,86,46,86,46,86,0,0
DEFB 1,129,0,129,1,160,0,255
DEFB 113,65,193,1,65,197,1,255
DEFB 31,23,31,23,31,23,31,23
DEFB 251,251,251,251,251,251,251,251
DEFB 184,88,184,88,184,88,184,88
DEFB 255,2,2,2,255,32,32,32
DEFB 128,64,32,16,13,10,5,10
DEFB 1,3,7,15,95,175,95,175
DEFB 5,10,5,10,31,63,127,255
DEFB 95,175,95,175,247,251,253,254
DEFB 248,248,248,248,0,216,216,216
DEFB 29,29,29,29,0,31,31,31
DEFB 0,124,214,146,186,238,254,56
DEFB 3,3,3,3,3,3,3,3
MARIO
DEFB 3,240
DEFB 15,208
DEFB 31,208
DEFB 31,254
DEFB 28,144
DEFB 38,204
DEFB 38,2
DEFB 96,34
DEFB 96,252
DEFB 112,124
DEFB 24,0
DEFB 8,32
DEFB 11,208
DEFB 27,216
DEFB 59,220
DEFB 123,222
DEFB 115,206
DEFB 243,207
DEFB 240,15
DEFB 244,47
DEFB 144,9
DEFB 144,9
DEFB 80,10
DEFB 32,4
DEFB 32,4
DEFB 65,130
DEFB 66,66
DEFB 68,34
DEFB 68,34
DEFB 60,60
DEFB 252,63
DEFB 252,63
FON_SRC
defs 64,0


print_bc
CALL 11563
CALL 11747
jr $
;page 6
;defb 0


Внизу можно раскомментироватть
page 1
defb 0
и всё, картина меняется

- - - Добавлено - - -


можешь попробовать создать нужный тебе SNA файл - первые 27 + 49152 байта как из 48-го снапшота - затем добавляешь 2 байта PC, 1 байт Состояние порта #7FFD и 1 байт Выбор ПЗУ TR-DOS (0 - неактивно, 1 - активно)
итого должен получиться файл по размеру обычного SNA-48 плюс 4 байта.
Я могу создать сна, но если он 48 НО использует банки, то аут

- - - Добавлено - - -


затем добавляешь 2 байта PC, 1 байт Состояние порта #7FFD и 1 байт Выбор ПЗУ TR-DOS (0 - неактивно, 1 - активно)
итого должен получиться файл по размеру обычного SNA-48 плюс 4 байта.
после этого должен получиться как минимум 128(всё невклёчёные банка, а нет(

- - - Добавлено - - -


2 байта PC
они и в хаголовке неплоъхо себя чувствуют(что 128, что 48)

void ZX_SNA_Saver::FillHeader(ByteVector & mas, unsigned int start)
{
//Заполним заголовок sna(27 байт)
mas.push_back(63); //регистр I

mas.push_back(0); //HL'
mas.push_back(0);
mas.push_back(0); //DE'
mas.push_back(0);
mas.push_back(32); //BC'
mas.push_back(23);
mas.push_back(68); //AF'
mas.push_back(0);

mas.push_back(168); //HL
mas.push_back(16);
mas.push_back(185); //DE
mas.push_back(92);
mas.push_back(0); //BC
mas.push_back(0);
mas.push_back(58); //IY
mas.push_back(92);
mas.push_back(0); //IX
mas.push_back(0);

mas.push_back(6); //Флаги прерываний
mas.push_back(0); //Регистр регенерации динамической памяти R

mas.push_back(116); //AF
mas.push_back(0);
mas.push_back((start - 2) % 256); //SP
mas.push_back((start - 2) / 256);

mas.push_back(1); //Режим прерываний
mas.push_back(7); //Цвет бордюра

}

- - - Добавлено - - -

Пожоду я показывал уже..

- - - Добавлено - - -

Упс.. а тут нет пс, а где в 48 он?

- - - Добавлено - - -

А пк опять же только в 128 режиме

//Если 128k
if (is128)
{
sna.push_back(start % 256); //Регистровая пара PC
sna.push_back(start / 256);
sna.push_back(16); //Состояние порта #7FFD
sna.push_back(0); //ПЗУ TR-DOS (0 - неактивно, 1 - активно)

// Банки 1 3 4 6 7
this->Addpage(compiler, sna, 1);
this->Addpage(compiler, sna, 3);
this->Addpage(compiler, sna, 4);
this->Addpage(compiler, sna, 6);
this->Addpage(compiler, sna, 7);
}

- - - Добавлено - - -

Весь этот разговор изначальную проблему не решает, в сна 48 эмуляторы сразу отключают юз страниц

- - - Добавлено - - -

а не надо так) не надо такими быть :v2_dizzy_roll:

- - - Добавлено - - -

Поменяйте 1 битик

- - - Добавлено - - -

Где в SNA-48 хранится PC

- - - Добавлено - - -

Где в SNA-48 хранится PC

в сна 48 эмуляторы сразу отключают юз страниц
Знавчит стырили с оджного источника))

- - - Добавлено - - -

За-Ба-СтоВка(бунт) ну там Покожите, где я дибил, либо, но увы перекомпилите эмули, ыыыыы)))

goodboy
24.08.2020, 19:43
Где в SNA-48 хранится PC

- - - Добавлено - - -

Где в SNA-48 хранится PC

ты мудак ?
читай пост #11

Dwa83
24.08.2020, 19:49
А интересно, тут есть создатели Эмулей?

- - - Добавлено - - -


ты мудак ?
читай пост #11

И что там мне поможет? ты идиот?

- - - Добавлено - - -


точнее эмулируют именно 48ую модель.
Зачем?

- - - Добавлено - - -

Зачем БИТ включать?

goodboy
24.08.2020, 19:53
SnapShot это именно сохранёнка состояния под эмулем.
а то что ты пытаешься создать sna допустим под асмом это твои проблемы, а не авторов эмуля.
.................
ещё могу подсказать что режим im1 на 128ой машине работает совсем по другому
и если прерывания разрешены то подсунув 48ой SNA ты скорее всего вызовешь сброс/зависание

Dwa83
24.08.2020, 20:06
Ты читал тему с начала, идиотик?

- - - Добавлено - - -

Ну с поста третьего примерно

- - - Добавлено - - -

Что ты мне посоветуешь с моей проблемой?

- - - Добавлено - - -

В 48 к где хранится инфа о порте

- - - Добавлено - - -

Почему сразу заглушка?

goodboy
24.08.2020, 20:11
Что ты мне посоветуешь с моей проблемой?
убейся об стену или смени среду разработки
..............
правильно говорят что один дурак задаст столько вопросов что сто мудрецов не ответят

- - - Добавлено - - -


В 48 к где хранится инфа о порте
смотря какой порт интересует - Одесский или Кейптаунский

Dwa83
24.08.2020, 20:28
или смени среду разработки
Я иж меняю как перчатки))))

- - - Добавлено - - -

Я думал ты подскажешь в сложной ситуации, а ты просто никчёмный

- - - Добавлено - - -


или смени среду разработки
на какую?

- - - Добавлено - - -


о порте


о порте
Все понимают, ты один как сцыкливая сипа хотешь высказаться

- - - Добавлено - - -

Эй гудбой, где в 48 то что нужно?

- - - Добавлено - - -

Хоть бы байт по делу сказал, ну правда

- - - Добавлено - - -

яж код дал, что мешает проверить. Наверное идиотизм

goodboy
24.08.2020, 20:30
обосрался - обтекай, не умеешь - впитывай

Dwa83
24.08.2020, 20:44
итог холивара, даже если код переключает страницы, но сохранён в сна 48, забудь о страницах, обращайся напрямик к разрабам, тут тебя обосрут, а они возможно и нет

- - - Добавлено - - -


В режиме 48к
Давай проще
Мне компиль выдал sna48
я его запускаю, он запускакется, но
в коде этого сна есть переключение страниц, которые эмуль уже не делает, ну 48 же было

- - - Добавлено - - -

уже заглушка

goodboy
24.08.2020, 20:48
посмотри на свою проблему с логики автора эмуля.
зачем ему сохранять sna48 если комп находится в 128ом режиме ?
более того некоторые эмули ещё и сохраняют тип 128ой машины (фирма/пентагон)

Dwa83
24.08.2020, 20:57
Ну я понял. проще писать костыль
чтоб всегда было 128, я думал проблема решаема и я где-то накосячил, но в итоге гудбой не сцыунул и повёл себя как мужик)

Dwa83
24.08.2020, 21:18
а ко мне приехала пачка злосных спектрумистов и сказали мне как кодить)))

- - - Добавлено - - -


Не делает, потому что переключился на 48кДак да нафига

Xpeccy или ZXMAK2.
не даютхотя насчёт второго не уверен

- - - Добавлено - - -

Просто пусть при загрузку снапшотов 48, не включаетчся бит загнлушки

SoftLight
24.08.2020, 23:00
Дак да нафига

Странный вопрос. Ты когда в меню 128 спектрума выбираешь BASIC48 у тебя же физически комп не превращается в спектрум 48к? Эмулятор эмулит конкретную модель машины. Тебе же выше минимум два раза объясняли, что когда эмулятор видит на входе sna, снятый с машины 48к, он не порт конфигурации блочит и не байты в системные переменные выставляет. Он просто считает, что для работы поднимаем эмуляцию машины 48к, где памяти выше 48к и порта конфигурации просто нет!

Vladius
26.08.2020, 02:23
приветствую,

какая сейчас примерно технология работы с современными Z80 ассмеблерами и запуском бинарника на эмуляторе?
т.е например sjasmplus собирает мою helloworld программу но никакого бинарного файла не создает.
В примерах sjasmplus в файле frost10.z80 стоит макрокоманда
SAVESNA "frost10.sna",STARTF
я так понимаю что это команда для формирования полного образа памяти snapshot.
С загрузчиком? Помнится на BASIC загручик еще нужен был .

Вообщем я совершенно запутался тут , в элементарнейшем вопросе как раз для этой темы.
Я нашел несколько гайдов по настройке окружения в современных условиях, но там как то этот не расммотрен.

Буду благодарен за подсказку!
Эмуляторы вроде советуют для разработки CSpect и ZEsarUX
Я пишу на С++ и на asm писал бывало для x86 , но спектрум последний раз запускал 25 лет назад и никогда на асме не писал под него.

NEO SPECTRUMAN
26.08.2020, 02:55
Эмуляторы вроде советуют для разработки CSpect и ZEsarUX
эмуляторы
unreal
xpeccy (иногда нужен там где не удобно отлаживать в unreal)

за CSpect не знаю
ZEsarUX - редкостное гафно


самый последний и навороченный sjasm брать тут
https://github.com/z00m128/sjasmplus/releases/
не забывать RTFM
http://z00m128.github.io/sjasmplus/documentation.html



SAVESNA "frost10.sna",STARTF
я так понимаю что это команда для формирования полного образа памяти snapshot.
С загрузчиком? Помнится на BASIC загручик еще нужен был .
оно формирует снапшот для эмулятора
такой вариант подходит для отладки и тестирования

загружать sna на реале не всегда возможно...
да и не принято в таком формате что то выпускать

вот те например сохранялка в tap образа ленты
с загрузчиком лежащим в rem
и который грузит кодовый блок без заголовка и запускает

может с ходу не работать
тк у меня более сложная обвязка на lua вокруг
которая будет не читаема для новичков
и пришлось много чего выкинуть



emptytap "test.tap"

org $0


basic_start

defb $00,00 ;
defw end_basic_line_0 - basic_line_0
basic_line_0
defb $EA ;REM

;загрузчик в REM

di
ld ix,$C000 ;грузим по адресу $C000
ld de,$2000 ;$2000 байт
ld a,$FF
scf
call 1366 ;процедура загрузки в ПЗУ
di

jp start ;и запускаем


defb $0D

end_basic_line_0

defb $00,10
defw end_basic_line_10 - basic_line_10
basic_line_10
defb $FD,$B0 ;CLEAR VAL
defb $22,"24575",$22
defb $3A ; :

defb $F9,$C0 ;RANDOMIZE USR
defb $28 ;(
defb "5" ;5
defb $0E,$00,$00,$05,$00,$00
defb $2B ;+
defb "256" ;256
defb $0E,$00,$00,$00,$01,$00
defb $2A ;*
defb $BE,$B0 ;PEEK VAL
defb $22,"23636",$22 ;"23636"
defb $2B ;+
defb $BE,$B0 ;PEEK VAL
defb $22,"23635",$22 ;"23635"
defb $29 ;)
defb $0D

end_basic_line_10

defb $80 ;autorun
defb $AA,10,0 ;не уверен нужны ли эти строки

basic_end



;сохраняем бейсик
savetap "test.tap",BASIC,"prog_name",$0,basic_end-basic_start,0 ;0 autorun line


;сохраняем кодовый блок без заголовка
savetap "test.tap",HEADLESS,$C000,$2000




тоже самое для создания образа диска trd

тоже может с ходу не работать



tr_dos_var_current_track_sector = $5CF4

emptytrd "test,trd"

org $0

basic_start

defb $00,00 ;
defw end_basic_line_0 - basic_line_0
basic_line_0
defb $EA ;REM

;загрузчик в REM

di

ld bc,$2005 ;грузим $20 секторов = $2000 байт
;05 режим загрузки
ld de,(tr_dos_var_current_track_sector) ;d номер трека e номер сектора
;в данном случае берем последнее положение

ld hl,$C000 ;куда грузим

im 1
call $3D13 ;стандартная точка входа в ПЗУ tr-dos
di

jp start ;запускаем то что загрузили


defb $0D

end_basic_line_0

defb $00,10
defw end_basic_line_10 - basic_line_10
basic_line_10
defb $FD,$B0 ;CLEAR VAL
defb $22,"24575",$22
defb $3A ; :

defb $F9,$C0 ;RANDOMIZE USR
defb $28 ;(
defb "5" ;5
defb $0E,$00,$00,$05,$00,$00
defb $2B ;+
defb "256" ;256
defb $0E,$00,$00,$00,$01,$00
defb $2A ;*
defb $BE,$B0 ;PEEK VAL
defb $22,"23636",$22 ;"23636"
defb $2B ;+
defb $BE,$B0 ;PEEK VAL
defb $22,"23635",$22 ;"23635"
defb $29 ;)
defb $0D

end_basic_line_10

defb $80 ;autorun
defb $AA,10,0

basic_end



;сохраняем бейсик загрузчик
savetrd "test","boot.B",$0,basic_end-basic_start ;если хотим автозапуск по run

;savetrd "test","prog.B",$0,basic_end-basic_start ;если не хотим автозапуск
;и лучше писать мелкими буквами
;тк некоторым придется вводить run "prog" ручками

;сохраняем кодовый блок
savetrd "test.trd","data.C",$C000,$2000 ;сохраняем $2000 байт начиная с адреса $C000





в принципе для начала можно сохранять и в sna
это проще всего

в начале сорца нужно указать тип машины
(да и в общем его нужно указывать для доступа ко многим полезным функциям)

DEVICE ZXSPECTRUM128

в конце

SAVESNA "test.sna",start
где start собственно стартовый адрес программы...

ну и в sna по идеи можно сохранить только
ZXSPECTRUM48
ZXSPECTRUM128

если нужно больше
нужно уже извращаться
снапшотов для больше 128К так и не изобрели до сих пор...


Я пишу на С++
ну писать на C для спектрума не лучшее решение
есть у нас тут конечно писатели
но результат в конечно итоге всегда посредственный...

так что
только асм только хардкор

вот хорошая таблица по z80 асму
http://www.z80.info/zip/z80-documented.pdf
начиная с 26 страницы
все лаконично и понятно

Dwa83
26.08.2020, 09:40
Ты когда в меню 128 спектрума выбираешь BASIC48 у тебя же физически комп не превращается в спектрум 48к? Эмулятор эмулит конкретную модель машины. Тебе же выше минимум два раза объясняли, что когда эмулятор видит на входе sna, снятый с машины 48к, он не порт конфигурации блочит и не байты в системные переменные выставляет.
Это конечно понятно, но если уже есть поддержка 128(и более), зачем при загрузке 48 снимка памяти и систему сразу делать 48ой? Ведь я, например имея 128к, выгружу часть памяти, соответствующую 48, в которой имеется код работы со страницами, загружу в другой 128, всё ведь нормально будет работать. Просто мне кажется, что рассматривать 48sna лучше было бы как минимальную часть памяти(поддерживаемую и теми и другими моделями), а не признак конкретно модели. Ну это такое, у разрабов эмулей своё видение, и менять никто ничего всё равно не будет.

- - - Добавлено - - -


Ты когда в меню 128 спектрума выбираешь BASIC48
Но там я выбираю сам, а тут мне выбора не дают.

Причём только что ещё раз посмотрел, и в эмузвине есть настройка
Ignore soft lock 48k by setting bit 5 in port 7FFD (always 128k in 128k mode),
но в данном случае она не помогает, так как эмулятор, видя 48к памяти в снапшоте, и машину делает 48. Но таки при загрузке 128 в режиме 48, он сначала спрашивает, переключить ли модель?

Andrew771
27.08.2020, 23:35
какая сейчас примерно технология работы с современными Z80 ассмеблерами и запуском бинарника на эмуляторе?
т
Эмулятор EmuZWin v.2.7, со встроенным ассемблером и отладчиком. Я им пользуюсь.

NEO SPECTRUMAN
28.08.2020, 00:12
Эмулятор EmuZWin v.2.7, со встроенным ассемблером и отладчиком. Я им пользуюсь.
Vladius
НИ В КОЕМ СЛУЧАЕ!
это глючное гафно
оно то и дело зависает теряя результат работы
постоянно глючит
большой сорец компилит с 10+ попытки (остальные разы зависая)
особенно доставляет кнопка new которая моментально уничтожает все не спрашивая
когда ее случайно нажимаешь
итд


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

- - - Добавлено - - -


Я им пользуюсь.
да ты и на паскалях пишешь
и никто тебя так и не переубедил бросить заниматься этим грязным делом
да и там целая тема про "ищу кодыра"
про то как мышки плачут колятся но продолжают пытаться писать на сях и прочих паскалях
и тратят больше времени на пляски с бубном вокруг этого гофна
вместо того чтобы писать по людски на асме...

Andrew771
28.08.2020, 00:29
по-людски я уже писал, получалось очень долго, а сейчас это уже нереально по времени.

NEO SPECTRUMAN
28.08.2020, 00:36
по-людски я уже писал,
ну до это универсальная отмазка всех сишников...

а так еще асм в emuzwin сильно убогий
все адреса должны быть известны уже на первом проходе
чуть более сложный код где не все известно на первом проходе
и все
все переходы ведут в никуда :v2_dizzy_facepalm:

ни чуть не жалею что бросил это ***** в свое время

- - - Добавлено - - -


а сейчас это уже нереально по времени.
ну да настолько не реально
что хватило чтоб запилить свой паскаль чтобы на нем уже тратить время

Andrew771
29.08.2020, 18:30
это глючное гафно
оно то и дело зависает теряя результат работы
постоянно глючит
большой сорец компилит с 10+ попытки (остальные разы зависая)
особенно доставляет кнопка new которая моментально уничтожает все не спрашивая
когда ее случайно нажимаешь
итд
у тебя наверно глючная версия, мне такие попадались. Нужно именно 2.7. И лучше свой код писать во внешнем файле, а тут только компилировать и запускать.

NEO SPECTRUMAN
29.08.2020, 18:42
у тебя наверно
https://jpegshare.net/images/3a/a0/3aa08544e795a61bb482101c5d997c92.png
не советуй людям хрен знает что

это чудо не одному мне доставило кучу неприятностей...


...правда там с номерами версий сам аффтар определится не смог
да и в самой последней существующей версии не работает spec256

- - - Добавлено - - -


И лучше свой код писать во внешнем файле, а тут только компилировать и запускать.
лучшо
но еще раз говорю компилятор убогий
+ сама эмуляция z80 с ошибками...

- - - Добавлено - - -

а еще доставляет
как окно с каждым запуском растягивается в высоту все больше и больше :v2_lol:
https://jpegshare.net/images/b5/39/b539a9dbf521878c1ae71ae7db53fd10.png

Andrew771
29.08.2020, 18:56
слюшай, я с 2011 года его использую до сих пор, всё нормально пашет. У тебя глюкавый какой-то.

AndTorp
30.08.2020, 03:43
Привет.
Какие банки ОЗУ нельзя использовать в Scorpion ZS-256 Turbo+ , чтобы не нарушить работу теневика?

izzx
30.08.2020, 11:40
Привет.
Какие банки ОЗУ нельзя использовать в Scorpion ZS-256 Turbo+ , чтобы не нарушить работу теневика?

"Для своей работы сервис - монитор использует 8 и 9 страницы ОЗУ" это в руководстве написано от "Scorpion ZS 256 Turbo", наверно не отличается от +.

- - - Добавлено - - -

"Программа монитора полностью занимает банк 2 ПЗУ (Monitor), частично 3 (TR - DOS) и использует несколько ячеек из 0 и 1 банков. Для своей работы сервис - монитор использует 8 и 9 банки ОЗУ, а также 11 ячеек из стека пользователя (см. табл. 30)."

metamorpho
01.09.2020, 08:07
Привет всем!!

Пишу на ассемблере свою первую игру для ZX Spectrum 48.
Для начала мне нужен вот такой вывод спрайта - особенности:
- видеорежим стандартный
- вывод познакоместный
- без маски
- без буфера, сразу в экран
- без OR, просто прямой вывод в экран

Конечно нужна скорость, чтобы ничего не моргало и не дёргалось, а всё было плавно и красиво :)
Какой вариант кода посоветуете использовать для такого вывода спрайта ?

Andrew771
01.09.2020, 09:17
Какой вариант кода посоветуете использовать для такого вывода спрайта ?
Книга "Как написать игру на ассемблере", там есть

metamorpho
01.09.2020, 10:09
Книга "Как написать игру на ассемблере", там есть


Andrew771, спасибо за информацию!!

А что-то быстрее этого есть ?

Andrew771
01.09.2020, 10:32
А что-то быстрее этого есть ?
Зависит от того, что за спрайты - прямоугольные? большие/маленькие? проверка краев экрана нужна? и т.д.
Целая баталия по выводу спрайтов сейчас ведется тут (https://zx-pk.ru/threads/30330-ishchu-zhelayushchikh-vystupit-v-roli-programmista.html?p=1078794&viewfull=1#post1078794)

Если брать за основу процедуры из книги, то можно:
- раскрыть циклы (тело цикла написать 8 раз, а push/pop/djnz убрать);
- удалить проверки краев экрана, если спрайты априори не выходят за края.

Andrew771
01.09.2020, 22:21
Для прямоугольных спрайтов, которые не выходят за пределы экрана, выгоднее кодировать строками спрайта, а не отдельными знакоместами. Тогда каждую строку выводишь командами ldir, предварительно задав нужную длину строки в байтах в bc. Переход на следующую строку знакоместа - inc h (или inc d).

А самый быстрый способ - установить начало стека в нужное место экрана и перебрасывать командами по два байта сразу:
ld hl,...
push hl

metamorpho
02.09.2020, 07:38
А самый быстрый способ - установить начало стека в нужное место экрана и перебрасывать командами по два байта сразу:
ld hl,...push hl

Andrew771, спасибо за идеи !!
А как быть в случае со стеком если попадаешь на границу перехода одного из трёх блоков экранной памяти ?

Andrew771
02.09.2020, 17:31
А как быть в случае со стеком если попадаешь на границу перехода одного из трёх блоков экранной памяти ?
Заново считать SP для первого знакоместа новой строки.
Кстати, я еще встречал другой вариант, может с ним проще:
pop hl ; читаем из памяти 2 байта спрайта
ld (addr),hl ; помещаем по нужному адресу экрана

metamorpho
02.09.2020, 21:49
Заново считать SP для первого знакоместа новой строки.
Кстати, я еще встречал другой вариант, может с ним проще:
pop hl ; читаем из памяти 2 байта спрайта
ld (addr),hl ; помещаем по нужному адресу экрана

Andrew771, спасибо!!

jerri
03.09.2020, 15:55
Привет всем!!

Пишу на ассемблере свою первую игру для ZX Spectrum 48.
Для начала мне нужен вот такой вывод спрайта - особенности:
- видеорежим стандартный
- вывод познакоместный
- без маски
- без буфера, сразу в экран
- без OR, просто прямой вывод в экран

Конечно нужна скорость, чтобы ничего не моргало и не дёргалось, а всё было плавно и красиво :)
Какой вариант кода посоветуете использовать для такого вывода спрайта ?





;вывод спрайта 32*b

screenhigh equ #c0

drop_sprite32

ld (sprite_sp0),sp
;hl adr spr
;de coor
;Dy Ex 0-ff 0-1f
;b sprite high

ld a,d
cp screenhigh ;max Y
jr c,drop_sp1 ;middle check high

add a,b
jp nc,drop_end ;out of screen

ld c,a
sub b
neg
ld b,c

;вычисляем обьем обрезания спрайта
add a,a ;*2
add a,a ;*4

;изменяем размер спрайта
add a,l
ld l,a
adc a,h
sub l
ld h,a
;Y=0
ld d,0
jr drop_sp10

drop_sp1

;проверяем уход за экран

sub screenhigh
neg
cp b
jr nc,$+3
ld b,a

drop_sp10
ld a,d
and #38
add a,a
add a,a
add a,e
ld e,a

ld a,d
rra
rra
rra
and #18
xor d
and #f8
xor d
add a,#40
ld d,a
ld a,b

ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
ld h,d
ld d,a

drop_sp0
ld l,e

ld (hl),c
inc l
ld (hl),b
inc l
pop bc
ld (hl),c
inc l
ld (hl),b

dec d
jp z,drop_end

pop bc

inc h
ld a,h
and #07
jp nz,drop_sp0
ld a,e
add a,32
ld e,a
jr c,drop_sp0
ld a,h
sub 8
ld h,a
jp drop_sp0

drop_end
ld sp,0
sprite_sp0 equ $-2
ret


;вывод спрайта 24*b


drop_sprite24

ld (sprite_sp0),sp
;hl adr spr
;de coor
;Dy Ex 0-ff 0-1f
;b sprite high

ld a,d
cp screenhigh ;max Y
jr c,drop_sp2 ;middle check high

add a,b
jp nc,drop_end ;out of screen

ld c,a
sub b
neg
ld b,c

;вычисляем обьем обрезания спрайта
ld c,a
add a,a ;*2
add a,c ;*3

;изменяем размер спрайта
add a,l
ld l,a
adc a,h
sub l
ld h,a
;Y=0
ld d,0
jr drop_sp20

drop_sp2

;проверяем уход за экран

sub screenhigh
neg
cp b
jr nc,$+3
ld b,a

drop_sp20
ld a,d
and #38
add a,a
add a,a
add a,e
ld e,a

ld a,d
rra
rra
rra
and #18
xor d
and #f8
xor d
add a,#40
ld d,a
ld a,b

ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
ld h,d
ld d,a

drop_sp240
ld l,e

ld (hl),c
inc l
ld (hl),b
inc l
pop bc
ld (hl),c


dec d
jp z,drop_end

inc h
ld a,h
and #07
jp nz,drop_sp241
ld a,e
add a,32
ld e,a
jr c,drop_sp241
ld a,h
sub 8
ld h,a

drop_sp241
ld l,e

ld (hl),b
inc l
pop bc
ld (hl),c
inc l
ld (hl),b

dec d
jp z,drop_end

pop bc

inc h
ld a,h
and #07
jp nz,drop_sp240
ld a,e
add a,32
ld e,a
jr c,drop_sp240
ld a,h
sub 8
ld h,a
jp drop_sp240

metamorpho
03.09.2020, 19:23
jerri, спасибо!!

metamorpho
04.09.2020, 07:33
Правильно ли я понял что на Спектруме в стандартном графическом режиме
сделать горизонтальный или вертикальный скролин плавно по одной точке не получиться если
рядом стоящие знакоместа имеют разный атрибут цвета ?

jerri
04.09.2020, 09:04
Правильно ли я понял что на Спектруме в стандартном графическом режиме
сделать горизонтальный или вертикальный скролин плавно по одной точке не получиться если
рядом стоящие знакоместа имеют разный атрибут цвета ?

на спектруме окраска цветом происходит по блокам 8х8
попиксельный цветной скролл на спектруме вообще не возможен если не использовать различные хитрости.

izzx
04.09.2020, 09:07
metamorpho, да, будет не красиво. Делают или познакоместный скроллинг цветной, или попиксельно, но ч/б.

NEO SPECTRUMAN
04.09.2020, 09:17
попиксельный цветной скролл на спектруме вообще не возможен если не использовать различные хитрости.

да легко возможен
только это сильно палевно

https://www.youtube.com/watch?v=02FQeLSgrIA

Oleg N. Cher
04.09.2020, 09:19
Иногда делают псевдоцветной попиксельный скроллинг, обрамляя цветные объекты чёрной каймой, что достаточно для того, чтобы убрать клэшинг. Навскидку сейчас игр, которые используют эту технику, не помню, но может камрады подскажут. Есть такие скролл-шутеры.

Raydac
04.09.2020, 09:32
Навскидку сейчас игр, которые используют эту технику, не помню, но может камрады подскажут. Есть такие скролл-шутеры.
Zynaps например

NEO SPECTRUMAN
04.09.2020, 09:38
https://www.youtube.com/watch?v=zoDPU8fXKZY

https://www.youtube.com/watch?v=-6lvAXSGBpI

https://www.youtube.com/watch?v=nP4DoD4mLsQ

https://www.youtube.com/watch?v=d7j-O9FVeH8

https://www.youtube.com/watch?v=ZEQL9zDRR-4

metamorpho
04.09.2020, 09:56
Спасибо всем, теперь ясно. Буду создавать на примере этих вариантов.

Bedazzle
04.09.2020, 10:20
Иногда делают псевдоцветной попиксельный скроллинг, обрамляя цветные объекты чёрной каймой, что достаточно для того, чтобы убрать клэшинг. Навскидку сейчас игр, которые используют эту технику, не помню, но может камрады подскажут. Есть такие скролл-шутеры.

https://youtu.be/ZE_6tpkIvgo?t=454

jerri
04.09.2020, 13:02
да легко возможен
только это сильно палевно

https://www.youtube.com/watch?v=02FQeLSgrIA

я про хитрости и говорю.

metamorpho
09.09.2020, 19:40
Написал код, скроллинг получается тормозной.
Какие хитрости нужно применить чтоы сделать такую же плавность и скорость как например в "Cobra Force" или "Soldier of fortune" ?

goodboy
09.09.2020, 19:58
Какие хитрости нужно применить
а что мешает изучить движок игры ?

metamorpho
09.09.2020, 20:01
а что есть исходник на asm ?

Перечитал уже много информации по программированию на Спектрум.
Достаточно много всяких моментов нужно учесть чтобы грамотно написать игру для Спектрума.
И пока не встретил ни одного описания где вся эта конкретика (в отношении написания игры) с примерами кода была бы собрана в одном месте.
Есть игры, которые демонстрируют плавность скроллинга вертикального и горизонтального, но как это сделано - тайна.
Или не тайна ? Может где-то есть такое описание и код ?
Неужели до сих пор на Спектруме нет ниодного примера кода базовой "основы-заготовки" платформера типа "Soldier of Fortune" ?

goodboy
09.09.2020, 20:26
ну отладчики в эмулях (с возможностью дизасма) никто не отменял.
ещё как вариант - формат спрайтов может быть совсем не очевидным,
например (для скорости вывода) змейкой или чередующимся с маской

Black Cat / Era CG
09.09.2020, 20:57
Soldier of fortuneЭто слишком круто. Так сразу не догнать.

jerri
09.09.2020, 21:32
а что есть исходник на asm ?

Перечитал уже много информации по программированию на Спектрум.
Достаточно много всяких моментов нужно учесть чтобы грамотно написать игру для Спектрума.
И пока не встретил ни одного описания где вся эта конкретика (в отношении написания игры) с примерами кода была бы собрана в одном месте.
Есть игры, которые демонстрируют плавность скроллинга вертикального и горизонтального, но как это сделано - тайна.
Или не тайна ? Может где-то есть такое описание и код ?
Неужели до сих пор на Спектруме нет ниодного примера кода базовой "основы-заготовки" платформера типа "Soldier of Fortune" ?

SoF как и Zynaps это очень технологичный движок.
там просчитано всё.
Количество блоков местности на экране, максимальное количество обьектов и прочее.

ты же хочешь чтото высокоподвижное
а экран у спектрума великоват для быстрого обновления.
И тут в ход идут хитрости

Firefly, GhoulsNGhosts - обеднение фона, сокращение объектов.

RoboCop, Batman - низкий ФПС, чернобелая графика.

Rtype, Zynaps - отсутствие заднего плана, все обьекты ЗА обьектами окружения.

Black Cat / Era CG
09.09.2020, 22:01
Redshift (2019) еще крутой шмап с хитростями. Но там уже 128 и 2 экрана.

dimidus
05.10.2020, 08:59
У меня есть вопрос, касаемо организации памяти для игры. Вывожу в два экрана поочерёдно, поскольку fps предполагается плавающим (в зависимости от нагруженности отображаемой части карты). Первый экран, это банка памяти №5, жестко закреплённая с адреса #4000. Второй экран, это банка №7, она подключается с адреса #c000. Значит мне попеременно нужно выводить или в #4000, или в #c000. Получается что вся выводимая за кадр графика должна умещаться где-то между #6000 и #c000, ну и остаётся ещё место после #db00, но там у меня программа вывода этой самой графики. В итоге, преимущество в памяти 128-го спектрума нивелируется, поскольку я не могу её использовать в полной мере при выводе на два экрана, конфигурация "цементируется" банками #5, 2 и 7. Я всё правильно описал, или есть способы вывода графики из других банок памяти на два экрана?

NEO SPECTRUMAN
05.10.2020, 10:17
Первый экран, это банка памяти №5, жестко закреплённая с адреса #4000. Второй экран, это банка №7, она подключается с адреса #c000. Значит мне попеременно нужно выводить или в #4000, или в #c000
проще подключать и 5 и 7 банку в $С000


В итоге, преимущество в памяти 128-го спектрума нивелируется
можно копировать графику в $8000
на время использования из других страниц
тк она вся не нужно одновременно и сразу
а потом подключать 5\7 страницу в $C000

можно строить все как и раньше в линейном буфере в районе $8000
имея несколько страниц с графикой
а потом подключать видео память по $C000
и туда перекидывать содержимое буфера

можно отключить видео память из адресного пространства процессора вообще
и использовать все 48К под какой то код
если не использовать 5-ю банку а отображать 7-ю

или же хранить процедуры работы с графикой и сами спрайта в 5 и 7-й странице
а под игровую логику отводить 40К адресного пространства

так что 128 это крута %)

dimidus
05.10.2020, 11:46
проще подключать и 5 и 7 банку в $С000
Из плюсов, не нужно обновлять адреса вывода. Какие ещё есть плюсы?
Минус - теряется область памяти с $db00, где у меня программа вывода графики.


можно копировать графику в $8000
на время использования из других страниц
тк она вся не нужно одновременно и сразу
а потом подключать 5\7 страницу в $C000
У меня платформер со скроллом экрана. Это значит что нужна вся графика которая есть на уровне.
Эта графика как раз занимает у меня 16КБ начиная с $8000. Особенности решения позволяют хранить там 64 тайла. Этого маловато. Хочется буйства текстур, разнообразия и красоты :)
Копирование графики из других страниц во время движения по уровню будет просаживать fps, кроме того, это надо делать незаметно, подменяя тайлы которых уже нет на экране. В общем, хотелось бы этого избежать.


можно строить все как и раньше в линейном буфере в районе $8000
имея несколько страниц с графикой
а потом подключать видео память по $C000
и туда перекидывать содержимое буфера
Для скролл-платформера насколько приемлемо использование буфера?


можно отключить видео память из адресного пространства процессора вообще
и использовать все 48К под какой то код
если не использовать 5-ю банку а отображать 7-ю
Это полезная фича, но вопрос про вывод на экран.


или же хранить процедуры работы с графикой и сами спрайта в 5 и 7-й странице
а под игровую логику отводить 40К адресного пространства
Боюсь, не уместится всё туда, кроме того, я не вижу в этом варианте преимущества в использовании доп.памяти.


так что 128 это крута %)
Безусловно, это лучше чем 48К, однако, если бы была дополнительная возможность подключать, к примеру, второй экран в область $4000, то применение техники двух экранов раскрылась бы на полную, поскольку можно было бы использовать доп.банки памяти для вывода во второй экран. Вообще, игры на спектрум стали бы на голову лучше. Как пример, хранение развёрнутых (уже отскроленных) тайлов в нескольких банках и их подключение, при этом, вывод на 1/2-й экран. А так приходится выбирать между отсутствием съехавшего кадра (вывод поочерёдно в два экрана) или богатством графики (вся графика текущего уровня должна помещаться в текущее адресное пространство), или приемлемым fps-ом (переброска из других страниц через буфер снижает скорость игры). Ещё приходится жертвовать размером игрового поля. Это происходит практически в большинстве игр.

В любом случае, спасибо за ответ и за "палитру возможностей" :)

LW
05.10.2020, 12:13
Минус - теряется область памяти с $db00, где у меня программа вывода графики.
Если не планируется использовать системные переменные, продублировать в 5-й странице процедуры вывода графики.

dimidus
05.10.2020, 12:23
Если не планируется использовать системные переменные, продублировать в 5-й странице процедуры вывода графики.

Это можно. Но зачем? В чём преимущество данного приёма по сравнению с переменным выводом в $4000/c000?

NEO SPECTRUMAN
05.10.2020, 12:30
У меня платформер со скроллом экрана. Это значит что нужна вся графика которая есть на уровне.
Эта графика как раз занимает у меня 16КБ начиная с $8000. Особенности решения позволяют хранить там 64 тайла. Этого маловато. Хочется буйства текстур, разнообразия и красоты
ты можешь в процессе перемещения по карте менять сменные наборы таилов
одновременно всего на экране не будет
но на небольшом расстоянии можно делать буйство

но фоне постоянного зеркалиния туда сюда спрайтов в играх на 48
это будет тьфу

посмотри как это все время делается на приставках
с весьма ограниченным набором тайлов
на всяких несах часто есть в дебагере...


- - - Добавлено - - -


Для скролл-платформера насколько приемлемо использование буфера?
а это зависит от того гонишься ли ты за фреймовостью
(где нужно рисовать напрямую на экран)

или не гонишься
и у тебя будет 15 слоев фона и куча спрайтов
и для которых может быть оптимальней линейный буфер

ну и которые будут строится несколько фреймов
на фоне которых пол фрейма перекидывания буфера уже не играет роли...

- - - Добавлено - - -


с переменным выводом в $4000/c000?
переменный вывод более медленный
нужны или корекции процедур на каждую смену а это такты
или два набора процедур а это дополнительное место
или два набора таблиц а это много места

не очень идея...

tae1980
05.10.2020, 13:16
или не гонишься
и у тебя будет 15 слоев фона и куча спрайтов
и для которых может быть оптимальней линейный буфер
Для общего развития.
Переброска всего экрана (если буфер в экран) занимает ~1.5-1.7 прерывания, полюс подготовка кадра. Получается, что на вывод одного кадра придётся затратить ~3 прерывания? 15-16 кадров в секунду. Ускориться можно, только за счёт уменьшения окна вывода. Я не ошибаюсь?

dimidus
05.10.2020, 14:37
ты можешь в процессе перемещения по карте менять сменные наборы таилов
одновременно всего на экране не будет
но на небольшом расстоянии можно делать буйство
Да, есть такая идея, динамически подменять тайлы, только надо подумать как это делать незаметно для игрока. Ну и сам механизм смены тайлов тоже надо продумывать. Кроме того, это накладывает определённые ограничения на левел-дизайн. Вот к примеру, в игре Sonic'n'Knuckles одно только кольцо из лианы съест практически весь мой набор тайлов. Но оно появляется на экране не отдельно, к нему ГГ прикатывается плавно, а катится он по фону с разнообразной травой, подъёмами и спусками. Значит вокруг такого сложного объекта фон нужно как то обеднять, делать примитивнее, в общем, да, задачка...


но фоне постоянного зеркалиния туда сюда спрайтов в играх на 48
это будет тьфу


посмотри как это все время делается на приставках
с весьма ограниченным набором тайлов
на всяких несах часто есть в дебагере...
Верю на слово :)


а это зависит от того гонишься ли ты за фреймовостью
(где нужно рисовать напрямую на экран)
Гонюсь, не то слово :) А как ты себе представляешь игру с динамичным геймплеем? Лучшую игру на ZX! :)


переменный вывод более медленный
нужны или корекции процедур на каждую смену а это такты
или два набора процедур а это дополнительное место
или два набора таблиц а это много места

не очень идея...
Таблиц с адресами строк экрана? Вероятно, речь идёт о выводе спрайтов?
Потому что для вывода тайлов я не вижу смысла прописывать адреса внутри процедур или строить таблицу. Достаточно inc h для следующей строки пикселей и ld bc,offset, add hl,bc, для следующего знакоместа/трети экрана.
Честно говоря, до вывода спрайтов я ещё не дошёл. Возможно, я выберу вариант с одним адресом экрана. А может как-то выкручусь с двумя. Надо будет посчитать сколько памяти больше расходуется.

NEO SPECTRUMAN
05.10.2020, 15:04
Переброска всего экрана (если буфер в экран) занимает ~1.5-1.7 прерывания,
но это зависит от того какие бкшники перекидывают экран и как...
чуть больше чем за фрейм можно перекинуть полностью весь экран
(конечно с точки зрения пентагона
на тормозилках это будет несколько дольше)


15-16 кадров в секунду.
а так я не считаю это не плеябельной скоростью

- - - Добавлено - - -


Достаточно inc h для следующей строки пикселей
это то да
а вот как ты собираешься находить адрес первого байта?
сложениями и сдвигами что ли?

- - - Добавлено - - -


Гонюсь, не то слово А как ты себе представляешь игру с динамичным геймплеем? Л
кстате если "динамический" геймплей идет на фоне статического фона и небольшого числа спрайтов :)
еще бывает строят в буфере
но перекидывают на экран только квадратики со спрайтом а не весь экран

dimidus
05.10.2020, 15:24
это то да
а вот как ты собираешься находить адрес первого байта?
сложениями и сдвигами что ли?
Не совсем понял о каком первом байте речь.


кстате если "динамический" геймплей идет на фоне статического фона и небольшого числа спрайтов :)
еще бывает строят в буфере
но перекидывают на экран только квадратики со спрайтом а не весь экран
Да, но это не мой случай. У меня перерисовывается весь экран, только в некоторых местах пустые тайлы могут пропускаться, там где много свободного места.

NEO SPECTRUMAN
05.10.2020, 15:30
Не совсем понял о каком первом байте речь.
от которого ты будешь шагать вниз по экрану при помощи inc h...
для него и нужна таблица байт на 512...

dimidus
05.10.2020, 16:49
от которого ты будешь шагать вниз по экрану при помощи inc h...
для него и нужна таблица байт на 512...

Ну сначала в hl записываем #4000 (или #c000). В этом месте старший байт адреса меняется при переключении экрана.
Выводим первый тайл. После этого hl указывает на нижний левый угол тайла (потому что вывожу змейкой). Прибавляем к hl смещение (#f8e2), получаемся адрес для вывода следующего тайла.
Когда ряд из тайлов вывели, прибавляем смещение (#f901) для нового ряда тайлов. Выводим 4 ряда тайлов. При переходе на следующую треть экрана, добавляем ещё смещение (#0700).

izzx
22.10.2020, 15:13
Старый вопрос, но нужно обновить.
Какую звуковую карту купить (начать мечтать) для скорпа? Есть свободный слот шины ZS.
Железок придумано много, трудно охватить всё взглядом.
Чтобы почти не надо было паять, прошивать, чтобы софт поддерживал, коллекция музла была. Хорошо, если много-в-одном типа AYX32. Хорошо, если не дорого - богато.
В общем, самое лучшее цена/качество.
Или сразу мечтать целиком купить комп современный, типа ZXDOS?

polikarpov76
22.10.2020, 16:16
Или сразу мечтать целиком купить комп современный, типа ZXDOS?
Лучше всего взять или собранную плату ZX Evolution и собрать самому в корпус mITX. Звуковую карту для Evo взять NeoGS или ZXM-SoundCard.
или если есть деньги, то ZX Spectrum Next, пока не дорого надо брать.
https://i.ibb.co/2cX5nnS/ozi-Kyvxeb-Qg.jpg
ZXDOS точно не подойдет под критерий 'не прошивать'.

NEO SPECTRUMAN
22.10.2020, 16:34
то ZX Spectrum Next, пока не дорого надо брать.
только это НЕ спектрум а фпга дев борда в "красивой" коробке
штуку баксов можно просадить и на более полезные вещи
не спонсируя при этом колумбийский бразильцев еврейского происхождения

polikarpov76
22.10.2020, 16:37
только это НЕ спектрум а фпга дев борда в "красивой" коробке
штуку баксов можно просадить и на более полезные вещи
не спонсируя при этом колумбийский бразильцев еврейского происхождения
Дед Синклер фигни не посоветует, а на коробке гордо стоит его имя. Так что только Next единственный современный аутентичный вариант спека и за ним будущее. Че там в потрохах среднестатистическому покупателю пофиг.

NEO SPECTRUMAN
22.10.2020, 16:44
Дед Синклер фигни не посоветует, а на коробке гордо стоит его имя.
дед синклер гордо продал своё имя амстраду...

- - - Добавлено - - -

и имя синклера стоит даже на ибмпц совместимом компе
https://www.old-computers.com/museum/photos/Sinclair_PC200_System_s1.jpg
не скажу что это плохо
просто факт


да и бразильские колумбийцы купили имя синклера скорей всего не у синклера...

в придачу имя NEXT для спектрума забили русские еще 30 лет назад...

izzx
22.10.2020, 16:44
Лучше всего взять или собранную плату ZX Evolution и собрать самому в корпус mITX. Звуковую карту для Evo взять NeoGS или ZXM-SoundCard.
......
ZXDOS точно не подойдет под критерий 'не прошивать'.

Эва+NeoGS наверно на 13к-14к потянет? Не мало. А ZXDOS же наверно просто прошивается, в смысле программатор не надо покупать? Не интересовался пока.

polikarpov76
22.10.2020, 16:53
Эва+NeoGS наверно на 13к-14к потянет? Не мало. А ZXDOS же наверно просто прошивается, в смысле программатор не надо покупать? Не интересовался пока.
ZXDOS+ в корпусе 125 евро + 25 евро доставка и будет тебе теже 13 600р. Программатор не надо если не слетит прошивка.
ZXEVO полный комплект еще и с монитором без стоимости доставки на Авито есть за 15 000р. У производителя собранная плата ZXEVO и NeoGS 7800+6800=14 600р + корпус ~2000р выходит около 17тр. Не ну а как вы хотели с таким курсом деревянного? Хобби вообще не дешевая затея.

NEO SPECTRUMAN
22.10.2020, 16:53
а на коробке гордо стоит его имя
не могу не запостить :)
http://www.leningrad.su/museum/38/zx-1-1.jpg
http://www.leningrad.su/museum/38/szx-1.jpg

Bedazzle
22.10.2020, 17:43
только это НЕ спектрум а фпга дев борда в "красивой" коробке
штуку баксов можно просадить и на более полезные вещи
не спонсируя при этом колумбийский бразильцев еврейского происхождения

То, что кто-то продаёт за штуку баксов - не значит, что это реальная цена.
У нас на локальной барахолке периодически неработающие 48К самопалы по сотне евров продают. Но это не значит, что скорей надо бежать покупать.

NEO SPECTRUMAN
22.10.2020, 17:50
То, что кто-то продаёт за штуку баксов - не значит, что это реальная цена.
а если вспомнить сколько эти барыги хотели за первый экземпляр с подписями лично колумбийских бразильцев
то это вообще :v2_dizzy_facepalm:

который по моему так и не был продан
тк цена видимо высоковато даже для буржуинов

Barmaley_m
23.10.2020, 23:16
переменный вывод более медленный
нужны или корекции процедур на каждую смену а это такты
или два набора процедур а это дополнительное место
или два набора таблиц а это много места

не очень идея...
Вывод делаем всегда в #C000, подключая попеременно 5 или 7 страницы. В чём проблема-то?

NEO SPECTRUMAN
25.10.2020, 14:09
Вывод делаем всегда в #C000, подключая попеременно 5 или 7 страницы. В чём проблема-то?
ты это не мне адресуй
а тем кто попеременно хочет выводить то в 4000 то в С000

dimidus
25.10.2020, 16:14
Вывод делаем всегда в #C000, подключая попеременно 5 или 7 страницы. В чём проблема-то?

Проблема как всегда, в нехватке памяти (или/и быстродействия). У меня в 7-й странице лежит код, который выводит графику. Можно переместить в пятую, но тогда надо точно знать что не будет использоваться TR-DOS. Хотя... можно сохранять критичную для TR-DOSa информацию на время геймплея, а потом её восстанавливать?

Как я понял, выводить всегда в #c000 это уже сложившаяся практика.

NEO SPECTRUMAN
25.10.2020, 16:19
Хотя... можно сохранять критичную для TR-DOSa информацию на время геймплея, а потом её восстанавливать?

можно инициализировать переменные тырдырдоса, когда нужно обращение к тырыдосу, так
и вроде все после этого работает



trdos_init
ld hl,$5c00
ld de,$5c01
ld bc,$0240
ld (hl),l
ldir
ld iy,$5C3A

ld a,$FF
ld (iy+$00),a
ld ($5D0C),a ;#ff=i/o Буфер неиспользуется

ld a,$C9
ld ($5CC2),a ;для TR-DOS

ld a,$83
ld ($5CC8),a ;режим работы дисковода А
;для B,C,D будут $C9,$CA,$CB
;$5D16 содержит номер дисковода (0-3=А-D)+$3C
ну по крайней мере я такое теперь юзаю
тк хранить все переменные отдельно а потом восстанавливать сильно жирно

NEO SPECTRUMAN
05.11.2020, 13:10
кстате где то писалось что tr-dos повреждает какие то участки памяти в процессе
чо он там повреждает?
и с какого адреса можно безопасно грузить ни о чем не думая?

Bedazzle
07.11.2020, 00:03
кстате где то писалось что tr-dos повреждает какие то участки памяти в процессе

Это не про 3dos часом речь шла и седьмую банку?

NEO SPECTRUMAN
07.11.2020, 00:15
Это не про 3dos часом речь шла и седьмую банку?
да нет
к сожалению не помню где я это видел
но речь шла по трдос

+дето писалось что для чтения трдос создает дето буфер
и что при этом трдос сам выбирает где этому буферу быть


так же вот что то подозрительное нашел у алона
неизвестно для чего (в суть не вникал)
что тоже меня настараживает


;после дисковых операций
EI ;vTRDOS bug!!!
LD HL,$5C00
LD DE,SYSBUF
LD BC,$5D3B-$5C00
LDIR ;иначе экран АТМ запарывает
HALT
CALL ZEROATR
HALT
DI

IFN atm
CALL $3D46 ;вызов "проверочной" точки в (v)TR-DOS
;портит $5CEF (экран)
LD (wasvtr),A
OR A ;CP #00 ;если не 0,vTR-DOS нет и ПЗУ не подменяем
CALL Z,$3C9E ;вызов триггера подмены ПЗУ TRD/vTRD
;vTRDOS выключен


хотя 5C00 это уже не спектрумовский экран
и похоже на адрес переменных

TomCaT
07.11.2020, 02:03
Процедуры "считать сектора" и "записать сектора", насколько помню, ничего, кроме некоторых из своих 112 байт, не трогают. А многие другие типа поиска дескриптора или чтения файла по имени, вынуждены сектора потихоньку читать, поэтому создают временно буфер для одного сектора. Кажется, в стандартной штатной бейсиковской "куче", указанной переменной WORKSP (23649) и ограниченной STKBOT(23651). А вот какие еще нужно заполнять указатели, если нужно...

tiboh
07.11.2020, 02:18
"Во время чтения или записи сектора, между областью переменных DOS и CHANS создается буфер сектора - 257 байт (256 байт данных + контрольный байт)"
http://zxpress.ru/book_articles.php?id=1352

NEO SPECTRUMAN
07.11.2020, 02:49
Указанный способ выделения буфера перед областью CHANS объясняет странное поведение TR-DOS при обращении к MS-DOS дискете: любое обращение к диску начинается с чтения 8-го сектора во временный буфер, а так как сектор MS-DOS вдвое длиннее, таблица CHANS оказывается затертой - с соответствующими последствиями...

а трдос при простом чтении секторов через 05 3D13 использует CHANS?

может можно читать посекторно мсдосный диск через 3D13
при этом забирая прочитанный буфер ручками?

Dim7
23.11.2020, 13:32
del

goodboy
23.11.2020, 13:44
назначь кнопки "MSYULE" (появится надпись CheatActive) после этого жми GTI в игре для завершения уровня

dimidus
15.12.2020, 16:34
Вопрос по скроллингу фона.
Вы как обычно любите делать, сначала вывести на экран, а потом скроллить, или выводить и скроллить "на лету"?
Теоретически, на лету должно быть быстрее, потому что не нужно два раза ходить по одному и тому же месту (сначала вывод, потом скролл).

jerri
15.12.2020, 19:37
Вопрос по скроллингу фона.
Вы как обычно любите делать, сначала вывести на экран, а потом скроллить, или выводить и скроллить "на лету"?
Теоретически, на лету должно быть быстрее, потому что не нужно два раза ходить по одному и тому же месту (сначала вывод, потом скролл).

у тебя фон из тайлов? или фон просто фон?

если выбирать из вариантов скроллить на лету или перерисовывать тайлы
то вариант - проскроллить и дорисовать - быстрее

dimidus
16.12.2020, 13:27
у тебя фон из тайлов? или фон просто фон?

если выбирать из вариантов скроллить на лету или перерисовывать тайлы
то вариант - проскроллить и дорисовать - быстрее

Фон просто фон. Проскроллить и дорисовать, это значит прочитать графику там где она хранится, проскроллить в регистрах и положить на экран?

Ещё вопрос к тебе. В одной из тем ты пишешь про табличный скроллинг. Но я, честно говоря, так и не смог понять как он устроен.
https://zx-pk.ru/threads/22125-kak-bystro-skrollit-pamyat-na-2-piksela.html?p=642038&viewfull=1#post642038

Можешь поподробнее объяснить?

jerri
16.12.2020, 16:20
Фон просто фон. Проскроллить и дорисовать, это значит прочитать графику там где она хранится, проскроллить в регистрах и положить на экран?

Ещё вопрос к тебе. В одной из тем ты пишешь про табличный скроллинг. Но я, честно говоря, так и не смог понять как он устроен.
https://zx-pk.ru/threads/22125-kak-bystro-skrollit-pamyat-na-2-piksela.html?p=642038&viewfull=1#post642038

Можешь поподробнее объяснить?Нет.
Без внятного ТЗ я тебе не помогу.
Что именно ты скроллиш и с какой целью.

dimidus
17.12.2020, 16:46
Нет.
Без внятного ТЗ я тебе не помогу.
Что именно ты скроллиш и с какой целью.

Есть картинка шириной 400 пикселей и высотой 112 строк, это фон. Фон должен выводиться на всю ширину экрана начиная с 32-й (если считать с нуля) строки экрана и скроллиться влево-вправо на любое количество пикселей.
Фон занимает 5600 байт.
У меня 8 процедур вывода. Каждая выводит с определённым смещением (от 0 до 7). Получается не очень шустро: 67, 113, 188, 192, 192, 194, 187, 112 килотактов (Кт) соответственно. Скроллю "на лету" т.е., беру байт из места хранения фона, сдвигаю в регистре, кладу на экран. И так всю строку. Там где нужно использовать сдвиг тетрады, делаю второй проход уже по экрану.

Так вот хотел узнать про табличный скроллинг, может с ним быстрее будет?

jerri
17.12.2020, 19:05
Есть картинка шириной 400 пикселей и высотой 112 строк, это фон. Фон должен выводиться на всю ширину экрана начиная с 32-й (если считать с нуля) строки экрана и скроллиться влево-вправо на любое количество пикселей.
Фон занимает 5600 байт.
У меня 8 процедур вывода. Каждая выводит с определённым смещением (от 0 до 7). Получается не очень шустро: 67, 113, 188, 192, 192, 194, 187, 112 килотактов (Кт) соответственно. Скроллю "на лету" т.е., беру байт из места хранения фона, сдвигаю в регистре, кладу на экран. И так всю строку. Там где нужно использовать сдвиг тетрады, делаю второй проход уже по экрану.

Так вот хотел узнать про табличный скроллинг, может с ним быстрее будет?

там в ветке ниже было посчитано что гдето 42 байта на байт.
200к быстрее не сделаешь
хочешь быстро - делаешь 8 копий фона со скроллом

74235 примерно так.

и потом быстро быстро кидаешь их на экран

если в анриле посмотришь код
то увидишь как делать это быстро

PATHNK
17.12.2020, 20:03
А кто-нибудь работал с SpectNet IDE (https://dotneteer.github.io/spectnetide/) или знает о ней? Стоит ли заводить новую тему, есть ли подобные аналоги?

dimidus
17.12.2020, 21:00
там в ветке ниже было посчитано что гдето 42 байта на байт.
200к быстрее не сделаешь
хочешь быстро - делаешь 8 копий фона со скроллом

74235 примерно так.

и потом быстро быстро кидаешь их на экран

если в анриле посмотришь код
то увидишь как делать это быстро

Спасибо, посмотрел, да шустро получается. У меня, к сожалению, места под скролл-копии нет. Есть огрызок 7-й страницы для хранения фона. Ладно, буду посмотреть как это в итоге будет выглядеть в игре. В крайнем случае, сделаю фон интерлейсом через строку.

Bedazzle
17.12.2020, 21:31
У меня 8 процедур вывода. Каждая выводит с определённым смещением (от 0 до 7).

А скроллишь байт как?
И что именно за фон - динамически меняющийся, или собран из маленьких спрайтов?

dimidus
18.12.2020, 09:53
А скроллишь байт как?
И что именно за фон - динамически меняющийся, или собран из маленьких спрайтов?

Фон просто последовательность байтов, 112 строк, длиной по 50 байт.



;--------------------------------------------------------------------
;
; Подпрограмма вывода фона
; Префикс для меток: bg
; В этой версии будем выводить и скроллить одновременно
;
;--------------------------------------------------------------------
;

;include vars.asm ; Общие переменные (для локальной компиляции)


bg
ld a,(vars_bgofs_r) ; Берём смещение фона (в пикселях) из игровой переменной
ld b,a ; Сохраняем
and %00000111 ; Определяем на сколько скроллить
add a,a ; Умножаем на 4 чтобы сделать табличный переход
add a,a
ld (bg_ag),a ; Готовим переход на нужную подрограмму вывода
ld a,b ; Восстанавливаем

srl a ; Делим новое смещение на 8
srl a ; Получаем смещение в знакоместах
srl a

ld ix,#0040 ; Адрес экранной таблицы. Выводим на 32-ю строку экрана.
bg_ast equ $-1 ; Старший байт таблицы будет подставлен сюда извне.

jr $ ; Переходим к нужному варианту вывода
bg_ag equ $-1
jp bg0
nop
jp bg1
nop
jp bg2
nop
jp bg3
nop
jp bg4
nop
jp bg5
nop
jp bg6
nop
jp bg7
nop

;-----------------------------------------------------------------------------------------
; Подпрограммы вывода фона
; Вх: a - смещение от начала графики в знакоместах
; ix - адрес строки экранной таблицы с которой начинать вывод фона
;-----------------------------------------------------------------------------------------
; Вывод фона без смещения
bg0
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a
ld bc,#d90 ; 112 * 31

bg0_loop ld e,(ix) ; Определяем адрес экрана
ld d,(ix+1)
dup 31
ldi
edup
ld a,(hl)
ld (de),a
ret po ; Если bc==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,19 ; Следующая строка фона
add a,l
ld l,a
jr nc,bg0_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jr bg0_loop

; Вывод со сдвигом на 1 пиксель влево
bg1
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a
ld bc,32 ; Начинаем вывод с конца строки
add hl,bc

ld c,112 ; 112 строк

bg1_loop ld a,(ix) ; Определяем адрес экрана
ld d,(ix+1)
add a,31 ; Выводим с конца строки справа налево
ld e,a

ld a,(hl) ; Берём скрытый байт графики и пыжим его в CY
dec hl
rla

dup 31
ld a,(hl)
rla
ld (de),a
dec e
dec hl
edup
ld a,(hl)
rla
ld (de),a
dec c
ret z ; Если c==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,82 ; Конец следующей строки фона
add a,l
ld l,a
jp nc,bg1_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jp bg1_loop

; Вывод со сдвигом на 2 пикселя влево
bg2
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a
ld bc,32 ; Начинаем вывод с конца строки
add hl,bc

ld c,112 ; 112 строк

bg2_loop ld a,(ix) ; Определяем адрес экрана
ld d,(ix+1)
add a,31 ; Выводим с конца строки справа налево
ld e,a

ld a,(hl)
rla
rl b
rla
rr b
dec hl

dup 31
ld a,(hl)
rla
rl b
rla
rr b
ld (de),a
dec e
dec hl
edup
ld a,(hl)
rla
rl b
rla
rr b
ld (de),a
dec c
ret z ; Если c==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,82 ; Конец следующей строки фона
add a,l
ld l,a
jp nc,bg2_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jp bg2_loop

; Вывод со сдвигом на 3 пикселя влево
; Вывод строки со сдвигом на пиксель вправо, потом в обратную сторону двигаем
; строку на экране влево на 4 пихаря
bg3
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a

ld c,112 ; 112 строк

bg3_loop ld e,(ix) ; Определяем адрес экрана
ld d,(ix+1)

; Выводим строку со сдвигом на пиксель вправо
dup 31
ld a,(hl)
rra
ld (de),a
inc e
inc hl
edup
ld a,(hl)
rra
ld (de),a

inc hl ; Читаем крайний справа для выдвигания влево
ld a,(hl)
rra
ex de,hl
dup 31
rld
dec l
edup
rld
ex de,hl

dec c
ret z ; Если c==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,18 ; Начало следующей строки фона
add a,l
ld l,a
jp nc,bg3_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jp bg3_loop

; Вывод со сдвигом на 4 пикселя влево
bg4
ld d,bggfx_ah ; Вычисляем начало графики
ld e,a
ld c,112 ; 112 строк

bg4_loop ld l,(ix) ; Определяем адрес экрана
ld h,(ix+1)

ex af,af'
ld a,(de)
ex af,af'
inc de
dup 31
ld a,(de)
ld (hl),a
ex af,af'
rrd
ex af,af'
inc l
inc de
edup
ld a,(de)
ld (hl),a
ex af,af'
rrd
ex af,af'

dec c ; Если c==0, то выходим
ret z

inc ix ; Следующая экранная строка
inc ix
ld a,18 ; Следующая строка фона
add a,e
ld e,a
jp nc,bg4_loop ; Если не было переполнения, то уходим на круг
inc d ; Иначе прибавляем старший байт и тоже на круг
jp bg4_loop

; Вывод со сдвигом на 5 пикселей влево
; Читаем, сдвигаем влево на пиксель, потом вправо на 4
bg5
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a
ld bc,32 ; Начинаем вывод с конца строки
add hl,bc

ld c,112 ; 112 строк

bg5_loop ld a,(ix) ; Определяем адрес экрана
ld d,(ix+1)
add a,31 ; Выводим с конца строки справа налево
ld e,a

; Делаем сначала сдвиг влево на пихарь с выводом
dup 31
ld a,(hl)
rla
ld (de),a
dec e
dec hl
edup
ld a,(hl) ; Вывели первый байт строки
rla
ld (de),a

dec hl ; Читаем предыдущий слева
ld a,(hl)
rla
ex de,hl
dup 31
rrd
inc l
edup
rrd
ex de,hl

dec c
ret z ; Если c==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,82 ; Конец следующей строки фона
add a,l
ld l,a
jp nc,bg5_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jp bg5_loop

; Вывод со сдвигом на 7 пикселей влево
; Смещаемся на байт влево, сдвигаем строку вправо на 1 пихарь
bg6
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a

ld c,112 ; 112 строк

bg6_loop ld e,(ix) ; Определяем адрес экрана
ld d,(ix+1)

ld a,(hl)
rra
rr b
rra
rl b
inc hl

dup 31
ld a,(hl)
rra
rr b
rra
rl b
ld (de),a
inc e
inc hl
edup
ld a,(hl)
rra
rr b
rra
rl b
ld (de),a

dec c
ret z ; Если c==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,18 ; На начало следующей строки фона
add a,l
ld l,a
jp nc,bg6_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jp bg6_loop

; Вывод со сдвигом на 6 пикселей влево
; Смещаемся на байт влево, сдвигаем строку вправо на 1 пихарь
bg7
ld h,bggfx_ah ; Вычисляем начало графики
ld l,a

ld c,112 ; 112 строк

bg7_loop ld e,(ix) ; Определяем адрес экрана
ld d,(ix+1)

ld a,(hl) ; Берём скрытый байт графики и пыжим его в CY
inc hl
rra

dup 31
ld a,(hl)
rra
ld (de),a
inc e
inc hl
edup
ld a,(hl)
rra
ld (de),a

dec c
ret z ; Если c==0, то выходим

inc ix ; Следующая экранная строка
inc ix
ld a,18 ; На начало следующей строки фона
add a,l
ld l,a
jp nc,bg7_loop ; Если не было переполнения, то уходим на круг
inc h ; Иначе прибавляем старший байт и тоже на круг
jp bg7_loop

Shadow Maker
28.12.2020, 02:46
А кто-нибудь работал с SpectNet IDE (https://dotneteer.github.io/spectnetide/) или знает о ней? Стоит ли заводить новую тему, есть ли подобные аналоги?
Не, не надо тему. Аналоги - vscode + z80code от mborik + dezog в связке с одним из эмуляторов. Будет даже лучше, там по-моему и юнит-тесты есть и работает на любой платформе, а не только на виндовс. Ну и некст поддержан, если он нужен.

PATHNK
28.12.2020, 12:29
Не, не надо тему.
Я уже понял, что надо :) . Это уникальная вещь в своем роде. У программиста должен быть выбор. Я бы уже давно протестировал, просто лень ставить VS 2019, но как-нибудь протестирую.

Shadow Maker
28.12.2020, 12:39
Я уже понял, что надо :) . Это уникальная вещь в своем роде. У программиста должен быть выбор. Я бы уже давно протестировал, просто лень ставить VS 2019, но как-нибудь протестирую.
Ну что же, раз надо - то давай :) Только если возможно - было бы круто и vscode вариант и сравнить

NEO SPECTRUMAN
28.12.2020, 12:42
vscode
иму ищо и вин15 наверно падавать...

Shadow Maker
28.12.2020, 13:22
иму ищо и вин15 наверно падавать...
чойто? семерки хватит за глаза

Black Cat / Era CG
28.12.2020, 13:25
У него ХР.

Shadow Maker
28.12.2020, 14:37
У него ХР.
Тогда на ум только виртмашина приходит. Ну и я сомневаюсь, что VS2019 (обсуждаемая выше) будет на xp работать.

izzx
24.04.2021, 19:18
Подскажите, как быстро переходить по строке вверх/вниз на расширенном экране скорпиона?
У него все строчки по порядку идут, каждая 80 байт.
Знаю, что на тех компах, где между соседними строчками ровно 2048 байт, пользуются командами типа
set 3,d
res 3,d
А тут как? Вот самый простой и медленный вариант, для ширины спрайта 6 байт:

;de - адрес на экране
;hl - адрес спрайта
ldi ;скопировали байт
ldi
... ;перенесли одну строчку спрайта
push hl ; теперь на строку ниже
ld hl,80-6 ;ширина строки минус ширина спрайта
add hl,de ;перешли на след. строку
ex de,hl
pop hl ;восстановили hl

Есть способы побыстрее?

reddie
08.07.2021, 23:22
push hl ; теперь на строку ниже
ld hl,80-6 ;ширина строки минус ширина спрайта
add hl,de ;перешли на след. строку
ex de,hl
pop hl ;восстановили hl

Есть способы побыстрее?


Давно спрашивали, но ответа не было... пускай будет))
Условимся, что машина без циклов wait. Считаем такты в исходном примере: 11+10+11+4+10 = 46, длина 7 байт.
Без использования стека как хранилища/приемника данных вариантов немного. Первый, без каких-либо опций со стеком:

ld hl ,from
ld de ,to
ld bc ,80-ширина спрайта ; b=0, c=смещение
ld a,с ; аккум хранит смещение, задается один раз перед выводом спрайта

ldi ldi ldi сколько надо

------ сама процедура перевода строки:

ld c,a ; восстанавливаем регистр
ex de, hl
add hl, bc
ex de, hl

------ все, дальше опять пошло ldi ldi ldi

Итого: 4+4+11+4 = 23 такта, 4 байта. Используем аккум, зато в 2 раза ускоряем процедуру.
Если код вывода свернут в цикл, счетчик можно организовать в половинке IX либо в альт. регистре

Второй способ нестандартный, используем регистр SP как константу:

ld (savesp+1), sp ; сохраняем стек
ld sp, смещение ; (80-ширина) грузим смещение в SP и больше его не трогаем
; задаем hl и de. аккумулятор не задействуется

ldi ldi ldi сколько надо

------ сама процедура перевода строки:

ex de, hl
add hl, sp
ex de, hl

------ все, дальше опять пошло ldi ldi ldi

savesp ld sp, 0 ; восстанавливаем sp, конец вывода

Итого 19 тактов, 3 байта. Разница с первым вариантом минимальна, но все зависит от конкретных условий применения.
Сразу видно ограничение: можно юзать только при запрещенных прерываниях, поскольку sp будет указывать в ПЗУ.
Однако можно красиво обойти его при одном условии: строки спрайта хранятся наоборот, от нижних к верхним, и выводятся так же.
В таком случае смещение задается отрицательное, т.к. нужно вернуться "назад" по экранным адресам, зато регистр sp будет указывать
на самый верх ОЗУ (#FFXX), который можно спокойно затереть (скажем, верхние 256 байт памяти резервируем и не трогаем).
Сама процедура аналогична предыдущей, можно юзать при разрешенных прерываниях.

izzx
09.07.2021, 09:30
ld hl ,from
ld de ,to
ld bc ,80-ширина спрайта ; b=0, c=смещение
ld a,с ; аккум хранит смещение, задается один раз перед выводом спрайта

ldi ldi ldi сколько надо

------ сама процедура перевода строки:

ld c,a ; восстанавливаем регистр
ex de, hl
add hl, bc
ex de, hl



Только там после цепочек ldi регистр b может оказаться не = 0, я думаю.
Ещё забыл сказать, что все регистры обычно заняты. Но в цикле иногда регистр bc можно и восстановить, это ничего.

reddie
09.07.2021, 14:16
Только там после цепочек ldi регистр b может оказаться не = 0, я думаю.

Именно, думаете)) вся соль в начальном задании пары BC как нуля (B) и ширины спрайта в C.
Если кол-во команд LDI равно ширине спрайта - LDI будет менять только С, а после каждой строки BC будет равно нулю (до перевода строки).
После вывода спрайта HL=адрес след. спрайта, если лежат последовательно, - может пригодиться.
Счетчик, как указывал, можно организовать в половинках IX/IY либо в AF', а можно развернуть код (если память не жмет).

izzx
09.07.2021, 17:26
Если кол-во команд LDI равно ширине спрайта - LDI будет менять только С, а после каждой строки BC будет равно нулю
Точно, всё правильно.

Тогда ещё вопрос в зал: проект на sjasm разбит на несколько файлов, но часть процедур используется одна и та же.
Приходится писать везде строчку типа:
Метка equ Адрес
А как сделать чтобы автоматом метки работали, как будто весь проект в одном файле?

Слить в один файл с указанием где какой банк памяти по ходу текста?

reddie
09.07.2021, 20:20
Ммм по ассемблерам на PC не подскажу, код писал пока только на реале))
Предположу, по аналогии, что там должны быть инструкции включения других файлов в проект.
Насчет банков, скорее всего, верно, на реале тоже можно распихивать код (и исходники) по страницам.

Black Cat / Era CG
09.07.2021, 20:44
Слить в один файл с указанием где какой банк памяти по ходу текста?
INCLUDE включит файл в текущее место же. Или я чего-то не понимаю.

jerri
09.07.2021, 21:09
Точно, всё правильно.

Тогда ещё вопрос в зал: проект на sjasm разбит на несколько файлов, но часть процедур используется одна и та же.
Приходится писать везде строчку типа:
Метка equ Адрес
А как сделать чтобы автоматом метки работали, как будто весь проект в одном файле?

Слить в один файл с указанием где какой банк памяти по ходу текста?

include ?
не совсем понятно

если несколько независимых уровней и один кернальный блок на всё
то просто собираешь весь проект при компиляции и записываешь блоками сразу.

izzx
09.07.2021, 21:12
INCLUDE включит файл в текущее место же. Или я чего-то не понимаю.
Да, я просто думал есть волшебная команда BANK. Но похоже она не так работает.

Изначально проект в нескольких файлах, как бы перекрёстные ссылки автоматом сделать. Из файла в файл.
Или надо собрать всё с помощью INCLUDE в один файл и не думать.

upd. То есть компилируем единый файл и выгружаем частями, если надо.

Dart Alver
09.07.2021, 21:46
То есть компилируем единый файл и выгружаем частями, если надо.
Можно компилировать и записывать частями в едином пространстве проекта хоть последовательно по одному и тому же адресу.
ORG, INCLUDE & SAVE*** в помощь. ))

izzx
09.07.2021, 21:58
Переформулирую: Как правильно сделать так, чтобы за один клик компилировалась большая прога и выгружался код в разные файлы для каждого банка памяти. Там же все они с одного адреса, типа #c000. И могли быть ссылки из любой части кода в любой. И можно было без проблем что-то менять в тексте, после чего адреса меток скомпилируются новые, естественно.
А потом загрузчик проги загружал всё по нужным банкам.


Можно компилировать и записывать частями в едином пространстве проекта хоть последовательно по одному и тому же адресу.
ORG, INCLUDE & SAVE*** в помощь. ))
То есть можно типа:
org #c000
....
save "part1"

org #c000
...
save "part2"

jerri
09.07.2021, 23:02
Переформулирую: Как правильно сделать так, чтобы за один клик компилировалась большая прога и выгружался код в разные файлы для каждого банка памяти. Там же все они с одного адреса, типа #c000. И могли быть ссылки из любой части кода в любой. И можно было без проблем что-то менять в тексте, после чего адреса меток скомпилируются новые, естественно.
А потом загрузчик проги загружал всё по нужным банкам.


То есть можно типа:
org #c000
....
save "part1"

org #c000
...
save "part2"


ну во первых sjasm поддерживает sna128

а делается это как то так


device zxspectrum128

include "_defines.a80"
slot 3

page 1
org #c000
incbin "./bin/gm.ram1.bin"
page 3
org #c000
incbin "./bin/gm.ram3.bin"




include "_levels.a80"


page 4
org lev1_data
incbin "./bin/stage1.bin"


page 6
org #c000
play_mus
include "_pt3_player.a80"
mus_table
dw mus_boss ;1 ;menu
dw intro_music ;2 ;intro
dw mus_stagestart ;3
dw mus_level1 ;4
dw mus_level2 ;5
dw mus_level3 ;6
dw mus_level4 ;7
dw mus_level5 ;8
dw mus_boss ;9
dw mus_garuda ;10
dw mus_stageclear ;11
dw mus_gameover ;12
dw mus_boss ;13
dw out_mus0 ;14
dw out_mus1 ;15
dw mus_boss ;16 ;empty mus

; dw mus_boss ;17
; dw mus_boss ;18
; dw mus_boss ;19



mus_boss incbin "\music\boss\BOSS.pt3"
mus_stagestart incbin "\music\stagestart.pt3"
mus_stageclear incbin "\music\stageclear.pt3"
mus_gameover incbin "\music\gameover.pt3"
ays_effects incbin "\sfx\sw.afb"

display "music free:",#10000-$
savebin "./bin/gm.music.bin",#c000,$-#c000




music_buf equ $


org music_buf
mus_level1
mus_level2
mus_level3
mus_level4
; incbin "\music\Level1.pt3"
; incbin "\music\level2.pt3"
; incbin "\music\L3final.pt3"
; incbin "\music\Level4.pt3"

mus_level5
incbin "\music\Level5.pt3"
mus_garuda
incbin "\music\GARUDA_FINAL_BATTLE.pt3"
display "l5music ",$

savesna "qsave.sna",beginning

izzx
10.07.2021, 20:24
В целом понятно, всем спасибо.

AndTorp
05.09.2021, 02:14
Напомните, пожалуйста, адрес подпрограммы ПЗУ - подобие бейсикового PAUSE.

Вспомнил - 7997

Enigmatic
17.12.2021, 17:45
Объясните мне пожалуйста про байт. Принимать значений он может 256. Но как они считаются? Когда имеются все 8 бит - 00000000, или складываются так:
Количество значений 1 бита
0ххххххх
+
Количество значений 2х бит
00хххххх
+
.... И так далее?

- - - Добавлено - - -

Объясните мне пожалуйста про байт. Принимать значений он может 256. Но как они считаются? Когда имеются все 8 бит - 00000000, или складываются так:
Количество значений 1 бита
0ххххххх
+
Количество значений 2х бит
00хххххх
+
.... И так далее?

Black Cat / Era CG
17.12.2021, 17:52
Эммм.
00000000 - 0
00000001
00000010
00000011
00000100
...
11111111 - 255
Всего 256.
В чем вопрос?
В 10-ой 3 знаками можно записать 1000 чисел, от 0 до 999. Тут так же. Только разряд хранит не 10, 2 возможных значения.

- - - Добавлено - - -

Емкость = Основание системы (2) в степени числа разрядов (8). 2^8=256.
10^3=1000.

Enigmatic
17.12.2021, 18:15
А почему это число 256 пишут ещё как +128 и - 128?

Bedazzle
17.12.2021, 18:34
А почему это число 256 пишут ещё как +128 и - 128?

Это где такое?
Всегда было от -128 до +127. Т.е. ноль отнесён к положительным смещениям.

Black Cat / Era CG
17.12.2021, 18:46
Знаковое. Старший бит как знак, 7 бит -- число.

LW
17.12.2021, 19:40
А почему это число 256 пишут ещё как +128 и - 128?
В байте нет числа 256, 256 это уже слово (2 байта)
Байт равен 0..255

NEO SPECTRUMAN
17.12.2021, 20:02
В байте нет числа 256,
в байте то нет
ну когда нуужон счетчик на 256
можно использовать 0 :)

ld b,low 256 ;0
djnz $

- - - Добавлено - - -


В байте нет числа 256, 256 это уже слово (2 байта)
Байт равен 0..255
с третей стороны это в ваших сях байт равен 0...255
на асме жо он можот быть равен тому чего надо програмизду

0...1
-10...+92
0...358,59°

LW
17.12.2021, 20:19
Как мы хотим представить себе значения байта это вопрос отдельной темы...
Значение байта при этом никак не изменится как было от #00 до #FF так и останется

NEO SPECTRUMAN
17.12.2021, 20:21
байт это 8 бит
как програмист решит их трактовать
так оно и будет :)

оно можот быть вообще двоично десятичным
а сяпаскали так не умеют

Destr
17.12.2021, 20:27
оно можот быть вообще двоично десятичным
а сяпаскали так не умеют
Им можно свои функции пихнуть, в стандартных может их и нет (ибо по сути эти BCD не стали чем-то необходимым)...

LW
17.12.2021, 20:41
байт это 8 бит
т.е. 2^8 значений, т.е. 0..255, но никак байт не будет равен 256, 257 и т.д.

и си, паскали тут вообще не причем.

reddie
17.12.2021, 21:40
Многие наверняка нижеописанное знают, однако, мало ли. Чуток оффтопного капитанства в продолжение темы байта.
Принимать он может 256 значений, часто применяются лукап-таблицы по 256 байт (или 256+256 для 16-битных слов), но я не про это.
У восьмиразрядного счетчика, коим является байт - ну или регистр, что чаще - есть одно замечательное свойство.
Неважно, какое значение мы прибавляем к байту (регистру) - через 256 повторов мы получим изначальное содержимое счетчика.
Для четных приращений оно "вернется" раньше, кратно степени двойки, т.е. на 256 повторов получим 2/4/8 и так далее возвратов к исходному числу.
Для любой нечетной прибавки, хоть +1, хоть +171, через 256 шагов счетчик примет исходный вид. Разумеется, оперируя байтом, а не словом.
Соответственно, если с неким шагом перебирать таблицу в 256 байт через приращение младшего регистра в паре, за 256 проходов она гарантированно будет обработана.

Spectramine
17.12.2021, 22:41
но никак байт не будет равен 256, 257 и т.д.
Байт может кодировать любые 256 значений, хоть 0..255, хоть -128..127, хоть 256..511.
Хоть 0,2,4,8,..,510, и т.д. ЛЮБЫЕ 256 значений.

- - - Добавлено - - -

или меньше 256 значений, но не больше.

LW
17.12.2021, 22:55
я о тёплом, вы о мягком....

байт может кодировать ровно 256 значений от %00000000 до %11111111. нет там ни 256, ни 511, 510 и т.п.
как значение байта интерпретирует программер, это уже совсем иной вопрос.

dimidus
18.12.2021, 09:33
У восьмиразрядного счетчика, коим является байт - ну или регистр, что чаще - есть одно замечательное свойство.
Неважно, какое значение мы прибавляем к байту (регистру) - через 256 повторов мы получим изначальное содержимое счетчика.
Для четных приращений оно "вернется" раньше, кратно степени двойки, т.е. на 256 повторов получим 2/4/8 и так далее возвратов к исходному числу.
Для любой нечетной прибавки, хоть +1, хоть +171, через 256 шагов счетчик примет исходный вид. Разумеется, оперируя байтом, а не словом.
Соответственно, если с неким шагом перебирать таблицу в 256 байт через приращение младшего регистра в паре, за 256 проходов она гарантированно будет обработана.

Интересное замечание. Так можно дёшево заполнять весь экран пикселями гарантированно за 256 проходов.

Reobne
18.12.2021, 09:37
Каждый прав, исходя из собственного определения байта. Суть одна и та же.

Изначально человека знакомят с битом, а потом с байтом как восьмью битами.
Учащийся должен сам попытаться посчитать, сколько различных состояний может принимать один бит, два бита, три бита и наконец восемь бит.

С другого захода человеку рассказывают, что есть десятичная система, где основание десять, а есть всякие другие. Особенно двоичная.

А наивный вопрос "что первично?", он как то сам по себе возникает в голове стайных животных с иерархией. Кто главнее?

Вот тот же z80 он по разному интерпретирует байт.
Как 8 уникальных бит в логических операциях.
Как ряд из 8 бит в операциях сдвига.
как целое 0..255 или -128..127 в операциях сложения отнимания, в зависимости от дальнейшего использования флагов.
Как смещение -128..+127 в коротких переходах и обращениях по индексным регистрам.
Чуть костылнее двоичнодесятичное представление и как два набора по четыре бита.

Видеосистема zx интерпретирует байт как ряд из 8 бит-пикселей и как совокупность бита мигания, бита яркости, 8 цветам подложки и 8 цветам чернил.

В других портах тоже соответствующие интерпретации.

Хотя первичны электрические состояния в восьми пронумерованных проводниках.

А программист может интерпретировать гораздо шире. Считать, например, байт числом от 1900 до 2155.

Определение же байта тоже у всех может быть разное. Смотря с какой стороны ты к сути байта подошёл.

reddie
18.12.2021, 09:50
Считать, например, байт числом от 1900 до 2155.

И вот тут (снова пооффтоплю) виден разный подход у разных людей. Вернёмся в прошлый век, к первым компам, да даже к первым линейкам PC, где год даты задавался всего одним байтом для экономии памяти. Вводился он непосредственным значением, скажем, 90-й. Может, там даже использовали символьное представление, тогда уходит два байта. В результате получили знаменитую "проблему 2000" при обнулении этого самого числа. Но что мешало задать дату смещением, выбрав за точку отсчёта некий год, например, год создания первого компьютера или (для удобства отсчёта) 1900-й, например? Всего один байт смещения решил бы проблему даты на двести с лишним лет вперёд - по сути, навсегда.

Sandro
18.12.2021, 10:35
Ну вот Unix date считается с 1972 года, и в 2036 юниксовы года закончатся. Это не решение проблемы, а заметание мусора под ковёр. Лучше всё-таки хранить дату, как есть.

reddie
18.12.2021, 11:34
Ну вот Unix date считается с 1972 года, и в 2036 юниксовы года закончатся

Ну вот хранили значение года "как есть", и получили ту же проблему куда раньше =)
А всё из-за вечного людского "на мой век хватит, а там хоть потоп".

Sandro
19.12.2021, 11:14
Ну вот хранили значение года "как есть", и получили ту же проблему куда раньше =)

Ну всё же с заворотом через век пока что проще, чем через 64 года. Ну и "как есть" всё же подразумевает 4 знака. :)


А всё из-за вечного людского "на мой век хватит, а там хоть потоп".

Увы. Есть такое.

tae1980
20.12.2021, 15:34
Ну вот Unix date считается с 1972 года, и в 2036 юниксовы года закончатся. Это не решение проблемы, а заметание мусора под ковёр. Лучше всё-таки хранить дату, как есть.
Как раз решение вопроса. Вот из rexx:
(BORNDATE - дата рождения): возвращает количество полных дней (не включая текущий день), начиная от даты рождества Христова (Январь 1, 0001), включая её. Результат выдается в формате ДДДДДД (без начальных нулей). Это формат удобен тем, что выражение вида DATE(B)//7 в качестве результата будет всегда иметь число из диапазона 0-6, где 0 соответствует понедельнику, а 6 - воскресенью (то есть, по сути, является номером дня недели). Поскольку дата '1 Января 0001 г.' основана на Григорианском календаре, который не существовал до 1582 года, количество дней, истёкших ‘от рождества Христова’, вычисляется следующим образом: 365 дней в году плюс 1 дополнительный день на каждые четыре года (исключая годы, символизирующие век: 100, 200 и т.д.) плюс 1 дополнительный день на каждый 400-ый год (400, 800 и т.д.). В расчёт не принимаются ошибки в существовавшей ранее календарной системе, которые и привели к созданию Григорианского календаря.

Сегодня идёт 738143 день. И вообще ни каких проблем, и ни когда (во вменяемом будущем) их не будет. 6 байт или 3 байта + очень лёгкие расчёты с ней.

reddie
20.12.2021, 15:51
6 байт или 3 байта + очень лёгкие расчёты с ней
Да, но тут задается лишь дата, без часов, минут и так далее. Юниксовый отсчет дается с точностью до секунды, а это (в день) 86400 тиков, что минимум + еще 2 байта.
Итого по критически важному (в те древние времена) количеству байт проигрываем юниксовому варианту. Расширив который на байт, можно было "уйти" в вечность.

tae1980
20.12.2021, 16:56
Да, но тут задается лишь дата, без часов, минут и так далее.
Но, мы про дату и говорили.

Время так же задаётся числом секунд прошедших с полуночи (86400). Это ты указал правильно. Плюс ещё 3 байта. Итого получаем 6 байт и минимум гемора.
Но непосредственно в rexx'се, ситуация вообще другая, так как ему глубоко плевать на байты, он хранит все цифра в текстовом формате. Да, с точки зрения экономии - это кошмар, но зато можно, например, посчитать число пи до абсолютно любого знака (при желании хоть миллионного - дурная голова рукам покоя не даёт). Главное, что бы хватило физической памяти. Про то сколько он это будет делать - даже думать не хочу. И не только посчитать, но и корректно выполнять арифметические действии с ним. При этом положив болт и на разрядность проца.

Разные задача, разные решения. В настоящее время, лично мне, подход rexx гораздо ближе.

tae1980
22.12.2021, 23:18
Касаемо даты.
Можно хранить число дней прошедших с начала текущего века. Получаем максимальное значение 365*100=36500. То есть влазим в 2 байта. А с двумя байтами работать у нас проще. А числа более максимально возможного числа можно рассматривать как даты в предыдущем столетии от начала нынешного (так сказать "до нашей эры"). Это ~29035 дней, которых хватит на 79 лет.
Для отдельных случаев можно добавлять третий байт - номер столетия. Думаю лучше всего -128...+127. Видеться, что этого периода хватит на все вменяемые даты.

А если время округлить до минут, то в сутках 1440 минут, так же для работы с ним хватит 2-х байт.
Нужны секунды, задействуем ещё один байт. Но храним там число секунд 0-59.

Такая схема избавит от необходимости иметь процедуры арифметики трёх байтных чисел.

izzx
25.12.2021, 22:39
1. Как в sjasm zoom сделать такую вещь:

ORG ADR1 [,ADR2]

ADR1 - где будет работать
ADR2 - куда положить код
2. Как делают проигрывание звука через ЦАП во время вывода картинки? А одновременно с чтением с карты? Через обычный ковокс. Или такое мало реально? Я думаю сложно.

LW
25.12.2021, 23:22
org ADR2
phase ADR1
....
unphase

reddie
27.12.2021, 10:57
2. Как делают проигрывание звука через ЦАП во время вывода картинки?
Тут основная задача - равномерный вывод данных в ЦАПы, чтоб избежать т.н. джиттера. На компах, где есть всякие дма-режимы и прерывания с высокой частотой, это не проблема, но на Спектруме (стандартном) ничего этого нет. Всё задержки/растактовки нужно высчитывать и реализовывать кодом. Не прям до такта, но с более-менее выравнивать вполне можно.
Кстати, используя GS как ЦАП, задача упрощается, но надо писать свою загружаемую в его память процедуру. Которая будет по внутренним прерываниям читать порт, что даст вполне удобные тайминги. Максимальная частота, соответственно, 37 КГц, либо с делителями на 2, 4 и так далее. Остаётся вовремя подкидывать данные в порт, следя за их принятием. Для варианта с подгрузкой потока с быстрых носителей - самое то.

SfS
02.01.2022, 13:34
Ну вот Unix date считается с 1972 года, и в 2036 юниксовы года закончатся. Это не решение проблемы, а заметание мусора под ковёр. Лучше всё-таки хранить дату, как есть.

Сейчас хранят не в 32 битах, а в 64х битах unix time. И на ближайшие миллиарды лет проблема решена:)

Кстати, юникс тайм хранит и отрицательные значения:)

Sandro
02.01.2022, 18:15
2. Как делают проигрывание звука через ЦАП во время вывода картинки? А одновременно с чтением с карты? Через обычный ковокс. Или такое мало реально? Я думаю сложно.[/QUOTE]

Да вот так и делают. Good Apple выводит звук одновременно со чтением с карты. А The Craft ...

Да блин. У неё вообще ничего нет. Звукового адаптера у неё нет. Видеоадаптера у ней нет. У неё вообще ничего нет, кроме 20 МГц микроконтроллера и нескольких резисторов.

https://www.youtube.com/watch?v=sNCqrylNY-0

reddie
02.01.2022, 18:43
У неё вообще ничего нет, кроме 20 МГц микроконтроллера и нескольких резисторов.

20 МГц AVR довольно мощная штука, ей вполне по силам программно всё это делать. Спектрум да и БК хоть до условных двухсот разогнать, но тв-картинку они генерить если и смогут, то без другого функционала. Программисту всё равно зачёт, хотя видос уже довольно древний боян.
Good Apple хороший пример, но большая часть времени у Manwe ушла, подозреваю, на подготовку данных для вывода =)
Там всё же не полнокадровые 30 фпс, что физически на БК невозможно, а смена кусков кадра. Просчитать это всё и совместить массив видеоданных с аудио, пусть и заранее, тоже работка не на пять минут.

NEO SPECTRUMAN
02.01.2022, 18:55
а смена кусков кадра.
это ввсе на изичах
но вот подбирать всякие коэфициенты
чтоб добитсо желаемого качества и битрейта
придетсо ручками и долго :)

ALKO
12.01.2022, 14:29
Очень слоупочный фпс из-за очистки буфера и переброски его на реальный экран, все 7 килобайт.

Как сделать максимально быструю очистку всего экрана, и копирование его на реальный?

goodboy
12.01.2022, 15:01
смотря что у тебя с прерываниями - разрешены/запрещены. ldi/ldd / push/pop

ALKO
12.01.2022, 15:10
смотря что у тебя с прерываниями - разрешены/запрещены. ldi/ldd / push/pop

На момент процедуры очистки и переброски можно отрубить.

reddie
12.01.2022, 15:57
Очистку без проблем можно делать через стек и с разрешенными, т.к. идем сверху вниз. Развертываем PUSH RX (RX=00) на сколько памяти не жалко.
Копирование... максимально быстро через прямое задание SP для буфера и экрана, т.е. отдельно для PUSH и POP, и забор данных во все регистры.
Соответственно, процедура переброса займет примерно как сам экран. Прерывания допустимы, нужно разделить переброс между ними "впритык" или около.
Либо писать хитрожопый обработчик прерываний, анализирующий команды во время его прихода, и восстанавливающий 2 байта на стеке из нужной рег. пары.
Чуть помедленнее развертка вида POP HL: LD (NN),HL - но жрет памяти вдвое больше объема переброса. Зато два байта стека восстановить просто (прерывание).
Еще медленнее, но универсально и минимально по размеру, строчка команд LDI. Пояснений не требует.

zebest
13.01.2022, 00:48
Программа работает с IM2, и ей понадобилось прочесть файл с дискеты. Запретить на время прерывания по DI - этого мало ??
Обязательно надо IM 1: DI а потом уже 3d13h?
И второй вопрос, плавно вытекающий из первого.
Надо прочесть в буфер следующий файл на диске. Название не важно, количество секторов как бы еще неизвестно. Это надо с каталога сперва инфу прочесть, а потом уже файл читать ?

goodboy
13.01.2022, 01:12
Надо прочесть в буфер следующий файл на диске. Название не важно, количество секторов как бы еще неизвестно. Это надо с каталога сперва инфу прочесть, а потом уже файл читать ?
если ты точно уверен в расположении данных (склейка в моноблок) то забирай трек/сектор из переменной (23796)
если нужный файл находится в произвольном месте то только через чтение каталога

LW
13.01.2022, 07:43
Программа работает с IM2, и ей понадобилось прочесть файл с дискеты. Запретить на время прерывания по DI - этого мало ??
IY еще должен быть равен #5C3A при вызове #3D13

zebest
13.01.2022, 09:29
забирай трек/сектор из переменной (23796)
Ну у меня сей час так и сделано:


im 1
di ;
ld hl,buff_ ;
ld de,(current_track_sector)
ld bc,0605h ; C=#05 - чтение блока секторов:
call 3d13h ;
но надо знать количество секторов. С парой файлов я то могу посчитать сектора, а елси мне 255 штук надо считывать ?:(
Считывать инфу из каталога под текущий current_track_sector?


IY еще должен быть равен #5C3A при вызове #3D13
ну раз надо - то попробую IY выставить

LW
13.01.2022, 09:55
Постановка задачи то какая?
Если нужно загрузить несколько файлов из своего проекта, то размер этих файлов в секторах известен и берется из заранее составленной таблицы.

В более общем случае:
1. находим дескриптор первого файла в каталоге
2. берем из него сектор/дорожку и длину файла в секторах
3. грузим файл
4. переходим к дескриптору следующего файла
5. goto п.2, пока не загрузим нужное количество файлов.


а елси мне 255 штук надо
255 с одного диска не получится загрузить. Максимум 128

zebest
13.01.2022, 10:11
У меня как раз "более общий случай".
128 - маловато, ну пусть будет столько. Файлы предполагалось маленькие, в пределах 1-1,5 кБ. Хотя если всего 128 штук - ну тогда ~3-5кБ.
Хорошо. Попробую разобраться с чтением каталога.

goodboy
13.01.2022, 10:11
Обязательно надо IM 1: DI а потом уже 3d13h?
запрещать прерывания не обязательно.
в твоём случае EI выполнится в одной из подпрограмм trdos

reddie
13.01.2022, 10:29
128 - маловато, ну пусть будет столько. Файлы предполагалось маленькие, в пределах 1-1,5 кБ
Ничто не мешает хранить данные на диске и грузить последовательно. Хоть 120 файлов, хоть 400 "файлов", для последовательной загрузки это значения не имеет.
Просто берется номер следующих сектора/трека из #5CF4 и все. Как же записать 400 штук? Да аналогично, последовательно отгружать на диск.
Главное, чтобы общий объем файлов программы совпадал с ее размером, и если это больше 255 секторов (что очевидно) - ее файлы должны лежать друг за другом.
Если же планируется непоследовательная загрузка (или запись) из программы - без таблицы смещений уже не обойтись.
Либо, если все блоки будут одного размера (скажем, 2Кб), то и таблицы не надо. Сдвигом регистров устанавливаем смещение от начала и плюсуем стартовое.

Shadow Maker
13.01.2022, 11:18
Если же планируется непоследовательная загрузка (или запись) из программы - без таблицы смещений уже не обойтись.
Не нужна таблица смещений. Нужен только размер каждого файла и всё (но да, таблица размеров файлов нужна), файлы лежат последовательно, поэтому достаточно сложить размеры всех предыдущих (предположим размер в секторах, ну и в байтах там разницы почти никакой) с трек-сектором из #5cf4 и загрузить.

LW
13.01.2022, 11:21
Если бы размер файлов был одинаковый, либо была бы таблица с размерами, то такого вопроса и не возникло.

Shadow Maker
13.01.2022, 11:39
Ну вот хранили значение года "как есть", и получили ту же проблему куда раньше =)
А всё из-за вечного людского "на мой век хватит, а там хоть потоп".
Ну так-то и правильно, 32-битные системы отжили свое. В 64-битных системах по умолчанию 64-битный unixtime и там 292 миллиарда лет - хватит небось, там по гипотезам ученых уже через миллиард лет Солнце погаснет :)

- - - Добавлено - - -


Если бы размер файлов был одинаковый, либо была бы таблица с размерами, то такого вопроса и не возникло.
Ну так почему не сделать таблицу с размерами при записи файлов? Раз их количество превышает размер каталога. Кстати там еще свободное место в нулевом треке с 10 по 15 сектора, туда тоже можно накидать дескрипторов файлов. В общем какие-то надуманные проблемы. И кстати у автора вопрос возник, ты ему сказал. что максимум 128 файлов, что не является истиной, этот момент и разъяснили, как именно с файлами работать без каталога.

LW
13.01.2022, 11:50
Ну так почему не сделать таблицу с размерами при записи файлов?
Может поэтому

С парой файлов я то могу посчитать сектора, а елси мне 255 штук надо считывать ?

А вообще не зная цели загрузки такого количества файлов, и их происхождения, трудно предложить что-то оптимальное.
К примеру, если это фиксированный набор некоторых данных в файлах, ту же таблицу их размеров можно генерировать в процессе компиляции.

Shadow Maker
13.01.2022, 11:53
Может поэтому
Ну это мне лично показалось указанием на то, что "я не знаю как сделать считалку, расскажите". Ну мы и рассказали.


К примеру, если это фиксированный набор некоторых данных в файлах, ту же таблицу их размеров можно генерировать в процессе компиляции.
О чем и речь. А нефиксированный набор - или не запишешь на дискету (тк 128 файлов) или если ты их сам и сохраняешь - можешь и таблицу сам сохранить. В общем решение есть в любом случае.

reddie
13.01.2022, 12:06
Нужен только размер каждого файла и всё (но да, таблица размеров файлов нужна)
Ну это и подразумевалось под таблицей смещений в секторах. Либо да, хранить размер каждого в секторах, разница невелика.


там еще свободное место в нулевом треке с 10 по 15 сектора, туда тоже можно накидать
Если дискету копировать не потреково - при первом же копировании файлов эти сектора улетят в никуда =) Так что не стоит.

zebest
13.01.2022, 12:09
запрещать прерывания не обязательно.
в твоём случае EI выполнится в одной из подпрограмм trdos
Нее, плохо получается. Рандомно, чаще зависает, но может и загрузить правильно. Поэтому фиг с ими, с лишними двумя командами.


Если бы размер файлов был одинаковый, либо была бы таблица с размерами, то такого вопроса и не возникло.
Тут вот какое дело.
Для чипа SAA1099 существует, грубо говоря, 600 треков. Размер , ну пусть от 1кб до 4-5кБ. В исходном виде и так ясно, что на диск TRD не влезут, но если их пожать пакером - то каждый файл уже будет 1-1,5 кБ. Хорошо, пусть чуть больше 1,5кБ в идеале. Вопросы . Как пакетно сжать сразу 600 файлов, как их потом выровнять до 2кБ все (8 секторов). Если их решить - то 300 файлов по идее можно на диске разместить.
У формата .etc нет как такового признака окончания мелодии, поэтому или играем определенное время и грузим след., или по клавише грузим след.
Ну и так, для информации. Под EsxDOS есть довольно хороший плейер .ETC, из ограничений - в каталоге не видит больше определенного количества, 240 примерно файлов видит, точно не помню.
Поэтому в идеале было бы просто на тр-дос диск файлов накидать, ну или пожать и выровнять.

Shadow Maker
13.01.2022, 12:16
Тут вот какое дело.
Для чипа SAA1099 существует, грубо говоря, 600 треков. Размер , ну пусть от 1кб до 4-5кБ. В исходном виде и так ясно, что на диск TRD не влезут, но если их пожать пакером - то каждый файл уже будет 1-1,5 кБ. Хорошо, пусть чуть больше 1,5кБ в идеале. Вопросы . Как пакетно сжать сразу 600 файлов, как их потом выровнять до 2кБ все (8 секторов). Если их решить - то 300 файлов по идее можно на диске разместить.
Да без проблем вообще. Пишешь батник, который zx0 ужимает файлы из папки, потом дополняешь нулями до 2кб, потом лепишь всех в один файл и заменяешь данные на trd диске начиная с нужного тебе сектора. Я могу написать, но я батники забыл, т.к. у меня линух, но это реально несложно. Баш могу написать.

- - - Добавлено - - -


Если дискету копировать не потреково - при первом же копировании файлов эти сектора улетят в никуда =) Так что не стоит.
Вряд ли тут такой вопрос вообще стоит, раз автор хочет забить максимум.

reddie
13.01.2022, 12:30
в идеале было бы просто на тр-дос диск файлов накидать, ну или пожать и выровнять.
Да, если файлы точно не превышают два кило - будет вполне удобно. Забиваем TR-DOS диск данными с первой дорожки (не с нулевой ыы), при таком раскладе
достаточно номер трека разделить на два сдвигом регистровой пары (влезет-то больше 255 файлов), прибавить единицу и получить номер дорожки трека.
А флаг переноса отправить в третий бит номера сектора: либо 0, либо 8. Вот и вся математика.
Ну и каталог забить "файлами" по 255 до конца диска, чтобы не затирать данные. В конец можно бут/плеер записать для удобства.

goodboy
13.01.2022, 12:40
"запрещать прерывания не обязательно. в твоём случае EI выполнится в одной из подпрограмм trdos"

Нее, плохо получается. Рандомно, чаще зависает, но может и загрузить правильно. Поэтому фиг с ими, с лишними двумя командами.
???
а где я тебе что-то разъяснил про вторую (im1) команду ???
естественно режим im2 надо выключать, но прерывания запрещать не обязательно

- - - Добавлено - - -


Для чипа SAA1099 существует, грубо говоря, 600 треков. Размер , ну пусть от 1кб до 4-5кБ. В исходном виде и так ясно, что на диск TRD не влезут
пиши под isdos

ALKO
15.01.2022, 00:18
Какая должна быть последовательность операций AND/ OR/ XOR для наложения спрайта по маске?

Bedazzle
15.01.2022, 02:04
Какая должна быть последовательность операций AND/ OR/ XOR для наложения спрайта по маске?

(background AND mask) OR sprite

Reobne
15.01.2022, 10:13
(background AND mask) OR sprite
Если очень хочется, то вместо AND-OR можно AND-XOR, и переделав данные можно OR-XOR, OR-AND.

zebest
18.01.2022, 13:37
Пишешь батник, который zx0 ужимает файлы из папки, потом дополняешь нулями до 2кб, потом лепишь всех в один файл и заменяешь данные на trd диске начиная с нужного тебе сектора.
Так и сделал, в три захода. В один файл - плохая идея, хотя поначалу и сделал и одним 600к. Но потом все же сделал по 30 треков в пак, для меня вполне нормальное решение.
https://s.micp.ru/M0ZBI.png
Ну да, жал не новомодным zx0, а стареньким MLZ

Bedazzle
18.01.2022, 19:19
Ну да, жал не новомодным zx0, а стареньким MLZ

А что так? Если я правильно понимаю, zx0 жмёт в общем случае - лучше, а скорость - на уровне MegaLZ.

zebest
18.01.2022, 19:26
А что так?
Неее, ну полгода назад я пробовал zx0, вполне хорошо жмет. Возможно и тут бы лучше сжал. Возможно что бОльшая часть файлов влезла не в 8 секторов, а в 7, и тогда бы не 300, а 400 треков можно на тр-дос разместить... но то такое :)
И таааак сойдет! (с) Если только чисто для сравнения попробовать пережать те же 500 файлов

Bedazzle
18.01.2022, 19:35
И таааак сойдет! (с)

Фу-фу-фу!



Если только чисто для сравнения попробовать пережать те же 500 файлов

Интересно посмотреть на разницу!

zebest
18.01.2022, 20:18
Интересно посмотреть на разницу!
Легко!
Исходно 551 файл, суммарно 1461кБ
Сжато MLZ - 644 352 б
Сжато ZX0 - 605 339 б
Если отсечку делать по 7 секторов (1792б) - тогда на диск грубо говоря не 300 треков влезет, а 333
И таак сойдет (с)-2

drbars
19.01.2022, 18:55
Процедурка для посторение таблицы TR/SEC:



TRSEC_CALC:
ld a,[сколько секторов пропустить]
ld de,(TRSEC)
ld b,#10
add a,e
TRSEC_CALC2:
ccf
sub b
jr c,TRSEC_CALC1
inc d
jr TRSEC_CALC2
TRSEC_CALC1:
add a,b
ld e,a
ld (TRSEC),de
ret

goodboy
19.01.2022, 19:00
у него скорее пропуск секторов возможен >255 (тут уже рег.пара нужна)

drbars
19.01.2022, 19:09
у него скорее пропуск секторов возможен >255 (тут уже рег.пара нужна)
Ничего не мешает запустить процедурку пару раз.

tiboh
19.01.2022, 19:37
Ничего не мешает запустить процедурку пару раз.

Можно попроще сделать:


LD BC,сколько секторов пропустить
LD DE,(TRSEC)
NEXTD INC E

BIT 4,E
JR Z,NEXTD2
LD E,0
INC D
NEXTD2 DEC BC

LD A,B
OR C
JR NZ,NEXTD
LD (TRSEC),DE
RET

zebest
19.01.2022, 20:24
Надеюсь я понял правильно назначение процедуры.
Попробую реализовать. Спасибо.

drbars
23.01.2022, 16:46
Надеюсь я понял правильно назначение процедуры.
Попробую реализовать. Спасибо.

Могу ещё такой вариант предложить, смысл тот же, но другими словами :)



LD HL,[TR/SEC]
LD BC,[Skip Sectors]
NEXTD CPI
LD A,L
XOR #10
JR NZ,NEXTD2
LD L,A
INC H
NEXTD2 LD A,B
OR C
JR NZ,NEXTD
RET

zebest
23.01.2022, 19:06
Попробую, это не сложно.
Я сделал процедуру tiboh, теперь прыгает вперед на 10 треков и на 100.
Можно ли то же самое, но назад?) понимаю, что надо inc на dec менять, но я запутаюсь в сложении вычитания)

reddie
23.01.2022, 20:07
Можно ли то же самое, но назад?
А каким образом делается переход на 10 и 100 треков сразу? Складываются смещения (длины) всей пачки и затем плюсуются к #5CF4? Тогда и менять ничего не нужно, достаточно один раз запомнить _исходное_ содержимое переменной #5CF4 ( начало первого трека),а затем плюсовать к сохраненному значению нужное смещение. Два байта памяти, думаю, не проблема.

drbars
23.01.2022, 20:07
Попробую, это не сложно.
Я сделал процедуру tiboh, теперь прыгает вперед на 10 треков и на 100.
Можно ли то же самое, но назад?) понимаю, что надо inc на dec менять, но я запутаюсь в сложении вычитания)
А это зачем? :) Если есть каталог с файлами, то можно TR/SEC брать из него. Либо зная количество секторов для каждого файла, построить таблицу с TR/SEC и перемещаться уже по ней. Какой смысл считать вперёд/назад каждый раз?

reddie
23.01.2022, 20:48
Какой смысл считать вперёд/назад каждый раз?
Кстати, да. Строим таблицу готовых адресов для каждого файла, а для загрузки берём смещение на номер трека и получаем указатель на трек/сектор нужного файла, вот и всё.
А если все файлы выровнять до одного размера, как оговаривалось ранее, то и таблица не нужна.

drbars
24.01.2022, 20:57
А что за задача стоит?

Вот таким способом, без цикла, можно делать пропуск от 1 до 240 секторов:



LD DE,[TR/SEC]
LD A,[Skip Sectors 1-240]

ADD A,E
LD B,A
AND #0F
LD E,A

LD A,B
RRCA
RRCA
RRCA
RRCA
AND #0F
ADD A,D
LD D,A
RET

0xDEAD
29.01.2022, 22:26
Как бы сделать покрасивше:
в зависимости от состояния флага C поставить или сбросить 0-й бит в памяти по адресу (HL)?
Аккумулятор свободен.

if CY=1
set 0, (HL);
else
res 0, (hl);

jerri
29.01.2022, 23:45
Как бы сделать покрасивше:
в зависимости от состояния флага C поставить или сбросить 0-й бит в памяти по адресу (HL)?
Аккумулятор свободен.

if CY=1
set 0, (HL);
else
res 0, (hl);

ты смеешься да?

rl (hl)

если хочешь оставить C
то rr (hl): rlc (hl)

0xDEAD
30.01.2022, 00:03
jerri, так а что rl (hl)? Мне (HL) двигать нельзя, биты 1-7 должны быть там, где они есть. Только нулевой бит нужно установить/сбросить.

Хорошо. А если не нулевой бит?

if CY=1
set 5, (HL);
else
res 5, (hl);

Spectramine
30.01.2022, 01:20
Как бы сделать покрасивше:
в зависимости от состояния флага C поставить или сбросить 0-й бит в памяти по адресу (HL)?
Аккумулятор свободен.

if CY=1
set 0, (HL);
else
res 0, (hl);

Лучше, чем
set n,(hl)
jr c, $+2
res n,(hl)

ничего нету. И вообще, лучше сначала делать как понятно, а как покрасивше оставить на потом (или вообще не делать как покрасивше, обычно копеечная оптимизация себя не особо оправдывает, гораздо выгоднее алгоритмическая).

0xDEAD
30.01.2022, 01:23
Ну с переходом ясно. Думал, может есть какой-то красивый метод без перехода.

Spectramine
30.01.2022, 01:25
Красивые методы обычно ухудшают читабельность программы.

0xDEAD
30.01.2022, 01:51
ld a, 0
vs
xor a

Что-то подобное я имел в виду под "красивым методом".
Пусть себе ухудшают. Место критическое к скорости.

shurik-ua
30.01.2022, 02:54
Думал, может есть какой-то красивый метод без перехода.



ld a,0
adc a,0
or a,(hl)
ld (hl),a


правда здесь нету сброса бита - но возможно это и не требуется

Spectramine
30.01.2022, 03:05
ld a, 0
vs
xor a

Что-то подобное я имел в виду под "красивым методом".
Пусть себе ухудшают. Место критическое к скорости.

Обдумайте, как его оптимизировать алгоритмически. В данном случае инструкции SET/RES просто находка, на ВМ80 было бы длиннее, c использованием аккумулятора, двумя переходами, и флаги бы были испорчены без их сохранения.

- - - Добавлено - - -


правда здесь нету сброса бита - но возможно это и не требуется
По ТЗ требуется:
if CY=1
set 0, (HL);
else
res 0, (hl);

shurik-ua
30.01.2022, 04:50
вообще все эти трюки для неиспользования переходов полезны на х86, а на z80 каждый такт на вес золота )

LW
30.01.2022, 08:40
то rr (hl): rlc (hl)
вообще-то это как раз и соответствует первоначально поставленной задаче
биты 7-1 (hl) неизменны
бит 0,(hl) = флагу C

drbars
30.01.2022, 11:12
Как бы сделать покрасивше:
в зависимости от состояния флага C поставить или сбросить 0-й бит в памяти по адресу (HL)?
Аккумулятор свободен.

if CY=1
set 0, (HL);
else
res 0, (hl);




LD A,(HL)
RRA
RLCA
LD (HL),A


- - - Добавлено - - -


Хорошо. А если не нулевой бит?

if CY=1
set 5, (HL);
else
res 5, (hl);



LD HL,[адрес ячейки]

AND A ; Cf=0
[или]
SCF ; Cf=1

SBC A,A
AND %00100000 ; бит 5
LD C,A
LD A,(HL)
AND %11011111 ; не бит 5
OR C
LD (HL),A

jerri
30.01.2022, 11:36
jerri, так а что rl (hl)? Мне (HL) двигать нельзя, биты 1-7 должны быть там, где они есть. Только нулевой бит нужно установить/сбросить.

Хорошо. А если не нулевой бит?

if CY=1
set 5, (HL);
else
res 5, (hl);

тогда при прочих равных
jr nc,nnn
set N,(hl)

nnn res N,(hl)

- - - Добавлено - - -


вообще-то это как раз и соответствует первоначально поставленной задаче
биты 7-1 (hl) неизменны
бит 0,(hl) = флагу C

ну это автору не нравятся переходы.

reddie
30.01.2022, 11:44
автору не нравятся переходы
Так их и нету, две команды сдвига (нециклический+циклический обратно) - длина минимальна, остальные биты на своих местах - что еще нужно? =)

0xDEAD
30.01.2022, 11:54
ну это автору не нравятся переходы.

rr (hl): rlc (hl) - не вижу тут переходов.
А так - отлично для нулевого бита, спасибо.

Spectramine
30.01.2022, 12:31
rr (hl): rlc (hl) - не вижу тут переходов.
А так - отлично для нулевого бита, спасибо.

Для седьмого подобный прием тоже подойдет)

0xDEAD
30.01.2022, 12:31
Ну да, это крайности. В прямом смысле слова.

reddie
30.01.2022, 14:40
Схожий трюк можно проделать, если нужно сбросить/установить нулевой бит в аккуме или (HL), но перед этим проверить его.
Наиболее очевидны команды BIT 0,x: RES 0,x - но скроллы сэкономят байт: RRCA и следом SLA A/SLI A, для (HL) аналогично.
Ну и затем проверяем флаг переноса, а не нуля.

zebest
30.01.2022, 15:52
Очень странный и показательный ( в прямом смысле) тест инструкции CCF (ну или SCF)

.loop push hl
pop af
ccf
push af
pop bc
ld a,l
xor c
ld (hl),a
inc hl
ld a,h
and d
ld h,a
jp .loop
По идее он проверяет установку\снятие 3 и 5 флагов, если не путаю.
Вот только КАК он это делает - я плохо понимаю.
И да, это не для эмулей, они такое не могут эмулить. А вот на некоторых реальных процессорах красиво получается

https://drive.google.com/file/d/1lxIZyMH8RA7aREc7f9jTTrrG0iNawfoX/view?usp=sharing
Этого "мусора", в виде шевелящихся черных\белых точек - в эмулях не бывает.

reddie
30.01.2022, 17:04
Этого "мусора", в виде шевелящихся черных\белых точек - в эмулях не бывает
Дак может этот "мусор" именно глюки некоего реального железа? В памяти точно изменения происходят? Или только на экране их "видно"?
По логике, биты флагов вообще влиять не должны, т.к. на них действует AND, а в (HL) кладется значение аккума, никак от флагов не зависящее.

zebest
30.01.2022, 17:50
Если это и глюки - то довольно интересные)))))
У меня 3 (три!) штуки профика и десяток процессоров Z80. От платы эти глюки не зависят, а онли от производителя процессора) На Зилогах такого нет, на ST, Sharp, Т34 и пр. - как с добрым утром :) Подделки? не думаю (с) :))))))
Просто это особенности работы флагов CCF\SCF, которые нафик никомуу не нужны, но все же эти особенности есть)
(Ну или проектировщики профиков совсем л.)
Вот ST-шка

https://drive.google.com/file/d/1N1hqDtChHKEXefJQmjR65ePOK4kgiB_k/view?usp=sharing
во первых другой паттерн, ну и точки белые, в правом квадрате побольше, слева - поменьще, но они есть.
И это не артефакты экрана . Это уже в памИтИ так :)

Spectramine
30.01.2022, 18:00
По идее он проверяет установку\снятие 3 и 5 флагов, если не путаю.
Вот только КАК он это делает - я плохо понимаю.

Он ничего не проверяет, он строит регулярную картинку по заданному алгоритму, берет младший байт текущего адреса, ксорит с регистром F после CCF, и выводит на экран.
Это не весь тест, а его фрагмент, так как неизвестно содержимое регистров D и HL. Похоже, в HL выставлен #4000, а в D маска, не дающая HL выйти за пределы 4кб области, типа $EF.
Если содержимое F после CCF нестабильно, на регулярной картинке будут мерцающие точки.


И да, это не для эмулей, они такое не могут эмулить.
Эмули могут всё сэмулить, была бы в этом необходимость. Раз на Zilog такого нет, я этим заниматься не буду)

Lethargeek
30.01.2022, 18:07
По идее он проверяет установку\снятие 3 и 5 флагов, если не путаю.
Вот только КАК он это делает - я плохо понимаю.
И да, это не для эмулей, они такое не могут эмулить. А вот на некоторых реальных процессорах красиво получается
https://drive.google.com/file/d/1lxI...ew?usp=sharing
Этого "мусора", в виде шевелящихся черных\белых точек - в эмулях не бывает.
эмули (программные) как раз могут, кто ж им запретит
нехт не может :p

Spectramine
30.01.2022, 18:11
Кстати, тут на форуме человек давно предполагал подобное поведение флагов 3 и 5 после CCF/SCF, но на реальные тесты его не хватило) Однако, на Зайлогах такой нестабильности не оказалось, что радует (меньше возни писателям эмулей :) ).

zebest
30.01.2022, 18:17
Новый тест Патрика проверяет разницу SCF\CCF у трех производителей, Zilog, ST, NEC. Мои процессоры (кроме Zilog и GS) ни в одну категорию не попадают. А именно NEC у меня и нет.

Spectramine
30.01.2022, 18:33
Новый тест Патрика проверяет разницу SCF\CCF у трех производителей, Zilog, ST, NEC. Мои процессоры (кроме Zilog и GS) ни в одну категорию не попадают. А именно NEC у меня и нет.

Не вижу особого смысла разбираться с поведением клонов Z80 на недокументированных фичах. Ибо там они могут плясать кто во что горазд.

- - - Добавлено - - -


Кстати, тут на форуме человек давно предполагал подобное поведение флагов 3 и 5 после CCF/SCF, но на реальные тесты его не хватило) Однако, на Зайлогах такой нестабильности не оказалось, что радует (меньше возни писателям эмулей :) ).

Ссылка (https://zx-pk.ru/threads/23797-testirovanie-emulyatorov.html?p=900366&viewfull=1#post900366) на то сообщение. Предполагается, что с понижением частоты проца его поведение для недокументированных флагов будет изменяться.

zebest
30.01.2022, 18:39
А никто никого и даже не просит разбираться. Колхоз - дело добровольное
https://s.micp.ru/E7yZL.jpg
и да, на картинках - два разных Зилог-а. Шах и мат.
И вполне ожидаемый "мусор" на втором зайлог-е
https://s.micp.ru/8rme9.jpg

Spectramine
30.01.2022, 18:47
https://s.micp.ru/E7yZL.jpg
и да, на картинках - два разных Зилог-а. Шах и мат.

А вот это уже печальнее. Т.е. даже для двух зайлогов поведение после SCF/CCF разное. Странно, что тест на одном зайлоге пропустил тесты для NEC и ST, а на другом полез в них.

Lethargeek
30.01.2022, 18:48
на картинках - два разных Зилог-а
два каких? у него же вроде нмоповский эталон


Странно, что тест на одном зайлоге пропустил тесты для NEC и ST, а на другом полез в них.
так потому и полез, что первые не прошли

Spectramine
30.01.2022, 18:49
Надо код теста смотреть, может, автор там где-то прерывания не выключил, и они вклинились в тест.

zebest
30.01.2022, 18:54
так потому и полез, что первые не прошли
Праавильно говоришь, прааавильно (с)
Первый к-моп, как ни странно, второй - н-моп.



Надо код теста смотреть
ну так смотри, Патрик свои тесты не прячет. Там правда асм непонятный, в чем его компилить. Но посмотреть всегда можно

Spectramine
30.01.2022, 18:55
и да, на картинках - два разных Зилог-а. Шах и мат.
И вполне ожидаемый "мусор" на втором зайлог-е
А кстати, тактовая у обоих зайлогов одинаковая или разная?

zebest
30.01.2022, 18:59
Это один и тот же Профи-к. Только процы поменял. Версия 5.05 от Олега. Или Олег плохо собрал?? Ай-яй-яй....

Spectramine
30.01.2022, 19:00
ну так смотри, Патрик свои тесты не прячет. Там правда асм непонятный, в чем его компилить. Но посмотреть всегда можно

И вполне ожидаемый "мусор" на втором зайлог-е

Если на втором зайлоге мусор, значит, смысла смотреть код нет, это точно нестабильность поведения проца.

- - - Добавлено - - -


Это один и тот же Профи-к. Только процы поменял. Версия 5.05 от Олега. Или Олег плохо собрал?? Ай-яй-яй....
А частота Профика стандартная или турбо?

zebest
30.01.2022, 19:10
стандартная, на турбо загрузка tap не работает.
Я еще думаю, что может подтяжка пул-ап по шине и на тактовой так влияет на поведение проциков. Разным - разная надо.
Ну и крайний вариант - Профи - не для тестов!!!

Spectramine
30.01.2022, 19:38
стандартная, на турбо загрузка tap не работает.
Я еще думаю, что может подтяжка пул-ап по шине и на тактовой так влияет на поведение проциков. Разным - разная надо.
Ну и крайний вариант - Профи - не для тестов!!!

Ну, нестабильность налицо, один проц работает как надо, второй по-другому. Не думаю, что обвязка проца влияет на его поведение внутри, хотя мало ли.

- - - Добавлено - - -

А вывод отсюда простой - особого смысла в эмуляции флагов 3/5 после CCF/SCF нет, так как стабильности в их поведении нет, даже для оригинальных процов(

- - - Добавлено - - -

Просьба к модераторам - перенести часть этой темы от этого сообщения (https://zx-pk.ru/threads/32014-tema-dlya-vsyakikh-glupykh-voprosov.html?p=1145644&viewfull=1#post1145644) до данного в эту тему (https://zx-pk.ru/threads/23797-testirovanie-emulyatorov.html)

zebest
30.01.2022, 19:44
Стабильность вполне возможно и есть, но эти флаги работают несколько по другому. Не так, как до сих пор думали. У Патрика есть уже на этот счет гипотеза :)
Ладно. Пустое это все. Прекращаем. Пойду пинать Патрика :)

Titus
30.01.2022, 19:50
А вывод отсюда простой - особого смысла в эмуляции флагов 3/5 после CCF/SCF нет, так как стабильности в их поведении нет, даже для оригинальных процов(
Реверс Z80 еще никто не сделал?