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 ───
продолжение следует...




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

Похожие статьи:
scene - краткий отчёт о millennium'1902.
cc'000 - GFX COMPO: Взгляд со стороны простого деревенского парня.
Инфекционные болезни - Специально для Владимира Кладова погрязшего в фоменковщине немного вырезок об инфекционных болезнях в Европе и России.
Интервью - Интервью с музыкантом X-Raizor из Omega Hackers Group.
Новинка - Компьютер "Спринтер" 97.

В этот день...   19 апреля