home *** CD-ROM | disk | FTP | other *** search
- ;********************************************************************
- ;
- ; cookie
- ;
- ; (C) Stuart Mitchell - 11/11/90
- ;
- ;********************************************************************
-
- section cookie,code
-
- opt o+
-
- incdir include:
-
- include exec/types.i
- include exec/memory.i
- include libraries/dos.i
- include libraries/arpbase.i
- include libraries/dosextens.i
-
- _LVOOpenLibrary equ -$228
- _LVOCloseLibrary equ -$19e
-
- BUFFER equ 256
- COOKIE equ 1024 ; size of buffer to store cookie
- SEPERATOR equ $0c ; char that seperates fortunes
-
- ; register defns. - NB don't change address-->data or vice versa
-
- r_jar equr a2
- r_buffer equr a3
- r_dest equr a4
- r_arpbase equr a6 ; this must be a6
-
- r_cookies_fh equr d4
- r_ptrs_fh equr d5
- r_current_char equr d6
- r_num_read equr d7
-
- CALL macro
- jsr _LVO\1(a6)
- endm
-
- ;********************************************************************
-
- start: lea arplib(pc),a1
- moveq.l #0,d0
- move.l 4.w,a6
- CALL OpenLibrary
- tst.l d0
- beq to_dos
- move.l d0,r_arpbase
-
- ; allocate memory (MEMF_PUBLIC|MEMF_CLEAR) for cookie & file buffer
-
- move.l #BUFFER+COOKIE,d0
- CALL ArpAlloc
- tst.l d0
- beq closearp
-
- cont: move.l d0,r_jar ; save address of cookie jar
- lea COOKIE(r_jar),r_buffer ; address of read buffer
-
- ; open cookie/pointers file
-
- move.l #file,d1
- move.l #MODE_OLDFILE,d2
- CALL ArpOpen ; open cookies
- move.l d0,r_cookies_fh ; sets zero flag if zero
- beq.s error
- move.l #ptrs,d1
- CALL ArpOpen ; open pointers
- move.l d0,r_ptrs_fh
- bne.s setseed ; ok ... so continue
-
- ; if error then print msg
-
- error: lea no_cookies(pc),a1
- CALL Puts
- bra.s closearp
-
- ; main loop proggy
-
- setseed: move.l r_buffer,d1 ; move start of buffer
- CALL DateStamp
-
- ;set random seed based on ticks value from DateStamp
-
- move.l ds_Tick(r_buffer),d0
- bsr RandomSeed
-
- ; get position in file
-
- getpos: moveq.l #0,d2
- move.l r_ptrs_fh,d1
- moveq.l #OFFSET_BEGINNING,d3
- CALL Seek ; move to start pointers
-
- ; get number of cookies
-
- bsr.s readptr
-
- ; generate random number in range 0..(number cookies -1)
-
- move.l (r_buffer),d0
- bsr Random ; get number 0..number cookies
-
- asl.l #2,d0 ; times 4
- move.l d0,d2
- move.l r_ptrs_fh,d1
- moveq.l #OFFSET_CURRENT,d3
- CALL Seek ; move to cookie pointer
- bmi.s getpos
-
- bsr.s readptr
- move.l (r_buffer),d2 ; save cookie position
-
- ; seek to position in cookie file
-
- move.l r_cookies_fh,d1 ; get cookie file handle
- moveq.l #OFFSET_BEGINNING,d3
- CALL Seek
- bmi.s getpos ; if negative repeat
-
- ; copy fortune into buffer
-
- moveq.l #0,r_current_char
- moveq.l #0,r_num_read
- move.l r_jar,r_dest ; a4 = destination char
-
- copy_fort: bsr.s getchar
- beq.s out ; if EOF then print
- move.b d0,(r_dest)+
- cmpi.b #SEPERATOR,d0
- bne.s copy_fort
-
- out: clr.b -1(r_dest) ; null terminate string
-
- ; write contents of cookie jar
-
- move.l r_jar,a1
- CALL Puts
-
- ; Arp automatically frees memory & closes files
-
- closearp: move.l r_arpbase,a1
- move.l 4.w,a6
- CALL CloseLibrary
-
- to_dos: moveq.l #0,d0
- rts
-
- ; read 4 bytes from file, used to get number of cookies/cookie locations
-
- readptr: move.l r_ptrs_fh,d1
- moveq.l #4,d3
- move.l r_buffer,d2
- jmp _LVORead(a6) ; read 4 bytes
-
- ; get character from file, refill buffer if required
-
- getchar: cmp.l r_current_char,r_num_read
- bne.s retchar
- move.l r_cookies_fh,d1
- move.l r_buffer,d2
- move.l #BUFFER,d3
- CALL Read
- move.l d0,r_num_read
- beq.s oh_no ; read failed!
- moveq.l #0,r_current_char
- retchar: move.b (r_buffer,r_current_char),d0
- addq.l #1,r_current_char
- oh_no: rts
-
- ; random number functions
-
- ; The following code was taken from a public domain program. However I
- ;have since forgetton the name of the author. I apologise to him/her but
- ;do acknowledge their authorship.
-
- RandomSeed add.l d0,d1 user seed in d0 (d1 too)
- movem.l d0/d1,rnd
-
- LongRnd movem.l d2-d3,-(sp)
- movem.l rnd,d0/d1 d0=LSB's, d1=MSB's of random number
- andi.b #$0e,d0 ensure upper 59 bits are an...
- ori.b #$20,d0 ...odd binary number
- move.l d0,d2
- move.l d1,d3
- add.l d2,d2 accounts for 1 of 17 left shifts
- addx.l d3,d3 [d2/d3] = rnd*2
- add.l d2,d0
- addx.l d3,d1 [d0/d1] = rnd*3
- swap d3 shift [d2/d3] additional 16 times
- swap d2
- move.w d2,d3
- clr.w d2
- add.l d2,d0 add to [d0/d1]
- addx.l d3,d1
- movem.l d0/d1,rnd save for next time through
- move.l d1,d0 most random part to d0
- movem.l (sp)+,d2-d3
- rts
-
- Random move.w d2,-(sp)
- move.w d0,d2 save upper limit
- beq.s 10$ range of 0 returns 0 always
- bsr.s LongRnd get a longword random number
- clr.w d0 use upper word (it's most random)
- swap d0
- divu.w d2,d0 divide by range...
- clr.w d0 ...and use remainder for the value
- swap d0 result in d0.w
- 10$ move.w (sp)+,d2
- rts
-
- even
- no_cookies: dc.b "No cookies!",$0a,0
- even
- file: dc.b "s:cookie.dat",0
- even
- ptrs: dc.b "s:cookie.ptr",0
- even
- arplib: dc.b "arp.library",0
- even
- rnd ds.l 2 random number
-
- end
-