URL
https://opencores.org/ocsvn/rtf65002/rtf65002/trunk
Subversion Repositories rtf65002
Compare Revisions
- This comparison shows the changes necessary to convert path
/rtf65002
- from Rev 33 to Rev 34
- ↔ Reverse comparison
Rev 33 → Rev 34
/trunk/software/asm/asm.exe
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/software/asm/bootrom.asm
1,3 → 1,4
|
; ============================================================================ |
; __ |
; \\__/ o\ (C) 2013 Robert Finch, Stratford |
79,6 → 80,7
FCB_DE_DATETIME =0x28 |
FCB_DE_CLUSTER =0x30 ; starting cluster of file |
FCB_DE_SIZE =0x34 ; 6 byte file size |
|
FCB_DIR_SECTOR =0x40 ; LBA directory sector this is from |
FCB_DIR_ENT =0x44 ; offset in sector for dir entry |
FCB_LDRV =0x48 ; logical drive this is on |
203,6 → 205,14
CONFIGREC EQU 0xFFDCFFF0 |
CR_CLOCK EQU 0xFFDCFFF4 |
GACCEL EQU 0xFFDAE000 |
GA_X0 EQU 0xFFDAE002 |
GA_Y0 EQU 0xFFDAE003 |
GA_PEN EQU 0xFFDAE000 |
GA_X1 EQU 0xFFDAE004 |
GA_Y1 EQU 0xFFDAE005 |
GA_STATE EQU 0xFFDAE00E |
GA_CMD EQU 0xFFDAE00F |
|
AC97 EQU 0xFFDC1000 |
PSG EQU 0xFFD50000 |
PSGFREQ0 EQU 0xFFD50000 |
233,6 → 243,42
ETH_HASH1_ADDR EQU 0x13 |
ETH_TXCTRL EQU 0x14 |
|
ETH_WCTRLDATA EQU 4 |
ETH_MIICOMMAND_RSTAT EQU 2 |
ETH_MIISTATUS_BUSY EQU 2 |
ETH_MIIMODER_RST EQU $200 |
ETH_MODER_RST EQU $800 |
ETH_MII_BMCR EQU 0 ; basic mode control register |
ETH_MII_ADVERTISE EQU 4 |
ETH_MII_EXPANSION =6 |
ETH_MII_CTRL1000 =9 |
ETH_ADVERTISE_ALL EQU $1E0 |
ETH_ADVERTISE_1000FULL =0x0200 ; Advertise 1000BASE-T full duplex |
ETH_ADVERTISE_1000HALF =0x0100 ; Advertise 1000BASE-T half duplex |
ETH_ESTATUS_1000_TFULL =0x2000 ; Can do 1000BT Full |
ETH_ESTATUS_1000_THALF =0x1000 ; Can do 1000BT Half |
ETH_BMCR_ANRESTART = 0x0200 ; Auto negotiation restart |
ETH_BMCR_ISOLATE = 0x0400 ; Disconnect DP83840 from MII |
ETH_BMCR_PDOWN = 0x0800 ; Powerdown the DP83840 |
ETH_BMCR_ANENABLE = 0x1000 ; Enable auto negotiation |
|
ETH_PHY =7 |
|
MMU EQU 0xFFDC4000 |
MMU_KVMMU EQU 0xFFDC4800 |
MMU_FUSE EQU 0xFFDC4811 |
MMU_AKEY EQU 0xFFDC4812 |
MMU_OKEY EQU 0xFFDC4813 |
MMU_MAPEN EQU 0xFFDC4814 |
|
DATETIME EQU 0xFFDC0400 |
DATETIME_TIME EQU 0xFFDC0400 |
DATETIME_DATE EQU 0xFFDC0401 |
DATETIME_ALMTIME EQU 0xFFDC0402 |
DATETIME_ALMDATE EQU 0xFFDC0403 |
DATETIME_CTRL EQU 0xFFDC0404 |
DATETIME_SNAPSHOT EQU 0xFFDC0405 |
|
SPRITEREGS EQU 0xFFDAD000 |
SPRRAM EQU 0xFFD80000 |
|
293,6 → 339,7
TCB_SP8Save EQU 0x05FBD800 ; TCB_SP8Save area |
TCB_SPSave EQU 0x05FBD900 ; TCB_SPSave area |
TCB_ABS8Save EQU 0x05FBDA00 |
TCB_mmu_map EQU 0x05FBDB00 |
|
KeybdHead EQU 0x05FBEA00 |
KeybdTail EQU 0x05FBEB00 |
303,7 → 350,7
KeybdBuffer EQU 0x05FBF000 ; buffer is 16 chars |
|
HeapStart EQU 0x04200000 |
HeapEnd EQU 0x05AFFFFF |
HeapEnd EQU 0x043FFFFF |
|
; Bitmap of tasks requesting the I/O focus |
; |
318,17 → 365,12
; |
; TinyBasic AREA = 0xF00 to 0xF7F |
|
HeadRdy0 EQU 0xF80 |
HeadRdy1 EQU HeadRdy0+1 |
HeadRdy2 EQU HeadRdy1+1 |
HeadRdy3 EQU HeadRdy2+1 |
HeadRdy4 EQU HeadRdy3+1 |
TailRdy0 EQU HeadRdy4+1 |
TailRdy1 EQU TailRdy0+1 |
TailRdy2 EQU TailRdy1+1 |
TailRdy3 EQU TailRdy2+1 |
TailRdy4 EQU TailRdy3+1 |
FreeTCB EQU TailRdy4+1 |
QNdx0 EQU 0xF80 |
QNdx1 EQU QNdx0+1 |
QNdx2 EQU QNdx1+1 |
QNdx3 EQU QNdx2+1 |
QNdx4 EQU QNdx3+1 |
FreeTCB EQU QNdx4+1 |
TimeoutList EQU FreeTCB+1 |
RunningTCB EQU TimeoutList+1 |
FreeMbx EQU RunningTCB + 1 |
373,6 → 415,10
eth_unique_id EQU 0xFC8 |
LineColor EQU 0xFC9 |
QIndex EQU 0xFCA |
ROMcs EQU 0xFCB |
mmu_present EQU 0xFCC |
TestTask EQU 0xFCD |
KeybdIsSetup EQU 0xFCE |
|
Uart_rxfifo EQU 0x05FBC000 |
Uart_rxhead EQU 0xFD0 |
398,6 → 444,7
message "jump table" |
; jump table of popular BIOS routines |
org $FFFF8000 |
ROMStart: |
dw DisplayChar |
dw KeybdCheckForKeyDirect |
dw KeybdGetCharDirect |
424,7 → 471,18
ldx #BIOS_STACKS+0x03FF ; setup stack pointer top of memory |
txs |
trs r0,abs8 ; set 8 bit mode absolute address offset |
|
lda #3 |
trs r1,cc ; enable dcache and icache |
jsr ROMChecksum |
sta ROMcs |
stz mmu_present ; assume no mmu |
lda CONFIGREC |
bit #4096 |
beq st_nommu |
jsr InitMMU ; setup the maps and enable the mmu |
lda #1 |
sta mmu_present |
st_nommu: |
jsr MemInit ; Initialize the heap |
|
lda #2 |
435,10 → 493,19
; also sets nmoi policy (native mode on interrupt) |
trs r2,vbr |
dex |
phx |
txy ; y = pointer to vector table |
lda #511 ; 512 vectors to setup |
ldx #brk_rout ; point vector to brk routine |
stos |
|
plx |
lda #brk_rout |
sta (x) |
lda #slp_rout |
sta 1,x |
lda #reschedule |
sta 2,x |
lda #KeybdRST |
sta 448+1,x |
lda #p1000Hz |
468,35 → 535,28
|
lda #-1 |
sta TimeoutList ; no entries in timeout list |
sta HeadRdy0 ; task zero (the BIOS task) is always present |
sta HeadRdy1 |
sta HeadRdy2 |
sta HeadRdy3 |
sta HeadRdy4 |
sta TailRdy0 |
sta TailRdy1 |
sta TailRdy2 |
sta TailRdy3 |
sta TailRdy4 |
sta QNdx0 |
sta QNdx1 |
sta QNdx2 |
sta QNdx3 |
sta QNdx4 |
|
|
; Initialize IO Focus List |
; |
ldx #1 |
st5: |
stz IOFocusTbl,x |
inx |
cpx #8 |
bne st5 |
lda #7 |
ldx #0 |
ldy #IOFocusTbl |
stos |
|
ldx #1 |
lda #-1 |
st9: |
sta TCB_iof_next,x |
sta TCB_iof_prev,x |
inx |
cpx #256 |
bne st9 |
lda #255 |
ldx #-1 |
ldy #TCB_iof_next |
stos |
lda #255 |
ldx #-1 |
ldy #TCB_iof_prev |
stos |
|
; Initialize free message list |
lda #8192 |
546,12 → 606,10
sta LEDS |
|
; Manually setup the BIOS task |
lda #-1 |
stz RunningTCB ; BIOS is task #0 |
sta TCB_NxtRdy ; manually build the ready list |
sta TCB_PrvRdy |
stz HeadRdy0 ; insert at priority 4 |
stz TailRdy0 |
stz TCB_NxtRdy ; manually build the ready list |
stz TCB_PrvRdy |
stz QNdx0 ; insert at priority 0 |
stz TCB_iof_next ; manually build the IO focus list |
stz TCB_iof_prev |
stz IOFocusNdx ; task #0 has the focus |
559,11 → 617,12
sta IOFocusTbl ; set the task#0 request bit |
lda #0 |
sta TCB_Priority |
stz TCB_Timeout |
lda #TS_RUNNING|TS_READY |
sta TCB_Status |
stz TCB_CursorRow |
stz TCB_CursorCol |
|
|
lda #1 |
sta MBX_SEMA |
sta IOF_LIST_SEMA |
576,11 → 635,15
sta CursorFlash |
jsr ClearScreen |
jsr ClearBmpScreen |
jsr PICInit |
; Enable interrupts |
; This will likely cause an interrupt right away because the timer |
; pulses run since power-up. |
cli |
lda #4 |
ldx #0 |
ldy #IdleTask |
jsr StartTask |
jsr PICInit |
lda CONFIGREC ; do we have a serial port ? |
bit #32 |
beq st7 |
618,6 → 681,11
lda #msgStart |
jsr DisplayStringB |
jsr ReportMemFree |
lda #msgChecksum |
jsr DisplayStringB |
lda ROMcs |
jsr DisplayWord |
jsr CRLF |
lda #10 |
sta LEDS |
|
627,10 → 695,10
bit #4 |
beq st6 |
jsr SetupAC97 |
lda #2 |
lda #4 |
ldx #0 |
ldy #Beep |
jsr StartTask |
; jsr StartTask |
st6: |
lda #11 |
sta LEDS |
644,6 → 712,84
msgStart |
db "RTF65002 system starting.",$0d,$0a,00 |
|
;------------------------------------------------------------------------------ |
; InitMMU |
; |
; Initialize the 64 maps of the MMU. |
; Initially all the maps are set the same: |
; Virtual Page Physical Page |
; 000-255 000-255 |
; 256-511 1792-2047 |
; Note that there are only 512 virtual pages per map, and 2048 real |
; physical pages of memory. This limits maps to 32MB. |
; This range includes the BIOS assigned stacks for the tasks and tasks |
; virtual video buffers. It also includes the bitmap screen buffer. |
; Note that physical pages 256 to 1791 are not mapped, but do exist. |
; If changing the maps the last 128 pages (8MB) of the map should always point |
; to the BIOS area. Don't change map entries 384-511 or the system may |
; crash. |
; If the rts at the end of this routine works, then memory was mapped |
; successfully. |
;------------------------------------------------------------------------------ |
InitMMU: |
lda #1 |
sta MMU_KVMMU+1 |
dea |
sta MMU_KVMMU |
immu1: |
sta MMU_AKEY ; set access key for map |
ldy #0 ; |
ldx #0 |
immu2: |
; set the first 256 pages to physical page 0-255 |
; set the last 256 pages to physical page 1792-2047 |
ld r4,r3 |
bit r3,#$0100 |
beq immu3 |
add r4,r4,#1536 |
immu3: |
st r4,MMU,x |
iny |
inx |
cpx #512 |
bne immu2 |
ina |
cmp #64 ; 64 MMU maps |
bne immu1 |
stz MMU_OKEY ; set operating key to map #0 |
lda #2 |
sta MMU_FUSE ; set fuse to 2 clocks before mapping starts |
nop |
nop |
|
EnableMMUMapping: |
pha |
lda #1 |
sta MMU_MAPEN |
pla |
rts |
DisableMMUMapping: |
stz MMU_MAPEN |
rts |
|
;------------------------------------------------------------------------------ |
; The ROM contents are summed up to ensure the ROM is okay. |
;------------------------------------------------------------------------------ |
ROMChecksum: |
lda #0 |
ldx #ROMStart>>2 |
idc1: |
add (x) |
inx |
cpx #$100000000>>2 |
bne idc1 |
cmp #0 ; The sum of all the words in the |
; ROM should be zero. |
rts |
|
msgChecksum: |
db CR,LF,"ROM checksum: ",0 |
|
;---------------------------------------------------------- |
; Initialize programmable interrupt controller (PIC) |
; 0 = nmi (parity error) |
680,7 → 826,7
php |
sei |
dtl2: |
lda HeadRdy0,y |
lda QNdx0,y |
ld r4,r1 |
bmi dtl1 |
dtl3: |
715,7 → 861,8
jsr DisplayWord |
jsr CRLF |
ld r4,TCB_NxtRdy,r4 |
bpl dtl3 |
cmp r4,QNdx0,y |
bne dtl3 |
dtl1: |
iny |
cpy #5 |
732,6 → 879,57
|
;------------------------------------------------------------------------------ |
;------------------------------------------------------------------------------ |
message "DumpTimeoutList" |
DumpTimeoutList: |
pha |
phx |
phy |
push r4 |
lda #msgTimeoutList |
jsr DisplayStringB |
php |
sei |
dtol2: |
lda TimeoutList |
ld r4,r1 |
bmi dtol1 |
dtol3: |
ld r1,r4 |
ldx #3 |
jsr PRTNUM |
lda #' ' |
jsr DisplayChar |
jsr DisplayChar |
jsr DisplayChar |
ld r1,r4 |
ldx #3 |
lda TCB_PrvRdy,r4 |
jsr PRTNUM |
lda #' ' |
jsr DisplayChar |
ldx #3 |
lda TCB_NxtRdy,r4 |
jsr PRTNUM |
lda #' ' |
jsr DisplayChar |
lda TCB_Timeout,r4 |
jsr DisplayWord |
jsr CRLF |
ld r4,TCB_NxtRdy,r4 |
bpl dtol3 |
dtol1: |
plp |
pop r4 |
ply |
plx |
pla |
rts |
|
msgTimeoutList: |
db CR,LF,"Task Prv Nxt Timeout",CR,LF,0 |
|
;------------------------------------------------------------------------------ |
;------------------------------------------------------------------------------ |
message "DumpIOFocusList" |
DumpIOFocusList: |
pha |
773,8 → 971,8
db CR,LF,"Task Prv Nxt",CR,LF,0 |
|
RunningTCBErr: |
lda #$FF |
sta LEDS |
; lda #$FF |
; sta LEDS |
lda #msgRunningTCB |
jsr DisplayStringB |
rtcberr1: |
787,19 → 985,41
db CR,LF,"RunningTCB is bad.",CR,LF,0 |
|
;------------------------------------------------------------------------------ |
; IdleTask |
; |
; IdleTask is a low priority task that is always running. It runs when there |
; is nothing else to run. |
; This task check for tasks that are stuck in infinite loops and kills them. |
;------------------------------------------------------------------------------ |
IdleTask: |
inc TEXTSCR+167 ; increment IDLE active flag |
stz TestTask |
it2: |
inc TEXTSCR+111 ; increment IDLE active flag |
ldx TestTask |
and r2,r2,#$FF |
beq it1 |
lda TCB_Status,x |
cmp #TS_SLEEP |
bne it1 |
txa |
jsr KillTask |
it1: |
inc TestTask |
cli ; enable interrupts |
wai ; wait for one to happen |
bra IdleTask |
bra it2 |
|
;------------------------------------------------------------------------------ |
; r1 = task priority |
; r2 = start flags |
; r3 = start address |
; StartTask |
; |
; Startup a task. The task is automatically allocated a 1kW stack from the BIOS |
; stacks area. The scheduler is invoked after the task is added to the ready |
; list. |
; |
; Parameters: |
; r1 = task priority |
; r2 = start flags |
; r3 = start address |
;------------------------------------------------------------------------------ |
message "StartTask" |
StartTask: |
811,9 → 1031,8
push r6 |
push r7 |
push r8 |
tsr sp,r4 ; save off current stack pointer |
ld r6,r1 ; r6 = task priority |
ld r8,r2 |
ld r8,r2 ; r8 = flag register value on startup |
|
; get a free TCB |
; |
825,14 → 1044,30
lda TCB_NxtTCB,x |
sta FreeTCB ; update the FreeTCB list pointer |
plp |
txa |
txa ; acc = TCB index (task number) |
|
; setup the stack for the task |
; Zap the stack memory. |
ld r7,r2 |
asl r2,r2,#10 ; 1kW stack per task |
add r2,r2,#BIOS_STACKS+0x3ff ; add in stack base |
add r2,r2,#BIOS_STACKS ;+0x3ff ; add in stack base |
pha |
phx |
phy |
txy ; y = target address |
ldx #ExitTask ; x = fill value |
lda #$3FF ; acc = # words to fill -1 |
stos |
ply |
plx |
pla |
|
add r2,r2,#$3FF ; Move pointer to top of stack |
php |
tsr sp,r4 ; save off current stack pointer |
sei |
txs |
ldx #$FF |
ldx #$1FF |
stx TCB_SP8Save,r7 |
st r6,TCB_Priority,r7 |
stz TCB_Status,r7 |
840,6 → 1075,8
; setup virtual video for the task |
stz TCB_CursorRow,r7 |
stz TCB_CursorCol,r7 |
stz TCB_mmu_map,r7 ; use mmu map #0 |
stz TCB_ABS8Save,r7 |
|
; setup the initial stack image for the task |
; Cause a return to the ExitTask routine when the task does a |
862,6 → 1099,8
|
; Insert the task into the ready list |
jsr AddTaskToReadyList |
plp |
int #2 ; invoke the scheduler |
stask2: |
pop r8 |
pop r7 |
882,9 → 1121,12
db "No more task control blocks available.",CR,LF,0 |
|
;------------------------------------------------------------------------------ |
; ExitTask |
; |
; This routine is called when the task exits with an rts instruction. OR |
; it may be invoked with a JMP ExitTask. In either case the task must be |
; running so it can't be on the timeout list. |
; running so it can't be on the timeout list. The scheduler is invoked |
; after the task is removed from the ready list. |
;------------------------------------------------------------------------------ |
message "ExitTask" |
ExitTask: |
892,71 → 1134,114
; release any aquired resources |
; - mailboxes |
; - messages |
hoff |
lda RunningTCB |
bmi RunningTCBErr |
cmp #MAX_TASKNO |
bhi xtsk1 |
jsr RemoveTaskFromReadyList |
jsr RemoveFromTimeoutList |
stz TCB_Status,r1 ; set task status to TS_NONE |
jsr ReleaseIOFocus |
ldx #86 |
stx LEDS |
ldx FreeTCB ; add the task control block to the free list |
stx TCB_NxtTCB,r1 |
sta FreeTCB |
xtsk1: |
jmp SelectTaskToRun |
|
;------------------------------------------------------------------------------ |
; r1 = task number |
; r2 = new priority |
;------------------------------------------------------------------------------ |
SetTaskPriority: |
cmp #MAX_TASKNO ; make sure task number is reasonable |
bhi stp1 |
cpx #5 ; make sure priority is okay |
bhs stp1 |
phy |
php |
sei |
ldy TCB_Status,r1 ; if the task is on the ready list |
bit r3,#TS_READY|TS_RUNNING ; then remove it and re-add it. |
beq stp2 ; Otherwise just go set the priority field |
jsr RemoveTaskFromReadyList |
stx TCB_Priority,r1 |
jsr AddTaskToReadyList |
plp |
ply |
stp1: |
rts |
stp2: |
stx TCB_Priority,r1 |
plp |
ply |
rts |
|
;------------------------------------------------------------------------------ |
; AddTaskToReadyList |
; This subroutine is called from the timer ISR so it must be relatively |
; fast. |
; |
; The ready list is a group of five ready lists, one for each priority |
; level. Each ready list is organized as a doubly linked list to allow fast |
; insertions and removals. The list is organized as a ring (or bubble) with |
; the last entry pointing back to the first. This allows a fast task switch |
; to the next task. Which task is at the head of the list is maintained |
; in the variable QNdx for the priority level. |
; |
; Registers Affected: none |
; Parameters: |
; r1 = task number |
; Returns: |
; none |
;------------------------------------------------------------------------------ |
; |
message "AddTaskToReadyList" |
AddTaskToReadyList: |
php |
pha |
phx |
phy |
sei |
ldx #TS_READY |
stx TCB_Status,r1 |
ldy TCB_Priority,r1 |
ldx TCB_Status,r1 ; set the task status to ready |
or r2,r2,#TS_READY |
stx TCB_Status,r1 |
ldx TailRdy0,y ; insert the task at the list tail |
bmi arl1 ; if no tail, then either the list is screwed up, or no tasks are on it. |
sta TCB_NxtRdy,x ; add as next ready on tail |
arl4: |
stx TCB_PrvRdy,r1 ; the old tail is the previous task on the list now. |
sta TailRdy0,y ; update with new tail |
ldx #-1 |
stx TCB_NxtRdy,r1 ; There is no next ready task to the tail. |
ldx HeadRdy0,y ; check if the head of the ready list needs to be updated |
bpl arl3 |
sta HeadRdy0,y ; Update the head of the ready list. |
ldx #-1 ; There is no previous task at the head. |
stx TCB_PrvRdy,r1 |
ldx QNdx0,y |
bmi arl5 |
ldy TCB_PrvRdy,x |
sta TCB_NxtRdy,y |
sty TCB_PrvRdy,r1 |
sta TCB_PrvRdy,x |
stx TCB_NxtRdy,r1 |
arl3: |
ply |
plx |
pla |
plp |
rts |
; Here the tail of the ready list needed to be updated. Flag no prior task. |
arl1: |
ldx #-1 |
bra arl4 |
|
; Here the ready list was empty, so add at head |
arl5: |
sta QNdx0,y |
sta TCB_NxtRdy,r1 |
sta TCB_PrvRdy,r1 |
ply |
plx |
plp |
rts |
|
;------------------------------------------------------------------------------ |
; RemoveTaskFromReadyList |
; |
; This subroutine removes a task from the ready list. |
; This can be called from within an ISR. |
; |
; r1 = task number |
; Registers Affected: none |
; Parameters: |
; r1 = task number |
; Returns: |
; r1 = task number |
;------------------------------------------------------------------------------ |
|
message "RemoveTaskFromReadyList" |
RemoveTaskFromReadyList: |
php ; save off interrupt mask state |
pha |
phx |
phy |
push r4 |
963,44 → 1248,34
push r5 |
|
sei |
ldy TCB_Status,r1 ; is the task on the ready list ? |
bit r3,#TS_READY|TS_RUNNING |
beq rfr2 |
stz TCB_Status,r1 ; task status = TS_NONE |
ld r4,TCB_NxtRdy,r1 ; Get previous and next fields. |
ld r5,TCB_PrvRdy,r1 ; if there is no previous task, then this is |
bmi rfr1 ; the head of the list. Update. |
ld r5,TCB_PrvRdy,r1 |
st r4,TCB_NxtRdy,r5 |
cmp r4,#0 ; is there a next task to update ? |
bmi rfr4 |
st r5,TCB_PrvRdy,r4 |
bra rfr4 |
|
; Update the head of the list |
rfr1: |
ldy TCB_Priority,r1 |
st r4,HeadRdy0,y |
cmp r4,#0 ; did we empty the list ? |
bmi rfr3 |
ld r5,#-1 ; flag no previous task for head of list |
st r5,TCB_PrvRdy,r4 |
rfr4: |
stz TCB_NxtRdy,r1 ; Task is removed from ready list so the |
stz TCB_PrvRdy,r1 ; contents of these fields shouldn't matter. |
; They are set to zero (the BIOS task) in case |
; there is a list problem. |
|
ldx TCB_Status,r1 ; set the task status to no longer ready. |
and r2,r2,#~TS_READY |
stx TCB_Status,r1 |
cmp r1,QNdx0,y ; Are we removing the QNdx task ? |
bne rfr2 |
st r4,QNdx0,y |
; Now we test for the case where the task being removed was the only one |
; on the ready list of that priority level. We can tell because the |
; NxtRdy would point to the task itself. |
cmp r4,r1 |
bne rfr2 |
ldx #-1 ; Make QNdx negative |
stx QNdx0,y |
stx TCB_NxtRdy,r1 |
stx TCB_PrvRdy,r1 |
rfr2: |
pop r5 |
pop r4 |
ply |
plx |
pla |
plp |
rfr9: |
rts |
rfr3: |
st r4,TailRdy0,y ; |
bra rfr4 |
|
;------------------------------------------------------------------------------ |
; AddToTimeoutList |
1007,6 → 1282,7
; AddToTimeoutList adds a task to the timeout list. The task is placed in the |
; list depending on it's timeout value. |
; |
; Registers Affected: none |
; Parameters: |
; r1 = task |
; r2 = timeout value |
1013,26 → 1289,23
;------------------------------------------------------------------------------ |
message "AddToTimeoutList" |
AddToTimeoutList: |
cmp #0 ; quickly validate the task number |
bmi RunningTCBErr ; must be between 0 and 255 |
cmp #MAX_TASKNO |
bpl RunningTCBErr |
|
php |
phx |
push r4 |
push r5 |
php |
sei |
|
ld r5,#-1 |
ld r4,TimeoutList ; are there any tasks on the timeout list ? |
bmi attl1 |
cmp r4,#MAX_TASKNO |
bhi attl1 |
attl_check_next: |
sub r2,r2,TCB_Timeout,r4 ; is this timeout > next |
bmi attl_insert_before |
ld r5,r4 |
ld r4,TCB_NxtRdy,r4 |
bpl attl_check_next |
cmp r4,#MAX_TASKNO |
bls attl_check_next |
|
; Here we scanned until the end of the timeout list and didn't find a |
; timeout of a greater value. So we add the task to the end of the list. |
1044,8 → 1317,8
bra attl_exit |
|
attl_insert_before: |
cmp r5,#-1 |
beq attl2 |
cmp r5,#MAX_TASKNO |
bhi attl2 |
st r4,TCB_NxtRdy,r1 ; next on list goes after this task |
st r5,TCB_PrvRdy,r1 ; set previous link |
st r1,TCB_NxtRdy,r5 |
1076,52 → 1349,51
stx TCB_NxtRdy,r1 ; no next entries |
stx TCB_PrvRdy,r1 ; and no prev entries |
attl_exit: |
ldx TCB_Status,r1 ; set the task's status as timing out |
or r2,r2,#TS_TIMEOUT |
ldx #TS_TIMEOUT ; set the task's status as timing out |
stx TCB_Status,r1 |
plp |
pop r5 |
pop r4 |
plx |
attl4: |
plp |
rts |
|
msgTimeout1: |
db CR,LF,"Adding to timeout list:",CR,LF,0 |
|
;------------------------------------------------------------------------------ |
; RemoveFromTimeoutList |
; |
; This subroutine is called from within the timer ISR when the task's |
; timeout expires. |
; timeout expires. It may also be called when a task is killed. |
; |
; r1 = task number |
; Registers Affected: none |
; Parameters: |
; r1 = task number |
;------------------------------------------------------------------------------ |
message "RemoveFromTimeoutList" |
RemoveFromTimeoutList: |
cmp #0 ; quickly validate the task number |
bmi RunningTCBErr ; must be between 0 and 255 |
cmp #MAX_TASKNO |
bpl RunningTCBErr |
|
pha |
php |
phx |
push r4 |
push r5 |
php |
sei |
|
ld r4,TCB_Status,r1 ; Is the task even on the timeout list ? |
bit #TS_TIMEOUT |
beq rftl5 |
cmp TimeoutList ; Are we removing the head of the list ? |
beq rftl2 |
ld r4,TCB_PrvRdy,r1 ; adjust the links of the next and previous |
bmi rftl2 |
bmi rftl3 ; no previous link - list corrupt? |
ld r5,TCB_NxtRdy,r1 ; tasks on the list to point around the task |
st r5,TCB_NxtRdy,r4 |
bmi rftl1 |
bmi rftl3 |
st r4,TCB_PrvRdy,r5 |
ldx TCB_Timeout,r1 ; update the timeout of the next on list |
add r2,r2,TCB_Timeout,r5 ; with any remaining timeout in the task |
stx TCB_Timeout,r5 ; removed from the list |
|
; Here there is no next item on the list |
rftl1: |
bra rftl3 |
|
; Here there is no previous item on the list, so update the head of |
; the list. |
; Update the head of the list. |
rftl2: |
ld r5,TCB_NxtRdy,r1 |
st r5,TimeoutList ; store next field into list head |
1135,35 → 1407,76
; Here there is no previous or next items in the list, so the list |
; will be empty once this task is removed from it. |
rftl3: |
ldx TCB_Status,r1 ; set the task status to not timing out |
and r2,r2,#~TS_TIMEOUT |
stx TCB_Status,r1 |
plp |
stz TCB_Status,r1 ; set the task status to TS_NONE |
ldx #-1 ; make sure the next and prev fields indicate |
stx TCB_NxtRdy,r1 ; the task is not on a list. |
stx TCB_PrvRdy,r1 |
rftl5: |
pop r5 |
pop r4 |
plx |
pla |
rft4: |
plp |
rts |
|
;------------------------------------------------------------------------------ |
; Sleep |
; |
; Put the currently running task to sleep for a specified time. |
; |
; Registers Affected: none |
; Parameters: |
; r1 = time duration in centi-seconds (1/100 second). |
;------------------------------------------------------------------------------ |
Sleep: |
php |
pha |
phx |
tax |
sei |
lda RunningTCB |
jsr RemoveTaskFromReadyList |
jsr AddToTimeoutList |
ldx #SleepRet ; The scheduler will be returning to this |
jmp PushRegsAndRunTask ; task eventually, once the timeout expires, |
; so fake an interrupt call |
jsr AddToTimeoutList ; The scheduler will be returning to this |
int #2 ; task eventually, once the timeout expires, |
SleepRet: |
cli |
plx |
pla |
plp |
rts |
|
;------------------------------------------------------------------------------ |
; KillTask |
; |
; "Kills" a task, removing it from all system lists. If the task has the |
; IO focus, the IO focus is switched. Task #0 is immortal and cannot be |
; killed. |
; |
; Registers Affected: none |
; Parameters: |
; r1 = task number |
;------------------------------------------------------------------------------ |
; |
KillTask: |
php |
phx |
cmp #1 ; BIOS task and IDLE task are immortal |
bls kt1 |
cmp #MAX_TASKNO |
bhi kt1 |
sei |
jsr ForceReleaseIOFocus |
jsr RemoveTaskFromReadyList |
jsr RemoveFromTimeoutList |
stz TCB_Status,r1 ; set task status to TS_NONE |
ldx FreeTCB ; add the task control block to the free list |
stx TCB_NxtTCB,r1 |
sta FreeTCB |
int #2 ; invoke scheduler to reschedule tasks |
kt1: |
plx |
plp |
rts |
|
;------------------------------------------------------------------------------ |
; Allocate a mailbox |
; r1 = pointer to place to store handle |
;------------------------------------------------------------------------------ |
1316,9 → 1629,7
st r4,TCB_mbq_next,r5 |
st r4,TCB_mbq_prev,r5 |
stz TCB_hWaitMbx,r5 |
lda TCB_Status,r5 |
and #~TS_WAITMSG |
sta TCB_Status,r5 |
stz TCB_Status,r5 ; set task status = TS_NONE |
pop r5 |
pop r4 |
plp |
1335,10 → 1646,8
;------------------------------------------------------------------------------ |
message "SendMsg" |
SendMsg: |
cmp #0 ; check the mailbox number to make sure |
bmi smsg1 ; that it's sensible |
cmp #2047 |
bpl smsg1 |
cmp #2047 ; check the mailbox number to make sure |
bhi smsg1 ; that it's sensible |
push r4 |
push r5 |
push r6 |
1382,7 → 1691,7
sty (r5) |
smsg7: |
ld r5,TCB_Status,r6 |
and r5,r5,#TS_TIMEOUT |
bit r5,#TS_TIMEOUT |
beq smsg8 |
ld r1,r6 |
jsr RemoveFromTimeoutList |
1389,6 → 1698,7
smsg8: |
ld r1,r6 |
jsr AddTaskToReadyList |
int #2 ; invoke the scheduler |
smsg5: |
plp |
pop r6 |
1431,10 → 1741,8
; r1=E_NotAlloc for a mailbox that isn't allocated |
;------------------------------------------------------------------------------ |
WaitMsg: |
cmp #0 ; check the mailbox number to make sure |
bmi wmsg1 ; that it's sensible |
cmp #2047 |
bpl wmsg1 |
cmp #2047 ; check the mailbox number to make sure |
bhi wmsg1 ; that it's sensible |
phx |
phy |
push r4 |
1445,7 → 1753,8
php |
sei |
ld r5,MBX_OWNER,r1 |
bmi wmsg2 ; error: no owner |
cmp r5,#MAX_TASKNO |
bhi wmsg2 ; error: no owner |
jsr DequeueMsgFromMbx |
cmp #0 |
bpl wmsg3 |
1454,10 → 1763,8
; the ready list, and optionally add it to the timeout list. |
; Queue the task at the mailbox. |
lda RunningTCB ; remove the task from the ready list |
bmi wmsg8 |
jsr RemoveTaskFromReadyList |
ld r7,TCB_Status,r1 ; set task status to waiting |
or r7,r7,#TS_WAITMSG |
ld r7,#TS_WAITMSG ; set task status to waiting |
st r7,TCB_Status,r1 |
st r6,TCB_hWaitMbx,r1 ; set which mailbox is waited for |
ld r7,#-1 |
1477,26 → 1784,7
ld r2,r4 |
jsr AddToTimeoutList |
wmsg10: |
ld r2,#wmsg8 ; save the return address |
PushRegsAndRunTask: |
phx |
php ; save status register |
pha ; and save the register set |
phx |
phy |
push r4 |
push r5 |
push r6 |
push r7 |
push r8 |
push r9 |
push r10 |
push r11 |
push r12 |
push r13 |
push r14 |
push r15 |
jmp SelectTaskToRun |
int #2 ; invoke the scheduler |
|
; Here there were no prior tasks queued at the mailbox |
wmsg6: |
1567,10 → 1855,8
; r1=E_NotAlloc for a mailbox that isn't allocated |
;------------------------------------------------------------------------------ |
CheckMsg: |
cmp #0 ; check the mailbox number to make sure |
bmi cmsg1 ; that it's sensible |
cmp #2047 |
bpl cmsg1 |
cmp #2047 ; check the mailbox number to make sure |
bhi cmsg1 ; that it's sensible |
phx |
phy |
push r4 |
1634,6 → 1920,7
|
;------------------------------------------------------------------------------ |
;------------------------------------------------------------------------------ |
comment ~ |
SetIOFocusBit: |
and r2,r2,#$FF |
and r1,r2,#$1F ; get bit index 0 to 31 |
1644,7 → 1931,7
or r1,r1,r3 |
sta IOFocusTbl,x |
rts |
|
~ |
;------------------------------------------------------------------------------ |
; The I/O focus list is an array indicating which tasks are requesting the |
; I/O focus. The I/O focus is user controlled by pressing ALT-TAB on the |
1658,6 → 1945,8
php |
sei |
ldx RunningTCB |
cpx #MAX_TASKNO |
bhi riof1 |
ldy IOFocusNdx ; Is the focus list empty ? |
bmi riof2 |
riof4: |
1670,7 → 1959,10
sty TCB_iof_prev,x |
stx TCB_iof_next,y |
riof3: |
jsr SetIOFocusBit |
txa |
bms IOFocusTbl |
; jsr SetIOFocusBit |
riof1: |
plp |
ply |
plx |
1688,17 → 1980,37
;------------------------------------------------------------------------------ |
; Releasing the I/O focus causes the focus to switch if the running task |
; had the I/O focus. |
; ForceReleaseIOFocus forces the release of the IO focus for a task |
; different than the one currently running. |
;------------------------------------------------------------------------------ |
; |
message "ForceReleaseIOFocus" |
ForceReleaseIOFocus: |
php |
pha |
phx |
phy |
sei |
tax |
jmp rliof4 |
message "ReleaseIOFocus" |
ReleaseIOFocus: |
php |
pha |
phx |
phy |
php |
sei |
ldx RunningTCB |
phx |
rliof4: |
cpx #MAX_TASKNO |
bhi rliof3 |
; phx |
ldy #1 |
txa |
bmt IOFocusTbl |
beq rliof3 |
bmc IOFocusTbl |
comment ~ |
and r1,r2,#$1F ; get bit index 0 to 31 |
asl r3,r3,r1 ; shift bit to proper place |
eor r3,r3,#-1 ; invert bit mask |
1706,7 → 2018,8
lda IOFocusTbl,x |
and r1,r1,r3 |
sta IOFocusTbl,x |
plx |
~ |
; plx |
cpx IOFocusNdx ; Does the running task have the I/O focus ? |
bne rliof1 |
jsr SwitchIOFocus ; If so, then switch the focus. |
1727,10 → 2040,10
sta TCB_iof_next,x ; the task is no longer on the list. |
sta TCB_iof_prev,x |
rliof3: |
plp |
ply |
plx |
pla |
plp |
rts |
|
;------------------------------------------------------------------------------ |
1861,27 → 2174,23
pha ; holds a space character |
phx ; loop counter |
phy ; memory addressing |
push r4 ; holds the screen color |
push r5 |
lda TEXTREG+TEXT_COLS ; calc number to clear |
ldx TEXTREG+TEXT_ROWS |
mul r2,r1,r2 ; r2 = # chars to clear |
mul r1,r1,r2 ; r1 = # chars to clear |
pha |
jsr GetScreenLocation |
tay |
jsr GetColorCodeLocation |
ld r5,r1 |
tay ; y = target address |
lda #' ' ; space char |
ld r4,ScreenColor |
jsr AsciiToScreen |
csj4: |
sta (y) |
iny |
st r4,(r5) |
inc r5 |
dex |
bne csj4 |
pop r5 |
pop r4 |
tax ; x is value to store |
pla ; a is count |
pha |
stos ; clear the memory |
ld r2,ScreenColor ; x = value to use |
jsr GetColorCodeLocation |
tay ; y = targte address |
pla ; a = count |
stos |
ply |
plx |
pla |
2096,7 → 2405,7
bne dcx6 |
pha |
lda TCB_CursorCol,r4 |
cmp #83 |
cmp #55 |
bcs dcx7 |
ina |
sta TCB_CursorCol,r4 |
2346,16 → 2655,22
lda #32 |
sta LEDS |
ldx #0 |
kbdi1: |
stz KeybdHead,x ; setup keyboard buffer |
stz KeybdTail,x |
lda #1 ; turn on keyboard echo |
sta KeybdEcho,x |
stz KeybdBad,x |
inx |
cpx #MAX_TASKNO+1 |
bne kbdi1 |
|
lda #MAX_TASKNO |
ldx #0 |
ldy #KeybdHead |
stos |
lda #MAX_TASKNO |
ldy #KeybdTail |
stos |
lda #MAX_TASKNO |
ldy #KeybdBad |
stos |
lda #MAX_TASKNO |
ldx #1 ; turn on keyboard echo |
ldy #KeybdEcho |
stos |
|
lda PIC_IE |
or r1,r1,#$8000 ; enable kbd_irq |
sta PIC_IE |
2466,9 → 2781,15
rts |
|
;------------------------------------------------------------------------------ |
; KeybdIRQ |
; |
; Normal keyboard interrupt, the lowest priority interrupt in the system. |
; Grab the character from the keyboard device and store it in a buffer. |
; The buffer of the task with the input focus is updated. |
; This IRQ has to check for the ALT-tab character and take care of |
; switching the IO focus if detected. It can't be done in the KeybdGetChar |
; because the app with the IO focus may not call that routine. We know for |
; sure the interrupt routine will be called when a key is pressed. |
;------------------------------------------------------------------------------ |
; |
message "KeybdIRQ" |
2494,6 → 2815,17
ldx KEYBD ; get keyboard character |
ld r0,KEYBD+1 ; clear keyboard strobe (turns off the IRQ) |
txy ; check for a keyboard ACK code |
|
bit r3,#$800 ; test bit #11 |
bne KeybdIRQc ; ignore keyup messages for now |
bit r3,#$200 ; check for ALT-tab |
beq KeybdIrq3 |
and r3,r3,#$FF |
cmp r3,#TAB ; if we find an ALT-tab |
bne KeybdIrq3 |
jsr SwitchIOFocus |
bra KeybdIRQc ; don't store off the ALT-tab character |
KeybdIrq3: |
and r3,r3,#$ff |
cmp r3,#$FA |
bne KeybdIrq1 |
2536,6 → 2868,7
plx |
rts |
|
comment ~ |
;------------------------------------------------------------------------------ |
; Get a bit from the I/O focus table. |
;------------------------------------------------------------------------------ |
2551,6 → 2884,28
ply |
plx |
rts |
~ |
;------------------------------------------------------------------------------ |
; ForceIOFocus |
; |
; Force the IO focus to a specific task. |
;------------------------------------------------------------------------------ |
; |
ForceIOFocus: |
php |
pha |
phy |
ldy IOFocusNdx |
cmp r1,r3 |
beq fif1 |
jsr CopyScreenToVirtualScreen |
sta IOFocusNdx |
jsr CopyVirtualScreenToScreen |
fif1: |
ply |
pla |
plp |
rts |
|
;------------------------------------------------------------------------------ |
; SwitchIOFocus |
2595,14 → 2950,13
;------------------------------------------------------------------------------ |
message "KeybdGetChar" |
KeybdGetChar: |
php |
phx |
push r4 |
php |
sei |
ld r4,RunningTCB |
bmi RunningTCBErr |
cmp #MAX_TASKNO |
bpl RunningTCBErr |
cmp r4,#MAX_TASKNO |
bhi nochar |
ldx KeybdTail,r4 ; if keybdTail==keybdHead then there are no |
lda KeybdHead,r4 ; characters in the keyboard buffer |
cmp r1,r2 |
2612,19 → 2966,6
add r2,r2,r4 |
lda KeybdBuffer,x |
plx |
bit #$200 ; check for ALT-tab |
beq kgc4 |
and #$FF |
cmp #TAB ; if we find an ALT-tab |
bne kgc4 |
jsr SwitchIOFocus |
; Now eat up the ALT-TAB character |
; Flush the keyboard buffer |
lsr r4,r4,#4 |
stz KeybdTail,r4 |
stz KeybdHead,r4 |
bra nochar |
kgc4: |
and r1,r1,#$ff ; mask off control bits |
inx ; increment index |
and r2,r2,#$0f |
2642,9 → 2983,9
nochar: |
lda #-1 |
kgc3: |
plp |
pop r4 |
plx |
plp |
rts |
|
;------------------------------------------------------------------------------ |
2704,14 → 3045,14
ld r0,KEYBD+1 ; clear keyboard strobe |
bit #$800 ; is it a keydown event ? |
bne kgc1 |
bit #$200 ; check for ALT-tab |
bne kgc2 |
and r2,r1,#$7f |
cmp r2,#TAB ; if we find an ALT-tab |
bne kgc2 |
jsr SwitchIOFocus |
bra kgc1 |
kgc2: |
; bit #$200 ; check for ALT-tab |
; bne kgc2 |
; and r2,r1,#$7f |
; cmp r2,#TAB ; if we find an ALT-tab |
; bne kgc2 |
; jsr SwitchIOFocus |
; bra kgc1 |
;kgc2: |
and #$ff ; remove strobe bit |
ldx KeybdEcho ; is keyboard echo on ? |
beq gk1 |
3155,9 → 3496,8
lda #80 |
sta LEDS |
ldx RunningTCB |
bmi RunningTCBErr |
cpx #MAX_TASKNO |
bpl RunningTCBErr |
bhi Prompt3 |
lda #81 |
sta LEDS |
stz TCB_CursorCol,x ; go back to the start of the line |
3165,16 → 3505,12
tay |
lda #82 |
sta LEDS |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #'$' |
bne Prompt2 ; skip over '$' prompt character |
lda #83 |
sta LEDS |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
|
; Dispatch based on command character |
; |
3183,9 → 3519,7
beq EditMem |
cmp #'D' |
bne Prompt8 |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #'R' |
beq DumpReg |
cmp #'I' |
3195,14 → 3529,14
Prompt8: |
cmp #'F' |
bne Prompt7 |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #'L' |
bne Prompt8a |
jsr DumpIOFocusList |
jmp Monitor |
Prompt8a: |
cmp #'I' |
beq DoFig |
cmp #'M' |
beq DoFmt |
dey |
3221,7 → 3555,7
bne Prompt5 |
lda #3 ; priority level 3 |
ldy #$C000 ; start address $C000 |
ldx #$20000000 ; flags: emmulation mode set |
ldx #$00000000 ; flags: |
jsr StartTask |
bra Monitor |
emm |
3249,8 → 3583,8
lda #4 ; priority level 4 |
ldx #0 ; zero all flags at startup |
ldy #RandomLines ; task address |
jsr (y) |
; jsr StartTask |
; jsr (y) |
jsr StartTask |
jmp Monitor |
; jmp RandomLinesCall |
Prompt12: |
3262,17 → 3596,34
ldy #Piano |
jsr StartTask |
jmp Monitor |
|
Prompt14: |
cmp #'T' |
bne Prompt15 |
jsr MonGetch |
cmp #'O' |
bne Prompt14a |
jsr DumpTimeoutList |
jmp Monitor |
Prompt14a: |
cmp #'I' |
bne Prompt14b |
jsr DisplayDatetime |
jmp Monitor |
Prompt14b: |
cmp #'E' |
bne Prompt14c |
jsr ReadTemp |
jmp Monitor |
Prompt14c: |
dey |
jsr DumpTaskList |
jmp Monitor |
|
Prompt15: |
cmp #'S' |
bne Prompt16 |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #'P' |
bne Prompt18 |
jsr ignBlanks |
3295,23 → 3646,44
Prompt16: |
cmp #'e' |
bne Prompt17 |
jsr eth_main |
lda #1 |
ldx #0 |
ldy #eth_main |
jsr StartTask |
; jsr eth_main |
jmp Monitor |
Prompt17: |
cmp #'R' |
bne Monitor |
lda (y) |
iny |
jsr ScreenToAscii |
bne Prompt19 |
jsr MonGetch |
cmp #'S' |
beq LoadSector |
dey |
bra SetRegValue |
jmp Monitor |
Prompt19: |
cmp #'K' |
bne Monitor |
Prompt19a: |
jsr MonGetch |
cmp #' ' |
bne Prompt19a |
jsr ignBlanks |
jsr GetDecNumber |
jsr KillTask |
jmp Monitor |
|
message "Prompt16" |
RandomLinesCall: |
; jsr RandomLines |
jmp Monitor |
|
MonGetch: |
lda (y) |
iny |
jsr ScreenToAscii |
rts |
|
DoDir: |
jsr do_dir |
jmp Monitor |
3318,16 → 3690,18
DoFmt: |
jsr do_fmt |
jmp Monitor |
|
DoFig: |
lda #3 ; priority level 3 |
ldy #$A000 ; start address $A000 |
ldx #$20000000 ; flags: emmulation mode set |
jsr StartTask |
bra Monitor |
|
TestCLS: |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #'L' |
bne Monitor |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #'S' |
bne Monitor |
jsr ClearScreen |
3348,6 → 3722,8
db "D = Dump memory",CR,LF |
db "F = Fill memory",CR,LF |
db "FL = Dump I/O Focus List",CR,LF |
; db "FIG = start FIG Forth",CR,LF |
db "KILL n = kill task #n",CR,LF |
db "B = start tiny basic",CR,LF |
db "b = start EhBasic 6502",CR,LF |
db "J = Jump to code",CR,LF |
3355,6 → 3731,9
db "r = random lines - test bitmap",CR,LF |
db "e = ethernet test",CR,LF |
db "T = Dump task list",CR,LF |
db "TO = Dump timeout list",CR,LF |
db "TI = display date/time",CR,LF |
db "TEMP = display temperature",CR,LF |
db "P = Piano",CR,LF,0 |
|
;------------------------------------------------------------------------------ |
3365,9 → 3744,7
; |
ignBlanks: |
ignBlanks1: |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
cmp #' ' |
beq ignBlanks1 |
dey |
3575,9 → 3952,7
ldx #0 |
ld r4,#8 |
gthxn2: |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
jsr AsciiToHexNybble |
cmp #-1 |
beq gthxn1 |
3600,9 → 3975,7
ld r4,#10 |
ld r5,#10 |
gtdcn2: |
lda (y) |
iny |
jsr ScreenToAscii |
jsr MonGetch |
jsr AsciiToDecNybble |
cmp #-1 |
beq gtdcn1 |
3667,14 → 4040,15
pha |
phx |
phy |
ldx #(1364*768)>>2 ; x = # words to clear |
lda #0x29292929 ; acc = color for four pixels |
lda #(1364*768)>>2 ; a = # words to clear |
ldx #0x29292929 ; acc = color for four pixels |
ldy #BITMAPSCR ; y = screen address |
cbsj4 |
sta (y) ; store pixel data |
iny ; advance screen address |
dex ; decrement pixel count and loop back |
bne cbsj4 |
stos |
;cbsj4 |
; sta (y) ; store pixel data |
; iny ; advance screen address |
; dex ; decrement pixel count and loop back |
; bne cbsj4 |
ply |
plx |
pla |
3700,7 → 4074,7
ld r3,Milliseconds |
sub r3,r3,r4 |
cmp r3,#1000 |
bpl sac97Abort |
bhi sac97Abort |
jsr KeybdGetChar ; see if we needed to CTRL-C |
cmp #CTRLC |
beq sac973 |
3722,7 → 4096,7
ld r3,Milliseconds |
sub r3,r3,r4 |
cmp r3,#1000 |
bpl sac97Abort |
bhi sac97Abort |
jsr KeybdGetChar |
cmp #CTRLC |
beq sac975 |
3751,9 → 4125,8
;-------------------------------------------------------------------------- |
; |
Beep: |
pha |
lda #15 ; master volume to max |
sta PSG+128 |
sta PSG+64 |
lda #13422 ; 800Hz |
sta PSGFREQ0 |
; decay (16.384 ms)2 |
3770,9 → 4143,10
sta PSGCTRL0 |
lda #100 ; delay about 1s |
jsr Sleep |
lda #83 |
sta LEDS |
lda #0x0000 ; gate off, output enable off, no waveform |
sta PSGCTRL0 |
pla |
rts |
|
;-------------------------------------------------------------------------- |
3781,7 → 4155,7
Piano: |
jsr RequestIOFocus |
lda #15 ; master volume to max |
sta PSG+128 |
sta PSG+64 |
playnt: |
jsr KeybdGetChar |
cmp #CTRLC |
4470,6 → 4844,119
my_MAC5 EQU 0xDA |
my_MAC6 EQU 0x42 |
|
; r1 = PHY |
; r2 = regnum |
; r3 = data |
; |
eth_mii_write: |
pha |
phx |
push r4 |
ld r4,#ETHMAC |
asl r2,r2,#8 |
or r1,r1,r2 |
sta ETH_MIIADDRESS,r4 |
sty ETH_MIITX_DATA,r4 |
lda #ETH_WCTRLDATA |
sta ETH_MIICOMMAND,r4 |
stz ETH_MIICOMMAND,r4 |
emiw1: |
lda ETH_MIISTATUS,r4 |
bit #ETH_MIISTATUS_BUSY |
bne emiw1 |
pop r4 |
plx |
pla |
rts |
|
; r1 = PHY |
; r2 = reg |
|
eth_mii_read: |
phx |
phy |
ldy #ETHMAC |
asl r2,r2,#8 |
or r1,r1,r2 |
sta ETH_MIIADDRESS,y |
lda #ETH_MIICOMMAND_RSTAT |
sta ETH_MIICOMMAND,y |
stz ETH_MIICOMMAND,y |
emir1: |
lda ETH_MIISTATUS,y |
bit #ETH_MIISTATUS_BUSY |
bne emir1 |
lda ETH_MIIRX_DATA,y |
ply |
plx |
rts |
|
ethmac_setup: |
ld r4,#ETHMAC |
lda #ETH_MIIMODER_RST |
sta ETH_MIIMODER,r4 |
lda ETH_MIIMODER,r4 |
and #~ETH_MIIMODER_RST |
sta ETH_MIIMODER,r4 |
lda #$10 ; /16=1.25MHz |
sta ETH_MIIMODER,r4 ; Clock divider for MII Management interface |
lda #ETH_MODER_RST |
sta ETH_MODER,r4 |
lda ETH_MODER,r4 |
and #~ETH_MODER_RST |
sta ETH_MODER,r4 |
|
stz ETH_MIITX_DATA,r4 |
stz ETH_MIIADDRESS,r4 |
stz ETH_MIICOMMAND,r4 |
|
lda #0xEEF0DA42 |
sta ETH_MAC_ADDR0,r4 ; MAC0 |
lda #0x00FF |
sta ETH_MAC_ADDR1,r4 ; MAC1 |
|
lda #-1 |
sta ETH_INT_SOURCE,r4 |
|
; Advertise support for 10/100 FD/HD |
lda #ETH_PHY |
ldx #ETH_MII_ADVERTISE |
jsr eth_mii_read |
or r3,r1,#ETH_ADVERTISE_ALL |
lda #ETH_PHY |
ldx #ETH_MII_ADVERTISE |
jsr eth_mii_write |
|
; Do NOT advertise support for 1000BT |
lda #ETH_PHY |
ldx #ETH_MII_CTRL1000 |
jsr eth_mii_read |
and r3,r1,#~(ETH_ADVERTISE_1000FULL|ETH_ADVERTISE_1000HALF) |
lda #ETH_PHY |
ldx #ETH_MII_CTRL1000 |
jsr eth_mii_write |
|
; Disable 1000BT |
lda #ETH_PHY |
ldx #ETH_MII_EXPANSION |
jsr eth_mii_read |
and r3,r1,#~(ETH_ESTATUS_1000_THALF|ETH_ESTATUS_1000_TFULL) |
ldx #ETH_MII_EXPANSION |
jsr eth_mii_write |
|
; Restart autonegotiation |
lda #0 |
ldx #ETH_MII_BMCR |
jsr eth_mii_read |
and r3,r1,#~(ETH_BMCR_ANRESTART|ETH_BMCR_ANENABLE) |
lda #7 |
jsr eth_mii_write |
|
; Enable BOTH the transmiter and receiver |
lda #$A003 |
sta ETH_MODER,r4 |
rts |
|
; Initialize the ethmac controller. |
; Supply a MAC address, set MD clock |
; |
4478,10 → 4965,12
pha |
phy |
ldy #ETHMAC |
lda #0x64 ; 100 |
sta ETH_MIIMODER,y |
lda #7 ; PHY address |
sta ETH_MIIADDRESS,y |
lda #$A003 |
sta ETH_MODER,y |
; lda #0x64 ; 100 |
; sta ETH_MIIMODER,y |
; lda #7 ; PHY address |
; sta ETH_MIIADDRESS,y |
lda #0xEEF0DA42 |
sta ETH_MAC_ADDR0,y ; MAC0 |
lda #0x00FF |
4508,15 → 4997,18
eth1: |
nop |
ldx ETH_INT_SOURCE,y |
and r2,r2,#4 ; get bit #2 |
bit r2,#4 ; get bit #2 |
beq eth1 |
ldx 0x180,y ; get from descriptor |
lsr r2,r2,#16 |
ldy #0 |
ld r4,#TEXTSCR+3780 ; second last line of screen |
pha |
jsr GetScreenLocation |
add r4,r1,3780 ; second last line of screen |
pla |
eth20: |
add r5,r1,r3 |
ldx (r5) ; get byte |
lb r2,0,r5 ; get byte |
add r5,r4,r3 |
stx (r5) ; store to screen |
iny |
4584,7 → 5076,7
; wait for tx buffer to be clear |
eth8: |
ld r4,0x100,y |
and r4,r4,#$8000 |
bit r4,#$8000 |
bne eth8 |
ld r4,#1 ; clear tx interrupt |
st r4,ETH_INT_SOURCE,y |
4770,9 → 5262,18
eor r1,r1,r1 |
bra eth13 |
|
msgEthTest |
db CR,LF,"Ethernet test - press CTRL-C to exit.",CR,LF,0 |
|
message "eth_main" |
eth_main: |
jsr eth_init |
jsr RequestIOFocus |
jsr ClearScreen |
jsr HomeCursor |
lda #msgEthTest |
jsr DisplayStringB |
; jsr eth_init |
jsr ethmac_setup |
eth_loop: |
jsr KeybdGetChar |
cmp #-1 |
4779,6 → 5280,9
beq eth17 |
cmp #CTRLC |
bne eth17 |
lda #$A000 ; tunr off transmit/recieve |
sta ETH_MODER+ETHMAC |
jsr ReleaseIOFocus |
rts |
eth17 |
lda #eth_rx_buffer<<2 ; memory address zero |
4954,6 → 5458,7
;-------------------------------------------------------------------------- |
; Initialize sprite image caches with random data. |
;-------------------------------------------------------------------------- |
message "RandomizeSprram" |
RandomizeSprram: |
ldx #SPRRAM |
ld r4,#14336 ; number of chars to initialize |
4969,6 → 5474,7
; Draw random lines on the bitmap screen. |
;-------------------------------------------------------------------------- |
; |
message "RandomLines" |
RandomLines: |
pha |
phx |
4976,28 → 5482,34
push r4 |
push r5 |
jsr RequestIOFocus |
jsr ClearScreen |
jsr HomeCursor |
lda #msgRandomLines |
jsr DisplayStringB |
rl5: |
tsr LFSR,r1 |
tsr LFSR,r2 |
tsr LFSR,r3 |
mod r1,r1,#1364 |
mod r2,r2,#768 |
jsr DrawPixel |
tsr LFSR,r1 |
sta LineColor ; select a random color |
rl1: ; random X0 |
tsr LFSR,r1 |
ld r5,#1364 |
mod r1,r1,r5 |
mod r1,r1,#1364 |
rl2: ; random X1 |
tsr LFSR,r3 |
mod r3,r3,r5 |
mod r3,r3,#1364 |
rl3: ; random Y0 |
tsr LFSR,r2 |
ld r5,#768 |
mod r2,r2,r5 |
mod r2,r2,#768 |
rl4: ; random Y1 |
tsr LFSR,r4 |
ld r5,#768 |
mod r4,r4,r5 |
mod r4,r4,#768 |
rl8: |
ld r5,GA_STATE ; make sure state is IDLE |
bne rl8 |
jsr DrawLine |
jsr KeybdGetChar |
cmp #CTRLC |
5012,6 → 5524,9
pla |
rts |
|
msgRandomLines: |
db CR,LF,"Random lines running - press CTRL-C to exit.",CR,LF,0 |
|
;-------------------------------------------------------------------------- |
; Draw a pixel on the bitmap screen. |
; r1 = x coordinate |
5018,15 → 5533,24
; r2 = y coordinate |
; r3 = color |
;-------------------------------------------------------------------------- |
message "DrawPixel" |
DrawPixel: |
pha |
sta GA_X0 |
stx GA_Y0 |
sty GA_PEN |
lda #1 |
sta GA_CMD |
pla |
rts |
|
comment ~ |
pha |
phx |
push r4 |
ld r4,#768 |
mod r2,r2,r4 |
ld r4,#1364 |
mod r1,r1,r4 |
mul r2,r2,r4 ; y * 1364 |
mod r2,r2,#768 |
mod r1,r1,#1364 |
mul r2,r2,#1364 ; y * 1364 |
add r1,r1,r2 ; + x |
sb r3,BITMAPSCR<<2,r1 |
pop r4 |
5033,6 → 5557,7
plx |
pla |
rts |
~ |
|
;-------------------------------------------------------------------------- |
; Draw a line on the bitmap screen. |
5056,8 → 5581,22
;270 GOTO 150 |
;300 RETURN |
|
message "DrawLine" |
DrawLine: |
pha |
sta GA_X0 |
stx GA_Y0 |
sty GA_X1 |
st r4,GA_Y1 |
lda LineColor |
sta GA_PEN |
lda #2 |
sta GA_CMD |
pla |
rts |
|
comment ~ |
pha |
phx |
phy |
push r4 |
5134,10 → 5673,192
plx |
pla |
rts |
~ |
|
;include "float.asm" |
|
;-------------------------------------------------------------------------- |
; RTF65002 code to display the date and time from the date/time device. |
;-------------------------------------------------------------------------- |
DisplayDatetime |
pha |
phx |
lda #' ' |
jsr DisplayChar |
stz DATETIME_SNAPSHOT ; take a snapshot of the running date/time |
lda DATETIME_DATE |
tax |
lsr r1,r1,#16 |
jsr DisplayHalf ; display the year |
lda #'/' |
jsr DisplayChar |
txa |
lsr r1,r1,#8 |
and #$FF |
jsr DisplayByte ; display the month |
lda #'/' |
jsr DisplayChar |
txa |
and #$FF |
jsr DisplayByte ; display the day |
lda #' ' |
jsr DisplayChar |
lda #' ' |
jsr DisplayChar |
lda DATETIME_TIME |
tax |
lsr r1,r1,#24 |
jsr DisplayByte ; display hours |
lda #':' |
jsr DisplayChar |
txa |
lsr r1,r1,#16 |
jsr DisplayByte ; display minutes |
lda #':' |
jsr DisplayChar |
txa |
lsr r1,r1,#8 |
jsr DisplayByte ; display seconds |
lda #'.' |
jsr DisplayChar |
txa |
jsr DisplayByte ; display 100ths seconds |
jsr CRLF |
plx |
pla |
rts |
|
;-------------------------------------------------------------------------- |
; ReadTemp |
; Read and display the temperature from a DS1626 temperature sensor |
; device. RTF65002 source code. |
;-------------------------------------------------------------------------- |
DS1626_CMD =$FFDC0300 |
DS1626_DAT =$FFDC0301 |
; Commands |
START_CNV = $51; |
STOP_CNV = $22; |
READ_TEMP = $AA; |
READ_CONFIG = $AC; |
READ_TH = $A1; |
READ_TL = $A2; |
WRITE_TH = $01; |
WRITE_TL = $02; |
WRITE_CONFIG = $0C; |
POR = $54; |
|
ReadTemp: |
lda CONFIGREC ; Do we even have a temperature sensor ? |
bit #$10 |
beq rdtmp3 ; If not, output '0.000' |
rdtmp1: |
; On power up the DS1626 interface circuit sends a power on reset (POR) |
; command to the DS1626. Waiting here makes sure this command has been |
; completed. |
jsr rdt_busy_wait |
lda #$0F ; 12 bits resolution, cpu mode, one-shot mode |
sta DS1626_DAT |
lda #WRITE_CONFIG ; write the desired config to the device |
sta DS1626_CMD |
jsr rdt_busy_wait |
lda #10 |
jsr tSleep |
lda #0 |
sta DS1626_DAT |
lda #START_CNV ; issue a start conversion command |
sta DS1626_CMD |
jsr rdt_busy_wait |
lda #10 |
jsr tSleep |
; Now poll the config register to determine when the conversion has completed. |
rdtmp2: |
lda #READ_CONFIG ; issue the READ_CONFIG command |
sta DS1626_CMD |
jsr rdt_busy_wait |
pha |
lda #10 ; Wait a bit before checking again. The conversion |
jsr tSleep ; can take up to 1s to complete. |
pla |
bit #$80 ; test done bit |
beq rdtmp2 ; loop back if not done conversion |
lda #0 |
sta DS1626_DAT ; issue a stop conversion command |
lda #STOP_CNV |
sta DS1626_CMD |
jsr rdt_busy_wait |
lda #10 |
jsr tSleep |
lda #READ_TEMP ; issue the READ_TEMP command |
sta DS1626_CMD |
jsr rdt_busy_wait |
pha |
lda #10 |
jsr tSleep |
pla |
rdtmp4: |
jsr CRLF |
and #$FFF |
bit #$800 ; check for negative temperature |
beq rdtmp7 |
sub r1,r0,r1 ; negate the number |
and #$FFF |
pha |
lda #'-' ; output a minus sign |
jsr DisplayChar |
pla |
rdtmp7: |
pha ; save off value |
lsr r1,r1,#4 ; get rid of fractional portion |
and #$7F ; strip off sign bit |
ldx #3 ; output the whole number part |
jsr PRTNUM |
lda #'.' ; followed by a decimal point |
jsr DisplayChar |
pla ; get back temp value |
and #$0F |
mul r1,r1,#625 ; 1/16th's per degree |
pha ; save off fraction bits |
div r1,r1,#100 ; calculate the first digit |
add #'0' |
jsr DisplayChar ; output digit |
pla ; get back fractions bits |
pha ; and save again |
div r1,r1,#10 ; shift over to second digit |
mod r1,r1,#10 ; ignore high order bits |
add #'0' |
jsr DisplayChar ; display the digit |
pla ; get back fraction |
mod r1,r1,#10 ; compute low order digit |
add #'0' |
jsr DisplayChar ; display low order digit |
jsr CRLF |
rts |
rdtmp3: |
lda #0 |
bra rdtmp4 |
|
; Returns: |
; acc = value from data register |
; |
rdt_busy_wait: |
jsr KeybdGetChar |
cmp #CTRLC |
beq Monitor |
lda DS1626_DAT |
bit #$8000 |
bne rdt_busy_wait |
rts |
|
tSleep: |
ldx Milliseconds |
txa |
tSleep1: |
ldx Milliseconds |
sub r2,r2,r1 |
cpx #100 |
blo tSleep1 |
rts |
|
;============================================================================== |
; Memory Management routines follow. |
;============================================================================== |
5284,11 → 6005,17
message "bus_err_rout" |
bus_err_rout: |
cld |
ldx #87 |
stx LEDS |
pla ; get rid of the stacked flags |
ply ; get the error PC |
ldx #$05FFFFF8 ; setup stack pointer top of memory |
txs |
ldx #88 |
stx LEDS |
jsr CRLF |
stz RunningTCB |
stz IOFocusNdx |
lda #msgBusErr |
jsr DisplayStringB |
tya |
5297,12 → 6024,28
jsr DisplayStringB |
tsr #9,r1 |
jsr DisplayWord |
cli ; enable interrupts so we can get a char |
ldx #89 |
stx LEDS |
ldx #128 |
ber2: |
lda #' ' |
jsr DisplayChar |
tsr hist,r1 |
jsr DisplayWord |
dex |
bne ber2 |
jsr CRLF |
ber3: |
nop |
jmp ber3 |
;cli ; enable interrupts so we can get a char |
ber1: |
jsr KeybdGetChar |
jsr KeybdGetCharDirect ; Don't use the keyboard buffer |
cmp #-1 |
beq ber1 |
jmp ber1 |
lda RunningTCB |
jsr KillTask |
jmp SelectTaskToRun |
|
msgBusErr: |
db "Bus error at: ",0 |
5309,13 → 6052,33
msgDataAddr: |
db " data address: ",0 |
|
|
;------------------------------------------------------------------------------ |
; Reschedule tasks to run without affecting the timeout list timing. |
;------------------------------------------------------------------------------ |
; |
reschedule: |
cld ; clear extended precision mode |
|
pusha ; save off regs on the stack |
|
ldx RunningTCB |
tsa ; save off the stack pointer |
sta TCB_SPSave,x |
tsr sp8,r1 ; and the eight bit mode stack pointer |
sta TCB_SP8Save,x |
tsr abs8,r1 |
sta TCB_ABS8Save,x ; 8 bit emulation base register |
jmp SelectTaskToRun |
|
strStartQue: |
db 1,0,0,0,2,0,0,0,3,1,0,0,4,0,0,0 |
db 1,0,0,0,2,0,0,0,3,0,1,0,4,0,0,0 |
; db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
|
;------------------------------------------------------------------------------ |
; 100 Hz interrupt |
; - takes care of "flashing" the cursor |
; - decrements timeouts for tasks on timeout list |
; - switching tasks |
;------------------------------------------------------------------------------ |
; |
5324,13 → 6087,12
pha |
lda #3 ; reset the edge sense circuit |
sta PIC_RSTE |
; inc TEXTSCR+83 ; update IRQ live indicator on screen |
lda IRQFlag |
ina |
sta IRQFlag |
ror |
pla |
bcc p100Hz11 |
pla |
rti |
|
p100Hz11: |
5337,21 → 6099,8
|
cld ; clear extended precision mode |
|
; save off regs on the stack |
phx |
phy |
push r4 |
push r5 |
push r6 |
push r7 |
push r8 |
push r9 |
push r10 |
push r11 |
push r12 |
push r13 |
push r14 |
push r15 |
pusha ; save off regs on the stack |
|
ldx RunningTCB |
tsa ; save off the stack pointer |
sta TCB_SPSave,x |
5359,9 → 6108,7
sta TCB_SP8Save,x |
tsr abs8,r1 |
sta TCB_ABS8Save,x ; 8 bit emulation base register |
lda TCB_Status,x ; set the task status to PREEMPT |
and r1,r1,#~TS_RUNNING |
or r1,r1,#TS_PREEMPT |
lda #TS_READY |
sta TCB_Status,x |
p100Hz4: |
|
5375,10 → 6122,10
and #$E0 |
sb r1,IrqBase |
|
inc TEXTSCR+83 ; update IRQ live indicator on screen |
inc TEXTSCR+55 ; update IRQ live indicator on screen |
|
; flash the cursor |
cpx IOFocusNdx ; only flash the cursor for the task with the IO focus. |
cpx IOFocusNdx ; only bother to flash the cursor for the task with the IO focus. |
bne p100Hz1a |
lda CursorFlash ; test if we want a flashing cursor |
beq p100Hz1a |
5405,81 → 6152,73
jsr RemoveFromTimeoutList |
jsr AddTaskToReadyList |
bra p100Hz15 ; go back and see if there's another task to be removed |
|
; there could be a string of tasks to make ready. |
p100Hz14: |
dea ; decrement the entry's timeout |
sta TCB_Timeout,x |
|
p100Hz12: |
; Falls through into selecting a task to run |
|
;------------------------------------------------------------------------------ |
; Search the ready queues for a ready task. |
; The search is occasionally started at a lower priority queue in order |
; to prevent starvation of lower priority tasks. This is managed by |
; using a tick count as an index to a string containing the start que. |
;------------------------------------------------------------------------------ |
; |
SelectTaskToRun: |
; Search the ready queues for a ready task. |
; The search is occasionally started at a lower priority queue in order |
; to prevent starvation of lower priority tasks. This is managed by |
; using a tick count as an index to a string containing the start que. |
|
ld r6,#5 ; number of queues to search |
ldy IRQFlag ; use the IRQFlag as a buffer index |
lsr r3,r3,#1 ; the LSB is always the same |
and r3,r3,#$0F ; counts from 0 to 15 |
lb r3,strStartQue,y ; get the queue to start search at |
p100Hz2: |
lda HeadRdy0,y |
bmi p100Hz1 |
; Move the head of the ready queue to the tail |
jsr RemoveTaskFromReadyList ; remove task |
jsr AddTaskToReadyList ; add it back (automatically goes to tail spot) |
ldx TCB_Status,r1 ; the task is no longer running |
and r2,r2,#~TS_RUNNING |
stx TCB_Status,r1 |
lda HeadRdy0,y |
sttr2: |
lda QNdx0,y |
bmi sttr1 |
lda TCB_NxtRdy,r1 ; Advance the queue index |
sta QNdx0,y |
; This is the only place the RunningTCB is set (except for initialization). |
sta RunningTCB |
ldx TCB_Status,r1 ; flag the task as the running task |
or r2,r2,#TS_RUNNING ; task is now running and not preempt |
and r2,r2,#~TS_PREEMPT |
ldx #TS_RUNNING ; flag the task as the running task |
stx TCB_Status,r1 |
bra p100Hz3 |
p100Hz1: |
iny |
cpy #5 |
bne p100Hz5 |
ldy #0 |
p100Hz5 |
dec r6 |
bne p100Hz2 |
|
; here there were no tasks ready |
; this might happen if the interrupt is called before tasks |
; are setup. Otherwise the IDLE task should at least be running. |
bra p100Hz6 |
p100Hz3: |
p100Hz10 |
ldx RunningTCB |
; The mmu map better have the task control block area mapped |
; properly. |
tax |
lda CONFIGREC |
bit #4096 |
beq sttr4 |
lda TCB_mmu_map,x |
sta MMU_OKEY ; select the mmu map for the task |
lda #2 |
sta MMU_FUSE ; set fuse to 2 clocks before mapping starts |
sttr4: |
lda TCB_ABS8Save,x ; 8 bit emulation base register |
trs r1,abs8 |
trs r0,abs8 |
lda TCB_SP8Save,x ; get back eight bit stack pointer |
trs r1,sp8 |
ldx TCB_SPSave,x ; get back stack pointer |
txs |
; restore registers |
p100Hz6: |
pop r15 |
pop r14 |
pop r13 |
pop r12 |
pop r11 |
pop r10 |
pop r9 |
pop r8 |
pop r7 |
pop r6 |
pop r5 |
pop r4 |
ply |
plx |
pla |
popa ; restore registers |
rti |
|
; Set index to check the next ready list for a task to run |
sttr1: |
iny |
cpy #5 |
bne sttr5 |
ldy #0 |
sttr5 |
dec r6 |
bne sttr2 |
|
; Here there were no tasks ready |
; This should not be able to happen, so hang the machine. |
sttr3: |
ldx #94 |
stx LEDS |
bra sttr3 |
|
;------------------------------------------------------------------------------ |
; 1000 Hz interrupt |
; This IRQ must be fast. |
5491,7 → 6230,6
lda #2 ; reset edge sense circuit |
sta PIC_RSTE |
inc Milliseconds ; increment milliseconds count |
inc TEXTSCR+82 ; update IRQ live indicator on screen |
pla |
rti |
|
5502,31 → 6240,19
;------------------------------------------------------------------------------ |
slp_rout: |
cld ; clear extended precision mode |
pha |
phx |
phy |
push r4 |
push r5 |
push r6 |
push r7 |
push r8 |
push r9 |
push r10 |
push r11 |
push r12 |
push r13 |
push r14 |
push r15 |
ldx RunningTCB |
bmi RunningTCBErr |
and r2,r2,#$FF |
pusha |
lda RunningTCB |
cmp #MAX_TASKNO |
bhi slp1 |
jsr RemoveTaskFromReadyList |
tax |
tsa ; save off the stack pointer |
sta TCB_SPSave,x |
tsr sp8,r1 ; and the eight bit mode stack pointer |
sta TCB_SP8Save,x |
lda TCB_Status,x ; set the task status to SLEEP |
and r1,r1,#~TS_RUNNING |
or r1,r1,#TS_SLEEP |
tsr abs8,r1 |
sta TCB_ABS8Save,x |
lda #TS_SLEEP ; set the task status to SLEEP |
sta TCB_Status,x |
slp1: |
jmp SelectTaskToRun |
5557,7 → 6283,7
sta 4,x ; save incremented return address back to stack |
ldx #64 |
ioi1: |
tsr abs8,r1 |
tsr hist,r1 |
jsr DisplayWord |
lda #' ' |
jsr DisplayChar |