dewi@druca.UUCP (WilliamsD) (03/20/86)
After a few requests, here's the source to the ansiecho command that was
posted a week or so ago. It's been revised so that the V1.1 assembler and
linker believes in it, and has one bug fix -- the original wouldn't handle
ansiecho "" properly.
Also thrown in are cls.asm (clears the current window, what else...) and
ask.asm, which allows yes/no style dialog in CLI scripts by a rather gross
method.
Dewi Williams
--------------- cut, do not fold spindle or mutilate ----------------------
echo "creating source files:"
echo "\tcls.asm"
cat <<"FUNKYSTUFF" >cls.asm
* CLI TOY #1
* CLS.ASM: A command to clear the current (CLI) window. Works by
* sending a HOME/CLEAR TO END OF SCREEN sequence to CON:
*
* Perpetrator: Dewi Williams ..!ihnp4!druca!dewi
* Unconditionally placed in the public domain.
* Included equate files.
* -----------------------------------------------------------------------
NOLIST
INCLUDE "exec/types.i"
INCLUDE "exec/libraries.i"
INCLUDE "libraries/dos.i"
LIST
* Local Equates
* ------------------------------------------------------------------------
SysBase EQU 4 ; The one known address in the system.
* External references
* -----------------------------------------------------------------------
EXTERN_LIB OpenLibrary
EXTERN_LIB Write
EXTERN_LIB Output
EXTERN_LIB IoErr
* macros
* ------------------------------------------------------------------------
* Calls to dos.library and exec library
callsys MACRO
CALLLIB _LVO\1
ENDM
* The code segment
* -------------------------------------------------------------------------
RORG 0 ; Relocatable code.
;------ get Exec's library base pointer:
move.l SysBase,a6
LEA.L DOSName(PC),A1 ; name of dos library
move.l #LIBRARY_VERSION,d0
callsys OpenLibrary
MOVE.L D0,A6 ; Save library pointer (always in A6).
BEQ.S DOSFAIL ; Give up!
* Obtaining the output handle (needed for write)
callsys Output ; Always works -- copy from process structure.
MOVE.L D0,D1 ; Needed there by write
* Write the sequence to the driver
LEA.L CLS(PC),A0
MOVE.L A0,D2 ; Effective address of the buffer
MOVEQ #4,D3 ; Length of buffer to write
callsys Write ; Do it
TST.L D0 ; Just set condition code
BMI.S IOFAIL ; For disks & suchlike check == D3.
* Exit back to CLI (shouldn't close CLI handles).
MOVEQ #0,D0 ; Success exit code
FINISHED:
rts
* All the error traps go here
* ---------------------------
; Get here if we can't write to CON: for some reason.
IOFAIL:
callsys IoErr ; Returns real reason for failure.
BRA.S FINISHED ; Quit
; Get here if we can't open dos.library. Give up! We should really
; alert...
DOSFAIL:
MOVEQ #RETURN_FAIL,D0
RTS
* Data declarations
* ------------------------------------------------
DOSName DOSNAME;
CLS DC.B $9B,'H',$9B,'J' ; HOME, CLEAR TO END OF SCREEN
END
FUNKYSTUFF
echo "\techo.asm"
cat <<"FUNKYSTUFF" >echo.asm
* CLI TOY #2
* ANSIECHO.ASM: Extended echo that handles backslash constructs such as \t
* etc. Unlike UNIX echo, it takes \3A hex constructs instead
* of octal. I'd rather grow 6 new fingers than lose 2!
*
* The following backslash constructs are supported:
* \t tab
* \n newline
* \f formfeed (clear screen)
* \e escape character
* \c on end of string, suppresses newline
* \b backspace
* \\ single backslash
* \" explicit string quote, otherwise eaten.
* \nn hexadecimal characters (must be upper case).
*
* As an example, try echo \e[37mhello world\e[0m
*
* Perpetrator: Dewi Williams ..!ihnp4!druca!dewi
* Unconditionally placed in the public domain.
* Included equate files.
* -----------------------------------------------------------------------
NOLIST
INCLUDE "exec/types.i"
INCLUDE "exec/libraries.i"
INCLUDE "libraries/dos.i"
LIST
* External references
* -----------------------------------------------------------------------
EXTERN_LIB OpenLibrary
EXTERN_LIB Write
EXTERN_LIB Output
* Local Equates
* ------------------------------------------------------------------------
SysBase EQU 4 ; The one known address in the system.
TRUE EQU -1
FALSE EQU 0
CMD_SIZE EQU 300 ; plenty big enough!
* Macros
* ------------------------------------------------------------------------
* Calls to dos.library and exec library
callsys MACRO
CALLLIB _LVO\1
ENDM
* The code segment
* -------------------------------------------------------------------------
RORG 0 ; Relocatable code.
LINK A2,#(-CMD_SIZE) ; expand onto stack
LEA.L -CMD_SIZE(A2),A1 ; start of expansion buffer
jsr argtrim ; clean up command line
MOVEM.L D0/A0-A2,-(SP) ; Save command line (OpenLibrary trashes).
;------ get Exec's library base pointer:
move.l SysBase,a6
LEA.L DOSName(PC),A1 ; name of dos library
move.l #LIBRARY_VERSION,d0
callsys OpenLibrary
MOVE.L D0,A6 ; Save library pointer (always in A6).
BNE.S gotdos
; Should really issue an alert here...
moveq #RETURN_FAIL,D0 ; give up
bra FINISHED
* Set up loop addressing: A0 goes through command line, A1 references
* stack build area, A2 is the frame pointer, D4 is the nonl flag and
* D3 is a counter. The command line is terminated by a newline character.
gotdos:
* Obtain the output handle (needed for write)
callsys Output
MOVE.L D0,D5 ; Save for the write
MOVEM.L (SP)+,D0/A0-A2 ; restore command line etc.
MOVEQ #FALSE,D4 ; nonl assumed false as default
CLR.L D3 ; zero characters so far
mainloop:
CMPI.B #0,(A0) ; Reached end of string yet?
BEQ eos ; yes
CMPI.B #'\',(A0) ; is it escaped?
BNE notesc ; no
CMPI.B #0,1(A0) ; at the end of the string?
BEQ notesc ; not escaping anything, is itself
; Check out the \t \f etc. cases first
ADDQ #1,A0 ; move to next character
CMPI.B #'t',(A0) ; a tab?
BNE next1 ; no
MOVE.B #9,(A1)+ ; yes
bra gotit
next1:
cmpi.b #'b',(A0) ; a backspace?
bne next2 ; no
move.b #8,(A1)+ ; yes
bra gotit
next2:
cmpi.b #'n',(A0) ; a newline?
bne next3 ; no
move.b #10,(A1)+ ; yes
bra gotit
next3:
cmpi.b #'e',(a0) ; an escape char (not backslash!)
bne next4 ; no
move.b #27,(A1)+ ; yes
bra gotit
next4:
cmpi.b #'\',(a0) ; an escaped backslash?
bne next5 ; no
bra notesc ; yes
next5:
cmpi.b #'f',(a0) ; formfeed
bne next6 ; no
move.b #12,(A1)+ ; yes
bra gotit
next6:
cmpi.b #'c',(a0) ; no newline construct
bne next7 ; no
cmpi.b #0,1(A0) ; A \c at the end of the string?
bne notesc ; no
moveq #TRUE,D4 ; set up the nonl flag
bra eos ; know we've finished
next7:
cmpi.b #'"',(A0) ; a string quote?
bne maybehex ; no
move.b #'"',(A1)+ ; yes
bra gotit
; get here -- maybe it's 2 hex digits. Call ishexdig to find out.
maybehex:
move.b (a0),D1
jsr ishexdig ; Check the first character
beq notesc ; failed the test
move.b 1(a0),D1 ; Now check the second
jsr ishexdig
beq notesc ; second one failed
jsr hexstr ; translate it into a real character
addq #1,a0 ; lose both characters
move.b d0,(A1)+ ; and fall through to gotit.
gotit:
addq #1,a0 ; next input character
addq #1,d3 ; bump output count
bra mainloop ; round again
notesc:
; A normal character
move.b (a0)+,(a1)+ ; copy it over
addq #1,d3 ; bump output count
bra mainloop ; round again
; Left the loop.
eos:
TST.L D4 ; Check out the nonl flag
BNE skipnl ; set
move.b #10,(a1)+ ; add the newline.
addq #1,d3
skipnl:
; All set up for printing out the gathered string. Start by recalculating
; the start address of the output buffer.
lea.l -CMD_SIZE(A2),A0
move.l a0,d2 ; start address
move.l d5,d1 ; restore handle
callsys Write
MOVEQ #0,D0 ; success
FINISHED:
UNLK A2
RTS
* Subroutines
* ------------------------------------------------------------------------
* ishexdig: passed a character in D1, will report as a boolean in D0.
* Passes 0..9 and A..F (upper case).
ishexdig:
cmpi.b #'0',D1
blt hexlab
cmpi.b #'9',D1
ble yes
hexlab:
cmpi.b #'A',D1
blt no
cmpi.b #'F',D1
bgt no
yes:
moveq #TRUE,D0
bra endhex
no:
moveq #FALSE,D0
endhex:
rts
* hexstr: passed a hex string in A0, return its value in D0.
* Stop either at length 2 or invalid hex character.
* In this case, the string has already been validated.
* CREDITS: Slightly hacked version of p430 of "Programming the 68000"
* by Steve Williams. Sybex books. Recommended.
hexstr:
movem.l d1-d3/a0,-(sp) ; save starting registers
clr.l d0 ; clear accumulator
clr.l d3 ; count of digits processed
loop:
clr.l d1 ; zero out D1
cmpi.b #'9',(a0) ; upper bound
bhi notdec ; not a decimal digit
cmpi.b #'0',(a0) ; lower bound
blt nothex ; not a hex digit
move.b #'0',d1 ; correction factor
bra gotdig ; accumulate
notdec:
cmpi.b #'A',(a0) ; check letters
blt nothex ; not a hex digit
cmpi.b #'F',(a0) ; upper case hex?
bhi nothex ; no, and lower case is not allowed
move.b #'A'-10,d1 ; correction factor / fall through to gotdig
gotdig:
clr.l d2 ; zero high byte
move.b (a0)+,d2 ; get next digit
sub.l d1,d2 ; convert to binary
lsl.l #4,d0 ; multiply by 16
add.l d2,d0 ; add in digit
cmpi.l #1,d3 ; reached the end yet?
beq hexdone ; yes
addq.l #1,d-d3/a0 ; unsave registers
rts ; return to caller
* argtrim: a routine to trim the end of a command line and null terminate
* it. This is achieved in the following manner:
* Start at the end and run back until a non-whitespace (nl/blank)
* character is encountered. If this is a quote, toss it.
* If the *first* character is a quote, bump the start address by
* one. No pretense of quote matching here.
* Inputs: address in A0, length in D0
* Outputs: address in A0.
argtrim:
movem.l d1-d7/a1-a6,-(sp) ; save registers
cmpi.b #'"',(a0) ; starts with a quote?
bne.s checkline ; no
subq #1,d0 ; yes - decrement count
addq #1,a0 ; and bump start address
checkline:
cmpi.b #1,D0 ; length includes the newline
bne.s isline ; yes - there is something there
move.b #0,(a0) ; create null string
bra.s argfini ; done
isline:
; strip off any run of blanks on the end...
move.l a0,a1 ; computing end address of line
add.l d0,a1 ;
subq #2,a1 ;
toploop:
cmp.l a0,a1
beq.s empty ; single char or run of blanks
cmpi.b #' ',(a1)
bne.s endloop ; finished the scan
subq #1,a1 ; else back one more
bra.s toploop ; and try again
endloop:
cmpi.b #'"',(a1)
beq.s nullit
nullnext:
addq #1,a1
nullit:
move.b #0,(a1)
bra.s argfini
empty: ; could be blanks or a single char
cmpi.b #' ',(a1)
bne.s endloop ; or maybe a single quote!
move.b #0,(a0)
argfini:
movem.l (sp)+,d1-d7/a1-a6 ; restore registers
rts
* Data declarations
* -------------------------------------------------------------------------
DOSName DOSNAME
END
FUNKYSTUFF
echo "\task.asm"
cat <<"FUNKYSTUFF" >ask.asm
; CLI TOY #3.
; ask.asm: A routine to allow a single character answer to a question
; posed by a ansiecho or echo question.
; This character is then tested, and an ERROR issued if the
; answer is not "y" or "Y".
;
; The idea is based on H. Fischer's INFO-IBMPC submission of
; 12/83, called bat-ques.
;
; Complaint: IF should really allow IF ERROR=40... which would make this
; a more general purpose hack. Probably better to just do a
; more reasonable CLI.
; Perpetrator: Dewi Williams ..!ihnp4!druca!dewi
; Unconditionally placed in the public domain.
; Restrictions: You'll probably need the V1.1 linker & assembler.
; Usage:
; failat 20
; ansiecho "do you want to load up the RAM disk? \c"
; ask
; if not error
; ansiecho loading RAM...
; else
; ansiecho not loading RAM...
; endif
* Included equate files.
* -----------------------------------------------------------------------
NOLIST
INCLUDE "exec/types.i"
INCLUDE "exec/libraries.i"
INCLUDE "libraries/dos.i"
LIST
* External references
* -----------------------------------------------------------------------
EXTERN_LIB OpenLibrary
EXTERN_LIB Read
EXTERN_LIB Input
* Local Equates
* ------------------------------------------------------------------------
SysBase EQU 4 ; The one known address in the system.
TRUE EQU -1
FALSE EQU 0
CMD_SIZE EQU 300 ; plenty big enough!
* Macros
* ------------------------------------------------------------------------
* Calls to dos.library and exec.library
callsys MACRO
CALLLIB _LVO\1
ENDM
* The code segment
* -------------------------------------------------------------------------
RORG 0 ; Relocatable code.
LINK A2,#(-CMD_SIZE) ; expand onto stack
LEA.L -CMD_SIZE(A2),A3 ; start of read buffer
MOVEM.L A0-A3,-(SP) ; Save command line (OpenLibrary trashes).
;------ get Exec's library base pointer:
move.l SysBase,a6
LEA.L DOSName(PC),A1 ; name of dos library
move.l #LIBRARY_VERSION,d0
callsys OpenLibrary
MOVE.L D0,A6 ; Save library pointer (always in A6).
BNE.S gotdos
; Should do a dos failure alert here. They'll find out soon enough!
move.l #1000,D0
bra.s fini
gotdos:
MOVEM.L (SP)+,A0-A3 ; restore stack addressing.
* Obtain the Input handle.
callsys Input ; Always works -- copy from process structure.
MOVE.L D0,D1 ; Save for the read
* Read the console
move #CMD_SIZE,d3 ; Read >1 to swallow the CR
move.l a3,D2 ; read onto the stack
callsys Read ; D1 = handle D2 = address D3 = length
* Check out the read character
cmpi.b #'Y',(A3)
beq.s yes
cmpi.b #'y',(a3)
beq.s yes
moveq #RETURN_ERROR,D0 ; anything else means no
bra.s fini
yes:
moveq #RETURN_OK,D0
fini:
unlk a2
rts ; return with exit code in D0
* Data declarations
* -------------------------------------------------------------------------
DOSName DOSNAME
END
FUNKYSTUFF
echo "source file creation complete"
exit 0
------
--
----------------------------------------------------------------------
Dewi Williams.
uucp: ..!ihnp4!druca!dewi
phone: (303) 538 4884