 lib environment
 sttl Sleep and Wakeup routines
 pag
 name sleep
 global wakeup,sleep,tstint,xmtint,doint,cordm,intrpt,sdoint,rstint

*
* wakeup
*
* Wakeup all tasks waiting the event designated
* in the y register.  The x reg is preserved.
*

wakeup pshs cc,d,x,u save registers
 clr 0,-s
 seti mask interupts
 ldu #slplst
 ldx tsslnk,u point to sleep list
 beq wakeu4
wakeu2 cmpy tsevnt,x check event
 beq wakeu5
 leau 0,x mark this entry
wakeu3 ldx tsslnk,x follow chain
 bne wakeu2 end of list?
wakeu4 ldb 0,s+ get flag
 beq wake45
 tst rdytci swapper need awakened?
 beq wake45
 pshs y
 ldy #rdytci wakeup swapper event
 clr 0,y clear event flag
 bsr wakeup
 puls y reset registers
wake45 puls cc,d,x,u,pc return
wakeu5 lda tsmode,x check mode byte
 bita #TCORE is this guy swapped?
 bne wakeu6
 inc 0,s set wakeup flag
wakeu6 pshs x,y,u save registers
 ldd tsslnk,x remove from list
 std tsslnk,u
 lbsr makrdy put on ready list
 puls u,x,y
 bra wakeu3 repeat

 pag

*
* sleep
*
* Sleep will put this task to sleep with priority
* specified in the b register.  On entry, y is pointing
* to the event which will be awakened.
*

sleep pshs cc,x,u save registers
 ldx utask point to task
 lda tsact,x test activity counter
 beq sleep2 any there?
 dec tsact,x dec the count
sleep2 tstb check priority
 bmi sleep4 neg prior?
 seti mask ints
 stb tsprir,x set priority
 sty tsevnt,x set event
 ldd slplst+tsslnk get head of list
 std tsslnk,x save as link
 stx slplst+tsslnk set new link
 lda #TSLEEP set status
 sta tsstat,x
 lbsr rsched reschedule the cpu
 clri
 bra sleep6
sleep4 pshs b,y save data
 tst tssgnl,x test for special int
 bpl slee42
 sez set zero status
 bra slee45
slee42 bsr tstint signals waiting?
slee45 puls b,y
 bne sleep7
 seti mask ints
 stb tsprir,x set priority
 sty tsevnt,x set event
 lda #TSLEEP set status
 sta tsstat,x
 ldd slplst+tsslnk get head of list
 std tsslnk,x set new link
 stx slplst+tsslnk set new head
 tst rdytgo check scheduling flag
 beq sleep5
 clr rdytgo
 ldy #rdytgo wakeup events
 lbsr wakeup
sleep5 lbsr rsched reschedule cpu
 clri
 ldx utask get task entry
 tst tssgnl,x check for special int
 bmi sleep6
 bsr tstint signals waiting?
 bne sleep7
sleep6 puls cc,x,u,pc return
sleep7 puls cc,x,u reset cc and registers
 lds umark1 change stacks
 rts return

 pag

*
* tstint
*
* Test for a interrupt present.
*

tstint ldx utask point to task
 lda tssgnl,x get signal
 beq tstin4
 anda #$7f mask special bit
 deca remove bias
 asla
 ldy #usigs point to table
 ldd a,y get particular signal
 beq tstin1
 cmpd #1 ignore it?
 beq tstin2
tstin1 clz set ne status
 rts return
tstin2 ldd #0 set zero status
tstin4 rts return


*
* intrpt
*
* Send an interrupt to all tasks which are
* attached to the terminal structure pointed
* to by x. The interrupt type is in b.
*

intrpt pshs x save pointer
 tfr x,y
 ldx tsktab point to task tables
intrp1 cmpy tstty,x match?
 bne intrp2
 pshs d,x,y save these regs
 bsr xmtint go transmit interrupt
 puls d,x,y
intrp2 leax TSKSIZ,x next entry
 cmpx tskend end of table?
 bne intrp1
 puls x,pc return

 pag

*
* xmtint
*
* Transmit the specified interupt designated in b.
*

xmtint cmpb #SIGCNT check if valid type
 bhi xmtin8
 tstb is it zero?
 beq xmtin8 if so, error
 tsta check for special case
 beq xmtin1
 orb #$80 set special bit
xmtin1 stb tssgnl,x set intrpt
 ldb #USERPR set priority
 cmpb tsprir,x
 ble xmtin2
 stb tsprir,x
xmtin2 ldb tsstat,x get status
 cmpb #TSLEEP is it sleeping?
 bne xmtin8
 ldb tsprir,x get priority
 bpl xmtin8 if plus, leave alone
 tsta is hi byte non-zero?
 bne xmtin8 if so - don't awaken
xmtin5 pshs cc,x,y save regs
 seti
 ldd 1,s get task entry pointer
 ldx #slplst point to sleep list
xmtin6 cmpd tsslnk,x see if links match
 beq xmtin9
 ldx tsslnk,x follow link
 bne xmtin6 repeat?
 puls cc,x,y reset stack
xmtin8 rts return
xmtin9 ldy 1,s point to task entry
 ldd tsslnk,y get fwd link
 std tsslnk,x save in previous
 puls cc,x,y get regs back
 lda tsmode,x get modes
 bita #TCORE is task swapped?
 lbne makrdy go make ready
 pshs x,y save regs
 jsr makrdy go make ready
 tst rdytci swapper sleeping?
 beq xmti95
 ldy #rdytci get event
 clr 0,y zero event flag
 jsr wakeup wake him up!
xmti95 puls x,y,pc return

 pag

*
* doint
*
* Do the interrupt specified in the task table.
*

doint ldx utask point to task
 ldb tssgnl,x get int type
 andb #$7f mask special bit
 pshs b remember signal number
 clr tssgnl,x clear it out
 ldy #usigs point to status table
 decb remove bias
 aslb *2
 ldu b,y get the status
 beq doint4 exit if zero
 pshs u save status
 clr uerror
 tst SWTPCvii
 bne 0f
 cmpb #(TRACS-1)*2 is it trace?
 beq doint2
0 clr b,y clear out status
 incb
 clr b,y
doint2 ldx usp point to reg list
 leax -STKREG,x make room for registers
 stx usp save new sp
 ldb #5 set word count
 pshs b,x save regs
doin3 leax STKREG,x point to old stack
 lbsr gtuwrd get a word
 ldx 1,s get new sp
 lbsr ptuwrd save out word
 dec 0,s dec the counter
 beq doin35
 ldx 1,s get sp pointer
 leax 2,x advance to next word
 stx 1,s
 bra doin3 repeat
doin35 puls b,x reset stack
 puls d get interrupt address
 std urglst+UPC save in PC
 leax 2,x point to pc
 lbsr ptuwrd give to user
 puls b get interrupt number
 clra
 leax -9,x store interrupt number in d
 jsr ptuwrd
 rts
doint4 puls a get interrupt number
 clrb
 std usarg0 save as exit status
 cmpa #3 check coredump ints
 blo doint6
 cmpa #4
 bls doint5
 cmpa #7
 blo doint6
 cmpa #9
 bhi doint6
doint5 bsr cordm make a core dump
 bne doint6 successful?
 lda usarg0 get status
 ora #$80 set core dump bit
 sta usarg0 save new status
doint6 lbra lexit go terminate task


 pag

*
* rstint
*
* Reset all interrupts which are not being
* ignored by the task (those which are not 1).
*

rstint ldx #usigs point to interrupts
 ldb #SIGCNT set counter
 pshs b save counter
rstin2 ldd 0,x++ get int status
 cmpd #1 is it 1?
 beq rstin4 if so, ignore it
 ldd #0 else clear int out
 std -2,x by setting to zero
rstin4 dec 0,s dec the counter
 bne rstin2 repeat til done
 puls b,pc clean stack & return


 pag

*
* cordm
*
* Make a core dump file of this task.
*

cordm clr uerror clear out error
 ldd #cornam point to 'core' name
 std ucname setup for path
 clrb set system space flag
 lbsr pthnmc go check path name
 cmpx #0 file already there?
 bne cordm2 if so, jump ahead
 lda uerror any errors
 bne cordm8 if so, exit
 ldd #$B set up perms
 lbsr crfil create the core file
 cmpx #0 were we successful?
 beq cordm8 if not, exit
cordm2 ldb #1 set write code
 lbsr genprm check permission to write
 bne cordm7 if not, exit
 lda fstat,x get fdn status
 bita #FMNT is it mounted?
 bne cordm7
 ldd uuid check user id againstactual
 cmpd uuida
 bne cordm7 if no match, exit
 pshs x save fdn pointer
 lbsr rmvfil truncate file to 0 length
 ldd #PAGSIZ set xfr count
 std uicnt
 ldd #0 set file pos to 0
 std uipos
 std uipos2
 sta uiosp set system space flag
 ldd #USRLOC<<12 point to user block
 std uistrt set as start pos
 ldy 0,s get fdn pointer
 lbsr filwr write out userblock data
 lda usizet get text size
 ldb usized get size of data
 beq cordm5 if null, skip
 ldy 0,s get fdn
 bsr secdm dump the data section
cordm5 ldb usizes get stack size
 decb dec by one (for userblock)
 beq cordm6
 pshs b save count
 lda #USRHIP get image size
 suba 0,s+ find map offset for stack
 ldy 0,s get fdn
 bsr secdm dump stack section
cordm6 puls x get fdn
cordm7 lbsr frefdn free the fdn
cordm8 tst uerror any errors?
 rts return


*
* secdm
*
* Dump the section of memory to the 'core' file.
* A has mem map offset, B has segment count, and
* Y has fdn pointer.
*

secdm lsla calculate segment address
 lsla
 lsla
 lsla
 pshs b save count on stack
 clrb finish making address
 std uistrt set start address
 ldd #0 calculate xfr count
secdm2 addd #PAGSIZ add in page size
 dec 0,s dec the count
 bne secdm2
 leas 1,s fix stack
 std uicnt save count
 ldb #1 set user space flag
 stb uiosp
 lbra filwr go write data


 pag

*
* sdoint
*
* Do interrupt from os call (special pre-process).
*

sdoint ldd urglst+UPC get new pc
 ldx usp get sp
 leax 10,x point to PC
 lbsr ptuwrd put pc in user
 ldd urglst+UX
 ldx usp get sp
 leax 4,x point to x slot
 lbsr ptuwrd put in user
 ldd urglst+UD get d reg
 ldx usp
 leax 1,x point to d slot
 lbsr ptuwrd
 ldb urglst+UCC get cc
 ldx usp get sp
 lbsr ptubyt write out byte
 lbra doint go do interrupt
