stack_test.asm (3601B)
1 ;;; Copyright 2021 Gerd Beuster (gerd@frombelow.net). This is free 2 ;;; software under the GNU GPL v3 license or any later version. See 3 ;;; COPYING in the root directory for details. 4 5 ;;; A data stack 6 .include "os.inc" 7 8 .dsection code 9 .section code 10 11 ;; start_of_stack = $7fff-$206+$1 ; Minimal stack as defined in ROM 12 start_of_stack = end_of_code ; Stack starts right after code 13 init: 14 .block 15 cld 16 #ds.INIT_STACK start_of_stack 17 #io.SETUP 18 jsr stack_test 19 jsr test_local_variables 20 jsr test_recursion 21 jsr io.getc 22 jmp ($fffc) ; Reset 23 loop: 24 jmp loop 25 .bend 26 27 stack_test: 28 .block 29 ;; Testing empty stack 30 jsr ds.create_stack_frame 31 jsr ds.delete_stack_frame 32 lda ds.ptr 33 cmp #<start_of_stack 34 #CHECK_ERROR 35 lda ds.ptr+1 36 cmp #>start_of_stack 37 #CHECK_ERROR 38 ;; Push and pull 39 jsr ds.create_stack_frame 40 lda #$a0 41 sta (ds.ptr) 42 #ds.PUSH $01 43 lda #$b0 44 sta (ds.ptr) 45 #ds.PUSH $01 46 lda #$c0 47 sta (ds.ptr) 48 #ds.PUSH $01 49 #ds.PULL $01 50 lda (ds.ptr) 51 cmp #$c0 52 #CHECK_ERROR 53 #ds.PULL $01 54 lda (ds.ptr) 55 cmp #$b0 56 #CHECK_ERROR 57 #ds.PULL $01 58 lda (ds.ptr) 59 cmp #$a0 60 #CHECK_ERROR 61 #ds.PUSH $01 62 ;; Push and pull with new frame 63 lda #$a1 64 sta (ds.ptr) 65 #ds.PUSH $01 66 lda ds.ptr ; Save stack pointer 67 pha ; for later comparison 68 jsr ds.create_stack_frame 69 ldy #$00 70 lda #$b1 71 sta (ds.ptr),y 72 inc y 73 sta (ds.ptr),y 74 inc y 75 sta (ds.ptr),y 76 inc y 77 #ds.PUSH $03 78 #ds.PULL $01 79 lda (ds.ptr) 80 cmp #$b1 81 #CHECK_ERROR 82 jsr ds.delete_stack_frame 83 pla ; Still same stack pointer 84 cmp ds.ptr ; as before creating and 85 #CHECK_ERROR ; deleting frame? 86 #ds.PULL $01 87 lda (ds.ptr) 88 cmp #$a1 89 #CHECK_ERROR 90 #ds.PULL $01 91 lda (ds.ptr) 92 cmp #$a0 93 #CHECK_ERROR 94 jsr ds.delete_stack_frame 95 lda ds.ptr ; Stack should be 96 cmp #<start_of_stack ; empty again. 97 #CHECK_ERROR 98 lda ds.ptr+1 99 cmp #>start_of_stack 100 #CHECK_ERROR 101 #ds.PUSH_WORD $abcd 102 jsr ds.pull_a 103 cmp #$ab 104 #CHECK_ERROR 105 jsr ds.pull_a 106 cmp #$cd 107 #CHECK_ERROR 108 #io.PRINTSNL "Stack test completed!" 109 rts 110 .bend 111 112 CHECK_ERROR: .macro 113 beq error_cont 114 error: 115 #io.PRINTSNL "Error!" 116 error_loop: 117 jmp error_loop 118 error_cont: 119 .endm 120 121 test_local_variables: 122 .block 123 jsr ds.create_stack_frame 124 ;; Working with local variables 125 #ds.PUSH $02 ; Create local variables 126 lda #$ab 127 #ds.sta_LOCAL 0 128 lda #$00 129 #ds.lda_LOCAL 0 130 inc a 131 #ds.sta_LOCAL 1 132 lda #$00 133 #ds.lda_LOCAL 1 134 cmp #$ac 135 #CHECK_ERROR 136 ;; Passing paramters 137 lda #$01 138 #ds.sta_PARAM 0 139 lda #$02 140 #ds.sta_PARAM 1 141 jsr test_param 142 #ds.lda_PARAM 0 143 cmp #$03 144 #CHECK_ERROR 145 jsr ds.delete_stack_frame 146 #io.PRINTSNL "Local variable test completed!" 147 rts 148 .bend 149 150 test_param: 151 .block 152 jsr ds.create_stack_frame 153 #ds.PUSH $02 ; Local variables (here: parameters) 154 #ds.lda_LOCAL 0 155 clc 156 #ds.adc_LOCAL 1 157 #ds.sta_LOCAL 0 158 jsr ds.delete_stack_frame 159 rts 160 .bend 161 162 test_recursion: 163 .block 164 jsr ds.create_stack_frame 165 #ds.PUSH $02 ; Create local variables 166 lda #$04 ; Recursion counter 167 #ds.sta_LOCAL 0 168 lda #$01 ; Initial value 169 #ds.sta_LOCAL 1 170 #ds.CALL recursion, [0, 1], #ds.lda_LOCAL 171 #ds.lda_PARAM 1 ; Check for 172 cmp #$09 ; expected result 173 #CHECK_ERROR 174 jsr ds.delete_stack_frame 175 ;; Check if stack is empty again 176 lda ds.ptr 177 cmp #<start_of_stack 178 #CHECK_ERROR 179 lda ds.ptr+1 180 cmp #>start_of_stack 181 #CHECK_ERROR 182 #io.PRINTSNL "Recursion test completed!" 183 rts 184 .bend 185 186 recursion: 187 .block 188 jsr ds.create_stack_frame 189 #ds.PUSH $02 ; Local variables 190 #ds.lda_LOCAL 0 191 beq done 192 dec a 193 #ds.sta_LOCAL 0 194 #ds.lda_LOCAL 1 195 inc a 196 inc a 197 #ds.sta_LOCAL 1 198 #ds.CALL recursion, [0, 1], #ds.lda_LOCAL 199 #ds.lda_PARAM 1 200 #ds.sta_LOCAL 1 201 done: 202 jsr ds.delete_stack_frame 203 rts 204 .bend 205 206 207 end_of_code: 208 .send code 209