IY and the interrupt

The place for codemasters or beginners to talk about programming any language for the Spectrum.
dfzx
Dizzy
Posts: 92
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

IY and the interrupt

Post by dfzx » Wed Jan 03, 2018 11:23 am

I was dicking about with an IM2 interrupt in C using z88dk. I wanted to return to BASIC leaving my interrupt routine running, but z88dk doesn't support that. (It restores IM1 when returning to BASIC from C.) It's a simple-ish change to add support to the framework, but I discovered I really didn't understand the relationship between the Spectrum BASIC interrupt handler at 0x0038 and the IY register. The fix Alcoholics Anonymous gave me on the z88dk forum was, at the end of my ISR, to load IY with 0x5c38, then call 0x0038, then return. I have no doubt he'll be right, but... why?

I was looking at the Spectrum ROM disassembly book, and I see in there:

Code: Select all

LD IY,+5C3A      IY holds +ERR-NR always.
but searching for "IY" in the rest of the book yields nothing. Um, eh? IY is set but never read or referenced? That can't be right. I must be missing something.

So I sort of understand. The BASIC ISR (and possibly the entire BASIC system?) expects IY to always hold the value 0x5c3a, so restoring it to that value before calling the BASIC ISR would clearly be the right thing to do. But why is IY needed to point to the ERR NR system variable and why doesn't it appear to be dereferenced in the Spectrum ROM?
0 x

Hikaru
Microbot
Posts: 100
Joined: Mon Nov 13, 2017 1:42 pm
Location: Russia
Contact:

Re: IY and the interrupt

Post by Hikaru » Wed Jan 03, 2018 11:58 am

Hello, world! What you're seeing here is the effect of the so-called 'good practices' at work. A small example:

Code: Select all

0038 MASK-INT     PUSH  AF                  Save the current values held in
                  PUSH  HL                  these registers.
                  LD    HL,(FRAMES)         The lower two bytes of the

                  INC   HL                  frame counter are incremented
                  LD    (FRAMES),HL         every 20 ms. (U.K.) The highest
                  LD    A,H                 byte of the frame counter is
                  OR    L                   only incremented when the
                  JR    NZ,0048,KEY-INT     value of the lower two bytes
                  INC   (FRAMES-3)          is zero.
With a bit of attention and clairvoyance, the reader will be able to infer that the line, INC (FRAMES-3), is actually implemented as INC (IY+#40).
0 x
Inactive account

User avatar
Ast A. Moore
Manic Miner
Posts: 689
Joined: Mon Nov 13, 2017 3:16 pm

Re: IY and the interrupt

Post by Ast A. Moore » Wed Jan 03, 2018 12:17 pm

Ah, a rookie mistake. ;) The BASIC interpreter—well, many ROM routines, to be precise—make heavy use of IY and prime registers. If you fool around with them, you need to save and restore them before returning to BASIC.
0 x
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.

User avatar
Ast A. Moore
Manic Miner
Posts: 689
Joined: Mon Nov 13, 2017 3:16 pm

Re: IY and the interrupt

Post by Ast A. Moore » Wed Jan 03, 2018 12:30 pm

dfzx wrote:
Wed Jan 03, 2018 11:23 am
But why is IY needed to point to the ERR NR system variable and why doesn't it appear to be dereferenced in the Spectrum ROM?
A lot of (but not all) system variables are accessed via the IY register in ROM. That’s just how it is. IY is initialized by NEW and STACK_BC routines.
0 x
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.

dfzx
Dizzy
Posts: 92
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Re: IY and the interrupt

Post by dfzx » Wed Jan 03, 2018 12:36 pm

Ast A. Moore wrote:
Wed Jan 03, 2018 12:30 pm
dfzx wrote:
Wed Jan 03, 2018 11:23 am
But why is IY needed to point to the ERR NR system variable and why doesn't it appear to be dereferenced in the Spectrum ROM?
A lot of (but not all) system variables are accessed via the IY register in ROM. That’s just how it is. IY is initialized by NEW and STACK_BC routines.
OK, so my puzzlement now is the way this is expressed in the ROM disassembly book. Hikaru, and checking the ROM in my emulator's debugger, confirm that this:

Code: Select all

INC   (FRAMES-3)
is indeed implemented as:

Code: Select all

INC (IY+40)
How is the reader of the book supposed to go from "FRAMES-3" to "IY+40"? The word "FRAMES" doesn't appear anywhere else in the book. Is there a way of expressing such things in Z80 assembly language which I'm not familiar with?
0 x

User avatar
R-Tape
Site Admin
Posts: 1595
Joined: Thu Nov 09, 2017 11:46 am

Re: IY and the interrupt

Post by R-Tape » Wed Jan 03, 2018 12:48 pm

^That is indeed a bizarre way of expressing it!

I can't find a link to it now but this ROM disassembly is much clearer (might be Geoff Wearmouth et al), and even criticises not storing IY.

Code: Select all

L0038:  PUSH    AF              ; Save the registers that will be used but not
        PUSH    HL              ; the IY register unfortunately.
        LD      HL,($5C78)      ; Fetch the first two bytes at FRAMES1.
        INC     HL              ; Increment lowest two bytes of counter.
        LD      ($5C78),HL      ; Place back in FRAMES1.
        LD      A,H             ; Test if the result was zero.
        OR      L               ;            
        JR      NZ,L0048        ; Forward, if not, to KEY-INT

        INC     (IY+$40)        ; otherwise increment FRAMES3 the third byte.
0 x

User avatar
Seven.FFF
Manic Miner
Posts: 283
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: IY and the interrupt

Post by Seven.FFF » Wed Jan 03, 2018 1:07 pm

Ha, that’s hilarious!! Would have confused the heck out of me too. I can kinda see why they did it, but still

There’s no such instruction as ld (nn), n or ld (nn+o), nn, of course... but who pays attention to that when they're reading an authoritative tome!
0 x
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
seven-fff.com/blog

Hikaru
Microbot
Posts: 100
Joined: Mon Nov 13, 2017 1:42 pm
Location: Russia
Contact:

Re: IY and the interrupt

Post by Hikaru » Wed Jan 03, 2018 2:02 pm

dfzx wrote:
Wed Jan 03, 2018 12:36 pm
How is the reader of the book supposed to go from "FRAMES-3" to "IY+40"? The word "FRAMES" doesn't appear anywhere else in the book.
Regarding the lack of constant/variable list in the book at least, perhaps the 'ROM Disassembly' authors were relying on the fact that these are listed in this Spectrum manual, which I assume was part of the package. As I've never owned any of the original Spectrum models, I can't really tell.
0 x
Inactive account

User avatar
Ast A. Moore
Manic Miner
Posts: 689
Joined: Mon Nov 13, 2017 3:16 pm

Re: IY and the interrupt

Post by Ast A. Moore » Wed Jan 03, 2018 2:56 pm

dfzx wrote:
Wed Jan 03, 2018 12:36 pm
How is the reader of the book supposed to go from "FRAMES-3" to "IY+40"? The word "FRAMES" doesn't appear anywhere else in the book.
Now that you’ve mentioned it, it does appear to be a little, well, idiosyncratic on their part. Granted, they used the standard names for Spectrum’s system variables, so anybody familiar with them wouldn’t have questions about them.

That said, I’ve always consulted that book “the other way around.” That is, I rarely read the book first and wrote my routines around it later. I used a debugger/monitor, found an entry point, and then consulted the book. That way I generally read the comments, rather than looked at the disassembly in the book.

In any event, there’s an excellent electronic version of it you can consult instead of the printed book or a PDF. It does treat index registers the proper way and many things are hyperlinked for easy access.
0 x
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.

AndyC
Microbot
Posts: 167
Joined: Mon Nov 13, 2017 5:12 am

Re: IY and the interrupt

Post by AndyC » Wed Jan 03, 2018 7:44 pm

Yeah, very weird way of writing it. I'd expect to see:

INC (IY+FRAMES)

or

INC (IY+$40); update FRAMES

I can kind-of see the logic in what it was trying to convey, given that the Spectrum ROM assumes IY remains constant all the time, but it doesn't make things very obvious at all.
0 x

Post Reply