CODING-2. EMULATORS MUST DIE!
(C) 1998 ALK / Stars of Keladan
Here lived ... Emulators on resettlement! So what? Progs
fail became less frequent? - No. It's just over there -
"Programs for MS-DOS (R) have run faster and more reliable.
"Here's to launch a thread boot from a floppy disk and
avtoopredelitelem kranty ... I'm really not talking about demos
;) Emulators they turn into some kind of sucks! Therefore,
declare instead of an epigraph:
"A good emulsion - emulsion
recognized!"
For knowing that you're in the emulator, you can disable
the part of procedures, etc., can all go on the principle -
such as: "I do not want work on this sludge - went on ... "As
the program determines that it operates under the emulator?
Very simple ... I tell you to confidence, any emulator is
buggy. Need and just something - to recognize where the glitch,
but the truth ...
To date I know of eight bugs, measurable recognition. Turn
to their description:
<---- --->
1. "Gluck boundaries of memory"
Theory: Invalid command execution LD NN, (# FFFF)
Emulator: UKV Debugger (Uglekov)
Comments: The dubious value, since I know only
an emulator with the glitches, but it impacts
these commands is much more grim (see below). Can
used as a defense ... I suspect that one of
demo-releases Black Crow and was ...
LD HL, # FFFF
LD E, (HL)
INC HL
LD D, (HL)
LD HL, (# FFFF); <= This is where UKV and breakup,
, However, if installed QEMM386 or EMM,
, Then not only UKV, general PC hangs!
; That's Spectrum _legko_ can do
; Must die "calculator";)
OR A
SBC HL, DE
JP NZ, EMUL; Here and below the transition to a label
EMUL
; Mean a positive result
; Determine emulator
....
Postkommentary: writes on this subject the author himself
(Uglekov): "Teams such as LD HL, (FFFF) is not performed
correctly always (or rather, always, but not on all machines,
but from it is not easier). Almost certainly will work properly
in this configuration: 386 CPU + EMM386 is either
no driver EMM. Driver QEMM does not allow you to perform
commands such as LD HL, (FFFF) for sure. With 286 processor,
the situation worse - I have these commands are always hung up
the emulator (though tested on only one machine). "
That such things ...
<---- --->
2. Emulation Register regeneration R "
Theory: Incorrect emulation register R
Emulator: Z80 (version LUNTER), UKV
Comments: The Z80 and UKV has options to disable the emulation
of R, which greatly improves the "power" virtual Spectrum,
therefore, if those disabled, then this fact will be
established. Just in case is also verified the correctness of
emulation MSB R - He should not be changed. Little if any
emulators might be?
DI
LD A, # 7F
LD R, A
LD A, R
DEC A
JP NZ, EMUL
; Second check is needed only for older
; Bit R - checked first zero value,
And now - the unit.
LD A, # 81
LD R, A
LD A, R
CP # 81
JP NZ, EMUL
....
<---- --->
3. "Self-destruction team LDIR"
Theory: A rough emulation commands LDIR, LDDR
Emulator: Z80, UKV (navernoe. .. do not remember exactly)
Comments: The Z80 does not correctly handle command block
operations. There is, for example, LDIR holds up
one pass, "ie, the processor extracts the operation code (two
bytes), then executes the command, and then moves to the next.
In reality (even in books Rodionova / Larchenko about it
written!) Performance LDIR / LDDR runs cyclically - in front of
every shipment processor reads the operation code. If you
configure parameters in the HL, DE and BC so that LDIR filled
area of memory in which he himself is, for example, zeros,
then the real-Z80 execution LDIR happen early - to destroy the
team, rather its "half" prefix # ED, and then "earn" the other
half (# B0 = OR B). Naturally, after that no LDIRa
will not.
MEMTST EQU # 4000
LD HL, CNTLDR
LD DE, MEMTST
LD BC, 3 + ELDR-CNTLDR
PUSH DE
LDIR; We transfer tests the fragment in the
"unnecessary"
; Place (for multiple testing)
RET; pass the test
CNTLDR LD HL, MEMTST
LD DE, MEMTST +1
LD BC, ELDR-CNTLDR-1; length is taken in such a way
; To a glyukavom emulator "been killed" transition team
; JP NO_LDR - output, if the real Z80
LD (HL), 0
LDIR
JP NO_LDR; as a result of the emulator after LDIR
, Holds three NOP and we know that we have the emulsion.
ELDR JP EMUL
NO_LDR ....
<---- --->
4. "Gluck OUT (C), R"
Theory: Teams OUT (C), R in an emulator change a flag register
F. Emulator: Z80
Comments: Actually, I never would have had not guessed, learned
about it from MAXSOFT'a, so that: (C) MAXSOFT / Speed Co /
XTM. C characteristic manifestation of Gluck can meet zapistiv
under LUNTER Z80 one Ukrainian boot (sort of like on SVS'a)
where window in the center, and the screen mesh fly, every time
different ...
LD C, # FE; so as not to torment the beast, take a
harmless
; Port for execution
XOR A
LD L, A
LD H, A
PUSH HL
POP AF; totally cleanse AF
OUT (C), A
PUSH AF
POP DE; remember the "dirty" F to E
CP E; compare
JP NZ, EMUL
And the second step: check on reset bits in F
, And all because of that lazy to pull the source
; On the Z80 - here and check all the bits of F for all
And changes; (
LD L, # FF
PUSH HL
POP AF
OUT (C), A
PUSH AF
POP DE
INC E
JP NZ, EMUL
....
<---- --->
5. "Point intercept TR-DOS"
Theory: In the emulator UKV specific entry points in TR-DOS
replaced by a mask.
Emulator: UKV
Comments: To work more effectively with floppy emulator
not to "steam" with each command TR-DOS, replace parts
perform specific procedures on their own, native PC-shnye. A
emulator learns about it on the fact that in "his" TR-DOSe the
points intercept placed masks - Bytes # 49. Author's words:
"The locus TEST, SEEK1, SEEK2, RDWR, FORMAT, RESET emulator
puts the byte 49h (LD C, C), and right behind him - the team
RET "
Attention! Before you test the TR-DOS, check
presence of the 'TR-DOS! Not all emulators are written by
Beta-Disk Interface!
LD HL, # 2A53
CALL DOSRD; see below ... read 16 bytes from # 2A53 at
# 5CDD
LD HL, (# 5CDD)
LD DE, # 79ED
OR A
SBC HL, DE
JR NZ, E_DST; since I was in the scrap to calculate the
points for
, Version 5.01, check the TR-DOS to version 5.03 and
its clones.
; At # 2A53 (the most used procedure;)) in 5.3
; Is OUT (C), A. If not, then do not despair - write
; Own case for 5.1
LD HL, # 801
CALL DOSRD
CP # 1C
JP Z, EMUL; at the same time check-ka team AND # 1F -
in the Z80 ; Emulsion there is AND # 1C. According to
the author's revised
; V.A.Mochalina / Vitasoft, it is necessary to:
;"... If you give any - any command (such as "CAT")
; After initializing the drive, then unprotected from
; Recording drive will be formatted in a separate line.
; To get rid of it, had to change one byte
; In the system at 801 HEX (was 0FCh, and therefore 1Ch)
; For versions 5.03 and 5.04T ... "
; (Excerpt from the description Z80TRDOS)
LD HL, # 3DAD; well as on the conveyor ...
CALL DOSRD
JP Z, EMUL
LD HL, # 3EB5
CALL DOSRD
JP Z, EMUL
LD HL, # 1FFD
CALL DOSRD
JP Z, EMUL
....
DOSRD LD C, # 1913
IM 1
CALL # 3D13; reading TR-DOS ROM by itself TR-DOS
DI
LD A, (# 5CDD)
CP # 49, here she comes, this notorious test
RET
<---- --->
6. "Gluck speed OUT (C), R"
Theory: The command OUT (C), R is performed with a different
time for different values of the port in BC
Emulator: SHALAEV. So get to it, then all rodimogo.A
Z80 yes UKV ...
Comment: I stumbled across this bug myself, so the copyright
(C) ALK / SoK. In general, of course, external devices are
emulated differently, and therefore time for them is different.
And what interesting - even if in the emulator to connect the
addition TIMES.ADD, and which is needed to ensure stability
relative speed (the number of cycles between
interrupts), then in this case, the OUT (C), R is still
different!
If this addition to the emulsion Shalaeva disabled, and then
this trap works - in this case strongly, "walking" speed
the same teams (not even OUTy).
CALL INIINT; procedure itself, see the last example
; Established IM 2, table interrupt # 8000 - # 8101
; HL points to the alleged obrabot.preryvany
, At # 8181
LD DE, EXTOUT
LD (HL), # C3; <= there establish JP EXTOUT
INC HL
LD (HL), E
INC HL
LD (HL), D
LD BC, # BFFD
XOR A
CALL CHKZL2; measures the number of cycles in one
; Aborting the command OUT (# BFFD), 0
; Who do not know - data register AY - in SHALAEVe is
PUSH HL; remember the number of cycles
LD BC, # 7FFD
LD A, # 10
CALL CHKZL2; the same thing for the team done a
; OUT (# 7FFD), # 10
; Who do not know - I'm not to blame;)
PUSH HL; similarly to remember
LD HL, TSOUT2
CALL CHKZL; and finally, the "control" measurement
equivalent
; OUT (C), A time-piece of the 3 NOP (12 cycles)
EX DE, HL; DE - check number
POP HL; count for OUT (# 7FFD), # 10
CALL CHEK_E1; comparison of "mod"
POP HL; count for OUT (# BFFD), 0
JP NC, EMUL
CALL CHEK_E1
JP NC, EMUL
.....
.....
EXTOUT POP AF; This is the type that the handler is in fact
LD A, # C9; trap to exit the infinite loop
; Triggered once
LD (# 8181), A; RET aims to Rec.
EX DE, HL
RET
CHKZL2 LD HL, TSOUT1; address to test OUT
CHKZL LD DE, 1
PUSH AF
LD A, # C9
LD (# 8181), A
LD A, # C3
EI
HALT
EI
HALT; "stabilization" HALTy
LD (# 8181), A; JP puts on a pseudo-handler
POP AF
EI
JP (HL)
TSOUT1 OUT (C), A; in DE accumulated result
INC DE
JP (HL); HL = TSOUT1
TSOUT2 NOP
NOP
NOP
INC DE
JP (HL); HL = TSOUT2
CHEK_E1 OR A; comparison of results
SBC HL, DE
JR NC, NNG1
LD A, H; In general, if something less than something
, Then give the difference to a positive number
; Similar design will still meet on ...
CPL
LD H, A
LD A, L
CPL
LD L, A
INC HL
OR A
NNG1 LD BC, 8; here 8 - the maximum spread of
; For the correction on the real Spectrum. I certainly
understand
; That there is enough to put two (+ / -1 cycle error)
, But it's worth just in case, little if any self-made
, "Pathology" are
SBC HL, BC; NC - spread wide - emulator
RET
Postkommentary: - "And if you disable AY mode 48K?" - What
can I say? There are still some good ports: # xxFE (border),
# Xx1F (kempston joystick), # FDFD (memory selector PROFI) -
go ahead and pray, that this is not a neSHALAEVe zaglyuchilo.
And now something else. Maybe it is I have such glyukavy PC486,
but recent data, this test does not work for one of the Samara
spektrumista - Sergei Zotov. When you start at the 482nd
calculator under SHALAEV'ym fifth OBERON presence emulator does
not recognize until then, until indulge in the mouse
(PC'shnaya). I works! Tested 10 times ... Maybe just the only
cases:)
<---- --->
7. "Instability of performance"
Theory: The significant differences of the relative speed can
be concluded on the execution in the emulator. Emulator: Z80,
UKV, SHALAEV, Spectrum Emulator ZX32 for Windows
Comments: This is a test - a logical continuation of the
previous one. The test is to test changes in speed
within a specified period of time.
(C) ALK / SoK
CALL INIINT; initialize a 2-second interrupt mode
LD B, 20; I think that the 20 measurements would be
sufficient LOOP PUSH BC
CALL TSPERF; actually, it ... (See below)
POP BC
DJNZ LOOP
LD A, (FLTSP +1); if there are 0, then the emulator
OR A
JP Z, EMUL
....
TSPERF LD HL, # BF00; address where we will process
, Measuring the number of cycles between
interrupts
, It is desirable to place it within the #
8000 ; # BFFF, mindful of the so-called
"slow"
; Memory
CALL PERFOR; in BC - the number taktov/10 (for details
see below) OLDTAC LD HL, 0, previous value of number of cycles,
first = 0
OR A
SBC HL, BC
RET Z; if equal the previous one, then the output
; ... Sometimes (on the real Spectrum) does not work
, (Error of + / - one cycle)
EX AF, AF '; remember for the future result of the
subtraction FLTSP LD A, # FF; if the trap has worked, then pass
-
; Idle cycles
OR A
JR Z, EN_PERF
LD DE, (OLDTAC +1); this check is needed
; To prevent false positives of the program
, With the first cycle of calculations - simply pass
LD A, D
OR E
JR Z, EN_PERF
PUSH BC; remember the "new" value of number of cycles
EX AF, AF '; remember the result of the difference
JR NC, NNG2; give the difference in otn.bystrodeystvii
; To a positive number
LD A, H
CPL
LD H, A
LD A, L
CPL
LD L, A
INC HL
OR A
NNG2 LD BC, 5; if the variance is less than 50 strokes (again
; Reinsurance) then skip
SBC HL, BC
JR C, EN_PRF1
SCMD LD A, 7; decrease counter the "bad" changes
DEC A
LD (SCMD +1), A
JR NZ, EN_PRF2; if not seven times, then
; Continue - on the way out
LD (FLTSP +1), A; if seven consecutive jumped
; Speed, this emulsion - reset flag -
And the remaining races' are ignored
JR EN_PRF2
EN_PRF1 LD A, 7, if the next jump was within normal limits
, Then set the counter again, "jumps in a row"
LD (SCMD +1), A
EN_PRF2 POP BC; remember the current value of number of cycles
EN_PERF LD (OLDTAC +1), BC; now it's "old"
RET
; Procedure for measurement of number of cycles between
interrupts ; Idea (C) VAV / Exploder / Extreme
PERFOR LD BC, 3; initial value of counter ticks
LD A, # C9
LD (# 8181), A; Handler on RET
LD DE, EXPRFT
LD (# 8182), DE; Preparation of this mod.
LD (HL), 3; <= INC BC <= 6 cycles
INC HL
LD (HL), # E9; <= JP (HL) <= 4 clocks
DEC HL
LD A, # C3
EI
HALT; Stabilization
LD (# 8181), A
EI
JP (HL)
; Initial value of BC = 3 is not by chance, if you put the time
of the three , Above the scroll. Command + RET command handler,
you get 25 ; Cycles. Counting procedure consists of 2 teams,
one cycle ; Takes 10 cycles - very convenient to display!
However, for , In our case, this accuracy is not so important
... EXPRFT POP AF; the same as the previous example
LD A, # C9
LD (# 8181), A
RET
; Initialization procedure interrupts the second kind
INIINT DI
LD A, # 80
LD BC, # 100
LD I, A
LD H, A
LD D, A
LD L, C
LD E, B
INC A
LD (HL), A
LDIR
LD H, A
LD L, A
IM 2
RET
Postkommentary: This algorithm was implemented in the
introductory test to Oberon5, and to my regret, later I found
here most that on a BUG! Incidentally, in the text, it is also
a;) If you sit in front of a quiet and most importantly - do
not touch, everything works train (on the emulator everything
is fine). BUG Regarding the real Spectrum. You know our users
... They just let me flip through the different bells and
whistles, buttons, Turbo, Slow, Stop etc. So, if you quickly
switch the Turbo / Normal and back (theoretically seven times),
then flick of the wrist Spectrum turns ... on an ordinary PC!
Bug corrected simply: procedure TSPERF instead of RET Z
put JR Z, EN_PRF3 and added:
EN_PRF3 LD A, 7
LD (SCMD +1), A
RET
Therefore, when performing tests N6 and N7, I strongly do not
recommend click buttons and move the mouse. But all seven
examples violent struggle - nothing compared to last ...
<---- --->
As the curtain can teach you a small sensation!
Copyright law, he is assigned to Copyright:
(C) 1998 Ivan Roshchin, Moscow
8. It's hard to believe: "The Z80 is a mistake!"
Theory: Improper command LD A, R / LD A, I at
This Z80.
Emulator: Z80, UKV, SHALAEV, ZX32 for Windows, WARAJEVO, ZX-JAM
ZX-EMUL by Lion17, X128 by James McKay (all updated), and
probably in all other emulators too, as none of
this error did not know!
Comment: If immediately when the command (for
Allow interruptions of any kind) LD A, R, or LD A, I
"Wedged" interrupt, the flag F, namely bit P / V
formed incorrectly.
Here is an excerpt from Article II Roshchina:
"But what can be related interruptions and teamwork LD A, R?
This team puts in a flag P / V content trigger interrupt
IFF2. When interrupt enable this trigger is 1, and when
comes to interrupt the momentum, it is automatically reset to 0,
to avoid re-processing interruptions. But the treatment
interrupt request line begins at the time of the last
tact executed commands (ie commands LD A, R). And, apparently,
already thrown trigger IFF2 copied to the flag of P / V (in
fact, with in terms of CPU, interrupt at this point already
prohibited). All of the above applies to the command LD A, I.
This information has been verified on the original processor
ZILOG Z80 firms and domestic counterparts KR1858VM1.
CALL INIINT
LD (HL), # FB; <= EI handler consists of two
INC HL
LD (HL), # C9; <= RET instruction.
EI
LD BC, 0; Over 65,536 cycles interrupt necessarily
; Hook into LD A, R at least once
LTSBUG LD A, R
JP PO, REALZ80; if the flag is cleared - that present
Z80
DEC BC
LD A, C
OR B
JR NZ, LTSBUG
EMUL ..............; Emulator defined
RET
REALZ80 ..............; No emulator
RET
Postkommentary: This is a serious blow! On this occasion I have
Proposition: It is necessary to make a request in Addiction
with Zilog Descriptions of Gluck - could, so it should be? :)
Of course, in This laborious really help I-Net. Because if
there is a man equally well, "groping" in the Internet and in
English, and if he More and spektrumist, all progressive
humanity in the faces the rest will be spektrumistov him over a
beer (each) for this invaluable. On both said!
<---- --->
P.S. And what for it here so much pains, you might say, when
using the latter test can be uniquely identified by _lyuboy_
1998 emulator? - I just described the tests in the order
in which I learned about them / invented, let alone the last I
learned in December 1998, so do not blame me ... Good Luck!
<---- --->
From the Editor:
Of course, for good, it was necessary to put the full article Mr
Roshchina of a glitch in the Z80, because it is the truth in
sensational material that is not surfaced for almost 20
years since the establishment of the first CPU Zilog Z80.
However, Ivan Roshchin making such a momentous discovery and
even writing article on this subject has not provided (?) in
which it either electronic editions, and released to "freedom"
- a network of FidoNet, where it was caught by us. Republish
this material it would be rash, as sure a number of other
near-net newspapers also did not pass by such tidbits ...
Although the method of I. Roshchina allows 100% determined
emulators, all those gadgets that are described ALK may also be
useful. They allow you to determine not only the emulator, but
his version. A here you can and make conclusions about the car.
For example if the Z80 - it means "Cars" from Comrade frail if
UKV, then it either Hacker or brake, but if ZXEMUL031 by Lion17
then ... Go for it!