Mercurial > hg > Members > kono > nitros9-code
changeset 1280:48d47eb305dc
Back-ported from OS-9 Level Two
author | boisy |
---|---|
date | Wed, 27 Aug 2003 23:44:50 +0000 |
parents | 9a563c32979a |
children | a248b7df616a |
files | level1/modules/pipeman.asm |
diffstat | 1 files changed, 517 insertions(+), 223 deletions(-) [+] |
line wrap: on
line diff
--- a/level1/modules/pipeman.asm Wed Aug 27 21:31:07 2003 +0000 +++ b/level1/modules/pipeman.asm Wed Aug 27 23:44:50 2003 +0000 @@ -1,31 +1,70 @@ ******************************************************************** -* PipeMan - Pipe file manager +* PipeMan - OS-9 Pipe File Manager * * $Id$ * -* Ed. Comments Who YY/MM/DD +* Some tests under NitrOS-9: +* +* 'show grf.3.a | eat' (eat is cat, but just does a I$ReadLn, and not I$WritLn) +* April 10, 1996 14:05:15 +* April 10, 1996 14:07:47 +* 15.2 seconds per iteration +* i.e. everything but the screen writes +* +* fast SCF+fast pipe +* 'show grf.3.a | cat', 10 times +* April 10, 1996 13:17:54 +* April 10, 1996 13:21:57 +* 24.3 seconds per iteration +* 9.1 solely for pipes +* +* fast SCF+old slow pipe +* April 10, 1996 13:30:24 +* April 10, 1996 13:38:04 +* 46.0 seconds per iteration +* 30.8 solely for pipes +* +* speedup percent is (30.8-9.1)/30.8 = 70% +* +* Pipes are more than doubled in speed! +* +* 32 byte read and write buffers +* +* Edt/Rev YYYY/MM/DD Modified by +* Comment * ------------------------------------------------------------------ -* 4 From Tandy OS-9 Level One VR 02.00.00 +* 4 ????/??/?? Alan DeKok +* Enhanced and re-written. +* +* 5r0 2003/08/27 Boisy G. Pitre +* Back-ported from OS-9 Level Two to OS-9 Level One. nam PipeMan - ttl Pipe file manager - -* Disassembled 98/08/23 18:26:04 by Disasm v1.6 (C) 1988 by RML + ttl OS-9 Pipe File Manager ifp1 use defsfile + use pipedefs + use scfdefs endc tylg set FlMgr+Objct -atrv set ReEnt+rev -rev set $01 -edition set 4 +atrv set ReEnt+Rev +rev set $00 +edition set 5 mod eom,name,tylg,atrv,start,size -u0000 rmb 0 + rmb $0000 size equ . + + org $0000 +P.CPR rmb 1 process ID +P.CNT rmb 1 count +P.SIG rmb 1 signal code +P.FLAG rmb 1 raw/edit flag + name fcs /PipeMan/ fcb edition @@ -34,236 +73,491 @@ lbra MakDir lbra ChgDir lbra Delete - lbra Seek +* +* I$Seek Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +Seek clrb + rts + nop lbra Read lbra Write lbra ReadLn lbra WritLn - lbra GetStt - lbra SetStt - lbra Close -MakDir -ChgDir -Delete - comb - ldb #E$UnkSvc - rts -Seek -GetStt -SetStt - clrb + +* +* I$GetStat Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +GetStt clrb + rts + nop + +* +* I$SetStat Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +SetStt clrb + rts + nop + +* +* I$Close Entry Point +* +* Entry: A = path number +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +Close lda PD.CNT,y + bne L008E + ldu PD.BUF,y if no one's using it, + clrb + inca + os9 F$SRtMem return the memory + clrb + rts + +L008E leax PD.Read,y + cmpa PD.Read+P.CNT,y is the read count zero? + beq L009C + + cmpa PD.Writ+P.CNT,y is the write count zero? + bne L00A9 + leax PD.Writ,y + +L009C lda P.CPR,x get process ID that's reading/writing + beq L00A9 if none + ldb P.SIG,x get signal code + beq L00A9 + clr P.SIG,x + os9 F$Send send a wake-up signal to the process +L00A9 clrb rts -Create -Open - ldu $06,y - ldx $04,u - pshs y - os9 F$PrsNam - bcs L0073 - lda -$01,y - bmi L0058 - leax ,y - os9 F$PrsNam - bcc L0073 -L0058 sty $04,u - puls y + +* +* I$MakDir Entry Point +* +* Entry: X = address of the pathlist +* +* Exit: X = last byte of pathlist address +* +* Error: CC Carry set +* B = errcode +* +MakDir equ * + +* +* I$ChgDir Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +ChgDir equ * + +* +* I$Delete Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +Delete equ * + comb + ldb #E$UnkSVC + rts + +* +* I$Create Entry Point +* +* Entry: A = access mode desired +* B = file attributes +* X = address of the pathlist +* +* Exit: A = pathnum +* X = last byte of pathlist address +* +* Error: CC Carry set +* B = errcode +* +Create equ * + +* +* I$Open Entry Point +* +* Entry: A = access mode desired +* X = address of the pathlist +* +* Exit: A = pathnum +* X = last byte of pathlist address +* +* Error: CC Carry set +* B = errcode +* +Open equ * + ldx R$X,u get address of filename to open + pshs y save PD pointer + os9 F$PrsNam parse /pipe + bcs L007B exit on error + IFGT Level-1 + ldx <D.Proc current process ptr + ldb P$Task,x get task number for call, below + leax -$01,y back up one character + os9 F$LDABX get last character of the filename + tsta check the character + ELSE +* leax -1,y + lda -1,y + ENDC + bmi L0060 if high bit set, it's OK + leax ,y point to next bit + os9 F$PrsNam else parse name + bcc L007B if no error, it's a sub-dir, and we error out +L0060 sty R$X,u save new pathname ptr + puls y restore PD pointer ldd #$0100 - os9 F$SRqMem - bcs L0072 - stu $08,y - stu <$14,y - stu <$16,y - leau d,u - stu <$12,y -L0072 rts -L0073 comb - ldb #$D7 + os9 F$SRqMem request one page for the pipe + bcs L007A exit on error + stu PD.BUF,y save ptr to the buffer + stu <PD.NxtI,y save write pointer + stu <PD.NxtO,y and read pointer + leau d,u point to the end of the buffer + stu <PD.End,y save save the ptr +L007A rts + +L007B comb + ldb #E$BPNam bad path name puls pc,y -Close lda $02,y - bne L0086 - ldu $08,y - ldd #$0100 - os9 F$SRtMem - bra L00A1 -L0086 cmpa $0B,y - bne L008E - leax $0A,y - bra L0094 -L008E cmpa $0F,y - bne L00A1 - leax $0E,y -L0094 lda ,x - beq L00A1 - ldb $02,x - beq L00A1 - clr $02,x - os9 F$Send -L00A1 clrb - rts + +* +* I$ReadLn Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* ReadLn ldb #$0D - stb $0D,y - bra L00AB -Read clr $0D,y -L00AB leax $0A,y - lbsr L0140 - bcs L00EB - ldd $06,u - beq L00EB - ldx $04,u - addd $04,u - pshs b,a - bra L00C9 -L00BE pshs x - leax $0A,y - lbsr L016B - puls x - bcs L00DC -L00C9 lbsr L01D2 - bcs L00BE + fcb $21 skip one byte + +* +* I$Read Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +Read clrb + stb PD.Read+P.FLAG,y raw read + leax PD.Read,y + lbsr L0160 send wakeup signals to process + bcs L0100 on error, wake up writing process + ldx R$Y,u + beq L0100 if no bytes to rwad + ldd R$X,u start address to read from + leax d,x add in number of bytes: end address + +* NOTE: PD.RGS,Y will change as the processes read/write the pipe, +* and sleep. + pshs u save current caller's register stack + leas -32,s reserve a 32-byte buffer on the stack + leau ,s point to the start of the buffer + pshs d,x save start, end to read + + clrb no bytes read to user yet + puls x restore number of data bytes read, read address +L00DB bsr L01F2 are we blocked? + bcs L00C8 yes, send a signal + sta b,u store the byte in the internal read buffer + leax $01,x go up by one byte + incb one more byte in the buffer + cmpb #32 reached maximum size of the buffer? + blo L00E0 no, continue + bsr read.out read 32 bytes of data to the caller + +L00E0 tst PD.Read+P.FLAG,Y was it a raw read? + beq L00ED skip ahead if raw + cmpa #C$CR was the character a CR? + beq L00F1 yes, we're done: flush and exit +L00ED cmpx ,s or at end of data to read? + blo L00DB no, keep reading + +L00F1 bsr read.out flush the rest of the pipe buffer to the user +L00F2 tfr x,d this is how far we got + subd ,s++ take out start of buffer + leas 32,s kill our on-stack buffer + puls u restore caller's register stack ptr: NOT PD.RGS,Y + addd R$Y,u add in number of bytes + std R$Y,u save bytes read + bne L00FF if not zero + ldb #E$EOF zero bytes read:EOF error + fcb $21 skip one byte + +L00FF clrb no errors +L0100 leax PD.Read,y read data ptr + lbra L01BD signal other it's OK to go ahead + +read.out pshs a,x,y,u save registers + tstb any data to write? + beq read.ex no, skip ahead + IFGT Level-1 + clra make 16-bit data length + tfr d,y number of data bytes to read to user + negb make it negative + leax b,x back up TO pointer + pshs x save it + leax ,u point to the start of the buffer + ldu <D.Proc current process pointer + ldb P$Task,u A=$00 from above, already + puls u restore TO pointer + os9 F$Move move the data over + clrb no bytes read to the caller yet + ELSE + tfr b,a copy byte count to A + nega make it negative + leax a,x back up TO pointer +ReadLoop lda ,u+ sta ,x+ - tst $0D,y - beq L00D8 - cmpa $0D,y - beq L00DC -L00D8 cmpx ,s - bcs L00C9 -L00DC tfr x,d - subd ,s++ - addd $06,u - std $06,u - bne L00EA - ldb #$D3 - bra L00EB -L00EA clrb -L00EB leax $0A,y - lbra L019D -WritLn ldb #$0D - stb <$11,y - bra L00FA -Write clr <$11,y -L00FA leax $0E,y - lbsr L0140 - bcs L013C - ldd $06,u - beq L013C - ldx $04,u - addd $04,u - pshs b,a - bra L0118 -L010D pshs x - leax $0E,y - lbsr L016B + decb + bne ReadLoop + ENDC +read.ex puls a,x,y,u,pc restore registers and exit + +L00C8 pshs x save read pointer + bsr read.out dump data out to the user + pshs b save number of bytes read + leax PD.Read,y read data area ptr + lbsr L018B setup for signal + puls x,b restore registers: note B=$00, but we CANNOT do a + bcc L00DB clrb, because this line needs CC.C! + bra L00F2 don't write data out again, but exit + +* Check if we're blocked +L01F2 lda <PD.RFlg,y we blocked? + bne L01F9 no, skip ahead + coma set flag: blocked + rts and return to the caller + +L01F9 pshs x save read ptr + ldx <PD.NxtO,y where to read from in the buffer + lda ,x+ get a byte + cmpx <PD.End,y at the end of the buffer? + blo L0207 no, skip ahesd + ldx PD.BUF,y yes, go to start +L0207 stx <PD.NxtO,y save new read ptr + cmpx <PD.NxtI,y caught up to the write pointer yet? + bne L0212 no, skeip ahead + clr <PD.RFlg,y yes, set read is blocked +L0212 andcc #^Carry no errors + puls pc,x restore regs and exit + +L0160 lda P.CPR,x get current process + beq L0185 none, exit + cmpa PD.CPR,y current process ID + beq L0189 none, exit + inc P.CNT,x one more process using this pipe + ldb P.CNT,x + cmpb PD.CNT,y same as the number for this path? + bne L0173 no, skip ahead + lbsr L009C no, send a wake-up signal +L0173 os9 F$IOQu and insert it in the others IO queue + dec P.CNT,x decrement count + pshs x + ldx <D.Proc current process ptr + ldb <P$Signal,x signal code puls x - bcs L0130 -L0118 lda ,x - lbsr L01AC - bcs L010D - leax $01,x - tst <$11,y - beq L012B - cmpa <$11,y - beq L0130 -L012B cmpx ,s - bcs L0118 - clrb -L0130 pshs b,cc - tfr x,d - subd $02,s - addd $06,u - std $06,u - puls x,b,cc -L013C leax $0E,y - bra L019D -L0140 lda ,x - beq L0165 - cmpa $05,y - beq L0169 - inc $01,x - ldb $01,x - cmpb $02,y - bne L0153 - lbsr L0094 -L0153 os9 F$IOQu - dec $01,x - pshs x - ldx <$004B - ldb <$36,x - puls x - beq L0140 - coma + beq L0160 if no signal code sent, do another process + coma otherwise return CC.C set, and B=signal code rts -L0165 ldb $05,y - stb ,x -L0169 clrb - rts -L016B ldb $01,x - incb - cmpb $02,y - beq L0199 - stb $01,x - ldb #$01 - stb $02,x - clr $05,y - pshs x - tfr x,d - eorb #$04 - tfr d,x - lbsr L0094 - ldx #$0000 - os9 F$Sleep - ldx <$004B - ldb <$36,x - puls x - dec $01,x - tstb - bne L019B - clrb - rts -L0199 ldb #$F5 -L019B coma - rts -L019D pshs u,b,cc - clr ,x - tfr x,d - eorb #$04 - tfr d,x - lbsr L0094 - puls pc,u,b,cc -L01AC pshs x,b - ldx <$14,y - ldb <$18,y - beq L01BE - cmpx <$16,y - bne L01C3 + +L0185 ldb PD.CPR,y grab current PD process + stb P.CPR,x save as current reading/writing process +L0189 clrb no errors + rts and exit + +L01CC pshs b,x save regs + ldx <PD.NxtI,y + ldb <PD.RFlg,y 0=READ, 1=WRITE + beq L01DE was reading, set to write and continue + cmpx <PD.NxtO,y caught up to the read pointer yet? + bne L01E3 comb puls pc,x,b -L01BE ldb #$01 - stb <$18,y -L01C3 sta ,x+ - cmpx <$12,y - bcs L01CC - ldx $08,y -L01CC stx <$14,y + +L01DE inc <PD.RFlg,y set to writing into the pipe +L01E3 sta ,X+ save the byte + cmpx <PD.End,y if at the end of the buffer + blo L01EC + ldx PD.BUF,y reset to the beginning +L01EC stx <PD.NxtI,y clrb puls pc,x,b -L01D2 lda <$18,y - bne L01D9 - comb + +write.in pshs a,x,y save registers + leau -32,u point to the start of the buffer again + IFGT Level-1 + ldx <D.Proc current process pointer + lda P$Task,x get FROM task number for this process + ldx 1,s get FROM pointer + ldy #32 16 bytes to grab + clrb TO the system task + os9 F$Move + ELSE + ldb #31 +WritLoop lda b,x + sta b,u + decb + bpl WritLoop + ENDC + ldb #32 16 bytes in the buffer + puls a,x,y,pc + +* +* I$WritLn Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +WritLn ldb #$0D + fcb $21 skip one byte + +* +* I$Write Entry Point +* +* Entry: +* +* Exit: +* +* Error: CC Carry set +* B = errcode +* +Write clrb + stb <PD.Writ+P.FLAG,y + leax PD.Writ,y + bsr L0160 make sure it's OK + bcs L015C + ldx R$Y,u get number of bytes to write + beq L015C + ldd R$X,u start address + leax d,x add in number of bytes + pshs u + leau ,s point to the end of the buffer + leas -32,s + pshs d,x save start, end + + ldx ,s get initial start pointer + bsr write.in fill the write buffer + + puls x +L0137 lda ,u + bsr L01CC save it in the buffer + bcs L0124 caught up to reading process yet? + leax $01,x up by one byte + leau 1,u + decb + bne L0138 + bsr write.in fill the buffer again + +L0138 tst <PD.Writ+P.FLAG,y + beq L014B + cmpa #C$CR at the end of a line to output? + beq L014F +L014B cmpx ,S at end yet? + blo L0137 if not, read more data +L014F clrb clear carry and error +L0150 ldu 2+32,s skip END, 32-byte write buffer, get U + pshs b,cc + tfr x,d + subd $02,s take out end address + addd R$Y,u add in number of bytes + std R$Y,u save bytes written + puls x,b,cc + leas 32,s kill write buffer + puls u + +L015C leax PD.Writ,y +* can probably lose saving 'U' in next few lines... but only minor difference +* Signal read/write it's OK to go ahead +L01BD pshs u,b,cc + clr P.CPR,x NO process currently using this device + bsr Other signal other process to start + puls pc,u,b,cc + +L0124 pshs x,b + leax PD.Writ,y + bsr L018B send signal to other + tfr b,a save error code, if applicable + puls x,b restore pointer, byte count + bcc L0137 continue if OK + tfr a,b otherwise restore error code + bra L0150 exit, returning the error code to the user + +L018B ldb P.CNT,x + incb + cmpb PD.CNT,y + beq L01B9 + stb P.CNT,x + ldb #$01 + stb P.SIG,x + clr PD.CPR,y + pshs x + bsr Other + ldx #$0000 make X=0 + os9 F$Sleep sleep forever + ldx <D.Proc + ldb <P$Signal,x get signal code + puls x + dec P.CNT,x + tstb + bne L01BB if a signal, we can't wake up + clrb the writing process rts -L01D9 pshs x - ldx <$16,y - lda ,x+ - cmpx <$12,y - bcs L01E7 - ldx $08,y -L01E7 stx <$16,y - cmpx <$14,y - bne L01F2 - clr <$18,y -L01F2 andcc #^Carry - puls pc,x + +L01B9 ldb #E$Write write error +L01BB coma + rts + +Other exg x,d + eorb #$04 if r/w go to w/r + exg d,x + lbra L009C emod eom equ * end -