home *** CD-ROM | disk | FTP | other *** search
-
-
- incpath include:
- maclib sm.mac
- macfile macro.i
- macfile snoopy.i
- macfile macros/parse
- macfile extern/main
- macfile extern/misc
-
- section main,code
-
- ERROR_NONE equ 0
- ERROR_INVALID_LINE equ 1
- ERROR_INTERNAL equ 2
- ERROR_NOT_ENOUGH_MEMORY equ 3
- ERROR_ABORT equ 4
-
- ASSUME_LONG equ 0
- ASSUME_WORD equ 1
- ASSUME_BYTE equ 2
-
- ***********************************************************************************
- ;-------------- parse a scriptfile with a given name. Note that this parser
- ;-------------- is re-entrant, which means that includes are just normal scriptfiles
- ;-------------- like the main scriptfile.
- ;--------------
- ;-------------- => a0: APTR filename of scriptfile
- ;-------------- <= d0: BOOL success
- STRUCTURE psfStack,0
- APTR psf_Filename
- APTR psf_FileHandle
- LONG psf_Line
- LABEL psf_SIZEOF
-
- ENTRY ParseScriptFile,d1-d7/a0-a6,psf_SIZEOF,a5
- move.l a0,(psf_Filename,a5)
- clr.b (includeLevel)
- clr.l (flagSkipSimilar)
- clr.l (priority)
- clr.b (outputMemory)
- clr.l (timeout)
- clr.l (structureOffset)
- move.b #ASSUME_WORD,(assume)
- move.l (argNoSegTracker),d0
- not.l d0
- move.l d0,(flagSegTracker)
-
- ;-------------- copy command line incdir
- tst.l (argIncdir)
- beq.b .NOINCDIR
- lea (incdirBuffer),a1
- movea.l (argIncdir),a0
- move.w #MAX_INCDIRNAME-1,d0
- STRCPY a0,a1
- .NOINCDIR
- ;-------------- open file
- move.l (psf_Filename,a5),d1
- move.l d1,(outputArgs)
- move.l #MODE_OLDFILE,d2
- CALL Open,dosBase
- move.l d0,(psf_FileHandle,a5)
- beq.b .NoFile
-
- ;-------------- read all lines one-by-one
- .LOOP move.l (psf_FileHandle,a5),d1
- move.l #inputMemory,d2
- move.l #MAX_INPUT,d3
- CALL FGets
- tst.l d0
- beq.b .DONE
- addq.l #1,(psf_Line,a5)
- move.l (psf_Line,a5),(currentLine)
- bsr.b ProcessInput
- tst.l d0
- bne.b .FAIL
- bra.b .LOOP
-
- ;-------------- FGets() returned NULL; so we have to check if it was EOF or an error
- .DONE CALL IoErr
- move.l d0,d1
- beq.b .ReallyDone
-
- ;-------------- it WAS an error, so show it and exit
- jsr ShowDosError
- .FAIL move.l (psf_FileHandle,a5),d1
- CALL Close
- moveq #ERROR_INVALID_LINE,d0
- bra.b ParseScriptFile_done
-
- ;-------------- return to sender
- .ReallyDone move.l (psf_FileHandle,a5),d1
- CALL Close
- moveq #ERROR_NONE,d0
- bra.b ParseScriptFile_done
-
- ;-------------- some error message
- .NoFile lea (openfileErr,pc),a0
- jsr ShowErrorMessage
- moveq #ERROR_INTERNAL,d0
- DONE ParseScriptFile
-
- ***********************************************************************************
- ;-------------- process current input data line (in 'input' buffer)
- ;--------------
- ;-------------- <= d0: BOOL success
- ;--------------
- ENTRY ProcessInput,d1-d7/a0-a6
- bsr PrepareInput
- tst.b (input)
- beq .DONE
-
- ;-------------- see if it is one of the codewords we need
- lea (KeywordTable),a0
- .CodewordLoop tst.l (a0)
- beq.b .InvalidLine
-
- ;-------------- compare codeword and inputline
- move.l (a0),a1
- lea (input),a2
- .STRICMP move.b (a1)+,d0
- beq.b .Found
- move.b (a2)+,d1
- UCASE d1
- cmp.b d1,d0
- beq.b .STRICMP
-
- .NotFound addq.l #8,a0
- bra.b .CodewordLoop
-
- ;-------------- codeword found -> call function !
- .Found tst.b (a2)
- beq.b .FOUND
- cmpi.b #"=",(a2)+
- bne.b .NotFound
- .FOUND tst.l (4,a0)
- beq.b .DONE
- move.l (4,a0),a1
- movea.l a2,a0 ; a0 = start of current line
- jsr a1 ; a1 = code for handler function
- tst.l d0
- beq.b ProcessInput_done
- cmpi.l #ERROR_NOT_ENOUGH_MEMORY,d0
- beq.b .NOMEMORY
-
- ;-------------- invalid input line
- cmpi.l #ERROR_INVALID_LINE,d0
- bne.b ProcessInput_done
- .InvalidLine lea (invalidlineErr,pc),a0
- bsr ParserError
- bra.b ProcessInput_done
-
- ;-------------- not enough memory, display alert (because it doesn't eat up memory)
- .NOMEMORY move.l #RECOVERY_ALERT,d0 ; AlertNumber
- lea (memoryError,pc),a0 ; String
- moveq #50,d1 ; Height
- CALL DisplayAlert,intBase
- moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bne.b ProcessInput_done
-
- .DONE moveq #ERROR_NONE,d0
- DONE ProcessInput
-
- ***********************************************************************************
- ;-------------- define a new library base
- ;--------------
- ;-------------- => a0: APTR current string position
-
- ENTRY SetBase,d1-d7/a0-a6
-
- ;-------------- create new list entry
- move.l #sbase_SIZEOF,d0
- lea (bases),a1
- bsr CreateEntry
- tst.l d0
- beq .NoMemory
-
- ;-------------- copy base
- lea (sbase_Name,a5),a1
- moveq #MAX_BASENAME-2,d1
- .CopyBaseName move.b (a0)+,d0
- beq .FAILURE
- cmpi.b #",",d0
- beq.b .NameFound
- UCASE d0
- move.b d0,(a1)+
- dbra d1,.CopyBaseName
- bra .BaseTooLong
- .NameFound clr.b (a1)+
- move.l a0,d7 ; d7 = library name
-
- .FindEnd move.b (a0)+,d0
- beq.b .EndFound
-
- ;-------------- another comma indicates the user wants to give a version description
- cmpi.b #",",d0
- bne.b .FindEnd
- .Version clr.b (-1,a0)
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,d6
- bra.b .GoOn
-
- ;-------------- we have to remove trailing whitespaces because the library name
- ;-------------- is to be directly transfered to OpenLibrary() which otherwise
- ;-------------- could fail
- .EndFound subq.l #1,a0
- .WhileIsWhite cmpa.l d7,a0
- beq.b .WhiteIsDone
- move.b -(a0),d0
- cmpi.b #" ",d0
- beq.b .WhileIsWhite
- cmpi.b #" ",d0
- beq.b .WhileIsWhite
- .WhiteIsDone clr.b (1,a0)
-
- ;-------------- now try to open the library
- .GoOn movea.l d7,a1
- move.l d6,d0
- CALL OpenLibrary,<(execBase).w>
- move.l d0,(sbase_Library,a5)
- beq.b .CannotOpenLib
- .DONE moveq #ERROR_NONE,d0
- bra.b SetBase_done
-
- ;-------------- base name exceeds MAX_BASENAME
- .BaseTooLong lea (basesizeErr,pc),a0
- bra.b .SHOWERROR
-
- ;-------------- unable to OpenLibrary()
- .CannotOpenLib lea (openlibErr,pc),a0
- move.l d7,outputArgs+4
- .SHOWERROR bsr ParserError
- bra.b SetBase_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetBase_done
-
- .FAILURE moveq #ERROR_INVALID_LINE,d0
- DONE SetBase
-
- ***********************************************************************************
- ;-------------- define a new resource base
- ;--------------
- ;-------------- => a0: APTR current string position
-
- ENTRY SetResource,d1-d7/a0-a6
-
- ;-------------- create new list entry
- move.l #sbase_SIZEOF,d0
- lea (resources),a1
- bsr CreateEntry
- tst.l d0
- beq .NoMemory
-
- ;-------------- copy base
- lea (sbase_Name,a5),a1
- moveq #MAX_BASENAME-2,d1
- .CopyBaseName move.b (a0)+,d0
- beq .FAILURE
- cmpi.b #",",d0
- beq.b .NameFound
- UCASE d0
- move.b d0,(a1)+
- dbra d1,.CopyBaseName
- bra .BaseTooLong
- .NameFound clr.b (a1)+
- move.l a0,d7 ; d7 = library name
- .FindEnd subq.l #1,a0
-
- ;-------------- we have to remove trailing whitespaces because the library name
- ;-------------- is to be directly transfered to OpenResource() which otherwise
- ;-------------- could fail
- .WhileIsWhite cmpa.l d7,a0
- beq.b .WhiteIsDone
- move.b -(a0),d0
- cmpi.b #" ",d0
- beq.b .WhileIsWhite
- cmpi.b #" ",d0
- beq.b .WhileIsWhite
- .WhiteIsDone clr.b (1,a0)
-
- ;-------------- now try to open the library
- .GoOn movea.l d7,a1
- CALL OpenResource,<(execBase).w>
- move.l d0,(sbase_Library,a5)
- beq.b .CannotOpenRes
- .DONE moveq #ERROR_NONE,d0
- bra.b SetBase_done
-
- ;-------------- base name exceeds MAX_BASENAME
- .BaseTooLong lea (basesizeErr,pc),a0
- bra.b .SHOWERROR
-
- ;-------------- unable to OpenLibrary()
- .CannotOpenRes lea (openresErr,pc),a0
- move.l d7,outputArgs+4
- .SHOWERROR bsr ParserError
- bra.b SetResource_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetResource_done
-
- .FAILURE moveq #ERROR_INVALID_LINE,d0
- DONE SetResource
-
- ***********************************************************************************
- ;-------------- define a new library base
- ;--------------
- ;-------------- => a0: APTR current string position
-
- ENTRY SetDevice,d1-d7/a0-a6
-
- ;-------------- create new list entry
- move.l #sdevbase_SIZEOF,d0
- lea (deviceBases),a1
- bsr CreateEntry
- tst.l d0
- beq .NoMemory
-
- ;-------------- setup list header
- lea (sdevbase_Patches,a5),a1
- NEWLIST a1
-
- ;-------------- creatup message port **NOT SUPPORTED YET**
- ;push a0
- ;CALL CreateMsgPort,<(execBase).w>
- ;pop a0
- ;move.l d0,(sdevbase_MsgPort,a5)
- ;beq .NOMSGPORT
- ;push a0
- ;movea.l d0,a1
- ;move.l #NULL,(LN_NAME,a1)
- ;CALL AddPort
- ;pop a0
-
- ;-------------- copy base
- lea (sdevbase_Name,a5),a1
- moveq #MAX_BASENAME-2,d1
- .CopyBaseName move.b (a0)+,d0
- beq .FAILURE
- cmpi.b #",",d0
- beq.b .NameFound
- UCASE d0
- move.b d0,(a1)+
- dbra d1,.CopyBaseName
- bra .BaseTooLong
- .NameFound clr.b (a1)+
- move.l a0,d7 ; d7 = device name
-
- move.l #IOSTD_SIZE,(sdevbase_IOSize,a5)
- move.l #-1,(sdevbase_Unit,a5) ; any unit will do
-
- .FindEnd move.b (a0)+,d0
- beq.b .EndFound
-
- ;-------------- another comma indicates the user wants to give an IO size (default=IOSTD_SIZE)
- cmpi.b #",",d0
- bne.b .FindEnd
- clr.b (-1,a0)
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,(sdevbase_IOSize,a5) ; set unit
-
- ;-------------- another comma indicates the user wants to give a unit (default=0)
- .FindEnd2 move.b (a0)+,d0
- cmpi.b #",",d0
- bne.b .FindEnd
- clr.b (-1,a0)
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,(sdevbase_Unit,a5) ; set unit
- bra.b .GoOn
-
- ;-------------- we have to remove trailing whitespaces because the library name
- ;-------------- is to be directly transfered to OpenLibrary() which otherwise
- ;-------------- could fail
- .EndFound subq.l #1,a0
- .WhileIsWhite cmpa.l d7,a0
- beq.b .WhiteIsDone
- move.b -(a0),d0
- cmpi.b #" ",d0
- beq.b .WhileIsWhite
- cmpi.b #" ",d0
- beq.b .WhileIsWhite
- .WhiteIsDone clr.b (1,a0)
-
- ;-------------- now try to open the device
- ;-------------- note that what we do here is really not very smart, but it works:
- ;-------------- we find the device by name and "lock" it by adding an openlib count
-
- .GoOn CALL Forbid,<(execBase).w>
- movea.l d7,a1 ; name
- lea (DeviceList,a6),a0 ; start
- CALL FindName
- move.l d0,(sdevbase_Device,a5)
- beq.b .CannotOpenDev
- movea.l d0,a1
- addq.w #1,(LIB_OPENCNT,a1)
- move.b (LIB_FLAGS,a1),d0
- bset #LIBB_CHANGED,d0
- move.b d0,(LIB_FLAGS,a1)
- CALL SumLibrary
- CALL Permit
-
- moveq #ERROR_NONE,d0
- bra.b SetDevice_done
-
- ;-------------- base name exceeds MAX_BASENAME
- .BaseTooLong lea (basesizeErr,pc),a0
- bra.b .SHOWERROR
-
- ;-------------- unable to OpenLibrary()
- .CannotOpenDev CALL Permit
- lea (opendevErr,pc),a0
- move.l d7,outputArgs+4
- .SHOWERROR bsr ParserError
- bra.b SetDevice_done
-
- .NOMSGPORT lea (msgportErr,pc),a0
- bra.b .SHOWERROR
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetDevice_done
-
- .FAILURE moveq #ERROR_INVALID_LINE,d0
- DONE SetDevice
-
- ***********************************************************************************
- ;-------------- define a new offset
- ;--------------
- ;-------------- => a0: APTR current string position
-
- ENTRY SetDefine,d1-d7/a0-a6
- move.l a0,d7
-
- ;-------------- find start of offset
- .FindComma move.b (a0)+,d0
- beq .InvalidLine
- cmpi.b #",",d0
- bne.b .FindComma
- clr.b (-1,a0)
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,d6
-
- ;-------------- allocate new define
- lea (defines),a1
- move.l #sdef_SIZEOF,d0
- bsr CreateEntry
- tst.l d0
- beq.b .NoMemory
-
- move.l d6,(sdef_Offset,a5)
- lea (sdef_Name,a5),a1
- movea.l d7,a0
- moveq #MAX_DEFINENAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (defsizeErr,pc),a0
- bsr ParserError
- bra.b SetDefine_done
-
- .InvalidLine moveq #ERROR_INVALID_LINE,d0
- bra.b SetDefine_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetDefine_done
-
- .STRCPYEND moveq #ERROR_NONE,d0
- DONE SetDefine
-
- ***********************************************************************************
- ;-------------- define a new offset
- ;--------------
- ;-------------- => a0: APTR current string position
-
- ENTRY SetBitdef,d1-d7/a0-a6
- move.l a0,d7
-
- ;-------------- find start of offset
- .FindComma move.b (a0)+,d0
- beq .InvalidLine
- cmpi.b #",",d0
- bne.b .FindComma
- clr.b (-1,a0)
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- moveq #0,d6
- bset d0,d6
-
- ;-------------- allocate new define
- lea (defines),a1
- move.l #sdef_SIZEOF,d0
- bsr CreateEntry
- tst.l d0
- beq.b .NoMemory
-
- move.l d6,(sdef_Offset,a5)
- lea (sdef_Name,a5),a1
- movea.l d7,a0
- moveq #MAX_DEFINENAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (defsizeErr,pc),a0
- bsr ParserError
- bra.b SetBitdef_done
-
- .InvalidLine moveq #ERROR_INVALID_LINE,d0
- bra.b SetBitdef_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetBitdef_done
-
- .STRCPYEND moveq #ERROR_NONE,d0
- DONE SetBitdef
-
-
- ***********************************************************************************
- ;-------------- include a file
- ;--------------
- ;-------------- => a0: APTR filename
- STRUCTURE siStack,0
- APTR sis_Handle
- LONG sis_Line
- LABEL sis_SIZEOF
-
- ENTRY SetInclude,d1-d7/a0-a6,sis_SIZEOF,a4
-
- ;-------------- FIRST: try to find file in local directory
- move.l a0,d1
- move.l a0,d7
- move.l d1,(outputArgs)
- move.l #MODE_OLDFILE,d2
- CALL Open,<(dosBase)>
- move.l d0,(sis_Handle,a4)
- bne.b .FileFound
-
- ;-------------- build includefile name
- lea (incdirBuffer),a1
- lea (includeName),a2
- STRCPY a1,a2
-
- ;-------------- create filename
- move.l #includeName,d1
- move.l d7,d2
- move.l #MAX_INCDIRNAME,d3
- CALL AddPart
-
- ;-------------- open file
- move.l #includeName,d1
- move.l d1,(outputArgs+4)
- move.l #MODE_OLDFILE,d2
- CALL Open
- move.l d0,(sis_Handle,a4)
- beq.b .NoFile
-
- ;-------------- this is really not a very smart way of preventing
- ;-------------- "endless include loops" but it works
- .FileFound cmpi.b #MAX_INCLUDELEVEL,(includeLevel)
- beq.b .LEVELOVERFLOW
- addq.b #1,(includeLevel)
-
- ;-------------- read all lines one-by-one
- .LOOP move.l (sis_Handle,a4),d1
- move.l #inputMemory,d2
- move.l #MAX_INPUT,d3
- CALL FGets
- tst.l d0
- beq.b .DONE
- addq.l #1,(sis_Line,a4)
- move.l (sis_Line,a4),(currentLine)
- bsr ProcessInput
- tst.l d0
- bne.b .FAIL
- bra.b .LOOP
-
- ;-------------- FGets() returned NULL; so we have to check if it was EOF or an error
- .DONE CALL IoErr
- move.l d0,d1
- beq.b .ReallyDone
-
- ;-------------- it WAS an error, so show it and exit
- jsr ShowDosError
- .FAIL move.l (sis_Handle,a4),d1
- CALL Close
- subq.b #1,(includeLevel)
- moveq #ERROR_INTERNAL,d0
- bra.b SetInclude_done
-
- ;-------------- return to sender
- .ReallyDone move.l (sis_Handle,a4),d1
- CALL Close
- subq.b #1,(includeLevel)
- moveq #ERROR_NONE,d0
- bra.b SetInclude_done
-
- ;-------------- too many include files
- .LEVELOVERFLOW move.l (sis_Handle,a4),d1
- CALL Close
- lea (inclevelErr,pc),a0
- bra.b .SHOWERROR
-
- ;-------------- some error message
- .NoFile lea (openincErr,pc),a0
- .SHOWERROR bsr ParserError
- DONE SetInclude
-
- ***********************************************************************************
- ;-------------- set new directory for includes
- ;--------------
- ENTRY SetIncdir,d1-d7/a0-a6
-
- ;-------------- copy name to incdir Buffer
- lea (incdirBuffer),a1
- move.w #MAX_INCDIRNAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (incdirsizeErr,pc),a0
- bsr ParserError
- bra.b SetIncdir_done
-
- ;-------------- return success
- .STRCPYEND moveq #ERROR_NONE,d0
- DONE SetIncdir
-
- **************************************************************************
- ;-------------- various boolean flags
- SetSticky lea (argSticky),a1
- bra FindBooleanKeyword
- SetMatch lea (argMatch),a1
- bra FindBooleanKeyword
- SetTaskInfo lea (argTaskInfo),a1
- bra FindBooleanKeyword
- SetSegTracker lea (flagSegTracker),a1
- bra FindBooleanKeyword
- SetSkipSimilar lea (flagSkipSimilar),a1
- bra FindBooleanKeyword
- SetSkipSegNotFound
- lea (flagSkipSegNotFound),a1
- bra FindBooleanKeyword
-
- ***********************************************************************************
- ;-------------- define a new offset
- ;--------------
- ;-------------- => a0: APTR current string position
- SetHide lea (hides),a1
- bra SetTask
- SetShow lea (shows),a1
- move.b #1,(showsactive)
- bra SetTask
-
- ENTRY SetTask,d1-d7/a0-a6
-
- ;-------------- allocate new task information
- move.l #stask_SIZEOF,d0
- bsr CreateEntry
- tst.l d0
- beq.b .NoMemory
-
- ;-------------- if it starts with a $ its assumed to be an address
- cmpi.b #"$",(a0)
- bne.b .ITSANAME
- cmpi.b #"$",(1,a0)
- bne.b .ITSAPOINTER
- .ITSANAME lea (stask_Name,a5),a1
- moveq #MAX_TASKNAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (tasksizeErr,pc),a0
- bsr ParserError
- bra.b SetTask_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetTask_done
-
- ;-------------- its a pointer; get its address
- .ITSAPOINTER moveq #STVFORMAT_HEX,d0
- jsr StringToValue
- move.l d0,(stask_Pointer,a5)
- .STRCPYEND moveq #ERROR_NONE,d0
- DONE SetTask
-
- **************************************************************************
- ;-------------- display a message in the output file
- ;--------------
- SetEcho jsr ShowEchoMessage
- tst.w d0
- beq .FAIL
- moveq #ERROR_NONE,d0
- rts
- .FAIL moveq #ERROR_ABORT,d0
- rts
-
- ***********************************************************************************
- ;-------------- define a new alias
- ;--------------
- ENTRY SetAlias,d1-d7/a0-a6
- move.l a0,d7
-
- ;-------------- find start of offset
- .FindComma move.b (a0)+,d0
- beq.b .InvalidLine
- cmpi.b #",",d0
- bne.b .FindComma
- clr.b (-1,a0)
- move.l a0,d6 ; d6 = TEMPLATE, d7 = ALIAS
-
- ;-------------- allocate new define
- move.l #salias_SIZEOF,d0
- lea (aliases),a1
- bsr CreateEntry
- tst.l d0
- beq.b .NoMemory
-
- ;-------------- copy alias name
- lea (salias_Name,a5),a1
- movea.l d7,a0
- moveq #MAX_ALIASNAME-1,d0
- .STRCPY1 move.b (a0)+,(a1)+
- beq.b .STRCPYEND1
- dbra d0,.STRCPY1
- lea (aliasnameErr,pc),a0
- .SHOWERROR bsr ParserError
- bra.b SetAlias_done
-
- ;-------------- copy alias contents
- .STRCPYEND1 lea (salias_Contents,a5),a1
- movea.l d6,a0
- move.w #MAX_ALIASCONTENTS-1,d0
- .STRCPY2 move.b (a0)+,(a1)+
- beq.b .STRCPYEND2
- dbra d0,.STRCPY2
- lea (aliascontentErr,pc),a0
- bra.b .SHOWERROR
- .STRCPYEND2 moveq #ERROR_NONE,d0
- bra.b SetAlias_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetAlias_done
-
- .InvalidLine moveq #ERROR_INVALID_LINE,d0
- DONE SetAlias
-
- **************************************************************************
- ;--------------
- ENTRY SetAssume,d1-d7/a0-a6
- lea (AssumeKeys,pc),a3
- .LOOP move.w (a3),d0
- beq.b .FAILED
- lea (AssumeKeys,pc),a4
- lea (a4,d0.w),a4 ; a4 = string to match
- movea.l a0,a2 ; a2 = current string
- .STRICMP move.b (a4)+,d0
- beq.b .Found
- move.b (a2)+,d1
- UCASE d1
- cmp.b d1,d0
- beq.b .STRICMP
- .NEXT addq.l #4,a3
- bra.b .LOOP
- .Found move.b (a2)+,d1
- beq.b .SUCCESS
- cmpi.b #' ',d1
- beq.b .SUCCESS
- cmpi.b #' ',d1
- bne.b .NEXT
- .SUCCESS move.w (2,a3),d0
- move.b d0,(assume)
- moveq #ERROR_NONE,d0
- bra.b SetAssume_done
-
- ;-------------- display warning
- .FAILED move.l a0,(outputArgs+4)
- lea (invassumeErr,pc),a0
- bsr ParserError
- DONE SetAssume
-
- **************************************************************************
- ;-------------- set running priority
- ENTRY SetPri
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,(priority)
- moveq #ERROR_NONE,d0
- DONE SetPri
-
- **************************************************************************
- ;-------------- set timeout delay
- ENTRY SetTimeout
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,(timeout)
- moveq #ERROR_NONE,d0
- DONE SetTimeout
-
- **************************************************************************
- ;-------------- set output handle
- ENTRY SetOutput,d1-d7/a0-a6
- lea (outputMemory),a1
- STRCPY a0,a1
- moveq #ERROR_NONE,d0
- DONE SetOutput
-
- **************************************************************************
- ;-------------- define a new library snooper
- ;--------------
- ENTRY SetWatch,d1-d7/a0-a6
-
- ;-------------- create new patch entry
- move.l a0,d7
- move.l #spatch_SIZEOF,d0
- lea (watches),a1
- bsr CreateEntry
- tst.l d0
- beq .NoMemory
-
- ;-------------- NEW: Setup flags
- moveq #0,d0
- tst.l (flagSegTracker)
- bne.b .STOFF
- bset #SINFOB_NOSEGTRACKER,d0
- .STOFF tst.l (flagSkipSimilar)
- beq.b .SSOFF
- bset #SINFOB_SKIPSIMILAR,d0
- .SSOFF move.l d0,(spatch_Flags,a5)
- move.l (timeout),(spatch_Timeout,a5)
-
- ;-------------- try to find a base for this watch
- lea (bases),a1
- movea.l (LH_HEAD,a1),a1
- .FindBaseLOOP tst.l (LN_SUCC,a1) ; a1 = current node
- beq .NoBaseFound
- lea (sbase_Name,a1),a2
- movea.l d7,a0
- .STRICMP move.b (a0)+,d0
- UCASE d0
- move.b (a2)+,d1
- beq.b .BaseFound
- cmp.b d1,d0
- beq.b .STRICMP
- movea.l (LN_SUCC,a1),a1
- bra.b .FindBaseLOOP
- .BaseFound move.l (sbase_Library,a1),(spatch_Library,a5)
-
- ;-------------- find Offset
- movea.l d7,a0
- .FindFirstComma move.b (a0)+,d0
- beq .InvalidLine
- cmpi.b #",",d0
- bne.b .FindFirstComma
-
- ;-------------- NEW: if its not '-' or a digit, fail
- cmpi.b #"-",(a0)
- beq.b .ITSADIGIT
- IFDIGIT (a0),.ITSADIGIT
- bsr FindDefine
- tst.w d0
- beq.b .OffsetNotFound
- move.w d1,(spatch_Offset,a5)
- .SKIP_Comma cmpi.b #",",(a0)+
- bne.b .SKIP_Comma
- bra.b .OFFSETFOUND
- .ITSADIGIT moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.w d0,(spatch_Offset,a5)
- .OFFSETFOUND
- ;-------------- now parse the register information
- bsr ParseRegisterInfo
- tst d0
- beq.b .InvalidLine
-
- ;-------------- the rest of this line is interpreted as the argument template
- lea (spatch_Template,a5),a1
- move.w #MAX_TEMPLATE-2,d0
- .CopyTemplate move.b (a0)+,(a1)+
- beq.b .SUCCESS
- dbra d0,.CopyTemplate
- lea (tempsizeErr,pc),a0
- bsr ParserError
- bra.b SetWatch_done
-
- ;-------------- return successfully
- .SUCCESS moveq #ERROR_NONE,d0
- bra.b SetWatch_done
-
- ;-------------- library base could not be found
- .NoBaseFound lea (nobaseErr,pc),a0
- .SHOWERROR bsr ParserError
- bra.b SetWatch_done
-
- ;-------------- offset not found
- .OffsetNotFound move.l a0,(outputArgs+4)
- .ONFLOOP move.b (a0)+,d0
- beq.b .ONFDONE
- cmpi.b #",",d0
- bne.b .ONFLOOP
- clr.b -(a0)
- .ONFDONE lea (nooffsetErr,pc),a0
- bra.b .SHOWERROR
-
- .InvalidLine moveq #ERROR_INVALID_LINE,d0
- bra.b SetWatch_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- DONE SetWatch
-
- ***********************************************************************************
- ;-------------- read in register information stored in a syntax of
- ;--------------
- ;-------------- <register 0>/<register 1>/.../<register n>
- ;--------------
- ;-------------- where <register x> is
- ;--------------
- ;-------------- [R|B]((D|A)<0..7>)[L|W|b][:<offset>]
- ;--------------
- ;-------------- => A0: APTR start of register information
- ;-------------- A5: struct PatchInfo *pi
- ;--------------
-
- ENTRY ParseRegisterInfo,d1-d7/a1-a6
- moveq #0,d5 ; current argument counter
-
- lea (spatch_Arguments,a5),a4 ; load register data in a4
- cmpi.b #",",(a0)+
- beq .EmptyReglist
- subq.l #1,a0
- .LOOP moveq #0,d0
-
- ;-------------- set size assumption
- cmpi.b #ASSUME_BYTE,(assume)
- beq .ASSUME_BYTE
- cmpi.b #ASSUME_LONG,(assume)
- beq .ASSUME_LONG
- bra .ASSUME_WORD ; "default"
-
- ;-------------- handle register
- .GetRegister move.b (a0)+,d1
- beq .InvalidLine
- UCASE d1
-
- ;-------------- a leading R signals that this register is a return value
- cmpi.b #"R",d1
- bne.b .NotReturn
- bset #REGB_RESULT,d0
- bra.b .GetRegister
- .NotReturn
- ;-------------- a leading B signals that this register is a boolean value
- cmpi.b #"B",d1
- bne.b .NotBoolean
- bset #REGB_BOOLEAN,d0
- bra.b .GetRegister
- .NotBoolean
- ;-------------- a D is for data registers
- cmpi.b #"D",d1
- bne.b .NotData
- move.b (a0)+,d1
- beq .InvalidLine
- subi.b #"0",d1
- andi.b #%111,d1
- or.b d1,d0
- bset #REGB_DATA,d0
- bra.b .GetRegister
-
- ;-------------- an A stands for address registers
- .NotData cmpi.b #"A",d1
- bne.b .NotAddr
- move.b (a0)+,d1
- beq .InvalidLine
- subi.b #"0",d1
- andi.b #%111,d1
- or.b d1,d0
- bset #REGB_ADDR,d0
- bra.b .GetRegister
-
- ;-------------- an I stands for address registers relative
- .NotAddr cmpi.b #"I",d1
- bne.b .NotRelative
- move.b (a0)+,d1
- beq .InvalidLine
- subi.b #"0",d1
- andi.b #%111,d1
- or.b d1,d0
- bset #REGB_INDIRECT,d0
- bra .GetRegister
- .NotRelative
- ;-------------- a trailing L stands for LONG
- cmpi.b #"L",d1
- bne.b .NotLong
- .ASSUME_LONG bset #REGB_LONG,d0
- bclr #REGB_WORD,d0
- bclr #REGB_BYTE,d0
- bra .GetRegister
- .NotLong
- ;-------------- a trailing W stands for WORD
- cmpi.b #"W",d1
- bne.b .NotWord
- .ASSUME_WORD bclr #REGB_LONG,d0
- bset #REGB_WORD,d0
- bclr #REGB_BYTE,d0
- bra .GetRegister
- .NotWord
- ;-------------- a trailing b stands for WORD
- cmpi.b #"b",d1
- bne.b .NotByte
- .ASSUME_BYTE bclr #REGB_LONG,d0
- bclr #REGB_WORD,d0
- bset #REGB_BYTE,d0
- bra .GetRegister
- .NotByte
- ;-------------- a ':' indicates start of an offset definition
- cmpi.b #":",d1
- bne.b .NotOffset
- pushm d1-d7/a0-a6
- bsr FindDefine
- tst.w d0
- bne.b .FindSlash
- moveq #STVFORMAT_DEC,d0
- push a0
- jsr StringToValue
- pop d2
- addq.l #1,d2
- moveq #TRUE,d1
- cmpa.l d2,a0
- bne.b .DigitFound
- moveq #FALSE,d1
- .DigitFound exg.l d0,d1
- .FindSlash move.l d1,(sarg_Offset,a4)
- popm d1-d7/a0-a6
- tst.w d0
- beq.b .InvalidLine
-
- ;-------------- must be limited with a / or a ','
- .FindSlashLoop move.b (a0)+,d1
- beq.b .InvalidLine
- cmpi.b #'/',d1
- beq.b .SlashFound
- cmpi.b #',',d1
- beq.b .CommaFound
- bra.b .FindSlashLoop
- .NotOffset
- ;-------------- a slash / indicates the end of one register definition, so position
- ;-------------- to the next register slot
- cmpi.b #"/",d1
- bne.b .NotSlash
- .SlashFound move.w d0,(a4)
- lea (sarg_SIZEOF,a4),a4
- addq.l #1,d5
- cmpi.l #MAX_ARGUMENTS,d5
- beq.b .TOOMANYARGS
- bra .LOOP
- .NotSlash
- ;-------------- a comma , indicates the end of the register list definition
- cmpi.b #",",d1
- bne.b .InvalidLine
- .CommaFound move.w d0,(a4)
- lea (sarg_SIZEOF,a4),a4
- addq.l #1,d5
- cmpi.l #MAX_ARGUMENTS,d5
- beq .TOOMANYARGS
- .EmptyReglist move.w #REG_DONE,(a4)
- moveq #TRUE,d0
- bra.b ParseRegisterInfo_done
-
- .TOOMANYARGS lea (argsizeErr,pc),a0
- bsr ParserError
- bra.b ParseRegisterInfo_done
-
- .InvalidLine moveq #FALSE,d0
- DONE ParseRegisterInfo
-
- **************************************************************************
- ;-------------- define a new device snooper
- ;--------------
- ;-------------- devcmd=<device>,<command>,<offsets>,<register list>
- ;--------------
- ;--------------
-
- SetBeginIO moveq #SINFOF_BEGINIO,d5
- bra.b HandleDevCmd
-
- SetAbortIO moveq #SINFOF_ABORTIO,d5
- bra.b HandleDevCmd
-
- SetDevCmd moveq #SINFOF_BEGINIO|SINFOF_ABORTIO,d5
- ;bra.b HandleDevCmd
-
- ENTRY HandleDevCmd,d1-d7/a0-a6
-
- ;-------------- try to find the device base for this watch
- lea (deviceBases),a1
- movea.l (LH_HEAD,a1),a1
- move.l a0,d7
- .FindBaseLOOP tst.l (LN_SUCC,a1) ; a1 = current node
- beq .NoBaseFound
- lea (sdevbase_Name,a1),a2
- movea.l d7,a0
- .STRICMP move.b (a0)+,d0
- UCASE d0
- move.b (a2)+,d1
- beq.b .BaseFound
- cmp.b d1,d0
- beq.b .STRICMP
- movea.l (LN_SUCC,a1),a1
- bra.b .FindBaseLOOP
- .BaseFound move.l (sdevbase_Device,a1),d6
-
- ;-------------- NOTE: unlike library WATCHes, DEVCMDs are stored in list
- ;-------------- of the device structures; this makes it later easier to
- ;-------------- display the device messages.
- lea (sdevbase_Patches,a1),a1
- move.l #spatch_SIZEOF,d0
- bsr CreateEntry
- tst.l d0
- beq .NoMemory
- move.l d6,(spatch_Library,a5) ; (struct Device *)
-
- ;-------------- NEW: Setup flags
- moveq #0,d0
- or.w d5,d0
- tst.l (flagSegTracker)
- bne.b .STOFF
- bset #SINFOB_NOSEGTRACKER,d0
- .STOFF tst.l (flagSkipSimilar)
- beq.b .SSOFF
- bset #SINFOB_SKIPSIMILAR,d0
- .SSOFF move.l d0,(spatch_Flags,a5)
-
- ;-------------- find Offset
- movea.l d7,a0
- .FindFirstComma move.b (a0)+,d0
- beq .InvalidLine
- cmpi.b #",",d0
- bne.b .FindFirstComma
-
- ;-------------- NEW: if its not '-' or a digit, fail
- cmpi.b #"-",(a0)
- beq.b .ITSADIGIT
- IFDIGIT (a0),.ITSADIGIT
- bsr FindDefine
- tst.w d0
- beq.b .OffsetNotFound
- move.w d1,(spatch_Offset,a5)
- .SKIP_Comma cmpi.b #",",(a0)+
- bne.b .SKIP_Comma
- bra.b .OFFSETFOUND
- .ITSADIGIT moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.w d0,(spatch_Offset,a5)
- .OFFSETFOUND
- ;-------------- now parse the register information
- ;-------------- currently this is the same function that is used by SetWatch();
- ;-------------- Note that YOU SHOULD NOT USE register specifications, but rather
- ;-------------- statements in the form
- ;--------------
- ;-------------- .../<size>:<offset>/...
- ;--------------
- ;-------------- such as
- ;--------------
- ;-------------- .../L:IO_CMD/...
- ;--------------
- bsr ParseRegisterInfo
- tst d0
- beq.b .InvalidLine
-
- ;-------------- the rest of this line is interpreted as the argument template
- lea (spatch_Template,a5),a1
- move.w #MAX_TEMPLATE-2,d0
- .CopyTemplate move.b (a0)+,(a1)+
- beq.b .SUCCESS
- dbra d0,.CopyTemplate
- lea (tempsizeErr,pc),a0
- bsr ParserError
- bra.b HandleDevCmd_done
-
- ;-------------- return successfully
- .SUCCESS moveq #ERROR_NONE,d0
- bra.b HandleDevCmd_done
-
- ;-------------- device base could not be found
- .NoBaseFound lea (nodevbaseErr,pc),a0
- .SHOWERROR bsr ParserError
- bra.b HandleDevCmd_done
-
- ;-------------- offset not found
- .OffsetNotFound move.l a0,(outputArgs+4)
- .ONFLOOP move.b (a0)+,d0
- beq.b .ONFDONE
- cmpi.b #",",d0
- bne.b .ONFLOOP
- clr.b -(a0)
- .ONFDONE lea (nooffsetErr,pc),a0
- bra.b .SHOWERROR
-
- .InvalidLine moveq #ERROR_INVALID_LINE,d0
- bra.b HandleDevCmd_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- DONE HandleDevCmd
-
- ***********************************************************************************
- ;-------------- try to find a defined number for a function (or io command) offset
- ;--------------
- ENTRY FindDefine,d2-d7/a0-a6
- movea.l a0,a4
- lea (defines),a5
- movea.l (LH_HEAD,a5),a5
- .LOOP tst.l (LN_SUCC,a5) ; a5 = current node
- beq.b .NotInList
- movea.l a4,a0 ; string to find
- lea (sdef_Name,a5),a1 ; definition of String
- .STRICMP move.b (a1)+,d0
- beq.b .InList
- move.b (a0)+,d1
- cmp.b d1,d0
- beq.b .STRICMP
- movea.l (LN_SUCC,a5),a5
- bra.b .LOOP
-
- .InList cmpi.b #"/",(a0)+
- beq.b .ISINLIST
- cmpi.b #",",(-1,a0)
- bne.b .NotInList
- .ISINLIST moveq #TRUE,d0
- move.l (sdef_Offset,a5),d1
- bra.b FindDefine_done
-
- .NotInList moveq #FALSE,d0
- DONE FindDefine
-
- **************************************************************************
- ;-------------- try to find the boolean value for a keyword
- ;--------------
- ;-------------- => a0: APTR string
- ;-------------- a1: APTR flag pointer
- ENTRY FindBooleanKeyword,d1-d7/a0-a6
- lea (BoolKeys,pc),a3
- .LOOP move.w (a3),d0
- beq.b .FAILED
- lea (BoolKeys,pc),a4
- lea (a4,d0.w),a4 ; a4 = string to match
- movea.l a0,a2 ; a2 = current string
- .STRICMP move.b (a4)+,d0
- beq.b .Found
- move.b (a2)+,d1
- UCASE d1
- cmp.b d1,d0
- beq.b .STRICMP
- .NEXT addq.l #4,a3
- bra.b .LOOP
- .Found move.b (a2)+,d1
- beq.b .SUCCESS
- cmpi.b #' ',d1
- beq.b .SUCCESS
- cmpi.b #' ',d1
- bne.b .NEXT
- .SUCCESS move.w (2,a3),d0
- ext.l d0
- move.l d0,(a1)
- moveq #ERROR_NONE,d0
- bra.b FindBooleanKeyword_done
-
- ;-------------- display warning
- .FAILED move.l a0,(outputArgs+4)
- lea (invalidboolErr,pc),a0
- bsr ParserError
- DONE FindBooleanKeyword
-
- **************************************************************************
- ;-------------- this creates a new (internal) structure entry and adds it
- ;-------------- to the top of a given list
- ;--------------
- ;-------------- => d0: LONG size
- ;-------------- a1: APTR list header
- ;-------------- <= d0 = a5: APTR new entry
- ;--------------
- ENTRY CreateEntry,d1-d7/a0-a4/a6
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- movea.l a1,a5
- CALL AllocMem,<(execBase).w>
- tst.l d0
- beq.b CreateEntry_done
- movea.l a5,a0
- movea.l d0,a5
- movea.l d0,a1
- ADDHEAD
- DONE CreateEntry
-
- **************************************************************************
- ;--------------
- ENTRY ParserError,d1-d7/a0-a6
- lea (outputArgs),a5
- push a0
- move.l (currentLine),(a5)
- move.l (4,a5),d7
- lea (input),a0
- move.l a0,(4,a5)
- move.b #'.',(input+30) ; max of 30 characters
- move.b #'.',(input+31)
- move.b #'.',(input+32)
- move.b #0,(input+33)
- lea (errorHeader,pc),a0 ; format string
- lea (outputArgs),a1 ; format data
- lea (errorBuffer),a2 ; target string
- jsr SPrintf
- pop a0
- move.l #errorBuffer,(a5)
- move.l d7,(4,a5)
- jsr ShowErrorMessage
- moveq #ERROR_INTERNAL,d0
- DONE ParserError
-
- ***********************************************************************************
- ;-------------- dealias input line
- ;--------------
- ENTRY PrepareInput,d0-d7/a0-a6
-
- ;-------------- FIRST PASS: dealias input
- lea (inputMemory),a1 ; source
- lea (input),a0 ; target
- .COPYINPUT move.b (a1)+,d0
- beq .DONEPASS1
-
- ;-------------- if its a $ and the next character is a bracket '(', it could
- ;-------------- be an alias....
- cmpi.b #"$",d0
- bne .COPYCHAR
- cmpi.b #"\\",(-2,a1)
- beq .COPYCHAR
- moveq #">",d7
- lea (defines),a3 ; a3 = current DEFINE
- cmpi.b #"<",(a1)
- beq.b .DEALIASNUMERIC
- moveq #")",d7
- lea (aliases),a3 ; a3 = current ALIAS
- cmpi.b #"(",(a1)
- bne .COPYCHAR
- bra.b .DEALIAS
-
- ;-------------- defines understand leading '$','%'
- .DEALIASNUMERIC moveq #STVFORMAT_DEC,d6 ; current number output
- cmpi.b #"$",(1,a1)
- bne.b .DEALIAS
- moveq #STVFORMAT_HEX,d6
- addq.l #1,a1
- .DEALIAS lea (1,a1),a2 ; a2 = begin of ALIAS-name
- movea.l (LH_HEAD,a3),a3
- .ALIASLOOP tst.l (LN_SUCC,a3)
- beq .COPYCHAR
- lea (salias_Name,a3),a5 ; name to match
- cmpi.b #">",d7
- bne.b .HANDLEALIAS
- lea (sdef_Name,a3),a5 ; name to match
- .HANDLEALIAS movea.l a2,a4 ; alias name
- .STRCMP move.b (a4)+,d1
- move.b (a5)+,d2
- beq.b .EOALIAS
- cmp.b d2,d1
- beq.b .STRCMP
- .NEXTALIAS movea.l (LN_SUCC,a3),a3
- bra.b .ALIASLOOP
-
- ;-------------- end of alias name reached; call must close with ')' else its
- ;-------------- not a valid alias
- .EOALIAS cmp.b d7,d1
- bne.b .NEXTALIAS
- cmpi.b #">",d7
- beq.b .INSERTDEFINE
-
- ;-------------- insert contents for alias
- lea (salias_Contents,a3),a3
- .INSERTALIAS move.b (a3)+,(a0)+
- bne.b .INSERTALIAS
- subq.l #1,a0
- movea.l a4,a1
- bra .COPYINPUT
-
- ;-------------- insert numeric value for define
- .INSERTDEFINE pushm d0-d7/a0-a6
- movea.l a0,a2 ; a2=target string
- lea (insertdecFormat,pc),a0 ; a0=format string
- cmpi.b #STVFORMAT_HEX,d6
- bne.b .USEDECFORMAT
- lea (inserthexFormat,pc),a0 ; a0=format string
- .USEDECFORMAT lea (outputArgs),a1 ; a1=format data
- move.l (sdef_Offset,a3),(a1)
- jsr SPrintf
- popm d0-d7/a0-a6
- .SKIPZERO tst.b (a0)+
- bne.b .SKIPZERO
- subq.l #1,a0
- movea.l a4,a1
- bra .COPYINPUT
-
- ;-------------- default: copy char
- .COPYCHAR move.b d0,(a0)+
- bra .COPYINPUT
- .DONEPASS1 clr.b (a0)+
- ;-------------- (END OF FIRST PASS)
-
- ;-------------- PASS TWO: remove comments, skip trailing whitespaces
- ;-------------- remove comments and NEWLINE
- lea (input),a0
- cmpi.b #COMMENT_LINE,(a0) ; skip if its a comment line
- beq.b .SKIPLINE
- .CommentLoop move.b (a0)+,d0
- beq.b .CommentDone
- cmpi.b #"\\",d0
- beq.b .EscapeChar
- cmpi.b #COMMENT,d0
- beq.b .CommentFound
- cmpi.b #"\n",d0
- bne.b .CommentLoop
- .CommentFound clr.b -(a0)
- .CommentDone
- ;-------------- skip the line if it only consists of whitespaces
- lea (input),a0
- .WhitespaceLoop move.b (a0)+,d0
- beq.b .SKIPLINE
- cmpi.b #" ",d0
- beq.b .WhitespaceLoop
- cmpi.b #" ",d0
- beq.b .WhitespaceLoop
- .NotWhitespaces bra.b PrepareInput_done
-
- ;-------------- skip whole line
- .SKIPLINE clr.b (input)
- bra.b PrepareInput_done
-
- ;-------------- new: support escape characters \\,\n,\t,\e,\;,\$
- .EscapeChar move.b (a0),d1
-
- ;-------------- '\;' results in ';'
- moveq #';',d0
- cmpi.b #';',d1
- beq.b .deleteChar
-
- ;-------------- '\n' results in '<NEWLINE>'
- moveq #10,d0
- cmpi.b #'n',d1
- beq.b .deleteChar
-
- ;-------------- '\e' results in '<ESC>'
- moveq #'',d0
- cmpi.b #'e',d1
- beq.b .deleteChar
-
- ;-------------- '\\' results in '\'
- moveq #'\\',d0
- cmpi.b #'\\',d1
- beq.b .deleteChar
-
- ;-------------- '\$' results in '$'
- moveq #'$',d0
- cmpi.b #'$',d1
- beq.b .deleteChar
-
- ;-------------- '\t' results in '<TAB>'
- moveq #8,d0
- cmpi.b #'\t',d1
- beq.b .deleteChar
-
- bra.b .CommentLoop
-
- .deleteChar lea (-1,a0),a1 ; a1=where the former '\' was placed
- move.b d0,(a1)+
- addq.l #1,a0
- push a0
- .DELETECOPY move.b (a0)+,(a1)+
- bne.b .DELETECOPY
- pop a0
- subq.l #1,a0
- bra.b .CommentLoop
-
- DONE PrepareInput
-
- **************************************************************************
- ;-------------- add SHOW statements given in the command line
- ;--------------
- ENTRY SetCmdlineSHOWs,d0-d7/a0-a6
- move.l (argShow),d0
- beq.b .DONE
- movea.l d0,a4
- .LOOP move.l (a4)+,d1
- beq.b .DONE
- move.l #stask_SIZEOF,d0
- lea (shows),a1
- bsr CreateEntry
- tst d0
- beq.b SetCmdlineSHOWs_done
- movea.l d1,a0
- move.b #1,(showsactive)
-
- ;-------------- if it starts with a $ its assumed to be an address
- cmpi.b #"$",(a0)
- bne.b .ITSANAME
- cmpi.b #"$",(1,a0)
- bne.b .ITSAPOINTER
- .ITSANAME lea (stask_Name,a5),a1
- moveq #MAX_TASKNAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (tasksizeErr,pc),a0
- jsr ParserError
- bra.b SetCmdlineSHOWs_done
-
- ;-------------- its a pointer; get its address
- .ITSAPOINTER moveq #STVFORMAT_HEX,d0
- jsr StringToValue
- move.l d0,(stask_Pointer,a5)
- .STRCPYEND moveq #ERROR_NONE,d0
- bra.b .LOOP
- .DONE moveq #ERROR_NONE,d0
- DONE SetCmdlineSHOWs
-
- ***********************************************************************************
- ;-------------- structure macro:
- ;--------------
- ;-------------- STRUCTURE <NAME>,<SIZE>
- ;--------------
- ;-------------- => a0: APTR current string position
-
- SetStructure moveq #FALSE,d5
- bra.b SetSTRUCTURE
- SetSTRUCT moveq #TRUE,d5
- ;bra.b SetSTRUCTURE
- ENTRY SetSTRUCTURE,d1-d7/a0-a6
- move.l a0,d7
-
- ;-------------- find start of offset
- .FindComma move.b (a0)+,d0
- beq .InvalidLine
- cmpi.b #",",d0
- bne.b .FindComma
- clr.b (-1,a0)
- moveq #STVFORMAT_DEC,d0
- jsr StringToValue
- move.l d0,d6
-
- ;-------------- allocate new define
- lea (defines),a1
- move.l #sdef_SIZEOF,d0
- bsr CreateEntry
- tst.l d0
- beq.b .NoMemory
-
- tst.w d5
- beq.b .SetStructure
- move.l (structureOffset),(sdef_Offset,a5)
- add.l d6,(structureOffset)
- bra.b .SetContinue
- .SetStructure move.l #0,(sdef_Offset,a5) ; not d6!!!!!!!!!!!!!!!!!!!!!!!!
- move.l d6,(structureOffset)
- .SetContinue lea (sdef_Name,a5),a1
- movea.l d7,a0
- moveq #MAX_DEFINENAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (defsizeErr,pc),a0
- bsr ParserError
- bra.b SetSTRUCTURE_done
-
- .InvalidLine moveq #ERROR_INVALID_LINE,d0
- bra.b SetSTRUCTURE_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetSTRUCTURE_done
-
- .STRCPYEND moveq #ERROR_NONE,d0
- DONE SetSTRUCTURE
-
- ***********************************************************************************
- ;-------------- set structure entry
- ;--------------
- ;-------------- <element> <NAME>
- ;--------------
- ;-------------- => a0: APTR current string position
- ;-------------- d6: LONG structure size increment
-
- SetLONG moveq #4,d6
- bra.b SetStructureElement
-
- SetWORD moveq #2,d6
- bra.b SetStructureElement
-
- SetBYTE moveq #1,d6
- bra.b SetStructureElement
-
- SetLABEL moveq #0,d6
- ;bra.b SetStructureElement
- ENTRY SetStructureElement,d1-d7/a0-a6
- move.l a0,d7
-
- ;-------------- skip trailing whitespaces
- .STRIPWS move.b (a0)+,d0
- beq.b .STRIPPED
- cmpi.b #" ",d0
- beq.b .STRIP
- cmpi.b #" ",d0
- bne.b .STRIPWS
- .STRIP clr.b (-1,a0)
- .STRIPPED
- ;-------------- allocate new define
- lea (defines),a1
- move.l #sdef_SIZEOF,d0
- bsr CreateEntry
- tst.l d0
- beq.b .NoMemory
-
- move.l (structureOffset),(sdef_Offset,a5) ; not d6!!!!!!!!!!!!!!!!!!!!!!!!
- add.l d6,(structureOffset)
- lea (sdef_Name,a5),a1
- movea.l d7,a0
- moveq #MAX_DEFINENAME-1,d0
- .STRCPY move.b (a0)+,(a1)+
- beq.b .STRCPYEND
- dbra d0,.STRCPY
-
- ;-------------- error, define name too long
- lea (defsizeErr,pc),a0
- bsr ParserError
- bra.b SetStructureElement_done
-
- .NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
- bra.b SetStructureElement_done
-
- .STRCPYEND moveq #ERROR_NONE,d0
- DONE SetStructureElement
-
- SetALIGNWORD move.l (structureOffset),d0
- BRBC.B #0,d0,.ISEVEN
- addq.l #1,(structureOffset)
- .ISEVEN moveq #ERROR_NONE,d0
- rts
-
- SetALIGNLONG move.l (structureOffset),d0
- BRBC.B #0,d0,.ISEVEN
- addq.l #1,d0
- .ISEVEN BRBC.B #1,d0,.ISLONG
- addq.l #2,d0
- .ISLONG move.l d0,(structureOffset)
- moveq #ERROR_NONE,d0
- rts
-
- ;-------------- The keyword table describes which commands Snoopy understands.
- ;-------------- NOTE: You can define your personal keyword aliases by adding
- ;-------------- statements that only have a different second argument; example:
- ;--------------
- ;-------------- keyword Base,LIBRARY
- ;--------------
- ;-------------- will define the new keyword LIBRARY that is exactly the same as Base
- ;-------------- Define your own keyword handling functions as Set<Name> (SetBase in
- ;-------------- the example above)
- KeywordTable keyword RESET
- keyword Base,BASE
- keyword Watch,WATCH
- keyword Watch,SNOOP ; synonym for WATCH
- keyword Hide,HIDE
- keyword Pri,PRI
- keyword Show,SHOW
- keyword Define,DEFINE
- keyword Bitdef,BITDEF
- keyword Include,INCLUDE
- keyword Incdir,INCDIR
- keyword Output,OUTPUT
- keyword Sticky,STICKY
- keyword Match,MATCH
- keyword TaskInfo,TASKINFO
- keyword SegTracker,SEGTRACKER
- keyword Alias,ALIAS
- keyword Assume,ASSUME
- keyword Echo,ECHO
- keyword Echo,PRINT
- keyword Device,DEVICE
- keyword DevCmd,DEVCMD
- keyword BeginIO,BEGINIO
- keyword AbortIO,ABORTIO
- keyword Resource,RESOURCE
- keyword SkipSimilar,SKIPSIMILAR
- keyword Timeout,DELAY
-
- ;-------------- structure macros
- keyword Structure,STRUCTURE
- keyword LONG,APTR
- keyword LONG,CPTR
- keyword LONG,FPTR
- keyword LONG,LONG
- keyword LONG,ULONG
- keyword LONG,FLOAT
- keyword WORD,BOOL
- keyword WORD,RPTR
- keyword WORD,WORD
- keyword WORD,UWORD
- keyword WORD,SHORT
- keyword WORD,USHORT
- keyword BYTE,BYTE
- keyword BYTE,UBYTE
- keyword LABEL,LABEL
- keyword STRUCT,STRUCT
- keyword ALIGNWORD,ALIGNWORD
- keyword ALIGNLONG,ALIGNLONG
-
- ;-------------- the following options are not documented (yet); they will be fully
- ;-------------- introduced in the next versions (guess what they are about)
- keyword SkipSegNotFound,SKIPSEGNOTFOUND
- keyword DONE
-
- BoolKeys dc.w .1-BoolKeys,TRUE
- dc.w .2-BoolKeys,TRUE
- dc.w .3-BoolKeys,TRUE
- dc.w .4-BoolKeys,TRUE
- dc.w .5-BoolKeys,FALSE
- dc.w .6-BoolKeys,FALSE
- dc.w .7-BoolKeys,FALSE
- dc.w .8-BoolKeys,FALSE
- dc.w .9-BoolKeys,TRUE
- dc.w .10-BoolKeys,FALSE
- dc.w 0
- .1 cstr "YES"
- .2 cstr "TRUE"
- .3 cstr "ON"
- .4 cstr "ACTIVE"
- .5 cstr "NO"
- .6 cstr "FALSE"
- .7 cstr "OFF"
- .8 cstr "NOT ACTIVE"
- ;-------------- hey! you found out about these! Don't tell everybody! ;-)
- .9 cstr "FUNKY"
- .10 cstr "SHIT"
- even
-
- AssumeKeys dc.w .1-AssumeKeys,ASSUME_LONG
- dc.w .2-AssumeKeys,ASSUME_WORD
- dc.w .3-AssumeKeys,ASSUME_BYTE
- dc.w 0
- .1 cstr "LONG"
- .2 cstr "WORD"
- .3 cstr "BYTE"
- even
-
- memoryError DEFINE_ALERT <FATAL ERROR, not enough memory available>
-
- insertdecFormat cstr '%ld'
- inserthexFormat cstr '%lx'
- openfileErr cstr 'ERROR, cannot open scriptfile "%s"'
-
- ;-------------- error strings supported by this module
- errorHeader cstr 'ERROR in line %ld: "%s"\n'
- invalidlineErr cstr '%sunknown commands or invalid input line\n'
- openlibErr cstr '%scannot open library "%s"'
- openresErr cstr '%scannot open resource "%s"'
- opendevErr cstr '%scannot open device "%s"'
- basesizeErr cstr '%sbase shortcut too long (max=',_VALOF(MAX_BASENAME),')'
- defsizeErr cstr '%sdefine name too long (max=',_VALOF(MAX_DEFINENAME),')'
- inclevelErr cstr '%sinclude level overflow (max=',_VALOF(MAX_INCLUDELEVEL),')'
- openincErr cstr '%scannot open includefile "%s"'
- incdirsizeErr cstr '%sincdir name too long (max=',_VALOF(MAX_INCDIRNAME),')'
- tasksizeErr cstr '%staskname too long (max=',_VALOF(MAX_TASKNAME),')'
- invalidboolErr cstr '%sinvalid boolean expression "%s"'
- aliasnameErr cstr '%salias name too long (max=',_VALOF(MAX_ALIASNAME),')'
- aliascontentErr cstr '%salias contents too long (max=',_VALOF(MAX_ALIASCONTENTS),')'
- invassumeErr cstr '%sinvalid assumption "%s"'
- tempsizeErr cstr '%stemplate too long (max=',_VALOF(MAX_TEMPLATE),')'
- nobaseErr cstr '%scannot find library base for this definition'
- nodevbaseErr cstr '%scannot find device base for this definition'
- nooffsetErr cstr '%soffset "%s" not defined'
- argsizeErr cstr '%stoo many output arguments (max=',_VALOF(MAX_ARGUMENTS),')'
- msgportErr cstr '%scannot allocate message port'
-
- section memory,bss
-
- currentLine ds.l 1
- defs.l outputArgs,256
- defs.b inputMemory,<(MAX_INPUT+2)>
- input ds.b MAX_INPUT+2
- defs.b outputMemory,MAX_INPUT+2
- incdirBuffer ds.b MAX_INCDIRNAME
- includeName ds.b MAX_INCDIRNAME
- includeLevel ds.b 1
- assume ds.b 1
- even
- errorBuffer ds.b MAX_INPUT+80
- defs.l flagSegTracker,1
- defs.l flagSkipSimilar,1
- defs.l flagSkipSegNotFound,1
- defs.l timeout,1
- defs.l priority,1
- defs.l structureOffset,1
-
- end
-
- ;-------------- ecstasy mutherfuckers! the future is before your eyes!
-
- **************************************************************************
- ;--------------
-