Mercurial > hg > Members > kono > nitros9-code
view level1/modules/kernel.asm @ 1287:10957d54bf16
Made all modules rev 0
author | boisy |
---|---|
date | Sat, 30 Aug 2003 20:16:51 +0000 |
parents | 607fcc81c5ae |
children | bfb91dc51fb6 |
line wrap: on
line source
******************************************************************** * OS9p1 - OS-9 Level One V2 P1 module * * $Id$ * * This is how the memory map looks after the kernel has initialized: * * $0000----> ================================== * | | * | | * $0020-$0111 | System Globals (D.FMBM-D.XNMI) | * | | * | | * $0200---->|==================================| * | Free Memory Bitmap | * $0200-$0221 | (1 bit = 256 byte page) | * |----------------------------------| * | System Dispatch Table | * $0222-$0291 | (Room for 56 addresses) | * |----------------------------------| * $0292-$02FF | User Dispatch Table | * | (Room for 56 addresses) | * $0300---->|==================================| * | | * | | * $0300-$03FF | Module Directory Entries | * | (Room for 64 entries) | * | | * $0400---->|==================================| * | | * $0400-$04FF | System Stack | * | | * $0500---->|==================================| * * Edt/Rev YYYY/MM/DD Modified by * Comment * ------------------------------------------------------------------ * 14 1985/??/?? * From Tandy OS-9 Level One VR 02.00.00 * * 15 2002/07/21 Boisy G. Pitre * Module validation consists only of module header parity check. * CRC check is not done unless D.CRC is set to 1, which is NOT the * default case. By default, D.CRC is set to 0, thus there is no * CRC checking. Speeds up module loads quite a bit. The Init module * has a bit in a compatibility byte that can turn on/off CRC checking nam OS9 ttl OS-9 Level One V2 P1 module ifp1 use defsfile use scfdefs endc tylg set Systm+Objct atrv set ReEnt+rev rev set $00 edition set 15 L0000 mod eom,name,tylg,atrv,OS9Cold,size size equ . name fcs /OS9/ fcb edition fcc /CC/ InitNam fcs /INIT/ P2Nam fcs /OS9P2/ VectCode bra SWI3Jmp $0100 nop bra SWI2Jmp $0103 nop bra SWIJmp $0106 nop bra NMIJmp $0109 nop bra IRQJmp $010C nop bra FIRQJmp $010F SWI3Jmp jmp [>D.SWI3] SWI2Jmp jmp [>D.SWI2] SWIJmp jmp [>D.SWI] NMIJmp jmp [>D.NMI] IRQJmp jmp [>D.IRQ] FIRQJmp jmp [>D.FIRQ] VectCSz equ *-VectCode SysTbl fcb F$Link fdb FLink-*-2 fcb F$Fork fdb FFork-*-2 fcb F$Chain fdb FChain-*-2 fcb F$Chain+$80 fdb SFChain-*-2 fcb F$PrsNam fdb FPrsNam-*-2 fcb F$CmpNam fdb FCmpNam-*-2 fcb F$SchBit fdb FSchBit-*-2 fcb F$AllBit fdb FAllBit-*-2 fcb F$DelBit fdb FDelBit-*-2 fcb F$CRC fdb FCRC-*-2 fcb F$SRqMem+$80 fdb FSRqMem-*-2 fcb F$SRtMem+$80 fdb FSRtMem-*-2 fcb F$AProc+$80 fdb FAProc-*-2 fcb F$NProc+$80 fdb FNProc-*-2 fcb F$VModul+$80 fdb FVModul-*-2 fcb F$SSvc fdb FSSvc-*-2 fcb $80 * * OS-9 Genesis! OS9Cold equ * * clear out system globals from $0020-$0400 ldx #D.FMBM ldy #$400-D.FMBM clra clrb L007F std ,x++ leay -2,y bne L007F * set up system globals inca inca D = $200 std <D.FMBM $200 = start of free memory bitmap addb #$20 std <D.FMBM+2 $220 = end of free memory bitmap addb #$02 std <D.SysDis $222 = addr of sys dispatch tbl addb #$70 std <D.UsrDis $292 = addr of usr dispatch tbl clrb inca D = $300 std <D.ModDir $300 = mod dir start stx <D.ModDir+2 X = $400 = mod dir end leas >$0100,x S = $500 (system stack?) * Check for valid RAM starting at $400 ChkRAM leay ,x ldd ,y store org contents in D ldx #$00FF stx ,y write pattern to ,Y cmpx ,y same as what we wrote? bne L00C2 nope, not RAM here! ldx #$FF00 try different pattern stx ,y write it to ,Y cmpx ,y same as what we wrote? bne L00C2 nope, not RAM here! std ,y else restore org contents leax >$0100,y check top of next 256 block cmpx #BTStart stop short of boot track mem bcs ChkRAM leay ,x * Here, Y = end of RAM L00C2 leax ,y X = end of RAM stx <D.MLIM save off memory limit * Copy vector code over to address $100 pshs y,x leax >VectCode,pcr ldy #D.XSWI3 ldb #VectCSz L00D2 lda ,x+ sta ,y+ decb bne L00D2 puls y,x * validate modules at top of RAM (kernel, etc.) L00DB lbsr ValMod bcs L00E6 ldd M$Size,x leax d,x go past module bra L00EC L00E6 cmpb #E$KwnMod beq L00EE leax 1,x L00EC bne L00DB * copy vectors to system globals L00EE leay >Vectors,pcr leax >L0000,pcr pshs x ldx #D.SWI3 L00FB ldd ,y++ addd ,s std ,x++ cmpx #$0036 bls L00FB leas 2,s restore stack * fill in more system globals leax >URtoSs,pcr stx <D.URtoSs leax >UsrIRQ,pcr stx <D.UsrIRQ leax >UsrSvc,pcr stx <D.UsrSvc leax >SysIRQ,pcr stx <D.SysIRQ stx <D.SvcIRQ leax >SysSvc,pcr stx <D.SysSvc stx <D.SWI2 leax >Poll,pcr stx <D.Poll leax >Clock,pcr stx <D.Clock stx <D.AltIRQ * install system calls leay >SysTbl,pcr lbsr InstSSvc * link to init module lda #Systm+0 leax >InitNam,pcr os9 F$Link lbcs OS9Cold stu <D.Init lda Feature1,u get feature byte 1 bita #CRCOn CRC on? beq GetMem branch if not (already cleared earlier) inc <D.CRC else turn on CRC checking GetMem ldd MaxMem+1,u clrb cmpd <D.MLIM bcc L0158 std <D.MLIM L0158 ldx <D.FMBM ldb #$F8 stb ,x clra ldb <D.MLIM negb tfr d,y negb lbsr L065A * jump into OS9p2 here leax >P2Nam,pcr lda #Systm+Objct os9 F$Link lbcs OS9Cold jmp ,y SWI3 pshs pc,x,b ldb #P$SWI3 bra L018C SWI2 pshs pc,x,b ldb #P$SWI2 bra L018C DUMMY rti SVCIRQ jmp [>D.SvcIRQ] SWI pshs pc,x,b ldb #P$SWI L018C ldx >D.Proc ldx b,x get SWI entry stx 3,s put in PC on stack puls pc,x,b UsrIRQ leay <L01B1,pcr * transition from user to system state URtoSs clra tfr a,dp clear direct page ldx <D.Proc ldd <D.SysSvc std <D.SWI2 ldd <D.SysIRQ std <D.SvcIRQ leau ,s stu P$SP,x lda P$State,x ora #SysState sta P$State,x jmp ,y L01B1 jsr [>D.Poll] bcc L01BD ldb ,s orb #$10 stb ,s L01BD lbra L0255 SysIRQ clra tfr a,dp jsr [>D.Poll] bcc L01CF ldb ,s orb #$10 stb ,s L01CF rti Poll comb rts Clock ldx <D.SProcQ beq L01FD lda P$State,x bita #TimSleep beq L01FD ldu P$SP,x ldd P$SP,u subd #$0001 std P$SP,u bne L01FD L01E7 ldu P$Queue,x bsr L021A leax ,u beq L01FB lda P$State,x bita #TimSleep beq L01FB ldu P$SP,x ldd P$SP,u beq L01E7 L01FB stx <D.SProcQ L01FD dec <D.Slice bne ClockRTI lda <D.TSlice sta <D.Slice ldx <D.Proc beq ClockRTI lda P$State,x ora #TimOut sta P$State,x bpl L0212 branch if not system state ClockRTI rti L0212 leay >L0255,pcr bra URtoSs * X = proc desc FAProc ldx R$X,u L021A pshs u,y ldu #$003F bra L0228 L0221 ldb P$Age,u incb beq L0228 stb P$Age,u L0228 ldu P$Queue,u U = proc desc bne L0221 ldu #$003F lda P$Prior,x sta P$Age,x orcc #IntMasks L0235 leay ,u ldu P$Queue,u beq L023F cmpa P$Age,u bls L0235 L023F stu P$Queue,x stx P$Queue,y clrb puls pc,u,y UsrSvc leay <L024E,pcr orcc #IntMasks lbra URtoSs L024E andcc #^IntMasks ldy <D.UsrDis bsr L0278 L0255 ldx <D.Proc get current proc desc beq FNProc branch to FNProc if none orcc #IntMasks ldb P$State,x andb #^SysState stb P$State,x bitb #TimOut beq L02D1 andb #^TimOut stb P$State,x bsr L021A bra FNProc * system call entry SysSvc clra tfr a,dp set direct page to 0 leau ,s ldy <D.SysDis bsr L0278 rti L0278 pshs u ldx R$PC,u point X to PC ldb ,x+ get func code at X stx R$PC,u restore updated PC lslb multiply by 2 bcc L0288 branch if user call rorb ldx -2,y bra L0290 L0288 cmpb #$6E bcc L02A7 ldx b,y X = addr of system call beq L02A7 L0290 jsr ,x jsr into system call L0292 puls u tfr cc,a bcc FixCC branch if no error stb R$B,u store error code FixCC ldb R$CC,u get caller's CC andb #^(Negative+Zero+TwosOvfl+Carry) stb R$CC,u anda #Negative+Zero+TwosOvfl+Carry ora R$CC,u sta R$CC,u rts L02A7 comb ldb #E$UnkSvc bra L0292 * no signal handler, exit with signal value as exit code L02AC ldb P$State,x orb #SysState stb P$State,x ldb <P$Signal,x andcc #^(IntMasks) os9 F$Exit FNProc clra clrb std <D.Proc bra L02C2 * execution goes here when there are no active processes L02C0 cwai #^(IntMasks) L02C2 orcc #IntMasks ldx <D.AProcQ get next active process beq L02C0 CWAI if none ldd P$Queue,x get queue ptr std <D.AProcQ store in Active Q stx <D.Proc store in current process lds P$SP,x get process' stack ptr L02D1 ldb P$State,x get state bmi L0308 branch if system state bitb #Condem process condemned? bne L02AC branch if so... ldb <P$Signal,x get signal no beq L02FF branch if none decb decrement beq L02FC branch if wake up ldu <P$SigVec,x get signal handler addr beq L02AC branch if none ldy <P$SigDat,x get data addr ldd $06,s pshs u,y,b,a ldu $0A,s lda <P$Signal,x ldb $09,s tfr d,y ldd $06,s pshs u,y,b,a clrb L02FC stb <P$Signal,x L02FF ldd <P$SWI2,x std <D.SWI2 ldd <D.UsrIRQ std <D.SvcIRQ L0308 rti FLink pshs u save caller regs ldd R$A,u ldx R$X,u lbsr L0443 bcc FLinkOK ldb #E$MNF bra L033D * U = module dir entry FLinkOK ldy ,u get module ptr ldb M$Revs,y bitb #ReEnt reentrant? bne L032A branch if so tst $02,u link count zero? beq L032A yep, ok to link to nonreent comb else module is busy ldb #E$ModBsy bra L033D L032A inc $02,u increment link count ldu ,s get caller regs from stack stx R$X,u sty R$U,u ldd M$Type,y std R$D,u ldd M$IDSize,y leax d,y stx R$Y,u L033D puls pc,u FVModul pshs u ldx R$X,u bsr ValMod puls y stu R$U,y rts * X = address of module to validate ValMod bsr ChkMHCRC bcs L039A lda M$Type,x pshs x,a ldd M$Name,x leax d,x X = addr of name in mod puls a lbsr L0443 puls x bcs L039B ldb #E$KwnMod cmpx ,u beq L03A1 lda M$Revs,x anda #RevsMask pshs a ldy ,u lda M$Revs,y anda #RevsMask cmpa ,s+ same revision as other mod? bcc L03A1 pshs y,x ldb M$Size,u bne L0395 ldx ,u cmpx <D.BTLO bcc L0395 ldd $02,x addd #$00FF tfr a,b clra tfr d,y ldb ,u ldx <D.FMBM os9 F$DelBit clr $02,u L0395 puls y,x L0397 stx ,u clrb L039A rts L039B leay ,u bne L0397 ldb #E$DirFul L03A1 coma rts * check module header and CRC * X = address of potential module ChkMHCRC ldd ,x cmpd #M$ID12 sync bytes? bne L03B1 nope, not a module here leay M$Parity,x bsr ChkMHPar check header parity bcc L03B5 branch if ok L03B1 comb ldb #E$BMID rts L03B5 * Following 4 lines added to support no CRC checks - 2002/07/21 lda <D.CRC is CRC checking on? bne DoCRCCk branch if so clrb rts DoCRCCk pshs x ldy M$Size,x bsr ChkMCRC checkm module CRC puls pc,x * check module header parity * Y = pointer to parity byte ChkMHPar pshs y,x clra ChkM010 eora ,x+ cmpx 2,s compare to addr of M$Parity bls ChkM010 cmpa #$FF puls pc,y,x * X = address of potential module * Y = size of module ChkMCRC ldd #$FFFF pshs b,a pshs b,a leau 1,s L03D4 lda ,x+ bsr CRCAlgo leay -1,y dec Y (size of module) bne L03D4 continue clr -1,u lda ,u cmpa #CRCCon1 bne L03EC ldd 1,u cmpd #CRCCon23 beq L03EF L03EC comb ldb #E$BMCRC L03EF puls pc,y,x * F$CRC FCRC ldx R$X,u ldy R$Y,u beq L0402 ldu R$U,u L03FA lda ,x+ bsr CRCAlgo leay -1,y bne L03FA L0402 clrb rts CRCAlgo eora ,u pshs a ldd $01,u std ,u clra ldb ,s lslb rola eora 1,u std 1,u clrb lda ,s lsra rorb lsra rorb eora 1,u eorb 2,u std 1,u lda ,s lsla eora ,s sta ,s lsla lsla eora ,s sta ,s lsla lsla lsla lsla eora ,s+ bpl L0442 ldd #$8021 eora ,u sta ,u eorb 2,u stb 2,u L0442 rts L0443 ldu #$0000 tfr a,b anda #TypeMask andb #LangMask pshs u,y,x,b,a bsr EatSpace cmpa #PDELIM pathlist char? beq L049C branch if so lbsr L074D parse name bcs L049D return if error ldu <D.ModDir L045B pshs u,y,b ldu ,u beq L048B ldd $04,u leay d,u ldb ,s lbsr L07AB bcs L0493 lda $05,s beq L0476 eora $06,u anda #$F0 bne L0493 L0476 lda $06,s beq L0480 eora $06,u anda #$0F bne L0493 L0480 puls u,x,b stu $06,s bsr EatSpace stx $02,s clra bra L049D L048B ldd $0B,s bne L0493 ldd $03,s std $0B,s L0493 puls u,y,b leau $04,u cmpu <D.ModDir+2 bcs L045B L049C comb L049D puls pc,u,y,x,b,a EatSpace lda #C$SPAC EatSpc10 cmpa ,x+ beq EatSpc10 lda ,-x rts FFork ldx <D.PrcDBT os9 F$All64 bcs L0517 ldx <D.Proc pshs x save calling proc desc on stack ldd P$User,x std P$User,y lda P$Prior,x clrb std P$Prior,y ldb #SysState stb P$State,y sty <D.Proc ldd <P$NIO,x std <P$NIO,y ldd <P$NIO+2,x std <P$NIO+2,y leax <P$DIO,x leay <P$DIO,y ldb #DefIOSiz * copy I/O stuff from parent to child L04D7 lda ,x+ sta ,y+ decb bne L04D7 * X/Y = address of path table in respective proc desc * Dup stdin/stdout/stderr ldb #$03 L04E0 lda ,x+ os9 I$Dup bcc L04E8 clra L04E8 sta ,y+ decb bne L04E0 bsr L0553 bcs L050C puls y get parent proc desc sty <D.Proc lda P$ID,x get ID of new process sta R$A,u store in caller's A ldb P$CID,y get child id of parent sta P$CID,y store new proc in parent's CID lda P$ID,y get ID of parent std P$PID,x store in child proc desc ldb P$State,x update state of child andb #^SysState stb P$State,x os9 F$AProc insert child in active Q rts L050C pshs b os9 F$Exit comb puls x,b stx <D.Proc rts L0517 comb ldb #E$PrcFul rts FChain bsr L0543 bcs L0531 orcc #IntMasks ldb $0D,x andb #$7F stb $0D,x L0527 os9 F$AProc os9 F$NProc SFChain bsr L0543 bcc L0527 L0531 pshs b stb <P$Signal,x ldb P$State,x orb #Condem stb P$State,x ldb #$FF stb P$Prior,x comb puls pc,b L0543 pshs u ldx <D.Proc ldu <P$PModul,x os9 F$UnLink ldu ,s bsr L0553 puls pc,u L0553 ldx <D.Proc pshs u,x ldd <D.UsrSvc std <P$SWI,x std <P$SWI2,x std <P$SWI3,x clra clrb sta <P$Signal,x std <P$SigVec,x lda R$A,u ldx R$X,u os9 F$Link bcc L0578 os9 F$Load bcs L05E7 L0578 ldy <D.Proc stu <P$PModul,y cmpa #Prgrm+Objct beq L058B cmpa #Systm+Objct beq L058B comb ldb #E$NEMod bra L05E7 L058B leay ,u Y = addr of module ldu 2,s get U off stack (caller regs) stx R$X,u lda R$B,u clrb cmpd M$Mem,y compare passed mem to module's bcc L059B branch if less than ldd M$Mem,y L059B addd #$0000 bne L05A0 L05A0 os9 F$Mem bcs L05E7 subd #R$Size subtract registers subd R$Y,u subtract parameter area bcs L05E5 ldx R$U,u get parameter area ldd R$Y,u get parameter size pshs b,a beq L05BE leax d,x point to end of param area L05B6 lda ,-x get byte, dec X sta ,-y save byte in data area, dec X cmpx R$U,u at top of param area? bhi L05B6 * set up registers for return of F$Fork/F$Chain L05BE ldx <D.Proc sty -$08,y put in X on caller stack leay -R$Size,y back up register size sty P$SP,x lda P$ADDR,x clrb std R$U,y lowest address sta R$DP,y set direct page adda P$PagCnt,x std R$Y,y puls b,a std R$D,y size of param area ldb #Entire stb R$CC,y ldu <P$PModul,x get addr of prim. mod ldd M$Exec,u leau d,u stu R$PC,y put in PC on caller reg clrb L05E5 ldb #E$IForkP L05E7 puls pc,u,x FSRqMem ldd R$D,u addd #$00FF clrb std R$D,u ldx <D.FMBM+2 ldd #$01FF pshs b,a bra L0604 L05FA dec $01,s ldb $01,s L05FE lsl ,s bcc L060A rol ,s L0604 leax -1,x cmpx <D.FMBM bcs L0620 L060A lda ,x anda ,s bne L05FA dec 1,s subb 1,s cmpb 1,u rora addb 1,s rola bcs L05FE ldb 1,s clra incb L0620 leas 2,s bcs L0635 ldx <D.FMBM tfr d,y ldb 1,u clra exg d,y bsr L065A exg a,b std 8,u L0633 clra rts L0635 comb ldb #E$MemFul rts FSRtMem ldd R$D,u addd #$00FF tfr a,b clra tfr d,y ldd R$U,u beq L0633 tstb beq L064E comb ldb #E$BPAddr rts L064E exg a,b ldx <D.FMBM bra L06AD FAllBit ldd R$D,u leau R$X,u pulu y,x L065A pshs y,x,b,a bsr L0690 tsta pshs a bmi L0671 lda ,x L0665 ora ,s leay -1,y beq L0689 lsr ,s bcc L0665 sta ,x+ L0671 tfr y,d sta ,s lda #$FF bra L067B L0679 sta ,x+ L067B subb #$08 bcc L0679 dec ,s bpl L0679 L0683 lsla incb bne L0683 ora ,x L0689 sta ,x clra leas 1,s puls pc,y,x,b,a L0690 pshs b lsra rorb lsra rorb lsra rorb leax d,x puls b lda #$80 andb #$07 beq L06A6 L06A2 lsra decb bne L06A2 L06A6 rts FDelBit ldd R$D,u leau R$X,u pulu y,x L06AD pshs y,x,b,a bsr L0690 coma pshs a bpl L06C4 lda ,x L06B8 anda ,s leay -1,y beq L06D8 asr ,s bcs L06B8 sta ,x+ L06C4 tfr y,d bra L06CA L06C8 clr ,x+ L06CA subd #$0008 bhi L06C8 beq L06D8 L06D1 lsla incb bne L06D1 coma anda ,x L06D8 sta ,x clr ,s+ puls pc,y,x,b,a FSchBit pshs u ldd R$D,u ldx R$X,u ldy R$Y,u ldu R$U,u bsr L06F3 puls u std R$D,u sty R$Y,u rts L06F3 pshs u,y,x,b,a pshs y,b,a clr 8,s clr 9,s tfr d,y bsr L0690 pshs a bra L0710 L0703 leay $01,y sty $05,s L0708 lsr ,s bcc L0714 ror ,s leax $01,x L0710 cmpx $0B,s bcc L0732 L0714 lda ,x anda ,s bne L0703 leay $01,y tfr y,d subd $05,s cmpd $03,s bcc L0739 cmpd $09,s bls L0708 std $09,s ldd $05,s std $01,s bra L0708 L0732 ldd $01,s std $05,s coma bra L073B L0739 std $09,s L073B leas $05,s puls pc,u,y,x,b,a FPrsNam ldx R$X,u bsr L074D std R$D,u bcs L0749 stx R$X,u L0749 sty R$Y,u rts L074D lda ,x cmpa #PDELIM pathlist char? bne L0755 branch if not leax 1,x go past pathlist char L0755 leay ,x clrb lda ,y+ anda #$7F bsr L0792 bcs L0772 L0760 incb lda -1,y bmi L076F hi bit set on this char, done lda ,y+ anda #$7F bsr IllChar bcc L0760 lda ,-y L076F andcc #^Carry rts L0772 cmpa #C$COMA comma? bne L0778 L0776 lda ,y+ L0778 cmpa #C$SPAC space? beq L0776 lda ,-y comb ldb #E$BNam rts * check for illegal characters in a pathlist IllChar cmpa #C$PERD period? beq L07C9 branch if so cmpa #'0 zero? bcs L07A2 branch if less than cmpa #'9 number? bls L07C9 branch if lower/same cmpa #'_ underscore? beq L07C9 branch if so L0792 cmpa #'A A? bcs L07A2 branch if less than cmpa #'Z Z? bls L07C9 branch if less or equal cmpa #'a a? bcs L07A2 branch if lower cmpa #'z z? bls L07C9 branch if less or equal L07A2 orcc #Carry rts FCmpNam ldb R$B,u leau R$X,u pulu y,x L07AB pshs y,x,b,a L07AD lda ,y+ bmi L07BE decb beq L07BA eora ,x+ anda #$DF beq L07AD L07BA orcc #Carry puls pc,y,x,b,a L07BE decb bne L07BA eora ,x anda #$5F bne L07BA puls y,x,b,a L07C9 andcc #^Carry rts FSSvc ldy R$Y,u bra InstSSvc SSvcLoop tfr b,a put syscall code in A anda #$7F kill hi bit cmpa #$7F is code $7F? beq SSvcOK cmpa #$37 compare against highest call allowed bcs SSvcOK branch if A less than highest call comb ldb #E$ISWI rts SSvcOK lslb ldu <D.SysDis leau b,u U points to entry in table ldd ,y++ get addr of func leax d,y get absolute addr stx ,u store in system table bcs InstSSvc branch if system only stx <$70,u else store in user table too InstSSvc ldb ,y+ get system call code in B cmpb #$80 end of table? bne SSvcLoop branch if not rts emod eom equ * fdb Clock Vectors fdb SWI3 SWI3 fdb SWI2 SWI2 fdb DUMMY FIRQ fdb SVCIRQ IRQ fdb SWI SWI fdb DUMMY NMI end