Signetics 2650 & 2636 程式設計/中斷
中斷是一種機制,允許外部事件向微處理器發出訊號,使其停止正在執行的操作並處理該事件的需求。在這些控制檯中,只有 PVI 能夠做到這一點。導致中斷的事件是
- 每次垂直復位的前沿
- 物件的影片生成完成。
PVI 的中斷在垂直復位訊號的後沿被複位。
PVI 在其 INTREQ 引腳上向處理器發出中斷請求訊號。如果處理器程式狀態字上部的中斷禁止位沒有設定,則以下事件將發生
- 處理器完成正在執行的指令
- 處理器將指令地址暫存器壓入返回地址棧
- 處理器設定中斷禁止位
- 處理器在 INTACK 訊號上發出它接受請求的訊號
- 處理器開始執行一個 ZBSR(分支到相對於位置零的子程式)
- PVI 在資料匯流排上輸出 $03,它內建的中斷向量和 ZBSR 指令的第二個位元組
- 處理器透過從地址 $0003 開始執行來完成 ZBSR 指令
注意,處理器自動儲存的唯一資訊是返回地址。由程式設計師來儲存狀態暫存器和中斷服務例程可能使用的任何通用暫存器(見下文)。
處理器可以透過檢查暫存器 $1FCA 的物件完成位和暫存器 $1FCB 的 VRLE 位來確定 PVI 請求中斷的原因。請注意,這些暫存器的所有位在讀取時被清除,並在 VRST 的後沿被清除。
中斷服務例程透過一個從子程式返回指令來終止,通常是一個 RETE,它會再次啟用中斷,或者可以使用 RETC 指令,如果不需要啟用中斷。
在任何中斷服務結束時,必須將暫存器恢復到中斷髮生時的相同狀態。對於暫存器 r1、r2 和 r3,這通常透過在中斷服務例程期間切換到第二個暫存器組來實現。
暫存器 r0 和程式狀態字下部更麻煩。問題在於,在 2650A 上,程式狀態字只能轉移到 r0,而不能直接轉移到記憶體。在 2650B 上,透過新增 LDPL 和 STPL 指令解決了這個問題。
這不起作用
stra,r0 STORER0 ;save r0 in memory
spsl ;r0 = PSL
stra,r0 STOREPSL ;save PSL in memory
......
..the rest of the interrupt service routine goes here
......
loda,r0 STOREPSL
lpsl ;restore PSL
loda,r0 STORER0 ;restore r0
rete,un
這裡的問題是最後一個 loda 指令會影響恢復的 PSL 中的條件碼位。
一個巧妙的解決方案如下
start_interrupt:
stra,r0 PRESERVER0 ;PRESERVER0 = r0
ppsl $10 ;bank 1
spsl
stra,r0 PRESERVEPSL ;save PSL with bank 1 already selected!
..........
end_interrupt:
loda,r0 PRESERVEPSL ;
strz r4 ;put a copy of PSL in r4
lpsl ;restores psl (but with bank 1 still selected)
loda,r0 PRESERVER0 ;restore r0 (but probably changes the condition code)
andi,r4 $C0 ;this restores the condition code!
cpsl $10 ;switch to bank 0
rete,un ;
如果還不清楚那個 AND 操作是如何工作的,那是因為條件碼位於 PSL 的位 7 和 6 中。它們的二進位制值(00=零,01=正,10=負)對應於 AND $C0 操作的結果
- 00000000 為零
- 01000000 是一個正數
- 10000000 是一個負數

本教程的程式 執行與 同步到物件完成 中相同的任務,但它不是不斷檢查 VRST 的狀態或輪詢 PVI 來檢視物件 1 的影片生成是否已完成,而是依賴於 PVI 的中斷來使處理器停止正在執行的操作並處理髮生的任何事件。
一旦發生中斷,並且暫存器 0 和 PSL 被儲存,中斷服務例程會檢查中斷是否由垂直復位引起。它透過測試 “碰撞” 暫存器 $1FCB 中的 VRLE 位來做到這一點。如果是,則子程式 Object1A 會負責設定物件的初始狀態。然後退出中斷例程,處理器在這種情況下去等待下一個中斷。當下一箇中斷到來時,它一定是由於物件 1 的完成引起的。然而,此時有必要確定是主物件、它的第一個副本還是它的第二個副本引起了中斷。PVI 無法直接告訴我們這一點,因此使用了變數 Obj1dup 來做到這一點。如果變數為 1,則執行子程式 Object1B;這會設定第一個副本並將變數設定為 2。在下一個中斷時,執行 Object1C,這會設定第二個副本並將變數設定為 0。
這是一個非常簡單的程式,只有一個物件引起中斷,而且只需要確定是哪個副本引起了中斷。當使用更多物件時,中斷服務例程還必須確定哪個物件正在引起中斷。這是透過讀取 $1FCA 的 objectstatus 來完成的。位 0-3 根據哪個物件已完成進行設定。
在使用此暫存器時需要小心,因為它在讀取時會被複位,而且它還包含物件/背景碰撞標誌。這意味著所有設定的位都需要立即處理,或者儲存在變數中以便以後使用。