1.1 --- a/macros.oph Sun Jun 28 15:45:29 2015 +0200
1.2 +++ b/macros.oph Sun Jun 28 19:23:06 2015 +0200
1.3 @@ -144,6 +144,8 @@
1.4 ;
1.5 ; _1: valueW
1.6 ; _2: {valueL, valueH} -> {valueL', valueH'}
1.7 +;
1.8 +; affects: A, C
1.9
1.10 .macro sub16
1.11 sec
1.12 @@ -165,52 +167,81 @@
1.13 adc #1
1.14 .macend
1.15
1.16 -; push PC onto a "user space" stack and jump to subroutine
1.17 +; push A onto the "user space" stack, adding an empty byte for compatibility
1.18 +; with PC storage
1.19 ;
1.20 -; _1: target
1.21 -
1.22 -.macro call
1.23 - sei ; prevent CPU stack disturbance
1.24 - jsr copy_to_user_stack
1.25 - cli ; permit CPU stack access again
1.26 - jmp _1
1.27 - nop
1.28 -.macend
1.29 -
1.30 -; pull PC from a "user space" stack and return from subroutine
1.31 -
1.32 -.macro return
1.33 - jmp copy_from_user_stack
1.34 -.macend
1.35 -
1.36 -; push A onto the "user space" stack
1.37 -;
1.38 -; affects: USER (gains A), TEMP
1.39 +; affects: USER (gains empty, A), TEMP
1.40
1.41 .macro pushA
1.42 sei
1.43 + php
1.44 pha
1.45 sty TEMP
1.46 ldy #0
1.47 sta (USER), y
1.48 - .invoke sub16 1, USER
1.49 + .invoke sub16 2, USER
1.50 ldy TEMP
1.51 pla
1.52 + plp
1.53 cli
1.54 .macend
1.55
1.56 ; pull A from the "user space" stack
1.57 ;
1.58 -; affects: A, USER (loses A), TEMP
1.59 +; affects: A, USER (loses empty, A), TEMP
1.60
1.61 .macro pullA
1.62 sei
1.63 + php
1.64 sty TEMP
1.65 - .invoke add16 1, USER
1.66 + .invoke add16 2, USER
1.67 ldy #0
1.68 lda (USER), y
1.69 ldy TEMP
1.70 + plp
1.71 cli
1.72 .macend
1.73
1.74 +; push a return address onto the "user space" stack and jump to a subroutine
1.75 +;
1.76 +; _1: subroutine address
1.77 +; _2: return address
1.78 +;
1.79 +; affects: USER (gains LSB, MSB), TEMP
1.80 +
1.81 +.macro call
1.82 + sei
1.83 + php
1.84 + pha
1.85 + sty TEMP
1.86 + ldy #0
1.87 + lda #<_2
1.88 + sta (USER), y
1.89 + iny
1.90 + lda #>_2
1.91 + sta (USER), y
1.92 + .invoke sub16 2, USER
1.93 + ldy TEMP
1.94 + pla
1.95 + plp
1.96 + cli
1.97 + jmp _1
1.98 +.macend
1.99 +
1.100 +; pull an address from the "user space" stack and return to it
1.101 +;
1.102 +; affects: USER (loses LSB, MSB), ABSTEMP
1.103 +
1.104 +.macro return
1.105 + sei
1.106 + php
1.107 + pha
1.108 + .invoke add16 2, USER
1.109 + .invoke mov16_from_ref USER, ABSTEMP
1.110 + pla
1.111 + plp
1.112 + cli
1.113 + jmp (ABSTEMP)
1.114 +.macend
1.115 +
1.116 ; vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/switcher.oph Sun Jun 28 15:45:29 2015 +0200
2.2 +++ b/switcher.oph Sun Jun 28 19:23:06 2015 +0200
2.3 @@ -38,7 +38,8 @@
2.4 ; "user space" stack for the main program where the invocations might be
2.5 ; interrupted and where the CPU stack might be disrupted
2.6
2.7 -.alias main_stack $1fff
2.8 +.alias main_stack $1ffc
2.9 +.alias ABSTEMP $1ffe
2.10
2.11
2.12
2.13 @@ -50,135 +51,20 @@
2.14 ; main program, installing the handler and adding example tasks
2.15
2.16 main:
2.17 - jsr install_handler
2.18 .invoke store16 tasks, ARG1
2.19 .invoke store16 main_stack, USER
2.20 .invoke store16 first_task, ARG0
2.21 - .invoke call new_task
2.22 - .invoke store16 second_task, ARG0
2.23 - .invoke call new_task
2.24 - .invoke store16 third_task, ARG0
2.25 - .invoke call new_task
2.26 + .invoke call new_task, +
2.27 +* .invoke store16 second_task, ARG0
2.28 + .invoke call new_task, +
2.29 +* .invoke store16 third_task, ARG0
2.30 + .invoke call new_task, +
2.31 +* jsr install_handler
2.32 wait:
2.33 jmp wait ; wait for the switcher to take over
2.34
2.35
2.36
2.37 -; move CPU stack data to the "user space" stack
2.38 -;
2.39 -; affects: USER (gains LSB, MSB)
2.40 -
2.41 -copy_to_user_stack:
2.42 - pha ; A -> stack
2.43 - txa
2.44 - pha ; X -> stack
2.45 - tsx ; capture the stack pointer now for later use
2.46 - ; (stack is Y, X, A, LSB, MSB)
2.47 - tya
2.48 - pha ; Y -> stack
2.49 -
2.50 - ; save zero-page locations used
2.51 -
2.52 - .invoke push16 SP
2.53 -
2.54 - ; initialise the stack frame pointer
2.55 -
2.56 - txa
2.57 - sta SP
2.58 - lda #$01 ; $01xx
2.59 - sta SPH
2.60 -
2.61 - ; allocate "user space" stack space to be compatible with the CPU stack
2.62 -
2.63 - .invoke sub16 5, USER
2.64 -
2.65 - ; copy the PC, updated by 4 (see the call macro)
2.66 -
2.67 - ldy #3
2.68 - clc
2.69 - lda (SP), y
2.70 - adc #4
2.71 - sta (USER), y
2.72 - iny
2.73 - lda (SP), y
2.74 - adc #0
2.75 - sta (USER), y
2.76 -
2.77 - ; correct "user space" stack
2.78 -
2.79 - .invoke add16 3, USER
2.80 -
2.81 - ; restore zero-page locations used
2.82 -
2.83 - .invoke pull16 SP
2.84 -
2.85 - ; return to the caller
2.86 -
2.87 - pla
2.88 - tay ; stack -> Y
2.89 - pla
2.90 - tax ; stack -> X
2.91 - pla ; stack -> A
2.92 - rts
2.93 -
2.94 -
2.95 -
2.96 -; move CPU stack data from the "user space" stack
2.97 -;
2.98 -; affects: USER (loses LSB, MSB)
2.99 -
2.100 -copy_from_user_stack:
2.101 - pha ; padding
2.102 - pha ; padding
2.103 - pha ; A -> stack
2.104 - txa
2.105 - pha ; X -> stack
2.106 - tsx ; capture the stack pointer now for later use
2.107 - ; (stack is Y, X, A, LSB, MSB)
2.108 - tya
2.109 - pha ; Y -> stack
2.110 -
2.111 - ; save zero-page locations used
2.112 -
2.113 - .invoke push16 SP
2.114 -
2.115 - ; initialise the stack frame pointer
2.116 -
2.117 - txa
2.118 - sta SP
2.119 - lda #$01 ; $01xx
2.120 - sta SPH
2.121 -
2.122 - ; adjust the "user space" stack pointer to be compatible with the PC stack
2.123 -
2.124 - .invoke sub16 3, USER
2.125 -
2.126 - ; copy the PC
2.127 -
2.128 - ldy #3
2.129 - .invoke mov8_refs USER, SP
2.130 - iny
2.131 - .invoke mov8_refs USER, SP
2.132 -
2.133 - ; update the "user space" stack pointer
2.134 -
2.135 - .invoke add16 5, USER
2.136 -
2.137 - ; restore zero-page locations used
2.138 -
2.139 - .invoke pull16 SP
2.140 -
2.141 - ; return to the stored PC
2.142 -
2.143 - pla
2.144 - tay ; stack -> Y
2.145 - pla
2.146 - tax ; stack -> X
2.147 - pla ; stack -> A
2.148 - rts
2.149 -
2.150 -
2.151 -
2.152 ; install the interrupt handler address in IRQ1V
2.153 ;
2.154 ; affects: A
2.155 @@ -342,6 +228,7 @@
2.156 ;
2.157 ; ARG0, ARG0H: location of task structure
2.158 ; affects: A, Y
2.159 +; returns: 0 if successful, 1 if unsuccessful
2.160
2.161 new_task:
2.162
2.163 @@ -374,9 +261,11 @@
2.164 sta tasks, y
2.165 cli
2.166
2.167 + lda #0
2.168 .invoke return
2.169
2.170 no_new_task:
2.171 + lda #1
2.172 .invoke return
2.173
2.174
2.175 @@ -438,24 +327,30 @@
2.176 .word third_task_start ; saved PC
2.177 third_task_start:
2.178 ldx #0
2.179 - ldy #0
2.180 +_begin:
2.181 + ldy #0 ; reset counter LSB
2.182 + lda #0 ; reset counter MSB
2.183 + sta $7011
2.184 _loop:
2.185 + sty $7010
2.186 cpy #$ff
2.187 bne _continue
2.188 - inc $7011
2.189 - lda $7011
2.190 + clc
2.191 + lda $7011 ; next MSB
2.192 + adc #1
2.193 + sta $7011
2.194 cmp #$ff
2.195 bne _continue
2.196 - tya
2.197 + txa
2.198 .invoke pushA
2.199 - txa
2.200 - .invoke call remove_task
2.201 - .invoke pullA
2.202 - tay
2.203 - inx
2.204 + .invoke call remove_task, +
2.205 +* .invoke pullA
2.206 + tax
2.207 + inx ; move to next offset
2.208 + inx ; which is 2 locations away
2.209 + jmp _begin
2.210 _continue:
2.211 iny
2.212 - sty $7010
2.213 jmp _loop
2.214 third_task_stack:
2.215 .word 0
2.216 @@ -463,7 +358,7 @@
2.217 .word 0
2.218 .word 0
2.219 .word 0
2.220 +third_task_stack_base:
2.221 .word 0
2.222 -third_task_stack_base:
2.223
2.224 ; vim: tabstop=4 expandtab shiftwidth=4