Да, ты прав, такая эмуляция не вполне корректна![]()
Да, ты прав, такая эмуляция не вполне корректна![]()
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Давно уже пора полноценно эмулировать не только проц "изнутри" да юлу, но и шину (потактовое состояние). И всякие "девайсоплагины" будет проще прикручивать. Правда, эмуль тормознутый получится... но это ничего, у винтела дури хватает.![]()
Прихожу без разрешения, сею смерть и разрушение...
Потактово это конечно хорошо, да и дури хватит(а при хорошей архитектуре эмуля может и лучше будет), но вот инфы по интимным делам железа внутри команд надо будет ещё поискать...
попробую, глянем, сколько там у винтела дуриСообщение от Lethargeek
![]()
по каким "делам внутри команд"?Сообщение от NovaStorm
ну у тебя я не смотрел, сорцы-то закрытыСообщение от Vladimir Kladov
![]()
в zemu, в глюкалке с точностью до опкода ULA работает. в US все кошерно.
а у тебя как это реализовано? жестко на каждом такте дергается ULA, или как в US -- после записи в видеопамять/порт?
Интим - это например LDIR,условные переходы и вообще что-то более-менее "сложное". Порядок изменения этоми инструкциями регистров разнится на клонах Z80, да на разных по технологии изготовления Z80. Для точной эмуляции, нужно было бы выбирать конкретный проц.
Бездоказательно, весьма бездоказательно...Сообщение от NovaStorm
![]()
Я тут гонял zexall на нескольких эмуляторах z80 - результат удручающий. А он еще не самое полное тестирование проводит...Сообщение от Titus
Лучше сделать и жалеть, чем не сделать и жалеть.
Некоторые из моих поделок тут: https://github.com/serge-404
это только пресловутого MEMPTR касается, а с ним уже ясно все (http://zx.pk.ru/showpost.php?p=44058&postcount=150). насчет разных технологий и странных клонов ходят слухи, но конкретных экземпляров пока не выявлено. если у тебя есть -- давай сюдаСообщение от NovaStorm
![]()
конечно. но, к счастью с хардовым Z80 все куда приятнейСообщение от Error404
есть небольшая разница (см ссылку выше) но в целом один хрен
так что это скорей показатель недоделанности некоторых эмуляторов
у меня на асме написан код, который отвечает за декодирование ULA. Asm свой, но смысл понять можно.
это - код макросов для эмуляции задержек и ULA.
продолжение следует...Код://////////////////////////////////////////////////////////////////////////////// // // // //// // // // // // // // // // // // // // // // // // // //////// // // // // // ///////// //////////// // // //////////////////////////////////////////////////////////////////////////////// MC_VIDEO_SCREEN_READY MACRO // буфер заполнен, вывод экрана и другие действия MOV EAX, [VideoOutObj] // вывод экрана LEAVE_MMX PUSH ECX PUSH EAX XOR B[&ZX].Reg_F, flag_N XCHG D[MC_Screen_Buffer_Pos], EDI .IF AntiSlowDown and 0 MOV EDI, 71690+256 .ENDIF MOV D[&ZX].TactCount, EDI SUB D[&ZX].TactCount, $100 MOV [&ZX].Reg_PC, BX CALL VideoOutObj_FrameReady XCHG [MC_Screen_Buffer_Pos], EDI .IF Gfx256 MOV D[GfxVideoTarget], VideoOutObj_GfxPixels MOV D[ScreenAttrTarget], VideoOutObj_ScreenAttrs .ENDIF POP EAX MOV DL, 1 // ManageFlash = TRUE CALL VideoOutObj_ScreenReady POP ECX ENTER_MMX XOR EDI, EDI END //MC_VIDEO_SCREEN_READY //****************************************************************************** ULA_unit MACRO Flag=YES .IF MultiColor .IF AntiSlowDown CMP D[&ZX].AntiSlow_HaltDetected, 0 JZ @@ULA_antislow1_&& CMP D[&ZX].AntiSlow_HaltDetected, 8 JB @@ULA_antislow_end&& // halt detected, ... @@ULA_antislow1_&&: // нет halt'ов, только in-ы CMP EDI, 71680 JAE LONG @@ULA_end_all&& XCHG EDI, [MC_Screen_Buffer_Pos] CMP EDI, MC_Screen_Buffer_Size XCHG EDI, [MC_Screen_Buffer_Pos] JAE LONG @@ULA_end_all&& @@ULA_antislow_end&&: .ENDIF .IF PrepareVideo LEA ECX, [EDI-256] .IF UlaBuffer > 0 ADD ECX, UlaBuffer .ENDIF SUB ECX, [ULA_TCounter0] JLE LONG @@_ULA_end&& SHR ECX, 2 JZ LONG @@_ULA_end&& MOV EDX, ECX SHL EDX, 2 ADD [ULA_TCounter0], EDX // CL = число байтов для отображения > 0 XCHG EDI, [MC_Screen_Buffer_Pos] .IF "&Flag" = "YES" MOV [&ZX].Reg_F, AH // если будет вызван FrameReady, // то нужно текущее состояние Reg_F для TimeStamper-а .ENDIF PUSH EAX //-------------------------------------\ // цикл вывода байтов @@_ULAout_loop&&: .IF AntiSlowDown CMP EDI, MC_Screen_Buffer_Size JAE LONG @@_ULAfin&& .ENDIF // первым сохраняем текущий BorderColor и видеорежим MOV DL, [&ZX].BorderColor MOV DH, [&ZX].VideoMode MOV [EDI*4+2+MC_Screen_Buffer], DX .IF Gfx256 = 0 OR GfxDraw = 0 .IF GigaScreen MOV [EDI*4+2+MC_Screen_Buffer_Giga], DL //int 3 .ENDIF .ENDIF // продолжаем цепочку бордюра MOV DX, [&ZX].BorderColorNext MOV [&ZX].BorderColor, DX AND B[&ZX].BorderColorNxt2, $F .IF Gfx256 AND GfxDraw //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // в режиме мультиколора с включенным Gfx надо // пересылать Gfx-данные, которых в 8 раз больше MOVSX EAX, W[EDI*2+MC_Screen_Table_Pixels] //ADD EAX, EAX SHL EAX, 3 JS SHORT @@_ULA_8pixels_stored&& ADD EAX, [GFXVidAddress] // откуда брать 8 байтов XCHG ESI, EAX XCHG EDI, [GfxVideoTarget] MOVSD MOVSD XCHG EDI, [GfxVideoTarget] XCHG ESI, EAX // теперь нужен еще атрибут, хотя и Gfx-режим // берем байт атрибутов MOVZX EAX, W[EDI*2+MC_Screen_Table_Attrs] DEC EAX JZ LONG @@_ULA_8pixels_stored&& ADD EAX, [&ZX].VideoBaseAddr MOVZX EDX, B[EAX] MOV DH, [&ZX].Flash MOV AL, B[EDX+GfxAttrConvertTable] XCHG EDI, [ScreenAttrTarget] STOSB XCHG EDI, [ScreenAttrTarget] .ELSE Gfx256 = 0 OR GfxDraw = 0 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // берем байт атрибутов MOVZX EAX, W[EDI*2+MC_Screen_Table_Attrs] DEC EAX JZ LONG @@_ULA_8pixels_stored&& // проверяем эффект "снег" CMP B[&ZX].SnowEffect, 0 JZ SHORT @@_ULAload_data&& MOV AL, B[&ZX].TactRCount AND AL, $7F OR AL, [&ZX].Reg_R_7 ADD EAX, [&ZX].VideoBaseAddr MOVZX EDX, B[EAX] MOV DH, [&ZX].Flash MOV DL, B[EDX+AttrConvertTable] // берем очередной байт 8 пикселов MOVZX EAX, W[EDI*2+MC_Screen_Table_Pixels] MOV AL, B[&ZX].TactRCount AND AL, $7F OR AL, [&ZX].Reg_R_7 ADD EAX, [VideoBaseAddr] MOV DH, B[EAX] MOV W[EDI*4+MC_Screen_Buffer], DX JMP SHORT @@_ULA_8pixels_stored&& @@_ULAload_data&&: ADD EAX, [&ZX].VideoBaseAddr MOVZX EDX, B[EAX] MOV DH, [&ZX].Flash MOV DL, B[EDX+AttrConvertTable] // берем очередной байт 8 пикселов MOVZX EAX, W[EDI*2+MC_Screen_Table_Pixels] ADD EAX, [&ZX].VideoBaseAddr MOV DH, B[EAX] MOV W[EDI*4+MC_Screen_Buffer], DX .IF GigaScreen // для GigaScreen, то же самое для альтернативного экрана: MOVZX EAX, W[EDI*2+MC_Screen_Table_Attrs] DEC EAX JZ SHORT @@_ULA_8pixels_stored&& ADD EAX, [&ZX].AltVideoBaseAddr MOVZX EDX, B[EAX] MOV DH, [&ZX].Flash MOV DL, B[EDX+AttrConvertTable] // берем очередной байт 8 пикселов MOVZX EAX, W[EDI*2+MC_Screen_Table_Pixels] ADD EAX, [&ZX].AltVideoBaseAddr MOV DH, B[EAX] MOV W[EDI*4+MC_Screen_Buffer_Giga], DX .ENDIF //GigaScreen .ENDIF //not Gfx256 ~~~~~~~~~~~~~~~~~~~~~~~~~ @@_ULA_8pixels_stored&&: INC EDI .IF RZX_play = 0 CMP EDI, BytesInFrame JB LONG @@_ULAnext&& .IF AntiSlowDown // CMP BX, $4000 // JAE @@ULA_AntiSlow_ScreenReady&& // MC_VIDEO_SCREEN_READY //@@ULA_AntiSlow_ScreenReady&&: .ELSE MC_VIDEO_SCREEN_READY .ENDIF @@ULA_skipscreen&&: CMP B[&ZX].StopOnEndOfFrame, 0 JZ SHORT @@_ULAnext&& MOV D[&ZX].JumpPt, StopExec .ELSE CMP EDI, BytesInFrame JB SHORT @@_ULAnext&& DEC EDI .ENDIF RZX_play = 0 @@_ULAnext&&: DEC ECX JG @@_ULAout_loop&& //LOOP @@_ULAout_loop&& @@_ULAfin&&: POP EAX XCHG EDI, [MC_Screen_Buffer_Pos] // EDI = TactCounter+256 @@_ULA_end&&: .ELSE //not PrepareVideo LEA ECX, [EDI-256] .IF UlaBuffer > 0 ADD ECX, UlaBuffer .ENDIF SUB ECX, [ULA_TCounter0] JLE LONG @@_ULAnovideo_end&& SHR ECX, 2 JZ LONG @@_ULAnovideo_end&& MOV EDX, ECX SHL EDX, 2 ADD [ULA_TCounter0], EDX // CL = число байтов для "отображения" > 0 XCHG EDI, [MC_Screen_Buffer_Pos] .IF "&Flag" = "YES" MOV [&ZX].Reg_F, AH // если будет вызван FrameReady, // то нужно текущее состояние Reg_F для TimeStamper-а .ENDIF PUSH EAX //-------------------------------------\ // цикл вывода байтов @@_ULAnovideo_out_loop&&: INC EDI .IF RZX_play = 0 CMP EDI, BytesInFrame JB SHORT @@_ULAnovideo_next&& .IF AntiSlowDown // CMP EBX, $4000 // JAE @@ULA_AntiSlow_ScreenReady1_&& // MC_VIDEO_SCREEN_READY //@@ULA_AntiSlow_ScreenReady1_&&: .ELSE MC_VIDEO_SCREEN_READY .ENDIF CMP B[&ZX].StopOnEndOfFrame, 0 JZ SHORT @@_ULAnovideo_next&& MOV D[&ZX].JumpPt, StopExec .ELSE CMP EDI, BytesInFrame JB SHORT @@_ULAnovideo_next&& DEC EDI .ENDIF RZX_play = 0 @@_ULAnovideo_next&&: DEC ECX JG @@_ULAnovideo_out_loop&& //LOOP @@_ULAnovideo_out_loop&& POP EAX XCHG EDI, [MC_Screen_Buffer_Pos] // EDI = TactCounter+256 @@_ULAnovideo_end&&: .ENDIF //PrepareVideo @@ULA_end_all&&: .ENDIF //MultiColor END //ULA_unit
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)