changeset 1336:b718065f2629

New utility
author boisy
date Tue, 09 Sep 2003 21:42:08 +0000
parents e91c6a1fd92f
children c061b3b3c10d
files level1/cmds/padrom.asm
diffstat 1 files changed, 408 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/cmds/padrom.asm	Tue Sep 09 21:42:08 2003 +0000
@@ -0,0 +1,408 @@
+********************************************************************
+* PadROM - ROM padding utility
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2003/09/06  Boisy G. Pitre
+* Started.
+
+         nam   PadROM
+         ttl   ROM padding utility
+
+         ifp1
+         use   defsfile
+         use   rbfdefs
+         endc
+
+* Here are some tweakable options
+DOHELP   set   0	1 = include help info
+STACKSZ  set   128	estimated stack size in bytes
+PARMSZ   set   256	estimated parameter size in bytes
+
+* Module header definitions
+tylg     set   Prgrm+Objct   
+atrv     set   ReEnt+rev
+rev      set   $00
+edition  set   1
+
+         mod   eom,name,tylg,atrv,start,size
+
+* Your utility's static storage vars go here
+         org   0
+* These vars are used by the base template and shouldn't be removed
+parmptr  rmb   2	pointer to our command line params
+filecnt  rmb   1
+* These vars are used for this example, it will probably change for you
+hexcnt   rmb   1	used by hex routine
+hexvalue rmb   2	maximum size is $FFFF
+openmode rmb   1
+openpath rmb   1
+filesize rmb   2
+gota     rmb   1
+gotb     rmb   1
+padbyte  rmb   1
+padpage  rmb   256
+cleartop equ   .
+         rmb   STACKSZ+PARMSZ
+size     equ   .
+
+* The utility name and edition goes here
+name     fcs   /PadROM/
+         fcb   edition
+
+* Place constant strings here
+         IFNE  DOHELP
+HlpMsg   fcb   C$LF
+         fcc   /Use: NGU [<opts>] <path> [<path>] [<opts>]/
+         fcb   C$LF
+         fcc   /   -a    option 1/
+         fcb   C$LF
+         fcc   /   -b    option 2/
+         fcb   C$LF
+         fcc   /   -c=f  option 3/
+         fcb   C$LF
+CR       fcb   C$CR
+HlpMsgL  equ   *-HlpMsg
+         ENDC
+BadSize  fcc   /padrom only pads up to $FFFF bytes/
+         fcb   C$CR
+BadSizeL equ   *-BadSize
+BadPad   fcc   /file size exceeds pad size/
+         fcb   C$CR
+BadPadL  equ   *-BadPad
+UnkOpt   fcc   /unknown option: /
+UnkOptL  equ   *-UnkOpt
+
+* 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
+
+* The start of the program is here.
+* Before any command line processing is done, we clear out
+* our static memory from U to cleartop, then determine the
+* size of our data area (minus the stack).
+start    subd  #$0001		subtract 1 from D (param length)
+         lbeq  ShowHelp		if zero, no params were on line
+
+         pshs  u,x              save registers for later
+         leax  cleartop,u       point to end of area to zero out
+         IFNE  H6309
+         subr  u,x              subtract U from X
+         tfr   x,w              and put X in W
+         clr   ,-s              put a zero on the stack
+         tfm   s,u+             and use TFM to clear starting at U
+         leas  1,s              clean up the stack
+         ELSE
+         pshs   x               save end pointer on stack
+clrnxt   clr   ,u+              clear out
+         cmpu  ,s               done?
+         bne   clrnxt           branch if not
+         leas  2,s              else clear stack
+         ENDC
+         puls  x,u              and restore our earlier saved registers
+
+InitVars stx   <parmptr		save parameter pointer
+         lda   #UPDAT.		get default open mode
+         sta   <openmode	and save it
+         lda   #$FF
+         sta   <padbyte		assume a default pad byte
+
+* At this point we have determined our buffer space and saved pointers
+* for later use.  Now we will parse the command line for options that
+* begin with a dash.
+* Note that X will NOT point to a space, but to either a CR (if no
+* parameters were passed) or the first non-space character of the
+* parameter.
+* Here we merely grab the byte at X into A and test for end of line,
+* exiting if so.  Utilities that don't require arguments should
+* comment out the following three lines.
+GetChar  lda   ,x+		get next character on cmd line
+         cmpa  #C$CR		CR?
+         beq   DoPadROM		if so, do whatever this utility does
+         cmpa  #'-		is it an option?
+         beq   GetDash		if so, process it
+         inc   <filecnt         else must be a non-option argument (file)
+         lbsr  SkipNSpc         move past the argument
+ChkDash  lbsr  SkipSpcs         and any following spaces
+         bra   GetChar          start processing again
+GetDash  clr   -1,x		wipe out the dash from the cmd line
+GetDash2 ldd   ,x+		load option char and char following
+         ora   #$20		make lowercase
+IsItX    cmpa  #'x		is it this option?
+         bne   IsItC		branch if not
+         lda   #EXEC.+UPDAT.
+         sta   <openmode
+         bra   FixCmdLn
+IsItC    cmpa  #'c		is it this option?
+         bne   BadOpt		branch if not
+         cmpb  #'=		2nd char =?
+         lbne  ShowHelp		show help if not
+         clr   -$01,x		write over c
+         clr   ,x+		and = sign, inc X to dest dir
+* check for valid char after -c=
+         lbsr  Hex2Int		get value of hex pad char
+         lda   <hexvalue+1
+         sta   <padbyte         save pad character byte
+         lda   ,x		get char at X (should be space or CR)
+         cmpa  #C$SPAC
+         beq   ChkDash
+         cmpa  #C$CR
+         beq   ChkDash
+         lbra  ShowHelp		neither, so show help
+
+FixCmdLn clr   -$01,x		wipe out option character
+         cmpb  #'0
+         blt   ChkDash		start dash option processing again
+         bra   GetDash		possibly another option following?
+
+* We branch here if we encounter an unknown option character
+* A = bad option character
+BadOpt   leax  UnkOpt,pcr
+         ldy   #UnkOptL
+         ldb   #C$CR
+         pshs  d		save bad option and CR on stack
+         lda   #$02		stderr
+         os9   I$Write
+         leax  ,s		point X at option char on stack
+         os9   I$WritLn		print option and CR
+         puls  d		clean up stack
+         lbra  ShowHelp
+
+
+* At this point options are processed.
+* We load X with our parameter pointer and go down the command line
+* looking at each file to process (options have been wiped out with
+* spaces)
+*
+* Note, the following two instructions may not be needed, depending on
+* if your utility requires a non-option on the command line.
+DoPadROM 
+* Before processing any parameters, fill <padpage with <padchar
+         clrb
+         lda   <padbyte
+         leax  padpage,u
+fillpage sta   ,x+
+         decb
+         bne   fillpage
+
+* Get parameter pointer and skip leading spaces
+         ldx   <parmptr		get our parameter pointer
+         lbsr  SkipSpcs		skip any leading spaces
+* First parameter should be a hex pad size (maximum 4 hex bytes)
+         lbsr  Hex2Int		get hex value
+         dec   <filecnt		decrement file count
+         lbeq  ShowHelp		if no other file, exit with error
+DoLoop   lbsr  SkipSpcs		skip any leading spaces
+         cmpa  #C$CR		end of parameters?
+         beq   ExitOk		if so, end the utility
+         pshs  x		save pointer to arg
+         bsr   ProcFile		process file at X
+         puls  x		get arg pointer
+         lbsr  SkipNSpc         skip the argument we just processed
+         bra   DoLoop
+
+* This routine processes one file at a time.
+* Entry: X = ptr to argument on the command line.
+* On exit, X can point to the argument or past it.
+* Note that there are NO leading spaces.
+* They have been skipped by the caller.
+* The following code just echos the command line argument, followed
+* by a carriage return.
+ProcFile 
+         lda   <openmode	get open mode
+         ldy   #256
+         os9   I$Write
+         os9   I$Open		open file
+         bcs   Exit		exit if error
+         sta   <openpath	save path
+         ldb   #SS.Size		we want the file size
+         pshs  u,x		save
+         os9   I$GetStt		get the size
+         stu   <filesize	save file size
+         bcs   Exit		branch if error
+         cmpx  #$0000		file bigger than 65535?
+         bne   toobig		yup
+         lda   <openpath	get path to file
+         os9   I$Seek		seek to the end of the file
+         bcs   Exit		branch if error
+         puls  x,u		restore
+* Expand the file out to the desired size
+         ldd   <hexvalue	get pad size
+         subd  <filesize	get remaining size left
+         bcs   padbad
+* D now holds the number of bytes we need to write
+         pshs  d		save count on stack
+         lda   <openpath	get path to file
+         leax  padpage,u	point to pad page
+         tst   ,s		greater than 256 bytes left?
+         beq   cont2		no, write remaining
+         ldy   #256		for 256 bytes
+cont     os9   I$Write		write it out
+         bcs   Exit		branch if error
+         dec   ,s		decrement page count
+         bne   cont
+cont2    puls  y		get count off stack into Y
+         os9   I$Write		write out remaining bytes
+         bcs   Exit		branch if error
+
+* Now close the file and return
+         os9   I$Close		close it
+         rts
+
+toobig   lda   #$02		stdout
+         ldy   #BadSizeL	get length of bad size message
+         leax  BadSize,pcr	and point to it
+         os9   I$WritLn		send out the message
+         bra   error1
+
+padbad   lda   #$02
+         ldy   #BadPadL
+         leax  BadPad,pcr
+         os9   I$WritLn
+error1   ldb   #$01
+         bra   Exit
+
+ShowHelp equ   *
+         IFNE  DOHELP
+         leax  >HlpMsg,pcr	point to help message
+         ldy   #HlpMsgL		get length
+         lda   #$02		std error
+         os9   I$WritLn 	write it
+         ENDC
+ExitOk   clrb  			clear carry
+Exit     os9   F$Exit   	and exit
+
+
+* This routine skip over spaces and nul bytes
+*
+* Entry:
+*   X = ptr to data to parse
+* Exit:
+*   X = ptr to first non-whitespace char
+*   A = non-whitespace char
+SkipSpcs lda   ,x+
+         beq   SkipSpcs
+         cmpa  #C$SPAC
+         beq   SkipSpcs
+         leax  -1,x
+         rts
+
+* This routine skips over everything but spaces, nul bytes and CRs
+*
+* Entry:
+*   X = ptr to data to parse
+* Exit:
+*   X = ptr to first whitespace char
+*   A = whitespace char
+SkipNSpc lda   ,x+
+         beq   EatOut
+         cmpa  #C$SPAC
+         beq   EatOut
+         cmpa  #C$CR
+         bne   SkipNSpc
+EatOut   leax  -1,x
+         rts
+
+
+* Hex2Int
+*
+* Entry:
+*   X = address of hex string (1-4 bytes)
+* Exit:
+*   <hexvalue = value of hex string
+*   X = address of character after hex string
+Hex2Int  clr   <hexcnt		clear our counter
+         lda   ,x
+         cmpa  #'$		hex sign?
+         bne   Hex2Int2
+         clr   ,x+		clear it and move to next char
+Hex2Int2 bsr   Hex2Nib		get hex nibble at ,X
+         bcs   HexW2		branch if done
+         pshs  b		save good hex byte on stack
+         inc   <hexcnt		increment counter
+         lda   <hexcnt		get counter
+         cmpa  #$04		max size?
+         beq   HexW3
+         bra   Hex2Int2		and continue
+
+* Here, <hexcnt contains a count of the bytes on the stack that contain
+* hex values
+HexW2    tst   <hexcnt		any valid hex data?
+         beq   HexWDone		no, exit
+
+HexW3    clra			clear out return hex value
+         clrb
+         std   <hexvalue
+
+         puls  b		get nibble off the stack
+         stb   <hexvalue+1
+         dec   <hexcnt		decrement counter
+         beq   HexWDone		branch if done
+         lsl   ,s		else move lo-nib on stack to hi-nib
+         lsl   ,s
+         lsl   ,s
+         lsl   ,s
+         addb  ,s+		and add it to lonibble in B
+         stb   <hexvalue+1
+         dec   <hexcnt		decrement counter
+         beq   HexWDone
+         puls  b		get nibble off the stack
+         stb   <hexvalue+0
+         dec   <hexcnt		decrement counter
+         beq   HexWDone
+         lsl   ,s		else move lo-nib on stack to hi-nib
+         lsl   ,s
+         lsl   ,s
+         lsl   ,s
+         addb  ,s+		and add it to lonibble in A
+         stb   <hexvalue+0
+
+HexWDone rts
+         
+
+
+* Hex2Nib - Convert byte at X from hex to byte integer
+*
+* Entry:
+*   X = address of byte to convert
+* Exit:
+*   A = ASCII value of char at X
+*   B = byte value of hex char at X (if carry clear)
+*       OR error (if carry set)
+Hex2Nib  lda   ,x               get char at X
+         tfr   a,b		transfer it to working reg (B)
+         subb  #$30             subtract '0
+         cmpb  #$09             compare against 9
+         bls   L02B1            branch if valid number
+         cmpb  #$31             uppercase?
+         bcs   L02A7            branch if so
+         subb  #$20             else make uppercase
+L02A7    subb  #$07             subtract
+         cmpb  #$0F             compare against 0x0F
+         bhi   L02B6            branch if higher
+         cmpb  #$0A             compare against 0x0A
+         bcs   L02B6
+L02B1    andcc #^Carry          clear carry
+         clr   ,x		clear byte on cmd line
+         leax  $01,x            move X to next char
+         rts                    return
+L02B6    comb
+         rts
+
+         emod
+eom      equ   *
+         end