News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Pushing/Popping to the Stack

Started by IndyUK, 21:58, 09 May 25

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

IndyUK

Hi Folks,

I've been experimenting with the technique of using the SP as a source of writing bytes and have come across something which is baffling me. I'm using the following test code but, cannot figure out why this causes the screen to get corrupted.

org &1000


ld (spbakog),sp
di

ld sp,&4000
pop bc : pop de : pop hl
exx
pop bc : pop de : pop hl
exx

ei
ld sp,(spbakog)

ret

spbakog dw 0

It seems to happen when I use the shadow registers, the text on the screen gets corrupted. I haven't included the second part of the code, which is basically the opposite i.e. push the data somewhere.

Can someone please offer some advice as to what I'm doing wrong?

Thanks,

Jean-Marie

Shadow registers should not be overwritten when the Firmware is active.
Unless you turn off the interrupts and push/pop them to their initial state.

lightforce6128


exx
pop bc : pop de : pop hl
exx

If you want to use the second register set, then you need to backup them like the stack pointer and restore them before reenabling interrupts. E.g. register bc' is used to page rom in and out of memory and to remember what the last state was. If this is altered, bad things will happen.

ei
ld sp,(spbakog)

This (maybe) has strange side effects. This reenables interrupts before the stack address is restored. There can be pending (waiting) interrupts that will occur immediately after the 'ei' command. On the other hand I remember that 'ei' extends to one more command to enable 'ei : ret' in interrupt handling routines without unwanted recursion. But I'm not sure if this only applies to a subsequent 'ret' command or also to multi-byte commands like 'ld sp,(nnnn)'.

andycadley

EI doesn't enable interrupts until one command later, it doesn't matter that it is multi byte because the Z80 will never process an interrupt mid way through decoding or executing an instruction.

So that is technically safe.

IndyUK

Quote from: andycadley on 07:59, 10 May 25EI doesn't enable interrupts until one command later, it doesn't matter that it is multi byte because the Z80 will never process an interrupt mid way through decoding or executing an instruction.

So that is technically safe.
Thanks for confirming this. I did read somewhere (maybe on this forum) that upon issuing an EI, the next command will actually fire that, not the EI command. I did have a HALT immediately after but removed it as I didn't know if that was causing my issue so, luckily got away with what I've done.

Quote from: lightforce6128 on 04:38, 10 May 25If you want to use the second register set, then you need to backup them like the stack pointer and restore them before reenabling interrupts. E.g. register bc' is used to page rom in and out of memory and to remember what the last state was. If this is altered, bad things will happen.
What would you suggest is the best approach for backing up the shadow registers? To memory or to SP (before I repoint it)?

Thanks

McArti0

#5
org &1000

di
exx
push bc
push de
push hl
push AF
exx

ld (spbakog),sp

ld sp,&4000
pop bc : pop de : pop hl
exx
pop bc : pop de : pop hl
exx

ei
ld sp,(spbakog)

exx
push AF
push hl
push de
push bc
exx

ret

spbakog dw 0
CPC 6128, Whole 6128 and Only 6128, with .....
NewPAL v3 for use all 128kB RAM by CRTC as VRAM
One chip driver for 512kB(to640) extRAM 6128
TYPICAL :) TV Funai 22FL532/10 with VGA-RGB-in.

Longshot

I'm not a firmware expert but I think you only need to backup BC'.
Rhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!

Urusergi

#7
Quote from: Longshot on 18:09, 10 May 25I'm not a firmware expert but I think you only need to backup BC'.

Exactly, and also alternative flags (af')

https://cpctech.cpcwiki.de/docs/manual/s968ap11.pdf

lightforce6128

Quote from: McArti0 on 16:57, 10 May 25ei
ld sp,(spbakog)

exx
push AF
push hl
push de
push bc
exx


Something got mixed here at the end of the block. Because we have multiple commands here, 'ei' should be clearly the last one, not the first one. Also we want to restore the registers ('pop' instead of 'push'). Should be:

ld sp,(spbakog)
exx
pop af
pop hl
pop de
pop bc
exx
ei

McArti0

Yes good point! But POP order must be exactly opposite to PUSH.
CPC 6128, Whole 6128 and Only 6128, with .....
NewPAL v3 for use all 128kB RAM by CRTC as VRAM
One chip driver for 512kB(to640) extRAM 6128
TYPICAL :) TV Funai 22FL532/10 with VGA-RGB-in.

IndyUK

Quote from: Urusergi on 18:29, 10 May 25
Quote from: Longshot on 18:09, 10 May 25I'm not a firmware expert but I think you only need to backup BC'.

Exactly, and also alternative flags (af')

That's really useful to know. Saved a few bytes. 

BSC

Quote from: lightforce6128 on 23:32, 10 May 25exx

push AF
AF is not affected when using EXX. It has it's own instruction. EX AF,AF'

So if you want to fully save the 2nd register set you'd have to:

EXX
PUSH BC: PUSH DE: PUSH HL
EXX
EX AF, AF'
PUSH AF
EX AF,AF'

to have all 2nd register values on the stack. Before returning from your
code, POP them back in reverse order.
** My website ** Some music

My hardware: ** Schneider CPC 464 with colour screen, 64k extension, 3" and 5,25 drives and more ** Amstrad CPC 6128 with M4 board, GreaseWeazle.

GUNHED

#12
My two Pfennige (Pennies) about all that...  :) :) :)

Sadly most OS for the CPC use the 2nd register set for interrupts - or lets say they waste them.
So basically the CPC works in 8080 mode and can't use the power of the enhanced 2nd registers. This slows the computer down my approx. 30%

The origin of this evil is that the coders of the firmware came from the 8080 (that's what they told by themselves actually). There is some article somewhere (google it).

The CPC has 300 interrupts per second. This means roughly, between two interrupts there are 3300 us or NOPs. Wasting the 2nd register set for interrupts only gains one of two dozens of NOPs. Not even 1%!!!

Of course some users will (like usually) completely disagree, but just calculate for yourself and think about it for yourself  ;) :)
http://futureos.de --> Get the revolutionary FutureOS (Update: 2024.10.27)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Powered by SMFPacks Menu Editor Mod