; RUNBACK, a very small pure version that uses the NULL: device, translated
; from a C version which compiled to 848 bytes into assembly.  New size is 468
; bytes, small enough to fit in one floppy disk block.  Written 12/16/90 and
; 12/17/90 by Paul Kienitz, public domain.  Has a -delay option, like
;   RUNBACK -3 COMMAND
; makes it wait three seconds after starting the command.  The number after
; the dash must be ONE DIGIT ONLY, and it must come before the command.


		include		"exec/types.i"
		include		"exec/execbase.i"	    ; for ONE symbol!
		include		"libraries/dosextens.i"
		include		"libraries/dos_lib.i"


aptr		equr		a5
kask		equr		a4
me		equr		a3
dosbase		equr		a2
alen		equr		d7
kiss		equr		d6
koss		equr		d5
lay		equr		d4


callib:		macro
		  jsr		_LVO\1(a6)
		endm

dcall:		macro
		  move.l	dosbase,a6
		  callib	\1
		endm

_LVOFindTask		equ		-294
_LVOOldOpenLibrary	equ		-408
_LVOCloseLibrary	equ		-414


; for debugging:
		xdef		BEGIN,start,exit,Spew,lenokay,nullokay,xok


BEGIN:		bra		start

dosname:	dc.b		"dos.library",0
nullname:	dc.b		"NULL:",0
longerr:	dc.b		"RunBack command argument line too long!",10,0
nullerr:	dc.b		"NULL: not mounted for RunBack!",10,0
xerr:		dc.b		"Could not run command!  No memory?",10,0

BUFIZE		equ		300
cmdstart	equ		-BUFIZE-4

start:		lea		cmdstart(sp),sp
		move.l		d0,alen
		move.l		a0,aptr
		move.l		4,a6
;;;		sub.l		a1,a1
;;;		callib		FindTask
;;;		move.l		d0,me
		 move.l		ThisTask(a6),me
		lea		dosname,a1
		callib		OldOpenLibrary
		move.l		d0,dosbase
		move.l		pr_CIS(me),kiss
		move.l		pr_COS(me),koss
		move.l		pr_ConsoleTask(me),kask

		cmp.l		#251,alen
		ble		lenokay
		  lea		longerr,a0
;;;		  bsr		Spew
;;;		  moveq		#20,d3
;;;		  bra		exit
		   bra		spewDie

lenokay:	move.l		pr_WindowPtr(me),-(sp)
		move.l		#-1,pr_WindowPtr(me)
		lea		nullname,a0
		move.l		a0,d1
		move.l		#MODE_NEWFILE,d2
		dcall		Open
		move.l		(sp)+,pr_WindowPtr(me)
		move.l		d0,pr_COS(me)
		bne		nullokay
		  lea		nullerr,a0
spewDie:	  bsr		Spew
		  moveq		#20,d3
		  bra		exit
nullokay:	move.l		d0,pr_CIS(me)
		asl.l		#2,d0
		move.l		d0,a0
		move.l		fh_Type(a0),pr_ConsoleTask(me)

		moveq		#0,lay
		cmp.b		#'-',(aptr)
		bne		makecmd
		  move.b	1(aptr),d0
		  sub.b		#'0',d0
		  bmi		makecmd
		    cmp.b	#9,d0
		    bgt		makecmd
		      move.b	d0,lay			; aha, a -delay option
		      mulu	#TICKS_PER_SECOND,lay
		      addq	#3,aptr
		      subq	#3,alen
makecmd:	move.l		#'Run ',cmdstart(sp)
		lea		cmdstart+4(sp),a0
cpy:		  move.b	(aptr)+,(a0)+
		  dbra		alen,cpy
		clr.b		-(a0)		; loop always moves one too many

		lea		cmdstart(sp),a0
		move.l		a0,d1
		moveq		#0,d2
		move.l		pr_COS(me),d3
		callib		Execute		; TA DA
		moveq		#0,d3
		tst.l		d0
		bne		xok
		  lea		xerr,a0
		  bsr		Spew
		  moveq		#10,d3

xok:		move.l		pr_COS(me),d1
		callib		Close
		move.l		kiss,pr_CIS(me)
		move.l		koss,pr_COS(me)
		move.l		kask,pr_ConsoleTask(me)
		moveq		#0,d3
		tst.l		lay
		beq		exit
		  move.l	lay,d1
		  callib	Delay

exit:		move.l		dosbase,a1
		move.l		4,a6
		callib		CloseLibrary
		lea		-cmdstart(sp),sp
		move.l		d3,d0
		rts



; Spew: writes string passed in a0 to standard output.

Spew:		move.l		koss,d1
		beq		nospew
		move.l		a0,a1
len:		  tst.b		(a1)+
		  bne		len
		sub.l		a0,a1
		subq.l		#1,a1
		move.l		a1,d3
		move.l		a0,d2
		dcall		Write
nospew:		rts
