(C) Ivan Roshchin, Moscow
Music: WORLD without LIMIT / KENOTRON
Undocumented feature
CPU Z80
1. How it all began.
I wrote once the next version of the program
BestView (v2.4) and used it here is a snippet:
....
EI
CALL SUBR1
HALT
....
SUBR1 LD A, R
PUSH AF
DI
....
POP AF
DI
RET PO
EI
RET
In the snippet is a procedure call
SUBR1, which at the time of their work bans
interrupts, while output - restore old
mode of their work.
Verifying that are allowed or disallowed interrupts the
procedure call and restore interrupt mode is as follows:
- The team LD A, R enters into a flag P / V condition
trigger interrupt IFF2;
- Register pair AF is stored on the stack (PUSH AF);
- Do not Interrupt (DI);
- Run, actually those functions for which
and the intended procedure SUBR1;
- The contents of AF recovered (POP AF);
- Interrupts are prohibited (DI);
- If the flag P / V reset is exited about
procedure with restricted Interrupt (RET PO);
- Otherwise exits with preemption
s (EI: RET).
I began to notice that when running this fragment BestViev
hangs - not always or even very often, but in very rare cases.
But, anyway, It was not very nice. The program, like,
did not contain any mistakes, at least at first glance nothing
suspicious, I did not notice. Had only to resort to more
powerful tools ...
2. The situation begins to brighten.
After another hang-up I put in a clean
CD and confidently pressed the MAGIC. Then loaded
debugger "STS 6.2 + @" (not in vain, I reworked it -
now using it after downloading @ file, you can
restore the contents of CPU registers on the
instant relief to disk). Pressing the pair of keys - and now I
see where in the program occurred hang.
....
EI
CALL SUBR1
HALT
"Sts6.2 ", which will be made and corrections.
Then you need to find a free 14 bytes - their
appointment will be explained below. You can use the
buffer function of the user (address # FE37). But in
the version of the STS, I use this buffer
occupied by the procedure of disassembling with labels
assembler ZX ASM, so I decided to cut some text messages:
'Block' -> 'Bl.' (Save 2 bytes)
'Save' -> 'S.' (------/------ 2 ---/---)
'Load' -> 'L.' (------/------ 2 ---/---)
'DEFB' -> '' (------/------ 4 ---/---)
'FileName' -> 'Name' (------/------ 4 ---/---)
For this purpose, addresses # EB24, enter the following
sequence of bytes:
# EB24: AE 46 72 6F ED 54 EF 46
# EB2C: 69 6C E5 53 65 63 74 6F
# EB34: F2 53 AE 4C AE 53 74 6F
# EB3C: 70 20 69 E6 42 61 6E EB
# EB44: 51 75 69 F4 54 72 61 63
# EB4C: E5 53 74 61 72 44 69 F4
# EB54: 73 61 73 ED A0 46 69 6C
# EB5C: E5 42 41 53 49 C3 20 44
# EB64: 4F D3
At # E702 replaces the value in # 0A
# 0E, to correctly print the name of the file (as
instead of a string FileName remain just Name).
So now with the address # EB66 free 14 bytes.
See where the STS is to determine the state trigger interrupts:
# DFFE: LD (# 5BA1), SP
LD SP, # 5BA1
PUSH BC
PUSH AF
LD A, R
DI
LD BC, # 7FFD
LD A, # 1F
OUT (C), A
LD B, # BF
LD A, # 00
OUT (C), A
JP # E028
Replace command LD A, R: DI on NOP, but the team JP # E028
- to JP # EB66. With the address # EB66 put this snippet:
# EB66: LD A, R
JP PO, # EB6E
NOP
JR # EB70
LD A, R <
> DI
JP # E028
Please note - this piece in any
If their work with the increases in the register R
the same value (7). The fact that more
will be executed one more command LD A, R, this
time is needed to determine the value of the register R,
and the correction will be made of measured value,
as R register value increases with each command, and it is
necessary to know its value to the end of the implementation
team traced. Here's how it looks:
# DCA2: LD A, # 5A
LD HL, # FEF4
SLA (HL)
RLA
ADD A, (HL)
RRCA
LD (HL), A
RET
Constant # 5A at # DCA3 should be replaced by # 53, ie,
reduced to 7 - because the program was added an additional
fragment, which increases the register R 7, and we must
compensate for this change.
After that you only write the changed file to disk.
Then the program was added an additional fragment, which
increases the register R 7, and we must compensate for this
change.
After that you only write the changed file to disk.