Mercurial > hg > Members > kono > nitros9-code
view level1/modules/ioman.asm @ 253:762792d92c57
Slight changes to source
author | boisy |
---|---|
date | Sat, 20 Jul 2002 04:43:05 +0000 |
parents | 668388823050 |
children | 10957d54bf16 |
line wrap: on
line source
******************************************************************** * IOMan - OS-9 Level One V2 I/O Manager module * * $Id$ * * Ed. Comments Who YY/MM/DD * ------------------------------------------------------------------ * 11 From Tandy OS-9 Level One VR 02.00.00 * 12 I/O Queue sort bug and I$Attach static storage BGP 02/05/11 * premature deallocation bug fixed nam IOMan ttl OS-9 Level One V2 I/O Manager module ifp1 use defsfile use scfdefs endc tylg set Systm+Objct atrv set ReEnt+rev rev set $01 * edition 11 = Stock OS-9 Level One Vr. 2.00 IOMan * edition 12 = IO Queue sort bug fixed, IAttach bug fixed edition equ 12 mod eom,name,tylg,atrv,IOManEnt,size size equ . name fcs /IOMan/ fcb edition * IOMan is called from OS9p2 IOManEnt equ * * allocate device and polling tables ldx <D.Init get pointer to init module lda PollCnt,x grab number of polling entries ldb #POLSIZ and size per entry mul D = size of all entries in bytes pshs b,a save off lda DevCnt,x get device table count in init mod ldb #DEVSIZ get size per dev table entry mul D = size of all entires in bytes pshs b,a save off addd 2,s add devsize to polsiz addd #$0018 add in ??? addd #$00FF bring up to next page clrb os9 F$SRqMem ask for the memory bcs Crash crash if we can't get it * clear allocated mem leax ,u point to dev table L0033 clr ,x+ subd #$0001 bhi L0033 stu <D.PolTbl U = pointer to polling table ldd ,s++ get dev table size leax d,u point X past polling table to dev table stx <D.DevTbl save off X to system vars addd ,s++ grab poll table size leax d,u stx <D.CLTB ldx <D.PthDBT os9 F$All64 bcs Crash stx <D.PthDBT os9 F$Ret64 leax >DPoll,pcr get address of IRQ poll routine stx <D.Poll save in statics * install I/O system calls leay <IOCalls,pcr point to I/O calls os9 F$SSvc install them rts return to OS9p2 Crash jmp [>$FFFE] IOCalls fcb $7F fdb UsrIO-*-2 fcb F$Load fdb FLoad-*-2 fcb F$PErr fdb FPErr-*-2 fcb F$IOQu+$80 fdb FIOQu-*-2 fcb $FF fdb SysIO-*-2 fcb F$IRQ+$80 fdb FIRQ-*-2 fcb F$IODel+$80 fdb FIODel-*-2 fcb $80 FIODel ldx R$X,u ldu <D.Init ldb DevCnt,u get device count ldu <D.DevTbl L0083 ldy V$DESC,u beq L0094 cmpx V$DESC,u beq L009B cmpx V$DRIV,u beq L009B cmpx V$FMGR,u beq L009B L0094 leau DEVSIZ,u decb bne L0083 clrb rts L009B comb ldb #E$ModBsy rts UsrIODis fdb IAttach-UsrIODis fdb IDetach-UsrIODis fdb IDup-UsrIODis fdb IUsrCall-UsrIODis fdb IUsrCall-UsrIODis fdb IMakDir-UsrIODis fdb IChgDir-UsrIODis fdb IDelete-UsrIODis fdb UISeek-UsrIODis fdb UIRead-UsrIODis fdb UIWrite-UsrIODis fdb UIRead-UsrIODis fdb UIWrite-UsrIODis fdb UIGetStt-UsrIODis fdb UISeek-UsrIODis fdb UIClose-UsrIODis fdb IDeletX-UsrIODis SysIODis fdb IAttach-SysIODis fdb IDetach-SysIODis fdb SIDup-SysIODis fdb ISysCall-SysIODis fdb ISysCall-SysIODis fdb IMakDir-SysIODis fdb IChgDir-SysIODis fdb IDelete-SysIODis fdb SISeek-SysIODis fdb SIRead-SysIODis fdb SIWrite-SysIODis fdb SIRead-SysIODis fdb SIWrite-SysIODis fdb SIGetStt-SysIODis fdb SISeek-SysIODis fdb SIClose-SysIODis fdb IDeletX-SysIODis * Entry to User and System I/O dispatch table * B = I/O system call code UsrIO leax <UsrIODis,pcr bra IODsptch SysIO leax <SysIODis,pcr IODsptch cmpb #I$DeletX compare with last I/O call bhi L00FA branch if greater pshs b lslb multiply by 2 ldd b,x offset leax d,x get address of routine puls b jmp ,x jump to it! L00FA comb we get here if illegal I/O code ldb #E$UnkSvc rts IAttach ldb #$11 L0100 clr ,-s decb bpl L0100 stu <$10,s caller regs lda R$A,u sta $09,s device mode ldx R$X,u lda #Devic+0 os9 F$Link link to device desc. bcs L0139 stu $04,s address of mod hdr ldy <$10,s get caller regs stx R$X,y save updated ptr ldd M$Port+1,u get port addr std $0C,s save on stack ldd M$PDev,u get driver name leax d,u point X to driver name lda #Drivr+0 os9 F$Link link to driver bcs L0139 stu ,s save driver addr on stack ldu $04,s get addr of dev desc. ldd M$FMgr,u get file mgr name leax d,u point X to fmgr name lda #FlMgr+0 os9 F$Link link to fmgr L0139 bcc L0149 * error on attach, so detach L013B stb <$11,s save fmgr addr on stack leau ,s point U to S os9 I$Detach leas <$11,s clean up stack comb puls pc,b return to caller L0149 stu $06,s save fmgr addr ldx <D.Init ldb DevCnt,x lda DevCnt,x ldu D.DevTbl L0153 ldx V$DESC,u get desc addr beq L0188 cmpx $04,s same? bne L016E branch if not ldx V$STAT,u get stat bne L016C branch if zero pshs a lda V$USRS,u get user count beq L0168 os9 F$IOQu L0168 puls a bra L0153 L016C stu $0E,s save dev entry on stack L016E ldx V$DESC,u get dev desc ptr ldy M$Port+1,x cmpy $0C,s compare to port addr on stack bne L0188 ldx V$DRIV,u cmpx ,s compare to driver addr on stack bne L0188 ldx V$STAT,u get static stx $02,s save static on stack tst V$USRS,u test user count beq L0188 branch if zero sta $0A,s store on stack L0188 leau DEVSIZ,u go to next entry decb decrement count bne L0153 go back to loop if not zero ldu $0E,s get dev entry off stack lbne L01E6 ldu D.DevTbl L0195 ldx V$DESC,u get dev desc ptr beq L01A6 branch if zero leau DEVSIZ,u deca bne L0195 continue loop ldb #E$DevOvf device table overflow bra L013B L01A2 ldb #E$BMode bad mode bra L013B L01A6 ldx $02,s get static storage off stack lbne L01DD stu $0E,s save off dev entry on stack ldx ,s get driver addr off stack ldd M$Mem,x get memory requirement addd #$00FF round up to next page clrb os9 F$SRqMem lbcs L013B stu $02,s save off on stack L01BF clr ,u+ clear static mem subd #$0001 bhi L01BF ldd $0C,s get port addr off stack ldu $02,s get static storage ptr clr V.PAGE,u std V.PORT,u save addr ldy $04,s get dev desc addr ldx ,s get driver addr ldd M$Exec,x get driver exec jsr d,x call Init routine lbcs L013B ldu $0E,s get dev entry L01DD ldb #$08 copy 8 bytes from stack to dev entry L01DF lda b,s sta b,u decb bpl L01DF L01E6 ldx V$DESC,u get dev desc ldb M$Revs,x lda $09,s get device mode off stack anda M$Mode,x AND mode with desc mode ldx V$DRIV,u get driver ptr anda M$Mode,x AND mode with driver mode cmpa $09,s compare with passed mode lbne L01A2 branch if error inc V$USRS,u else inc user count of dev entry bne L01FE branch if not overflow from 255->0 dec V$USRS,u else dec L01FE ldx <$10,s get caller regs stu R$U,x leas <$12,s restore stack clrb rts IDetach ldu R$U,u ldx V$DESC,u IFEQ edition-11 * Note: the following lines constitute a bug that can, in certain * circumstances, wipe out a device's static storage out from * underneath it. ldb V$USRS,u get user count bne L0218 branch if not zero pshs u,b ldu V$STAT,u pshs u bra L0254 ELSE tst V$USRS,u beq IDetach2 ENDC L0218 lda #255 cmpa V$USRS,u 255 users? lbeq L0283 branch if so dec V$USRS,u else dec user count lbne L0271 branch if dec not 0 IDetach2 ldx <D.Init ldb DevCnt,x pshs u,b ldx V$STAT,u clr V$STAT,u clr V$STAT+1,u ldy <D.DevTbl L0235 cmpx V$STAT,y beq L0267 leay DEVSIZ,y decb bne L0235 ldy <D.Proc ldb P$ID,y stb V$USRS,u ldy V$DESC,u ldu V$DRIV,u exg x,u X pts to driver, U pts to static ldd M$Exec,x leax d,x pshs u jsr $0F,x call term routine L0254 puls u ldx 1,s get U from stack (dev entry to detach) ldx V$DRIV,x ldd M$Mem,x get memory requirements addd #$00FF round up to next page clrb os9 F$SRtMem return mem ldx 1,s get U from stack (dev entry to detach) ldx V$DESC,x get dev desc ptr L0267 puls u,b get U,B ldx V$DESC,u clr V$DESC,u clr V$DESC+1,u clr V$USRS,u L0271 ldy V$DRIV,u ldu V$FMGR,u os9 F$UnLink unlink file manager leau ,y os9 F$UnLink unlink driver leau ,x os9 F$UnLink unlink descriptor L0283 lbsr L04D9 clrb rts * user state I$Dup IDup bsr FindPath look for a free path bcs IDupRTS branch if error pshs x,a else save of lda R$A,u get path to dup lda a,x point to path to dup bsr L02A1 bcs L029D puls x,b stb R$A,u save off new path to caller's A sta b,x rts L029D puls pc,x,a * system state I$Dup SIDup lda R$A,u L02A1 lbsr FindPDsc find path descriptor bcs IDupRTS exit if error inc PD.CNT,y else increment path count IDupRTS rts * Find next free path position in current proc * Exit: X = Ptr to proc's path table * A = Free path number (valid if carry clear) * FindPath ldx <D.Proc get ptr to current proc desc leax <P$PATH,x point X to proc's path table clra start from 0 L02AF tst a,x this path free? beq L02BC branch if so... inca else try next path... cmpa #NumPaths are we at the end? bcs L02AF branch if not comb else path table is full ldb #E$PthFul rts L02BC andcc #^Carry rts IUsrCall bsr FindPath bcs L02D1 pshs u,x,a bsr ISysCall puls u,x,a bcs L02D1 ldb R$A,u stb a,x sta R$A,u L02D1 rts ISysCall pshs b ldb R$A,u bsr L0349 bcs L02E6 puls b lbsr CallFMgr bcs L02F5 lda PD.PD,y sta R$A,u rts L02E6 puls pc,a * make directory IMakDir pshs b ldb #DIR.+WRITE. L02EC bsr L0349 bcs L02E6 puls b lbsr CallFMgr L02F5 pshs b,cc ldu PD.DEV,y os9 I$Detach lda PD.PD,y ldx <D.PthDBT os9 F$Ret64 puls pc,b,cc * change directory IChgDir pshs b ldb R$A,u orb #DIR. bsr L0349 bcs L02E6 puls b lbsr CallFMgr bcs L02F5 ldu <D.Proc ldb PD.MOD,y bitb #PWRIT.+PREAD.+UPDAT. beq L0329 ldx PD.DEV,y stx <P$DIO,u inc V$USRS,x bne L0329 dec V$USRS,x L0329 bitb #PEXEC.+EXEC. beq L0338 ldx PD.DEV,y stx <P$DIO+6,u inc V$USRS,x bne L0338 dec V$USRS,x L0338 clrb bra L02F5 IDelete pshs b ldb #$02 bra L02EC IDeletX ldb #$87 pshs b ldb $01,u bra L02EC * create path descriptor and initialize * Entry: * B = path mode L0349 pshs u ldx <D.PthDBT os9 F$All64 bcs L03A8 inc PD.CNT,y stb PD.MOD,y ldx R$X,u L0358 lda ,x+ cmpa #$20 beq L0358 leax -1,x stx R$X,u ldb PD.MOD,y cmpa #PDELIM beq L037E ldx <D.Proc bitb #PEXEC.+EXEC. beq L0373 ldx <P$DIO+6,x bra L0376 L0373 ldx <P$DIO,x L0376 beq L03AA ldx V$DESC,x ldd M$Name,x leax d,x L037E pshs y os9 F$PrsNam puls y bcs L03AA lda PD.MOD,y os9 I$Attach stu PD.DEV,y bcs L03AC ldx V$DESC,u leax <M$Opt,x ldb ,x+ leau <PD.DTP,y cmpb #$20 bls L03A4 ldb #$1F L03A0 lda ,x+ sta ,u+ L03A4 decb bpl L03A0 clrb L03A8 puls pc,u L03AA ldb #E$BPNam L03AC pshs b lda ,y ldx <D.PthDBT os9 F$Ret64 puls b coma bra L03A8 L03BA lda $01,u cmpa #$10 bcc L03CB ldx <D.Proc leax <$26,x andcc #^Carry lda a,x bne L03CE L03CB comb ldb #E$BPNum L03CE rts UISeek bsr L03BA bcc GetPDsc rts SISeek lda R$A,u GetPDsc bsr FindPDsc lbcc CallFMgr rts UIRead bsr L03BA bcc L03E4 rts SIRead lda R$A,u L03E4 pshs b ldb #$05 L03E8 bsr FindPDsc bcs L040B bitb $01,y beq L0409 ldd $06,u beq L03F8 addd $04,u bcs L03FD L03F8 puls b lbra CallFMgr L03FD ldb #$F4 lda ,s bita #$02 beq L040B ldb #$F5 bra L040B L0409 ldb #E$BMode L040B com ,s+ rts UIWrite bsr L03BA bcc L0415 rts SIWrite lda R$A,u L0415 pshs b ldb #$02 bra L03E8 * Find path descriptor of path passed in A * Entry: * A = path to find * Exit: * Y = addr of path desc (if no error) FindPDsc pshs x ldx <D.PthDBT os9 F$Find64 puls x lbcs L03CB L0428 rts UIGetStt lbsr L03BA bcc L0431 rts SIGetStt lda R$A,u L0431 pshs b,a lda R$B,u sta 1,s place in B on stack puls a get A bsr GetPDsc puls a A holds func code pshs b,cc ldb <PD.DTP,y cmpb #DT.NFM beq L044D tsta test func code beq GSOpt cmpa #SS.DevNm beq GSDevNm L044D puls pc,b,cc GSOpt leax <PD.DTP,y L0452 ldy R$X,u ldb #32 L0457 lda ,x+ copy 32 bytes from X to Y sta ,y+ decb bne L0457 leas 2,s fix stack clrb rts * get device name GSDevNm ldx PD.DEV,y ldx V$DESC,x ldd M$Name,x leax d,x bra L0452 UIClose lbsr L03BA bcs L0428 pshs b ldb R$A,u clr b,x puls b bra L047D SIClose lda R$A,u L047D bsr FindPDsc bcs L0428 dec PD.CNT,y tst PD.CPR,y bne L0489 bsr CallFMgr L0489 tst PD.CNT,y bne L0428 lbra L02F5 L0490 os9 F$IOQu comb ldb <P$Signal,x bne L04A4 L0499 ldx <D.Proc ldb P$ID,x clra lda PD.CPR,y bne L0490 stb PD.CPR,y L04A4 rts * B = entry point into FMgr * Y = path desc CallFMgr pshs u,y,x,b bsr L0499 bcs L04C1 stu PD.RGS,y lda <PD.DTP,y ldx PD.DEV,y ldx V$FMGR,x ldd M$Exec,x leax d,x ldb ,s subb #$83 subtract offset from B lda #$03 size of one entry mul compute jsr d,x branch into file manager L04C1 pshs b,cc bsr L04D9 ldy $05,s get path desc off stack lda <PD.DTP,y ldx <D.Proc lda P$ID,x cmpa PD.CPR,y bne L04D5 clr PD.CPR,y L04D5 puls b,cc puls pc,u,y,x,a L04D9 pshs y,x ldy <D.Proc lda <P$IOQN,y beq L04F3 clr <P$IOQN,y ldb #S$Wake os9 F$Send ldx <D.PrcDBT os9 F$Find64 clr <P$IOQP,y L04F3 clrb puls pc,y,x * IRQ install routine FIRQ ldx R$X,u ldb ,x B = flip byte ldx 1,x X = mask/priority clra pshs cc pshs x,b ldx <D.Init ldb PollCnt,x ldx <D.PolTbl ldy R$X,u beq RmvIRQEn tst 1,s mask byte beq L0572 decb dec poll table count lda #POLSIZ mul leax d,x point to last entry in table lda Q$MASK,x bne L0572 orcc #FIRQMask+IRQMask L051C ldb 2,s get priority byte cmpb -1,x compare with prev entry's prior bcs L052F ldb #POLSIZ else copy prev entry L0524 lda ,-x sta POLSIZ,x decb bne L0524 cmpx <D.PolTbl bhi L051C L052F ldd R$D,u get dev stat reg std Q$POLL,x save it ldd ,s++ get flip/mask sta Q$FLIP,x save flip stb Q$MASK,x save mask ldb ,s+ get priority stb Q$PRTY,x save priority ldd R$Y,u get IRQ svc addr std Q$SERV,x save ldd R$U,u get IRQ svc mem ptr std Q$STAT,x save puls pc,cc * remove IRQ poll entry RmvIRQEn leas 4,s clean stack ldy R$U,u L054C cmpy Q$STAT,x beq L0558 leax POLSIZ,x decb bne L054C clrb rts L0558 pshs b,cc orcc #FIRQMask+IRQMask bra L0565 L055E ldb POLSIZ,x stb ,x+ deca bne L055E L0565 lda #POLSIZ dec 1,s dec count bne L055E L056B clr ,x+ deca bne L056B puls pc,a,cc L0572 leas 4,s clean stack L0574 comb ldb #E$Poll rts * IRQ polling routine DPoll ldy <D.PolTbl ldx <D.Init ldb PollCnt,x bra L0586 L0581 leay POLSIZ,y decb beq L0574 L0586 lda [Q$POLL,y] eora Q$FLIP,y bita Q$MASK,y beq L0581 ldu Q$STAT,y pshs y,b jsr [<Q$SERV,y] puls y,b bcs L0581 rts * load a module FLoad pshs u ldx R$X,u bsr L05BC bcs L05BA inc $02,u increment link count ldy ,u get mod header addr ldu ,s get caller regs stx R$X,u sty R$U,u lda M$Type,y ldb M$Revs,y std R$D,u ldd M$Exec,y leax d,y stx R$Y,u L05BA puls pc,u L05BC lda #EXEC. os9 I$Open bcs L0632 leas -$0A,s make room on stack ldu #$0000 pshs u,y,x sta 6,s save path L05CC ldd 4,s get U (caller regs) from stack bne L05D2 stu 4,s L05D2 lda 6,s get path leax 7,s point to place on stack ldy #M$IDSize read M$IDSize bytes os9 I$Read bcs L061E ldd ,x cmpd #M$ID12 bne L061C ldd $09,s get module size os9 F$SRqMem allocate mem bcs L061E ldb #M$IDSize L05F0 lda ,x+ copy over first M$IDSize bytes sta ,u+ decb bne L05F0 lda $06,s get path leax ,u point X at updated U ldu $09,s get module size leay -M$IDSize,u subtract count os9 I$Read leax -M$IDSize,x bcs L060B os9 F$VModul validate module bcc L05CC L060B pshs u,b leau ,x point U at memory allocated ldd M$Size,x os9 F$SRtMem return mem puls u,b cmpb #E$KwnMod beq L05CC bra L061E L061C ldb #E$BMID L061E puls u,y,x lda ,s get path stb ,s save error code os9 I$Close close path ldb ,s leas $0A,s clear up stack cmpu #$0000 bne L0632 coma L0632 rts ErrHead fcc /ERROR #/ ErrNum equ *-ErrHead fcb $2F,$3A,$30,C$CR ErrLen equ *-ErrHead FPErr ldx <D.Proc lda <P$PATH+2,x get stderr path beq L0674 leas -ErrLen,s make room on stack * copy error message to stack leax <ErrHead,pcr leay ,s L064C lda ,x+ sta ,y+ cmpa #C$CR bne L064C ldb R$B,u get error # L0656 inc ErrNum+0,s subb #$64 bcc L0656 L065C dec ErrNum+1,s addb #$0A bcc L065C addb #$30 stb ErrNum+2,s ldx <D.Proc leax ,s point to error message ldu <D.Proc lda <P$PATH+2,u os9 I$WritLn write message leas ErrLen,s fix up stack L0674 rts FIOQu ldy <D.Proc L0678 lda <P$IOQN,y beq L06A0 cmpa R$A,u bne L0699 clr <P$IOQN,y ldx <D.PrcDBT os9 F$Find64 lbcs L070F clr <P$IOQP,y ldb #S$Wake os9 F$Send ldu <D.Proc bra L06AB L0699 ldx <D.PrcDBT os9 F$Find64 bcc L0678 L06A0 lda R$A,u ldu <D.Proc ldx <D.PrcDBT os9 F$Find64 bcs L070F L06AB leax ,y X = proc desc lda <P$IOQN,y beq L06D1 ldx <D.PrcDBT os9 F$Find64 bcs L070F ldb P$Age,u ifeq edition-11 * Note: the following line is a bug cmpd P$Age,y else cmpb P$Age,y endc bls L06AB ldb ,u stb <P$IOQN,x ldb P$ID,x stb <P$IOQP,u clr <P$IOQP,y exg y,u bra L06AB L06D1 lda P$ID,u sta <P$IOQN,y lda P$ID,y sta <P$IOQP,u ldx #$0000 os9 F$Sleep ldu <D.Proc lda <P$IOQP,u beq L070C ldx <D.PrcDBT os9 F$Find64 bcs L070C lda <P$IOQN,y beq L070C lda <P$IOQN,u sta <P$IOQN,y beq L070C clr <P$IOQN,u ldx <D.PrcDBT os9 F$Find64 bcs L070C lda <P$IOQP,u sta <P$IOQP,y L070C clr <P$IOQP,u L070F rts emod eom equ * end