]> git.sur5r.net Git - cc65/blob - libsrc/runtime/stkchk.s
rearranged order of new optimizations to better handle -Oi flag
[cc65] / libsrc / runtime / stkchk.s
1 ;
2 ; Ullrich von Bassewitz, 19.03.2001
3 ;
4 ; Stack checking code. These are actually two routines, one to check the C
5 ; stack, and the other one to check the 6502 hardware stack.
6 ; For performance reasons (to avoid having to pass a parameter), the compiler
7 ; calls the cstkchk routine *after* allocating space on the stack. So the
8 ; stackpointer may already be invalid if this routine is called. In addition
9 ; to that, pushs and pops that are needed for expression evaluation are not
10 ; checked (this would be way too much overhead). As a consequence we will
11 ; operate using a safety area at the stack bottom. Once the stack reaches this
12 ; safety area, we consider it an overflow, even if the stack is still inside
13 ; its' bounds.
14 ;
15
16         .export         stkchk, cstkchk
17         .constructor    initstkchk, 25
18         .import         __STACKSIZE__                   ; Linker defined
19         .import         pusha0, _exit
20         .importzp       sp
21
22         ; Use macros for better readability
23         .macpack        generic
24         .macpack        cpu
25
26
27 ; ----------------------------------------------------------------------------
28 ; Initialization code. This is a constructor, so it is called on startup if
29 ; the linker has detected references to this module.
30
31 .segment        "ONCE"
32
33 .proc   initstkchk
34
35         lda     sp
36         sta     initialsp
37         sub     #<__STACKSIZE__
38         sta     lowwater
39         lda     sp+1
40         sta     initialsp+1
41         sbc     #>__STACKSIZE__
42 .if (.cpu .bitand ::CPU_ISET_65SC02)
43         ina                     ; Add 256 bytes safety area
44 .else
45         add     #1              ; Add 256 bytes safety area
46 .endif
47         sta     lowwater+1
48         rts
49
50 .endproc
51
52 ; ----------------------------------------------------------------------------
53 ; 6502 stack checking routine. Does not need to save any registers.
54 ; Safety zone for the hardware stack is 12 bytes.
55
56 .code
57
58 stkchk: tsx
59         cpx     #12
60         bcc     Fail            ; Jump on stack overflow
61         rts                     ; Return if ok
62
63 ; ----------------------------------------------------------------------------
64 ; C stack checking routine. Does not need to save any registers.
65
66 .code
67
68 cstkchk:
69
70 ; Check the high byte of the software stack
71
72 @L0:    lda     lowwater+1
73         cmp     sp+1
74         bcs     @L1
75         rts
76
77 ; Check low byte
78
79 @L1:    bne     CStackOverflow
80         lda     lowwater
81         cmp     sp
82         bcs     CStackOverflow
83 Done:   rts
84
85 ; We have a C stack overflow. Set the stack pointer to the initial value, so
86 ; we can continue without worrying about stack issues.
87
88 CStackOverflow:
89         lda     initialsp
90         sta     sp
91         lda     initialsp+1
92         sta     sp+1
93
94 ; Generic abort entry. We should output a diagnostic here, but this is
95 ; difficult, since we're operating at a lower level here.
96
97 Fail:   lda     #4
98         ldx     #0
99         jmp     _exit
100
101 ; ----------------------------------------------------------------------------
102 ; Data
103
104 .segment        "INIT"
105
106 ; Initial stack pointer value. Stack is reset to this in case of overflows to
107 ; allow program exit processing.
108 initialsp:      .res    2
109
110 ; Stack low water mark.
111 lowwater:       .res    2
112
113
114