📄 arch_a.s
字号:
;*
;* Copyright (c) 2004-2005, Dennis Kuschel.
;* All rights reserved.
;*
;* Redistribution and use in source and binary forms, with or without
;* modification, are permitted provided that the following conditions
;* are met:
;*
;* 1. Redistributions of source code must retain the above copyright
;* notice, this list of conditions and the following disclaimer.
;* 2. Redistributions in binary form must reproduce the above copyright
;* notice, this list of conditions and the following disclaimer in the
;* documentation and/or other materials provided with the distribution.
;* 3. The name of the author may not be used to endorse or promote
;* products derived from this software without specific prior written
;* permission.
;*
;* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
;* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
;* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
;* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
;* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
;* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
;* OF THE POSSIBILITY OF SUCH DAMAGE.
;*
;
; This file is originally from the pico]OS realtime operating system
; (http://picoos.sourceforge.net).
;
; CVS-ID $Id: arch_a.s,v 1.4 2005/01/03 16:32:29 dkuschel Exp $
;
; ---------------------------------------------------------------
; configuration
; ---------------------------------------------------------------
.IFDEF POSNANO
;Set this define to nonzero (=1) to enable nano layer keyboard input
.DEFINE NOS_KEYINPUT 1
;Set this define to nonzero (=1) to enable nano layer display output
.DEFINE NOS_DISPOUT 1
.ELSE
.DEFINE NOS_KEYINPUT 0
.DEFINE NOS_DISPOUT 0
.ENDIF
; ---------------------------------------------------------------
; imports / exports and setup
; ---------------------------------------------------------------
.autoimport on
.case on
.debuginfo on
.importzp sp, ptr1
.macpack longbranch
.import _posCurrentTask_g
.import _posNextTask_g
.import _posInInterrupt_g
.import _c_pos_intEnter
.import _c_pos_intExit
.import _c_pos_timerInterrupt
.import incsp1
.import incsp2
.export _p_get_sp
.export _p_clear_cpustack
.export _p_pos_startFirstContext
.export _p_pos_softContextSwitch
.export _p_pos_intContextSwitch
.export _p_pos_findbit
.IF NOS_KEYINPUT
.import _c_nos_keyinput
.import pusha
.ENDIF
.IF NOS_DISPOUT
.export _p_putchar
.ENDIF
; local defines
zpsize = $1A
cstacksize = $40
snbr_sflag = $FF
isrstacksize = 256
KEY_COUNT := $C6
KEY_BUF := $0277
SCREEN_OUT := $E716
CURSOR_COLUMN := $D3
C64IRQVECT := $0314
_orgC64irqvect := $004B ;temp.mem for basic pointers (2 bytes)
; local variables
.segment "BSS"
;_orgC64irqvect
; .res 2
_saved_sp:
.res 2
_tmrdiv:
.res 1
_doorgirq:
.res 1
_isrstack:
.res 256
.IF NOS_DISPOUT
_savedchars:
.res 2
.ENDIF
; start of source code
.segment "CODE"
.IF NOS_DISPOUT
; ---------------------------------------------------------------
; void _p_putchar(char c)
; ---------------------------------------------------------------
.proc _p_putchar
ldy #$00
lda (sp),y
cmp #13
bne putc0
ldx _savedchars
sta _savedchars
beq putc2
lda #0
putc3:
sta _savedchars+1
putc7:
lda CURSOR_COLUMN
sta _savedchars
beq putc4
lda #$9D ;cursor left
jsr SCREEN_OUT
jmp putc7
putc4:
ldx _savedchars+1
beq putc2
lda #0
sta _savedchars+1
txa
putc0:
cmp #10
bne putc1
lda _savedchars
bne putc6
lda #$11 ;cursor down
bne putc5
putc6:
lda #0
sta _savedchars
lda #$0D ;CR+LF
putc1:
ldx _savedchars
bne putc3
putc5:
jsr SCREEN_OUT
putc2:
lda #1
jmp incsp1
.endproc
.ENDIF
; ---------------------------------------------------------------
; unsigned char* p_get_sp (void)
; ---------------------------------------------------------------
.proc _p_get_sp
lda sp
ldx sp+1
rts
.endproc
; ---------------------------------------------------------------
; void p_clear_cpustack (void)
; ---------------------------------------------------------------
.proc _p_clear_cpustack
sei
tsx
ldy #$00
ccs00:
lda $0101,x
sta $0100,y
iny
inx
bne ccs00
ldx #$00
ldy #$e0
ccs01:
lda $0100,x
sta $0100,y
inx
iny
bne ccs01
ldx #$df
txs
cli
rts
.endproc
; ---------------------------------------------------------------
; void p_pos_startFirstContext(void)
; ---------------------------------------------------------------
.proc _p_pos_startFirstContext
; initialize C64 timer intrrupt
jsr _p_start_timer
; load ptr
lda _posCurrentTask_g
ldx _posCurrentTask_g+1
sta ptr1
stx ptr1+1
; csp = task->cstackptr
ldy #$00
lda (ptr1),y
tax
txs
; dsp = task->dstackptr
iny
lda (ptr1),y
sta sp
iny
lda (ptr1),y
sta sp+1
pla
tay
pla
tax
pla
rti
.endproc
; ---------------------------------------------------------------
; void p_pos_softContextSwitch(void)
; ---------------------------------------------------------------
;
; Do a context switch from software level.
;
; Steps that are performed:
; 1. save flags and CPU registers to processor stack
; 2. save the context of the current task:
; - save processor stack pointer
; - save data stack pointer
; - save current zeropage environment
; - save processor stack frame into data stack
; if the currently running task has no own
; dedicated processor stack
; 3. switch context variable
; 4. restore context of the next task to execute:
; - restore processor stack pointer
; - restore data stack pointer
; - restore processor stack frame from data stack
; if the next task has no own processor stack
; - restore zeropage environment
; 5. restore CPU registers and flags from processor stack
; 6. execute next task
;
; ---------------------------------------------------------------
.proc _p_pos_softContextSwitch
php
pha
txa
pha
tya
pha
; adjust back jump address to be RTI conform
tsx
inc $0105,x
bne scs10
inc $0106,x
scs10:
; -- save context of current task --
; save sp
lda sp
ldy sp+1
sta _saved_sp
sty _saved_sp+1
; get ptr: sp = task->cstackptr
lda _posCurrentTask_g
ldy _posCurrentTask_g+1
sta sp
sty sp+1
ldy #$00
; store current csp: *sp = csp
; tsx - x has still the value of sp
txa
sta (sp),y
; get ptr: sp = task->dstackptr
iny
; store current dsp: *sp = dsp
lda _saved_sp
sta (sp),y
iny
lda _saved_sp+1
sta (sp),y
; x = task->cstacknbr
ldy #$05
lda (sp),y
tax
; get ptr: sp = task->savedzp
lda sp
clc
adc #$07
sta sp
bcc scs00
inc sp+1
scs00:
; store zero page content
ldy #zpsize-3
scs01:
lda sp+2,y
sta (sp),y
dey
bpl scs01
; copy cstack frame to dstack when slow task is detected
; test task->cstacknbr
cpx #snbr_sflag
bne scs02
; get ptr to save area on dstack
; ptr1 = task->dstackroot - csp
lda _posCurrentTask_g
ldy _posCurrentTask_g+1
sta sp
sty sp+1
ldy #$04
lda (sp),y
sta ptr1+1
dey
lda (sp),y
tsx
stx ptr1
sec
sbc ptr1
sta ptr1
bcs scs03
dec ptr1+1
scs03:
; calculate count of bytes to copy
; tsx - x has still the value of sp
txa
tay
and #cstacksize - 1
eor #cstacksize - 1
beq scs02
tax
; copy bytes
scs04:
lda $0101,y
sta (ptr1),y
iny
dex
bne scs04
scs02:
; proceed with the interrupt code,
; since it is the same we would do here.
jmp _p_pos_intContextSwitch
.endproc
; ---------------------------------------------------------------
; void p_pos_intContextSwitch(void)
; ---------------------------------------------------------------
;
; Do a context switch from software level.
;
; Steps that are performed:
; 1. switch context variable
; 2. restore context of the next task to execute:
; - restore processor stack pointer
; - restore data stack pointer
; - restore processor stack frame from data stack
; if the next task has no own processor stack
; - restore zeropage environment
; 3. restore CPU registers and flags from processor stack
; 4. return from interrupt, execute next task
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -