Mercurial > hg > Members > kono > nitros9-code
changeset 2615:530759e9f289
Added ccbkrn from Brett Gordon (level 2 only for now)
author | Boisy Pitre <boisy.pitre@nuance.com> |
---|---|
date | Mon, 06 Feb 2012 15:51:13 -0600 |
parents | d9e5c4629696 |
children | b9e8bb5a3796 |
files | level2/coco3/makefile_common level2/coco3/modules/kernel/makefile level2/coco3/modules/makefile level2/modules/kernel/ccbfsrqmem.asm level2/modules/kernel/ccbkrn.asm level2/modules/kernel/ccbkrn.txt level2/modules/kernel/fnproc.asm |
diffstat | 7 files changed, 1647 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/level2/coco3/makefile_common Sun Feb 05 13:30:35 2012 -0600 +++ b/level2/coco3/makefile_common Mon Feb 06 15:51:13 2012 -0600 @@ -37,6 +37,7 @@ STARTUP = startup STARTUP_DW = startup.dw SYSGO = sysgo_dd +CCBKRN = ccbkrn PACKAGENAME = $(DISTROVER).zip DSKDW3 = $(DISTROVER)_dw3.dsk @@ -95,6 +96,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS_DW) ../$@,CMDS @@ -148,6 +150,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS_DW) ../$@,CMDS @@ -201,6 +204,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS_DW) ../$@,CMDS @@ -254,6 +258,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS) ../$@,CMDS @@ -276,6 +281,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS) ../$@,CMDS @@ -338,6 +344,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS) ../$@,CMDS @@ -393,6 +400,7 @@ $(MAKDIR) $@,CMDS $(MAKDIR) $@,SYS $(MAKDIR) $@,DEFS + $(CP) modules/$(CCBKRN) $@,$(CCBKRN) $(CP) modules/$(SYSGO) $@,sysgo $(OS9ATTR_EXEC) $@,sysgo $(CD) cmds; $(CP) $(CMDS) ../$@,CMDS
--- a/level2/coco3/modules/kernel/makefile Sun Feb 05 13:30:35 2012 -0600 +++ b/level2/coco3/modules/kernel/makefile Mon Feb 06 15:51:13 2012 -0600 @@ -7,22 +7,25 @@ AFLAGS += -I$(LEVEL2)/modules/kernel -I$(LEVEL1)/modules/kernel KERNEL = krn +KERNEL_CCB = ccbkrn KERNELP2 = krnp2 SYSCALLS = fallimg.asm fallram.asm falltsk.asm faproc.asm fcmpnam.asm \ fcpymem.asm fdatlog.asm fdelram.asm ffmodul.asm ffreehb.asm \ fld.asm fldabx.asm flink.asm fmove.asm fnproc.asm fprsnam.asm \ - freboot.asm fsrqmem.asm fssvc.asm fvmodul.asm \ + freboot.asm fssvc.asm fvmodul.asm \ fallbit.asm fallprc.asm fchain.asm fclrblk.asm fcrcmod.asm \ fdelimg.asm fexit.asm ffind64.asm ffork.asm fgblkmp.asm \ fgcmdir.asm fgmoddr.asm fgprdsc.asm fgprocp.asm ficpt.asm \ fid.asm fmapblk.asm fmem.asm fsend.asm fsleep.asm fsprior.asm \ fsswi.asm fstime.asm fsuser.asm funlink.asm funload.asm -ALLOBJS = $(KERNEL) $(KERNELP2) +ALLOBJS = $(KERNEL) $(KERNEL_CCB) $(KERNELP2) all: $(ALLOBJS) -$(KERNEL): krn.asm $(SYSCALLS) +$(KERNEL): krn.asm $(SYSCALLS) fsrqmem.asm + +$(KERNEL_CCB): ccbkrn.asm $(SYSCALLS) ccbfsrqmem.asm $(KERNELP2): krnp2.asm $(SYSCALLS)
--- a/level2/coco3/modules/makefile Sun Feb 05 13:30:35 2012 -0600 +++ b/level2/coco3/modules/makefile Mon Feb 06 15:51:13 2012 -0600 @@ -87,7 +87,7 @@ all: $(ALLOBJS) # Kernel -krn krnp2: +ccbkrn krn krnp2: $(CD) kernel; make $@ $(CP) kernel/$@ .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level2/modules/kernel/ccbfsrqmem.asm Mon Feb 06 15:51:13 2012 -0600 @@ -0,0 +1,368 @@ +************************************************** +* System Call: F$SRqMem +* +* Function: Request memory +* +* F$SRqMem allocates memory from the system's 64K address space in 256 byte 'pages.' +* There are 256 of these '256 byte pages' in the system's RAM area (256*256=64K). +* The allocation map, pointed to by D.SysMem holds one byte per page, making the +* allocation map itself 256 bytes in size. +* +* Memory is allocated from the top of the system RAM map downwards. Rel/Boot/Krn +* also reside in this area, and are loaded from $ED00-$FFFF. Since this area is +* always allocated, we start searching for free pages from page $EC downward. +* +* F$SRqMem also updates the system memory map according to 8K DAT blocks. If an +* empty block is found, this routine re-does the 32 entries in the SMAP table to +* indicate that they are free. +* +* Input: D = Byte count +* +* Output: U = Address of allocated memory area +* +* Error: CC = C bit set; B = error code +* +FSRqMem ldd R$D,u get memory allocation size requested + addd #$00FF round it up to nearest 256 byte page (e.g. $1FF = $2FE) + clrb just keep # of pages (and start 8K block #, e.g. $2FE = $200) + std R$D,u save rounded version back to user +* leay Bt.Start/256,y +* leay $20,y skip Block 0 (always reserved for system) +* Change to pshs a,b:use 1,s for block # to check, and ,s for TFM spot +* incb skip block 0 (always reserved for system) + pshs d reserve a byte & put 0 byte on stack + + +* IMPORTANT!!! +* The following code was put in some time back to fix a problem. That problem was not documented +* so I cannot recall why this code was in place. What it appears to do is reset the system page +* memory map based upon the state of the system DAT image. +* This code really slows down F$SRqMem and since that system call is used quite often in the system, +* I am commenting it out in the hopes that I can remember what the hell I put it in for. -- Boisy + IFEQ 1 + ldy <D.SysMem get ptr to SMAP table +* This loop updates the SMAP table if anything can be marked as unused +L082F ldx <D.SysDAT get pointer to system DAT block list + lslb adjust block offset for 2 bytes/entry + ldd b,x get block type/# from system DAT + cmpd #DAT.Free Unused block? + beq L0847 yes, mark it free in SMAP table + ldx <D.BlkMap No, get ptr to MMAP table + lda d,x Get block marker for 2 meg mem map + cmpa #RAMinUse Is it in use (not free, ROM or used by module)? + bne L0848 No, mark it as type it is in SMAP table + leay 32,y Yes, move to next block in pages + bra L084F move to next block & try again +* Free RAM: +L0847 clra Byte to fill system page map with (0=Not in use) +* NOT! RAMinUse: + IFNE H6309 +L0848 sta ,s Put it on stack + ldw #$0020 Get size of 8K block in pages + tfm s,y+ Mark entire block's worth of pages with A + ELSE +L0848 ldb #32 count = 32 pages +L084A sta ,y+ mark the RAM + decb + bne L084A + ENDC +L084F inc 1,s Bump up to next block to check + ldb 1,s Get it + cmpb #DAT.BlCt Done whole 64k system space? + blo L082F no, keep checking + ENDC + + +* Now we can actually attempt to allocate the system RAM requested +* NOTE: Opt for CoCo/TC9 OS9 ONLY: skip last 256 - Bt.Start pages since +* they are: Kernel (REL/BOOT/KRN - 17 pages), vector RAM & I/O (2 pages) +* (Already permanently marked @ L01D2) +* At the start, Y is pointing to the end of the SMAP table+1 + ldx <D.SysMem Get start of table ptr + * CCB change - start scanning from f000 down, rather than ec00 + * leay Bt.Start>>8,x +* leay Where>>8,x + leay $ff00>>8,x + * end of CCB change + ldb #32 skip block 0: it's always full + abx same size, but faster than leax $20,x +* leay -(256-(Bt.Start>>8)),y skip Kernel, Vector RAM & I/O (Can't be free) +L0857 ldb R$A,u Get # 256 byte pages requested +* Loop (from end of system mem map) to look for # continuous pages requested +L0859 equ * + IFNE H6309 + cmpr x,y We still have any system RAM left to try? + ELSE + pshs x + cmpy ,s++ + ENDC + bhi L0863 Yes, continue + comb Exit with No System RAM Error + ldb #E$NoRAM + bra L0894 Eat stack & exit + +L0863 lda ,-y Get page marker (starting @ end of SMAP) + bne L0857 Used, try next lower page + decb Found 1 page, dec # pages we need to allocate + bne L0859 Still more pages needed, check if we can get more + sty ,s Found free contiguous pages, save SMAP entry ptr + lda 1,s Get LSB of ptr + lsra Divide by 32 (Calculate start 8K block #) + lsra + lsra + lsra + lsra + ldb 1,s Get LSB of ptr again + andb #%00011111 Keep only within 8K block offset + addb R$A,u Add # pages requested + addb #$1F Round up to nearest 8K block + lsrb Divide by 32 (Calculate end 8K block #) + lsrb + lsrb + lsrb + lsrb + ldx <D.SysPrc Get ptr to system proc. dsc. + lbsr L09BE Allocate an image with our start/end block #'s + bcs L0894 Couldn't, exit with error + ldb R$A,u Get # pages requested +* lda #RAMinUse Get SMAP in use flag +*L088A sta ,y+ Mark all the pages requested as In Use +L088A inc ,y+ Since RAMinUse is 1, we can save space by INC'ing from 0->1 + decb + bne L088A + lda 1,s Get MSB of ptr to start of newly allocated Sys RAM + std R$U,u Save for caller + clrb No error +L0894 puls u,pc Eat stack (U is changed after it exits) & return + + +************************************************** +* System Call: F$SRtMem +* +* Function: Return memory +* +* Input: U = Address of memory to return +* D = Number of bytes to return +* +* Output: None +* +* Error: CC = C bit set; B = error code +* +FSRtMem ldd R$D,u get # pages to free up + beq L08F2 nothing to free, return without error + addd #$00FF round it up to nearest page + ldb R$U+1,u get LSB of address + beq L08A6 it's a even page, skip ahead + comb set carry + ldb #E$BPAddr get error code + rts return + +L08A6 ldb R$U,u get MSB of page address + beq L08F2 not a legal page, return without error + ldx <D.SysMem get pointer to system memory map + abx set pointer into map +L08AD equ * + IFNE H6309 + aim #^RAMinUse,,x+ + ELSE + ldb ,x + andb #^RAMinUse + stb ,x+ + ENDC + deca + bne L08AD +* Scan DAT image to find memory blocks to free up + ldx <D.SysDAT get pointer to system DAT image + IFNE H6309 + lde #DAT.BlCt get # blocks to check + ELSE + ldy #DAT.BlCt + ENDC +L08BC ldd ,x get block image + cmpd #DAT.Free is it already free? + beq L08EC yes, skip to next one + ldu <D.BlkMap get pointer to MMU block map + lda d,u get allocation flag for this block: 16-bit offset + cmpa #RAMinUse being used? + bne L08EC no, move to next block + tfr x,d + subd <D.SysDAT + lslb + lslb + lslb + lslb + ldu <D.SysMem get pointer to system map + IFNE H6309 + addr d,u +* Check if we can remove the entire memory block from system map + ldf #16 get # pages per block/2 +L08DA ldd ,u++ Either of these 2 pages allocated? + ELSE + leau d,u + ldb #32 +L08DA lda ,u+ Either of these 2 pages allocated? + ENDC + bne L08EC yes, can't free block, skip to next one + IFNE H6309 + decf checked all pages? + ELSE + decb + ENDC + bne L08DA no, keep looking + ldd ,x get block # into B: could be >$80 + ldu <D.BlkMap point to allocation table + IFNE H6309 + sta d,u clear the block using 16-bit offset + ELSE + clr d,u + ENDC + ldd #DAT.Free get free block marker + std ,x save it into DAT image +L08EC leax 2,x move to next DAT block + IFNE H6309 + dece done? + ELSE + leay -1,y + ENDC + bne L08BC no, keep checking +L08F2 clrb clear errors +L08F3 rts return + + +************************************************** +* System Call: F$Boot +* +* Function: Bootstrap the system +* +* Optimized for size, as it's only called once... +* +* Input: None +* +* Output: None +* +* Error: CC = C bit set; B = error code +* +FBoot + ** CCB change: just panic + lda #'t tried to boot + jsr <D.BtBug + jmp <D.Crash + ** + coma Set boot flag + lda <D.Boot we booted once before? + bne L08F3 Yes, return + inc <D.Boot Set boot flag + ldx <D.Init Get ptr to init module if it exists + beq L0908 it doesn't, point to boot name + ldd <BootStr,x Get offset to text + beq L0908 Doesn't exist, get hard coded text + leax d,x Adjust X to point to boot module + bra L090C Try & link to module + +boot fcs /Boot/ + +L0908 leax <boot,pcr +* Link to module and execute +L090C lda #Systm+Objct + os9 F$Link + bcs L08F3 + lda #'b calling boot + jsr <D.BtBug + jsr ,y load boot file + bcs L08F3 + std <D.BtSz save boot file size + stx <D.BtPtr save start pointer of bootfile + lda #'b boot returns OK + jsr <D.BtBug + +* added for IOMan system memory extentions + IFNE H6309 + ldd M$Name,x grab the name offset + ldd d,x find the first 2 bytes of the first module + cmpd #$4E69 'Ni' ? (NitrOS9 module?) + bne not.ext no, not system memory extensions + ldd M$Exec,x grab the execution ptr + jmp d,x and go execute the system memory extension module + ENDC + +not.ext ldd <D.BtSz + bsr I.VBlock internal verify block routine + ldx <D.SysDAT get system DAT pointer + ldb $0D,x get highest allocated block number + incb allocate block 0, too + ldx <D.BlkMap point to the memory block map + lbra L01DF and go mark the blocks as used. + + +************************************************** +* System Call: F$VBlock +* +* Function: ??? +* +* Input: D = Size of block to verify +* X = Start address to verify +* +* Output: None +* +* Error: CC = C bit set; B = error code +* +FVBlock ldd R$D,u size of block to verify + ldx R$X,u start address to verify + +I.VBlock leau d,x point to end of bootfile + tfr x,d transfer start of block to D + anda #$E0 + clrb D is now block number + pshs d,u save starting block and end of block + lsra + lsra + lsra + lsra A is now logical block * 2 + ldy <D.SysDAT get pointer to system DAT + leay a,y y is pointer of sys block map of start of block +L092D ldd M$ID,x get module ID + cmpd #M$ID12 legal ID? + bne L0954 no, keep looking + + ldd M$Name,x find name offset pointer + pshs x + leax d,x +name.prt lda ,x+ get first character of the name + jsr <D.BtBug print it out + bpl name.prt + lda #C$SPAC a space + jsr <D.BtBug + puls x + + IFNE H6309 + ldd ,s offset into block + subr d,x make X=offset into block + ELSE + tfr x,d + subd ,s + tfr d,x + ENDC + tfr y,d + os9 F$VModul + IFNE H6309 + ldw ,s + leax w,x + ELSE + pshs b + ldd 1,s + leax d,x + puls b + ENDC + bcc L094E + cmpb #E$KwnMod + bne L0954 +L094E ldd M$Size,x + leax d,x + fcb $8C skip 2 bytes + +L0954 leax 1,x move to next byte +L0956 cmpx 2,s gone thru whole bootfile? + bcs L092D no, keep looking + leas 4,s purge stack + clrb + rts
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level2/modules/kernel/ccbkrn.asm Mon Feb 06 15:51:13 2012 -0600 @@ -0,0 +1,1121 @@ +******************************************************************** +* krn - NitrOS-9 Level 2 Kernel +* +* $Id: krn.asm,v 1.29 2010/05/20 16:35:47 boisy Exp $ +* +* Edt/Rev YYYY/MM/DD Modified by +* Comment +* ------------------------------------------------------------------ +* 19r6 2002/08/21 Boisy G. Pitre +* Assembles to the os9p1 module that works on my NitrOS-9 system. +* +* 19r7 2002/09/26 Boisy G. Pitre +* Added check for CRC feature bit in init module +* +* 19r8 2003/09/22 Boisy G. Pitre +* Back-ported to OS-9 Level Two. +* +* 19r8 2004/05/22 Boisy G. Pitre +* Renamed to 'krn' +* +* 19r9 2004/07/12 Boisy G. Pitre +* F$SRqMem now properly scans the DAT images of the system to update +* the D.SysMem map. + + nam krn + ttl NitrOS-9 Level 2 Kernel + + IFP1 + use defsfile + ENDC + +* defines for customizations +Revision set 9 module revision +Edition set 19 module Edition +Where equ $F000 absolute address of where Kernel starts in memory + + mod eom,MName,Systm,ReEnt+Revision,entry,0 + + * CCB Change: module name changes to CCBKrn +MName fcs /CCBKrn/ + fcb Edition + + * CCB Change: added a automagic "fill" directive + * between the end of the kernel module, proper, and the fe page code + * see way down. Manually refilling the empty space after each + * code change was a pain and error prone. BG + +* FILL - all unused bytes are now here +* fcc /www.nitros9.org / +* fcc /www.nitros9.org / +* fcc /www.ni/ +* fcc /w/ +* fcc /w/ +* fcc /w/ +* IFNE H6309 +* fcc /www.nitros9.org / +* fcc /www.nitros9.org / +* fcc /www/ +* ELSE +* fcc /www.nit/ +* ENDC + +* Might as well have this here as just past the end of Kernel... +DisTable + fdb L0CD2+Where D.Clock absolute address at the start + fdb XSWI3+Where D.XSWI3 + fdb XSWI2+Where D.XSWI2 + fdb D.Crash D.XFIRQ crash on an FIRQ + fdb XIRQ+Where D.XIRQ + fdb XSWI+Where D.XSWI + fdb D.Crash D.XNMI crash on an NMI + fdb $0055 D.ErrRst ??? Not used as far as I can tell + fdb Sys.Vec+Where Initial Kernel system call vector +DisSize equ *-DisTable +* DO NOT ADD ANYTHING BETWEEN THESE 2 TABLES: see code using 'SubSiz', below +LowSub equ $0160 start of low memory subroutines +SubStrt equ * +* D.Flip0 - switch to system task 0 +R.Flip0 equ * + IFNE H6309 + aim #$FE,<D.TINIT map type 0 + lde <D.TINIT another 2 bytes saved if GRFDRV does: tfr cc,e + ste >DAT.Task and we can use A here, instead of E + ELSE + pshs a + lda <D.TINIT + anda #$FE + sta <D.TINIT + sta >DAT.Task + puls a + ENDC + clr <D.SSTskN + tfr x,s + tfr a,cc + rts +SubSiz equ *-SubStrt +* Don't add any code here: See L0065, below. +* Interrupt service routine +Vectors jmp [<-(D.SWI3-D.XSWI3),x] (-$10) (Jmp to 2ndary vector) + +* Let's start by initializing system page +entry equ * + * CCB Addition - save stacked OS9Boot size and make a dummy kernel printer + pulu d pull boot file size from CoCoBoot and + std <D.BtSz save to direct page for later use + inc <D.Boot mark boot attempted flag + inc <D.Speed mark high speed + lds #$1fff reset system stack (s/b 0x2000 ?!?!) + lda #$7e put code in DP so rest of kernel can + sta <D.BtBug call kernel printing routine + leax BtDebug,pc + stx <D.BtBug+1 + sta <D.Crash and do the same with the kernel crash + leax Crash,pc code + stx <D.Crash+1 + bra CCBEND jump over new kprint & crash routines + + * This is a kernel print routine + * This is added to replace the same routine found in "rel.asm" + * so we get debug output. + * Takes A - charactor to print + * modifies - nothing +BtDebug pshs cc,d,x save the register + orcc #IntMasks turn IRQ's off + ldb #$3b block to map in + stb >$FFA0 map the boot screen into block 0 + ldx >$0002 where to put the bytes + sta ,x+ put the character on-screen + stx >$0002 save updated address + clr >$FFA0 map block 0 in again + puls cc,d,x,pc restore and return + * This routine just prints "!" and loops forever +Crash lda #'! print a "!" + jsr <D.BtBug +e bra e loop forever +CCBEND + * end of CCB Addition + + * This code clears the rest of the low block + * rel.asm/cocoboot has cleared the DP already. + IFNE H6309 + ldq #$01001f00 start address to clear & # bytes to clear + leay <entry+2,pc point to a 0 + tfm y,d+ + std <D.CCStk set pointer to top of global memory to $2000 + lda #$01 set task user table to $0100 + ELSE + ldx #$100 + ldy #$2000-$100 + clra + clrb +L001C std ,x++ + leay -2,y + bne L001C + stx <D.CCStk Set pointer to top of global memory to $2000 + inca D = $0100 + ENDC + +* Setup system direct page variables + std <D.Tasks set Task Structure pointer to 0x100 + addb #$20 set Task image table pointer to $0120 + std <D.TskIPt + clrb set memory block map pointer to $0200 + inca + std <D.BlkMap + addb #$40 set second block map pointer to $0240 + std <D.BlkMap+2 + clrb set system service dispatch table + inca pointer to 0x300 + std <D.SysDis + inca set user dispatch table pointer to $0400 + std <D.UsrDis + inca set process descriptor block pointer to $0500 + std <D.PrcDBT + inca set system process descriptor pointer to $0600 + std <D.SysPrc + std <D.Proc set user process descriptor pointer to $0600 + adda #$02 set stack pointer to $0800 + tfr d,s + inca set system stack base pointer to $0900 + std <D.SysStk + std <D.SysMem set system memory map ptr $0900 + inca set module directory start ptr to $0a00 + std <D.ModDir + std <D.ModEnd set module directory end ptr to $0a00 + adda #$06 set secondary module directory start to $1000 + std <D.ModDir+2 + std <D.ModDAT set module directory DAT pointer to $1000 + std <D.CCMem set pointer to beginning of global memory to $1000 +* In following line, CRC=ON if it is STA <D.CRC, CRC=OFF if it is a STB <D.CRC + stb <D.CRC set CRC checking flag to off + +* Initialize interrupt vector tables, move pointer data down to DP +* CCB Change: +* this line was an error? +* leay <DisTable,pcr + leay DisTable,pcr point to table of absolute vector addresses +* +* + ldx #D.Clock where to put it in memory + IFNE H6309 + ldf #DisSize size of the table - E=0 from TFM, above + tfm y+,x+ move it over + ELSE + ldb #DisSize +l@ + lda ,y+ load a byte from source + sta ,x+ store a byte to dest + decb bump counter + bne l@ loop if we're not done + ENDC + +* initialize D.Flip0 routine in low memory, move funtion down to low +* memory. +* Y=ptr to R.Flip0 already +* leay >R.Flip0,pc + ldu #LowSub move to 0x160 + stu <D.Flip0 store fuction pointer to DP area + IFNE H6309 + ldf #SubSiz size of it + tfm y+,u+ copy it over + ELSE + ldb #SubSiz +Loop2 lda ,y+ load a byte from source + sta ,u+ and save to destination + decb bump counter + bne Loop2 loop if not done + ENDC + +* leau <Vectors,pc point to vector +* fill in the secondard interrupt vectors to all point to + tfr y,u move the pointer to a faster register +L0065 stu ,x++ Set all IRQ vectors to go to Vectors for now + cmpx #D.NMI + bls L0065 + +* Initialize user interupt vectors + ldx <D.XSWI2 Get SWI2 (os9 command) service routine pointer + stx <D.UsrSvc Save it as user service routine pointer + ldx <D.XIRQ Get IRQ service routine pointer + stx <D.UsrIRQ Save it as user IRQ routine pointer + + leax >SysCall,pc Setup System service routine entry vector + stx <D.SysSvc + stx <D.XSWI2 + + leax >S.SysIRQ,pc Setup system IRQ service vector + stx <D.SysIRQ + stx <D.XIRQ + + leax >S.SvcIRQ,pc Setup in system IRQ service vector + stx <D.SvcIRQ + leax >S.Poll,pc Setup interrupt polling vector + stx <D.Poll ORCC #$01;RTS + leax >S.AltIRQ,pc Setup alternate IRQ vector: pts to an RTS + stx <D.AltIRQ + + lda #'K --- in Kernel + jsr <D.BtBug --- + + leax >S.Flip1,pc Setup change to task 1 vector + stx <D.Flip1 + +* Setup System calls + leay >SysCalls,pc load y with address of table, below + lbsr SysSvc copy table below into dispatch table + +* Initialize system process descriptor + ldu <D.PrcDBT get process table pointer + ldx <D.SysPrc get system process pointer +* These overlap because it is quicker than trying to strip hi byte from X + stx ,u save it as first process in table + stx 1,u save it as the second as well + IFNE H6309 + oim #$01,P$ID,x Set process ID to 1 (inited to 0) + oim #SysState,P$State,x Set to system state (inited to 0) + ELSE + ldd #$01*256+SysState + sta P$ID,x set PID to 1 + stb P$State,x set state to system (*NOT* zero ) + ENDC + clra set System task as task #0 + sta <D.SysTsk + sta P$Task,x + coma Setup its priority & age ($FF) + sta P$Prior,x + sta P$Age,x + leax <P$DATImg,x point to DAT image + stx <D.SysDAT save it as a pointer in DP +* actually, since block 0 is tfm'd to be zero, we can skip the next 2 lines + IFNE H6309 + clrd + ELSE + clra + clrb + ENDC + std ,x++ initialize 1st block to 0 (for this DP) + +* Dat.BlCt-ROMCount-RAMCount + lda #$06 initialize the rest of the blocks to be free + ldu #DAT.Free +L00EF stu ,x++ store free "flag" + deca bump counter + bne L00EF loop if not done + + ldu #$003F Block $3F is in use, at the top of system DAT image + stu ,x + + ldx <D.Tasks Point to task user table + inc ,x mark first 2 in use (system & GrfDrv) + inc 1,x + +* Setup system memory map + ldx <D.SysMem Get system memory map pointer + ldb <D.CCStk Get MSB of top of CC memory +L0104 inc ,x+ Mark it as used + decb Done? + bne L0104 No, go back till done + +* Calculate memory size + * CCB Comment: + * This code only modifies 2 bytes in the x0 blocks (x=doesn't cares) + * which at worst will be our DP. Should not effect CCB's prior load of + * OS9Boot it can only be loaded into block x1 through x6 and 3f so + * we should be safe. + ldx <D.BlkMap get ptr to 8k block map + inc <$3F,x mark block $3F as used (kernel) + IFNE H6309 + ldq #$00080100 e=Marker, D=Block # to check +L0111 asld get next block # + stb >$FFA5 Map block into block 6 of my task + ste >-$6000,x save marker to that block + cmpe ,x did it ghost to block 0? + bne L0111 No, keep going till ghost is found + stb <D.MemSz Save # 8k mem blocks that exist + addr x,d add number of blocks to block map start + ELSE + ldd #$0008 +L0111 aslb + rola + stb >$FFA5 + pshs a + lda #$01 + sta >-$6000,x + cmpa ,x + puls a + bne L0111 + stb <D.MemSz + pshs x + addd ,s++ + ENDC + std <D.BlkMap+2 save block map end pointer + +* [D] at this point will contain 1 of the following: +* $0210 - 128k +* $0220 - 256k +* $0240 - 512k +* $0280 - 1024k +* $0300 - 2048k + bitb #%00110000 block above 128K-256K? + beq L0170 yes, no need to mark block map + tstb 2 meg? + beq L0170 yes, skip this +* Mark blocks from 128k-256K to block $3F as NOT RAM + abx add maximum block number to block map start + leax -1,x Skip good blocks that are RAM + lda #NotRAM Not RAM flag + subb #$3F Calculate # blocks to mark as not RAM +L0127 sta ,x+ Mark them all + decb + bne L0127 + +L0170 +* CCB - Commented out next two line. we don't have REL or BOOT, so the verify will be only +* for the memory taken by KRN itself... f000 to ff00 +* ldx #Bt.Start start address of the boot track in memory +* lda #$12 size of the boot track: B=$00 from L0127 loop, above +* CCB Addtion - change 2 lines above to: +* ldx #Where start address of KRN in memory +* ldd #$f00 size of KRN: B is already 0, A = F, Size=15 sectors (max) +* end of CCB Addtion +* lbsr I.VBlock go verify it +* bsr L01D2 go mark system map +* CCB Change - I'm commenting out this whole section, and replacing it + IFEQ 1 +* See if init module is in memory already +L01B0 leax <init,pc point to 'Init' module name + bsr link try & link it + bcc L01BF no error, go on +L01B8 os9 F$Boot error linking init, try & load boot file + bcc L01B0 got it, try init again + bra L01CE error, re-booting do D.Crash +L01BF stu <D.Init Save init module pointer + lda Feature1,u Get feature byte #1 from init module + bita #CRCOn CRC feature on? + beq ShowI if not, continue + inc <D.CRC else inc. CRC flag +ShowI lda #'i found init module + jsr <D.BtBug + +L01C1 leax <krnp2,pc Point to it's name + bsr link Try to link it + bcc L01D0 It worked, execute it + os9 F$Boot It doesn't exist try re-booting + bcc L01C1 No error's, let's try to link it again +L01CE jmp <D.Crash obviously can't do it, crash machine +L01D0 jmp ,y execute krnp2 + ENDC + +* CCB we'll replace above with this: + ldd <D.BtSz get the size of OS9Boot file + addd #$fff add size of krn and round to higher size + clrb + pshs d save on stack + os9 F$SRqMem get memory - U is our starting address + stu <D.BtPtr save this just incase something uses it + tfr u,x setup x for vblock + puls d setup d for vblock with stacked size + lbsr I.VBlock verify OS9Boot + * this was copied from f$boot + * I dont know why we need to do this. Wouldn't + * f$srqmem do this for us?!?! But the system won't boot without. + ldx <D.SysDAT get system DAT pointer + ldb $0D,x get highest allocated block number + incb allocate block 0, too + ldx <D.BlkMap point to the memory block map + bsr L01DF and go mark the blocks as used + * end of copy from f$boot + leax <init,pc point to 'Init' module name + bsr link try & link it +L01BF stu <D.Init Save init module pointer + lda Feature1,u Get feature byte #1 from init module + bita #CRCOn CRC feature on? +* beq ShowI if not, continue + inc <D.CRC else inc. CRC flag +ShowI lda #'i found init module + jsr <D.BtBug +L01C1 leax <krnp2,pc Point to it's name + bsr link Try to link it +*e bra e +L01D0 jmp ,y execute krnp2 + + +* CCB - End of change + + +* Mark kernel in system memory map as used memory (256 byte blocks) +* L01D2 ldx <D.SysMem Get system mem ptr +* * CCB Change - only mark KRN as used (BOOT and REL don't exist) +* ldd #NotRAM*256+(Bt.Start/256) B = MSB of start of the boot +* ldd #NotRam*256+(Where/256) B = MSB of start of REL + * CCB Change end +* abx point to Bt.Start - start of boot track +* comb we have $FF-$ED pages to mark as used +* sta b,x Mark I/O as not RAM + +* Mark kernel and boot file in system memory as used - there is no +* reason this is a routine anymore - only one place calls it, but +* some speghetti is here... one of the IRQ routines "borrows" this rts. +L01DF lda #RAMinUse get in use flag +L01E1 sta ,x+ save it + decb done? + bne L01E1 no, keep going + ldx <D.BlkMap get pointer to start of block map + sta <$3f,x mark kernel block as RAMinUse, instead of ModInBlk +S.AltIRQ rts return + +* Link module pointed to by X +link lda #Systm Attempt to link system module + os9 F$Link + rts + +init fcs 'Init' +krnp2 fcs 'krnp2' + +* Service vector call pointers +SysCalls fcb F$Link + fdb FLink-*-2 + fcb F$PrsNam + fdb FPrsNam-*-2 + fcb F$CmpNam + fdb FCmpNam-*-2 + fcb F$CmpNam+SysState + fdb FSCmpNam-*-2 + fcb F$CRC + fdb FCRC-*-2 + fcb F$SRqMem+SysState + fdb FSRqMem-*-2 + fcb F$SRtMem+SysState + fdb FSRtMem-*-2 + fcb F$AProc+SysState + fdb FAProc-*-2 + fcb F$NProc+SysState + fdb FNProc-*-2 + fcb F$VModul+SysState + fdb FVModul-*-2 + fcb F$SSvc+SysState + fdb FSSvc-*-2 + fcb F$SLink+SysState + fdb FSLink-*-2 + fcb F$Boot+SysState + fdb FBoot-*-2 + fcb F$BtMem+SysState + fdb FSRqMem-*-2 + IFNE H6309 + fcb F$CpyMem + fdb FCpyMem-*-2 + ENDC + fcb F$Move+SysState + fdb FMove-*-2 + fcb F$AllImg+SysState + fdb FAllImg-*-2 + fcb F$SetImg+SysState + fdb FFreeLB-*-2 + fcb F$FreeLB+SysState + fdb FSFreeLB-*-2 + fcb F$FreeHB+SysState + fdb FFreeHB-*-2 + fcb F$AllTsk+SysState + fdb FAllTsk-*-2 + fcb F$DelTsk+SysState + fdb FDelTsk-*-2 + fcb F$SetTsk+SysState + fdb FSetTsk-*-2 + fcb F$ResTsk+SysState + fdb FResTsk-*-2 + fcb F$RelTsk+SysState + fdb FRelTsk-*-2 + fcb F$DATLog+SysState + fdb FDATLog-*-2 + fcb F$LDAXY+SysState + fdb FLDAXY-*-2 + fcb F$LDDDXY+SysState + fdb FLDDDXY-*-2 + fcb F$LDABX+SysState + fdb FLDABX-*-2 + fcb F$STABX+SysState + fdb FSTABX-*-2 + fcb F$ELink+SysState + fdb FELink-*-2 + fcb F$FModul+SysState + fdb FFModul-*-2 + fcb F$VBlock+SysState + fdb FVBlock-*-2 + IFNE H6309 + fcb F$DelRAM + fdb FDelRAM-*-2 + ENDC + fcb $80 + +* SWI3 vector entry +XSWI3 lda #P$SWI3 point to SWI3 vector + fcb $8C skip 2 bytes + +* SWI vector entry +XSWI lda #P$SWI point to SWI vector + ldx <D.Proc get process pointer + ldu a,x user defined SWI[x]? + beq L028E no, go get option byte +GoUser lbra L0E5E Yes, go call users's routine + +* SWI2 vector entry +XSWI2 ldx <D.Proc get current process descriptor + ldu P$SWI2,x any SWI vector? + bne GoUser yes, go execute it + +* Process software interupts from a user state +* Entry: X=Process descriptor pointer of process that made system call +* U=Register stack pointer +L028E ldu <D.SysSvc set system call processor to system side + stu <D.XSWI2 + ldu <D.SysIRQ do the same thing for IRQ's + stu <D.XIRQ + IFNE H6309 + oim #SysState,P$State,x mark process as in system state + ELSE + lda P$State,x + ora #SysState + sta P$State,x + ENDC +* copy register stack to process descriptor + sts P$SP,x save stack pointer + leas (P$Stack-R$Size),x point S to register stack destination + + IFNE H6309 + leau R$Size-1,s point to last byte of destination register stack + leay -1,y point to caller's register stack in $FEE1 + ldw #R$Size size of the register stack + tfm y-,u- + leau ,s needed because the TFM is u-, not -u (post, not pre) + ELSE +* Note! R$Size MUST BE an EVEN number of bytes for this to work! + leau R$Size,s point to last byte of destination register stack + lda #R$Size/2 +Loop3 ldx ,--y + stx ,--u + deca + bne Loop3 + ENDC + andcc #^IntMasks +* B=function code already from calling process: DON'T USE IT! + ldx R$PC,u get where PC was from process + leax 1,x move PC past option + stx R$PC,u save updated PC to process +* execute function call + ldy <D.UsrDis get user dispatch table pointer + lbsr L033B go execute option + IFNE H6309 + aim #^IntMasks,R$CC,u Clear interrupt flags in caller's CC + ELSE + lda R$CC,u + anda #^IntMasks + sta R$CC,u + ENDC + ldx <D.Proc get current process ptr + IFNE H6309 + aim #^(SysState+TimOut),P$State,x Clear system & timeout flags + ELSE + lda P$State,x + anda #^(SysState+TimOut) + sta P$State,x + ENDC + +* Check for image change now, which lets stuff like F$MapBlk and F$ClrBlk +* do the short-circuit thing, too. Adds about 20 cycles to each system call. + lbsr TstImg it doesn't hurt to call this twice + lda P$State,x get current state of the process + ora <P$Signal,x is there a pending signal? + sta <D.Quick save quick return flag + beq AllClr if nothing's have changed, do full checks + +DoFull bsr L02DA move the stack frame back to user state + lbra L0D80 go back to the process + +* add ldu P$SP,x, etc... +AllClr equ * + IFNE H6309 + inc <D.QCnt + aim #$1F,<D.QCnt + beq DoFull every 32 system calls, do the full check + ldw #R$Size --- size of the register stack + ldy #Where+SWIStack --- to stack at top of memory + orcc #IntMasks + tfm u+,y+ --- move the stack to the top of memory + ELSE + lda <D.QCnt + inca + anda #$1F + sta <D.QCnt + beq DoFull + ldb #R$Size + ldy #Where+SWIStack + orcc #IntMasks +Loop4 lda ,u+ + sta ,y+ + decb + bne Loop4 + ENDC + lbra BackTo1 otherwise simply return to the user + +* Copy register stack from user to system +* Entry: U=Ptr to Register stack in process dsc +L02CB pshs cc,x,y,u preserve registers + ldb P$Task,x get task # + ldx P$SP,x get stack pointer + lbsr L0BF3 calculate block offset (only affects A&X) + leax -$6000,x adjust pointer to where memory map will be + bra L02E9 go copy it + +* Copy register stack from system to user +* Entry: U=Ptr to Register stack in process dsc +L02DA pshs cc,x,y,u preserve registers + ldb P$Task,x get task # of destination + ldx P$SP,x get stack pointer + lbsr L0BF3 calculate block offset (only affects A&X) + leax -$6000,x adjust pointer to where memory map will be + exg x,y swap pointers & copy +* Copy a register stack +* Entry: X=Source +* Y=Destination +* A=Offset into DAT image of stack +* B=Task # +L02E9 leau a,u point to block # of where stack is + lda 1,u get first block + ldb 3,u get a second just in case of overlap + orcc #IntMasks shutdown interupts while we do this + std >$FFA5 map blocks in + IFNE H6309 + ldw #R$Size get size of register stack + tfm x+,y+ copy it + ELSE + ldb #R$Size +Loop5 lda ,x+ + sta ,y+ + decb + bne Loop5 + ENDC + ldx <D.SysDAT remap the blocks we took out + lda $0B,x + ldb $0D,x + std >$FFA5 + puls cc,x,y,u,pc restore & return + +* Process software interupts from system state +* Entry: U=Register stack pointer +SysCall leau ,s get pointer to register stack + lda <D.SSTskN Get system task # (0=SYSTEM, 1=GRFDRV) + clr <D.SSTskN Force to System Process + pshs a Save the system task number + lda ,u Restore callers CC register (R$CC=$00) + tfr a,cc make it current + ldx R$PC,u Get my caller's PC register + leax 1,x move PC to next position + stx R$PC,u Save my caller's updated PC register + ldy <D.SysDis get system dispatch table pointer + bsr L033B execute system call + puls a restore system state task number + lbra L0E2B return to process + +* Entry: X = system call vector to jump to +Sys.Vec jmp ,x execute service call + +* Execute system call +* Entry: B=Function call # +* Y=Function dispatch table pointer (D.SysDis or D.UsrDis) +L033B + lslb is it a I/O call? (Also multiplys by 2 for offset) + bcc L0345 no, go get normal vector +* Execute I/O system calls + ldx IOEntry,y get IOMan vector +* Execute the system call +L034F pshs u preserve register stack pointer + jsr [D.SysVec] perform a vectored system call + puls u restore pointer +L0355 tfr cc,a move CC to A for stack update + bcc L035B go update it if no error from call + stb R$B,u save error code to caller's B +L035B ldb R$CC,u get callers CC, R$CC=$00 + IFNE H6309 + andd #$2FD0 [A]=H,N,Z,V,C [B]=E,F,I + orr b,a merge them together + ELSE + anda #$2F [A]=H,N,Z,V,C + andb #$D0 [B]=E,F,I + pshs b + ora ,s+ + ENDC + sta R$CC,u return it to caller, R$CC=$00 + rts + +* Execute regular system calls +L0345 + clra clear MSB of offset + ldx d,y get vector to call + bne L034F it's initialized, go execute it + comb set carry for error + ldb #E$UnkSvc get error code + bra L0355 return with it + + use freboot.asm + + use fssvc.asm + + use flink.asm + + use fvmodul.asm + + use ffmodul.asm + + use fprsnam.asm + + use fcmpnam.asm + + use ccbfsrqmem.asm + +* use fallram.asm + + + IFNE H6309 + use fdelram.asm + ENDC + + use fallimg.asm + + use ffreehb.asm + + use fdatlog.asm + + use fld.asm + + IFNE H6309 + use fcpymem.asm + ENDC + + use fmove.asm + + use fldabx.asm + + use falltsk.asm + + use faproc.asm + +* System IRQ service routine +XIRQ ldx <D.Proc get current process pointer + sts P$SP,x save the stack pointer + lds <D.SysStk get system stack pointer + ldd <D.SysSvc set system service routine to current + std <D.XSWI2 + ldd <D.SysIRQ set system IRQ routine to current + std <D.XIRQ + jsr [>D.SvcIRQ] execute irq service + bcc L0D5B + + ldx <D.Proc get current process pointer + ldb P$Task,x + ldx P$SP,x get it's stack pointer + + pshs u,d,cc save some registers + leau ,s point to a 'caller register stack' + lbsr L0C40 do a LDB 0,X in task B + puls u,d,cc and now A ( R$A,U ) = the CC we want + + ora #IntMasks disable it's IRQ's + lbsr L0C28 save it back +L0D5B orcc #IntMasks shut down IRQ's + ldx <D.Proc get current process pointer + tst <D.QIRQ was it a clock IRQ? + lbne L0DF7 if not, do a quick return + + lda P$State,x Get it's state + bita #TimOut Is it timed out? + bne L0D7C yes, wake it up +* Update active process queue + ldu #(D.AProcQ-P$Queue) point to active process queue + ldb #Suspend get suspend flag +L0D6A ldu P$Queue,u get a active process pointer + beq L0D78 + bitb P$State,u is it suspended? + bne L0D6A yes, go to next one in chain + ldb P$Prior,x get current process priority + cmpb P$Prior,u do we bump this one? + blo L0D7C + +L0D78 ldu P$SP,x + bra L0DB9 + +L0D7C anda #^TimOut + sta P$State,x + +L0D80 equ * +L0D83 bsr L0D11 activate next process + + use fnproc.asm + +* The following routines must appear no earlier than $E00 when assembled, as +* they have to always be in the vector RAM page ($FE00-$FEFF) + +* CCB: this code (after pad) start assembling *before* 0xfe00, it's too big to +* fit into the memory as stated above!!!! + +PAD fill $00,($0df1-*) fill memory to ensure the above happens +* Default routine for D.SysIRQ +S.SysIRQ + lda <D.SSTskN Get current task's GIME task # (0 or 1) + beq FastIRQ Use super-fast version for system state + clr <D.SSTskN Clear out memory copy (task 0) + jsr [>D.SvcIRQ] (Normally routine in Clock calling D.Poll) + inc <D.SSTskN Save task # for system state + lda #1 Task 1 + ora <D.TINIT Merge task bit's into Shadow version + sta <D.TINIT Update shadow + sta >DAT.Task Save to GIME as well & return + bra DoneIRQ Check for error and exit + +FastIRQ jsr [>D.SvcIRQ] (Normally routine in Clock calling D.Poll) +DoneIRQ bcc L0E28 No error on IRQ, exit + IFNE H6309 + oim #IntMasks,0,s Setup RTI to shut interrupts off again + ELSE + lda ,s + ora #IntMasks + sta ,s + ENDC +L0E28 rti + +* return from a system call +L0E29 clra Force System task # to 0 (non-GRDRV) +L0E2B ldx <D.SysPrc Get system process dsc. ptr + lbsr TstImg check image, and F$SetTsk (PRESERVES A) + orcc #IntMasks Shut interrupts off + sta <D.SSTskN Save task # for system state + beq Fst2 If task 0, skip subroutine + ora <D.TINIT Merge task bit's into Shadow version + sta <D.TINIT Update shadow + sta >DAT.Task Save to GIME as well & return +Fst2 leas ,u Stack ptr=U & return + rti + +* Switch to new process, X=Process descriptor pointer, U=Stack pointer +L0E4C equ * + IFNE H6309 + oim #$01,<D.TINIT switch GIME shadow to user state + lda <D.TINIT + ELSE + lda <D.TINIT + ora #$01 + sta <D.TINIT + ENDC + sta >DAT.Task save it to GIME + leas ,y point to new stack + tstb is the stack at SWISTACK? + bne MyRTI no, we're doing a system-state rti + + IFNE H6309 + ldf #R$Size E=0 from call to L0E8D before + ldu #Where+SWIStack point to the stack + tfm u+,y+ move the stack from top of memory to user memory + ELSE + ldb #R$Size + ldu #Where+SWIStack point to the stack +RtiLoop lda ,u+ + sta ,y+ + decb + bne RtiLoop + ENDC +MyRTI rti return from IRQ + + +* Execute routine in task 1 pointed to by U +* comes from user requested SWI vectors +L0E5E equ * + IFNE H6309 + oim #$01,<D.TINIT switch GIME shadow to user state + ldb <D.TINIT + ELSE + ldb <D.TINIT + orb #$01 + stb <D.TINIT + ENDC + stb >DAT.Task + jmp ,u + +* Flip to task 1 (used by GRF/WINDInt to switch to GRFDRV) (pointed to +* by <D.Flip1). All regs are already preserved on stack for the RTI +S.Flip1 ldb #2 get Task image entry numberx2 for Grfdrv (task 1) + bsr L0E8D copy over the DAT image + IFNE H6309 + oim #$01,<D.TINIT + lda <D.TINIT get copy of GIME Task side + ELSE + lda <D.TINIT + ora #$01 + sta <D.TINIT + ENDC + sta >DAT.Task save it to GIME register + inc <D.SSTskN increment system state task number + rti return + +* Setup MMU in task 1, B=Task # to swap to, shifted left 1 bit +L0E8D cmpb <D.Task1N are we going back to the same task + beq L0EA3 without the DAT image changing? + stb <D.Task1N nope, save current task in map type 1 + ldx #$FFA8 get MMU start register for process's + ldu <D.TskIPt get task image pointer table + ldu b,u get address of DAT image +L0E93 leau 1,u point to actual MMU block + IFNE H6309 + lde #4 get # banks/2 for task + ELSE + lda #4 + pshs a + ENDC +L0E9B lda ,u++ get a bank + ldb ,u++ and next one + std ,x++ Save it to MMU + IFNE H6309 + dece done? + ELSE + dec ,s + ENDC + bne L0E9B no, keep going + IFEQ H6309 + leas 1,s + ENDC +L0EA3 rts return + +* Execute FIRQ vector (called from $FEF4) +FIRQVCT ldx #D.FIRQ get DP offset of vector + bra L0EB8 go execute it + +* Execute IRQ vector (called from $FEF7) +IRQVCT orcc #IntMasks disasble IRQ's + ldx #D.IRQ get DP offset of vector + +* Execute interrupt vector, B=DP Vector offset +L0EB8 clra (faster than CLR >$xxxx) + sta >DAT.Task Force to Task 0 (system state) + IFNE H6309 + tfr 0,dp setup DP + ELSE + tfr a,dp + ENDC +MapGrf equ * + IFNE H6309 + aim #$FE,<D.TINIT switch GIME shadow to system state + lda <D.TINIT set GIME again just in case timer is used + ELSE + lda <D.TINIT + anda #$FE + sta <D.TINIT + ENDC +MapT0 sta >DAT.Task + jmp [,x] execute it + +* Execute SWI3 vector (called from $FEEE) +SWI3VCT orcc #IntMasks disable IRQ's + ldx #D.SWI3 get DP offset of vector + bra SWICall go execute it + +* Execute SWI2 vector (called from $FEF1) +SWI2VCT orcc #IntMasks disasble IRQ's + ldx #D.SWI2 get DP offset of vector + +* This routine is called from an SWI, SWI2, or SWI3 +* saves 1 cycle on system-system calls +* saves about 200 cycles (calls to I.LDABX and L029E) on grfdrv-system, +* or user-system calls. +SWICall ldb [R$PC,s] get callcode of the system call +* NOTE: Alan DeKok claims that this is BAD. It crashed Colin McKay's +* CoCo 3. Instead, we should do a clra/sta >DAT.Task. +* clr >DAT.Task go to map type 1 + clra + sta >DAT.Task +* set DP to zero + IFNE H6309 + tfr 0,dp + ELSE + tfr a,dp + ENDC + +* These lines add a total of 81 addition cycles to each SWI(2,3) call, +* and 36 bytes+12 for R$Size in the constant page at $FExx +* It takes no more time for a SWI(2,3) from system state than previously, +* ... and adds 14 cycles to each SWI(2,3) call from grfdrv... not a problem. +* For processes that re-vector SWI, SWI3, it adds 81 cycles. BUT SWI(3) +* CANNOT be vectored to L0EBF cause the user SWI service routine has been +* changed + lda <D.TINIT get map type flag + bita #$01 check it without changing it + +* Change to LBEQ R.SysSvc to avoid JMP [,X] +* and add R.SysSvc STA >DAT.Task ??? + beq MapT0 in map 0: restore hardware and do system service + tst <D.SSTskN get system state 0,1 + bne MapGrf if in grfdrv, go to map 0 and do system service + +* the preceding few lines are necessary, as all SWI's still pass thru +* here before being vectored to the system service routine... which +* doesn't copy the stack from user state. + sta >DAT.Task go to map type X again to get user's stack +* a byte less, a cycle more than ldy #$FEED-R$Size, or ldy #$F000+SWIStack + leay <SWIStack,pc where to put the register stack: to $FEDF + tfr s,u get a copy of where the stack is + IFNE H6309 + ldw #R$Size get the size of the stack + tfm u+,y+ move the stack to the top of memory + ELSE + pshs b + ldb #R$Size +Looper lda ,u+ + sta ,y+ + decb + bne Looper + puls b + ENDC + bra L0EB8 and go from map type 1 to map type 0 + +* Execute SWI vector (called from $FEFA) +SWIVCT ldx #D.SWI get DP offset of vector + bra SWICall go execute it + +* Execute NMI vector (called from $FEFD) +NMIVCT ldx #D.NMI get DP offset of vector + bra L0EB8 go execute it + +* The end of the kernel module is here + emod +eom equ * + +* What follows after the kernel module is the register stack, starting +* at $FEDD (6309) or $FEDF (6809). This register stack area is used by +* the kernel to save the caller's registers in the $FEXX area of memory +* because it doesn't* get "switched out" no matter the contents of the +* MMU registers. +SWIStack + fcc /REGISTER STACK/ same # bytes as R$Size for 6809 + IFNE H6309 + fcc /63/ if 6309, add two more spaces + ENDC + + fcb $55 D.ErrRst + +* This list of addresses ends up at $FEEE after the kernel track is loaded +* into memory. All interrupts come through the 6809 vectors at $FFF0-$FFFE +* and get directed to here. From here, the BRA takes CPU control to the +* various handlers in the kernel. + bra SWI3VCT SWI3 vector comes here + nop + bra SWI2VCT SWI2 vector comes here + nop + bra FIRQVCT FIRQ vector comes here + nop + bra IRQVCT IRQ vector comes here + nop + bra SWIVCT SWI vector comes here + nop + bra NMIVCT NMI vector comes here + nop + + + end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/level2/modules/kernel/ccbkrn.txt Mon Feb 06 15:51:13 2012 -0600 @@ -0,0 +1,142 @@ +* I eliminated the manual padding of the kernel. I inserted a fill + directive much further down in the source between the "regular" + module part of the kernel, and the fe00 page code. Down at that end + the assembler will auto-compute the size needed + +* At entry, the kernel now pulls the size of the bootfile from the U + stack, which is still setup from CCB, and saves it to + its proper place in the DP. Also misc. DP flags are set - if boot + was attempted, and CPU speed is set (CCB uses high speed for coco3) + +* at entry, the kernel now installs it's own debug printing and crash + routines, something that REL used to do. + +* there's a place where some IRQ-ish tables are copied down to the DP, + where I found a bug: reg Y was being filled with a bogus source + address. I'm NOT good with PCR addressing, but after fixing, my code + changes started working....maybe you want to verify this change. + +* read comments in the "calculate memory size" section... I got way + lucky on this one! + +* the biggest functional changes occur at label L0170: + + - The kernel no longer verifies itself (and hense adds itself to the + modules directory), it now verifies itself and the preloaded + bootfile together. The kernel no longer reserves it's own memory + either, it now simply calls f$srqmem to do this for us and the + bootfile together as one big block. + + - AFTER reserving system memory and verifying, we now mark up the + sysDAT... I don't understand why we have to do this. Shouldn't + f$rsysmem do this for us?!?! + + - we link to init and set CRC checking and jump to krnp2's exec. + +* Near commented out label L01D2, I've commented out this section, it + no longer needed as f$rsysmem DOES do this for the entire kernel + now, not just the bootfile + +* the code at L01DF can be "inlined", nothing calls it but one place. + One of the IRQ vectors borrow's this routine's RTS though ... goofy + speghetti code! + +* AFTER all the normal included system call files, and BEFORE the FE00 + page stuff near label S.SysIRQ I added automatic padding + +* S.SysIRQ which is supposed to be in FE page, assembles at around + fdf1 or so.... which according to the comments is a BAD thing. + Nothing seems to happen. Basically, the FE page code it TOO BIG to + fit! + + +And in f$srqmem.asm: + +* I modified this system call to request memory starting from 0xff00 + rather than ed00... it might be a touch lesss efficient AFTER + booting, but it sure helped DURING booting. This is how I reused + fsrqmem to setup the KRN and OS9BOOT file in one swoop. + +* I changed f$boot to just issue a kernel panic. I'm not sure if this + is the thing to do. KRNP2 calls f$boot on chdir and open default + device error. I'm not sure if anything else calls it. Maybe it can + be it can be deleted and KRNP2 changed just to panic itself rather + than system calling to do so. + + +*** All changes were made to a fresh CVS'd copy of Nitros9 Version 3.2.9. +*** I have no idea if this all works on a coco2 or a 6309 + + +*** CoCoBoot / OS9 Contract: + +- Size of the pre-loaded bootfile (NOT boot and cckrn) is passed as + the top 2 bytes on the U stack. MSB on top... the usually motorola + byte order. In Forth lingo, the top cell of the data stack is the + size of the bootfile. Calling the kernel works and appears just like + calling any other forth word, except we don't return, e.i.: + +: gotokernel ( u -- ) \ jump to kernel passing it u - the bootfile +\ size in bytes, this funtion doesn't return. + +- Module CCBKRN is loaded to block 0x3f at offset 0x1000, or 0xf000 in + cpu-space. CCBKRN must be exactly 0x0f00 in size and be in a + standard os9 executable module format. + +- The OS9Boot file is loaded on a page boundary just low enough in + cpu-space to fit below 0xf000 (the CCBKRN module) physical blocks + are allocated in order starting with block 0x01 (or 0x31 on a 128k + machine). + +- The source of OS9Boot and CCBKRN is not guaranteed! + +- Register Guarantees: + D - not guaranteed + DP - not guaranteed + X - not guaranteed + Y - not guaranteed but usually will be in the 0x3800-0x6000 range + U - set to top of a stack usually in the 0x7e00-0x7f00 + S - not guaranteed but usually will be in the 0x7f00 - 0x8000 range + CC - not guaranteed. + +- MMU Guarantees: + physical block 0x3f will be banked in at 0xe000-0xff00 in cpu-space + + + + +*** CoCoBoot does this but maybe CCBKRN should do instead: + +- physical block 0x00 is in cpu-space at 0x0000 upon calling to + CCBKRN. DP is set to 0x00 and the DP area in block 0x00 is cleared. + +- CPU interrupts and Pia0 side B's interrupts are disabled. + +- memory map is guaranteed to look like this (in hex): + + 00 39 3a 3b 3c 3d 3e 3f + +- Physical Block 3b will be cleared to spaces except offset 0x0000: + will be initialized to 0x0008. This serves as a screen pointer to + kernel debug printing. + +- The GIME registers will be set as follows: + + starting at 0xff90: + 6c init0 + 00 init1 + 00 irq enable + 00 firq enable + 0900 timer register + 0000 unused + 0320 screen settings + 0000 ???? + 00 ???? + ec01 physical video address (block 3b offset 0x0008 ) + 00 horizontal offset / scroll + + A mirror of these bytes will appear at 0x0090-0x009f in the DP + + + +Brett M. Gordon \ No newline at end of file
--- a/level2/modules/kernel/fnproc.asm Sun Feb 05 13:30:35 2012 -0600 +++ b/level2/modules/kernel/fnproc.asm Mon Feb 06 15:51:13 2012 -0600 @@ -89,7 +89,7 @@ lbsr L0E8D re-map the DAT image, if necessary ldb <D.Quick get quick return flag - bra L0E4C Go switch GIME over to new process & run + lbra L0E4C Go switch GIME over to new process & run * Process a signal (process had no signal trap) L0DFD equ *