ZXNet эхоконференция «zxnet.pc»


тема: ULA в EmuzWin



от: Владимир Кладов
кому: All
дата: 19 Jan 2007
Hello, boo_boo у меня на асме написан код, который отвечает за декодирование ULA. Asm свой, но смысл понять можно. это - код макросов для эмуляции задержек и ULA. ┌─- CODE ─── /////////////////////////////////////////////////////////////////////////////// / // // // //// // // // // // // // // // // // // // // // // // // //////// // // // // // ///////// //////////// // // /////////////////////////////////////////////////////////////////////////////// / 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 //-------------------------------------\n // цикл вывода байтов @@_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 //-------------------------------------\n // цикл вывода байтов @@_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 └── CODE ─── продолжение следует...




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Coding - Описание программы AntiRST8 (для ZS256).
Железо - дешифратор для кабельного TV.
Обзор новинок - 12 тайных книг (demo).
СС'99 - интервью: Volga Soft.
Scene - interview: интервью с Минским художником Surfin Bird.

В этот день...   8 мая