*** Configure interrupt routine. *** NOTE: This assumes that VDP R1 has bit >20 set so that the VDP actually ***       does generate interrupts.  This is somewhat counter-intuitive ***       because we won't actually process those interrupts.  Indeed we'll ***       wait for the first one to occur then never clear it.  However, ***       it is necessary for this hack to work correctly. *** * CONFIG LIMI 0 * Munge the GPLWS.        LWPI >83E0        CLR  R14               * Disable cassette interrupt and protect >8379.        LI   R15,>877B         * Disable VDPST reading and protect >837B. * Munge the INTWS.        LWPI >83C0        SETO R1                * Disable all VDP interrupt processing.        LI   R2,INTRPT         * Set our interrupt vector.        SETO R11               * Disable screen timeouts.        CLR  R12               * Set to 9901 CRU base. * Synchronize with the next VDP interrupt. SYNC   TB   2                 * Check for VDP interrupt.        JEQ  SYNC * Configure the 9901 for interrupts.        SBO  1                 * Enable external interrupt prioritization.        SBZ  2                 * Disable VDP interrupt prioritization.        SBZ  3                 * Disable Timer interrupt prioritization. * Done        LWPI MYWS              * Switch back to old workspace.        RT                     * Done. *** *** Interrupt routine. *** INTRPT LWPI >83C0        SBZ  2                 * Disable VDP interrupt prioritization. * Decode interrupt.        TB   1                 * Was it an external interrupt?        JNE  EXTINT        TB   3                 * Was it a timer interrupt?        JNE  TIMINT        RTWP                   * Must have been spurious. * Handle external interrupt. EXTINT ... do something...        RTWP * Handle timer interrupt. TIMINT SBO  3                 * Reset timer interrupt latch. ... do something...        RTWP The main program just needs to do LIMI 1 / LIMI 0 when it is ready to handle interrupts as usual. The following locations are destroyed or reserved by the ROM interrupt routine: >83C2 : Contains >FFFF.  (most significant bit must be 1) >83C4 : Contains address of user interrupt routine. >83D6 : Incremented by 2 each interrupt.  (least significant bit must be 1) >83D8 : Destroyed. >83E2 : Destroyed. >83F0 : Destroyed if interrupt routine returns normally. >83F6 : Set to return address from user interrupt routine. >83F8 : Cleared then set to address of user interrupt routine prior to call. >83FC : Contains >0000.  (contents ANDed with >FF20 must equal 0) >83FE : Contains >877B.