mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-06-08 05:29:33 +00:00
1338 lines
21 KiB
NASM
1338 lines
21 KiB
NASM
|
* $Id: pty.asm,v 1.1 1998/02/02 08:19:40 taubert Exp $
|
||
|
****************************************************************
|
||
|
*
|
||
|
* Pseudo-TTY device drivers and line discipline
|
||
|
*
|
||
|
* Assumes 32 PTYs right now
|
||
|
*
|
||
|
****************************************************************
|
||
|
|
||
|
case on
|
||
|
mcopy m/pty.mac
|
||
|
copy inc/tty.inc
|
||
|
|
||
|
DebugNames gequ 1
|
||
|
ptyBufSize gequ 4096 !! MUST BE A POWER OF TWO !!
|
||
|
ptyDevStart gequ 6
|
||
|
|
||
|
IncBusy gequ $E10064
|
||
|
DecBusy gequ $E10068
|
||
|
|
||
|
ptyDPindex START KERN2
|
||
|
dc i2'ptyRecSize*0'
|
||
|
dc i2'ptyRecSize*0'
|
||
|
dc i2'ptyRecSize*1'
|
||
|
dc i2'ptyRecSize*1'
|
||
|
dc i2'ptyRecSize*2'
|
||
|
dc i2'ptyRecSize*2'
|
||
|
dc i2'ptyRecSize*3'
|
||
|
dc i2'ptyRecSize*3'
|
||
|
dc i2'ptyRecSize*4'
|
||
|
dc i2'ptyRecSize*4'
|
||
|
dc i2'ptyRecSize*5'
|
||
|
dc i2'ptyRecSize*5'
|
||
|
dc i2'ptyRecSize*6'
|
||
|
dc i2'ptyRecSize*6'
|
||
|
dc i2'ptyRecSize*7'
|
||
|
dc i2'ptyRecSize*7'
|
||
|
dc i2'ptyRecSize*8'
|
||
|
dc i2'ptyRecSize*8'
|
||
|
dc i2'ptyRecSize*9'
|
||
|
dc i2'ptyRecSize*9'
|
||
|
dc i2'ptyRecSize*10'
|
||
|
dc i2'ptyRecSize*10'
|
||
|
dc i2'ptyRecSize*11'
|
||
|
dc i2'ptyRecSize*11'
|
||
|
dc i2'ptyRecSize*12'
|
||
|
dc i2'ptyRecSize*12'
|
||
|
dc i2'ptyRecSize*13'
|
||
|
dc i2'ptyRecSize*14'
|
||
|
dc i2'ptyRecSize*14'
|
||
|
dc i2'ptyRecSize*15'
|
||
|
dc i2'ptyRecSize*15'
|
||
|
dc i2'ptyRecSize*16'
|
||
|
dc i2'ptyRecSize*16'
|
||
|
dc i2'ptyRecSize*17'
|
||
|
dc i2'ptyRecSize*17'
|
||
|
dc i2'ptyRecSize*18'
|
||
|
dc i2'ptyRecSize*18'
|
||
|
dc i2'ptyRecSize*19'
|
||
|
dc i2'ptyRecSize*19'
|
||
|
dc i2'ptyRecSize*20'
|
||
|
dc i2'ptyRecSize*20'
|
||
|
dc i2'ptyRecSize*21'
|
||
|
dc i2'ptyRecSize*21'
|
||
|
dc i2'ptyRecSize*22'
|
||
|
dc i2'ptyRecSize*22'
|
||
|
dc i2'ptyRecSize*23'
|
||
|
dc i2'ptyRecSize*23'
|
||
|
dc i2'ptyRecSize*24'
|
||
|
dc i2'ptyRecSize*24'
|
||
|
dc i2'ptyRecSize*25'
|
||
|
dc i2'ptyRecSize*25'
|
||
|
dc i2'ptyRecSize*26'
|
||
|
dc i2'ptyRecSize*26'
|
||
|
dc i2'ptyRecSize*27'
|
||
|
dc i2'ptyRecSize*27'
|
||
|
dc i2'ptyRecSize*28'
|
||
|
dc i2'ptyRecSize*28'
|
||
|
dc i2'ptyRecSize*29'
|
||
|
dc i2'ptyRecSize*29'
|
||
|
dc i2'ptyRecSize*30'
|
||
|
dc i2'ptyRecSize*30'
|
||
|
dc i2'ptyRecSize*31'
|
||
|
dc i2'ptyRecSize*31'
|
||
|
END
|
||
|
|
||
|
PTY_signalIO START KERN2
|
||
|
txa ; put devNum in acc
|
||
|
txy
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
tya
|
||
|
eor 6,s
|
||
|
bit #1
|
||
|
bne Bcheck4select
|
||
|
|
||
|
; check for select here.
|
||
|
|
||
|
Acheck4select anop
|
||
|
lda >PTYSlaveHeader+t_select_proc
|
||
|
cmp #$FFFF
|
||
|
beq Adone
|
||
|
|
||
|
* someone is selecting on us, so call selwakeup with the process ID
|
||
|
* and our collision flag
|
||
|
pha
|
||
|
|
||
|
lda >PTYSlaveHeader+privFlags
|
||
|
and #TS_RCOLL
|
||
|
pha
|
||
|
jsl >PTYSlaveHeader+t_selwakeup
|
||
|
lda >PTYSlaveHeader+privFlags
|
||
|
and #TS_RCOLL.EOR.$FFFF
|
||
|
sta >PTYSlaveHeader+privFlags
|
||
|
lda #$FFFF
|
||
|
sta >PTYSlaveHeader+t_select_proc
|
||
|
|
||
|
Adone anop
|
||
|
pei (p_bufAptr+2)
|
||
|
pei (p_bufAptr)
|
||
|
jsl k_wakeup
|
||
|
bra byebye
|
||
|
|
||
|
; check for select here.
|
||
|
|
||
|
Bcheck4select anop
|
||
|
lda >PTYMastHeader+t_select_proc
|
||
|
cmp #$FFFF
|
||
|
beq Bdone
|
||
|
|
||
|
* someone is selecting on us, so call selwakeup with the process ID
|
||
|
* and our collision flag
|
||
|
pha
|
||
|
|
||
|
lda >PTYMastHeader+privFlags
|
||
|
and #TS_RCOLL
|
||
|
pha
|
||
|
jsl >PTYMastHeader+t_selwakeup
|
||
|
lda >PTYMastHeader+privFlags
|
||
|
and #TS_RCOLL.EOR.$FFFF
|
||
|
sta >PTYMastHeader+privFlags
|
||
|
lda #$FFFF
|
||
|
sta >PTYMastHeader+t_select_proc
|
||
|
|
||
|
Bdone anop
|
||
|
pei (p_bufBptr+2)
|
||
|
pei (p_bufBptr)
|
||
|
jsl k_wakeup
|
||
|
|
||
|
byebye anop
|
||
|
pld
|
||
|
lda 2,s
|
||
|
sta 4,s
|
||
|
lda 1,s
|
||
|
sta 3,s
|
||
|
pla
|
||
|
rtl
|
||
|
END
|
||
|
|
||
|
A_sizeq START KERN2
|
||
|
_A_sizeq name
|
||
|
|
||
|
txa ; put devNum in acc
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
lda #4095
|
||
|
sec
|
||
|
sbc p_Aleft
|
||
|
pld
|
||
|
rtl
|
||
|
END
|
||
|
|
||
|
A_leftq START KERN2
|
||
|
_A_leftq name
|
||
|
|
||
|
txa ; put devNum in acc
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
lda p_Aleft
|
||
|
pld
|
||
|
rtl
|
||
|
END
|
||
|
|
||
|
B_sizeq START KERN2
|
||
|
_B_sizeq name
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
lda #4095
|
||
|
sec
|
||
|
sbc p_Bleft
|
||
|
pld
|
||
|
rtl
|
||
|
END
|
||
|
|
||
|
B_leftq START KERN2
|
||
|
_B_leftq name
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
lda p_Bleft
|
||
|
pld
|
||
|
rtl
|
||
|
END
|
||
|
|
||
|
pty_mutex START KERN2
|
||
|
_pty_mutex name
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
pei (p_sem)
|
||
|
jsl >IncBusy
|
||
|
jsl asmWait
|
||
|
pld
|
||
|
rtl
|
||
|
END
|
||
|
|
||
|
pty_demutex START KERN2
|
||
|
_pty_demutex name
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
pei (p_sem)
|
||
|
jsl asmSignal
|
||
|
jsl >DecBusy
|
||
|
pld
|
||
|
rtl
|
||
|
END
|
||
|
*
|
||
|
* ENQUEUE/DEQUEUE routines
|
||
|
*
|
||
|
|
||
|
A_deq START KERN2
|
||
|
using KernelStruct
|
||
|
_a_deq name
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
|
||
|
again ldx p_Aleft
|
||
|
cpx #4095
|
||
|
beq dowait
|
||
|
ldy p_Atail
|
||
|
lda [p_bufAptr],y
|
||
|
and #$00FF
|
||
|
pha
|
||
|
tya
|
||
|
inc a
|
||
|
and #ptyBufSize-1 ; wrap it around
|
||
|
sta p_Atail
|
||
|
inx
|
||
|
stx p_Aleft
|
||
|
pla
|
||
|
pld
|
||
|
rtl
|
||
|
dowait anop
|
||
|
* free access semaphore
|
||
|
pei (p_sem)
|
||
|
jsl asmSignal
|
||
|
|
||
|
* wait on vector of buffer A; the line discipline code calls a low level
|
||
|
* signal_operation(read|write) to indicate what happened. That way we
|
||
|
* don't vec_signal each and every time a character goes out.
|
||
|
lda >truepid
|
||
|
pha
|
||
|
pea 0
|
||
|
pei (p_bufAptr+2)
|
||
|
pei (p_bufAptr)
|
||
|
jsl k_sleep
|
||
|
|
||
|
pei (p_sem)
|
||
|
jsl asmWait
|
||
|
bra again
|
||
|
END
|
||
|
|
||
|
B_deq START KERN2
|
||
|
using KernelStruct
|
||
|
_b_deq name
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
|
||
|
again ldx p_Bleft
|
||
|
cpx #4095
|
||
|
beq dowait
|
||
|
ldy p_Btail
|
||
|
lda [p_bufBptr],y
|
||
|
and #$00FF
|
||
|
pha
|
||
|
tya
|
||
|
inc a
|
||
|
and #ptyBufSize-1 ; wrap it around
|
||
|
sta p_Btail
|
||
|
inx
|
||
|
stx p_Bleft
|
||
|
pla
|
||
|
pld
|
||
|
rtl
|
||
|
dowait anop
|
||
|
pei (p_sem)
|
||
|
jsl asmSignal
|
||
|
lda >truepid
|
||
|
pha
|
||
|
pea 0
|
||
|
pei (p_bufBptr+2)
|
||
|
pei (p_bufBptr)
|
||
|
jsl k_sleep
|
||
|
pei (p_sem)
|
||
|
jsl asmWait
|
||
|
bra again
|
||
|
END
|
||
|
|
||
|
A_enq START KERN2
|
||
|
using KernelStruct
|
||
|
char equ 6
|
||
|
_a_enq name
|
||
|
|
||
|
* subroutine (2:char),2
|
||
|
* 'char' is 6,7,S
|
||
|
* RTL address is 3,4,5,S
|
||
|
* dp is 1,2,S
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd ; 1,s
|
||
|
tcd
|
||
|
|
||
|
again ldx p_Aleft
|
||
|
cpx #0
|
||
|
beq dowait
|
||
|
ldy p_Ahead
|
||
|
short m
|
||
|
lda char,S
|
||
|
sta [p_bufAptr],y
|
||
|
long m
|
||
|
tya
|
||
|
inc a
|
||
|
and #ptyBufSize-1 ; wrap it around
|
||
|
sta p_Ahead
|
||
|
dex
|
||
|
stx p_Aleft
|
||
|
pld
|
||
|
lda 2,s
|
||
|
sta 4,s
|
||
|
lda 1,s
|
||
|
sta 3,s
|
||
|
pla
|
||
|
rtl
|
||
|
|
||
|
dowait anop
|
||
|
* free access semaphore
|
||
|
pei (p_sem)
|
||
|
jsl asmSignal
|
||
|
|
||
|
* wait on vector of buffer A; the line discipline code calls a low level
|
||
|
* signal_operation(read|write) to indicate what happened. That way we
|
||
|
* don't vec_signal each and every time a character goes out.
|
||
|
lda >truepid
|
||
|
pha
|
||
|
pea 0
|
||
|
pei (p_bufAptr+2)
|
||
|
pei (p_bufAptr)
|
||
|
jsl k_sleep
|
||
|
|
||
|
pei (p_sem)
|
||
|
jsl asmWait
|
||
|
bra again
|
||
|
END
|
||
|
|
||
|
B_enq START KERN2
|
||
|
using KernelStruct
|
||
|
char equ 6
|
||
|
_b_enq name
|
||
|
* subroutine (2:char),2
|
||
|
|
||
|
txa
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
phd
|
||
|
tcd
|
||
|
|
||
|
again ldx p_Bleft
|
||
|
cpx #0
|
||
|
beq dowait
|
||
|
ldy p_Bhead
|
||
|
short m
|
||
|
lda char,S
|
||
|
sta [p_bufBptr],y
|
||
|
long m
|
||
|
tya
|
||
|
inc a
|
||
|
and #ptyBufSize-1 ; wrap it around
|
||
|
sta p_Bhead
|
||
|
dex
|
||
|
stx p_Bleft
|
||
|
pld
|
||
|
lda 2,s
|
||
|
sta 4,s
|
||
|
lda 1,s
|
||
|
sta 3,s
|
||
|
pla
|
||
|
rtl
|
||
|
|
||
|
dowait anop
|
||
|
* free access semaphore
|
||
|
pei (p_sem)
|
||
|
jsl asmSignal
|
||
|
|
||
|
lda >truepid
|
||
|
pha
|
||
|
pea 0 ; wakeup priority
|
||
|
pei (p_bufBptr+2)
|
||
|
pei (p_bufBptr)
|
||
|
jsl k_sleep
|
||
|
pei (p_sem)
|
||
|
jsl asmWait
|
||
|
bra again
|
||
|
END
|
||
|
|
||
|
* 24 bytes each. 24*32 = 768 pages of direct page space
|
||
|
* Steal this from the kernel.
|
||
|
|
||
|
PTYSlaveHeader START KERN2
|
||
|
ds t_open
|
||
|
* Line Discipline entry points
|
||
|
dc i4'PTYOpen'
|
||
|
dc i4'PTYClose'
|
||
|
dc i4'PTYIOCTL'
|
||
|
dc i4'ttread'
|
||
|
dc i4'ttwrite'
|
||
|
dc i4'pty_mutex'
|
||
|
dc i4'pty_demutex'
|
||
|
dc i4'B_enq'
|
||
|
dc i4'A_enq'
|
||
|
dc i4'B_deq'
|
||
|
dc i4'A_deq'
|
||
|
dc i4'A_sizeq'
|
||
|
dc i4'B_sizeq'
|
||
|
ds t_signalIO-editInd
|
||
|
dc i4'PTY_signalIO'
|
||
|
dc i2'$FFFF' ; noone selecting
|
||
|
dc i4'PTYS_select'
|
||
|
jmp >selwakeup
|
||
|
|
||
|
END
|
||
|
|
||
|
PTYMastHeader START KERN2
|
||
|
ds t_open
|
||
|
* Line Discipline entry points
|
||
|
dc i4'PTYOpen'
|
||
|
dc i4'PTYClose'
|
||
|
dc i4'PTYIOCTL'
|
||
|
dc i4'ttread'
|
||
|
dc i4'ptwrite'
|
||
|
dc i4'pty_mutex'
|
||
|
dc i4'pty_demutex'
|
||
|
dc i4'A_enq'
|
||
|
dc i4'B_enq'
|
||
|
dc i4'A_deq'
|
||
|
dc i4'B_deq'
|
||
|
dc i4'B_sizeq'
|
||
|
dc i4'A_sizeq'
|
||
|
ds t_signalIO-editInd
|
||
|
dc i4'PTY_signalIO'
|
||
|
dc i2'$FFFF' ; noone selecting
|
||
|
dc i4'PTYM_select'
|
||
|
jmp >selwakeup
|
||
|
|
||
|
END
|
||
|
|
||
|
initPTY START KERN2
|
||
|
ptyhand equ 0
|
||
|
ptyptr equ 4
|
||
|
_init_pty name
|
||
|
|
||
|
subroutine (0:foo),8
|
||
|
|
||
|
pha
|
||
|
pha
|
||
|
pea 0
|
||
|
pea ptyRecSize*32
|
||
|
lda >~USER_ID
|
||
|
pha
|
||
|
pea $C015
|
||
|
pea 0
|
||
|
pea 0
|
||
|
_NewHandle
|
||
|
pl4 ptyhand
|
||
|
|
||
|
lda [ptyhand]
|
||
|
sta >PTYDP
|
||
|
sta ptyptr
|
||
|
ldy #2
|
||
|
lda [ptyhand],y
|
||
|
sta >PTYDP+2
|
||
|
sta ptyptr+2
|
||
|
|
||
|
ldy #0
|
||
|
next lda #0
|
||
|
sta [ptyptr],y
|
||
|
iny
|
||
|
iny
|
||
|
sta [ptyptr],y
|
||
|
tya
|
||
|
clc
|
||
|
adc #ptyRecSize-2
|
||
|
tay
|
||
|
cmp #ptyRecSize*32
|
||
|
bcc next
|
||
|
|
||
|
return
|
||
|
END
|
||
|
|
||
|
* If the devNum is even, this is the master we're opening.
|
||
|
* If the devNum is odd, this is the slave we're opening.
|
||
|
|
||
|
PTYOpen START KERN2
|
||
|
using KernelStruct
|
||
|
ptyDpPtr equ 0
|
||
|
bufA equ 4
|
||
|
bufB equ 8
|
||
|
dTermioPtr equ 12
|
||
|
result equ 16
|
||
|
masterTerm equ 18
|
||
|
slaveTerm equ 22
|
||
|
subroutine (2:devNum),26
|
||
|
|
||
|
stz result
|
||
|
lda devNum
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
sta ptyDpPtr
|
||
|
stz ptyDpPtr+2
|
||
|
ldy #p_bufAptr
|
||
|
lda [ptyDpPtr],y
|
||
|
ldy #p_bufAptr+2
|
||
|
ora [ptyDpPtr],y
|
||
|
beq notInit ; this pty was not yet initialized
|
||
|
|
||
|
* at this point, the pty structures are already allocated and initialized.
|
||
|
* So, we need to signal the process that opened the other end of the pty
|
||
|
* to continue.
|
||
|
; pei (ptyDpPtr+2)
|
||
|
; pei (ptyDpPtr)
|
||
|
; jsl k_wakeup
|
||
|
jmp finish
|
||
|
notInit anop
|
||
|
|
||
|
; if we're trying to open the Slave w/o the master being open, fail
|
||
|
; with an error $50.
|
||
|
lda devNum
|
||
|
bit #1
|
||
|
beq isMaster
|
||
|
lda #$50
|
||
|
sta result
|
||
|
jmp finish
|
||
|
; allocate master's and slave's TTY headers via malloc
|
||
|
|
||
|
isMaster ph4 #ttyRecSize
|
||
|
jsl malloc
|
||
|
stx masterTerm+2
|
||
|
sta masterTerm
|
||
|
ph4 #ttyRecSize
|
||
|
jsl malloc
|
||
|
stx slaveTerm+2
|
||
|
sta slaveTerm
|
||
|
|
||
|
; initialize them by copying data from the static copies here in KERN2
|
||
|
|
||
|
lda #ptwrite ; install custom write routine
|
||
|
ldy #t_write ; for the master
|
||
|
sta PTYMastHeader,y
|
||
|
lda #^ptwrite
|
||
|
sta PTYMastHeader+2,y
|
||
|
|
||
|
ph4 #ttyRecSize
|
||
|
ph4 #PTYMastHeader
|
||
|
pei (masterTerm+2)
|
||
|
pei (masterTerm)
|
||
|
jsl memcpy
|
||
|
ph4 #ttyRecSize
|
||
|
ph4 #PTYSlaveHeader
|
||
|
pei (slaveTerm+2)
|
||
|
pei (slaveTerm)
|
||
|
jsl memcpy
|
||
|
|
||
|
lda devNum
|
||
|
and #$FFFE ; clear the low bit
|
||
|
asl a
|
||
|
asl a
|
||
|
tax
|
||
|
lda masterTerm+2 ; init the header pointers
|
||
|
sta >DeviceBlock+2,x
|
||
|
lda masterTerm
|
||
|
sta >DeviceBlock,x
|
||
|
lda slaveTerm+2
|
||
|
sta >DeviceBlock+6,x
|
||
|
lda slaveTerm
|
||
|
sta >DeviceBlock+4,x
|
||
|
|
||
|
pea 0
|
||
|
pea ptyBufSize
|
||
|
jsl malloc ; alloc buffer A
|
||
|
stx bufA+2
|
||
|
sta bufA
|
||
|
ldy #p_bufAptr
|
||
|
sta [ptyDpPtr],y
|
||
|
txa
|
||
|
ldy #p_bufAptr+2
|
||
|
sta [ptyDpPtr],y
|
||
|
pea 0
|
||
|
pea ptyBufSize
|
||
|
jsl malloc ; alloc buffer B
|
||
|
stx bufB+2
|
||
|
sta bufB
|
||
|
ldy #p_bufBptr
|
||
|
sta [ptyDpPtr],y
|
||
|
txa
|
||
|
ldy #p_bufBptr+2
|
||
|
sta [ptyDpPtr],y
|
||
|
|
||
|
* For purposes of interrupt chars & whatnot, both devices use the slave's
|
||
|
* ioctl structure, so initialize that.
|
||
|
* Initialize default values for terminal settings
|
||
|
ldy #sg_flags
|
||
|
lda #CRMOD+ECHO
|
||
|
sta [slaveTerm],y
|
||
|
short m
|
||
|
lda #0
|
||
|
sta [slaveTerm] ; ispeed
|
||
|
ldy #sg_ospeed
|
||
|
sta [slaveTerm],y ; ospeed
|
||
|
ldy #t_intrc
|
||
|
lda #'C'-64
|
||
|
sta [slaveTerm],y ; t_intrc
|
||
|
ldy #t_suspc
|
||
|
lda #'Z'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_quitc
|
||
|
lda #'\'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_startc
|
||
|
lda #'Q'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_stopc
|
||
|
lda #'S'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_eofc
|
||
|
lda #'D'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_brkc
|
||
|
lda #-1
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_dsuspc
|
||
|
lda #'Y'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #t_rprntc
|
||
|
lda #'R'-64
|
||
|
sta [slaveTerm],y
|
||
|
ldy #sg_erase
|
||
|
lda #$7F
|
||
|
sta [slaveTerm],y
|
||
|
long m
|
||
|
|
||
|
ldy #privFlags
|
||
|
lda #0 ; master can only be opened once
|
||
|
sta [slaveTerm],y
|
||
|
lda #EXCL
|
||
|
sta [masterTerm],y
|
||
|
|
||
|
ldy #local
|
||
|
lda #LCRTERA+LCTLECH
|
||
|
sta [slaveTerm],y
|
||
|
|
||
|
ldy #ws_row
|
||
|
lda #24
|
||
|
sta [slaveTerm],y
|
||
|
ldy #ws_col
|
||
|
lda #80
|
||
|
sta [slaveTerm],y
|
||
|
ldy #ws_xpixel
|
||
|
lda #0
|
||
|
sta [slaveTerm],y
|
||
|
ldy #ws_ypixel
|
||
|
sta [slaveTerm],y
|
||
|
|
||
|
lda #RAW
|
||
|
ldy #sg_flags
|
||
|
sta [masterTerm],y
|
||
|
|
||
|
pea 1
|
||
|
jsl asmSemNew
|
||
|
ldy #p_sem
|
||
|
sta [ptyDpPtr],y
|
||
|
|
||
|
lda #0
|
||
|
ldy #p_Ahead
|
||
|
sta [ptyDpPtr],y
|
||
|
ldy #p_Atail
|
||
|
sta [ptyDpPtr],y
|
||
|
ldy #p_Bhead
|
||
|
sta [ptyDpPtr],y
|
||
|
ldy #p_Btail
|
||
|
sta [ptyDpPtr],y
|
||
|
lda #ptyBufSize-1
|
||
|
ldy #p_Aleft
|
||
|
sta [ptyDpPtr],y
|
||
|
ldy #p_Bleft
|
||
|
sta [ptyDpPtr],y
|
||
|
|
||
|
; jsl decBusy
|
||
|
; lda >truepid
|
||
|
; pha
|
||
|
; pea 0
|
||
|
; pei (ptyDpPtr+2)
|
||
|
; pei (ptyDpPtr)
|
||
|
; jsl k_sleep
|
||
|
; jsl incBusy
|
||
|
|
||
|
finish anop
|
||
|
return 2:result
|
||
|
PTYDP ENTRY
|
||
|
dc i4'0'
|
||
|
END
|
||
|
|
||
|
PTYClose START KERN2
|
||
|
ptyDpPtr equ 0
|
||
|
otherHeader equ 4
|
||
|
devIndex equ 8
|
||
|
|
||
|
subroutine (2:devNum),10
|
||
|
|
||
|
lda devNum
|
||
|
sec
|
||
|
sbc #ptyDevStart
|
||
|
asl a ; calculate index into table
|
||
|
tax
|
||
|
lda >ptyDPindex,x
|
||
|
clc ; clc$$
|
||
|
adc >PTYDP
|
||
|
sta ptyDpPtr
|
||
|
stz ptyDpPtr+2
|
||
|
|
||
|
* only deallocate PTY information if the both ends of the PTY have been
|
||
|
* closed (see if the other PTY has been closed)
|
||
|
|
||
|
lda devNum
|
||
|
asl a
|
||
|
asl a
|
||
|
sta devIndex
|
||
|
lda devNum
|
||
|
eor #1 ; the OTHER one, dork
|
||
|
asl a
|
||
|
asl a
|
||
|
tax
|
||
|
lda #^PTYMastHeader
|
||
|
cmp >DeviceBlock+2,x
|
||
|
bne notClosed
|
||
|
|
||
|
lda >DeviceBlock,x
|
||
|
cmp #PTYMastHeader
|
||
|
beq isClosed
|
||
|
cmp #PTYSlaveHeader
|
||
|
beq isClosed
|
||
|
|
||
|
* If we're closing the master, send a SIGHUP to the PTYs process group
|
||
|
* If the slave was already closed, we assume there are no processes
|
||
|
* to kill and thus we don't fall through
|
||
|
|
||
|
notClosed lda devNum
|
||
|
ror a
|
||
|
bcs notMaster
|
||
|
|
||
|
pea 1 ; push signal number
|
||
|
lda devNum
|
||
|
inc a
|
||
|
pha ; signal the TTY end
|
||
|
jsl PTYSlaveHeader+t_sendSignal
|
||
|
notMaster bra goaway
|
||
|
|
||
|
* Deallocate the pty buffers - only executed when both ends are
|
||
|
* closed
|
||
|
isClosed ldy #p_bufAptr+2
|
||
|
lda [ptyDpPtr],y
|
||
|
pha
|
||
|
ldy #p_bufAptr
|
||
|
lda [ptyDpPtr],y
|
||
|
pha
|
||
|
jsl nfree
|
||
|
ldy #p_bufBptr+2
|
||
|
lda [ptyDpPtr],y
|
||
|
pha
|
||
|
ldy #p_bufBptr
|
||
|
lda [ptyDpPtr],y
|
||
|
pha
|
||
|
jsl nfree
|
||
|
|
||
|
lda #0
|
||
|
ldy #p_bufAptr ; zero out this info
|
||
|
sta [ptyDpPtr],y
|
||
|
ldy #p_bufAptr+2
|
||
|
sta [ptyDpPtr],y
|
||
|
|
||
|
goaway anop
|
||
|
* Deallocate the PTYs header
|
||
|
ldx devIndex
|
||
|
lda >DeviceBlock+2,x
|
||
|
pha
|
||
|
lda >DeviceBlock,x
|
||
|
pha
|
||
|
jsl free
|
||
|
|
||
|
* Reset the tty header pointer so we know we're closed
|
||
|
ldx devIndex
|
||
|
lda devNum
|
||
|
ror a
|
||
|
bcs resetSlave
|
||
|
lda #^PTYMastHeader
|
||
|
sta >DeviceBlock+2,x
|
||
|
lda #PTYMastHeader
|
||
|
sta >DeviceBlock,x
|
||
|
bra byebye
|
||
|
resetSlave lda #^PTYSlaveHeader
|
||
|
sta >DeviceBlock+2,x
|
||
|
lda #PTYSlaveHeader
|
||
|
sta >DeviceBlock,x
|
||
|
|
||
|
byebye return
|
||
|
END
|
||
|
|
||
|
PTYIOCTL START KERN2
|
||
|
using KernelStruct
|
||
|
retval equ 0
|
||
|
subroutine (4:tioc,4:dataPtr,2:devNum),2
|
||
|
|
||
|
lda tioc
|
||
|
and #$FF00
|
||
|
xba
|
||
|
cmp #'f'
|
||
|
beq chkfile
|
||
|
cmp #'t'
|
||
|
beq tioctl
|
||
|
err lda #-1
|
||
|
sta retval
|
||
|
jmp goaway
|
||
|
chkfile lda tioc
|
||
|
and #$7F
|
||
|
cmp #127
|
||
|
bne err
|
||
|
|
||
|
ldx devNum
|
||
|
jsl pty_mutex
|
||
|
lda devNum
|
||
|
tax
|
||
|
bit #%00000001 ; ARGH! IMMEDIATE! IMMEDIATE!
|
||
|
beq isMaster
|
||
|
jsl A_sizeq
|
||
|
bra notMaster
|
||
|
isMaster jsl B_sizeq
|
||
|
notMaster anop
|
||
|
sta [dataPtr]
|
||
|
ldx devNum
|
||
|
jsl pty_demutex
|
||
|
stz retval
|
||
|
jmp goaway
|
||
|
tioctl anop
|
||
|
lda tioc
|
||
|
and #$7F
|
||
|
cmp #21
|
||
|
bcc okay2
|
||
|
eor #$7F
|
||
|
cmp #26
|
||
|
bcc okay1
|
||
|
jmp invalid
|
||
|
okay1 anop
|
||
|
asl a
|
||
|
asl a
|
||
|
inc a
|
||
|
inc a
|
||
|
tax
|
||
|
jmp (tNTable,x)
|
||
|
okay2 anop
|
||
|
asl a
|
||
|
asl a
|
||
|
inc a
|
||
|
inc a
|
||
|
tax
|
||
|
jmp (tPTable,x)
|
||
|
goaway return 2:retval
|
||
|
|
||
|
tPTable anop
|
||
|
dc i2'0',a2'TIOCGETD'
|
||
|
dc i2'1',a2'TIOCSETD'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'8',a2'TIOCGETP'
|
||
|
dc i2'9',a2'TIOCSETP'
|
||
|
dc i2'10',a2'TIOCSETN'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'16',a2'TIOCFLUSH'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'19',a2'invalid'
|
||
|
dc i2'20',a2'invalid'
|
||
|
|
||
|
tNTable anop
|
||
|
dc i2'127',a2'invalid'
|
||
|
dc i2'126',a2'invalid'
|
||
|
dc i2'125',a2'invalid'
|
||
|
dc i2'124',a2'invalid'
|
||
|
|
||
|
dc i2'123',a2'invalid'
|
||
|
dc i2'122',a2'invalid'
|
||
|
dc i2'121',a2'invalid'
|
||
|
dc i2'120',a2'invalid'
|
||
|
|
||
|
dc i2'119',a2'invalid'
|
||
|
dc i2'118',a2'invalid'
|
||
|
dc i2'117',a2'invalid'
|
||
|
dc i2'116',a2'invalid'
|
||
|
dc i2'115',a2'TIOCOUTQ'
|
||
|
dc i2'114',a2'TIOCSTI'
|
||
|
dc i2'113',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'111',a2'TIOCSTOP'
|
||
|
dc i2'110',a2'TIOCSTART'
|
||
|
|
||
|
dc i2'109',a2'invalid'
|
||
|
dc i2'108',a2'invalid'
|
||
|
dc i2'107',a2'invalid'
|
||
|
dc i2'106',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'104',a2'invalid'
|
||
|
dc i2'103',a2'invalid'
|
||
|
|
||
|
invalid lda #-1
|
||
|
sta retval
|
||
|
jmp goaway
|
||
|
*****************************************************
|
||
|
|
||
|
dc i2'0',a2'TIOCGETD'
|
||
|
dc i2'1',a2'TIOCSETD'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'-1',a2'invalid'
|
||
|
dc i2'8',a2'TIOCGETP'
|
||
|
dc i2'9',a2'TIOCSETP'
|
||
|
dc i2'10',a2'TIOCSETN'
|
||
|
|
||
|
TIOCGETD anop
|
||
|
TIOCSETD anop
|
||
|
TIOCSETN anop
|
||
|
TIOCSETP anop
|
||
|
TIOCGETP stz retval
|
||
|
jmp goaway
|
||
|
|
||
|
TIOCOUTQ anop
|
||
|
TIOCSTOP anop
|
||
|
TIOCSTART anop
|
||
|
TIOCFLUSH anop
|
||
|
* simulate terminal input (this code is borrowed from INOUT.ASM/OurADB
|
||
|
TIOCSTI anop
|
||
|
stz retval
|
||
|
jmp goaway
|
||
|
|
||
|
END
|
||
|
|
||
|
ptwrite START KERN2
|
||
|
ttyPtr equ 0
|
||
|
c equ 4
|
||
|
xfer equ 6
|
||
|
retval equ 8
|
||
|
slavePtr equ 10
|
||
|
|
||
|
subroutine (2:length,4:buf,2:devNum),14
|
||
|
|
||
|
lda devNum
|
||
|
jsr fetchDevPtr
|
||
|
sta ttyPtr
|
||
|
stx ttyPtr+2
|
||
|
|
||
|
lda devNum
|
||
|
and #%11111110 clear lo bit
|
||
|
inc a
|
||
|
jsr fetchDevPtr
|
||
|
sta slavePtr
|
||
|
stx slavePtr+2
|
||
|
|
||
|
lda length
|
||
|
sta xfer
|
||
|
stz retval
|
||
|
ldx devNum
|
||
|
ldy #mutex
|
||
|
jsl ttyDispatch
|
||
|
|
||
|
px1 anop we were in raw or cbreak mode
|
||
|
|
||
|
lda length
|
||
|
jeq pw1
|
||
|
dea
|
||
|
sta length
|
||
|
lda [buf]
|
||
|
and #$00FF
|
||
|
sta c
|
||
|
inc buf
|
||
|
bne px2
|
||
|
inc buf+2
|
||
|
px2 anop
|
||
|
; check for special characters going to the slave, and process appropriately
|
||
|
|
||
|
lda c
|
||
|
jsr checkPtyIntr
|
||
|
bcs px1 ; don't write char if it was a signal
|
||
|
|
||
|
pei (c)
|
||
|
ldx devNum
|
||
|
ldy #out_enq
|
||
|
jsl ttyDispatch
|
||
|
jmp px1
|
||
|
pw1 ldx devNum
|
||
|
ldy #demutex
|
||
|
jsl ttyDispatch
|
||
|
|
||
|
pea 0 ; 0 means 'write occurred'
|
||
|
ldx devNum
|
||
|
ldy #t_signalIO
|
||
|
jsl ttyDispatch
|
||
|
|
||
|
return 4:xfer
|
||
|
|
||
|
checkPtyIntr anop
|
||
|
|
||
|
php
|
||
|
long ai
|
||
|
and #$7f
|
||
|
pha
|
||
|
short m
|
||
|
|
||
|
ldy #sg_flags
|
||
|
lda [slavePtr],y
|
||
|
bit #RAW ; RAW mode?
|
||
|
beq x9 ; yep, no character checking
|
||
|
brl notty
|
||
|
x9 ldy #t_quitc
|
||
|
lda [slavePtr],y
|
||
|
cmp #-1
|
||
|
beq x0
|
||
|
cmp 1,s
|
||
|
beq gotQQ
|
||
|
x0 ldy #t_suspc
|
||
|
lda [slavePtr],y
|
||
|
cmp #-1
|
||
|
beq x1
|
||
|
cmp 1,s
|
||
|
beq gotZ
|
||
|
x1 ldy #t_intrc
|
||
|
lda [slavePtr],y
|
||
|
cmp #-1
|
||
|
beq x2
|
||
|
cmp 1,s
|
||
|
beq gotC
|
||
|
bra notty
|
||
|
x2 anop
|
||
|
; lda >OutStopped
|
||
|
; bne x3
|
||
|
; ldy #t_stopc
|
||
|
; lda [slavePtr],y
|
||
|
; cmp #-1
|
||
|
; beq x3
|
||
|
; cmp 1,s
|
||
|
; beq gotS
|
||
|
x3 anop
|
||
|
; ldy #t_startc
|
||
|
; lda [slavePtr],y
|
||
|
; cmp #-1
|
||
|
; beq notty
|
||
|
; cmp 1,s
|
||
|
; beq gotQ
|
||
|
; bra notty
|
||
|
;gotS long m
|
||
|
; pla
|
||
|
; lda #1
|
||
|
; sta >OutStopped
|
||
|
; plp
|
||
|
; sec
|
||
|
; rts
|
||
|
;gotQ long m
|
||
|
; pla
|
||
|
; lda >OutStopped
|
||
|
; beq notQ
|
||
|
; lda #0
|
||
|
; sta >OutStopped
|
||
|
; plp
|
||
|
; sec
|
||
|
; rts
|
||
|
notQ anop ;oops!
|
||
|
plp
|
||
|
clc
|
||
|
rts
|
||
|
gotQQ long m
|
||
|
lda #3
|
||
|
bra gotSIG
|
||
|
gotZ long m
|
||
|
lda #18
|
||
|
bra gotSIG
|
||
|
gotC long m
|
||
|
lda #2
|
||
|
gotSIG anop
|
||
|
phx
|
||
|
phy
|
||
|
pha
|
||
|
|
||
|
pha ; push signal number
|
||
|
lda devNum
|
||
|
inc a ; push our device number
|
||
|
pha
|
||
|
jsl PTYSlaveHeader+t_sendSignal ; setup by InstallDriver
|
||
|
|
||
|
; flush internal editing buffers on interrupt character
|
||
|
lda #0
|
||
|
ldy #editInd
|
||
|
sta [slavePtr],y
|
||
|
ldy #editBegin
|
||
|
sta [slavePtr],y
|
||
|
ldy #st_flags
|
||
|
sta [slavePtr],y
|
||
|
|
||
|
pla ; prolly don't need to, but what
|
||
|
ply ; the hell...
|
||
|
plx
|
||
|
|
||
|
pla ; the character
|
||
|
plp ; ready? Let's go!
|
||
|
|
||
|
sec
|
||
|
rts
|
||
|
notty anop
|
||
|
long m
|
||
|
pla
|
||
|
plp
|
||
|
clc
|
||
|
rts
|
||
|
sigtosend dc i2'0'
|
||
|
END
|
||
|
|
||
|
; eeeeewwwww, just one t_select_proc for all the ptys?
|
||
|
; we should probably store that on a per-pty basis...
|
||
|
|
||
|
PTYS_select START KERN2
|
||
|
res equ 0
|
||
|
subroutine (2:ttyn,2:which,2:pid),2
|
||
|
|
||
|
lda #1
|
||
|
sta res
|
||
|
lda ttyn
|
||
|
tax ; *_sizeq needs devNum in X
|
||
|
lda which ; which I/O to check?
|
||
|
cmp #SEL_READ
|
||
|
bne trywrite
|
||
|
jsl A_sizeq ; # bytes in in q
|
||
|
cmp #0
|
||
|
bne done
|
||
|
|
||
|
willwait anop
|
||
|
* record that the process wants to do I/O
|
||
|
lda >PTYSlaveHeader+t_select_proc ; see if someone's here already
|
||
|
cmp #$FFFF ; nope
|
||
|
beq nocollision
|
||
|
cmp pid ; is it us?
|
||
|
beq nocollision
|
||
|
lda >PTYSlaveHeader+privFlags
|
||
|
ora #TS_RCOLL
|
||
|
sta >PTYSlaveHeader+privFlags
|
||
|
bra none
|
||
|
nocollision anop
|
||
|
lda pid ; set select_proc field to
|
||
|
sta >PTYSlaveHeader+t_select_proc ; current process ID
|
||
|
bra none
|
||
|
|
||
|
trywrite cmp #SEL_WRITE
|
||
|
bne doexcept
|
||
|
jsl B_leftq ; # bytes avail in out q
|
||
|
cmp #0
|
||
|
bne done
|
||
|
bra willwait
|
||
|
|
||
|
doexcept anop
|
||
|
; there are no exceptions on ptys - what about other side close?
|
||
|
none lda #0 ; no data, return 0
|
||
|
sta res
|
||
|
done anop
|
||
|
|
||
|
return 2:res
|
||
|
END
|
||
|
|
||
|
PTYM_select START KERN2
|
||
|
res equ 0
|
||
|
subroutine (2:ttyn,2:which,2:pid),2
|
||
|
|
||
|
lda #1
|
||
|
sta res
|
||
|
lda ttyn
|
||
|
tax ; *_sizeq needs devNum in X
|
||
|
lda which ; which I/O to check?
|
||
|
cmp #SEL_READ
|
||
|
bne trywrite
|
||
|
jsl B_sizeq ; # bytes in in q
|
||
|
cmp #0
|
||
|
bne done
|
||
|
|
||
|
willwait anop
|
||
|
* record that the process wants to do I/O
|
||
|
lda >PTYMastHeader+t_select_proc ; see if someone's here already
|
||
|
cmp #$FFFF ; nope
|
||
|
beq nocollision
|
||
|
cmp pid ; is it us?
|
||
|
beq nocollision
|
||
|
lda >PTYMastHeader+privFlags
|
||
|
ora #TS_RCOLL
|
||
|
sta >PTYMastHeader+privFlags
|
||
|
bra none
|
||
|
nocollision anop
|
||
|
lda pid ; set select_proc field to
|
||
|
sta >PTYMastHeader+t_select_proc ; current process ID
|
||
|
bra none
|
||
|
|
||
|
trywrite cmp #SEL_WRITE
|
||
|
bne doexcept
|
||
|
jsl A_leftq ; # bytes avail in out q
|
||
|
cmp #0
|
||
|
bne done
|
||
|
bra willwait
|
||
|
|
||
|
doexcept anop
|
||
|
; there are no exceptions on ptys - what about other side close?
|
||
|
none lda #0 ; no data, return 0
|
||
|
sta res
|
||
|
done anop
|
||
|
|
||
|
return 2:res
|
||
|
END
|