| ------------------------------------------------------------------------------ | viint.s -- VSDD Vertical Interval interrupt handler for the Buchla 700 | Version 17 -- 1989-12-19 -- D.N. Lynx Crowe | VIint | VSDD Vertical Interval interrupt handler. Enables display of | any object whose bit is set in vi_ctl. Bit 0 = object 0, etc. | SetPri() uses BIOS(B_SETV, 25, VIint) to set the interrupt | vector and lets VIint() enable the object. If vi_dis | is set, SetPri() won't enable the interrupt or set the vector | so that several objects can be started up at once. | This routine also sets the base address and scroll offset | for the score display object if vi_sadr is non-zero, | after a delay for VSDD FRAMESTOP synchronization. | ------------------------------------------------------------------------------ .text .xdef VIint | Vertical Interval int. handler .xdef vi_sadr | score object base address .xdef vi_scrl | score object scroll offset .xdef lclsadr | local scroll address .xdef lclscrl | local scroll offset .xdef vdelay | VSDD scroll delay .xdef VIct1 | VSDD interrupt R11 .xdef VIct2 | VSDD interrupt R11 .xdef VIct3 | VSDD interrupt R11 .xdef VIct4 | VSDD interrupt R11 .xref v_regs | VSDD registers .xref v_odtab | VSDD object descriptor table .xref vi_clk | scroll delay timer .xref vi_ctl | unblank control word .xref vi_tag | VSDD 'needs service' tag .page | Miscellaneous equates: | ---------------------- DELAY = 17 | FRAMESTOP sync delay in Ms STACKSR = 32 | offset to sr on stack V_BLA = 4 | V_BLA (blank) bit number VSDD_R5 = 10 | VSDD R5 byte offset in v_regs VSDD_R11 = 22 | VSDD R11 byte offset in v_regs VT_BASE = 128 | word offset of VSDD Access Table VT_1 = VT_BASE+300 | high time VT_2 = VT_BASE+2 | low time | ------------------------------------------------------------------------------ | Stack picture after movem.l at entry: | ------------------------------------- | LONG PC +34 | WORD SR +32 STACKSR | LONG A6 +28 | LONG A2 +24 | LONG A1 +20 | LONG A0 +16 | LONG D3 +12 | LONG D2 +8 | LONG D1 +4 | LONG D0 +0 | ------------------------------------------------------------------------------ .page | VIint -- Vertical interval interrupt handler | ----- ----------------------------------- VIint: movem.l d0-d3/a0-a2/a6,-(a7) | save registers addi.w #0x0100,STACKSR(a7) | raise IPL in sr on the stack move.w v_regs+VSDD_R11,VIct1 | save the VSDD R11 value tst.w vi_sadr | see if we should scroll beq viunbl | jump if not | ------------------------------------------------------------------------------ | setup delayed scroll parameters | ------------------------------------------------------------------------------ move.w v_regs+VSDD_R5,d0 | get VSDD R5 move.w d0,d1 | save it for later andi.w #0x0180,d0 | see if we're already in bank 0 beq dlyscrl | jump if so clr.w v_regs+VSDD_R5 | set bank 0 move.w v_regs+VSDD_R11,VIct2 | save the VSDD R11 value vw1a: cmp.w #VT_1,v_regs+VSDD_R11 | wait for FRAMESTOP bcc vw1a | ... vw2a: cmp.w #VT_1,v_regs+VSDD_R11 | ... bcs vw2a | ... vw3a: cmp.w #VT_1,v_regs+VSDD_R11 | ... bcc vw3a | ... vw4a: cmp.w #VT_2,v_regs+VSDD_R11 | ... bcs vw4a | ... dlyscrl: tst.w vi_tag | wait for previous scroll bne dlyscrl | ... move.w vi_sadr,lclsadr | save address for timeint move.w vi_scrl,lclscrl | save offset for timeint clr.w vi_sadr | reset for next time clr.w vi_scrl | ... move.w vdelay,vi_clk | set the scroll delay timer st vi_tag | set the 'need service' tag | ------------------------------------------------------------------------------ | check for unblank requests | ------------------------------------------------------------------------------ move.w vi_ctl,d2 | get the unblank control word beq viexit | exit if nothing to unblank bra unblnk | go unblank some objects viunbl: move.w vi_ctl,d2 | get the unblank control word beq vidone | exit if nothing to unblank move.w v_regs+VSDD_R5,d0 | get VSDD R5 move.w d0,d1 | save it for later andi.w #0x0180,d0 | see if we're already in bank 0 beq unblnk | jump if so clr.w v_regs+VSDD_R5 | set bank 0 move.w v_regs+VSDD_R11,VIct3 | save the VSDD R11 value vw1b: cmp.w #VT_1,v_regs+VSDD_R11 | wait for FRAMESTOP bcc vw1b | ... vw2b: cmp.w #VT_1,v_regs+VSDD_R11 | ... bcs vw2b | ... vw3b: cmp.w #VT_1,v_regs+VSDD_R11 | ... bcc vw3b | ... vw4b: cmp.w #VT_2,v_regs+VSDD_R11 | ... bcs vw4b | ... .page | ------------------------------------------------------------------------------ | unblank objects indicated by contents of d2 (loaded earlier from vi_ctl) | ------------------------------------------------------------------------------ unblnk: clr.w d3 | clear the counter clr.w vi_ctl | clear the unblank control word lea v_odtab,a1 | point at first object vicheck: btst d3,d2 | check the object bit beq vinext | go check next one if not set move.w (a1),d0 | get v_odtab[obj][0] bclr #V_BLA,d0 | clear the blanking bit move.w d0,(a1) | set v_odtab[obj][0] vinext: cmpi.w #15,d3 | see if we're done beq viexit | jump if so addq.l #8,a1 | point at next object addq.w #1,d3 | increment object counter bra vicheck | go check next object | ------------------------------------------------------------------------------ | switch back to the bank the interrupted code was using if we changed it | ------------------------------------------------------------------------------ viexit: move.w d1,d0 | see if we were in bank 0 andi.w #0x0180,d0 | ... beq vidone | jump if so viwait: tst.w vi_tag | wait for timer to run out bne viwait | ... so timeint sees bank 0 move.w d1,v_regs+VSDD_R5 | restore v_regs[5] to old bank move.w v_regs+VSDD_R11,VIct4 | save the VSDD R11 value vw1c: cmp.w #VT_1,v_regs+VSDD_R11 | wait for FRAMESTOP bcc vw1c | ... vw2c: cmp.w #VT_1,v_regs+VSDD_R11 | ... bcs vw2c | ... vw3c: cmp.w #VT_1,v_regs+VSDD_R11 | ... bcc vw3c | ... vw4c: cmp.w #VT_2,v_regs+VSDD_R11 | ... bcs vw4c | ... | ------------------------------------------------------------------------------ | restore registers and return to interrupted code | ------------------------------------------------------------------------------ vidone: movem.l (a7)+,d0-d3/a0-a2/a6 | restore registers rte | return from interrupt .page | ------------------------------------------------------------------------------ .data | ------------------------------------------------------------------------------ vdelay: .dc.w DELAY | VSDD scroll delay | ------------------------------------------------------------------------------ .bss | ------------------------------------------------------------------------------ vi_sadr: .ds.w 1 | score object base address vi_scrl: .ds.w 1 | score object scroll offset lclsadr: .ds.w 1 | local copy of vi_sadr lclscrl: .ds.w 1 | local copy of vi_scrl VIct1: .ds.w 1 | VSDD R11 value at interrupt VIct2: .ds.w 1 | VSDD R11 value at interrupt VIct3: .ds.w 1 | VSDD R11 value at interrupt VIct4: .ds.w 1 | VSDD R11 value at interrupt .end