..

Week of the 04/27/2026 - #18

Contents

tech

  • ZX Spectrum Demos / Art

ZX Spectrum Demos / Art

Last weekend was the Multimatograf 2026 demo party @Vologda, Rusia. Here are some entries that caught my attention:

Oldschool graphics entry

Oldschool graphics entry

Oldschool graphics entry

Oldschool graphics entry

ASCII/Petscii

These four where from the Oldschool graphics compo and ASCII/ANSI graphics.

In terms of demos I liked these two for the ZX Spectrum:

Text UIs

I’m interested in text based ui’s. Here are some resources I found:

TUI on a cellphone

TUI on a cellphone

TUI on a cellphone

TUI inspiration

TUI inspiration

TUI inspiration

Apple //c vblank

I asked Gemini to tell me how to implement the Apple IIc’s vblank interrupt handler. Here’s what Gemini said:

To set up an interrupt handler on an Apple IIc without an operating system, you must bypass the standard vectoring used by ProDOS/DOS and directly interface with the hardware and the 6502 (65C02) architecture.

The Apple IIc ROM contains the permanent interrupt vector at $FFFE–$FFFF. This vector points to a routine in the ROM that eventually jumps to a specific RAM address that you can control.

1. Identify the User Interrupt Vector

In the Apple II architecture, the ROM-based IRQ handler redirects control to a “User Vector” located in RAM. Without an OS, you are responsible for placing your routine’s address here:

  • Vector Address: $03FE (Low Byte) and $03FF (High Byte).
  • Example: If your code starts at $4000, you must POKE/STA $00 into $03FE and $40 into $03FF.

2. Prepare the Interrupt Service Routine (ISR)

Your handler must follow a specific structure to ensure the CPU returns to its previous task safely. Unlike a standard subroutine (RTS), an interrupt must end with RTI (Return from Interrupt).

Key Requirements for your ISR:

  • Save Registers: The 65C02 does not automatically save the Accumulator, X, or Y registers. You must push them to the stack at the start and pull them back at the end.
  • Verify Source: Since multiple hardware components (VBL, Mouse, Serial) can trigger an IRQ, your code should check softswitches (like $C019 for VBL) to confirm the source
  • Clear the Interrupt: You must reset the hardware flag that triggered the interrupt. For VBL, this is typically done by reading/writing to $C019.
  • Exit with RTI: Use the RTI instruction to restore the processor status and program counter from the stack.

3. Enable Hardware and CPU Interrupts

Once your vector and handler are ready, you must tell both the hardware and the CPU to allow interrupts.

  1. Hardware Level: Use the VBL softswitches mentioned previously ($C05B with IOUDis management) to enable the signal at the source.
  2. CPU Level: Execute the CLI (Clear Interrupt Disable) assembly instruction. This clears the “I” flag in the status register, allowing the 65C02 to respond to IRQ signals.

4. Implementation Example (Assembly)

; --- Setup ---
SEI             ; Disable interrupts while configuring
LDA #<MY_ISR    ; Get low byte of handler address
STA $03FE       ; Store in user vector
LDA #>MY_ISR    ; Get high byte
STA $03FF
; (Insert Apple IIc VBL hardware enable code here)
CLI             ; Enable interrupts
RTS             ; Return to main program loop

; --- Handler ---
MY_ISR:
    PHA         ; Save Accumulator
    PHX         ; Save X (65C02 specific)
    PHY         ; Save Y (65C02 specific)

    BIT $C019   ; Check if VBL is the cause (Bit 7)
    BPL NEXT    ; If not VBL, skip or check other sources
    STA $C019   ; Clear VBL interrupt flag

    ; [Your Code Here - Keep it fast!]

NEXT:
    PLY         ; Restore Y
    PLX         ; Restore X
    PLA         ; Restore Accumulator
    RTI         ; Return from Interrupt

By placing your routine’s address at $03FE and ending with RTI`, you successfully hook into the Apple IIc’s native interrupt chain.

Enhanced Apple IIe Interrupt Setup

On an Enhanced Apple IIe, the code for setting up an interrupt handler is conceptually identical to the IIc, but there is one critical hardware difference: The standard Apple IIe does not have built-in VBL interrupt hardware.

While the Enhanced IIe shares the 65C02 CPU and firmware features with the IIc, the circuitry to trigger an interrupt at every vertical blanking interval was a specific addition to the IIc’s integrated motherboard.

1. The Core Difference: No Built-in VBL

On an Enhanced IIe, the softswitches at $C019, $C05A, and $C05B generally do not generate interrupts unless you have added specific expansion hardware.

  • Apple IIc: VBL interrupts are native and built-in.
  • Enhanced IIe: To get a VBL interrupt, you typically need an AppleMouse II card (usually in Slot 4) or a Mockingboard.

2. Equivalent Setup (Using a Mouse Card)

If you have a Mouse Card in Slot 4, you must initialize the card’s firmware to begin generating interrupts. The “User Vector” at $03FE/$03FF remains the same as the IIc.

; --- IIe Setup (Assuming Mouse Card in Slot 4) ---
SEI             ; Disable interrupts

LDA #<MY_ISR    ; Set User Vector at $03FE
STA $03FE
LDA #>MY_ISR
STA $03FF

; Enable Mouse Card Interrupts (Slot 4 example)
LDA #$01        ; Mode 1: Mouse interrupts on
LDX #$40        ; Slot 4 ($C400)
JSR $C412       ; SETMOUSE call (Standard entry point)

CLI             ; Enable CPU interrupts
RTS

3. Polling VBL (Status Only)

If you do not have an interrupt-generating card, you cannot use an ISR for VBL on a IIe. You can, however, poll the VBL status to synchronize code (without using interrupts).

  • IIe Polling Loop:
    WAITVBL:
        BIT $C019   ; Check VBL status
        BPL WAITVBL ; Wait until bit 7 is high (VBL active)
    

4. Summary Table

Feature Apple IIc Enhanced Apple IIe
CPU 65C02 65C02
VBL IRQ Built-in Requires Card (Mouse/Mockingboard)
User Vector $03FE/$03FF $03FE/$03FF
Softswitch $C019 Status & Clear Status only (usually)