diff 3rdparty/utils/gene/vfy.asm @ 2977:2e740da2088e

3rdparty/utils: Add disk with Gene's bootlink and vfy utilities
author Tormod Volden <debian.tormod@gmail.com>
date Sat, 05 Apr 2014 01:01:32 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/utils/gene/vfy.asm	Sat Apr 05 01:01:32 2014 +0200
@@ -0,0 +1,1407 @@
+* vfy.asm, module file verification tool
+* Copyright (C) 1993-2014  Gene Heskett
+* License: GPLv2
+* See vfy.doc for more licensing information
+ 
+          opt w 86
+          nam vfy Edition 17
+          ttl A new verify, finds, fixes modules in files
+*************************************************
+* This verify will search thru any file to find a
+* valid module header in the $87CD format, get that
+* modules size, do a header parity/crc check on it,
+* and if the -f option is on, will update the header
+* parity and CRC bytes in the file too. It then
+* resumes the search of the named file for more
+* modules and loops till <eof>. If it finds <eof>
+* while doing the crc, the error is reported as such.
+* 2/18/93 version 7
+* The housekeeping was pretty well complete, so it
+* wasn't very much trouble to add the file split
+* ability to this, now we can even split out the
+* kernal track modules, plus head and tail too! Ver 8
+* 11.24.93 GH Ver 9Adding some stuffs from "fixmod" here 
+* Now have total control over its vebosity 11/24/93 GH Ver 10
+* 11/24/93 GH, -ua,-ur,-ut,-ul=$hexval installed
+* 11/26-27/93 GH fine tuning the above GH Ver 11
+* 01/25/94 GH another minor mod so it doesn't complain
+* if the header parity is correct even if told to fix GH Ver 12
+* 11/11/94 GH Ver 13. bug smashing, didn't update datasize
+* if header parity was ok. Wrong branch at hdr parity check,
+* if good it skipped the header update! Shame on me. :-(
+* 11/14/94 GH Now it beeps and updates the header even if
+* theres nothing wrong if the -f option is on. It doesn't
+* hurt anything except the speed, but looking to fix
+* it anyway. Now it does a header/datasize update
+* independantly of the crc fixes, fixing only the
+* header of the named file for one of the header
+* fix variables, and the crc of that named file.
+* If the -f option is on, it will fix the crc's
+* and headers all thru the file. A good way to
+* clean up after ded when working on hand patches
+* in the kernal track.
+* 05/04/95 GH, wasn't showing the correct info from the
+* INIT module. Several minor changes there. Now ed #15
+* 05/10/95 GH, adding the ability to change one module
+* in a file via the name match, -n=modname
+* also put verbose control in (finally), now edition 16
+* Seeing if its possible to make it split a $62CD library
+* after looking over the header format for an ROF file,
+* it might be better to do a whole new "libsplit"
+          ifp1
+          use  os9.d
+          endc
+ver       set  17
+atrev     set  reent+1
+*
+          mod  len,name,prgrm+objct,atrev,entry,dsiz
+
+crcacc    rmb  1 for new crc's
+crcac2    rmb  1
+crcac3    rmb  1
+filecrc1  rmb  1 for the actual crc
+filecrc2  rmb  1
+filecrc3  rmb  1
+numptr    rmb  2 ptr to src
+linptr    rmb  2 ptr to linbuff
+linbuff   rmb  8 max len for printables
+
+**** the modules header directly loaded ****
+modid1    rmb  1 the $87
+modid2    rmb  1 the $CD
+modlen    rmb  2 for the modules length
+modname   rmb  2 offset ptr to module name
+typelang  rmb  1
+modatrev  rmb  1
+checksum  rmb  1
+execptr1  rmb  1 the exec offset in the header
+execptr2  rmb  1 more exec address
+pdatasz1  rmb  1 the permanent data size from the header
+pdatasz2  rmb  1 more data size or IRQ Poll count
+dvtblent  rmb  1 the device table entries value for INIT
+***** the above loaded directly from the file ****
+
+modhstrt  rmb  2 set by sethead at start of
+modlstrt  rmb  2 module being checked
+lmnscrc   rmb  2 length minus crc for seeks
+flenms16  rmb  2 overall file size ms16
+flenls16  rmb  2 ditto             ls16
+filesiz   rmb  2 size of individual module
+modpos    rmb  2 where in module now
+seekms16  rmb  2 for seeks
+seekls16  rmb  2 ditto
+moddone   rmb  1 flag for last read
+seperat   rmb  1 flag for seperations
+kernal    rmb  1 flag to save it all
+kbptrms   rmb  1 msb of int
+kbptr     rmb  1 ptr to krnlbuf location
+exdir     rmb  1 for defining the access attributes
+inpath    rmb  1 for pathnum
+outpath   rmb  1 flag and output paths
+kpath     rmb  1 for kernal extras path
+fixit     rmb  1 tally for fix it
+fixname   rmb  1 fix only this name
+fixty     rmb  1 tally for individual fix
+fixla     rmb  1 ditto
+fixat     rmb  1 ditto
+fixrv     rmb  1 ditto
+sizyet    rmb  1 size not displayed yet if set
+exectyp   rmb  1 is executable
+lftnbbl   rmb  1 controls left-right nibble processing
+verbose   rmb  1 do we wanta see the results
+updtrv    rmb  1 update revision nibble
+updtat    rmb  1 update the attr nibble
+updtty    rmb  1 update the modules type nibble
+updtla    rmb  1 update the modules language nibble
+updtdtsz  rmb  2 update modules memsize integer
+updthead  rmb  1 controls the re-write of the header
+cmpname   rmb  32 to hold wanted name
+datsiz    equ  . memory from 0 to here gets cleared
+mdlname   rmb  32 room for name
+krnlbuf   rmb  64 enough for what I've seen
+buffer    rmb  256 save the disk buffer
+params    rmb  200
+stack     rmb  200
+dsiz      equ  .
+*
+name      fcs  /VFY/
+          fcb  ver
+helpmsg   fcb  $0D,$0A
+          fcc  'Syntax: vfy [-options] [-options] /path/filename'
+          fcb  $0D,$0A
+          fcc  / Options -> -f  =fix (whole file) IF CRC is bad./
+          fcb  $0D,$0A
+          fcc  /         -> -v  =work silently./
+          fcb  $0D,$0A
+          fcc  /         -> -n=name fix or adjust only "name" module./
+          fcb  $0D,$0A
+          fcc  /         -> -x  =file is in EXEC dir./
+          fcb  $0D,$0A
+          fcc  /         -> -s  =seperate MERGED file./
+          fcb  $0D,$0A
+          fcc  /         -> -sk =seperate KERNAL file./
+          fcb  $0D,$0A
+         fcc  /         -> -ua=$hexchar -ur=$hexchar -ut=$hexchar -ul=$hexchar/
+          fcb  $0D,$0A
+         fcc  / a=att nibl, r=rev nibl, t=type nibl, l=lang nibl, "$" required/
+          fcb  $0D,$0A
+          fcc  /         -> -ud=$hexint to add (modulo $10000) data size./
+          fcb  $0D,$0A
+          fcc  /       if -u, -f is enabled for first file encountered./
+          fcb  $0D,$0A
+          fcc  /       if -n, -f is enabled for named file encountered./
+          fcb  $0D,$0A
+cpyrit    fcc  /  VFY (c) 1993, 1994, 1995 by Maurice E.(Gene) Heskett/
+          fcb  $0D,$0A
+msgsiz    equ  *
+advise0   fcc  /A header file called /
+kernal0   fcc  /KernalHead/
+          fcb  $0D put cr on name
+krnlhsz   equ  *
+advise1   fcc  /A tail file called /
+kernal1   fcc  /KernalTail/
+          fcb  $0D put cr on name
+krnltsz   equ  *
+advlen    fcc  / with a length of $/
+advend    fcc  / has been made./
+hednamsg  fcc  /Header for    : /
+hedckmsg  fcc  /Header parity : $/
+ckbadsiz  equ  *
+fixxmsg   fcc  / Repaired to: $/
+newln     fcb  $0d,$0a
+hdgdsiz   equ  *
+modlnmsg  fcc  /Module size   : $/
+crcmsg    fcc  /Module CRC is : $/
+crcmsiz   equ  *
+gdmsg     fcc  / (good)/
+          fcb  $0d,$0a
+gdsiz     equ  *
+shdabeen  fcc  ' S/B $'
+badmsg    fcc  / (bad)/
+          fcb  $07,$07,$07,$07,$07
+badsiz    equ  *
+mdoffset  fcc  /Module found at offset $/
+mdoffend  fcc  / in this file/
+mdoffnln  fcb  $0d,$0a
+ftopmem   fcc  /Top of free ram $/
+ftopsiz   equ  *-ftopmem
+ptabent   fcc  /, IRQ poll table entries $/
+ptabsiz   equ  *-ptabent
+dvtabent  fcc  /, Device table entries $/
+dvtabsiz  equ  *-dvtabent
+flenmsg   fcc  /Length of file: $/
+howmany   fcc  /Bytes read    : $/
+execoff   fcc  /Exec. off     : $/
+datasiz   fcc  /Data Size     : $/
+vertion   fcc  /Edition       : $/
+tplgatrv  fcc  'Ty/La At/Rv   : $'
+
+******** The lookup table for TYPE
+typelook  equ  *
+typunksz  fdb  sstmod-unktyp zero is not defined
+typunkst  fdb  unktyp-*
+typprgsz  fdb  sbrutn-prgtyp 1 is program
+typprgst  fdb  prgtyp-*
+typsubsz  fdb  mltmod-sbrutn 2 is subroutine
+typsubst  fdb  sbrutn-*
+typmltsz  fdb  dtmtyp-mltmod 3 is multi-mod
+typmltst  fdb  mltmod-* whatever that is
+typdatsz  fdb  unktyp-dtmtyp
+typdatst  fdb  dtmtyp-*
+typ5siz   fdb  sstmod-unktyp
+typ5str   fdb  unktyp-*
+typ6siz   fdb  sstmod-unktyp
+typ6str   fdb  unktyp-*
+typ7siz   fdb  sstmod-unktyp
+typ7str   fdb  unktyp-*
+typ8siz   fdb  sstmod-unktyp
+typ8str   fdb  unktyp-*
+typ9siz   fdb  sstmod-unktyp
+typ9str   fdb  unktyp-*
+typAsiz   fdb  sstmod-unktyp
+typAstr   fdb  unktyp-*
+typBsiz   fdb  sstmod-unktyp
+typBstr   fdb  unktyp-*
+typCsiz   fdb  fmntyp-sstmod
+typCstr   fdb  sstmod-*
+typDsiz   fdb  ddrtyp-fmntyp
+typDstr   fdb  fmntyp-*
+typEsiz   fdb  ddstyp-ddrtyp
+typEstr   fdb  ddrtyp-*
+typFsiz   fdb  ddssiz-ddstyp
+typFstr   fdb  ddstyp-*
+
+*********** The type defines ***********
+typstrs   equ  *
+prgtyp    fcc  /Program module/
+sbrutn    fcc  /Subroutine/
+mltmod    fcc  /Multi-Mod/
+dtmtyp    fcc  /Data module/
+unktyp    fcc  /Unknown type/ from 5 to B
+sstmod    fcc  /System module/
+fmntyp    fcc  /File manager/
+ddrtyp    fcc  /Device driver/
+ddstyp    fcc  /Device descriptor/
+ddssiz    equ  *
+
+*********** The lookup table for LANG
+langlook  equ  *
+lan0siz   fdb  std809-sysdat 0 is data
+lan0str   fdb  sysdat-* 
+lan1siz   fdb  b09typ-std809 1 is 6809 object
+lan1str   fdb  std809-*
+lan2siz   fdb  pastyp-b09typ 2 is Basic09 I-code
+lan2str   fdb  b09typ-*
+lan3siz   fdb  ftntyp-pastyp 3 is Pascal P-code
+lan3str   fdb  pastyp-*
+lan4siz   fdb  ccityp-ftntyp 4 is Fortran I-code
+lan4str   fdb  ftntyp-*
+lan5siz   fdb  cbltyp-ccityp 5 is C I-code, in .r mods maybe
+lan5str   fdb  ccityp-*
+lan6siz   fdb  obj309-cbltyp 6 is Cobol I-code
+lan6str   fdb  cbltyp-*
+lan7siz   fdb  unklan-obj309 7 is 6309 object (NATIVE mode)
+lan7str   fdb  obj309-*
+lan8siz   fdb  unklsz-unklan 8 undefined
+lan8str   fdb  unklan-*
+lan9siz   fdb  unklsz-unklan 9 undefined
+lan9str   fdb  unklan-*
+lanAsiz   fdb  unklsz-unklan 10 undefined
+lanAstr   fdb  unklan-*
+lanBsiz   fdb  unklsz-unklan 11 undefined
+lanBstr   fdb  unklan-*
+lanCsiz   fdb  unklsz-unklan 12 undefined
+lanCstr   fdb  unklan-*
+lanDsiz   fdb  unklsz-unklan 13 undefined
+lanDstr   fdb  unklan-*
+lanEsiz   fdb  unklsz-unklan 14 undefined
+lanEstr   fdb  unklan-*
+lanFsiz   fdb  unklsz-unklan 15 undefined
+lanFstr   fdb  unklan-*
+
+*********** The language defines *********
+lanstrs   equ  *
+sysdat    fcc  /, Data/
+std809    fcc  /, 6809 object/
+b09typ    fcc  /, Basic09 I-code/
+pastyp    fcc  /, Pascal P-code/
+ftntyp    fcc  /, Fortran I-code/
+ccityp    fcc  /, C I-code/
+cbltyp    fcc  /, Cobol I-code/
+obj309    fcc  /, 6309 object/
+unklan    fcc  /, Unknown language/
+unklsz    equ  *
+
+********** The attr defines ************
+rent1     fcc  /, Re-enterable/
+rdonly    fcc  ', R/O'
+rwattr    fcc  ', R/W'
+ntv309    fcc  /, NATIVE MODE!/
+ntvend    equ  *
+
+******* Beginning of some subroutines *******
+* SKEQDLR - skip the = and $
+*  or detect a cmndline error
+skeqdlr  lda  ,x+
+         decb
+         cmpa #'=
+         lbne help
+         lda  ,x+
+         decb
+         cmpa #'$
+         lbne help
+         lda  ,x+ get next char as value to use
+         decb
+         rts  and return to sender
+
+***********************************
+* A switchable showit routine
+showit    pshs  a,cc
+          tst  <verbose
+          beq  showend
+          lda  #$02 stderr
+          os9  I$Write
+showend   puls  a,cc
+          rts
+
+**********************************
+* A switchable newlnfd, exits thru showend
+newlnfd   pshs a,cc
+          tst  <verbose
+          beq  showend
+          lda  #$02
+          os9  I$Writln
+          bra  showend
+
+****** the display subroutine ******
+* entry - offset into lookup table in B
+* entry - address of lookup table in X
+tylandis  clra just in case
+          abx  1st string location in x, add only!
+          ldy  ,x++ get size to print
+          ldd  ,x get offset to object itself
+          pshs x save pointer
+          addd ,s++ add offset & puls x
+          tfr  d,x back to x
+          bsr  showit
+          rts  thats all for now folks
+
+*********************************
+* dfinemd - a subroutine to display
+* the modules header defined data
+*  first, set the tallies as to what it is
+dfinemd   leax exectyp,u
+          clra
+          ldb  #verbose-exectyp
+dfinclr   sta  ,x+
+          decb
+          bne  dfinclr
+          ldb  <typelang
+          andb #$F0 get type define
+          lsrb b/2 
+          lsrb b/4 so increment thru list=4 bytes
+          leax typelook,pcr top of type string list
+          bsr  tylandis
+          ldb  <typelang
+          andb #$0F
+          beq  dfn1
+          inc  <exectyp
+dfn1      aslb b*2
+          aslb b*4 see reason above on b/4
+          leax langlook,pcr top of language string list
+          bsr  tylandis
+att0      ldb  <modatrev
+          bitb #$80
+          beq  att1
+          leax rent1,pcr
+          ldy  #rdonly-rent1
+          bsr  showit
+          ldb  <modatrev
+att1      bitb #$40 gimix module write protect
+          bne  att2
+          leax rdonly,pcr
+          ldy  #rwattr-rdonly
+          bsr  showit
+          ldb  <modatrev
+          bra  att3
+att2      leax rwattr,pcr
+          ldy  #ntv309-rwattr
+          lbsr showit
+          ldb  <modatrev
+att3      bitb #$20
+          beq  dis0
+          leax ntv309,pcr
+          ldy  #ntvend-ntv309
+          lbsr showit
+dis0      leax newln,pcr
+          ldy  #2
+          lbsr newlnfd
+          tst  <exectyp
+          beq  dis2 not executable code!
+          ldb  <typelang testing for DESCR module
+          cmpb #$F1 a device descriptor?
+          beq  dis3 no, skip the Exec,Data reports
+          leax execoff,pcr to msg
+          ldy  #datasiz-execoff
+          lbsr showit 'Exec offset :$'
+          leax execptr1,u
+          stx  <numptr
+          ldb  #$02
+          lbsr printit show num
+          leax newln,pcr 
+          ldy  #2
+          lbsr newlnfd
+* numptr pointing at data size in module
+skdatup   leax datasiz,pcr
+          ldy  #vertion-datasiz
+          lbsr showit 'Data size  :$'
+          ldb  #$02
+          lbsr printit perm data size
+          leax newln,pcr 
+          lbsr newlnfd newline it
+          bra  dis3
+dis2      ldb  <typelang testing for INIT module
+          cmpb #$C0 is it system+data=INIT?
+          bne  dis3 no, go
+          leax execptr1,u get it started at the right place
+          stx  <numptr
+          leax ftopmem,pcr
+          ldy  #ftopsiz
+          lbsr showit
+          ldb  #$03
+          lbsr printit
+          leax ptabent,pcr
+          ldy  #ptabsiz
+          lbsr showit
+          ldb  #$01
+          lbsr printit
+          leax dvtabent,pcr
+          ldy  #dvtabsiz
+          lbsr showit 
+          ldb  #$01
+          lbsr printit
+          leax newln,pcr
+          lbsr newlnfd 
+dis3      clr  <sizyet
+          rts
+
+*******************************
+* A routine to make ascii->hex
+* ENTRY:  valid data in a
+* EXIT :  hex in a
+ascihex   cmpa #'0
+          lblo help wrong!
+          cmpa #'9
+          bls  ascinum
+** no numbers get thru here **
+          cmpa #'Z
+          blo asciup
+          anda #$DF
+asciup    cmpa #'F
+          lbhi help
+          suba #$07
+ascinum   suba #'0 ok sub the first $30
+shiftit   tst  <lftnbbl
+          beq  asciret
+          lsla
+          lsla
+          lsla
+          lsla if lftnbbl shift it to left nibble
+asciret   rts should be ok, but Murphy is watching!
+
+********************************
+* The REAL start of this program!
+* ENTRY: a command line full of data
+* pointed to by regs.x
+entry     pshs d,x,y save possible params
+          leax crcacc,u clear some memory
+          ldb  #datsiz out for us.
+          clra
+clrloop   sta  ,x+
+          decb
+          bne  clrloop
+          lda  #READ. setup for data dir
+          sta  <exdir
+          sta  <verbose to enable it unless shut off
+          puls d,x,y
+          decb arguments?
+          lbeq help no,go
+          incb back to right count!
+
+* and fall thru to setup, my command line checker with
+* syntax relaxations, can take vfy -x -f filename,
+* or vfy -fx (-xf) filename, also -s, -sk, -k alone illegal
+* also -v now works to shut it up GH
+setup     lda  ,x+ get a char from cmnd line
+          decb track cmndline chars left
+          lbeq help
+setret    cmpa #$20 a space?
+          beq  setup yup, go get next char
+          cmpa #'- is "-"?
+          beq  setup1 yup, go do the options
+          leax -1,x not space or -, rtn ptr
+          incb to restore count
+          lbra openit godoit, our other exit from here
+
+setup1    lda  ,x+
+          decb 
+          cmpa #$41 is regs.a<#'A alpha char?
+          bmi  setret wasn't, go
+          anda #$df else make uppercase
+
+***** Edition 16 addition *****
+          cmpa #'V
+          bne setfix
+          clr  <verbose shut it up
+          bra  setup1
+
+setfix    cmpa #'F
+          bne  setx nope, go
+          sta  <fixit to nz it
+          lda  #UPDAT.+SHARE. we don't wanna share
+setatts   ora  <exdir if we're fixing it
+          sta  <exdir
+          bra  setup1
+setx      cmpa #'X
+          bne  setsepU 
+          lda  #EXEC.
+          bra  setatts
+
+************ setsepU ************
+* added to pick up args for "fixmod"
+* like operations 
+setsepU   cmpa #'U
+          lbne setsepS
+          lda  ,x+ get next char to tell us what to do
+          decb track data
+          lbeq help can't be out here
+          anda #$DF make uppercase
+          cmpa #'A change attr nibble?
+          bne  setsepR
+setSepA   lbsr skeqdlr checks errs, returns good char
+          sta  <lftnbbl to nz it so ascihex will shift
+          sta  <fixat to tally new data avail
+          lbsr ascihex go make it a hexval
+          sta  <updtat 
+          clr  <lftnbbl cancel the order
+          inc  <updthead
+          bra  setup
+
+setsepR   cmpa #'R change rev nibble?
+          bne  setsepT nope, maybe its Type
+          lbsr skeqdlr
+          sta  <fixrv to tally new data avail
+          lbsr ascihex
+          sta  <updtrv
+          inc  <updthead
+          bra  setup
+
+setsepT   cmpa #'T
+          bne  setsepL maybe its Language nibble?
+          lbsr skeqdlr
+          sta  <lftnbbl to nz it
+          sta  <fixty to tally new data avail
+          lbsr ascihex
+          sta  <updtty new Type value in left nibble
+          clr  <lftnbbl shut down the shifter
+          inc  <updthead
+          lbra setup
+
+setsepL   cmpa #'L is it change lang nibble?
+          bne  setsepD might be data size
+          lbsr skeqdlr
+          sta  <fixla to tally new data avail
+          lbsr ascihex
+          sta  <updtla
+          inc  <updthead
+          lbra setup
+
+*************** setsepD ***************
+* if more than 4 valid hex digits are entered
+* on cmnd line, it will keep on looping,
+* keeping the last 4 in updtdtsz. You can add
+* as little as one byte with this retriever or
+* subtract since the addition is modulo $8000,
+* use -ud=$FFFE to subtract one byte!
+setsepD   lbsr skeqdlr see if right syntax used
+setdtsz   lbsr ascihex returns val in reg.a
+          pshs b we want this order on the stack
+          pshs a save the nibble on the stack
+          ldd  <updtdtsz
+          lslb
+          rola times 2 now
+          lslb
+          rola times 4 now
+          lslb
+          rola times 8 now
+          lslb
+          rola updtdtsz now *16
+          orb  ,s+ least sig nibble dummy!
+          std  <updtdtsz
+          puls b thats why we wanted this order
+          lda  ,x+
+          decb tryin to track cmdln data used
+          lbeq help better be more data here!
+          cmpa #$20
+          lbeq setup oops, out of data but ok
+          lbmi help real probs, no filename!
+          inc  <updthead
+          bra  setdtsz
+
+************** setsepS ***************
+* sets it up to seperate a merged file,
+* the kernal to be specific, but works
+* on os9boot files too.
+setsepS   cmpa #'S
+          bne  SetName this was to help
+          sta  <seperat make nz to enable
+          lda  ,x+
+          decb obscure bug fixing
+          anda #$DF
+          cmpa #'K
+          bne setsep1
+          lda #$30 a zero
+          sta  <kernal to nz it and furnish number
+          lbra setup1
+setsep1   leax -1,x
+          incb bug fixing
+          lbra setup1
+
+****** Edition 16 addition ******
+SetName   cmpa #'N
+          lbne help
+          lda  ,x+
+          cmpa #'=
+          lbne help
+          pshs y we're gonna diddle it, save it
+          leay cmpname,u
+NameSave  lda  ,x+
+          cmpa #32
+          bls  EndNmSv must be done, back out
+          cmpa #'9
+          bls  noupcase
+          anda #$DF name uppercase
+* ok, lets see what its doing
+noupcase  sta  ,y+ and save it
+          bra  NameSave
+EndNmSv   clr  ,y zero mark end of name
+          inc  <fixname
+          puls y
+          bra  setsep1
+
+**** end of setup, openit start ****
+openit    decb filename there yet?
+          lbeq help no, go squawk
+          lda  <fixat
+          adda <fixrv
+          adda <fixla
+          adda <fixty
+          adda <fixname
+          adda <updthead
+          beq  openatok
+          lda  #UPDAT.+SHARE.
+          ora  <exdir
+          sta  <exdir
+* first, if named, get rid of updthead silliness
+openatok  tst  <fixname did we name a module?
+          beq  openit1 no, skip this
+          clr  <updthead one or the other bud!
+openit1   lda  <exdir get attributes
+          os9  I$Open
+          lbcs help oh-oh, file not avail
+          sta  <inpath
+          lbsr getsiz get overall size
+          lbsr seekmod start at 0, old readit lbl
+readit    lbsr readabyt opens head/tail files too
+          lda  ,x
+readit1   cmpa #$87 look for 1st byte
+          bne  readit
+          sta  <modid1
+readit2   lbsr readabyt updates filepos via addseek
+          lda  ,x
+          cmpa #$CD
+          bne  readit1
+          sta  <modid2 we found a file!
+          ldx  #$0002 we've got 2 bytes of 
+          stx  <modpos a module, record it
+          dec  <kbptr cancel 2 outa non-mod buf
+          dec  <kbptr
+          beq  readit3 no use if zero
+          tst  <kernal are we saving all
+          beq  readit3
+          lbsr openkern makes filepath
+          lbsr clskrnl writes kbptr size buffer and closes up
+readit3   clr  <kbptr so's it don't accumulate
+          lda  <inpath get rest of header
+          leax modlen,u
+          ldy  #$000C get dev table entries too
+          os9  I$read get those 12 bytes
+          lbsr addsect those 12 bytes to total len
+          ldd  <modlen
+          subd #$03
+          std  <lmnscrc
+          lbsr sethead ->GETNAM->SEEKMOD
+          leax mdoffset,pcr
+          ldy  #mdoffend-mdoffset
+          lbsr showit
+          leax modhstrt,u
+          stx  <numptr
+          ldb  #$04
+          lbsr printit
+          leax mdoffend,pcr
+          ldy  #ftopmem-mdoffend
+          lbsr showit
+initcrc   leax crcacc,u
+          ldb  #6
+          lda  #$FF
+psetcrc   sta  ,x+
+          decb 
+          bne  psetcrc
+          lbsr chkhead go check/fix ty/la at/rv, parity, pdatasz
+          ldy  #$0E (was $D)Because parity fixed in mem,
+          leax modid1,u crc displayed is right IF
+          os9  F$CRC we do crc of 1st 14 bytes in mem
+* after chkhead! It should arrive here with modpos=14
+          tst  <seperat
+          beq  docrc0
+          lbsr openout
+docrc0    inc  <sizyet
+docrc     leax buffer,u
+          ldd  <lmnscrc module length-crcbytes
+          subd <modpos
+          cmpd #$100
+          bhi  getmore
+          tfr  d,y
+          inc  <moddone
+          bra  getlast
+getmore   ldy  #$100 get a sectors worth
+getlast   lda  <inpath
+          os9  I$Read 
+          lbsr addsect doesn't chg x,y
+          tst  <sizyet
+          beq  getcont
+          pshs d,x,y save count
+          lbsr dfinemd
+          puls d,x,y
+getcont   leax buffer,u the data
+          pshs x,y save the pointer and quantity
+          os9  F$Crc U already points at crcacc!
+          puls x,y restore
+          lda  <outpath
+          beq  doneyet we're not spliting it
+          os9  I$Write
+          lbcs help report error and quit  
+doneyet   tst  <moddone
+          beq  docrc
+          pshs y
+          ldd  <crcacc now copy crc to filecrc
+          coma and make valid
+          comb 
+          std  <filecrc1 in case its bad
+          ldb  <crcac3 ditto
+          comb 
+          stb  <filecrc3 ditto
+          bcc  donyet2
+          comb clear any carry
+donyet2   tfr  x,d
+          addd ,s++ puls the Y
+          tfr  d,x x now=crc location in buffer
+          pshs x save it
+          lda  <inpath
+          ldy  #$03 the 3 crc bytes
+          os9  I$Read
+          lbsr addsect add to filepos
+          puls x retrieve crc addr, y still=3
+          os9  F$CRC whole modules crc now in crcacc
+          lbsr chkcrc go check, correct it
+          lda  <outpath
+          beq  dunyet if zero, no path
+          leax filecrc1,u put good one out
+          ldy  #3
+          os9  I$Write
+          os9  I$Close
+          clr  <outpath
+dunyet    clr  <moddone
+          lbra readit see if more file
+
+*************************************
+* The EOF is found, close up, go home
+cleanup   bcc  cleanup1
+          comb we get here with the carry set
+cleanup1  pshs x,u save so's the tail is right
+          lda  <inpath
+          ldu  <flenls16 go back to real end of file
+          ldx  <flenms16
+          os9  I$Seek to end of file
+          puls x,u recover tail pointers
+          os9  I$Close and close up w/o len change
+          tst  <kernal are we saveing a kernal?
+          beq  cleanup2 if 0, nothing to write! 
+          lbsr openkern go open a path
+          lbsr clskrnl write and close it
+          bcc  cleanup2
+          comb clear error flag
+cleanup2  leax howmany,pcr
+          ldy  #execoff-howmany
+          lbsr showit print the string
+          leax seekms16,u point at total length
+          stx  numptr of file
+          ldb  #$04 bytes to print
+          lbsr printit convert to ascii and print
+          leax newln,pcr hang a newline on it
+          lbsr newlnfd
+alldun    clrb
+          os9  F$Exit all done folks!
+
+*************************************
+* CHKHEAD - checks, fixes header checksum
+*    entry: header in memory at modid1,u
+chkhead   leax hednamsg,pcr
+          ldy  #hedckmsg-hednamsg
+          lbsr showit 'Header for: '
+          leax mdlname,u
+          ldy  #$20 maxlength
+          lbsr newlnfd show the filename with cr
+          leax hedckmsg,pcr
+          ldy  #ckbadsiz-hedckmsg
+          lbsr showit Header parity : $
+          ldb  #$01 only one byte to convert
+          leax checksum,u pass address of checksum
+          stx  <numptr
+          lbsr printit the parity byte
+
+***********************************
+* see if we got anything to fix
+* check attr,rev,typ,lang,dsize
+* and update the memory image
+          lda  <updthead will be 1 if right module
+          adda <fixit
+          beq  psetpar nothin to fix
+          tst  <fixat else
+          beq  revchk
+atchk     lda  <modatrev
+          anda #$0F clear the attrib nibble
+          ora  <updtat add in the attrib nibble
+          sta  <modatrev
+          clr  <fixat
+revchk    tst  <fixrv
+          beq  tychk
+          lda  <modatrev
+          anda #$F0 leave at nibble alone
+          ora  <updtrv
+          sta  <modatrev
+          clr  <fixrv
+tychk     tst  <fixty
+          beq  langchk
+          lda  <typelang
+          anda #$0F clear out the type
+          ora  <updtty
+          sta  <typelang
+          clr  <fixty
+langchk   tst  <fixla
+          beq  chkdtsz
+          lda  <typelang
+          anda #$F0 leave upper nibble alone
+          ora  <updtla
+          sta  <typelang
+          clr  <fixla
+chkdtsz   ldd  <updtdtsz
+          cmpd #$0000 anything there?
+          beq  psetpar
+          ldd  <pdatasz1
+          addd <updtdtsz we're not saveing the carry folks!
+          std  <pdatasz1
+          clra
+          clrb
+          std  <updtdtsz to make it one time only!
+psetpar   lda  #$FF pset parity accumulator
+          ldb  #$08
+          leax modid1,u
+headchk   eora ,x+ and check the checksum
+          decb
+          bne  headchk
+          cmpa ,x s/b equal
+          beq  fxittst go see if data needs updt
+          pshs a,x else save a few things
+          leax badmsg,pcr show its bad
+          ldy  #badsiz-badmsg
+          lbsr showit ' (bad)'
+          puls a,x a had correct parity
+          sta  ,x else fix in memory
+          stx  <numptr point at it
+          leax shdabeen,pcr
+          ldy  #badmsg-shdabeen
+          lbsr showit ' S/B $'
+          ldb  #$01 only one byte to convert
+          lbsr printit numptr already has src
+fxittst   lda  <updthead either will trigger fix
+          adda <fixit if neither one is on, go
+          beq  okmsg leave it alone
+
+*******************************************
+* enableing the files fix, its now good in memory
+          pshs u
+          ldx  <modhstrt
+          ldu  <modlstrt 
+          lda  <inpath
+          os9  I$Seek back up to $87CD bytes
+          puls u
+          leax modid1,u
+          ldy  #$0D bytes to write
+          lda  <inpath
+          os9  I$Write insert ty/la at/rv,parity,exec,pdatasz in file
+          lbcs help
+          lbsr seekmod to restore the file pointer
+          leax fixxmsg,pcr
+          ldy  #newln-fixxmsg
+          lbsr showit ' Repaired to $'
+          leax checksum,u
+          stx  <numptr
+          ldb  #$01 numptr already set
+          lbsr printit
+okmsg     leax gdmsg,pcr
+          ldy  #gdsiz-gdmsg
+          lbsr newlnfd ' (Good)\n'
+          lbsr seekmod to reset file ptr
+headout   leax modlnmsg,pcr
+          ldy  #crcmsg-modlnmsg
+          lbsr showit 'Module size   : $'
+          leax modlen,u point to size in header
+          stx  <numptr
+          ldb  #$02
+          lbsr printit
+          leax newln,pcr
+          lbsr newlnfd finish this up
+          leax vertion,pcr
+          ldy  #tplgatrv-vertion
+          lbsr showit 'Edition      : $'
+          leax mdlname,u
+fndend    lda  ,x+
+          cmpa #$0D
+          bne  fndend
+          stx  <numptr is -> at edition now
+          ldb  #$01 one hex byte only
+          lbsr printit show it
+          leax newln,pcr
+          ldy  #hdgdsiz-newln
+          lbsr newlnfd 
+          leax tplgatrv,pcr
+          ldy  #typelook-tplgatrv
+          lbsr showit
+          leax typelang,u
+          stx  <numptr
+          ldb  #$01
+          lbsr printit
+          ldx  <linptr
+          lda  #$20 space it out for the
+          sta  ,x+ following atrev byte
+          sta  ,x+
+          sta  ,x+ 3 spaces
+          lda  #'$ and a $ sign
+          sta  ,x
+          ldx  <linptr
+          ldy  #$04
+          lbsr showit show '   $'
+          ldb  #$01 the prev call inc'ed numptr
+          lbsr printit to the atrv byte!
+          leax newln,pcr
+          ldy  #$02
+          lbsr newlnfd
+          rts
+          
+*************************************
+* CHKCRC of module 
+* when called, it expects to see the $800FE3
+* (seed polynomial) in the crc accumulator
+chkcrc    pshs x save ptr to modules crc
+          leax crcmsg,pcr
+          ldy  #crcmsiz-crcmsg
+          lbsr showit Modules CRC is: $
+          puls x
+* Now, x still points at the modules crc bytes!
+* so we don't need a seperate number buffer
+          pshs x we need it later
+          stx  <numptr
+          ldb  #$03 three bytes to display
+          lbsr printit
+          puls x
+          ldd  <crcacc now do the check
+          cmpd #$800F first two bytes
+          bne  badcrc
+          lda  <crcac3
+          cmpa #$E3 third
+          bne  badcrc
+          pshs x save it again
+crcdun    leax gdmsg,pcr
+          ldy  #gdsiz-gdmsg
+          lbsr showit
+          leax newln,pcr extra linefeed
+          ldy  #$02 to seperate reports
+          lbsr newlnfd
+          clr <updthead stop this silliness
+          puls x fergot it once, major crash!
+          rts
+
+*************************************
+* BADCRC - display results, check for
+* fixit orders and fixit if told
+badcrc    pshs x save that pointer!
+          leax badmsg,pcr
+          ldy  #badsiz-badmsg
+          lbsr newlnfd 
+          leax shdabeen,pcr
+          ldy  #badmsg-shdabeen
+          lbsr showit Write ' S/B $'
+          leax filecrc1,u show actual crc
+          stx  <numptr
+          ldb  #$03
+          lbsr printit
+          lda  <fixit is valid whole file
+          adda <updthead one module only
+          beq  crcdun wasn't told to fix it
+
+********* enabling the fix **********
+fixenbl   leax seekls16,u we're gonna write
+          ldd  ,x to the file, seek to
+          subd #$03 crc start again
+          std  ,x
+          bcc  msigok
+          ldx  <seekms16 if borrow, dec hi int
+          leax -1,x of addrress
+          stx  <seekms16
+msigok    lbsr seekmod
+          leax filecrc1,u
+          stx  <numptr for later printout
+          ldy  #$03
+          lda  <inpath
+          os9  I$Write and update the file!
+          lbcs help
+          leax fixxmsg,pcr
+          ldy  #newln-fixxmsg
+          lbsr showit 
+          ldy  #$03 
+          leax seekms16,u
+          bsr  addseek to restore file ptr
+          ldb  #$03 digits to print
+          lbsr printit numptr already set
+          clr  <updthead to stop it at one module
+          lbra crcdun go clean up end of crc display
+
+**************************************
+* ADDSECT - add reg.Y to length of module & file
+* ENTRY   Y bytes to add to present file size
+*         X location of 4 byte accumulator (seekms16,u)
+addsect   pshs y first inc modpos
+          ldd  <modpos
+          addd ,s++
+          std  <modpos
+
+* and fall thru to ---- ADDSEEK
+* ENTRY   Y bytes to add to position in file
+* EXIT    updated seekms16-seekls16 accumulator
+addseek   pshs x save present buffer addr 
+          pshs y updt passed file/seek pos
+          leax seekms16,u
+          ldd  2,x seekls16
+          addd ,s++
+          std  2,x
+          bcc  addout
+          ldd  ,x seekms16 works but cumbersome
+          adcb #$00 methodology
+          std  ,x seekms16
+          bcc  addout
+          adca #$00
+          std  ,x seekms16
+addout    puls x
+          rts
+
+***************************************************
+* SETHEAD - we've found an $87CD, reset modlstrt and
+* modhstrt to offset 0000 of module for name finding
+* also potential bugfixing. The previous usage of the
+* leau -9,u didn't set a borrow if it occurred. 
+* This method does. Returning just to call getname
+* was extra code, so now it falls thru since all we
+* were doing is giving getname an anchor point.
+sethead   ldd  <seekls16
+          ldx  <seekms16
+          subd <modpos
+          std  <modlstrt record starting pos
+          bcc  noborw
+          leax -1,x
+noborw    stx  <modhstrt so we can recover
+* and fall thru to getname
+getname   ldd  <modlstrt our reference location
+          pshs d this pshs and ,s++
+          ldd  <modname cancel
+          addd ,s++ each other
+          std  <seekls16
+          bcc  nocari
+          leax 1,x add carry to hi int
+nocari    stx  <seekms16
+getit     bsr  seekmod
+          leax mdlname,u
+gtbyt     lda  <inpath
+          ldy  #$01
+          os9  I$Read
+          ldb  ,x+
+          bpl  gtbyt
+          andb #$7F cancel set msb
+          stb  -1,x
+          ldb  #$0d add a cr
+          stb  ,x+ to stop writln 
+          lda  <inpath and get edition byte!
+          ldy  #$01
+          os9  I$Read
+
+***** Edition 16 addition ********************
+* NAMECMP - controls middle of file
+* fixit by name function
+* Entry:  nz in "fixname"
+*         module name in "cmpname"
+* Exit:   nz in updthead, zero in fixname if match
+* match is toupper of input name and saved name
+* till cr matches zero of saved name
+* by zeroing fixname, once done, don't waste
+* more time by continuing to look at following mods
+namecmp   tst  <fixname if a name, it won't be zero
+          beq  noname don't have a name to look for
+          pshs y save it
+          leay cmpname,u
+          leax mdlname,u
+namecmp1  lda  ,x+ get modules name
+          cmpa #$0D till the cr we stashed
+          beq  chkmatch
+          cmpa #'9 this might not be the right cmp!
+          bls  nocaseup
+          anda #$DF make upcase
+nocaseup  cmpa ,y+ against upcased saved name
+          bne  nomatch ifne, no match found here
+          bra  namecmp1
+chkmatch  tst  ,y ifeq, was end of saved name!
+          bne  nomatch
+          inc  <updthead
+          clr  <fixname zero the snooper flag
+nomatch   puls y
+
+* continue on with the previous code
+noname    ldx  <modhstrt now restore file ptr
+          ldd  <modlstrt to byte after parity
+          pshs d in header
+          ldd  <modpos
+          addd ,s++
+          std  <seekls16
+          bcc  ncri
+          leax 1,x
+ncri      stx  <seekms16
+* and fall through to SEEKMOD
+
+**************************************
+* SEEKMOD - positions file r/w pointer
+* Entry = valid pathnum in inpath
+* presumes valid size in seekls16,seekms16
+seekmod   lda  <inpath
+          pshs u
+          ldx  <seekms16
+          ldu  <seekls16
+          os9  I$Seek
+          puls u
+          bcs  oops
+          rts
+
+**************************************
+* READABYT get one byte from the file
+readabyt  lda  <inpath
+          ldy  #1
+          leax buffer,u
+          os9  I$Read
+          bcs  oops
+          pshs x
+          leax seekms16,u
+          lbsr addseek add y to file position
+readout   puls x but not to modpos just yet!
+          tst  <kernal saving it all?
+          beq  readrts no, go
+          pshs b,x else save in 64 byte buffer
+          leax krnlbuf,u
+          ldb  <kbptr
+          leax b,x
+          lda  buffer,u
+          sta  ,x
+          incb
+          stb  <kbptr
+          cmpb #buffer-krnlbuf
+          lbeq helpnbf
+          puls b,x and restore          
+readrts   rts
+
+oops      cmpb #E$EOF
+          lbeq cleanup
+          lbra help
+
+***************************************************
+* GETSIZ - function to get overall size of the file
+* ENTRY valid pathum in 'inpath'
+getsiz    pshs u
+          lda  <inpath
+          ldb  #SS.Size
+          os9  I$Getstt
+          bcs  help
+          stx  <flenms16
+          stu  <flenls16
+          leax flenmsg,pcr
+          ldy  #howmany-flenmsg
+          lbsr showit
+skppr20   puls u it needs U restored
+          leax flenms16,u so this works
+          stx  <numptr
+          ldb  #$04
+          bsr  printit
+          leax newln,pcr
+          ldy  #$02
+          lbsr newlnfd
+          lbsr newlnfd
+          rts
+
+************************************
+* PRINTIT - a front end for hextoasc
+* ENTRY:  address of src data in numptr
+*         regs.B=number of bytes to convert
+printit   pshs d,x,y
+          leax linbuff,u
+          pshs x
+          stx  <linptr
+          tfr  b,a save # to print
+          lsla dbl it
+          pshs a
+          clr  ,-s so we can puls y later
+          bsr  hextoasc
+          puls y get y back
+          puls x and linebuff->
+          lbsr showit display the number
+          puls d,x,y
+          rts
+
+*********************************************
+* HEXTOASC - routine to print hex numbers
+* ENTRY regs.b:#of chars to print,
+* variable location numptr set to src of data
+* variable location linptr someplace in linbuff
+hextoasc  ldx  <numptr defined in host routine
+          lda  ,x+
+          stx  <numptr save new ptr to next byte
+          pshs b save your counter
+          bsr  hxbtoasc
+          ldx  <linptr also defined in host routine
+          std  ,x++
+          stx  <linptr save new pos in output buffer
+          puls b
+          decb
+          bne  hextoasc till hex num all converted!
+          rts  and go print it
+
+*************************************************************
+* routine written up in the Rainbow  (11/92) by Tim Kientzle.
+* It will convert the value passed in the A register to a
+* pair of ascii characters in A:B which are the directly
+* printable ASCII representations of the original contents
+* of A. Load A with byte of src num, call, store A nd B in
+* order in the print buffer on return.  Neat routine Tim!
+* I shrank it by 4 lines & 6 bytes though (GH).
+hxbtoasc  tfr  a,b Make copy of a
+          anda #$0F mask off lower digit
+          bsr  nbltoasc
+          exg  a,b stash in b, get a back
+          lsra getting high nibble
+          lsra into position to
+          lsra convert it
+          lsra
+nbltoasc  adda #$90 repeat for high nibble
+          daa  generate carry if a>9
+          adca #$40
+          daa
+          rts returns a:b=two hexidecimal characters
+
+wphlp     comb
+          ldb  #$D6 no permission to write to it
+          bra  help
+helpnbf   comb
+          ldb #$BF E$BufferToDamnSmall!
+
+***********************************
+* HELP an error exit with prompting
+* Entry   error in B,carry set 
+help      pshs b,cc save stats for exit
+          inc  <verbose make sure the msg gets out
+          leax helpmsg,pcr
+          ldy  #msgsiz-helpmsg
+          lbsr showit 
+          puls b,cc recover error
+out       os9  F$Exit and report the error
+
+*************************************
+* OPENOUT - opens path for std module
+*
+openout   lda  #READ.+WRITE.
+          ldb  #READ.+WRITE.
+          leax mdlname,u point at name
+          os9  I$Create and attempt to make it
+          bcc  outhead made it ok, go
+          cmpb #218 oops, what error
+          bne  help nope, not already exist, go
+          lda  #READ.+WRITE.
+          leax mdlname,u
+          os9  I$Open
+          bcs  help
+outhead   sta  <outpath save pathnum
+          leax modid1,u
+          ldy  #14 write (repaired) module header w/exec & datsiz
+          os9  I$Write
+          bcs  help
+          rts thats all for now, folks
+
+*****************************************
+* OPENKERN - to open extra bytes files
+* pretty much self-contained
+openkern  pshs cc,a,x
+          lda  <kernal
+          beq  kerrts
+          cmpa #$30 head or tail?
+          bne  opentail
+          leax advise0,pcr
+          ldy  #krnlhsz-advise0-1
+          lbsr showit
+          ldb  <kbptr
+          bls  kerrts if zero or less, go
+          leax kernal0,pcr
+kopen     lda  #UPDAT.
+          ldb  #UPDAT.
+          os9  I$Create
+          bcc  kcont
+          cmpb #218 if exists, its ok
+          bne  help else go yelp
+          bcc  kopen1
+          comb to clear that damned error
+kopen1    ldb  #UPDAT.
+          os9  I$Open
+          bcs  help 
+kcont     sta  <kpath
+krts      inc  <kernal we been here, tally it
+kerrts    puls cc,a,x
+          rts
+
+opentail  bcc  opntail
+          comb carry set?
+opntail   cmpa #$31 skip boot, os9p1
+          bne  krts
+          leax advise1,pcr
+          ldy  #krnltsz-advise1-1
+          lbsr showit
+          leax kernal1,pcr
+          bra  kopen
+
+***********************************
+* CLSKRNL - write & close extras
+* valid size in kbptrms*256+kbptr
+clskrnl   pshs d,x,y
+          tst  <kernal
+          beq  clsoops shouldn't 'av come here
+          lda  <kpath
+          ldy  <kbptrms size to write
+          leax krnlbuf,u saved data
+          os9  I$Write
+          lbcs  help
+          lda  <kpath
+          ldb  #$05 get file pos
+          pshs x,u
+          os9  I$GetStt
+          lbcs  help
+          ldb  #$02 set as new size
+          os9  I$SetStt
+          lbcs  help
+          stu  <kbptrms
+          puls x,u
+          os9  I$Close
+          lbcs help
+          leax kbptrms,u point at filesize data
+          stx  <numptr save the filesize
+          leax advlen,pcr now point at "with a size of $"
+          ldy  #advend-advlen get length to write
+          lbsr showit
+          ldb  #$02
+          lbsr printit
+          leax advend,pcr
+          ldy  #hednamsg-advend
+          lbsr showit
+          leax newln,pcr
+          ldy  #2
+          lbsr newlnfd
+          clr  <kpath kill pathnum
+          clr  <kbptr reset
+          clr  <kbptrms
+clsoops   puls d,x,y
+          rts
+          emod
+len       equ  *
+          end
+