!to "threading.prg",cbm !cpu 6510 ;!source "mylib.a" !macro basic_header .a, .b, .c, .d { *= $0801 !byte <.eol,>.eol,0,0,$9e !text .a, .b, .c, .d .eol: !byte 0,0,0 } num_threads = 2 thread_num = $fd ; current thread number ;-------------------------------------------------------------------------- +basic_header "2", "0", "6", "1" *= $080d init: sei ; set up context switch IRQ lda #$35 sta $01 lda #<context_switch ldx #>context_switch sta $fffe stx $ffff lda #0 sta thread_num cli jmp thread1 ;-------------------------------------------------------------------------- context_switch: pha txa pha tya pha lda $dc0d ; save current thread lda thread_num ; *8 asl asl asl tay ; save A,X,Y pla sta thread_data+6,y pla sta thread_data+5,y pla sta thread_data+4,y ; save PSW pla sta thread_data+1,y ; save PC pla sta thread_data+2,y pla sta thread_data+3,y ; save SP tsx txa sta thread_data,y ; next thread, wraparound ldy thread_num iny cpy #num_threads bne + ldy #0 + sty thread_num ; *8 tya asl asl asl tay ; restore thread data ; stack pointer first lda thread_data,y tax txs ; push PC, PSW for RTI lda thread_data+3,y pha lda thread_data+2,y pha lda thread_data+1,y pha ; push registers lda thread_data+6,y pha lda thread_data+5,y pha lda thread_data+4,y pha pla tay pla tax pla rti ;-------------------------------------------------------------------------- thread1: inc $d021 ldy #$02 jsr wait2 jmp thread1 thread2: inc $d020 ldy #$80 jsr wait2 jmp thread2 wait2: - ldx #0 dex bne *-1 dey bne - rts ;-------------------------------------------------------------------------- thread_data: !fill 8, 0 !byte $ff-$40, $22, <thread2, >thread2, 0,0,0,0
Isn't there going to be some problems with stack in your implementation, Gregg?.. I mean, the more threads you add, the less stack there'd be free for each thread, correct?..
And copying the complete stack per thread (plus state) is going to be expensive in terms of both memory usage and CPU time spend on task switching...