mirror of https://github.com/GnoConsortium/gno.git
2282 lines
37 KiB
NASM
2282 lines
37 KiB
NASM
* $Id: gsos.asm,v 1.1 1998/02/02 08:19:23 taubert Exp $
|
|
**************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
* Derek Taubert
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* GSOS.ASM
|
|
* By Tim Meekins
|
|
* and Jawaid Bazyar
|
|
* and Derek Taubert (modified socket stuff)
|
|
*
|
|
* This file contains routines for patching GS/OS to intercept Shell
|
|
* calls and do special things with certain GS/OS calls.
|
|
*
|
|
* taken over by JB on 6/18/91
|
|
* 10/29/91 - extensive modifications to better support the data structures
|
|
* of the fd (file descriptor) table
|
|
*
|
|
**************************************************************************
|
|
|
|
copy global.equates
|
|
mcopy m/gsos.mac
|
|
case on
|
|
copy inc/gsos.inc
|
|
copy inc/tty.inc
|
|
|
|
GSOStable START
|
|
dc a2'GNOStandard' ; $2001 Create
|
|
dc a2'GNOStandard' ; $2002 Destroy
|
|
dc a2'NotImpGS' ; $2003 OSShutDown
|
|
dc a2'GNOChangePath' ; $2004 ChangePath
|
|
dc a2'GNOStandard' ; $2005 SetFileInfo
|
|
dc a2'GNOStandard' ; $2006 GetFileInfo
|
|
dc a2'NotImpGS' ; $2007 JudgeName
|
|
dc a2'NotImpGS' ; $2008 Volume
|
|
|
|
dc a2'GNOSetPrefix' ; $2009 SetPrefix
|
|
dc a2'PGGetPrefix' ; $200A GetPrefix
|
|
dc a2'GNOStandard' ; $200B ClearBackupBit
|
|
dc a2'NotImpGS' ; $200C SetSysPrefs
|
|
dc a2'NotImpGS' ; $200D Null
|
|
dc a2'GNOExpandPath' ; $200E ExpandPath
|
|
dc a2'NotImpGS' ; $200F GetSysPrefs
|
|
dc a2'GNOOpen' ; $2010 Open
|
|
dc a2'GNONewLine' ; $2011 NewLine
|
|
dc a2'GNORdWr' ; $2012 Read
|
|
dc a2'GNORdWr' ; $2013 Write
|
|
dc a2'PGClose' ; $2014 Close
|
|
dc a2'GNORefCommon' ; $2015 Flush
|
|
dc a2'GNORefCommon' ; $2016 SetMark
|
|
dc a2'GNORefCommon' ; $2017 GetMark
|
|
dc a2'GNORefCommon' ; $2018 SetEOF
|
|
dc a2'GNORefCommon' ; $2019 GetEOF
|
|
dc a2'GNOSetLevel' ; $201A SetLevel
|
|
dc a2'GNOGetLevel' ; $201B GetLevel
|
|
dc a2'GNORefCommon' ; $201C GetDirEntry
|
|
dc a2'NotImpGS' ; $201D BeginSession
|
|
dc a2'NotImpGS' ; $201E EndSession
|
|
dc a2'NotImpGS' ; $201F SessionStatus
|
|
dc a2'GNOStandard' ; $2020 GetDevNumber
|
|
dc a2'NotImpGS' ; $2021
|
|
dc a2'NotImpGS' ; $2022
|
|
dc a2'NotImpGS' ; $2023
|
|
dc a2'NotImpGS' ; $2024 Format
|
|
dc a2'NotImpGS' ; $2025 EraseDisk
|
|
dc a2'NotImpGS' ; $2026 ResetCache
|
|
dc a2'GNOGetName' ; $2027 GetName
|
|
dc a2'NotImpGS' ; $2028 GetBootVol
|
|
dc a2'GNOQuit' ; $2029 Quit
|
|
dc a2'NotImpGS' ; $202A GetVersion
|
|
dc a2'NotImpGS' ; $202B GetFSTInfo
|
|
dc a2'NotImpGS' ; $202C DInfo
|
|
dc a2'NotImpGS' ; $202D DStatus
|
|
dc a2'NotImpGS' ; $202E DControl
|
|
dc a2'NotImpGS' ; $202F DRead
|
|
dc a2'NotImpGS' ; $2030 DWrite
|
|
dc a2'NotImpGS' ; $2031 BindInt
|
|
dc a2'NotImpGS' ; $2032 UnbindInt
|
|
dc a2'NotImpGS' ; $2033 FSTSpecific
|
|
dc a2'NotImpGS' ; $2034 AddNotifyProc
|
|
dc a2'NotImpGS' ; $2035 DelNotifyProc
|
|
dc a2'NotImpGS' ; $2036 DRename
|
|
dc a2'GNOGetStdRefNum' ; $2037 GetStdRefNum
|
|
dc a2'NotImpGS' ; $2038 GetRefNum
|
|
dc a2'GNOGetRefInfo' ; $2039 GetRefInfo
|
|
dc a2'NotImpGS' ; $203A SetStdRefNum
|
|
END
|
|
|
|
;
|
|
; Patch GS/OS
|
|
; This has been modified greatly to install itself through our special
|
|
; Permanent Init (PIF) file. This will allow us to do GSBug OS call traps
|
|
; properly
|
|
;
|
|
|
|
GSOSinfo DATA
|
|
storeHandle dc i4'0'
|
|
patchType dc i2'0' ; 0 = no gnobug, 1 = gnobug
|
|
gnobugPath str '*:system:system.setup:gnobug'
|
|
END
|
|
|
|
patchGSOS START
|
|
using GSOSinfo
|
|
handle equ 0
|
|
nextHandle equ 4
|
|
lookuid equ 8
|
|
;
|
|
location equ 0
|
|
attributes equ 4
|
|
userID equ 6
|
|
length equ 8
|
|
last equ 12
|
|
next equ 16
|
|
|
|
subroutine (0:foo),10
|
|
pha
|
|
ph4 #gnobugPath
|
|
_GetUserID
|
|
cmp #0
|
|
beq okay1
|
|
jmp reggalar
|
|
okay1 pla
|
|
sta lookuid
|
|
|
|
FindHandle #patchGSOS,handle
|
|
|
|
lb1 ldy #last
|
|
lda [handle],y
|
|
tax
|
|
iny2
|
|
ora [handle],y
|
|
beq lb1a
|
|
lda [handle],y
|
|
sta handle+2
|
|
stx handle
|
|
bra lb1
|
|
|
|
lb1a anop
|
|
lb2 lda handle
|
|
ora handle+2
|
|
jeq reggalar
|
|
ldy #next
|
|
lda [handle],y
|
|
sta nextHandle
|
|
iny2
|
|
lda [handle],y
|
|
sta nextHandle+2
|
|
ldy #userID
|
|
lda [handle],y
|
|
cmp lookuid
|
|
beq around1
|
|
jmp lb3
|
|
around1 anop
|
|
ldy #attributes
|
|
lda [handle],y
|
|
cmp #$C018 ; always, for PIF
|
|
beq around2
|
|
jmp lb3
|
|
|
|
lb3 mv4 nextHandle,handle
|
|
jmp lb2
|
|
|
|
around2 anop ; we've got the handle
|
|
lda [handle]
|
|
sta nextHandle
|
|
ldy #2
|
|
lda [handle],y
|
|
sta nextHandle+2
|
|
|
|
lda [nextHandle]
|
|
sta OldGSOS
|
|
lda [nextHandle],y
|
|
sta OldGSOS+2
|
|
iny2
|
|
lda [nextHandle],y
|
|
sta OldGSOSSt
|
|
iny2
|
|
lda [nextHandle],y
|
|
sta OldGSOSSt+2
|
|
|
|
lda #<OurGSOS
|
|
ldy #1
|
|
sta [nextHandle],y
|
|
lda #>OurGSOS
|
|
iny
|
|
sta [nextHandle],y
|
|
|
|
lda #<StackGSOS
|
|
ldy #5
|
|
sta [nextHandle],y
|
|
lda #>StackGSOS
|
|
iny
|
|
sta [nextHandle],y
|
|
mv4 nextHandle,storeHandle
|
|
lda #1
|
|
sta patchType
|
|
return
|
|
|
|
reggalar anop
|
|
pla
|
|
stz patchType
|
|
mv4 >$E100A8,OldGSOS
|
|
ld2 <OurGSOS,>$E100A8+1
|
|
ld2 >OurGSOS,>$E100A8+2
|
|
|
|
mv4 >$E100B0,OldGSOSSt
|
|
ld2 <StackGSOS,>$E100B0+1
|
|
ld2 >StackGSOS,>$E100B0+2
|
|
return
|
|
|
|
END
|
|
|
|
;
|
|
; UnPatch GS/OS
|
|
;
|
|
unpatchGSOS START
|
|
using GSOSinfo
|
|
patchPtr equ 0
|
|
subroutine (0:foo),4
|
|
|
|
lda patchType
|
|
beq oldType
|
|
mv4 storeHandle,patchPtr
|
|
|
|
ldy #2
|
|
lda OldGSOS
|
|
sta [patchPtr]
|
|
lda OldGSOS+2
|
|
sta [patchPtr],y
|
|
iny2
|
|
lda OldGSOSSt
|
|
sta [patchPtr],y
|
|
iny2
|
|
lda OldGSOSSt+2
|
|
sta [patchPtr],y
|
|
return
|
|
oldType anop
|
|
mv4 OldGSOS,>$E100A8
|
|
mv4 OldGSOSSt,>$E100B0
|
|
return
|
|
END
|
|
|
|
OurGSOS START
|
|
php ; these six bytes are where
|
|
phb ; the call info (cmdNum/pBlockPtr)
|
|
long ai
|
|
phy ; get stored
|
|
pha ;
|
|
pha ; p/b reg contents
|
|
pha ; y reg contents
|
|
pha ; a reg contents
|
|
lda 11,s ; copy p,b, and y further down
|
|
sta 5,s ; so we can pull them off
|
|
lda 9,s ; before the call
|
|
sta 3,s
|
|
short a
|
|
lda 15,s ; set data bank to pBlock's
|
|
pha ; bank (to use short-based)
|
|
plb ; stack indirect adressing
|
|
long a
|
|
ldy #1
|
|
lda (13,s),y ; cmdNum
|
|
sta 7,s
|
|
|
|
ldy #5 ; copy high word of pBlock
|
|
lda (13,s),y ; pointer
|
|
sta 11,s
|
|
|
|
ldy #3 ; low word of pBlock pointer
|
|
lda (13,s),y
|
|
sta 9,s
|
|
lda 13,s
|
|
clc
|
|
adc #6 ; set rtl address to point after
|
|
sta 13,s ; the call information
|
|
|
|
pla
|
|
ply
|
|
plb
|
|
plp
|
|
jsl StackGSOS
|
|
rtl
|
|
END
|
|
|
|
StackGSOS START
|
|
using KernelStruct
|
|
|
|
phb ;Save the data bank
|
|
php ;Save the proc status
|
|
long ai
|
|
phx
|
|
phy
|
|
phd
|
|
phk
|
|
plb
|
|
cld
|
|
ldx curProcInd
|
|
sta exitCode,x
|
|
lda gsosDebug
|
|
and #1
|
|
beq noDebug
|
|
ErrWriteChar #'('
|
|
ErrWriteChar #'$'
|
|
lda 12,s
|
|
jsr writeacc
|
|
lda gsosDebug
|
|
and #32
|
|
beq noDebug
|
|
ErrWriteChar #','
|
|
ErrWriteChar #'$'
|
|
lda 16,s
|
|
and #$00FF
|
|
jsr writeacc
|
|
lda 14,s
|
|
jsr writeacc
|
|
noDebug anop
|
|
* check here to see if it's one of the call groups we handle
|
|
lda 12,s
|
|
and #$FF00
|
|
cmp #0 ; P16?
|
|
beq ok
|
|
cmp #$2000 ; GS/OS?
|
|
beq ok
|
|
cmp #$0100 ; ORCA?
|
|
beq ok
|
|
pld ; nope, go to the real GS/OS entry
|
|
ply ; point
|
|
plx
|
|
plp
|
|
plb
|
|
* real stack entry point
|
|
OldGSOSSt ENTRY
|
|
dc i4'0'
|
|
brk 0
|
|
* real inline entry point
|
|
OldGSOS ENTRY
|
|
dc i4'0'
|
|
brk 0
|
|
|
|
ok anop
|
|
tsc
|
|
sec
|
|
sbc #$1F
|
|
tcd
|
|
dec a
|
|
tcs
|
|
lda 45
|
|
sta pBlock
|
|
lda 47
|
|
sta pBlock+2
|
|
lda 43
|
|
sta cmdNum
|
|
lda 41
|
|
sta 47
|
|
lda 40
|
|
sta 46
|
|
lda 38
|
|
sta 44
|
|
lda 36
|
|
sta 42
|
|
lda 34
|
|
sta 40
|
|
lda 32
|
|
sta 38
|
|
|
|
jsl incBusy
|
|
lda cmdNum
|
|
and #$FF00 ;Is it a shell command?
|
|
cmp #$0100
|
|
beq shellit
|
|
cmp #$0000 ; P16?
|
|
beq P16it
|
|
jmp GSOSit ; must be GS/OS then!
|
|
|
|
P16it anop
|
|
|
|
; create pointer to process entry for the current process
|
|
|
|
lda curProcInd
|
|
clc
|
|
adc #|CKernData
|
|
sta procEnt
|
|
lda #^CKernData
|
|
sta procEnt+2
|
|
lda cmdNum
|
|
and #$00FF ; mask off (nothing!)
|
|
cmp #$32+1
|
|
bcc rangeOK
|
|
jmp NotImpP16
|
|
rangeOK anop
|
|
asl a
|
|
tax
|
|
jmp (P16table-2,x)
|
|
|
|
GSOSit anop
|
|
; create pointer to process entry for the current process
|
|
|
|
lda curProcInd
|
|
clc
|
|
adc #|CKernData
|
|
sta procEnt
|
|
lda #^CKernData
|
|
sta procEnt+2
|
|
|
|
lda cmdNum
|
|
and #$00FF ; mask off $2000
|
|
cmp #$3A+1
|
|
bcc range
|
|
jmp NotImpGS
|
|
range anop
|
|
asl a
|
|
tax
|
|
jmp (GSOStable-2,x)
|
|
|
|
shellit anop
|
|
lda cmdNum
|
|
and #$40
|
|
bne orca2
|
|
|
|
lda #0
|
|
sta pCount
|
|
bra chkcmd
|
|
orca2 anop
|
|
lda [pBlock]
|
|
sta pCount
|
|
lda pBlock
|
|
clc
|
|
adc #2
|
|
sta pBlock
|
|
lda pBlock+2
|
|
adc #0
|
|
sta pBlock+2
|
|
|
|
chkcmd anop
|
|
lda cmdNum
|
|
and #$3F ;Strip entry type 2 [don't ask]
|
|
cmp #$20 ; new calls
|
|
bcs BadCommand
|
|
|
|
asl a
|
|
tax
|
|
jmp (ShellCallTbl-2,x)
|
|
|
|
|
|
; | p pstat from before call
|
|
; | acch
|
|
; | accl
|
|
; | p pstat containing cznv result of cmp #1
|
|
|
|
;
|
|
; Not a valid command
|
|
;
|
|
|
|
BadCommand anop
|
|
lda #1
|
|
; [6/29/91] removed all this duplicated code [jb]
|
|
;
|
|
; Return from a GSOS call
|
|
;
|
|
GSOSReturn ENTRY
|
|
ShellReturn ENTRY
|
|
|
|
sta $1E+6 ; neat trick coming up
|
|
tsc
|
|
clc
|
|
adc #$1E+6 ; so we can pull the result
|
|
tcs
|
|
; pla
|
|
|
|
jsl decBusy
|
|
|
|
; pha
|
|
lda >gsosDebug
|
|
and #1
|
|
beq noDebug1
|
|
lda >gsosDebug
|
|
and #4
|
|
beq noDebug2
|
|
lda 1,s
|
|
beq noDebug2 ; if no error, no message
|
|
ErrWriteChar #15
|
|
ErrWriteChar #'#' ; error codes get a # sign
|
|
ldy #1
|
|
lda 1,s ; the error number (incognito)
|
|
jsr writeacc ;
|
|
ErrWriteChar #14
|
|
noDebug2 anop
|
|
ErrWritechar #')'
|
|
ErrWriteChar #13
|
|
noDebug1 anop
|
|
pla
|
|
|
|
pld
|
|
ply
|
|
plx
|
|
; insert from here
|
|
pha
|
|
cmp #1
|
|
lda 1,s
|
|
php
|
|
short m
|
|
lda 1,s
|
|
and #%11000011
|
|
sta 1,s
|
|
lda 4,s
|
|
and #%00111100
|
|
ora 1,s
|
|
sta 4,s
|
|
pla
|
|
long m
|
|
lda 3,s
|
|
xba
|
|
sta 3,s ; swap two bytes around
|
|
pla
|
|
; to here
|
|
plb ; modifies the fucking P!
|
|
plp
|
|
rtl
|
|
|
|
* Amazing how I've finally managed to merge all this code! Augh!
|
|
|
|
NotImpGS ENTRY
|
|
NotImpP16 ENTRY
|
|
NotImp ENTRY
|
|
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
* New GetPrefix code
|
|
* instead of a handle, we'll use a small malloc'd record as follows:
|
|
|
|
PGGetPrefix START
|
|
using KernelStruct
|
|
pfxRec equ 10
|
|
pfxString equ 14
|
|
|
|
ldy #prefixh-CKernData ; copy the handle of the prefix rec
|
|
lda [procEnt],y ; out of the process table
|
|
sta pfxRec ; we dereference it later
|
|
iny2
|
|
lda [procEnt],y
|
|
sta pfxRec+2
|
|
|
|
lda cmdNum
|
|
and #$FF00
|
|
beq ok2
|
|
|
|
lda [pBlock]
|
|
cmp #2
|
|
beq ok1
|
|
lda #$04
|
|
jmp GSOSReturn
|
|
|
|
ok2 lda [pBlock]
|
|
bra lookuppfx
|
|
|
|
ok1 ldy #2
|
|
lda [pBlock],y
|
|
|
|
lookuppfx anop
|
|
inc a
|
|
asl a
|
|
asl a
|
|
tay
|
|
iny2
|
|
lda [pfxRec],y
|
|
sta pfxString+2
|
|
pha
|
|
dey2
|
|
lda [pfxRec],y
|
|
sta pfxString
|
|
pha
|
|
|
|
ora 3,s
|
|
bne notnull
|
|
pla
|
|
pla
|
|
ph4 #nullGSOS
|
|
ld4 nullGSOS,pfxString
|
|
|
|
notnull lda cmdNum
|
|
and #$FF00
|
|
beq p16vers
|
|
|
|
ldy #6
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #4
|
|
lda [pBlock],y
|
|
pha
|
|
jsl copygs2res
|
|
jmp GSOSReturn
|
|
|
|
* for P16 calls, we need to condition the returned pathname somewhat
|
|
|
|
p16vers anop
|
|
lda [pfxString]
|
|
beq patherror ; length is zero, avoid major memtrashing
|
|
tay
|
|
iny
|
|
short m
|
|
|
|
* Scan the prefix for a slash; if one is present, return a null pathname
|
|
* because after processing ':'s to '/'s the pathname would be totally
|
|
* incorrect.
|
|
|
|
slashloop lda [pfxString],y
|
|
cmp #'/'
|
|
beq patherror
|
|
dey
|
|
cpy #2
|
|
bcs slashloop
|
|
long m
|
|
ldy #4
|
|
lda [pBlock],y
|
|
sta pfxString+2
|
|
pha
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta pfxString
|
|
pha
|
|
jsl copygs2p
|
|
lda [pfxString]
|
|
and #$00FF
|
|
tay
|
|
short m
|
|
fixloop lda [pfxString],y
|
|
cmp #':'
|
|
bne nofix
|
|
lda #'/'
|
|
sta [pfxString],y
|
|
nofix dey
|
|
bne fixloop
|
|
long m
|
|
|
|
lda #0
|
|
jmp GSOSReturn
|
|
patherror long m
|
|
pla ; remove input params
|
|
pla ; store a zero as length,
|
|
ldy #4 ; and don't return an error
|
|
lda [pBlock],y
|
|
sta pfxString+2
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta pfxString
|
|
lda #0
|
|
short m
|
|
sta [pfxString]
|
|
long m
|
|
jmp GSOSReturn
|
|
nullGSOS dc i2'0'
|
|
END
|
|
|
|
GNOSetPrefix START
|
|
using KernelStruct
|
|
pfxRec equ 10
|
|
pfxInd equ 14
|
|
|
|
pfxpCount equ 16
|
|
pfxpfxNum equ 18
|
|
pfxpathname equ 20
|
|
newPath equ 24
|
|
|
|
ldy #prefixh-CKernData ; copy the handle of the prefix rec
|
|
lda [procEnt],y ; out of the process table
|
|
sta pfxRec ; we dereference it later
|
|
iny2
|
|
lda [procEnt],y
|
|
sta pfxRec+2
|
|
|
|
lda [pBlock]
|
|
cmp #2
|
|
beq ok1
|
|
lda #$04
|
|
jmp GSOSReturn
|
|
|
|
ok1 anop
|
|
pea 1 ; don't do the named pfx expansion
|
|
ldy #2 ; push the prefix number
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #6 ; push the path to be expanded
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #4
|
|
lda [pBlock],y
|
|
pha
|
|
jsl gno_ExpandPath ; call our C routine
|
|
sta pfxpathname
|
|
stx pfxpathname+2 ; store result
|
|
cpx #$FFFF ; did an error occur?
|
|
bne noerr
|
|
jmp GSOSReturn
|
|
|
|
noerr anop
|
|
ldy #2
|
|
lda [pBlock],y
|
|
inc a
|
|
asl a
|
|
asl a
|
|
|
|
sta pfxInd
|
|
tay
|
|
iny2
|
|
lda [pfxRec],y
|
|
pha
|
|
dey2
|
|
lda [pfxRec],y
|
|
pha
|
|
ora 3,s
|
|
bne dodispose
|
|
pla
|
|
pla
|
|
bra nodispose
|
|
dodispose jsl ~NDISPOSE
|
|
|
|
nodispose lda [pfxpathname]
|
|
inc a
|
|
inc a
|
|
inc a
|
|
pea 0
|
|
pha
|
|
jsl ~NEW
|
|
sta newPath
|
|
stx newPath+2
|
|
|
|
ldy pfxInd ; copy the addr of the new mem into the
|
|
sta [pfxRec],y ; prefix record
|
|
iny2
|
|
txa
|
|
sta [pfxRec],y
|
|
|
|
ph4 pfxpathname ; copy the string
|
|
ph4 newPath
|
|
jsl copygsstr
|
|
lda [newPath]
|
|
inc a
|
|
tay
|
|
lda [newPath],y ; check to see if there's a
|
|
and #$00FF
|
|
cmp #':' ; separator at the end of the
|
|
beq alright
|
|
short m ; prefix, and if not, then
|
|
lda #':'
|
|
iny ; add one. Note that we alloced
|
|
sta [newPath],y ; one extra byte for this possibility
|
|
long m
|
|
dey
|
|
tya
|
|
sta [newPath]
|
|
alright lda #0
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
GNOChangePath START
|
|
temp1 equ 10
|
|
temp2 equ 14
|
|
oldpathres equ 18
|
|
newmem equ 22
|
|
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta temp1
|
|
iny2
|
|
lda [pBlock],y
|
|
sta temp1+2
|
|
iny2
|
|
lda [pBlock],y
|
|
sta temp2
|
|
iny2
|
|
lda [pBlock],y
|
|
sta temp2+2
|
|
|
|
pea 0
|
|
pea 0
|
|
pushlong temp1
|
|
jsl gno_ExpandPath
|
|
cpx #$FFFF
|
|
bne noerr
|
|
jmp GSOSReturn
|
|
noerr phx
|
|
pha ; push source addr for copy
|
|
stx oldpathres+2
|
|
sta oldpathres
|
|
|
|
pea $0000
|
|
lda [oldpathres]
|
|
clc
|
|
adc #2
|
|
pha
|
|
jsl ~NEW
|
|
stx newmem+2
|
|
sta newmem
|
|
|
|
phx
|
|
pha ; push dest address
|
|
|
|
ldy #2
|
|
sta [pBlock],y
|
|
iny2
|
|
txa
|
|
sta [pBlock],y
|
|
dey2
|
|
ora [pBlock],y
|
|
beq memoryErr
|
|
|
|
jsl copygsstr ; copy the expanded path to temp
|
|
|
|
pea 0
|
|
pushword #0
|
|
pushlong temp2
|
|
jsl gno_ExpandPath
|
|
cpx #$FFFF
|
|
bne noerr1
|
|
ph4 newmem
|
|
jsl ~NDISPOSE
|
|
jmp GSOSReturn
|
|
noerr1 anop
|
|
ldy #6
|
|
sta [pBlock],y
|
|
iny2
|
|
txa
|
|
sta [pBlock],y
|
|
|
|
movelong pBlock,pb
|
|
lda cmdNum
|
|
sta cn
|
|
|
|
jsl OldGSOS
|
|
cn dc i2'0' ; set to same call # we are
|
|
pb dc i4'0'
|
|
pha ; return any error we get
|
|
pushlong newmem
|
|
jsl ~NDISPOSE
|
|
|
|
interdict anop
|
|
ldy #2
|
|
lda temp1
|
|
sta [pBlock],y
|
|
iny2
|
|
lda temp1+2
|
|
sta [pBlock],y
|
|
iny2
|
|
lda temp2
|
|
sta [pBlock],y
|
|
iny2
|
|
lda temp2+2
|
|
sta [pBlock],y
|
|
pla
|
|
jmp GSOSReturn
|
|
memoryErr pla
|
|
pla
|
|
pea $0054
|
|
bra interdict
|
|
END
|
|
|
|
GNOStandard START
|
|
oldpath equ 10
|
|
exppath equ 14
|
|
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta oldpath
|
|
iny2
|
|
lda [pBlock],y
|
|
sta oldpath+2
|
|
|
|
pea 0
|
|
pushword #0
|
|
pushlong oldpath
|
|
jsl gno_ExpandPath
|
|
cpx #$FFFF
|
|
bne noerr
|
|
jmp GSOSReturn
|
|
noerr anop
|
|
sta exppath
|
|
stx exppath+2
|
|
ph4 exppath
|
|
jsl findDevice
|
|
cmp #$FFFF
|
|
beq notdevice
|
|
lda #$0058 ; not a block device!
|
|
bra goaway
|
|
|
|
notdevice anop
|
|
ldy #2
|
|
lda exppath
|
|
sta [pBlock],y
|
|
ldy #4
|
|
lda exppath+2
|
|
sta [pBlock],y
|
|
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
|
|
pha ; return any error we get
|
|
|
|
lda cmdNum
|
|
cmp #$2002
|
|
beq docff
|
|
cmp #$2005
|
|
bne noff
|
|
docff anop
|
|
ldx oldpath+2
|
|
lda oldpath
|
|
jsr checkFF
|
|
|
|
noff anop
|
|
ldy #2
|
|
lda oldpath
|
|
sta [pBlock],y
|
|
ldy #4
|
|
lda oldpath+2
|
|
sta [pBlock],y
|
|
pla
|
|
goaway jmp GSOSReturn
|
|
END
|
|
|
|
checkFF START
|
|
using KernelStruct
|
|
|
|
tay
|
|
|
|
lda gsosDebug ; don't print the path twice
|
|
pha
|
|
stz gsosDebug
|
|
|
|
pea 1
|
|
pea 0
|
|
phx ; pathname pointer
|
|
phy
|
|
jsl gno_ExpandPath ; expand it again, but this time
|
|
phx ; pointer to expanded pathname
|
|
pha
|
|
jsl FindFF
|
|
phx ; pointer to ff entry, if any
|
|
pha
|
|
ora 3,s ; null pointer means not in FF
|
|
beq noFF
|
|
jsl DeleteFF
|
|
|
|
goaway pla
|
|
sta gsosDebug
|
|
|
|
rts
|
|
noFF pla
|
|
pla
|
|
bra goaway
|
|
END
|
|
|
|
PcheckFF START
|
|
using KernelStruct
|
|
|
|
tay
|
|
|
|
lda gsosDebug ; don't print the path twice
|
|
pha
|
|
stz gsosDebug
|
|
|
|
pea 1
|
|
pea 0
|
|
phx ; pathname pointer
|
|
phy
|
|
jsl p16_ExpandPath ; expand it again, but this time
|
|
phx ; pointer to expanded pathname
|
|
pha
|
|
jsl FindFF
|
|
phx ; pointer to ff entry, if any
|
|
pha
|
|
ora 3,s ; null pointer means not in FF
|
|
beq noFF
|
|
jsl DeleteFF
|
|
|
|
goaway pla
|
|
sta gsosDebug
|
|
|
|
rts
|
|
noFF pla
|
|
pla
|
|
bra goaway
|
|
END
|
|
|
|
|
|
GNOOpen START
|
|
using KernelStruct
|
|
temp1 equ 10
|
|
files equ 14
|
|
fd equ 18
|
|
fdPtr equ 20
|
|
ttyn equ 24
|
|
|
|
* Save the old pathname so we can restore before we exit
|
|
|
|
ldy #4
|
|
lda [pBlock],y
|
|
sta temp1
|
|
iny2
|
|
lda [pBlock],y
|
|
sta temp1+2
|
|
|
|
ldy #openFiles-CKernData ; copy the handle of the prefix rec
|
|
lda [procEnt],y ; out of the process table
|
|
sta files ; we dereference it later
|
|
iny2
|
|
lda [procEnt],y
|
|
sta files+2
|
|
pea 0
|
|
pushword #0
|
|
pushlong temp1
|
|
jsl gno_ExpandPath
|
|
cpx #$FFFF
|
|
bne noerr
|
|
jmp GSOSReturn
|
|
noerr anop
|
|
phx
|
|
pha
|
|
phx
|
|
pha
|
|
jsl findDevice
|
|
cmp #$FFFF
|
|
jne openTTY
|
|
|
|
pla
|
|
plx
|
|
ldy #4 ; forgetting this is B A D (baaaad)
|
|
sta [pBlock],y
|
|
txa
|
|
iny2
|
|
sta [pBlock],y
|
|
movelong pBlock,pb
|
|
lda cmdNum
|
|
sta cn
|
|
|
|
ldy #FDTLevel ; open the file with the proper
|
|
lda [files],y ; GS/OS level
|
|
sta dolevel+2
|
|
ldy #FDTLevelMode
|
|
lda [files],y
|
|
sta dolevel+4
|
|
ph4 #dolevel
|
|
pea $201A ; SetLevelGS
|
|
jsl OldGSOSSt
|
|
|
|
jsl OldGSOS
|
|
cn dc i2'0' ; set to same call # we are
|
|
pb dc i4'0'
|
|
pha
|
|
cmp #0
|
|
jne error
|
|
|
|
; alloc a process file entry ONLY if GS/OS opened the file okay
|
|
|
|
lda [files] ; inc the number of open files,
|
|
inc a ; allocFD does not do this
|
|
sta [files]
|
|
|
|
pea 0 ; push the (dp) address of
|
|
tdc ; our local 'fd'
|
|
clc
|
|
adc #fd
|
|
pha
|
|
jsl allocFD
|
|
sta fdPtr
|
|
stx fdPtr+2
|
|
|
|
ldy #openFiles-CKernData
|
|
lda [procEnt],y
|
|
sta files
|
|
iny2
|
|
lda [procEnt],y
|
|
sta files+2
|
|
|
|
ldy #2
|
|
lda [pBlock],y
|
|
pha
|
|
pea FDgsos
|
|
jsl AddRefnum ; add to our tracking table
|
|
|
|
ldy #2 ; refNum returned by open
|
|
lda [pBlock],y
|
|
ldy #FDrefNum
|
|
sta [fdPtr],y ; and store the new refnum in the list
|
|
|
|
lda fd ; retreive the fd number and
|
|
ldy #2 ; return it in the pBlock
|
|
sta [pBlock],y
|
|
ldy #FDTLevel
|
|
lda [files],y
|
|
ldy #FDTLevelMode ; handle internal levels
|
|
ora [files],y
|
|
ldy #FDrefLevel
|
|
sta [fdPtr],y ; store file level with refnum
|
|
|
|
lda #0
|
|
sta 1,s ; no error! trick the stack
|
|
error anop
|
|
|
|
ldx temp1+2
|
|
lda temp1
|
|
jsr checkFF
|
|
|
|
ldy #4
|
|
lda temp1
|
|
sta [pBlock],y
|
|
iny2
|
|
lda temp1+2
|
|
sta [pBlock],y
|
|
pla
|
|
jmp GSOSReturn
|
|
* this should be common between P16/GSOS
|
|
openTTY anop
|
|
inc a
|
|
sta ttyn
|
|
pla
|
|
pla ; remove junk
|
|
|
|
pei (ttyn)
|
|
pea FDtty ; we're looking for this type
|
|
jsl FindRefnum
|
|
sta fdPtr
|
|
stx fdPtr+2 ; if fdptr==NULL, then there are
|
|
ora fdPtr+2 ; no references to this TTY
|
|
bne notfirst
|
|
|
|
* create a reference to this TTY
|
|
pei (ttyn)
|
|
pea FDtty
|
|
jsl AddRefnum
|
|
|
|
* since this is the first open on this TTY, reassign this process' controlling
|
|
* tty to this terminal. Also, make sure the terminal's process group is
|
|
* 0 (but not the process'- this allows the real controlling terminal to
|
|
* signal the process)
|
|
|
|
ldx curProcInd
|
|
lda ttyn
|
|
dec a
|
|
sta ttyID,x
|
|
lda ttyn
|
|
dec a
|
|
asl a
|
|
tax
|
|
stz ttyStruct,x
|
|
|
|
* here, call the Init routine in the Device Driver
|
|
lda ttyn
|
|
dec a ; 0-n device number
|
|
pha
|
|
ldy #t_open
|
|
jsl LineDiscDispatch
|
|
cmp #0
|
|
bne iserr ; open failed!
|
|
bra part2
|
|
notfirst anop
|
|
* should check here for exclusive access bit. If set, then the
|
|
* open call will fail (before we change any counts)
|
|
lda ttyn
|
|
jsl checkExclTTY
|
|
cpy #0
|
|
beq not_excl
|
|
lda #$50
|
|
bra iserr99 ; do NOT DecRefNum - we never inc'd it
|
|
iserr pha
|
|
pei (ttyn)
|
|
pea FDtty
|
|
jsl DecRefnum clean up after ourselves
|
|
pla
|
|
iserr99 jmp GSOSReturn ; the file is already open!
|
|
|
|
not_excl pei (ttyn)
|
|
pea FDtty
|
|
jsl IncRefnum ; tell 'em we're here to party!
|
|
|
|
part2 anop ; no errors-
|
|
pea 0
|
|
tdc
|
|
clc
|
|
adc #fd
|
|
pha ; push address of 'fd' (dp)
|
|
jsl allocFD
|
|
sta fdPtr
|
|
stx fdPtr+2
|
|
ora fdPtr+2
|
|
bne noerror9
|
|
|
|
lda #$42
|
|
bra iserr ; exit with error & cleanup
|
|
|
|
noerror9 anop
|
|
; re-dereference files since allocFD can modify it
|
|
ldy #openFiles-CKernData ; copy the handle of the prefix rec
|
|
lda [procEnt],y ; out of the process table
|
|
sta files ; we dereference it later
|
|
iny2
|
|
lda [procEnt],y
|
|
sta files+2
|
|
|
|
ldy #FDrefNum
|
|
lda ttyn
|
|
sta [fdPtr],y ; store device number
|
|
ldy #FDrefType
|
|
lda #FDtty
|
|
sta [fdPtr],y ; and file descriptor type
|
|
ldy #FDTLevel
|
|
lda [files],y ; and the file level
|
|
ldy #FDrefLevel
|
|
sta [fdPtr],y
|
|
lda #0
|
|
ldy #FDrefFlags ; no flags for TTYs yet!
|
|
sta [fdPtr],y
|
|
ldy #FDNLenableMask ; make sure newline mode is off
|
|
sta [fdPtr],y
|
|
|
|
ldy #FDTCount
|
|
lda [files],y
|
|
inc a
|
|
sta [files],y
|
|
|
|
lda fd ; retreive the fd number and
|
|
ldy #2 ; return it in the pBlock
|
|
sta [pBlock],y
|
|
lda [pBlock]
|
|
cmp #5
|
|
bcc ttybyebye
|
|
ldy #8
|
|
lda [pBlock],y
|
|
bne storeAccess
|
|
lda #3
|
|
storeAccess ldy #12
|
|
sta [pBlock],y
|
|
|
|
ttybyebye lda #0
|
|
jmp GSOSReturn
|
|
|
|
dolevel dc i2'2'
|
|
dc i2'0'
|
|
dc i2'0'
|
|
END
|
|
|
|
GNOSetLevel START
|
|
using KernelStruct
|
|
files equ 10
|
|
|
|
ldy #openFiles-CKernData ; copy the handle of the prefix rec
|
|
lda [procEnt],y ; out of the process table
|
|
sta files ; we dereference it later
|
|
iny2
|
|
lda [procEnt],y
|
|
sta files+2
|
|
lda [pBlock]
|
|
cmp #1
|
|
beq okay
|
|
cmp #2
|
|
beq okay1
|
|
lda #$04
|
|
bra error
|
|
okay anop
|
|
pea $8000 ; default to 'user' mode
|
|
bra okay2
|
|
okay1 anop
|
|
ldy #4 ; use the mode they passed us
|
|
lda [pBlock],y
|
|
and #$8000
|
|
pha
|
|
|
|
okay2 lda 1,s
|
|
bit #$8000
|
|
beq okay3
|
|
ldy #2
|
|
lda [pBlock],y
|
|
bit #$8000
|
|
beq okay3
|
|
pla
|
|
lda #$59
|
|
jmp GSOSReturn
|
|
|
|
okay3 ldy #2
|
|
lda [pBlock],y
|
|
ldy #FDTLevel
|
|
sta [files],y
|
|
pla
|
|
ldy #2 ; calculate the real file level
|
|
eor [pBlock],y
|
|
and #$8000
|
|
ldy #FDTLevelMode
|
|
sta [files],y
|
|
|
|
lda #0
|
|
error jmp GSOSReturn
|
|
END
|
|
|
|
GNOGetLevel START
|
|
using KernelStruct
|
|
files equ 10
|
|
|
|
ldy #openFiles-CKernData ; copy the handle of the prefix rec
|
|
lda [procEnt],y ; out of the process table
|
|
sta files ; we dereference it later
|
|
iny2
|
|
lda [procEnt],y
|
|
sta files+2
|
|
lda [pBlock]
|
|
cmp #1
|
|
beq okay
|
|
cmp #2
|
|
beq okay1
|
|
lda #$04
|
|
bra error
|
|
okay anop
|
|
pea $8000
|
|
bra okay2
|
|
okay1 anop
|
|
ldy #4
|
|
lda [pBlock],y ; levelmode is an input
|
|
and #$8000
|
|
pha
|
|
okay2 ldy #FDTLevel
|
|
lda [files],y
|
|
ldy #FDTLevelMode
|
|
ora [files],y
|
|
eor 1,s
|
|
ldy #2
|
|
sta [pBlock],y
|
|
pla
|
|
lda #0
|
|
error jmp GSOSReturn
|
|
END
|
|
|
|
GNOExpandPath START ; not to be confused with gno_EP
|
|
gep_flags equ 10
|
|
outPath equ 12
|
|
pathName equ 16
|
|
in_ind equ 20
|
|
out_ind equ 22
|
|
|
|
lda #0
|
|
sta gep_flags
|
|
lda [pBlock]
|
|
cmp #2
|
|
bcs okay
|
|
lda #4
|
|
jmp GSOSReturn
|
|
okay anop
|
|
beq okay1
|
|
ldy #$0A
|
|
lda [pBlock],y
|
|
sta gep_flags
|
|
okay1 anop
|
|
ldy #6
|
|
lda [pBlock],y
|
|
sta outPath
|
|
iny2
|
|
lda [pBlock],y
|
|
sta outPath+2
|
|
|
|
pea 1
|
|
pea $0000 ; prefix 0
|
|
ldy #4 ; push the old pathname ptr
|
|
lda [pBlock],y
|
|
pha
|
|
dey
|
|
dey
|
|
lda [pBlock],y ; on the stack and call C expandpath
|
|
pha
|
|
jsl gno_ExpandPath ; ha!
|
|
cpx #$FFFF
|
|
bne noerr
|
|
jmp GSOSReturn
|
|
noerr anop
|
|
sta pathName
|
|
stx pathName+2
|
|
ldy #6
|
|
lda [pBlock],y
|
|
sta outPath
|
|
iny2
|
|
lda [pBlock],y
|
|
sta outPath+2
|
|
|
|
lda [pathName]
|
|
clc
|
|
adc #4
|
|
cmp [outPath]
|
|
beq okay2
|
|
bcc okay2
|
|
ldy #2
|
|
sta [outPath],y
|
|
lda #$4F
|
|
jmp GSOSReturn
|
|
okay2 anop
|
|
|
|
lda [pathName]
|
|
ldy #2
|
|
sta [outPath],y
|
|
tax ; count down with X reg
|
|
beq noCopy
|
|
sty in_ind
|
|
lda #4
|
|
sta out_ind
|
|
|
|
short m
|
|
loop anop
|
|
ldy in_ind
|
|
lda [pathName],y
|
|
bit gep_flags+1 ; hi bit into 'N' preg bit
|
|
bpl noupper
|
|
cmp #'a'
|
|
bcc noupper
|
|
cmp #'z'+1
|
|
bcs noupper
|
|
sec
|
|
sbc #'a'-'A'
|
|
noupper anop
|
|
ldy out_ind
|
|
sta [outPath],y
|
|
long m
|
|
inc in_ind
|
|
inc out_ind
|
|
short m
|
|
dex
|
|
bne loop
|
|
|
|
noCopy anop
|
|
long m
|
|
lda #0
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
GNOQuit START
|
|
using KernelStruct
|
|
ldx curProcInd
|
|
lda flags,x
|
|
ora #%00001000 ; FL_NORMTERM
|
|
sta flags,x
|
|
lda [pBlock]
|
|
cmp #2
|
|
bcs doFlags
|
|
pea 0
|
|
bra noFlags
|
|
doFlags ldy #6
|
|
lda [pBlock],y
|
|
pha
|
|
noFlags lda [pBlock]
|
|
cmp #1
|
|
bcs doPname
|
|
pea 0
|
|
pea 0
|
|
bra noPname
|
|
doPname ldy #4
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #2
|
|
lda [pBlock],y
|
|
pha
|
|
ora 3,s
|
|
beq noPname
|
|
jsl gs2cstr
|
|
phx
|
|
pha ; push the coverted pathname
|
|
noPname anop
|
|
jsl CommonQuit
|
|
jmp GSOSReturn ; only returns on error
|
|
END
|
|
|
|
* Flush 2015 +2
|
|
* GetDirEntry 201C +2
|
|
* GetEOF 2019 +2 tty,pipe
|
|
* GetMark 2017 +2 tty,pipe
|
|
* GetRefInfo 2039 +2
|
|
* SetEOF 2018 +2 tty,pipe
|
|
* SetMark 2016 +2 tty,pipe
|
|
|
|
getFDptr START
|
|
using KernelStruct
|
|
files equ 0
|
|
|
|
subroutine (2:rn),4
|
|
lda rn
|
|
cmp #32 ; max # of open files
|
|
bcs invalidRN
|
|
|
|
ldx curProcInd
|
|
lda openFiles,x
|
|
sta files
|
|
lda openFiles+2,x
|
|
sta files+2
|
|
lda rn
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
sec
|
|
sbc #FDsize-FDTTable
|
|
clc
|
|
adc files
|
|
sta files
|
|
lda files+2
|
|
adc #0
|
|
sta files+2
|
|
goaway return 4:files
|
|
invalidRN stz files
|
|
stz files+2
|
|
bra goaway
|
|
END
|
|
|
|
mapRN START
|
|
using KernelStruct
|
|
files equ 0
|
|
retval equ 4
|
|
subroutine (2:rn),6
|
|
|
|
lda rn
|
|
cmp #32
|
|
bcs invalidRN
|
|
|
|
ldx curProcInd
|
|
lda openFiles,x
|
|
sta files
|
|
lda openFiles+2,x
|
|
sta files+2
|
|
lda rn
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
sec
|
|
sbc #FDsize-FDTTable
|
|
tay
|
|
lda [files],y
|
|
sta retval
|
|
goaway return 2:retval
|
|
invalidRN stz retval
|
|
bra goaway
|
|
END
|
|
|
|
* search the specified file descriptor table for the physical
|
|
* refnum specified. Returns 0 if the file wasn't found, or
|
|
* returns the refnum (index into table)
|
|
|
|
SearchFDTable START
|
|
rn equ 0
|
|
|
|
subroutine (4:fdptr,2:refnum),2
|
|
lda #0
|
|
sta rn
|
|
|
|
loop asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
clc
|
|
adc #FDTTable ; don't forget the 6 bytes on top
|
|
tay
|
|
lda [fdptr],y
|
|
cmp refnum
|
|
bne nxt
|
|
iny
|
|
iny
|
|
lda [fdptr],y
|
|
cmp #FDgsos
|
|
beq gotit
|
|
|
|
nxt inc rn
|
|
lda rn
|
|
cmp #32
|
|
bcc loop
|
|
|
|
stz rn ; search failed, return 0
|
|
bra byebye
|
|
gotit inc rn ; rn + 1 is actual refnum
|
|
byebye return 2:rn
|
|
END
|
|
|
|
GNOGetRefInfo START
|
|
|
|
oldRN equ 10
|
|
fdPtr equ 12
|
|
|
|
ldy #2
|
|
lda [pBlock],y
|
|
beq badRef ; refnum 0 is BAD
|
|
sta oldRN
|
|
pha
|
|
jsl getFDptr
|
|
sta fdPtr
|
|
stx fdPtr+2
|
|
ora fdPtr+2
|
|
beq badRef
|
|
lda [fdPtr]
|
|
cmp #0
|
|
bne okay
|
|
badRef lda #$43
|
|
jmp GSOSReturn
|
|
okay anop
|
|
ldy #FDrefType
|
|
lda [fdPtr],y
|
|
cmp #FDgsos
|
|
beq typeOkay
|
|
cmp #FDpipe
|
|
beq notGSOS
|
|
|
|
ldy #FDrefNum
|
|
lda [fdPtr],y
|
|
dec a
|
|
asl a
|
|
asl a
|
|
tax
|
|
|
|
lda #3
|
|
ldy #4
|
|
sta [pBlock],y
|
|
|
|
lda [pBlock]
|
|
cmp #3
|
|
bcc gohome
|
|
|
|
lda >DeviceNames+2,x
|
|
pha
|
|
lda >DeviceNames,x
|
|
pha
|
|
ldy #8
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #6
|
|
lda [pBlock],y
|
|
pha
|
|
jsl copygs2res
|
|
gohome lda #0
|
|
jmp GSOSReturn ; basically ignore the call. no harm
|
|
typeOkay lda [fdPtr]
|
|
ldy #2
|
|
sta [pBlock],y
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
pha
|
|
lda oldRN
|
|
ldy #2
|
|
sta [pBlock],y
|
|
pla
|
|
jmp GSOSReturn
|
|
notGSOS lda #$58
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
GNORefCommon START
|
|
oldRN equ 10
|
|
fdPtr equ 12
|
|
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta oldRN
|
|
pha
|
|
bne notzero
|
|
lda cmdNum
|
|
cmp #$2015
|
|
jeq FlushSpecial
|
|
pla
|
|
lda #$43
|
|
jmp GSOSReturn
|
|
|
|
notzero jsl getFDptr
|
|
sta fdPtr
|
|
stx fdPtr+2
|
|
lda [fdPtr]
|
|
cmp #0
|
|
bne okay
|
|
lda #$43
|
|
jmp GSOSReturn
|
|
okay anop
|
|
ldy #FDrefType
|
|
lda [fdPtr],y
|
|
cmp #FDgsos
|
|
beq typeOkay
|
|
jmp notGSOS
|
|
cmp #FDpipe
|
|
bne notGSOS
|
|
lda #0
|
|
jmp GSOSReturn ; basically ignore the call. no harm
|
|
typeOkay lda [fdPtr]
|
|
ldy #2
|
|
sta [pBlock],y
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
pha
|
|
lda oldRN
|
|
ldy #2
|
|
sta [pBlock],y
|
|
pla
|
|
jmp GSOSReturn
|
|
notGSOS lda #$58
|
|
jmp GSOSReturn
|
|
|
|
* Special case this: Flush() is the only routine here which can accept
|
|
* zero as a legal refnum; it should flush all open files, and we pass
|
|
* the call _unmodified_ into GS/OS for this reason.
|
|
|
|
FlushSpecial anop
|
|
pla
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
GNONewLine START
|
|
oldRN equ 10
|
|
fdrec equ 12
|
|
trueRN equ 16
|
|
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta oldRN
|
|
pha
|
|
jsl getFDptr
|
|
sta fdrec
|
|
stx fdrec+2
|
|
ora fdrec+2
|
|
beq badRef ; bad refnum
|
|
ldy #FDrefNum
|
|
lda [fdrec],y
|
|
cmp #0
|
|
bne okay
|
|
badRef lda #$43
|
|
jmp GSOSReturn
|
|
okay anop
|
|
sta trueRN
|
|
ldy #FDrefType
|
|
lda [fdrec],y
|
|
cmp #FDgsos
|
|
bne nlPipe
|
|
|
|
lda trueRN
|
|
ldy #2
|
|
sta [pBlock],y
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
pha
|
|
lda oldRN
|
|
ldy #2
|
|
sta [pBlock],y
|
|
pla
|
|
jmp GSOSReturn
|
|
nlPipe ldy #4
|
|
lda [pBlock],y
|
|
ldy #FDNLenableMask
|
|
sta [fdrec],y
|
|
beq noerror
|
|
ldy #6
|
|
lda [pBlock],y
|
|
ldy #FDNLnumChars
|
|
sta [fdrec],y
|
|
cmp #1
|
|
bcc doerror
|
|
cmp #256+1
|
|
bcs doerror
|
|
|
|
ldy #8
|
|
lda [pBlock],y
|
|
tax
|
|
iny2
|
|
lda [pBlock],y
|
|
ldy #FDNLtable+2
|
|
sta [fdrec],y
|
|
dey2
|
|
txa
|
|
sta [fdrec],y
|
|
ldy #FDrefFlags
|
|
lda [fdrec],y
|
|
and #%1111111111110111 ; ~rfP16NEWL
|
|
sta [fdrec],y
|
|
|
|
noerror lda #0
|
|
jmp GSOSReturn
|
|
doerror ldy #FDNLenableMask
|
|
lda #0
|
|
sta [fdrec],y
|
|
lda #$53
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
GNORdWr START
|
|
using KernelStruct
|
|
files equ 10
|
|
fdrec equ 14
|
|
rn equ 18
|
|
|
|
ldx curProcInd
|
|
lda openFiles,x
|
|
sta files
|
|
lda openFiles+2,x
|
|
sta files+2
|
|
ldy #2
|
|
lda [pBlock],y
|
|
pha
|
|
sta rn
|
|
jsl getFDptr
|
|
sta fdrec
|
|
stx fdrec+2
|
|
ora fdrec+2
|
|
bne refIsOk
|
|
lda #$43
|
|
jmp GSOSReturn
|
|
refIsOk ldy #FDrefType
|
|
lda [fdrec],y
|
|
asl a
|
|
tax
|
|
jmp (rdwrtable,X)
|
|
|
|
rdwrtable dc i2'doGSOS'
|
|
dc i2'doPipe'
|
|
dc i2'doTTY'
|
|
dc i2'doSocket'
|
|
|
|
*******************
|
|
doGSOS anop
|
|
ldy #FDrefNum
|
|
lda [fdrec],y
|
|
ldy #2
|
|
sta [pBlock],y
|
|
ph4 pBlock
|
|
ph2 cmdNum
|
|
jsl OldGSOSSt
|
|
pha
|
|
ldy #2
|
|
lda rn
|
|
sta [pBlock],y
|
|
pla
|
|
jmp GSOSReturn
|
|
|
|
*******************
|
|
doPipe anop
|
|
jsl decBusy
|
|
; ph4 (pBlock)+2
|
|
lda pBlock
|
|
clc
|
|
adc #2
|
|
tay
|
|
lda pBlock+2
|
|
adc #0
|
|
pha
|
|
phy
|
|
ldy #FDrefNum
|
|
lda [fdrec],y
|
|
pha
|
|
lda cmdNum
|
|
cmp #$2012
|
|
beq pread
|
|
jsl pipeHiWrite
|
|
bra goback
|
|
pread ph4 fdrec ; we need this for newline
|
|
jsl pipeHiRead
|
|
goback anop
|
|
jsl incBusy
|
|
jmp GSOSReturn
|
|
|
|
*******************
|
|
doTTY anop
|
|
jsl decBusy
|
|
ldy #8
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #6
|
|
lda [pBlock],y
|
|
pha
|
|
ldy #4
|
|
lda [pBlock],y
|
|
pha
|
|
lda cmdNum
|
|
cmp #$2012
|
|
beq tread
|
|
ldy #FDrefNum ; tty devId number
|
|
lda [fdrec],y
|
|
dec a
|
|
pha
|
|
ldy #t_write
|
|
jsl LineDiscDispatch
|
|
bra goaway2
|
|
tread ldy #FDrefNum ; the tty device ID number
|
|
lda [fdrec],y
|
|
dec a
|
|
pha
|
|
ldy #t_read
|
|
jsl LineDiscDispatch
|
|
goaway2 anop
|
|
phx
|
|
ldy #12
|
|
sta [pBlock],y ; to provide a way for TTYs to
|
|
lda #0 ; return EOF properly
|
|
ldy #14
|
|
sta [pBlock],y
|
|
jsl incBusy
|
|
pla
|
|
jmp GSOSReturn
|
|
|
|
*******************
|
|
doSocket anop
|
|
ldy #FDrefNum
|
|
lda [fdrec],y
|
|
pha
|
|
ph2 cmdNum
|
|
; ph4 pBlock
|
|
pei (pBlock+2)
|
|
lda pBlock
|
|
inc a
|
|
inc a
|
|
pha
|
|
jsl SOCKrdwr
|
|
jmp GSOSReturn
|
|
|
|
END
|
|
|
|
PGClose START
|
|
using KernelStruct
|
|
|
|
rn equ 10
|
|
files equ 12
|
|
fdptr equ 16
|
|
errno equ 20
|
|
cnt equ 22
|
|
level equ 24
|
|
|
|
stz errno
|
|
ldy #openFiles-CKernData ; get the address of the fd table
|
|
lda [procEnt],y
|
|
sta files
|
|
iny2
|
|
lda [procEnt],y
|
|
sta files+2
|
|
|
|
ldy #0
|
|
lda cmdNum
|
|
cmp #$0014 ; P16 refNum is at offset 0
|
|
beq whichOS
|
|
lda [pBlock]
|
|
cmp #1
|
|
beq pCountOkay
|
|
lda #$04
|
|
jmp GSOSReturn
|
|
pCountOkay ldy #2 ; GSOS refNum is at offset 2
|
|
whichOS lda [pBlock],y
|
|
sta rn
|
|
beq doClose0
|
|
pha
|
|
jsl getFDptr
|
|
stx fdptr+2
|
|
sta fdptr
|
|
ora fdptr+2
|
|
beq refIsBad
|
|
|
|
ph4 fdptr
|
|
jsl subClose
|
|
cmp #$43
|
|
beq dontdecr
|
|
pha
|
|
lda [files] ; decr the # of open files
|
|
dec a
|
|
sta [files]
|
|
pla
|
|
dontdecr jmp GSOSReturn
|
|
refIsBad lda #$43
|
|
jmp GSOSReturn
|
|
doClose0 anop
|
|
lda files
|
|
clc
|
|
adc #FDTTable
|
|
sta fdptr
|
|
lda files+2
|
|
adc #0
|
|
sta fdptr+2
|
|
|
|
ldy #FDTLevel ; calculate the actual
|
|
lda [files],y ; system level from the
|
|
ldy #FDTLevelMode ; user level setting
|
|
ora [files],y ; and the levelMode
|
|
sta level
|
|
|
|
lda [files] ; number of entries
|
|
sta cnt
|
|
loop anop
|
|
lda cnt
|
|
beq doneClose0
|
|
lda [fdptr] ; zero refNum means empty entry
|
|
beq nextEntry
|
|
|
|
; ldy #FDTLevel ; handle 'internal' file levels
|
|
; lda [files],y ; like System 6
|
|
; ldy #FDTLevelMode
|
|
; ora [files],y
|
|
; ldy #FDrefLevel
|
|
; cmp [fdptr],y
|
|
; bcs noclose
|
|
|
|
lda level ; our calculated level
|
|
ldy #FDTLevel
|
|
cmp [files],y ; 'global' file level
|
|
bcc noclose
|
|
|
|
ph4 fdptr
|
|
jsl subClose
|
|
cmp #0
|
|
beq noerror
|
|
sta errno
|
|
noerror anop
|
|
lda [files] ; decr the # of open files
|
|
dec a
|
|
sta [files]
|
|
noclose dec cnt
|
|
nextEntry lda fdptr
|
|
clc
|
|
adc #FDsize
|
|
sta fdptr
|
|
lda fdptr+2
|
|
adc #0
|
|
sta fdptr+2
|
|
bra loop
|
|
doneClose0 lda errno
|
|
jmp GSOSReturn
|
|
END
|
|
|
|
subClose START
|
|
CLpCount equ 0
|
|
CLrefNum equ 2
|
|
err equ 4
|
|
|
|
subroutine (4:fdptr),6
|
|
stz err
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
bne validRN
|
|
lda #$43
|
|
sta err
|
|
jmp errorRet
|
|
|
|
validRN anop
|
|
ldy #FDrefType
|
|
lda [fdptr],y
|
|
|
|
asl a
|
|
tax
|
|
jmp (closetable,X)
|
|
|
|
closetable dc i2'subGSOS'
|
|
dc i2'subPipe'
|
|
dc i2'subTTY'
|
|
dc i2'subSocket'
|
|
|
|
*******************
|
|
subSocket anop
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
pha
|
|
pea FDsocket
|
|
jsl DecRefnum
|
|
cmp #0 ; there are still more references
|
|
bne subSock1 ; to this file, don't close it!
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
pha
|
|
jsl SOCKclose
|
|
sta err
|
|
subSock1 jmp goaway
|
|
|
|
*******************
|
|
subGSOS anop
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
sta CLrefNum
|
|
pha
|
|
|
|
lda #1
|
|
sta CLpCount
|
|
pea FDgsos ; we know refType == gsos
|
|
jsl DecRefnum
|
|
cmp #0 ; there are still more references
|
|
bne goaway ; to this file, don't close it!
|
|
|
|
pea $0000 ; stack is always in bank 0!
|
|
phd
|
|
pea $2014 ; command number
|
|
jsl OldGSOSSt
|
|
sta err
|
|
jmp goaway
|
|
|
|
*******************
|
|
subPipe anop
|
|
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
pha
|
|
ldy #FDrefFlags
|
|
lda [fdptr],y
|
|
pha
|
|
jsl decPipe
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
pha
|
|
pea FDpipe
|
|
jsl DecRefnum
|
|
cmp #0
|
|
bne goaway
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
pha
|
|
jsl disposePipe
|
|
|
|
goaway anop
|
|
lda #0
|
|
ldy #FDrefNum
|
|
sta [fdptr],y
|
|
ldy #FDrefType
|
|
sta [fdptr],y
|
|
|
|
errorRet anop
|
|
return 2:err
|
|
|
|
*******************
|
|
subTTY anop
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
pha
|
|
pea FDtty
|
|
jsl DecRefnum
|
|
cmp #0
|
|
bne goaway
|
|
|
|
* Now, adjust the process group the terminal was in
|
|
ldy #FDrefNum
|
|
lda [fdptr],y
|
|
dec a
|
|
asl a
|
|
tax
|
|
lda ttyStruct,x
|
|
beq nopgrp ; no pgrp was set
|
|
dec a ; adjust, since pgrps start at
|
|
dec a ; number 2
|
|
asl a
|
|
tay
|
|
lda #0 ; zero the pgrp
|
|
sta ttyStruct,x
|
|
tyx
|
|
lda pgrpInfo,x ; decrement the pgrp count
|
|
dec a
|
|
sta pgrpInfo,x
|
|
|
|
nopgrp ldy #FDrefNum
|
|
lda [fdptr],y
|
|
dec a
|
|
pha
|
|
ldy #t_close ; shutdown the device driver
|
|
jsl LineDiscDispatch
|
|
|
|
bra goaway
|
|
|
|
END
|
|
|
|
GNOGetName START
|
|
using KernelStruct
|
|
pathptr equ 10
|
|
resptr equ 14
|
|
outind equ 18
|
|
inind equ 20
|
|
pathlen equ 22
|
|
|
|
* Note that forked processes will get the name of their parent
|
|
lda [pBlock]
|
|
beq pcerr
|
|
cmp #3
|
|
bcs pcerr
|
|
bra goaround
|
|
pcerr lda #4
|
|
jmp GSOSReturn
|
|
|
|
goaround anop
|
|
ldy #4
|
|
lda [pBlock],y
|
|
sta resptr+2
|
|
ldy #2
|
|
lda [pBlock],y
|
|
sta resptr
|
|
|
|
ldx curProcInd ; get the full pathname of
|
|
lda procUserID,x ; the process.
|
|
pha
|
|
pha ; space for tool call. ARGH!!!
|
|
pha
|
|
pea $1
|
|
_LGetPathname2
|
|
pl4 pathptr
|
|
lda [pathptr]
|
|
inc a
|
|
sta pathlen
|
|
tay
|
|
short m
|
|
loop lda [pathptr],y
|
|
cmp #':'
|
|
beq gotfname
|
|
dey
|
|
bra loop
|
|
gotfname long m
|
|
iny
|
|
sty inind
|
|
lda [pathptr] ; get length
|
|
sec
|
|
sbc inind ; length of filename
|
|
clc
|
|
adc #2 ; minus the length word
|
|
cmp [resptr] ; length of buffer?
|
|
beq okay ; <= is okay
|
|
bcs buffer2small
|
|
okay anop
|
|
ldy #2
|
|
sta [resptr],y ; store length of filename
|
|
|
|
ldy #4
|
|
sty outind
|
|
short m
|
|
cploop ldy inind
|
|
lda [pathptr],y
|
|
ldy outind
|
|
sta [resptr],y
|
|
ldy inind
|
|
cpy pathlen
|
|
bcs donecopy
|
|
long m
|
|
inc inind
|
|
inc outind
|
|
short m
|
|
bra cploop
|
|
donecopy long m
|
|
lda [pBlock]
|
|
cmp #1
|
|
beq done
|
|
ldx curProcInd
|
|
lda procUserID,x
|
|
ldy #6
|
|
sta [pBlock],y
|
|
done lda #0
|
|
jmp GSOSReturn
|
|
|
|
buffer2small ldy #2
|
|
sta [resptr],y
|
|
lda #$4F
|
|
jmp GSOSReturn ; buffer too small error
|
|
END
|
|
|
|
GNOGetStdRefNum START
|
|
lda [pBlock]
|
|
cmp #2
|
|
beq PCokay
|
|
lda #4
|
|
jmp GSOSReturn
|
|
|
|
PCokay ldy #2
|
|
lda [pBlock],y
|
|
cmp #10
|
|
bcc pfxerr
|
|
cmp #13
|
|
bcs pfxerr
|
|
|
|
sec
|
|
sbc #9
|
|
ldy #4
|
|
sta [pBlock],y
|
|
lda #0
|
|
jmp GSOSReturn
|
|
pfxerr lda #$53
|
|
jmp GSOSReturn
|
|
END
|