we continue to pervert
ZXNet echo conference «code.zx»
From Oleg Grigoriev → To All 22 February 1999
Hi, All!
1. Запуск рестарта по номеру.
CALL RST
DB номер_рестарта
...
RST EX (SP),HL ;19/20
PUSH AF ;11/12
LD A,(HL) ;7 /8
INC HL ;6
LD (N1+#01),HL ;16
ADD A,A ;4
LD L,A ;4
LD H,TABLE[ ;7 /8
LD A,(HL) ;7 /8
INC L ;4
LD H,(HL) ;7 /8
LD L,A ;4
LD (N2+#01),HL ;16
POP AF ;10
POP HL ;10
;132[138]
PUSH BC ;11/12
PUSH HL ;11/12
PUSH DE ;11/12
PUSH IX ;15/16
N2 CALL #0000 ;17/18
POP IX ;14
POP DE ;10
POP HL ;10
POP BC ;10
N1 JP #0000 ;10
;119[124]
;251[262]
2. Запуск рестарта по номеру в регистре С.
LD C,номер_рестарта
CALL RST
...
RST PUSH HL ;11/12
PUSH AF ;11/12
LD L,C ;4 SLA L ;8
LD H,TABLE[ ;7 /8
LD A,(HL) ;7 /8
INC L ;4
LD H,(HL) ;7 /8
LD L,A ;4
LD (N2+#01),HL ;16
POP AF ;10
POP HL ;10
;99[104]
PUSH BC ;11/12
PUSH HL ;11/12
PUSH DE ;11/12
PUSH IX ;15/16
N2 CALL #0000 ;17/18
POP IX ;14
POP DE ;10
POP HL ;10
POP BC ;10
RET ;10
;119[124]
;218[228]
WBR, Oleg.
From Valentin Pimenov → To Oleg Grigoriev 23 February 1999
+-Hello, Oleg!
|one day 02/22/99 at exactly 20:11:00
|Oleg Grigoriev wrote to All about continuing to pervert...
+------------------------
OG> Hi, All!
OG> 1. Start restart by number.
OG> CALL RST
OG> DB restart_number
OG> ...
[skip]
OG> ;251[262]
;rst x
;db function
x push hl ;save hl 11(12)
ex (sp),hl ;(sp)=hl hl=ret adress 19(20)
push af ;save af 11(12)
ld a,(hl) ;get function code 7 (8)
inc hl ;increment return address 6
ex (sp),hl ;(sp)=ret adress hl=old hl 19 (20)
x1 push hl ;save hl 11 (12)
;- alternative #1 --------------------------------------
ld hl,f_table ;any address 10
add a,a ;Nfunc*2 4
jr nc,$+3 ; 7/12 (8/12)
inc h ;no comments 4
add a,l ;form low byte of address 4
ld l,a ; 4
adc a,h ; 4
sub l ;h=h+(carry of ) 4
ld h,a ; 4ld a,(hl) ;get low address of funct. 7 (8)
inc hl ;next address in table 6
ld h,(hl) ;get high address 7 (8)
ld l,a 4
;- end of alternative 1 --------------------------------
ex (sp),hl ;(sp)=jp address,hl=old hl 19 (20)
pop af ;restore af 11 (12)
ret ;pc=function 10
---
193/198(204/208)
;no additional register saving required
;exit the function back by ret.
;address table for any address. otherwise you can
;optimize.
;for example like this
;- alternative 2 ------------------------------------
ld l,a
ld h,table[ ;table lies on the segment boundary
ld a,(hl) ;ml first. address byte,
inc h ;after 256 bytes
ld h,(hl) ;high byte of address
ld l,a ;hereinafter in the text (see above)
;- end of alternative -----------------------------
OG> 2. Start restart by number in register C.
OG> LD C,restart_number
OG> CALL RST
OG> ...
[skip]
OG> ;218[228]
x push af ;11(12)ld a,c ;4
jp x1 ;from the first example ;10
;---------------------------------- 145/150(152/156)
imho, launching via db function is more efficient in size
code, but through the register - faster and more dangerous.
and of course, it is advisable to use a zero page
below, then you won’t have to do different “call rst”,
but simply “rst x”, which is 6 clock cycles faster and 2 bytes shorter.
and finally the question: why the hell save registers around
call'a, if the function does not change them? let those functions that
they change something, they keep it, and the rest - what for. maybe
I have a restart function - set the border color from register A
:) so, you will save 4 registers, then restore them, and
nothing has changed.
+-All the best, Oleg!
|I was with you
|Valentin Pimenov aka Valker/Style_Group
+---------------
From Ivan Mak → To Oleg Grigoriev 24 February 1999
Greetings, Oleg!
On the day Oleg Grigoriev wrote to All:
OG> PUSH BC ;11/12
OG> PUSH HL ;11/12
OG> PUSH DE ;11/12
OG> PUSH IX ;15/16
OG> N2 CALL #0000 ;17/18
OG> POP IX ;14
OG> POP DE ;10
OG> POP HL ;10
OG> POP BC ;10
Why so much PUSH-POP that it would be impossible to get the result in the registers from
restart?
OG> 2. Start restart by number in register C.
OG> RST PUSH HL ;11/12
OG> PUSH AF ;11/12
OG> LD L,C ;4
OG> SLA L ;8
OG> LD H,TABLE[ ;7 /8
OG> LD A,(HL) ;7 /8
OG> INC L ;4
OG> LD H,(HL) ;7 /8 OG> LD L,A ;4
OG> LD (N2+#01),HL ;16
OG> POP AF ;10
OG> POP HL ;10
IMHO, it's better this way.
RST:PUSH HL
PUSH AF
LD L,C
SLA L
LD H,TABLE/256
LD A,(HL)
INC L
LD H,(HL)
LD L,A
POP AF
EX (SP),HL
RET
If you need to save registers, you need to do it in the function itself and save it there
only those that really need to be preserved.
You can also save money if you agree that all restart numbers are even, then
The SLA L command can be deleted.
P.S. The latter, of course, is only for new developments.
You can make it even cooler :)
The function number is in register A and must be divisible by 3
RST: LD ADR+1,A
ADR: JP FN_X
; there should be address alignment at 256
FN_X: JP FN_0
JP FN_1
JP FN_2
.......
JP FN_84
Wow! The Protoss are attacking my Zerlings! It's time to get going. Ivan.
- Divorce the scheme, big and small...
From Dmitry Grigoryev → To Oleg Grigoriev 25 February 1999
Hello Oleg!
Monday 22 February 1999 20:11, Oleg Grigoriev (500:812/10.13) wrote to All:
Gee :) The echo is starting to correspond to the echo tag ;)
OG> 2. Start restart by number in register C.
OG> LD C,restart_number
OG> CALL RST
OG> ...
OG> RST PUSH HL ;11/12
OG> PUSH AF ;11/12
OG> LD L,C ;4
OG> SLA L ;8
OG> LD H,TABLE[ ;7 /8
OG> LD A,(HL) ;7 /8
OG> INC L ;4
OG> LD H,(HL) ;7 /8
OG> LD L,A ;4
OG> LD (N2+#01),HL ;16
OG> POP AF ;10
OG> POP HL ;10
OG> ;99[104]
OG> PUSH BC ;11/12
OG> PUSH HL ;11/12 OG> PUSH DE ;11/12
OG> PUSH IX ;15/16
OG> N2 CALL #0000 ;17/18
OG> POP IX ;14
OG> POP DE ;10
OG> POP HL ;10
OG> POP BC ;10
OG> RET ;10
OG> ;119[124]
OG> ;218[228]
RST ex (sp),hl ;19
push hl ;11
ld l,c ;4
sla l ;8
ld h,tabl ;7
ld a,(hl) ;7
inc l ;4
ld h,(hl) ;7
ld l,a ;4
jp (hl) ;4(?)
75
Скорповские глюки подсчитывать не буду :)
А регистры пусть вызываемая подпрограмма сохраняет, какие ей нужно. То же
касается и испорченных hl и аккумулятора - лучше их сохранять перед вызовом
рестарта, хотя именно в них лучше всего передавать выходные параметры.
OG> WBR, Oleg.
С уважением, Дмитрий (OLDMAN). 500:095/100.1@ZXNet oldman@i-connect.ru
From Ivan Mak → To Dmitry Grigoryev 27 February 1999
Greetings, Dmitry!
On Dmitry Grigoryev wrote to Ivan Mak:
IM>> IMHO, it's better this way.
IM>> RST: PUSH HL
IM>>PUSH AF
IM>> LD L,C
IM>>SLA L
IM>> LD H,TABLE/256
IM>> LD A,(HL)
IM>>INC L
IM>> LD H,(HL)
IM>> LD L,A
IM>>POP AF
IM>> EX (SP),HL
IM>> RET
DG> Not bad. Especially if push hl; ex(sp),hl; ret replace with jp (hl)
DG> ;)
Really better. :)
But the registers must be saved, so all that remains is PUSH HL and start each function
with POP HL.
IM>> If you need to save registers, you need to do it in the function itself
IM>> save there only those that really need to be saved.
IM>> Yes
DG> Uh-huh. So why did you save af? ;)
As you yourself wrote, it is convenient to pass parameters in it. Same as in HL.
And for disk functions, for example, all registers count.
IM>> you can also save money if you agree that all restart numbers are even, IM>> then the SLA L command can be thrown out. P.S. The latter, of course
IM>> only for new developments.
DG> Why? Not a bad idea. Does it matter in what order the numbers are
DG> restarts?
Well, if you change the function numbers in the BIOS, the old programs will go to hell. :)
IM>> You can make it even cooler :)
IM>> The function number is in register A and must be divisible by 3
IM>> RST: LD ADR+1,A
IM>> ADR: JP FN_X
IM>> ; there should be address alignment at 256
IM>> FN_X: JP FN_0
IM>> JP FN_1
IM>> JP FN_2
IM>> .......
IM>> JP FN_84
DG> 33 bars! And the protoss are not fools ;)
Zerlings, zerlings, not protoss! :)))
And even more accurately - rectals.
DG> It’s even possible with any function number:
DG>RST:
DG> ld a,c
DG> sla c
add a,c here :)))
DG> add a,c
DG> 33+16=49... Mine is shorter, if jp (hl) really eats 4 bars... DG> But we don’t spoil hl...
45! Y? :))
DG> Painful thought, but if the restarts themselves (or just jumps on them)
DG> scatter to addresses divisible by 256? Then at h restart: ld l,0; jmp
DG> (hl); [jp restart] - 11/21 bars ;)
Let's remember what we do before the call:
LD H,restart ; 7
CALL RST<< ; 11
RST:
..... something there is at least 11 bars.
29 measures
And then we call restart like this:
LD HL,(RESTART*2+TABLE) ; 16
CALL RST ; 11
RST:JP(HL); 4
TABLE: DW FN_0,FN_1...
31 clock cycles, but there is no code scattered throughout the RAM.
You can also do it right away:
CALL RESTART*3+JPS_RST
JPS_RST:
JP FN_1
JP FN_2
But this is as old as time. :)))
Wow! The Protoss are attacking my Zerlings! It's time to get going. Ivan.
- Divorce the scheme, big and small...