changeset 3018:e7ffcda58117

Initial comming for my snakes demonstration and the sdir command. Snakes draws an animated snake in text and graphics windows. Sdir is used the display the directory on the CoCoSDC SD card.
author tlindner
date Thu, 27 Nov 2014 21:01:17 -0800
parents 545a59f51fee
children 9abe4d732538
files 3rdparty/utils/makefile 3rdparty/utils/tlindner/defsfile 3rdparty/utils/tlindner/makefile 3rdparty/utils/tlindner/sdir.asm 3rdparty/utils/tlindner/snake.asm
diffstat 5 files changed, 791 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/3rdparty/utils/makefile	Thu Nov 27 20:03:48 2014 -0800
+++ b/3rdparty/utils/makefile	Thu Nov 27 21:01:17 2014 -0800
@@ -1,6 +1,6 @@
 include ../../rules.mak
 
-dirs	= boisy dasm smartwatch supercomm dladd winfo gene
+dirs	= boisy dasm smartwatch supercomm dladd winfo gene tlindner
 
 # Make all components
 all:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/utils/tlindner/defsfile	Thu Nov 27 21:01:17 2014 -0800
@@ -0,0 +1,2 @@
+	use	os9.d
+	use	scf.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/utils/tlindner/makefile	Thu Nov 27 21:01:17 2014 -0800
@@ -0,0 +1,44 @@
+include ../../../rules.mak
+
+DEPENDS		= ./makefile
+
+CMDS		= snake sdir
+
+ALLOBJS		= $(CMDS)
+
+DSKTLU		= tlindner_utils.dsk
+
+DSKS		= $(DSKTLU)
+
+all:	banner $(ALLOBJS) $(DEPENDS)	
+
+banner:
+	@$(ECHO) "**************************************************"
+	@$(ECHO) "*                                                *"
+	@$(ECHO) "*               tlindner utilities               *"
+	@$(ECHO) "*                                                *"
+	@$(ECHO) "**************************************************"
+
+$(DSKTLU): $(CMDS)
+	$(RM) $@
+	$(OS9FORMAT) -q $@ -n"tindner utilities"
+	$(MAKDIR) $@,CMDS
+	$(OS9COPY) $(CMDS) $@,CMDS
+	$(OS9ATTR_EXEC) $(foreach file,$(CMDS),$@,CMDS/$(file))
+
+dsk: all $(DSKS)
+
+dskcopy: dsk
+	$(CP) $(DSKS) $(DSKDIR)
+
+dskclean:
+	$(RM) $(DSKS)
+
+clean: dskclean
+	$(RM) $(ALLOBJS)
+
+info:
+	@echo "*** tlindner utilities ***"
+	@$(foreach dsk, $(DSKS), $(ECHO) $(dsk);)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/utils/tlindner/sdir.asm	Thu Nov 27 21:01:17 2014 -0800
@@ -0,0 +1,370 @@
+********************************************************************
+* sdir - Print directory of SDC card
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2014/11/20  tim lindner
+* Started writing code.
+
+         nam   sdir
+         ttl   Print directory of SDC card
+
+         ifp1
+         use   defsfile
+         endc
+
+* Here are some tweakable options
+DOHELP   set   0	1 = include help info
+STACKSZ  set   32	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
+
+*********************************************************************
+*** Hardware Addressing
+*********************************************************************
+CTRLATCH equ $FF40 ; controller latch (write)
+CMDREG   equ $FF48 ; command register (write)
+STATREG  equ $FF48 ; status register (read)
+PREG1    equ $FF49 ; param register 1
+PREG2    equ $FF4A ; param register 2
+PREG3    equ $FF4B ; param register 3
+DATREGA  equ PREG2 ; first data register
+DATREGB  equ PREG3 ; second data register
+*********************************************************************
+*** STATUS BIT MASKS
+*********************************************************************
+BUSY     equ %00000001
+READY    equ %00000010
+FAILED   equ %10000000
+
+         mod   eom,name,tylg,atrv,start,size
+
+            org   0
+buffer	   rmb  256*5
+
+cleartop equ   .	everything up to here gets cleared at start
+* Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do
+         rmb   STACKSZ+PARMSZ
+size     equ   .
+
+* The utility name and edition goes here
+name     fcs   /sdir/
+         fcb   edition
+* Place constant strings here
+header   fcc   /SDC Directory: /
+headerL  equ   *-header
+basepath fcc	/L:*.*/
+			fcb	0
+timoutError fcc /Timeout./
+carrigeReturn fcb C$LF
+         fcb C$CR
+timoutErrorL  equ   *-timoutError
+
+dirNotFound fcc /Directory not found./
+            fcb C$LF
+            fcb C$CR
+dirNotFoundL  equ   *-dirNotFound
+
+pathNameInvalid fcc /Pathname is invalid./
+            fcb C$LF
+            fcb C$CR
+pathNameInvalidL  equ   *-pathNameInvalid
+
+miscHardwareError fcc /Miscellaneous hardware error./
+            fcb C$LF
+            fcb C$CR
+miscHardwareErrorL  equ   *-miscHardwareError
+
+notInitiated fcc /Listing not initiated./
+            fcb C$LF
+            fcb C$CR
+notInitiatedL  equ   *-notInitiated
+
+*
+* 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.
+* main program
+start    equ *
+* create path string in buffer area
+         decb
+   	   pshs u,x,d
+   	   leax basepath,pc
+   	   ldd ,x++ copy 'L:'
+   	   std ,u++
+   	   puls d
+   	   cmpd #$0
+   	   bne copyParameterArea
+* use '*.*' if user suplied no parameter
+   	   ldd ,x++ copy '*.*' and null
+   	   std ,u++
+   	   ldd ,x++
+   	   std ,u++
+   	   puls x,u
+   	   ldd #$5 Length of buffer
+   	   bra printHeader
+copyParameterArea equ *
+         puls x
+         pshs d
+cpaLoop  lda ,x+
+         sta ,u+
+         decb
+         beq cpaDone
+         bra cpaLoop
+cpaDone	clra put null at end of parameter string
+			sta ,u+
+			puls d
+			addd #3
+			puls u
+			leas	0,y  clobber parameter area, put stack at top, giving us as much RAM as possible
+printHeader equ *
+			pshs d
+         lda #1 Output path (stdout)
+         ldy #headerL
+         leax header,pc header in x
+         os9 I$Write Send the value to the device driver
+* print path			
+			puls y
+         leax buffer,u buffer in x
+         os9 I$Write Send the value to the device driver
+         ldy #2 length of buffer
+         leax >carrigeReturn,pcr buffer in x
+         os9 I$Write Send the value to the device driver
+* wait until our next tick to communicate with the SDC
+         ldx   #$1
+         os9   F$Sleep
+* setup SDC for directory processing
+         orcc #IntMasks  mask interrupts
+			lbsr CmdSetup
+			bcc sendCommand
+			ldb #$f6 Not ready error code
+			lbra Exit
+sendCommand equ *
+			ldb #$e0 load initial directory listing command
+			stb CMDREG send to SDC command register
+			exg a,a wait
+         leax buffer,u point to transfer bufer
+         lbsr txData transmit buffer to SDC
+         bcc getBuffer
+         tstb
+         beq timeOut
+			bitb #$10
+			bne targetDirectoryNotFoundError
+			bitb #$08
+			bne miscellaneousHardwareError
+			bitb #$04
+			bne pathNameInvalidError
+         lbra Exit
+getNextDirectoryPage equ *
+			leax 256*2,x
+			tfr s,d
+			pshs d
+			cmpx ,s++
+			bhi printBuffer
+			leax -256,x
+getBuffer equ *
+			ldb #$3e set parameter #1
+			stb PREG1
+			ldb #$c0 set command code
+			stb CMDREG send to SDC command register
+			lbsr rxData
+			bcc checkBuffer
+			tstb
+			beq timeOut
+			bitb #$8
+			bne notInitiatedError
+			bra Exit
+timeOut  equ *
+         leax >timoutError,pcr point to help message
+         ldy #timoutErrorL get length
+genErr   clr CTRLATCH
+         andcc #^IntMasks unmask interrupts
+         lda #$02		std error
+         os9 I$Write 	write it
+         clrb clear error
+			bra ExitNow
+targetDirectoryNotFoundError equ *
+			leax >dirNotFound,pcr
+			ldy #dirNotFoundL
+			bra genErr
+miscellaneousHardwareError equ *
+			leax >miscHardwareError,pcr
+			ldy #miscHardwareErrorL
+			bra genErr
+pathNameInvalidError equ *
+			leax >pathNameInvalid,pcr
+			ldy #pathNameInvalidL
+			bra genErr
+notInitiatedError equ *
+			leax >notInitiated,pcr
+			ldy #notInitiatedL
+			bra genErr
+
+* Check buffer for nulled entry. This signifies the end
+checkBuffer equ *
+         lda #16
+         leau ,x go back to start of buffer
+cbLoop   ldb ,u
+         beq printBuffer
+         leau 16,u
+         deca
+         beq getNextDirectoryPage
+         bra cbLoop
+         
+printBuffer equ *
+         clr CTRLATCH
+         andcc #^IntMasks unmask interrupts
+         clrb
+         tfr dp,a
+         tfr d,u
+         lda #1 Output path (stdout)
+pbLoop   ldy #8 length of buffer
+			leax ,u
+         os9 I$Write Send the value to the device driver
+         ldy #2 length of buffer
+         leax >carrigeReturn,pcr buffer in x
+         os9 I$Write Send the value to the device driver
+         leau 16,u
+         ldb ,u
+         beq ExitOK
+         bra pbLoop
+			
+
+ExitOk   clrb
+Exit     clr CTRLATCH
+         andcc #^IntMasks unmask interrupts
+ExitNow  os9 F$Exit
+
+*********************************************************************
+* Setup Controller for Command Mode
+*********************************************************************
+* EXIT:
+*   Carry cleared on success, set on timeout
+*   All other registers preserved
+*
+CmdSetup      pshs x,a                   ; preserve registers
+              lda #$43                   ; put controller into..
+              sta CTRLATCH               ; Command Mode
+              ldx #0                     ; long timeout counter = 65536
+busyLp        lda STATREG                ; read status
+              lsra                       ; move BUSY bit to Carry
+              bcc setupExit              ; branch if not busy
+              leax -1,x                  ; decrement timeout counter
+              bne busyLp                 ; loop if not timeout
+              lda #0                     ; clear A without clearing Carry
+              sta CTRLATCH               ; put controller back in emulation
+setupExit     puls a,x,pc                ; restore registers and return
+
+*********************************************************************
+* Send 256 bytes of Command Data to SDC Controller
+*********************************************************************
+* ENTRY:
+*   X = Data Address
+*
+* EXIT:
+*   B = Status
+*   Carry set on failure or timeout
+*   All other registers preserved
+*
+txData      pshs u,y,x                  ; preserve registers
+            ldy #DATREGA                ; point Y at the data registers
+* Poll for Controller Ready or Failed.
+            comb                        ; set carry in anticipation of failure
+            ldx #0                      ; max timeout counter = 65536
+txPoll      ldb -2,y                    ; read status register
+            bmi txExit                  ; branch if FAILED bit is set
+            bitb #READY                 ; test the READY bit
+            bne txRdy                   ; branch if ready
+            leax -1,x                   ; decrement timeout counter
+            beq txExit                  ; exit if timeout
+            bra txPoll                  ; poll again
+* Controller Ready. Send the Data.
+txRdy       ldx ,s                      ; re-load data address into X
+            ldb #128                    ; 128 words to send (256 bytes)
+txWord      ldu ,x++                    ; get data word from source
+            stu ,y                      ; send to controller
+            decb                        ; decrement word loop counter
+            bne txWord                  ; loop until done
+            ldx #0                      ; wait for result
+* Done sending data, wait for result
+            comb                        ; assume error
+txWait      ldb -2,y                    ; load status
+            bmi txExit                  ; branch if failed
+            bitb #READY                 ; test ready bit
+            bne txExitOK                ; branch if ready
+            leax -1,x                   ; decrememnt timeout counter
+            bne txWait			          ; loop back until timeout
+txExitOK    andcc #^1
+txExit      puls x,y,u,pc               ; restore registers and return
+
+*********************************************************************
+* Retrieve 256 bytes of Response Data from SDC Controller
+*********************************************************************
+* ENTRY:
+*    X = Data Storage Address
+*
+* EXIT:
+*    B = Status
+*    Carry set on failure or timeout
+*    All other registers preserved
+*
+rxData      pshs u,y,x                  ; preserve registers
+            ldy #DATREGA                ; point Y at the data registers
+* Poll for Controller Ready or Failed.
+            comb                        ; set carry in anticipation of failure
+            ldx #0                      ; max timeout counter = 65536
+rxPoll      ldb -2,y                    ; read status register
+            bmi rxExit                  ; branch if FAILED bit is set
+            bitb #READY                 ; test the READY bit
+            bne rxRdy                   ; branch if ready
+            leax -1,x                   ; decrement timeout counter
+            beq rxExit                  ; exit if timeout
+            bra rxPoll                  ; poll again
+* Controller Ready. Grab the Data.
+rxRdy       ldx ,s                      ; re-load data address into X
+            ldb #128                    ; 128 words to read (256 bytes)
+rxWord      ldu ,y                      ; read data word from controller
+            stu ,x++                    ; put into storage
+            decb                        ; decrement word loop counter
+            bne rxWord                  ; loop until done
+            clrb                        ; success! clear the carry flag
+rxExit      puls x,y,u,pc               ; restore registers and return
+
+*********************************************************************
+* This routine skip over spaces and commas
+*********************************************************************
+* Entry:
+*   X = ptr to data to parse
+* Exit:
+*   X = ptr to first non-whitespace char
+*   A = non-whitespace char
+SkipSpcs lda   ,x+
+         cmpa  #C$SPAC
+         beq   SkipSpcs
+         leax  -1,x
+         rts
+
+         emod
+eom      equ   *
+         end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/utils/tlindner/snake.asm	Thu Nov 27 21:01:17 2014 -0800
@@ -0,0 +1,374 @@
+********************************************************************
+* Snake - Animate slithering snake in window
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2014/10/08  tim lindner
+* Started writing code.
+
+         nam   Snake
+         ttl   Animate slithering snake in window
+
+         ifp1
+         use   defsfile
+         endc
+
+* Here are some tweakable options
+DOHELP   set   1	1 = include help info
+STACKSZ  set   32	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
+
+         org   0
+bail_flag   rmb   1
+windowx     rmb   1
+windowy     rmb   1
+time        rmb   3
+RND         rmb   3
+snakesize	rmb	1
+head        rmb   1
+IOBUF       rmb   4
+IOBUF2      rmb   4
+cleartop equ   .	everything up to here gets cleared at start
+* Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do
+snakebuffer rmb   80*2
+         rmb   STACKSZ+PARMSZ
+size     equ   .
+
+* The utility name and edition goes here
+name     fcs   /Snake/
+         fcb   edition
+         
+* Place constant strings here
+         IFNE  DOHELP
+HlpMsg   fcb   C$LF
+         fcc   /Use: Snake <size>/
+         fcb   C$LF
+         fcb   C$CR
+         fcc   /  Size is less than window width./
+         fcb   C$LF
+         fcb   C$CR
+HlpMsgL  equ   *-HlpMsg
+         ENDC
+*
+* 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
+
+* This routine skip over spaces and commas
+*
+* Entry:
+*   X = ptr to data to parse
+* Exit:
+*   X = ptr to first non-whitespace char
+*   A = non-whitespace char
+SkipSpcs lda   ,x+
+         cmpa  #C$SPAC
+         beq   SkipSpcs
+         leax  -1,x
+         rts
+
+* 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    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
+
+         lda   ,x+         	get first char
+         cmpa  #C$CR		CR?
+         lbeq  ShowHelp
+* Process command line (a single number)
+nextChar suba  #'0'     Convert ASCII number to value
+         adda  snakesize,u add stored value with new value
+         sta   snakesize,u store new snake size
+         lda   ,x      get next char
+         cmpa  #'0'
+         blo  clDone
+         cmpa  #'9'
+         bhi  clDone
+         lda   #10
+         ldb   snakesize,u multiply current snake size by 10
+         mul
+         stb   snakesize,u
+         lda   ,x+      get next char
+         bra   nextChar
+clDone   cmpb  #80
+         ble   timeSeed
+         ldb   #80
+         stb   snakesize,u
+* Get Time packet to seed PRNG
+timeSeed leax  time,u
+         os9   F$Time
+* Turn off cursor
+         leax  IOBUF,u
+         lda   #$05     05 20 is turn off cursor code
+         sta   ,x
+         lda   #$20
+         sta   1,x
+         ldy   #2      Length of buffer
+         lda   #1      Output path (stdout)
+         os9   I$Write  Send the value to the device driver
+* Add intercept
+         leax  IR,pcr
+         os9   F$Icpt
+* Clear screen
+         leax  IOBUF,u
+         lda   #$0c     load 'clear screen' code for VDGINT/WINDINT
+         sta   ,x
+         ldy   #1      Length of buffer
+         lda   #1      Output path (stdout)
+         os9   I$Write  Send the value to the device driver
+* get window size
+         ldx   #$0
+         ldy   #$0
+         lda   #1       Output Path (stdout)
+         ldb   #SS.ScSiz Request screen size
+         os9   I$Getstt Make requst
+         bcs   sizeErr
+         tfr   x,d
+         cmpb  #$0
+         beq   sizeErr  RBF returns screen size of $0
+         decb
+         stb   windowx,u
+         tfr   y,d
+         decb
+         stb   windowy,u
+         bra   compare
+* If SS.ScSiz returns an error set the window up for 80 x 24
+sizeErr  ldd   #$4f17
+         std   windowx,u
+* compare parameter with window width
+compare  ldb   snakesize,u
+         cmpb  windowx,u
+         lbpl   ShowHelp     bail if parameter is larger than window
+* fill snake buffer with initial X coordinate for snake positions
+*  figure out starting horizontal position of tail
+         clra
+         ldb   snakesize,u
+         lsrb           divide snake size by 2
+         stb   ,-s
+         ldb   windowx,u
+         lsrb           divide window width by 2
+         subb  ,s+     subtract half snake length from half window width
+         addb  #$20     Offset Horizontal position for VDGINT and WINDINT
+         leax  snakebuffer,u
+         lda   snakesize,u
+filloopx stb   ,x++
+         incb
+         deca
+         bne   filloopx fill snake buffer with initial horizontal coordinates
+*  Figure out starting vertical of snake body         
+         ldb   windowy,u
+         lsrb           divide window height by 2
+         addb  #$20     Offset vertical position for VDGINT or WINDINT
+         leax  snakebuffer+1,u
+         lda   snakesize,u
+filloopy stb   ,x++
+         deca
+         bne   filloopy fill snake buffer with initial vertical coordinates
+* Draw initial snake
+         leax  IOBUF,u
+         lda   #$02
+         sta   0,x
+         lda   #'*'
+         sta   3,x
+         ldy   #4      Length of buffer
+         lda   snakesize,u
+         pshs  u
+         leau   snakebuffer,u
+idrlp    ldb   ,u+
+         stb   1,x
+         ldb   ,u+
+         stb   2,x
+         exg   a,b
+         lda   #1      Output path (stdout)
+         os9   I$Write  Send the value to the device driver
+         exg   b,a
+         deca
+         bne   idrlp    Initial draw loop
+         puls  u
+         lda   snakesize,u set head pointer to snake size minus one
+         deca
+         sta   head,u
+* Offset Window size for VDGINT and WINDINT
+         ldd   windowx,u
+         addd  #$2020
+         std   windowx,u
+* Set up IOBUF2 for Easing
+         lda   #$02
+         sta   IOBUF2,u
+         lda   #' '
+         sta   IOBUF2+3,U
+MainLoop equ   *
+* Erase tail
+         leay  snakebuffer,u
+         leax  IOBUF2,u
+         ldb   head,u
+         incb
+         cmpb  snakesize,u
+         bne   mlcont1
+         clrb
+mlcont1  stb   head,u   Store new head offset
+         lslb
+         ldd   b,y   offset into table pointer
+         sta   1,x
+         stb   2,x
+         ldy   #4
+         lda   #1      Output path (stdout)
+         os9   I$Write  Send the value to the device driver
+* Find position for new head
+*  Set Reg X to point to current head position
+copyhead ldb   head,u   get head index
+         lslb
+         leax  snakebuffer,u
+         abx   advance X to correct position
+         lsrb
+         bne   mlcont2  if not zero
+         ldb   snakesize,u get snake buffer size
+mlcont2  decb  Back up one index
+         lslb  multiply by two
+         leay  snakebuffer,u  point y to start of buffer
+         leay  b,y      advance Y to correct position
+         ldd   ,y       load coordinates
+         std   ,x       save coordinates
+* pick random number
+pick     ldb   #$4
+         lbsr   RAND
+         deca
+         beq   goLeft
+         deca
+         beq   goDown
+         deca
+         beq   goRight
+
+* Remember: coordinates are pre-offset by a value of $20
+
+goUp     ldb   1,x
+         cmpb  #$20
+         beq   pick
+         decb
+         stb   1,x
+         bra   drawHead
+
+goDown   ldb   1,x
+         incb
+         cmpb  windowy,u
+         beq   pick
+         stb   1,x
+         bra   drawHead
+         
+goLeft   ldb   ,x
+         cmpb  #$20
+         beq   pick
+         decb
+         stb   ,x
+         bra   drawHead
+
+goRight  ldb   ,x
+         cmpb  windowx,u
+         beq   pick
+         incb
+         stb   ,x
+         bra   drawHead
+
+drawHead ldd   ,x
+         std   IOBUF+1,u
+         lda   #$1
+         ldy   #$4
+         leax  IOBUF,u
+         os9   I$Write  Send the value to the device driver
+         lda   bail_flag
+         bne   ExitOK
+         ldx   #$1
+         os9   F$Sleep
+         lbra  MainLoop
+
+ExitOk   bsr   bail
+         clrb
+Exit     os9   F$Exit
+
+IR       lda   #$ff
+         sta   bail_flag,u
+         rti
+* Turn on cursor
+bail     leax  IOBUF,u
+         lda   #$05     05 21 is turn on cursor code
+         sta   ,x
+         lda   #$21
+         sta   1,x
+         ldy   #2      Length of buffer
+         lda   #1      Output path (stdout)
+         os9   I$Write  Send the value to the device driver
+         rts
+
+ShowHelp equ   *
+         IFNE  DOHELP
+         leax  >HlpMsg,pcr	point to help message
+         ldy   #HlpMsgL		get length
+         lda   #$02		std error
+         os9   I$Write 	write it
+         ENDC
+         bra   ExitOk
+         
+* THIS IS A FAST MEDIUM GRADE RANDOM NUMBER GENERATOR
+* From SYMMETRY by Robert Gault, 1993
+* LENGTH OF NON-REPEATING SEQUENCE = 16,777,215
+* INTERMEDIATE OUTPUT 0 - 255 OR 0 - .996078431 STEPS OF .003921568
+* ENTER: REG.B = N+1
+* EXIT:  REG.A = 0 TO N
+*        REG.B = FRACTIONAL PART OF N
+RAND	LDA	RND+2,u	GET 19TH BIT
+      ANDA	#%00100000
+      LSLA		      ALIGN IT WITH 24TH BIT
+      LSLA		      FASTER THAN SHIFTING TO RIGHT
+      LSLA
+      ROLA
+      EORA	RND+2,u	     XOR BITS 19&24
+      LSRA		         RESULT TO CARRY
+      ROR	RND,u	      FEED RESULT INTO RANDOM NUMBER
+      ROR	RND+1,u		   AND SHIFT TO THE RIGHT
+      ROR	RND+2,u
+      LDA	RND,u
+      MUL
+      RTS
+
+         emod
+eom      equ   *
+         end
+         
\ No newline at end of file