
Сообщение от
boo_boo
, в которой понадобиться наследовать от класса Z80, не могу представить
ну можно наследовать, переопределив виртуальные ф-ции чтения портов/памяти, но это не освобождает от вызова через указатель. надо не наследовать от класса Z80, а делать типа этого:
Код:
CUniversalZ80WithoutMemPorts<CSpectrumMem,CSpectrumPorts> MainZ80;
CUniversalZ80WithoutMemPorts<CSpectrumMemDbg,CSpectrumPortsDbg> MainZ80Dbg;
CUniversalZ80WithoutMemPorts<CGSMem,CGSPorts> gsZ80;
таких ядер легко можно наделать сколько надо, причём всё, что относится к памяти/портам будет заинлайнено. в принципе, в unreal 3 ядра. не знаю, стоит ли ради повышения скорости в отдельных случаях так сильно увеличивать размер конечного exe-шника. хотя, если теперь эмуляторы даже на жабе пишут, скоростью можно пожертвовать

Сообщение от
boo_boo
где можно прочитать про этот самый кэш? слабо себе представляю, кто он такой
журналы чёрн.ворона#3, dejavu#7. это статическое ОЗУ 2-16k, припаиваемое параллельно ПЗУ. имеется небольшая схемка, которая включает его вместо пзу (например, вместо TR-DOS, позволяя программе в этом кеше обращаться сразу и ко всей 48-й памяти, и к портам дисковода). если ОЗУ-шка маленькая (2-8k), то старшие линии адреса никуда не заводятся, поэтому запись в адрес #0111 "запишет" и в #0911,#1111,#1911,#2111,#2911,#3111,#3911...

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

Сообщение от
boo_boo
пару слов о том, как это в US сделано?
ядро Z80 увеличивает счётчик тактов cpu.t на нужную величину, вызывает функцию записи в порт (которая читает этот счётчик), и снова увеличивает cpu.t, в сумме эти приращения дадут время выполнения команды. если, как ты хочешь, совсем отказываться от глобальных переменных, придётся эти временные метки таскать как параметры:
например, в void step(Z80 *cpu, int64 &tick) передавать время начала, потом, например, в команде OTIR вызывать void port_out(cpu->bc, read_mem(cpu->hl), tick+16), а потом увеличивать tick на 21