Тяжела и неказиста жизнь советского артиста (c) Для начала сделать бы клавиатуру и видео...
Тяжела и неказиста жизнь советского артиста (c) Для начала сделать бы клавиатуру и видео...
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
В комментарии к исходникам упоминается нечто по имени ИНТЕК. Что это?
Код:; -- таблица клавиш для ИНТЕК ( по новому ГОСТу ) ; бит 7 - признак необходимости инвертирования SHIFT ;---------------------------------------------------------------------------- ; ------------нет спецсимволов--- SHIFT1 ----SHIFT2-----позиция в матрице-- ; ИНТЕК ПОИСК LN_KEY1 DB 80H+09H, 04H, 80H+29H ; 1/12 1 4/7
На досуге ковырялся с PCem... Хочется все-таки сделать эмулятор с соблюдением тактов 8088, чтоб по скорости было максимально похоже на Поиск. Ну и чтоб работал "честно", то есть рисовал все символы программно, как это делает реал.
Пытался впилить в него обработку NMI. BTW, обработки NMI практически ни у кого нет, ни у fake86, ни у PCE. Вообще, хорошо если TRAP (int 1) обрабатывают, некоторые и на него забивают. Ввел несколько переменных и флагов:
Дальше vid_cga.c. Откуда-то скопипастил такую процедуру установки графического режима в CGA через порты. В качестве аргумента (mode) - 0x1E это по идее 640x400, 0x2E - это 320x200.Код:// POISK variables uint16_t p28h; // port 28 value uint8_t nmi_enabled; // NMI enabled ? uint8_t nmi_int_now=0; // force NMI uint8_t in_nmi=0; // in NMI? uint8_t p6Ah,p68h; // port 6Ah and port 68h
Процедура обработки порта 68. Смотрит, не сменился ли режим, если сменился - устанавливает новый. Также устанавливает флаг разрешения или запрещения NMI.Код:static int mode_graph[] = {0x38, 0x28, 0x2D, 0x0A, 0x7F, 0x06, 0x64, 0x70, 2, 1, 6, 7,0, 0, 0, 0}; void set_poisk_mode(uint8_t mode) #define MODE_REG 0x3d8 #define VID_DISABLE 0 #define ADDRESS_REG 0x3d4 #define REGISTER_PORT 0x3d5 { int loop_count = 0; cga_out(MODE_REG,VID_DISABLE); /*disable video signal */ for( ; loop_count < 0x0e; ++loop_count) { cga_out( ADDRESS_REG, loop_count ); /* set up CRT register */ cga_out( REGISTER_PORT, mode_graph[loop_count]); /* write to reg */ } cga_out( MODE_REG, mode); /* switch in mode now */; }
При возникновении NMI в порт 28 должно находится смещение, куда произошла запись:Код:void poisk_out(uint16_t addr, uint8_t val) { uint8_t b; uint8_t tmp_b; switch (addr) { case 0x68: p68h = val; b = 0x2e; //320x200 if (val & 0x80) b = 0x1e; //hires if (poisk_mode != b) { poisk_mode = b; set_poisk_mode(b); pclog("POISK set mode %02X: \n",b); } if (!(val & 8)) { nmi_enabled = 1; pclog("[poisk] NMI enable\n"); } else { nmi_enabled = 0; pclog("[poisk] NMI disable\n"); } pclog("POISK 68h value: %02X cgamode: %02X cgacol: %02X\n",val,tmp_b,b); return; case 0x6A: p6Ah = val; val = p68h; // TO DO: return; } } uint8_t poisk_in(uint16_t addr) { switch (addr) { case 0x68: return p68h; case 0x6A: return p6Ah; } return 0xFF; }
Дальше, установил новые хендлеры для портов:Код:uint16_t p28h_in(uint16_t addr) { switch (addr) { case 0x28: { pclog("[poisk] IN 0x28h = %04X\n",(p28h) & 0xFF); return ((p28h) & 0xFF); } case 0x29: { pclog("[poisk] IN 0x29h = %04X\n",(p28h>>8) & 0xFF); return ((p28h>>8) & 0xFF); } } }
Если что-то пишет в видео-память, проверить разрешены ли NMI, если разрешены - запомнить смещение куда произошла запись (для обработки 28 порта) и установить флаг вызова NMI.Код:io_sethandler(0x0068, 0x0002, poisk_in, NULL, NULL, poisk_out, NULL, NULL); io_sethandler(0x006A, 0x0002, poisk_in, NULL, NULL, poisk_out, NULL, NULL); io_sethandler(0x0028, 0x0002, p28h_in, NULL, NULL, NULL, NULL, NULL);
Дальше в x86.c обработку NMI сделал по аналогии обработки IRQ с PIC, вставил такой текст:Код:void cga_write(uint32_t addr, uint8_t val) { // pclog("CGA_WRITE %04X %02X\n", addr, val); vram[addr&0x3FFF]=val; charbuffer[ ((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc] = val; charbuffer[(((int)(((dispontime - vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; cycles -= 4; p28h = addr&0x3FFF; if (nmi_enabled == 1) { flags&=~I_FLAG; nmi_int_now = 1; } }
Пока результата никакого.Код:if (nmi_int_now && !in_nmi && !ssegs && !noint) // NMI interrupt { pclog("NMI INT NOW\n"); //if (ssegs) ss=oldss; // if (inhlt) pc++; writememw(ss,((SP-2)&0xFFFF),flags|0xF000); writememw(ss,((SP-4)&0xFFFF),CS); writememw(ss,((SP-6)&0xFFFF),pc); SP-=6; addr=2<<2; flags&=~I_FLAG; flags&=~T_FLAG; pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); FETCHCLEAR(); inint=1; nmi_int_now=0; in_nmi=1; cycles-=72; }
Tronix, огромное Вам спасибо за habrapost!
LodeDome: http://lodedome.no-ip.com/lodedome.php - Lode Runner 2010 Game Archive. KryoFlux, FluxEngine, Gotek boards
Ищу пересылкой любые (неисправные/дефективные/некомплектные) платы и узлы корпуса Электроники-85 (МС-0585); дискеты 5,25".
По_трошки: Поиск, УКНЦ, БК0010, МС1502, П-н 128, Вектор 06Ц, C64, MAC LC475, Львов ПК-01, ДВК-3Ш (ВМ2, ВМ3, MX, MY, КСМ, КЦГД, КТлК, MY4)
Контакты: скайп: ana-sana, почта: [email protected], email: [email protected], TG: https://t.me/adesodesa
Предлагаю не распылять усилия и пилить таки MESS, в нем заметно больше готовых запчастей.
Пока что безуспешно борюсь с эмуляцией клавиатуры -- алфавитные клавиши работают нормально, но прочие посылают весьма странные сканкоды.
Кто-нибудь помнит, как выглядел 4-тый нортон на Поиске? С цветами не совсем понятно. У меня в эмуляторе получилось вот так:
Последний раз редактировалось b2m; 22.11.2013 в 23:31.
Привет!
Вместо Зелёного берюзовый!!!
Последний раз редактировалось Sonic_Blast; 24.11.2013 в 13:29.
Да, если смотреть на палитру 1 в графическом режиме это цвет cyan (0x01), или light cyan
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)