home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / GLEN / APPLE2.ZIP / INT.ASM < prev    next >
Assembly Source File  |  1990-04-02  |  11KB  |  320 lines

  1.     Page    58,132
  2.     Title    INT.ASM     Interrupt Processor
  3. ;******************************************************************************
  4. ;
  5. ;   Name:    INT.ASM     Interrupt Processor
  6. ;
  7. ;   Group:    Emulator
  8. ;
  9. ;   Revision:    1.00
  10. ;
  11. ;   Date:    January 30, 1988
  12. ;
  13. ;   Author:    Randy W. Spurlock
  14. ;
  15. ;******************************************************************************
  16. ;
  17. ;  Module Functional Description:
  18. ;
  19. ;        This module contains all the code for the Apple
  20. ;    emulator interrupt handler.
  21. ;
  22. ;******************************************************************************
  23. ;
  24. ;  Changes:
  25. ;
  26. ;    DATE     REVISION                DESCRIPTION
  27. ;  --------   --------    -------------------------------------------------------
  28. ;   1/30/88    1.00    Original
  29. ;
  30. ;******************************************************************************
  31.     Page
  32. ;
  33. ;  Public Declarations
  34. ;
  35.     Public    Int_Init        ; Interrupt initialization routine
  36.     Public    Int_Reset        ; Interrupt reset routine
  37.     Public    Int_Update        ; Emulator interrupt update routine
  38.     Public    Interrupt        ; Interrupt processing routine
  39.     Public    Dummy_Int        ; Dummy interrupt processing routine
  40. ;
  41. ;  External Declarations
  42. ;
  43.     Extrn    Timer_Int:Near        ; Timer interrupt routine    (TIMER)
  44.     Extrn    Timer_Init:Near     ; Timer initialization routine    (TIMER)
  45.     Extrn    Timer_Reset:Near    ; Timer reset routine        (TIMER)
  46.     Extrn    Key_Int:Near        ; Keyboard interrupt routine (KEYBOARD)
  47.     Extrn    Emulator:Near        ; Emulator entry point          (EMULATE)
  48.     Extrn    Error:Near        ; Apple emulator error routine    (APPLE)
  49.     Extrn    Exit:Near        ; Apple emulator exit routine    (APPLE)
  50.     Extrn    Int_Table:Word        ; Interrupt jump table         (DATA)
  51.     Extrn    Original_Int_8:Dword    ; Original interrupt 8 vector     (DATA)
  52.     Extrn    Original_Int_9:Dword    ; Original interrupt 9 vector     (DATA)
  53.     Extrn    System_Flag:Byte    ; Apple emulator system flag byte(DATA)
  54.     Extrn    Emulate_Flag:Byte    ; Emulator interrupt flag byte     (DATA)
  55. ;
  56. ;  LOCAL Equates
  57. ;
  58. MAX_INTERRUPT    Equ    08h        ; Maximum interrupt count value
  59. INT_TIMER    Equ    08h        ; Timer hardware interrupt number
  60. INT_KEY     Equ    09h        ; Keyboard hardware interrupt number
  61. INT_MASK    Equ    7Fh        ; Dummy interrupt clear mask value
  62. ;
  63. ;  Define any include files needed
  64. ;
  65.     Include     Macros.inc    ; Include the macro definitions
  66.     Include     Equates.inc    ; Include the equate definitions
  67.     Include     Strucs.inc    ; Include the structure definitions
  68.     .286c                ; Include 80286 instructions
  69.     Page
  70. ;
  71. ;  Define the emulator code segment
  72. ;
  73. Emulate Segment Word Public 'EMULATE'   ; Emulator code segment
  74.     Assume    cs:Emulate, ds:Nothing, es:Nothing
  75.     Subttl    Int_Init    Interrupt Initialization
  76.     Page    +
  77. ;******************************************************************************
  78. ;
  79. ;    Int_Init()
  80. ;
  81. ;        Save the required registers
  82. ;        Save the original interrupt 8 (Timer) vector
  83. ;        Save the original interrupt 9 (Keyboard) vector
  84. ;        Set the new interrupt 8 vector
  85. ;        Call the timer initialization routine
  86. ;        Set the new interrupt 9 vector
  87. ;        Set the interrupt patched flag
  88. ;        Restore the required registers
  89. ;        Return to the caller
  90. ;
  91. ;    Registers on Entry:
  92. ;
  93. ;        None
  94. ;
  95. ;    Registers on Exit:
  96. ;
  97. ;        None
  98. ;
  99. ;******************************************************************************
  100.         Even            ; Force procedure to even address
  101. Int_Init    Proc    Near        ; Interrupt initialization procedure
  102.     Save    ax,bx,dx,ds,es        ; Save the required registers
  103.     mov    ah,GET_VECTOR        ; Get interrupt vector function code
  104.     mov    al,INT_TIMER        ; Get timer hardware interrupt (8)
  105.     int    DOS            ; Get the current timer interrupt
  106.     mov    Word Ptr cs:[Original_Int_8 + 0],bx
  107.     mov    Word Ptr cs:[Original_Int_8 + 2],es
  108.     mov    ah,GET_VECTOR        ; Get interrupt vector function code
  109.     mov    al,INT_KEY        ; Get keyboard hardware interrupt (9)
  110.     int    DOS            ; Get the current keyboard interrupt
  111.     mov    Word Ptr cs:[Original_Int_9 + 0],bx
  112.     mov    Word Ptr cs:[Original_Int_9 + 2],es
  113.     mov    ax,cs            ; Get the current CS register value
  114.     mov    ds,ax            ; Setup DS to current CS value
  115.     lea    dx,cs:[Timer_Int]    ; Get the new timer interrupt offset
  116.     mov    ah,SET_VECTOR        ; Get set interrupt vector function code
  117.     mov    al,INT_TIMER        ; Get timer hardware interrupt (8)
  118.     int    DOS            ; Set the new timer interrupt
  119.     call    Timer_Init        ; Call the timer initialization routine
  120.     lea    dx,cs:[Key_Int]     ; Get the new keyboard interrupt offset
  121.     mov    ah,SET_VECTOR        ; Get set interrupt vector function code
  122.     mov    al,INT_KEY        ; Get keyboard hardware interrupt (9)
  123.     int    DOS            ; Set the new keyboard interrupt
  124.     or    cs:[System_Flag],PATCHED; Set interrupts patched flag
  125.     Restore ax,bx,dx,ds,es        ; Restore the required registers
  126.     ret                ; Return to the caller
  127. Int_Init    Endp            ; End of the Int_Init procedure
  128.     Subttl    Int_Reset    Interrupt Reset
  129.     Page    +
  130. ;******************************************************************************
  131. ;
  132. ;    Int_Reset()
  133. ;
  134. ;        Save the required registers
  135. ;        If interrupts have been patched
  136. ;            Call the timer reset routine
  137. ;            Restore the original interrupt 8 (Timer) vector
  138. ;            Restore the original interrupt 9 (Keyboard) vector
  139. ;        Endif interrupts not patched
  140. ;        Restore the required registers
  141. ;        Return to the caller
  142. ;
  143. ;    Registers on Entry:
  144. ;
  145. ;        None
  146. ;
  147. ;    Registers on Exit:
  148. ;
  149. ;        None
  150. ;
  151. ;******************************************************************************
  152.         Even            ; Force procedure to even address
  153. Int_Reset    Proc    Near        ; Interrupt reset procedure
  154.     Save    ax,dx,ds        ; Save the required registers
  155.     test    cs:[System_Flag],PATCHED; Check for interrupts patched
  156.     jz    Reset_Done        ; Jump if interrupts not patched
  157.     call    Timer_Reset        ; Call the timer reset routine
  158.     mov    ah,SET_VECTOR        ; Get the set interrupt function code
  159.     mov    al,INT_TIMER        ; Get timer hardware interrupt (8)
  160.     mov    dx,Word Ptr cs:[Original_Int_8 + 0]
  161.     mov    ds,Word Ptr cs:[Original_Int_8 + 2]
  162.     int    DOS            ; Restore original timer interrupt
  163.     mov    ah,SET_VECTOR        ; Get the set interrupt function code
  164.     mov    al,INT_KEY        ; Get keyboard hardware interrupt (9)
  165.     mov    dx,Word Ptr cs:[Original_Int_9 + 0]
  166.     mov    ds,Word Ptr cs:[Original_Int_9 + 2]
  167.     int    DOS            ; Restore original keyboard interrupt
  168. Reset_Done:
  169.     Restore ax,dx,ds        ; Restore the required registers
  170.     ret                ; Return to the caller
  171. Int_Reset    Endp            ; End of the Int_Reset procedure
  172.     Subttl    Int_Update    Emulator Interrupt Update Routine
  173.     Page    +
  174. ;******************************************************************************
  175. ;
  176. ;    Int_Update(RAM_Space, Registers, Address, Stack_Frame)
  177. ;
  178. ;        Save the required registers
  179. ;        If currently executing 65C02 emulator
  180. ;            If there is a pending interrupt request
  181. ;                Set the emulator interrupt flag bit
  182. ;            Endif
  183. ;        Endif
  184. ;        Restore the required registers
  185. ;        Return control to the caller
  186. ;
  187. ;    Registers on Entry:
  188. ;
  189. ;        DL    - 65C02 Accumulator
  190. ;        DH    - 65C02 processor flags
  191. ;        CL    - 65C02 Y index register
  192. ;        CH    - 65C02 X index register
  193. ;        BX    - 65C02 Stack pointer
  194. ;        SI    - 65C02 Program counter
  195. ;        DI    - Current opcode address
  196. ;        DS    - 65C02 RAM space
  197. ;        SS:SP - Stack Frame
  198. ;
  199. ;    Registers on Exit:
  200. ;
  201. ;        AX    - Destroyed
  202. ;        DH    - Emulator interrupt set if interrupt pending
  203. ;
  204. ;******************************************************************************
  205.         Even            ; Force procedure to even address
  206. Int_Update    Proc    Near        ; Emulator interrupt update procedure
  207.     Save    bp            ; Save the required registers
  208.     mov    bp,sp            ; Setup access to the stack frame
  209.     mov    ax,cs            ; Get the Emulate code segment value
  210.     cmp    ax,ss:[bp.Current_CS]    ; Check for executing in Emulate segment
  211.     jne    Update_Exit        ; Jump if NOT in the Emulate segment
  212.     lea    ax,cs:[Emulator]    ; Get emulator entry point address
  213.     cmp    ax,ss:[bp.Current_IP]    ; Check for executing 65C02 emulator
  214.     jbe    Update_Exit        ; Jump if NOT in 65C02 emulator
  215.     test    cs:[Emulate_Flag],INT_REQUEST
  216.     jz    Update_Exit        ; Jump if no pending interrupt
  217.     or    dh,CPU_R        ; Set emulator interrupt flag bit
  218. Update_Exit:
  219.     Restore bp            ; Restore the required registers
  220.     ret                ; Return control to the caller
  221. Int_Update    Endp            ; End of the Interrupt procedure
  222.     Subttl    Interrupt    Interrupt Processor
  223.     Page    +
  224. ;******************************************************************************
  225. ;
  226. ;    Interrupt(RAM_Space, Registers, Address)
  227. ;
  228. ;        Clear the emulator interrupt flag bit
  229. ;        Setup Interrupt_Counter (MAX_INTERRUPT - 1 = 7)
  230. ;        While Interrupt_Counter >= 0
  231. ;            If this interrupt bit is set
  232. ;                Jump to the correct routine for interrupt
  233. ;            Endif
  234. ;            Decrement the Interrupt_Counter
  235. ;        Endwhile
  236. ;        Go process the next opcode (Never gets here)
  237. ;
  238. ;    Registers on Entry:
  239. ;
  240. ;        DL    - 65C02 Accumulator
  241. ;        DH    - 65C02 processor flags
  242. ;        CL    - 65C02 Y index register
  243. ;        CH    - 65C02 X index register
  244. ;        BX    - 65C02 Stack pointer
  245. ;        SI    - 65C02 Program counter
  246. ;        DI    - Current opcode address
  247. ;        DS    - 65C02 RAM space
  248. ;
  249. ;    Registers on Exit:
  250. ;
  251. ;        AX    - Destroyed
  252. ;        BP    - Destroyed
  253. ;
  254. ;******************************************************************************
  255.         Even            ; Force procedure to even address
  256. Interrupt    Proc    Near        ; Interrupt processing procedure
  257.     and    dh,Not CPU_R        ; Clear emulator interrupt flag bit
  258.     mov    ah,MAX_INTERRUPT - 1    ; Get the maximum interrupt count - 1
  259.     mov    al,cs:[Emulate_Flag]    ; Get the emulator flags (Interrupt)
  260. Interrupt_Loop:
  261.     shr    al,1            ; Check for interrupt occurred
  262.     jnc    Next_Interrupt        ; Jump if this is not the interrupt
  263.     mov    al,ah            ; Get the interrupt number
  264.     xor    ah,ah            ; Convert interrupt number to full word
  265.     shl    ax,1            ; Convert interrupt to table index
  266.     mov    bp,ax            ; Setup to go to the correct routine
  267.     jmp    cs:[bp + Int_Table]    ; Jump to the correct interrupt routine
  268. Next_Interrupt:
  269.     dec    ah            ; Decrement the interrupt counter
  270.     jns    Interrupt_Loop        ; Jump if more interrupts to check
  271.     jmp    di            ; Go process next opcode (Never here)
  272. Interrupt    Endp            ; End of the Interrupt procedure
  273.     Subttl    Dummy_Int    Dummy Interrupt Routine
  274.     Page    +
  275. ;******************************************************************************
  276. ;
  277. ;    Dummy_Int(Interrupt_Number, RAM_Space, Registers, Address)
  278. ;
  279. ;        Save the required registers
  280. ;        Calculate interrupt mask value
  281. ;        Clear the pending dummy interrupt
  282. ;        Restore the required registers
  283. ;        Go process the next opcode
  284. ;
  285. ;    Registers on Entry:
  286. ;
  287. ;        DL    - 65C02 Accumulator
  288. ;        DH    - 65C02 processor flags
  289. ;        CL    - 65C02 Y index register
  290. ;        CH    - 65C02 X index register
  291. ;        BX    - 65C02 Stack pointer
  292. ;        SI    - 65C02 Program counter
  293. ;        AX    - Interrupt number (Doubled)
  294. ;        DI    - Current opcode address
  295. ;        DS    - 65C02 RAM space
  296. ;
  297. ;    Registers on Exit:
  298. ;
  299. ;        AX    - Destroyed
  300. ;
  301. ;******************************************************************************
  302.         Even            ; Force procedure to even address
  303. Dummy_Int    Proc    Near        ; Interrupt processing procedure
  304.     Save    cx            ; Save the required registers
  305.     shr    ax,1            ; Restore the interrupt number
  306.     mov    ah,INT_MASK        ; Get interrupt mask value
  307.     mov    cl,al            ; Get the interrupt number in CL
  308.     ror    ah,cl            ; Rotate interrupt mask into position
  309.     and    cs:[Emulate_Flag],ah    ; Clear the current dummy interrupt
  310.     Restore cx            ; Restore the required registers
  311.     jmp    di            ; Go process the current opcode
  312. Dummy_Int    Endp            ; End of the Dummy_Int procedure
  313. ;******************************************************************************
  314. ;
  315. ;    Define the end of the Emulator Code Segment
  316. ;
  317. ;******************************************************************************
  318. Emulate Ends
  319.     End                ; End of the Int module
  320.