продолжение про ULA в EmuZWin
макросы, продолжение:
Код:
//******************************************************************************
Delay MACRO Time, Mem, Temp=D
.IF MultiColor
.IF AntiSlowDown
CMP EDI, 71690
JB @@Delay1_&&
.IF &Time > 1
ADD EDI, &Time
.ELSEIF &Time = 1
INC EDI
.ENDIF
JMP SHORT @@DelayEnd&&
@@Delay1_&&:
.ENDIF
.IF NoDelay = 0
MOVZX E&Temp.X, &Mem.H
MOV &Temp.H, [&ZX].CurRAMBank
MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
ADD EDI, D[EDI*8+E&Temp.X+MC_Contended_Delay_Table]
.IF &Time > 2
ADD EDI, &Time-1
.ELSEIF &Time = 2
INC EDI
.ENDIF
.ELSE NoDelay
.IF &Time > 1
ADD EDI, &Time
.ELSEIF &Time = 1
INC EDI
.ENDIF
.ENDIF
.IF AntiSlowDown
@@DelayEnd&&:
.ENDIF
.ENDIF
END //MACRO Delay
//******************************************************************************
DelayMore MACRO Time=1, Temp=D, Count=1
.IF MultiColor
.IF AntiSlowDown
CMP EDI, 71690
JB @@DelayMore1_&&
.IF &Time * &Count > 1
ADD EDI, &Time * &Count
.ELSEIF &Time * &Count = 1
INC EDI
.ENDIF
JMP SHORT @@DelayMoreEnd&&
@@DelayMore1_&&:
.ENDIF
.IF NoDelay = 0
.REPEAT &Count
ADD EDI, D[EDI*8+E&Temp.X+MC_Contended_Delay_Table]
.IF &Time > 2
ADD EDI, &Time-1
.ELSEIF &Time = 2
INC EDI
.ENDIF
.ENDREP
.ELSE NoDelay
.IF &Time * &Count > 1
ADD EDI, &Time * &Count
.ELSEIF &Time * &Count = 1
INC EDI
.ENDIF
.ENDIF
.IF AntiSlowDown
@@DelayMoreEnd&&:
.ENDIF
.ENDIF
END //MACRO DelayMore
//******************************************************************************
outDelay MACRO Port, Temp=D, io=
.IF MultiColor
.IF NoDelay = 0
.IF "&io" = ""
//--------------
MOVZX EDX, &Port.H
MOV &Temp.H, [&ZX].CurRAMBank
MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
TEST &Port.L, 1
JZ SHORT @@_outFE&&
// N:4 or C:1 C:1 C:1 C:1
XOR &Temp.L, 4
JNZ SHORT @@_outN4&&
.IF AntiSlowDown
CMP EDI, 71690
JB @@outDelay1_&&
ADD EDI, 4
JMP SHORT @@_outN4&&
@@outDelay1_&&:
.ENDIF
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
@@_outN4&&:
ADD EDI, E&Temp.X
JMP SHORT @@_end_out_contention&&
@@_outFE&&:
xor &Temp.L, 4
JNZ SHORT @@_outN1C3_&&
.IF AntiSlowDown
CMP EDI, 71690
JAE @@_outN1C3_&&
.ENDIF
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
DEC EDI
@@_outN1C3_&&:
INC EDI
.IF AntiSlowDown
CMP EDI, 71690
JB @@outDelay3_&&
ADD EDI, 3
JMP SHORT @@_end_out_contention&&
@@outDelay3_&&:
.ENDIF
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, 3-1
@@_end_out_contention&&:
//--------------
.ELSE
//--------------
.IF AntiSlowDown
CMP EDI, 71690
JAE @@outDelay5&&
.ENDIF
MOVZX E&Temp.X, &Port.H
MOV &Temp.H, [&ZX].CurRAMBank
MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
TEST &Port.L, 1
JNZ SHORT @@outDelay4&&
MOV &Temp.L, 4
@@outDelay4&&:
ADD EDI, D[EDI*8+E&Temp.X+MC_Contended_Delay_Table]
ADD EDI, &io-1
@@outDelay5&&:
//--------------
.ENDIF
.ELSE NoDelay
.IF "&io" = ""
ADD EDI, 4
.ELSEIF &io > 1
ADD EDI, &io
.ELSEIF &io = 1
INC EDI
.ENDIF
.ENDIF
.ENDIF //MultiColor
END //MACRO outDelay
//******************************************************************************
inDelay MACRO Port, Temp=D
.IF MultiColor <> 0
.IF NoDelay = 0
MOVZX E&Temp.X, &Port.H
MOV &Temp.H, [&ZX].CurRAMBank
MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
TEST &Port.L, 1
JZ SHORT @@_inFE&&
// bit 0 of port addr set - N:4 or C:1 C:1 C:1 C:1
XOR &Temp.L, 4
JNZ SHORT @@_inN4&&
.IF AntiSlowDown
CMP EDI, 71690
JB @@inDelay1_&&
ADD EDI, 4
JMP SHORT @@_inN4&&
@@inDelay1_&&:
.ENDIF
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
@@_inN4&&:
ADD EDI, E&Temp.X
JMP SHORT @@_end_in_contention&&
@@_inFE&&:
.IF AntiSlowDown
CMP EDI, 71690
JAE @@_end_in_contention&&
.ENDIF
XOR &Temp.L, 4
JnZ SHORT @@_inN1C3_&&
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
DEC EDI
@@_inN1C3_&&:
INC EDI
ADD EDI, D[EDI*8+4+MC_Contended_Delay_Table]
ADD EDI, 3-1
@@_end_in_contention&&:
.ELSE NoDelay
ADD EDI, 4
.ENDIF
.ENDIF //MultiColor
//--------------
END //MACRO inDelay
//******************************************************************************
ioDelay MACRO Port, Temp
.IF MultiColor
.IF NoDelay = 0
.IF AntiSlowDown
CMP EDI, 71690
JAE @@ioDelayEnd&&
.ENDIF
MOVZX E&Temp.X, &Port.H
MOV &Temp.H, [&ZX].CurRAMBank
MOVZX E&Temp.X, B[E&Temp.X+MC_Contended_Mem_Table]
TEST &Port.L, 1
JNZ SHORT @@ioDelay1_&&
MOV &Temp.L, 4
@@ioDelay1_&&:
ADD EDI, D[EDI*8+ECX+MC_Contended_Delay_Table]
.IF AntiSlowDown
@@ioDelayEnd&&:
.ENDIF
.ELSE NoDelay
//ADD EDI, 4
.ENDIF
.ENDIF
END //MACRO ioDelay
и еще чуть-чуть...
ULA в EMUZWin, продолжение. Часть 3
А вот это - реализация команд LDI/LDIR/LDD/LDDR. Разберитесь, если есть желание.
Код:
@@_ld&direction.r: // LDIR, LDDR
.IF (FastLDIR <> 0) and ("&LDIRHL" <> "")
CMP B[&ZX].DebuggerVisible, 0
JNZ @@_ld&direction.r_usual
MOVZX ECX, W[&ZX].Regs.Reg_BC
DEC ECX
JZ @@_ld&direction.r_usual
MOVZX EDX, W[&ZX].Regs.Reg_DE
MOV ECX, EBX
DEC CX
CMP CX, DX
JZ @@_ld&direction.r_usual
.if MemPtrNew
MOV [&ZX].reg_Hidden, CH
.endif
DEC CX
CMP CX, DX
JZ @@_ld&direction.r_usual
MOV EBX, ECX
PUSH EAX
.IF "&LDIRHL" = "BX"
PUSH EBX
.ENDIF
MOVZX &ELDIRHL, W[&ZX].Regs.Reg_HL
.IF GeneralSnd
ADD D[&ZX].TStatesToExecute, 16
.ENDIF
.IF MultiColor
MOV [&ZX].TempFlip, EDI
ADD D[&ZX].TempFlip, 256
.ENDIF
JMP SHORT @@_ld&direction.r_fast_next
@@_ld&direction.r_fast_loop:
.IF RZX_play
ADD D[&ZX].NumFetches, 2
.ELSEIF GeneralSnd
INC D[&ZX].NumFetches
.ENDIF
.IF MultiColor
ADD B[&ZX].TactRCount, 2
.IF NoDelay
ADD EDI, 8
.ELSEIF "&LDIRHL" = "BX"
POP EAX
PUSH EAX
Delay Time=4, Mem=A, Temp=C
INC AX
Delay Time=4, Mem=A, Temp=C
.ELSE
Delay Time=4, Mem=B, Temp=C
INC BX
Delay Time=4, Mem=B, Temp=C
DEC BX
.ENDIF
.ELSEIF MultiColor = 0
ADD D[&ZX].TactRCount, $100002
AND W[&ZX].TactRCount, $7F
.ENDIF
@@_ld&direction.r_fast_next:
.IF "&LDIRHL" = "BX"
Delay Time=3, Mem=B, Temp=C
GetMem1 Dest=AL, Addr=B, Temp=C, Gfx=mm0
.ELSE
MOV EAX, &ELDIRHL
Delay Time=3, Mem=A, Temp=C
GetMem1 Dest=AL, Addr=A, Temp=C, Gfx=mm0
.ENDIF
.IF Plus3 or NoDelay
Delay Time=5, Mem=D, Temp=C // задержка DE wr:5
.ELSE
Delay Time=3, Mem=D, Temp=C // задержка DE wr:3
DelayMore Temp=C, Count=2
.ENDIF
PutMem Addr=D, Reg=AL, Temp=C, Gfx=mm0
DEC W[&ZX].Regs.Reg_BC
JZ @@_ld&direction.r_fast_end_incRegs
.IF "&direction" = "i"
INC DX
INC &LDIRHL
.IF "&LDIRHL" = "BX"
CMP DX, [ESP]
.ELSE
AND &ELDIRHL, $FFFF
CMP DX, BX
.ENDIF
JZ SHORT @@_ld&direction.r_fast_fin
.IF MultiColor
CMP EDI, 60000
JGE SHORT @@_ld&direction.r_fast_fin
.ENDIF
.ELSE
DEC DX
DEC &LDIRHL
DEC DX
.IF "&LDIRHL" = "BX"
CMP DX, [ESP]
.ELSE
AND &ELDIRHL, $FFFF
CMP DX, BX
.ENDIF
JZ SHORT @@_ld&direction.r_fast_fin_INCDX
.IF MultiColor
CMP EDI, 60000
JGE SHORT @@_ld&direction.r_fast_fin_INCDX
.ENDIF
INC DX
.ENDIF
.IF MultiColor = 0
ADD W[&ZX].TactRCount + 2, 5
JS SHORT @@_ld&direction.r_fast_fin
.ELSE
.IF Plus3 or NoDelay
Delay Time=5, Mem=D, Temp=C // дополнительно 5 задержек DE:1
.ELSE
Delay Time=1, Mem=D, Temp=C // дополнительно 5 задержек DE:1
DelayMore Temp=C, Count=4
.ENDIF
.ENDIF
.IF GeneralSnd
SUB [&ZX].TStatesToExecute, 21
CMP [&ZX].TStatesToExecute, 21
JG @@_ld&direction.r_fast_loop
MOV ECX, [&ZX].NumFetches
CMP ECX, [&ZX].MaxFetches
JGE @@_ld&direction.r_fast_fin
.ELSEIF RZX_play
MOV ECX, [&ZX].NumFetches
CMP ECX, [&ZX].MaxFetches
JGE @@_ld&direction.r_fast_fin
.IF MultiColor
CMP B[EDI+MC_IntSignal_Table], 0
JNZ SHORT @@_ld&direction.r_fast_fin
.ENDIF
.ELSE
.IF MultiColor
CMP B[EDI+MC_IntSignal_Table], 0
JNZ SHORT @@_ld&direction.r_fast_fin
CMP EDI, [&ZX].TempFlip
JGE SHORT @@_ld&direction.r_fast_fin
.ELSE
.ENDIF
.ENDIF
JMP LONG @@_ld&direction.r_fast_loop
@@_ld&direction.r_fast_fin_INCDX:
INC DX
@@_ld&direction.r_fast_fin: // завершаем цикл быстрого LDIR по разным причинам,
// кроме исчерпания Reg_BC
MOV ECX, &ELDIRHL
MOV [&ZX].Regs.Reg_HL, CX
MOV [&ZX].Regs.Reg_DE, DX
.IF "&LDIRHL" = "BX"
POP EBX
.ENDIF
POP ECX
MOV AH, CH
ADD AL, [&ZX].Reg_A // !!! формируем флажки X и Y !!!
.IF LDIR_BY_TABLE
AND EAX, $FFFF
MOV AX, W[EAX*2+Table_LDIR1]
.ELSE
// !!! формируем флажки X и Y !!!
MOV CL, AL
AND CL, 2
SAL CL, 4
AND AL, $F
OR AL, CL //-------------------------------
AND AH, not flag_H
.ENDIF
OR AH, flag_N or flag_P
NextInstr
@@_ld&direction.r_fast_end_incRegs: // завершение быстрого LDIR по исчерпании Reg_BC
.IF "&direction" = "i"
INC DX
INC &LDIRHL
.ELSE
DEC DX
DEC &LDIRHL
.ENDIF
@@_ld&direction.r_fast_end: // завершение быстрого LDIR по исчерпании Reg_BC
.IF GeneralSnd
ADD D[&ZX].TStatesToExecute, 5
.ENDIF
MOV ECX, &ELDIRHL
MOV [&ZX].Regs.Reg_HL, CX
MOV [&ZX].Regs.Reg_DE, DX
.IF "&LDIRHL" = "BX"
POP EBX
.ENDIF
POP ECX
MOV AH, CH
ADD AL, [&ZX].Reg_A // !!! формируем флажки X и Y !!!
.IF LDIR_BY_TABLE
AND EAX, $FFFF
MOV AX, W[EAX*2+Table_LDIR1]
.ELSE
// !!! формируем флажки X и Y !!!
MOV CL, AL
AND CL, 2
SAL CL, 4
AND AL, $F
OR AL, CL //-------------------------------
AND AH, not (flag_P or flag_H)
.ENDIF
OR AH, flag_N
INC BX
INC BX
NextInstr
.ENDIF
@@_ld&direction.r_usual:
INC_TactRCount Value=5, ReturnTStates=16, ReturnPC=2, ReturnR=2, ReturnFetches=1
MOVZX ECX, W[&ZX].Regs.reg_HL
Delay Time=3, Mem=C // задержка HL:3
GetMem1 Dest=AL, Addr=C, Gfx=mm0
MOVZX ECX, W[&ZX].Regs.reg_DE
.IF Plus3 or NoDelay
Delay Time=5, Mem=C // задержка DE wr:5
.ELSE
Delay Time=3, Mem=C // задержка DE wr:3
DelayMore Count=2
.ENDIF
PutMem Addr=C, Reg=AL, Gfx=mm0
ADD AL, [&ZX].Reg_A // !!! формируем флажки X и Y !!!
.IF LDIR_BY_TABLE
AND EAX, $FFFF
MOV AX, W[EAX*2+Table_LDIR1]
.ELSE
// !!! формируем флажки X и Y !!!
MOV CL, AL
AND CL, 2
SAL CL, 4
AND AL, $F
OR AL, CL //-------------------------------
AND AH, not (flag_P or flag_H)
OR AH, flag_N
.ENDIF
MOVZX EDX, W[&ZX].Regs.reg_DE
.IF "&direction" = "i"
INC W[&ZX].Regs.reg_HL
INC W[&ZX].Regs.reg_DE
.ELSE
DEC W[&ZX].Regs.reg_HL
DEC W[&ZX].Regs.reg_DE
.ENDIF
DEC W[&ZX].Regs.reg_BC
JZ SHORT @@ld&direction.r_exit
.IF Plus3 or NoDelay
Delay Time=5, Mem=D // дополнительно 5 задержек DE:1
.ELSE
Delay Time=1, Mem=D // дополнительно 5 задержек DE:1
DelayMore Count=4
.ENDIF
OR AH, flag_P
DEC BX
.if MemPtrNew
MOV [&ZX].reg_Hidden, BH
.endif
DEC BX
@@ld&direction.r_exit:
NextInstr
.ENDFOR //direction
я жебил, я не шерхан, хавал жёваны штаны...