mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-09-27 12:55:35 +00:00
584 lines
8.8 KiB
NASM
584 lines
8.8 KiB
NASM
* $Id: select.asm,v 1.1 1998/02/02 08:19:46 taubert Exp $
|
|
*
|
|
* select.asm
|
|
*
|
|
* modified socket stuff - Derek Taubert - 12/13/94
|
|
* added GS/OS file support and proper return value - DT - 2/6/96
|
|
* added timeout support - DT - 2/13/96
|
|
*
|
|
|
|
mcopy m/select.mac
|
|
case on
|
|
copy inc/tty.inc
|
|
copy inc/gsos.inc
|
|
copy inc/kern.inc
|
|
copy global.equates
|
|
|
|
IncBusyFlag gequ $E10064
|
|
DecBusyFlag gequ $E10068
|
|
|
|
DebugNames gequ 1
|
|
|
|
*
|
|
*
|
|
*
|
|
|
|
TIselect START KERN2
|
|
TIselect name
|
|
using pipeRecord
|
|
using KernelStruct
|
|
using SelTimStruct
|
|
|
|
* locals
|
|
mask equ 1 1 used?
|
|
pPtr equ mask+4 5
|
|
fdtptr equ pPtr+4 9
|
|
fdPtr equ fdtptr+4 13 used?
|
|
slept equ fdPtr+4 17
|
|
r_mask equ slept+2 19
|
|
w_mask equ r_mask+4 23
|
|
x_mask equ w_mask+4 27,28,29,30
|
|
space equ x_mask+4-1
|
|
|
|
* intermediates
|
|
bsp equ x_mask+4 31
|
|
dsp equ bsp+1 32
|
|
rtl2 equ dsp+2 34
|
|
rtl1 equ rtl2+3 37
|
|
|
|
* args
|
|
errnoptr equ rtl1+3 40
|
|
timeout equ errnoptr+4 44
|
|
exceptfds equ timeout+4 48
|
|
writefds equ exceptfds+4 52
|
|
readfds equ writefds+4 56
|
|
width equ readfds+4 60
|
|
retval equ width+2 62
|
|
|
|
phd
|
|
phb
|
|
|
|
phk
|
|
plb
|
|
tsc
|
|
sec
|
|
sbc #space
|
|
tcd
|
|
tcs
|
|
|
|
stz retval
|
|
|
|
lda >procPtr
|
|
sta pPtr
|
|
lda >procPtr+2
|
|
sta pPtr+2
|
|
|
|
ldy #openFiles-CKernData
|
|
lda [pPtr],y
|
|
sta fdtptr
|
|
ldy #(openFiles-CKernData+2)
|
|
lda [pPtr],y
|
|
sta fdtptr+2
|
|
|
|
lda readfds
|
|
ora readfds+2
|
|
beq checkwr1
|
|
pei (readfds+2)
|
|
pei (readfds)
|
|
pei (fdtptr+2)
|
|
pei (fdtptr)
|
|
jsl validate_mask
|
|
cmp #0
|
|
bne err_mask
|
|
|
|
checkwr1 lda writefds
|
|
ora writefds+2
|
|
beq checkex1
|
|
pei (writefds+2)
|
|
pei (writefds)
|
|
pei (fdtptr+2)
|
|
pei (fdtptr)
|
|
jsl validate_mask
|
|
cmp #0
|
|
bne err_mask
|
|
|
|
checkex1 lda exceptfds
|
|
ora exceptfds+2
|
|
beq enter_loop
|
|
pei (exceptfds+2)
|
|
pei (exceptfds)
|
|
pei (fdtptr+2)
|
|
pei (fdtptr)
|
|
jsl validate_mask
|
|
cmp #0
|
|
beq enter_loop
|
|
err_mask lda #EBADF
|
|
sta [errnoptr]
|
|
lda #-1
|
|
sta retval
|
|
jmp goaway
|
|
|
|
enter_loop anop
|
|
stz slept
|
|
jsr getSelTimIndex
|
|
lda #0
|
|
sta >SelTimExpired,x
|
|
lda >curProcInd
|
|
tax
|
|
lda #0
|
|
sta >p_waitvec,x ; just for kicks..
|
|
sta >p_waitvec+2,x
|
|
|
|
select_loop anop
|
|
* First, reset the local select masks we're using
|
|
lda #0
|
|
sta r_mask
|
|
sta r_mask+2
|
|
sta w_mask
|
|
sta w_mask+2
|
|
sta x_mask
|
|
sta x_mask+2
|
|
|
|
* Set Process' "selecting" flag
|
|
ldy #flags-KernelStruct
|
|
lda [pPtr],y
|
|
ora #FL_SELECTING
|
|
sta [pPtr],y
|
|
|
|
* For each FD, poll the device by calling its select routine
|
|
* If the descriptor can't do the operation, select must record that
|
|
* this process wants to do I/O.
|
|
lda readfds
|
|
ora readfds+2
|
|
beq checkwr2
|
|
pea SEL_READ
|
|
pei (readfds+2)
|
|
pei (readfds)
|
|
pei (fdtptr+2)
|
|
pei (fdtptr)
|
|
pea 0
|
|
tdc
|
|
clc
|
|
adc #retval
|
|
pha
|
|
jsl poll_mask
|
|
sta r_mask
|
|
stx r_mask+2
|
|
|
|
checkwr2 lda writefds
|
|
ora writefds+2
|
|
beq checkex2
|
|
pea SEL_WRITE
|
|
pei (writefds+2)
|
|
pei (writefds)
|
|
pei (fdtptr+2)
|
|
pei (fdtptr)
|
|
pea 0
|
|
tdc
|
|
clc
|
|
adc #retval
|
|
pha
|
|
jsl poll_mask
|
|
sta w_mask
|
|
stx w_mask+2
|
|
|
|
checkex2 lda exceptfds
|
|
ora exceptfds+2
|
|
beq endpoll
|
|
pea SEL_EXCEPT
|
|
pei (exceptfds+2)
|
|
pei (exceptfds)
|
|
pei (fdtptr+2)
|
|
pei (fdtptr)
|
|
pea 0
|
|
tdc
|
|
clc
|
|
adc #retval
|
|
pha
|
|
jsl poll_mask
|
|
sta x_mask
|
|
stx x_mask+2
|
|
|
|
endpoll php
|
|
sei
|
|
lda >curProcInd
|
|
tax
|
|
lda >flags,x
|
|
bit #FL_SELECTING
|
|
bne noloop
|
|
* Somebody cleared FL_SELECTING, we better check again
|
|
plp
|
|
jmp select_loop
|
|
|
|
noloop and #FL_SELECTING.EOR.$FFFF
|
|
sta >flags,x
|
|
|
|
; retval slept timeout SelTimExpired
|
|
; 0 0 0 X sleep
|
|
; 0 0 1 X set alarm, sleep
|
|
; 0 1 0 X return -1, EINTR
|
|
; 0 1 1 0 return -1, EINTR
|
|
; 0 1 1 1 return 0
|
|
; 1 X X X return retval
|
|
lda retval
|
|
bne done1 ; we have a fd, kaptain!
|
|
lda slept
|
|
beq tosleep
|
|
; check to see how k_sleep woke up
|
|
lda timeout
|
|
ora timeout+2
|
|
beq interup
|
|
jsr getSelTimIndex
|
|
lda >SelTimExpired,x
|
|
beq interup
|
|
lda #0
|
|
sta >SelTimExpired,x
|
|
done1 bra done ; we timed out!
|
|
interup plp
|
|
lda #EINTR
|
|
sta [errnoptr]
|
|
lda #-1
|
|
sta retval
|
|
jmp goaway
|
|
|
|
timeoutTMP dc i4'0'
|
|
; set up alarm here
|
|
tosleep lda timeout
|
|
ora timeout+2
|
|
beq noalrm
|
|
setalrm anop
|
|
MUL4 [timeout],#10,timeoutTMP
|
|
; FIXME: add microseconds to timeoutTMP too
|
|
jsr getSelTimIndex
|
|
lda timeoutTMP
|
|
bne nofudge
|
|
inc A ; so SelTimTimeout never starts at zero
|
|
nofudge sta >SelTimTimeout,x
|
|
lda timeoutTMP+2
|
|
sta >SelTimTimeout+2,x
|
|
lda >curProcInd
|
|
sta >SelTimPID,x
|
|
|
|
noalrm lda >truepid
|
|
pha
|
|
pea 0
|
|
ph4 #selwait
|
|
jsl k_sleep
|
|
|
|
inc slept
|
|
lda timeout
|
|
ora timeout+2
|
|
beq noalrm2
|
|
; remove alarm here
|
|
jsr getSelTimIndex
|
|
lda #0
|
|
sta >SelTimTimeout,x
|
|
sta >SelTimTimeout+2,x
|
|
|
|
noalrm2 plp
|
|
jmp select_loop
|
|
|
|
done plp
|
|
ldy #2
|
|
lda r_mask
|
|
sta [readfds]
|
|
lda r_mask+2
|
|
sta [readfds],y
|
|
lda w_mask
|
|
sta [writefds]
|
|
lda w_mask+2
|
|
sta [writefds],y
|
|
lda x_mask
|
|
sta [exceptfds]
|
|
lda x_mask+2
|
|
sta [exceptfds],y
|
|
|
|
goaway anop
|
|
tsc
|
|
clc
|
|
adc #space
|
|
tcs
|
|
plb
|
|
pld
|
|
ldx #0
|
|
ldy #22
|
|
jmp >tool_exit
|
|
|
|
END
|
|
|
|
|
|
poll_mask START KERN2
|
|
poll_mask name
|
|
using KernelStruct
|
|
words_left equ 0
|
|
cur_fd equ 2
|
|
bitcount equ 4
|
|
wordind equ 6
|
|
fdPtr equ 8
|
|
outmask equ 12
|
|
|
|
subroutine (2:which,4:mask,4:fdtptr,4:fdsrdyptr),16
|
|
|
|
stz outmask
|
|
stz outmask+2
|
|
|
|
ldy #FDTfdTableSize
|
|
lda [fdtptr],y ; table size, divide by 16
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
sta words_left
|
|
stz cur_fd
|
|
stz wordind
|
|
val_loop1 lda #16
|
|
sta bitcount
|
|
ldy wordind
|
|
lda [mask],y
|
|
val_loop2 ror a ; rotate into carry flag
|
|
bcc dontcheck1 ; do not check this fd
|
|
pha
|
|
|
|
pei (cur_fd)
|
|
jsl getFDptr
|
|
sta fdPtr
|
|
stx fdPtr+2
|
|
|
|
; dispatch to the driver's select routine, which will tell us whether there's
|
|
; data and do other sundry stuff
|
|
|
|
lda [fdPtr] ; get device number
|
|
dec a ; dec to get device index
|
|
pha
|
|
pei (which) ; tell the driver which I/O operation
|
|
; had to add this parm - DT
|
|
lda >curProcInd ; current pid
|
|
pha
|
|
;
|
|
ldy #FDrefType
|
|
lda [fdPtr],y
|
|
cmp #FDsocket
|
|
beq selsok1
|
|
cmp #FDgsos
|
|
beq selsok2
|
|
; otherwise, it is #FDtty
|
|
; need to load A with dev type here, not ref type - DT
|
|
lda [fdPtr] ; get device number
|
|
dec a ; dec to get device index
|
|
ldy #t_select
|
|
jsl LineDiscDispatch
|
|
bra donesel1
|
|
|
|
; we can always read and write #FDgsos, never except
|
|
selsok2 anop
|
|
pla ; current pid
|
|
pla ; which operation
|
|
plx ; device number
|
|
cmp #SEL_EXCEPT
|
|
beq gsos_nox
|
|
sec
|
|
bra donesel2
|
|
gsos_nox clc
|
|
bra donesel2
|
|
|
|
selsok1 anop
|
|
jsl SOCKselect
|
|
|
|
donesel1 cmp #1 ; set carry properly
|
|
donesel2 bcc notready
|
|
lda [fdsrdyptr]
|
|
adc #0
|
|
sta [fdsrdyptr]
|
|
sec
|
|
notready ldx wordind
|
|
ror <outmask,x
|
|
|
|
pla
|
|
dontcheck inc cur_fd
|
|
dec bitcount
|
|
bne val_loop2
|
|
inc wordind
|
|
inc wordind
|
|
dec words_left
|
|
bne val_loop1
|
|
|
|
goaway return 4:outmask
|
|
dontcheck1 anop
|
|
ldx wordind
|
|
ror <outmask,x
|
|
bra dontcheck
|
|
END
|
|
|
|
|
|
validate_mask START KERN2
|
|
validate_mask name
|
|
words_left equ 0
|
|
cur_fd equ 2
|
|
res equ 4
|
|
bitcount equ 6
|
|
wordind equ 8
|
|
fdPtr equ 10
|
|
|
|
subroutine (4:mask,4:fdtptr),14
|
|
|
|
stz res
|
|
ldy #FDTfdTableSize
|
|
lda [fdtptr],y ; table size, divide by 16
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
sta words_left
|
|
stz cur_fd
|
|
stz wordind
|
|
val_loop1 lda #16
|
|
sta bitcount
|
|
ldy wordind
|
|
lda [mask],y
|
|
val_loop2 ror a ; rotate into carry flag
|
|
bcc dontcheck ; do not check this fd
|
|
pha
|
|
|
|
lda cur_fd
|
|
beq badfd ; fd 0 does not exist
|
|
pha
|
|
jsl getFDptr
|
|
sta fdPtr
|
|
stx fdPtr+2
|
|
lda [fdPtr]
|
|
beq badfd
|
|
ldy #FDrefType
|
|
lda [fdPtr],y
|
|
cmp #FDgsos
|
|
beq dn1
|
|
cmp #FDsocket
|
|
beq dn1
|
|
cmp #FDtty
|
|
bne badfd ; we only select on ttys & sockets
|
|
|
|
dn1 pla
|
|
dontcheck inc cur_fd
|
|
dec bitcount
|
|
bne val_loop2
|
|
inc wordind
|
|
inc wordind
|
|
dec words_left
|
|
bne val_loop1
|
|
|
|
goaway return 2:res
|
|
badfd pla
|
|
lda #1
|
|
sta res
|
|
bra goaway
|
|
END
|
|
|
|
|
|
selwakeupdefer START KERN2
|
|
selwakeupdefer name
|
|
subroutine (2:runflag,2:pid),0
|
|
|
|
pei (runflag)
|
|
pei (pid)
|
|
ph4 #selwait
|
|
jsl k_remove
|
|
return
|
|
END
|
|
|
|
|
|
selwakeup START KERN2
|
|
selwakeup name
|
|
selwait ENTRY
|
|
using KernelStruct
|
|
subroutine (2:pid,2:collflag),0
|
|
|
|
lda collflag
|
|
beq nocollision
|
|
|
|
ph4 #selwait
|
|
jsl k_wakeup
|
|
|
|
nocollision ldx pid
|
|
|
|
lda >p_waitvec,x
|
|
cmp #selwait
|
|
bne ck_coll
|
|
lda >p_waitvec+2,x
|
|
cmp #^selwait
|
|
bne ck_coll
|
|
lda >ProcessState,x
|
|
cmp #PS_SLEEP
|
|
bne ck_coll
|
|
|
|
ph4 #selwakeupdefer
|
|
lda pid
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
lsr a
|
|
pha
|
|
pea 1
|
|
jsl defer
|
|
bra goaway
|
|
|
|
ck_coll lda >flags,x
|
|
and #FL_SELECTING.EOR.$FFFF
|
|
sta >flags,x
|
|
|
|
goaway return
|
|
END
|
|
|
|
|
|
SelTimStruct DATA
|
|
SelTimTimeout dc i4'0' ; timeout in tenths of seconds
|
|
SelTimPID dc i2'0' ; pid argument to call selwakeup with
|
|
SelTimExpired dc i2'0' ; set by the HB routine when she blows
|
|
ds 8*(NPROC-1) ; space for 31 more entries
|
|
END
|
|
|
|
|
|
getSelTimIndex START KERN2
|
|
getSelTimIndex name
|
|
using KernelStruct
|
|
lda >truepid
|
|
asl a
|
|
asl a
|
|
asl a
|
|
tax
|
|
rts
|
|
END
|
|
|
|
|
|
;KERNgetdtablesize START KERN2
|
|
; using KernelStruct
|
|
;
|
|
;pPtr equ 0
|
|
;fdPtr equ 4
|
|
;ret equ 8
|
|
;
|
|
; subroutine (4:errptr),10
|
|
;
|
|
; mv4 >procPtr,pPtr
|
|
; ldy #openFiles-CKernData
|
|
; lda [pPtr],y
|
|
; sta fdPtr
|
|
; ldy #(openFiles-CKernData-2)
|
|
; lda [pPtr],y
|
|
; sta fdPtr+2
|
|
;
|
|
; lda #0
|
|
; sta [errptr]
|
|
;
|
|
; ldy #FDTfdTableSize
|
|
; lda [fdPtr],y
|
|
; sta ret
|
|
; return 2:ret
|
|
; END
|
|
;
|
|
;STACK START ~_STACK
|
|
; KIND $12
|
|
; ds 1024
|
|
; END
|