Mercurial > hg > Members > kono > nitros9-code
view level1/cmds/os9gen.asm @ 2848:94197db917c9 lwtools-port
Makefiles: Call OS9ATTR with multiple files (part 1)
Instead of spawning a os9 process for each file, call
it once with the whole bunch of files.
This can speed up the build process significantly when applied
globally. For now, do the special cases having "notdir".
author | Tormod Volden <debian.tormod@gmail.com> |
---|---|
date | Fri, 12 Jul 2013 00:01:00 +0200 |
parents | d706cc0dfd58 |
children | d80acb6d104b |
line wrap: on
line source
******************************************************************** * OS9Gen - OS-9 bootfile generator * * $Id$ * * -e = extended boot (fragmented) * -q=<path> = quick gen .. set sector zero pointing to <path> * -r = remove pointer to boot file (does not delete file) * -s = single drive option * -t=<boottrack> = boot track file to use * * Edt/Rev YYYY/MM/DD Modified by * Comment * ------------------------------------------------------------------ * 9 ????/??/?? * From OS-9 Level Two Vr. 2.00.01. * * 10 2003/06/28 Boisy G. Pitre * Added -t= option, fixed bug in single disk swap routine if key * besides 'C' was pressed, minor optimizations. * * l0r2 2003/07/24 Boisy G. Pitre * Fixed bug introduced in V03.01.03 where os9gen wouldn't write boot * track on DS disks. * * 11 2005/10/10 Boisy G. Pitre * Added -e option to create fragmented bootfiles. * * 12 2006/05/09 Christopher R. Hawks * Weren't clearing -e option, so all os9boot files were extended. * * 13 2011/09/13 Robert Gault * A flexible buffer is now used to hold the FAT map. * The boot file name is now copied into the data space for which * 160 bytes are reserved. F$Mem trashes parameter space. * DD.BIT can now be used to obtain a reasonably sized FAT with large drives. * Added error message if not enough room for bit map. * Replace sectbuff with bitmbuff for all FAT (DD.MAP) work. * Moved common code in ABMClear & ABMSet to subroutine. * * 14 2011/09/16 Robert Gault * Corrected a typo which occured when committing code. Exit of Initcalc had * ABM3 in wrong place. Also included C$CR in file name copy. * * 2011/09/18 Robert Gault * Cleaned up code and removed multiple calculations of shift divisor by * calculating it once and storing it in data. * Corrected sector count calculation to include partial clusters. nam OS9Gen ttl OS-9 bootfile generator * Disassembled 02/07/06 13:11:11 by Disasm v1.6 (C) 1988 by RML *Needed for stand alone compile *LEVEL equ 2 IFP1 use defsfile ENDC DOHELP set 0 DOHD set 1 allow bootfile creation on HD tylg set Prgrm+Objct atrv set ReEnt+rev rev set $00 edition set 12 mod eom,name,tylg,atrv,start,size org 0 btfname rmb 2 btflag rmb 1 qfname rmb 2 qflag rmb 1 rflag rmb 1 statptr rmb 2 bfpath rmb 1 devpath rmb 1 parmpath rmb 1 u0005 rmb 1 Needed? u0006 rmb 2 ddbt rmb 3 ddbtsz rmb 2 u000D rmb 2 u000F rmb 2 u0011 rmb 2 u0013 rmb 2 u0015 rmb 2 u0017 rmb 7 devopts rmb 20 bfdlsn rmb 3 u0035 rmb 9 u003E rmb 2 eflag rmb 1 sngldrv rmb 1 bootdev rmb 32 btshift rmb 2 bitflag rmb 1 lsn0 rmb 26 btfstr rmb 160 u007B rmb 2 u007D rmb 1 sectbuff rmb 1024 u047E rmb 16 u048E rmb 1 u048F rmb 7 u0496 rmb 7018 bitmbuf equ . size equ . name fcs /OS9Gen/ fcb edition IFNE DOHELP HelpMsg fcb C$LF fcc "Use (CAUTION): OS9Gen </devname> <opts>" fcb C$LF fcc " ..reads (std input) pathnames until EOF," fcb C$LF fcc " merging paths into New OS9Boot file." fcb C$LF fcc " -e = extended boot (fragmented)" fcb C$LF fcc " -s = single drive operation" fcb C$LF fcc " -t=boottrack = set boot track file" fcb C$LF,C$CR ENDC fcc "Can't find: " ErrWrit fcb C$LF fcc "Error writing kernel track" fcb C$CR MemErr fcb C$LF fcc "Not enough memory for bit map" fcb C$CR TrkErr fcb C$LF fcc "Can't read data" fcb C$CR IFEQ DOHD HDGen fcb C$LF fcc "Error - cannot gen to hard disk" fcb C$CR ENDC IFGT Level-1 CantRel fcb C$LF fcc "Error - can't link to Rel module" fcb C$CR ENDC CarRet fcb C$CR TheBell fcb C$BELL TWarn fcb C$LF fcc "Warning - file(s) present" fcb C$LF fcc "on track " IFEQ Bt.Track-34 fcc "34" ELSE fcc "??" ENDC fcc " - this track" fcb C$LF fcc "not rewritten." fcb C$CR BootFrag fcb C$LF fcc "Error - OS9Boot file fragmented" fcb C$CR IFNE 0 BadTkMsg fcc "Error - Boot track file must be 4608 bytes" fcb C$CR BadTkMsgL equ *-BadTkMsg ENDC Source fcc "Ready SOURCE, hit C to continue: " SourceL equ *-Source Destin fcc "Ready DESTINATION, hit C to continue: " DestinL equ *-Destin Rename fcc "RENAME " TempBoot fcc "TempBoot " fcb $FF OS9Boot fcc "OS9Boot" fcb C$CR fcb $FF IFGT Level-1 TheRel fcc "Rel" fcb $FF ENDC * Here's how registers are set when this process is forked: * * +-----------------+ <-- Y (highest address) * ! Parameter ! * ! Area ! * +-----------------+ <-- X, SP * ! Data Area ! * +-----------------+ * ! Direct Page ! * +-----------------+ <-- U, DP (lowest address) * * D = parameter area size * PC = module entry point abs. address * CC = F=0, I=0, others undefined start clrb stb <btflag assume no -t specified stb <u0005 stb <sngldrv assume multi-drive stb <eflag assume not extended bootfile stu <statptr save statics pointer leas >u047E,u point stack pointer to u047e pshs u tfr y,d copy pointer to top of our mem in D subd ,s++ D = Y-u047e = 7039 subd #u047E D = 5889 = $1701 What is it? R.G. clrb std <u0011 lda #PDELIM cmpa ,x first char of device name a path delimiter? lbne BadName branch if not (bad name) os9 F$PrsNam else parse name lbcs ShowHelp branch if error lda #PDELIM cmpa ,y lbeq BadName pshs b,a parseopt lda ,y+ get next character cmpa #'- dash? beq parsein branch if so cmpa #C$CR end of line? beq getdev branch if so bra parseopt else continue to parse options parsein ldd ,y+ get two chars after - cmpa #C$CR end of line? beq getdev branch if so cmpa #C$SPAC space? beq parseopt yes, look for next char anda #$DF else make value in A uppercase cmpa #'R is it R? beq remboot branch if so cmpa #'S is it S? beq onedrive branch if so cmpa #'E is it E beq extend branch if so cmpd #81*256+61 does D = 'Q=' beq quick cmpd #84*256+61 does D = 'T=' lbne SoftExit leay 1,y point past = * sty <btfname save pointer to boottrack filename R.G. sta <btflag pshs x copy btfname into data space leax btfstr,u making room to expand the data space R.G. stx btfname,u * Skip over non-spaces and non-CRs SkipNon lda ,y+ cmpa #C$CR beq getdev2 we must recover regX cmpa #C$SPAC beq parseopt2 "" sta ,x+ bra SkipNon getdev2 sta ,x this was added in rev 14 to correct an oversight R.G. puls x bra getdev parseopt2 puls x bra parseopt remboot inc <rflag remove bootfile reference from LSN0 flag bra parsein onedrive inc <sngldrv set single drive flag bra parsein extend inc <eflag set extended boot flag bra parsein quick leay 1,y point past = sty <qfname save pointer to quick filename sta <qflag getdev puls b,a leay <bootdev,u point to boot device L0239 sta ,y+ lda ,x+ decb bpl L0239 sty <u003E ldd #PENTIR*256+C$SPAC std ,y++ lbsr GetDest leax <bootdev,u lda #UPDAT. os9 I$Open sta <devpath lbcs ShowHelp leax <devopts,u clrb * ldb #SS.Opt os9 I$GetStt lbcs Bye IFEQ DOHD * If destination drive is hard disk, don't allow leax devopts,u lda <(PD.TYP-PD.OPT)+devopts,u get type byte bpl L0276 branch if not hard drive clrb leax >HDGen,pcr else tell user can't do hard drive lbra WritExit ENDC L0276 ldx <u003E leay >TempBoot,pcr lda #PDELIM L027E sta ,x+ lda ,y+ bpl L027E * Copy OS9Boot string to buffer leay >OS9Boot,pcr L0288 lda ,y+ sta ,x+ bpl L0288 tfr x,d leax <bootdev,u pshs x subd ,s++ std <u000D ldd #WRITE.*256+(READ.+WRITE.) * lda #WRITE. * ldb #READ.+WRITE. os9 I$Create sta <bfpath lbcs Bye ldx #$0000 upper 16 bits are zero stx <u0006 ldu #$3000 ldb #SS.Size os9 I$SetStt set size of newly created file lbcs Bye branch if error ldu <statptr retrieve static pointer bsr L032F * Read Bootlist file, line by line ReadBLst leax sectbuff,u ldy #256 clra standard input os9 I$ReadLn read line bcs L0312 branch if error lda ,x else get byte in A ldb #E$EOF and EOF error in B cmpa #C$CR CR? beq L0312 branch if so cmpa #'* comment? beq ReadBLst continue reading if so lda #READ. else use read perms os9 I$Open open file at X (line we read) bcs L031A branch if error sta <parmpath save path L02DD ldx <u0015 ldd <u0011 subd <u0013 tfr d,y lda <parmpath os9 I$Read bcc L02F9 cmpb #E$EOF lbne Bye os9 I$Close clr <parmpath bra ReadBLst L02F9 tfr y,d leax d,x stx <u0015 addd <u0013 std <u0013 cmpd <u0011 bcs L030C bsr L032B bcs L0328 L030C tst <parmpath bne L02DD bra ReadBLst L0312 cmpb #E$EOF end of file? bne L0328 branch if not bsr L033D bra L0377 L031A pshs b leax sectbuff,u ldy #256 lda #$02 standard error os9 I$WritLn write L0328 lbra Bye L032B bsr L033D bcs L033C L032F lbsr GetSrc clra clrb std <u0013 leax >u047E,u stx <u0015 L033C rts L033D lbsr GetDest ldd <u0013 beq L033C tst <sngldrv single drive? beq L0361 branch if not lda <devpath ldx #$0000 ldu #$0000 os9 I$Seek seek to LSN0 ldu <statptr +BGP+ added bcs L033C leax sectbuff,u ldy #256 os9 I$Read read LSN0 bcs L033C lbsr FShift sty btshift,u save divisor value R.G. L0361 lda <bfpath get bootfile path in A leax >u047E,u ldy <u0013 os9 I$Write bcs L033C tfr y,d addd <u0006 std <u0006 clrb rts L0377 leax <devopts,u clrb * ldb #SS.Opt lda <bfpath os9 I$GetStt lbcs Bye lda <bfpath get bootfile path ldx #$0000 ldu <u0006 ldb #SS.Size set bootfile size os9 I$SetStt lbcs Bye ldu <statptr os9 I$Close lbcs ShowHelp tst <eflag extended boot option used? bne nonfrag yes, don't check for fragmented file ldx <bfdlsn,u load X/U with LSN of bootfile fd sector lda <bfdlsn+2,u clrb round off to sector boundary tfr d,u lda <devpath get path to raw device os9 I$Seek seek ldu <statptr lbcs Bye leax >u047E,u point to buffer ldy #256 read one sector os9 I$Read do it! lbcs Bye ldd >u047E+(FD.SEG+FDSL.S+FDSL.B),u lbne ItsFragd if not zero, file is fragmented nonfrag lda <devpath get the device path ldx #$0000 ldu #DD.BT os9 I$Seek seek to DD.BT in LSN0 ldu <statptr lbcs Bye leax ddbt,u point to our internal ddbt copy in statics ldy #DD.DAT-DD.BT we want DD.BT and DD.BTSZ into ddbt,u os9 I$Read so read bootstrap sector and bootfile size lbcs Bye branch if error ldd <ddbtsz get DD.BTSZ in D beq L040D branch if zero ldx <u003E leay >OS9Boot,pcr lda #PDELIM L03F3 sta ,x+ lda ,y+ bpl L03F3 leax <bootdev,u os9 I$Delete delete the os9boot file ldx <u003E leay >TempBoot,pcr point to "tempboot" name lda #PDELIM L0407 sta ,x+ lda ,y+ bpl L0407 copy it into buffer L040D tst <sngldrv beq L042E clra leax >Rename,pcr os9 F$Link bcc L0428 lbsr GetSrc os9 F$Load lbcs Bye lbsr GetDest L0428 tfr u,d ldu <statptr std u000F,u L042E lda #$01 clrb leax >Rename,pcr ldy <u000D leau <bootdev,u os9 F$Fork fork rename tempboot os9gen lbcs Bye os9 F$Wait lbcs Bye tstb lbne Bye tst <sngldrv beq L045F ldu <statptr ldd u000F,u tfr d,u os9 F$UnLink lbcs Bye L045F ldu <statptr tst <eflag extended boot? beq oldstyle branch if not lda <bfdlsn,u get LSN of fdsect stb <ddbt save in DD.BT ldd <bfdlsn+1,u std <ddbt+1 save in DD.BT+1 clr <ddbtsz clear out DD.BTSZ clr <ddbtsz+1 since DD.BT points to FD bra around oldstyle ldb >u048E,u get size of file bits 23-16 stb <ddbt savein DD.BT ldd >u048F,u std <ddbt+1 save in DD.BT+1 ldd <u0006 get size of file bits 15-0 std <ddbtsz save in DD.BTSZ around ldx #$0000 ldu #DD.BT lda <devpath os9 I$Seek seek to DD.BT in LSN0 ldu <statptr lbcs Bye leax ddbt,u point X to modified DD.BT and DD.BTSZ ldy #DD.DAT-DD.BT write it out os9 I$Write lbcs Bye pshs u clra clrb tfr d,x tfr d,u lda <devpath os9 I$Seek seek to LSN0 lbcs Bye puls u leax <lsn0,u ldy #DD.DAT lda <devpath os9 I$Read read first part of LSN0 lbcs Bye ldd #$0001 lbsr Seek2LSN * leax sectbuff,u R.G. Expand memory to hold buffer ldd <lsn0+DD.MAP,u addd #bitmbuf+256 expand memory by DD.MAP+256 bytes os9 F$Mem leax MemErr,pcr lbcs WritExit tfr y,s relocate stack * leax sectbuff,u leax bitmbuf,u ldy <lsn0+DD.MAP,u get number of bytes in device's bitmap lda <devpath os9 I$Read read the FAT into the bitmbuf leax TrkErr,pcr lbcs WritExit ldd #Bt.Track*256 boot track regD=$2200 ldy #$0004 four bits lbsr ABMClear this should test for clear not clear it bcc L0520 ldd #Bt.Track*256 boot track, as it was not clear lbsr Seek2LSN seek to it leax <u0017,u ldy #$0007 lda <devpath os9 I$Read read first seven bytes of boot track lbcs Bye leax <u0017,u ldd ,x cmpd #256*'O+'S is this an OS-9 boot track lbne WarnUser go if not * cmpb #'O * lbne WarnUser * cmpb #'S * lbne WarnUser lda $04,x cmpa #$12 also check for NOP beq L0512 ldd #Bt.Track*256+15 boot track, sector 16 ldy #$0003 sectors 16-18 lbsr ABMClear lbcs WarnUser L0512 clra ldb <lsn0+DD.TKS,u get number of sectors in D tfr d,y ldd #Bt.Track*256 boot track lbsr ABMSet bra L0531 L0520 ldd #Bt.Track*256+4 boot track ldy #$000E sectors 5-18 lbsr ABMClear test rest of track lbcs WarnUser bra L0512 * Write altered map back to disk L0531 ldd #$0001 lbsr Seek2LSN * leax sectbuff,u leax bitmbuf,u ldy <lsn0+DD.MAP,u get number of bytes in device's bitmap lda <devpath os9 I$Write write out the bitmap lbcs Bye * Code added to write alternate boottrack file * BGP - 2003/06/26 tst <btflag beq BTMem get boot track from memory lbsr GetSrc ldx btfname,u lda #READ. os9 I$Open lbcs Bye IFNE 0 * Determine if the size of the file is 4608 bytes * Note, this assumes 18 sectors per track and 256 * bytes per sector. ldb #SS.Size os9 I$GetStt get size tfr u,y put lower 16 bytes of file size in Y ldu <statptr lbcs Bye branch if error cmpx #$0000 correct size? bne BadBTrak branch if not cmpy #$1200 correct size? beq ReadBTrk branch if not BadBTrak leax BadTkMsg,pcr ldy #BadTkMsgL lda #$02 os9 I$WritLn lbra Bye ELSE ldy #$1200 ENDC * Read in boot track file * Y = proper boottrack size ReadBTrk leax u0496,u point to sector buffer os9 I$Read read sector buffer lbcs Bye os9 I$Close close path to boot track lbsr GetDest ldd #Bt.Track*256 boot track lbsr Seek2LSN bra WrBTrack BTMem IFGT Level-1 * OS-9 Level Two: Link to Rel, which brings in boot code pshs u lda #Systm+Objct we want to link to a system object leax >TheRel,pcr point to REL name os9 F$Link link to it lbcs L0724 branch if error tfr u,d puls u subd #$0006 std u007B,u lda #$E0 anda u007B,u ora #$1E ldb #$FF subd u007B,u addd #$0001 tfr d,y ldd #Bt.Track*256 boot track lbsr Seek2LSN ldx u007B,u ELSE * OS-9 Level One: Write out boot track data ldd #Bt.Track*256 lbsr Seek2LSN ldx #Bt.Start ldy #Bt.Size ENDC WrBTrack lda <devpath os9 I$Write lbcs WriteErr os9 I$Close lbcs Bye clrb lbra Bye * Convert Track/Sector to absolute LSN * Entry: A = track, B = sector * Returns in D AbsLSN pshs b ldb <lsn0+DD.FMT,u get format byte andb #FMT.SIDE test sides bit beq AbsLSN1 branch if 1 ldb #$02 else 2 sides fcb $8C skip next two bytes * bra AbsLSN2 AbsLSN1 ldb #$01 1 side AbsLSN2 mul multiply sides times track lda <lsn0+DD.TKS,u get device tracks mul multiply by (sides * track) addb ,s+ add in sector * addb ,s add in sector adca #$00 * leas $01,s rts * Determine bit shift from DD.BIT R.G. * Return shift in regY needed for division FShift pshs d ldd lsn0+DD.BIT,u get sectors per cluster ldy #-1 * This finds number of bit shifts for DD.BIT R.G. SF1 lsra rorb leay 1,y cmpd #0 bne SF1 puls d,pc * Returns bit in bitmap corresponding to LSN in regA * X=bitmap buffer, on exit X points to bitmap byte of our LSN L05AA * We need to divide by DD.BITx8 R.G. pshs y,d ldy btshift,u cmpy #0 beq GBB3 * Divide LSN by DD.BIT R.G. GBB2 lsra rorb leay -1,y bne GBB2 GBB3 stb ,s save lsb andb #7 Make sure offset within table stb 1,s save table mask ldy #3 * Now regY is the number of right shifts required for 8 R.G. ldb ,s recover the lsb GBB4 lsra rorb leay -1,y bne GBB4 * Now regD is the byte number in the FAT leax d,x point regX at the byte puls d leay <BitTable,pcr Point to bit table lda b,y Get bit from table puls pc,y Restore regY and return BitTable fcb $80,$40,$20,$10,$08,$04,$02,$01 Bitmap bit table * Common routine used by ABMSet & ABMClear R.G. * Enter: see ABMSet & ABMClear * Exit: regY=divisor, regD=LSN Initcalc bsr AbsLSN convert A:B to LSN leax bitmbuf,u bsr L05AA getbitmapbit pshs d,y ldy btshift R.G. code to include DD.BIT cmpy #0 bne ABM2 puls d,y,pc ABM2 ldd 2,s recover regY sector count clr bitflag,u * Divide sector count by DD.BIT ABMlp lsra rorb bcc ABMlp2 inc bitflag,u mark carry over ABMlp2 leay -1,y bne ABMlp tst bitflag,u beq ABMnz incb include partial cluster ABMnz tfr d,y regY has been divided by DD.BIT ldd ,s recover content leas 4,s clean stack ABM3 rts * Clear bits in the allocation bitmap * Entry: A = Track, B = Sector, Y = number of bits to clear ABMClear pshs x,y,b,a bsr Initcalc * Back to older code sta ,-s save map bit bmi L05EA go if bit #7 L05D3 lda ,x get byte in bitmap sta u007D,u L05D9 anda ,s test byte on stack bne L0616 go if already set leay -1,y next bit to test beq L0612 lda u007D,u lsr ,s bcc L05D9 leax $01,x L05EA lda #$FF sta ,s bra L05FA L05F0 lda ,x anda ,s bne L0616 leax $01,x leay -$08,y L05FA cmpy #$0008 bhi L05F0 beq L060C lda ,s L0604 lsra leay -$01,y bne L0604 coma sta ,s L060C lda ,x anda ,s bne L0616 L0612 andcc #^Carry bra L0618 L0616 orcc #Carry L0618 leas $01,s puls pc,y,x,b,a * Set bits in the allocation bitmap * Entry: A = Track, B = Sector, Y = number of bits to set ABMSet pshs y,x,b,a lbsr Initcalc * Back to old code sta ,-s bmi L063A lda ,x L062C ora ,s leay -$01,y beq L0658 lsr ,s bcc L062C sta ,x leax $01,x L063A lda #$FF bra L0644 L063E sta ,x leax $01,x leay -$08,y L0644 cmpy #$0008 bhi L063E beq L0658 L064C lsra leay -$01,y bne L064C coma sta ,s lda ,x ora ,s L0658 sta ,x leas $01,s puls pc,y,x,b,a Seek2LSN pshs u,y,x,b,a lbsr AbsLSN pshs a tfr b,a clrb tfr d,u puls b clra tfr d,x lda <devpath os9 I$Seek lbcs WriteErr puls pc,u,y,x,b,a clra clrb tfr d,x tfr d,u lda <devpath os9 I$Seek leax <lsn0,u ldy #DD.DAT lda <devpath os9 I$Write bcs Bye rts * Routine to write various error messages then exiting WriteErr leax >ErrWrit,pcr bra WritExit BadName ldb #E$BPNam ShowHelp equ * IFNE DOHELP leax >HelpMsg,pcr ELSE clrb bra Bye ENDC WritExit pshs b lda #$02 ldy #256 os9 I$WritLn puls b Bye os9 F$Exit * Source/Destination Disk Switch Routine GetSrc pshs u,y,x,b,a clra bra TstSingl GetDest pshs u,y,x,b,a lda #$01 TstSingl tst <sngldrv beq L06FD AskUser pshs a AskUser2 tsta bne Ask4Dst Ask4Src leax >Source,pcr ldy #SourceL bra L06D4 Ask4Dst leax >Destin,pcr ldy #DestinL L06D4 bsr DoWrite leax ,-s ldy #$0001 lda #$02 read from stderr os9 I$Read read one char lda ,s+ eora #'C anda #$DF beq L06F9 branch if it's a C leax >TheBell,pcr ldy #$0001 bsr DoWrite else ring the error bell bsr WriteCR * BUG FIX: in certain cases, puls a was being done twice. lda ,s ++ * puls a -- bra AskUser2 ++ * bne AskUser -- L06F9 bsr WriteCR puls a L06FD puls pc,u,y,x,b,a DoWrite lda #$01 os9 I$WritLn rts WriteCR pshs y,x,a lda #$01 leax >CarRet,pcr ldy #80 os9 I$WritLn puls pc,y,x,a ItsFragd leax >BootFrag,pcr SoftExit ldb #$01 bra WritExit WarnUser leax >TWarn,pcr bra SoftExit IFGT Level-1 L0724 leax >CantRel,pcr lbra WritExit ENDC emod eom equ * end