易码技术论坛

 找回密码
 加入易码
搜索
查看: 698958|回复: 11

[请教]关于在WQX上仿多线程操作

[复制链接]
发表于 2006-8-17 14:51:38 | 显示全部楼层
我以前也想过......有点OK,但是....那个第一程序是暂停了的...
而且强行导入内存会死机`^~~`
发表于 2006-8-17 15:41:45 | 显示全部楼层
网上有可用的6502用的多任务源代码,原理是利用时钟中断让控制权交回系统,让系统保存当前任务的CPU状态,再恢复下一任务的CPU状态,再切换到下一任务。
发表于 2006-8-17 18:21:52 | 显示全部楼层
我机子上居然有这资料,帖出来让LZ看看:
;*------------------------------------------------------------------*
;*                   *
;*       Mini Multitasking Kernel       *
;*          for 6502 Systems         *
;*                   *
;*         by Joachim Deboy         *
;*                   *
;*   This mini kernel uses IRQ interrupts from a free running     *
;*   6522-timer for task switching. It currently supports 4     *
;*   concurrent tasks. The tasks receive control for fixed time   *
;*   slices in a round robin method. It should be easily possible  *
;*   to implement a priority driven task selector in the inter-   *
;*   rupt service routine.             *
;*                   *
;*   For performance reasons, the stack page will not be copied   *
;*   for every task switch, but is divided into 4 parts, one for  *
;*   each task. Because of that only the stack pointer and the    *
;*   other processor registers must be saved and loaded, when     *
;*   performing a task switch. A disadvantage is the 'home made'  *
;*   further limitation of the already short stack area.     *
;*                   *
;*   Two macros are implemented to allow a simple kind of seria-  *
;*   lization between concurrent tasks. A call of the enq-macro   *
;*   locks task switching until the deq-macro is used. This also  *
;*   prevents a discuption of a time critical process.      *
;*                   *
;*   This software is part of a heater control software, which    *
;*   runs at my home for several years now.         *
;*   It may be freely used and modified to suit other possible    *
;*   applications, but i can't guarantee for the usablity       *
;*   in any way. Use it at for own risk.         *
;*                   *
;*   If you have any comments, questions, further ideas or if you  *
;*   find any bugs, please contact me under joachim@deboy.de     *
;*                   *
;*------------------------------------------------------------------*
;*        page 0 addresses         *
;*------------------------------------------------------------------*
mtarlow  =$00        ; multitasking kernel, ret-addr., low
mtarhig  =$01        ; multitasking kernel, ret-addr.,high
mtatemp  =$02        ; multitasking kernel, temp. work
mtatask  =$03        ; multitasking kernel, actual task
mtastab  =$04        ; multitasking kernel, stack pointers
mtastbe  =$07        ; multitasking kernel, end of st-ptrs
reserved  =$08        ; reserved
mtalock  =$09        ; multitasking lock x'00' = free
;*------------------------------------------------------------------*
;*        6522 ports           *
;*------------------------------------------------------------------*
orb    =$c310      ; output-register a
ora    =$c311      ; output-register b
ddrb    =$c312      ; data direction register b
ddra    =$c313      ; data direction register a
t1csl    =$c314      ; read: counter, low
;          ; write: preset, low
t1csh    =$c315      ; read & write: counter, high
t1lsl    =$c316      ; read & write preset low, low
t1lsh    =$c317      ; read & write preset, high
acr    =$c31b      ; acr-helpregister
pcr    =$c31c      ; pcr-register
ifr    =$c31d      ; interrupt-flag-register
ier    =$c31e      ; interrupt-enable-register
orahlp    =$c31f      ; output-register a w/o handshaking
;*------------------------------------------------------------------*
;*      define macros           *
;*------------------------------------------------------------------*
#define enq() inc mtalock
#define deq() dec mtalock \ beq $+8 \ jsr mtaentry \ inc $100
;*------------------------------------------------------------------*
;*      initialization routine         *
;*------------------------------------------------------------------*
    .org $f000
init:
    lda  #$00      ; init output ports of pia 2
    sta  mtalock      ; reset multitasking lock
    lda  #$40      ; setup timer for free running
    sta  acr
    lda  #$c0      ; enable timer interrupts
    sta  ier

    ldy  #0
    lda  #0
stinit:  sta  $100,y      ; reset stack to x'00'
    iny
    bne  stinit

    lda  #$00      ; set actual task # to 0
    sta  mtatask
    ldy  #maxtask-1    ; get max. number of tasks
initloop:
    lda  mtasini,y    ; get initial stackpointer value
    sta  mtastab,y    ; and save value in page 0 table
    tax        ; move stack pointer value to reg x
    lda  #$b0      ; set initial flag register contents
    sta  $0104,x      ; save flag register on stack
    tya        ; get actual task number
    asl  a      ; multiply with 2
    tax        ; and move result to reg x
    stx  mtatemp      ; save reg x
    lda  ent_tab,x    ; get pcl-value
    ldx  mtastab,y    ; get stack pointer value
    sta  $0105,x      ; save pcl register on stack
    ldx  mtatemp      ; get reg x
    lda  ent_tab+1,x    ; get pch-value
    ldx  mtastab,y    ; get stack pointer value
    sta  $0106,x      ; save pch register on stack
    dey
    bpl  initloop     ; ==> loop for all tasks
    ldx  #$3f      ; set stack for task 0
    txs

    lda  #0      ; initial load timer
    sta  t1lsl
    lda  #40      ; about 1/100 sec timer value
    sta  t1csh
    cli        ; enable interrupts
    jmp  ent_task0    ; enter task 0
;*------------------------------------------------------------------*
;*      table of task entry addresses       *
;*------------------------------------------------------------------*
ent_tab:
    .word ent_task0
    .word ent_task1
    .word ent_task2
    .word ent_task3

;*------------------------------------------------------------------*
;*      program call entry to interrupt service routine     *
;*------------------------------------------------------------------*
mtaentry:
    php        ; save processor status on stack
;          ; for interrupt simulation
    pha        ; save registers on current stack
    txa
    pha
    tya
    pha
    tsx

    inc  $105,x      ; add 1 to return address
    bne  mtaent01     ; because of jsr command
    inc  $106,x
mtaent01:

    lda  #$00      ; reset task lock
    sta  mtalock
    jmp  mtaswitch    ; and process task switch

;*------------------------------------------------------------------*
;*      interrupt service routine       *
;*------------------------------------------------------------------*
irq:
    pha        ; save registers on current stack
    txa
    pha
    tya
    pha

    lda  t1csl      ; enable interrupt
    lda  #$c0      ; reset flag
    sta  ifr

    lda  mtalock      ; is task locked ?
    beq  mtaswitch    ; ==> no, then process task change
    inc  mtalock      ; indicate task switch requested
    jmp  irq_ret      ; ==> and skip task change

mtaswitch:        ; task switcher
    ldy  mtatask      ; get actual task number
    tsx        ; get actual stack pointer
    stx  mtastab,y    ; and save it in table
    iny        ; calculate next task number
    cpy  #maxtask     ; valid task number ?
    bcc  mtanumok     ; ==> yes
    ldy  #0      ; else start with task 0
mtanumok:
    sty  mtatask      ; save new task number
    ldx  mtastab,y    ; get new stack pointer
    txs        ; and load it in  sp-register

irq_ret:
    pla        ; load registers from current stack
    tay
    pla
    tax
    pla
    rti        ; ==> go and process task

mtasini  .byte $39,$79,$b9,$f9  ; initial stackpointer values
maxtask  =$-mtasini

    .org $fffa
nmivector .word init      ; nmi vector
resvector .word init      ; reset vector
irqvector .word irq      ; irq vector
    .end

发表于 2006-8-17 20:24:51 | 显示全部楼层
实现不太可能,毕竟是8位低端CPU么
发表于 2006-8-18 01:30:53 | 显示全部楼层
2楼的天书。。。
 楼主| 发表于 2006-8-18 13:07:50 | 显示全部楼层
谢谢各位了,不过不知道在V5100上可不可能,听说它的的CPU是多任务结构的,那样就不必用这个不入流的方法了
发表于 2006-8-18 14:32:35 | 显示全部楼层
方法是大同小异,即使硬件实现,还是要有类似的程序控制
发表于 2006-9-14 17:05:06 | 显示全部楼层
貌似内存会不足``

唉,WQX已经很不错了``
发表于 2006-9-16 11:54:02 | 显示全部楼层
抢占式多线程最主要的是可以设置堆栈段,数据段,程序段,6502 根本没有这种硬件能力,所以3楼的程序强行将堆栈分为4部分,可以支持4个线程,不过这4个线程还是统一连接才保证运行正常,没有扩展的余地.
发表于 2006-9-23 12:05:13 | 显示全部楼层
引用第2楼点虫虫2006-08-17 15:41发表的“”:
网上有可用的6502用的多任务源代码,原理是利用时钟中断让控制权交回系统,让系统保存当前任务的CPU状态,再恢复下一任务的CPU状态,再切换到下一任务。
这个只能算模拟多线程吧,后台任务不会被执行的
发表于 2006-9-29 02:54:48 | 显示全部楼层
多线程要把程序都编成'块'一样的东西,然后在总线循环中依条件而调用,似乎6502的内存和速度都跟不上~~~
 楼主| 发表于 2006-8-17 12:04:32 | 显示全部楼层 |阅读模式
游客,本帖隐藏的内容需要积分高于 200 才可浏览,您当前积分为 0
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-19 15:34 , Processed in 0.012846 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表