dsforth: added "NIP" and "TUCK"
[urasm.git] / dsforth / main_im2.zas
blob4150967e7b5604dbdf93845589e0591e25a846ff
1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; IM2 handling
3 ;; Ketmar Dark
4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6 DSFORTH_OLD_IM2_ORG = 0
8 ;; k8: hell's why?
9 IF 0
10   IF (high($) < 0x80) || (high($) >= 0xc0)
11     IF UFE_AFTER_TRACE
12       $WARNING "im2 interrupt handler must start in [#8000..#BFFF], but it is at #%04X; relocated", $
13       DSFORTH_OLD_IM2_ORG = $
14       org #8000
15     ELSE
16       $ERROR "im2 interrupt handler must start in [#8000..#BFFF], but it is at #%04X", $
17     ENDIF
18   ENDIF
19 ENDIF
21 IntrHandlerAddress equ #FFF5
22   IF USE_P3DOS || USE_SAFE_IM2_STACK
23 intr_saved_sp defw 0
24 intr_saved_af defw 0
25 intr_restore_sp defb 1
26   ENDIF
28 IntrHandler:
29   ;; switch to temporary stack here
30   IF USE_P3DOS || USE_SAFE_IM2_STACK
31   ld    (intr_saved_sp),sp
32   ld    sp,intr_saved_af+2
33   push  af
34   ld    sp,#5C00
35   ; do not switch stack if it is already somewhere in TSTACK
36   ld    a,(intr_saved_sp+1)
37   ld    (intr_restore_sp),a
38   cp    #5C+1
39   jp    nc,.stackok0
40   xor   a
41   ld    sp,(intr_saved_sp)
42 .stackok0:
43   ld    (intr_restore_sp),a
44   push  hl
45   ELSE
46   push  hl
47   push  af
48   ENDIF
49   ; save current LAST_K and clear it
50   IF USE_INTERNAL_LASTK
51     ld    hl,LAST_K
52     ld    a,(hl)
53     ld    (intr_saved_lastk),a
54     xor   a
55     ld    (hl),a
56   ENDIF
57   ; call user ISR
58   ld    hl,#02BF
59 intr_mc_routine_addr equ $-2
60   ld    a,l
61   or    h
62   jp    z,.done
63   push  de
64   push  bc
65   ld    de,.done0
66   push  de
67   jp    (hl)
68 .done0:
69   ; check if a key was pressed
70   IF USE_INTERNAL_LASTK
71     ld    hl,LAST_K
72     ld    a,(hl)
73     ; if a key was pressed, store it into `f_waskeypress` too
74     ld    (f_waskeypress),a
75     or    a
76     jr    nz,.done_waskey
77     ; restore LAST_K
78     ld    a,(intr_saved_lastk)
79     ld    (hl),a
80 .done_waskey:
81   ENDIF
82   pop   bc
83   pop   de
84 .done:
85   IF USE_SFX_ENGINE
86   ;call  intr_sfx
87   ld    a,r
88   or    0x80
89   ld    r,a
90   ENDIF
91   ld    hl,intr_frames
92   inc   (hl)
93   jp    nz,.frdone
94   inc   hl
95   inc   (hl)
96   jp    nz,.frdone
97   inc   hl
98   inc   (hl)
99 .frdone:
100   IF USE_P3DOS || USE_SAFE_IM2_STACK
101   pop   hl
102   di    ; just in case
103   ld    a,(intr_restore_sp)
104   or    a
105   jr    nz,.safeim2_skip_sp_restore
106   ; save current SP now, because we'll need it later
107   ld    (intr_saved_sp),sp
108 .safeim2_skip_sp_restore:
109   ld    sp,intr_saved_af
110   pop   af
111   ld    sp,(intr_saved_sp)
112   ELSE
113   pop   af
114   pop   hl
115   ENDIF
116   ei
117   ret
118 IntrHandlerEnd equ $
120 ;; k8: hell's why?
121   IF (high(IntrHandlerEnd-1) >= 0xc0
122     $ERROR "im2 interrupt handler must end in #8000..#BFFF], but it is at #%04X", IntrHandlerEnd-1
123   ENDIF
125   IF DSFORTH_OLD_IM2_ORG > 0
126     org DSFORTH_OLD_IM2_ORG
127   ENDIF