MEMPTR, эзотерический регистр ZiLOG Z80. Как известно, после выполнения инструкции BIT n,(HL) в 3 и 5 битах флагового регистра оказывается некое нечто, о котором в фирменных руководствах не сказано ни слова. На самом деле это -- 11й и 13й биты внутренней регистровой пары Z80, которая используется для операций с 16и-битными значениями, чаще всего -- адресами (обычная практика для процессоров с 8и-битной шиной данных, оперирующих 16и-битными данными). Как и зачем два бита этого регистра оказались во флагах, неясно, однако же, оказались. Упоминания об этом явлении можно встретить в "z80 undocumented documented" Шона Янга (http://www.myquest.nl/z80undocumented/), и, в несколько большем объеме, в описании Z80 из проекта "nocash" (http://www.work.de/nocash/zxdocs.htm), где эта регистровая пара и названа MEMPTR. К сожалению, до недавнего времени, попытки по состоянию двух бит разобраться, какие конкретные значения выставляются в MEMPTR некоторыми инструкциями процессора, были не слишком успешны. Но свершилось чудо. В результате множества экспериментов (основанных на предпосылке, что инструкции с индексной адресацией инициализируют MEMPTR соотвутствующим адресом), а также глубоких медитаций над результатами, нам удалось выяснить, что инструкция CPI увеличивает текущее значение MEMPTR на 1, а CPD текущее значение на 1 уменьшает. Таким образом, циклически декрементируя MEMPTR, и отслеживая заём из старших разрядов по двум известным битам, можно однозначно определить 14 младших бит MEMPTR, а имея их на руках -- сказать наверняка, по какому принципу выставляются значения. Далее -- список операций, влияющих на MEMPTR, с формулами для его содержимого. Здесь rp обозначает регистровую пару (16 бит), а INDEX - регистровые пары IX или IY. Операции, в этом списке отсутствующие, на MEMPTR, насколько известно, не влияют. Все процессора, на которых проводились испытания, дали одинаковые разультаты, за исключением КР1858ВМ1 и Т34ВМ1, которые будем обозначать "*BM1". ==================================================================================== LD A,(addr) MEMPTR = addr + 1 LD (addr),A MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = A для *BM1: MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = 0 LD A,(rp) где rp -- BC либо DE MEMPTR = rp + 1 LD (rp),A где rp -- BC либо DE MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = A для *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 LD (addr), rp LD rp,(addr) MEMPTR = addr + 1 EX (SP),rp MEMPTR = значение rp после операции ADD/ADC/SBC rp1,rp2 MEMPTR = rp1_до_операции + 1 RLD/RRD MEMPTR = HL + 1 JR/DJNZ/RET/RETI/RST (при переходе по addr) MEMPTR = addr JP(кроме JP rp)/CALL addr (в случае условного перехода -- независимо от удовлетворения условию) MEMPTR = addr IN A,(port) MEMPTR = (A_до_операции << 8) + port + 1 IN A,(C) MEMPTR = BC + 1 OUT (port),A MEMPTR_low = (port + 1) & #FF, MEMPTR_hi = A для *BM1: MEMPTR_low = (port + 1) & #FF, MEMPTR_hi = 0 OUT (C),A MEMPTR = BC + 1 LDIR/LDDR при BC <> 1: MEMPTR = адрес_инструкции + 1 при BC = 1 не влияет CPI MEMPTR = MEMPTR + 1 CPD MEMPTR = MEMPTR - 1 CPIR при BC=1 или A=(HL): как CPI в остальных случаях на каждом шаге MEMPTR = адрес_инструкции + 1 * поскольку на последнем шаге BC=1 или A=(HL), в итоге MEMPTR = адрес_инструкции + 1 + 1 (если перед этим не было прерывания) CPDR при BC=1 или A=(HL): как CPD в остальных случаях на каждом шаге MEMPTR = адрес_инструкции + 1 * поскольку на последнем шаге BC=1 или A=(HL), в итоге MEMPTR = адрес_инструкции + 1 - 1 (если перед этим не было прерывания) INI MEMPTR = BC_до_декремента_B + 1 IND MEMPTR = BC_до_декремента_B - 1 INIR как INI на каждом шаге. то есть, в итоге MEMPTR = ((1 << 8) + C) + 1 INDR как IND на каждом шаге. то есть, в итоге MEMPTR = ((1 << 8) + C) - 1 OUTI MEMPTR = BC_после_декремента_B + 1 OUTD MEMPTR = BC_после_декремента_B - 1 OTIR как OUTI на каждом шаге. то есть, в итоге MEMPTR = C + 1 OTDR как OUTD на каждом шаге. то есть, в итоге MEMPTR = C - 1 любая инструкция с (INDEX+d): MEMPTR = INDEX+d переход по прерыванию на addr: как при обычном CALL. то есть, MEMPTR = addr ==================================================================================== Какая же польза нам от этого Тайного Знания? Ну, во-первых, теперь возможно написание эмуляторов Z80, поддерживающих _все_ недокументированные особенности cpu. Во-вторых, то, что на некоторых клонах Z80 MEMPTR ведет себя слегка иначе, добавляет еще один метод в копилку способов автоопределения модели процессора. По-моему, уже немало! :) (c)2006, zx.pk.ru теоретическая часть: boo_boo, Vladimir Kladov натурные испытания: Wlodek, CHRV, icebear, molodcov_alex, goodboy