Coder Social home page Coder Social logo

Comments (6)

johnwbyrd avatar johnwbyrd commented on May 26, 2024

If MOS processors had had privileged modes, we would simply swap from the user set of registers to the privileged set before running the interrupt, and swap back before leaving it. This is possible on the MOS processors, and we could implement it, but since interrupts tend to happen every video frame, there would be a significant performance hit and I think people would not tolerate that, especially with a large number of imaginary registers.

An alternate method of handling this, might be to let different libraries resolve imaginary registers to different zero page addresses. Let's say your libc uses 16 zp registers, starting at $10. And let's say your interrupt handling library uses 16 zp registers, starting at $30. At link time, libc would use one base address to resolve imaginary register locations, and your interrupt handler would use another base address.

Your interrupt library couldn't do anything to the C stack -- it would be limited to working only in those shadowed imaginary registers -- but that might be enough to get by with the little bit of work that your C interrupt handler needs to do.

In any case, C has no established standard for interrupt handling, and it might be reasonable to dictate -- especially on a platform this small -- that all interrupts must be written in assembly.

from llvm-mos.

mysterymath avatar mysterymath commented on May 26, 2024

It's a bit of a half-truth that C doesn't establish interrupt handling. While the mechanism by which interrupts and C are interfaced is deliberately unspecified, a lot of both the text and the rationales given in the standard go towards making sure that C code operates meaningfully when called inside interrupt handlers. The C signal, volatile, and sig_atomic_t mechanisms also fall in line with this spirit; that's even a sticking point for new C developers, who assume that they're meant for simultaneous multithreading, which they're woefully incapable of handling.

An interrupt library would be totally free to manipulate the C stack; and that's a big part of the reason C has a stack in the first place. C runtimes typically retain an invariant regarding the stack pointer: "At all times, the stack pointer points to a free location in memory." As such, any interrupt C routines could feel free to allocate their own stacks at the current stack pointer, since this would be guaranteed after the stack frames of any code they're interrupting. We'd need to make sure that we actually do maintain this invariant, but that's not actually too difficult, and there's a separate C99 compatibility issue for this.

Having a way of splitting up the ZP register space sounds good for handling this, but we'd need a more specific mechanism for how this would be accomplished. Today, if you tried to link together the interrupt routines and regular routines, both would emit references to, say, the symbol __rc4, and they'd both need that to mean something different. AFAIK, LD doesn't really provide a mechanism for specifying that a symbol resolve to different things in different sections of the same link.

from llvm-mos.

mysterymath avatar mysterymath commented on May 26, 2024

I guess since there's so many different plausible ways of handling ZP registers in interrupt handlers, maybe we can punt that to the user by folding it into the "asm code that calls C code" calling conventions.

"You can feel free to call C from within an interrupt, so long as you make sure that the ASM code that calls your interrupt handler saves all caller-saved registers beforehand that might be both in use by the interrupted code and usable by the interrupt handler. Oh, and it's totally up to you (-num-imag-regs and a custom linker script) how many caller-saved registers (really how many registers at all) there are for both interrupt and interrupted code; tune to your heart's content, or do something totally custom via custom-allocating your ZP with symbols, etc."

Then they could split up their binary to use different numbers of ZP regs, etc, whatever. I guess this is a more C-ish version of "Just write it yourself in ASM". Shouldn't require any more work on our side beyond making sure that SP holds the "always past the last stack frame" invariant, so I'll close this. At some point I'll try to write a display list interrupt for the Atari 800 in C and see what that's actually like.

from llvm-mos.

johnwbyrd avatar johnwbyrd commented on May 26, 2024

An interrupt may occur on the 6502 at any moment, such as when the C stack pointer is being incremented or decremented. Ergo, the stack pointer may contain incorrect data when that interrupt is serviced, because the 16 bit value hasn't been fully updated yet. In short, I don't think you can count on the state of imaginary registers being sane whenever an interrupt may occur.

I can think of a few solutions to the naming resolution problem, but none are very pretty.

from llvm-mos.

johnwbyrd avatar johnwbyrd commented on May 26, 2024

I'll resurrect this issue on another project, because it's not that we are refusing to ever doing it -- it's just we are blowing it off until we can invest time in figuring out all the details.

from llvm-mos.

mysterymath avatar mysterymath commented on May 26, 2024

The stack pointer manipulation problem isn't actually as bad as it seems:

  • For decrements, you just need to make sure that the high byte is written first. That way, the stack pointer will always read a value lower than the value provided at function entry (that is, in safe RAM).
  • For increments back to the original SP, the order doesn't matter, since no ordering can produce an effective stack pointer higher than that seen when entering the function or outgoing call frame.

This does mean that the interrupt might start it's stack at some kooky offset below the real SP, but at least it would be below the SP.

This is also one of those "I've only proven it correct, not actually tried it" things. I'd want to be more careful about the math than I have been, and see what the implications are for forcing ordering like that in the code generator. That's the heft of that other bug. I'll add these deets there too; it's pretty vague.

from llvm-mos.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.