home *** CD-ROM | disk | FTP | other *** search
- opt l+,o+,ow-
-
- *-- AutoRev header do NOT edit!
- *
- * Program : ascii.s
- * Copyright : © 1991 Jaba Development
- * Author : Jan van den Baard
- * Creation Date : 16-Apr-91
- * Current version : 1.1ca
- * Translator : Devpac version 2.14
- *
- * REVISION HISTORY
- *
- * Date Version Comment
- * --------- ------- ------------------------------------------
- * 12-Aug-91 1.1a Output code size = 1664 bytes.
- * 12-Aug-91 1.1a Added FindFrom routine.
- * 23-Apr-91 1.0c Output code size = 1638 bytes.
- * 19-Apr-91 1.0b Output code size = 1758 bytes.
- * 18-Apr-91 1.0a Output code size = 1800 bytes.
- * 16-Apr-91 1.0 Output code size = 1808 bytes.
- * 16-Apr-91 1.0 Initial version!
- *
- *-- REV_END --*
-
- incdir 'sys:devpac_inc/'
- include 'mymacros.i'
- include 'exec/types.i'
- include 'exec/exec_lib.i'
- include 'libraries/dos.i'
- include 'libraries/dos_lib.i'
- include 'libraries/nofrag.i'
- include 'libraries/nofrag_lib.i'
-
- include ':ascii.i'
-
- xref _DOSBase
-
- xdef _BOpen
- xdef _BClose
- xdef _BIoErr
- xdef _BGetC
- xdef _BPutC
- xdef _BGetS
- xdef _BPutS
-
- xdef _AllocAscii
- xdef _FreeAscii
- xdef _FindFrom
- xdef _FirstOccurrence
- xdef _NextOccurrence
- xdef _PreviousOccurrence
-
- PUBLIC equ MEMF_PUBLIC!MEMF_CLEAR
- LF equ $0a
- TAB equ $09
- ESC equ $1b
- CSI equ $9b
-
- _BOpen: pushem.l d2-d4/a2-a3/a6
-
- move.l 7*4(sp),a2 ; name to a2
- move.l 8*4(sp),d2 ; mode to d2
-
- move.l (_SysBase).w,a6
- move.l #bio_SIZEOF,d0
- move.l #PUBLIC,d1
- libcall AllocMem ; allocate the structure
- move.l d0,a3 ; put it in a3
- beq.s NoFMem ; FAILED !?!?!
- move.l d2,bio_FileMode(a3) ; set file mode
- move.l _DOSBase,a6
- move.l a2,d1
- libcall Open ; try to open the file
- move.l d0,bio_Handle(a3) ; store the handle
- beq.s NoFile ; FAILED !?!?!
- lea.l bio_Buffer(a3),a0
- move.l a0,bio_Pointer(a3) ; set byte pointer
- move.w #ASE_OK,bio_Error(a3) ; preset file error
- move.w #0,bio_BytesLeft(a3) ; no bytes in buffer
- move.l #0,bio_BytesDone(a3) ; no bytes IO'd
- move.l a3,d0 ; return the pointer
- bra.s OAEnd
- NoFile: move.l (_SysBase).w,a6
- move.l #bio_SIZEOF,d0
- move.l a3,a1
- libcall FreeMem ; free the structure
- NoFMem: cldat d0 ; return null (FAIL)
- OAEnd: popem.l d2-d4/a2-a3/a6
- rts
-
- *
- * You should ALWAYS check if this routine returns a ASE_WRITE error
- * because it writes the bytes still in the buffer to the file when
- * bufferd output has been performed with the file!
- *
- _BClose: pushem.l d2-d4/a2/a6
-
- move.l 6*4(sp),a2 ; file pointer to a2
-
- cmp.l #MODE_NEWFILE,bio_FileMode(a2)
- bne.s IODone
- bsr FlushBuffer ; force bytes left to file
- blt.s Err ; < 0 is error
- moveq #ASE_OK,d2
- IODone: move.l _DOSBase,a6
- move.l bio_Handle(a2),d1
- libcall Close ; close the file
- move.l (_SysBase).w,a6
- move.l #bio_SIZEOF,d0
- move.l a2,a1
- libcall FreeMem ; deallocate the structure
- move.l d2,d0
- popem.l d2-d4/a2/a6
- rts
- Err: moveq #ASE_WRITE,d2 ; write error !?!
- bra.s IODone
-
- _BIoErr: move.l 4(sp),a0
- move.w bio_Error(a0),d0 ; get last error from struct
- ext.l d0 ; correct long exstension
- rts
-
- _BGetC: pushem.l d2-d4/a2/a6
-
- move.l 6*4(sp),a2 ; get file pointer in a2
-
- cmp.l #MODE_OLDFILE,bio_FileMode(a2)
- beq.s RBOK ; file mode is ok
- move.w #ASE_FILETYPE,bio_Error(a2)
- moveq #ASE_EOF,d0 ; eof marks error
- bra.s RBEnd
- RBOK: tst.w bio_BytesLeft(a2) ; bytes left in buffer ?
- beq.s FillBuff ; no.. fill the buffer
- GByte: move.l bio_Pointer(a2),a0
- cldat d0
- move.b (a0)+,d0 ; get byte from buffer
- move.l a0,bio_Pointer(a2) ; update byte pointer
- dec.w bio_BytesLeft(a2)
- bra.s RBEnd
- FillBuff: move.l _DOSBase,a6
- move.l bio_Handle(a2),d1 ; handle in d1
- move.l a2,d2
- addq.w #bio_Buffer,d2 ; buffer in d2
- move.l #1024,d3
- libcall Read ; read bytes in buffer
- move.l d0,d4 ; # bytes read in d4
- blt.s RErr
- beq.s REof
- lea.l bio_Buffer(a2),a0
- move.l a0,bio_Pointer(a2) ; reset byte pointer
- move.w d4,bio_BytesLeft(a2) ; reset bytes counter
- add.l d4,bio_BytesDone(a2) ; add # read to counter
- bra.s GByte
- RErr: move.w #ASE_READ,bio_Error(a2) ; read error !?!
- moveq #ASE_EOF,d0
- bra.s RBEnd
- REof: move.w #ASE_EOF,bio_Error(a2) ; end-of-file !?!
- moveq #ASE_EOF,d0
- RBEnd: popem.l d2-d4/a2/a6
- rts
-
- _BPutC: pushem.l d2-d5/a2/a6
-
- move.l 7*4(sp),a2 ; get file pointer in a2
-
- move.l d0,d5 ; byte to write in d5
- cmp.l #MODE_NEWFILE,bio_FileMode(a2)
- beq.s WBOK ; file mode is ok
- move.w #ASE_FILETYPE,bio_Error(a2)
- moveq #ASE_EOF,d0
- bra.s WBEnd
- WBOK: cmp.w #1024,bio_BytesLeft(a2) ; room left in buffer ?
- beq.s WriteBuff ; no.. write the buffer
- PByte: move.l bio_Pointer(a2),a0
- move.b d5,(a0)+ ; put byte in buffer
- move.l a0,bio_Pointer(a2) ; update byte pointer
- inc.w bio_BytesLeft(a2) ; increase byte count
- moveq #ASE_OK,d0
- bra.s WBEnd
- WriteBuff: bsr.s FlushBuffer ; force bytes left to file
- blt.s WErr
- lea.l bio_Buffer(a2),a0
- move.l a0,bio_Pointer(a2) ; reset byte pointer
- move.w #0,bio_BytesLeft(a2) ; reset bytes counter
- add.l d4,bio_BytesDone(a2) ; add # read to counter
- bra.s PByte
- WErr: move.w #ASE_WRITE,bio_Error(a2) ; write error !?!
- moveq #ASE_EOF,d0
- WBEnd: popem.l d2-d5/a2/a6
- rts
-
- FlushBuffer: move.l _DOSBase,a6
- move.l bio_Handle(a2),d1
- move.l a2,d2
- addq.w #bio_Buffer,d2
- cldat d3
- move.w bio_BytesLeft(a2),d3
- libcall Write ; write bytes from buffer
- move.l d0,d4 ; # bytes written in d4
- rts
-
- xref _NoFragBase
-
- _AllocAscii: pushem.l d2-d4/a2/a6
-
- move.l 6*4(sp),d3 ; tabsize to d3
- move.l 7*4(sp),d4 ; maxchars to d4
- move.l 8*4(sp),d2 ; flags to d2
-
- move.l (_SysBase).w,a6
- moveq #at_SIZEOF,d0
- move.l #PUBLIC,d1
- libcall AllocMem ; allocate the structure
- move.l d0,a2 ; put it in a2
- beq.s AANoMem ; FAILED !?!?!
- NEWLIST a2 ; initialize list
- move.w d2,at_Flags(a2) ; set flags
- move.l _NoFragBase,a6
- move.l #4096,d0
- libcall GetMemoryChain ; get memorychain struct
- move.l d0,at_MemoryUsed(a2) ; put it in asciitext struct
- bne.s AAChainOK
- move.l (_SysBase).w,a6
- move.l a2,a1
- moveq #at_SIZEOF,d0
- libcall FreeMem
- cldat d0
- bra.s AANoMem
- AAChainOK: cmp.w #MINTAB,d3
- bcc.s TOK
- move.w #MINTAB,d3
- bra.s CheckMax
- TOK: cmp.w #MAXTAB,d3
- bls.s CheckMax
- move.w #MAXTAB,d3
- CheckMax: cmp.w #5,d4
- bcc.s MOK
- move.w #5,d4
- bra.s AAEnd
- MOK: cmp.w #MAXLINE,d4
- bls.s AAEnd
- move.w #MAXLINE,d4
- AAEnd: move.w d3,at_TabJump(a2)
- move.w d4,at_MaxChars(a2)
- move.l a2,d0
- AANoMem: popem.l d2-d4/a2/a6
- rts
-
- _FreeAscii: pushem.l a2/a6
-
- move.l 3*4(sp),a2 ; ascii pointer in a2
-
- move.l _NoFragBase,a6
- move.l at_MemoryUsed(a2),a0
- moveq #1,d0
- libcall FreeMemoryChain ; free the text + chain
- move.l (_SysBase).w,a6
- move.l a2,a1
- moveq #at_SIZEOF,d0
- libcall FreeMem ; free the structure
- popem.l a2/a6
- rts
-
- _BGetS: pushem.l d2-d7/a2-a6
-
- move.l 12*4(sp),a2 ; file pointer to a2
- move.l 13*4(sp),a3 ; ascii pointer to a3
-
- cldat d4
- cldat d5
- cldat d6
- cldat d7
-
- move.w at_TabJump(a3),d6
- move.w d6,d7
- push.l a2
- move.l _NoFragBase,a6
- move.l at_MemoryUsed(a3),d3
- move.l d3,a0
- moveq #ln_SIZEOF,d0
- moveq #MEMF_PUBLIC,d1
- libcall AllocItem ; allocate a line structure
- move.l d0,a4 ; put it in a4
- beq RLNoMem ; FAILED !?!?!
- lea.l bio_Line(a2),a5 ; line buffer in a5
- LineLoop: bsr _BGetC ; read one byte
- move.l d0,d2 ; put it in d2
- blt ReadDone ; Eof ?
- cmp.b #LF,d2 ; is it a Line Feed ?
- bne.s NotLF
- move.b d2,(a5)+
- Max: inc.w d4
- move.w d6,d7
- cldat d0
- move.w d4,d0
- add.w d5,d0
- move.w d0,ln_Size(a4)
- add.l d0,at_NumBytes(a3)
- moveq #MEMF_PUBLIC,d1
- move.l d3,a0
- libcall AllocItem
- move.l d0,ln_Text(a4)
- bne.s MemOK
- move.w #ASE_NOMEM,bio_Error(a2)
- cldat d0
- bra RLEnd
- MemOK: lea.l bio_Line(a2),a0
- move.l d0,a1
- move.w ln_Size(a4),d0
- addq.w #3,d0
- and.w #-4,d0
- lsr.w #2,d0
- dec.w d0
- copy: move.l (a0)+,(a1)+
- dbra d0,copy
- inc.w at_NumLines(a3)
- move.l a4,d0
- move.w #ASE_OK,bio_Error(a2)
- bra RLEnd
- NotLF: move.w at_MaxChars(a3),d0
- dec.w d0
- cmp.w d4,d0
- bne.s NoSplit ; not at maximum
- Mx: bset #LNB_Split,ln_Flags(a4) ; set split flag
- inc.w at_NumSplit(a3)
- dec.l bio_Pointer(a2)
- dec.l bio_BytesDone(a2)
- inc.w bio_BytesLeft(a2)
- move.b #LF,(a5)+ ; put a LF in the line
- bra Max
- NoSplit: cmp.b #TAB,d2 ; is it a TAB ?
- bne.s NoTAB
- btst #ATB_TabConvert,at_Flags(a3)
- bne.s NoTAB ; no tab conversion
- cldat d0
- move.w d7,d0
- dec.w d0
- dec.l bio_BytesDone(a2)
- TabLoop: cldat d1
- move.w at_MaxChars(a3),d1
- dec.w d1
- cmp.w d4,d1
- beq.s Mx ; yes.. stop
- move.b #' ',(a5)+ ; put blank in line
- inc.w d4
- inc.l bio_BytesDone(a2) ; increase read counter
- dbra d0,TabLoop
- move.w d6,d7
- bra LineLoop
- NoTAB: btst #ATB_SkipEsc,at_Flags(a3)
- bne.s NoESC
- cmp.b #ESC,d2 ; is it a ESC ?
- beq.s Esc ; yes!!
- cmp.b #CSI,d2 ; else is it a CSI ?
- bne.s NoESC ; no!!
- Esc: move.b d2,(a5)+ ; put it in the line
- inc.w d5
- sub.b #' ',d2 ; check for terminator
- cmp.b #'?',d2
- bcs NotYet
- cmp.b #'Z',d2
- bls LineLoop
- bra.s GetB
- NotYet: tst.b d2
- beq LineLoop
- GetB: bsr _BGetC ; read sequence byte
- move.l d0,d2
- blt.s ReadDone
- bra.s Esc
- NoESC: dec.w d7
- bne.s TabLeft
- move.w d6,d7
- TabLeft: inc.w d4
- move.b d2,(a5)+
- bra LineLoop
- RLNoMem: move.w #ASE_NOMEM,bio_Error(a2)
- cldat d0
- bra.s RLEnd
- ReadDone: cmp.w #ASE_EOF,bio_Error(a2)
- beq.s Feof
- cldat d0
- bra.s RLEnd
- Feof: cldat d0
- tst.w d4
- bne Max
- move.l d3,a0
- move.l a4,a1
- moveq #ln_SIZEOF,d0
- libcall FreeItem
- cladr a4
- LOK: move.l a4,d0
- RLEnd: addq.w #4,sp
- popem.l d2-d7/a2-a6
- rts
-
- _BPutS: pushem.l d2/a2-a3
-
- move.l 4*4(sp),a2 ; asciifile in a2
- move.l 5*4(sp),a3 ; line in a3
-
- cldat d2
- move.w ln_Size(a3),d2
- dec.w d2
- btst #LNB_Split,ln_Flags(a3) ; line split up ?
- beq.s No ; no..
- dec.w d2
- No: move.l ln_Text(a3),a3
- NoSpt: cldat d0
- move.b (a3)+,d0
- push.l d0
- push.l a2
- bsr _BPutC ; write one char
- addq.w #8,sp
- cmp.l #ASE_EOF,d0
- beq.s WRErr
- dbra d2,NoSpt
- cldat d0
- bra.s WLEnd
- WRErr: move.w bio_Error(a2),d0
- ext.l d0
- WLEnd: popem.l d2/a2-a3
- rts
-
- _FindFrom: pushem.l d2-d5/a2-a6
-
- move.l 10*4(sp),a2 ; get Ascii pointer in a2
- move.l 11*4(sp),a3 ; get string pointer in a3
- move.l 12*4(sp),a4 ; get search in a4
- move.l 13*4(sp),a5 ; get line in a5
- move.l 14*4(sp),d2 ; get case flag in d2
-
- bra.s Search ; start searching....
-
- _FirstOccurrence: pushem.l d2-d5/a2-a6
-
- move.l 10*4(sp),a2 ; get Ascii pointer in a2
- move.l 11*4(sp),a3 ; get string pointer in a3
- move.l 12*4(sp),a4 ; get search in a4
- move.l 13*4(sp),d2 ; get case flag in d2
-
- move.l at_First(a2),a5 ; get first line in a5
- Search: cldat d5
- move.l a3,a0
- bsr StrLen
- move.l d0,d4
- FFLoop: tst.l ln_Next(a5)
- beq.s FFDone ; no more lines !
- move.l ln_Text(a5),a6 ; Text pointer in a6
- cldat d3
- move.w ln_Size(a5),d3 ; line size in d3
- sub.w d4,d3 ; substract it from d3
- dec.w d3
- tst.w d3
- blt.s FFNext ; when < 0 next line
- FFSLoop: move.l a6,a0
- move.l a3,a1
- move.l d4,d0
- tst.w d2
- beq.s FFNoCase
- bsr StrnCmp ; compare (case dependant)
- bra.s FFChecked
- FFNoCase: bsr StrniCmp ; compare (case independant)
- FFChecked: tst.l d0
- beq.s FFCLoop
- move.l a5,sc_Line(a4) ; set line in struct
- move.l a3,sc_String(a4) ; set string ptr in struct
- move.w d4,sc_StringSize(a4) ; set string size in struct
- move.w d5,sc_TextOffset(a4) ; set offset in struct
- move.l a2,sc_Text(a4) ; set Ascii pointer in struct
- move.l a6,sc_Address(a4) ; set address in struct
- moveq #1,d0 ; return TRUE
- bra.s FFEnd
- FFCLoop: inc.w d5 ; increase offset counter
- inc.w a6 ; increase text pointer
- dbra d3,FFSLoop
- FFNext: cldat d5
- move.l ln_Next(a5),a5 ; next line in a5
- bra.s FFLoop
- FFDone: moveq #0,d0
- FFEnd: popem.l d2-d5/a2-a6
- rts
-
- _NextOccurrence: pushem.l d2-d6/a2-a6
-
- move.l 11*4(sp),a4 ; get Search pointer in a4
- move.l 12*4(sp),d2 ; get case flag in d2
-
- push.l sc_Address(a4)
- push.l sc_Line(a4)
- push.w sc_TextOffset(a4)
- move.l sc_String(a4),a3 ; get string in a3
- cldat d4
- move.w sc_StringSize(a4),d4 ; get string size in d4
- move.l sc_Line(a4),a5 ; get line in a5
- cldat d5
- add.l d4,sc_Address(a4) ; add stringsize to address
- add.w d4,sc_TextOffset(a4) ; add stringsize to offset
- FNLoop: tst.l ln_Next(a5)
- beq.s FNDone ; no more lines !
- move.l sc_Address(a4),a6 ; next address in a6
- cldat d3
- move.w sc_TextOffset(a4),d5 ; text offset in d5
- move.w ln_Size(a5),d3 ; line size in d3
- sub.w d4,d3 ; substract size from d3
- sub.w d5,d3 ; substract offset from d3
- dec.w d3
- tst.w d3
- blt.s FNNext ; when < 0 next line
- FNSLoop: move.l a6,a0
- move.l a3,a1
- move.l d4,d0
- tst.w d2
- beq.s FNNoCase
- bsr StrnCmp ; compare (case dependant)
- bra.s FNChecked
- FNNoCase: bsr StrniCmp ; compare (case independant)
- FNChecked: tst.l d0
- beq.s FNCLoop
- move.l a5,sc_Line(a4) ; set line in struct
- FNNotSame: move.w d5,sc_TextOffset(a4) ; set offset in struct
- move.l a6,sc_Address(a4) ; set next addres in struct
- moveq #1,d0 ; return TRUE
- add.l #10,sp
- bra.s FNEnd
- FNCLoop: inc.w d5 ; increase offset counter
- inc.w a6 ; increase text pointer
- dbra d3,FNSLoop
- FNNext: cldat d5
- move.w #0,sc_TextOffset(a4) ; clear offset
- move.l ln_Next(a5),a5 ; next line in a5
- move.l ln_Text(a5),sc_Address(a4) ; text address in struc
- bra.s FNLoop
- FNDone: pop.w sc_TextOffset(a4)
- pop.l sc_Line(a4)
- pop.l sc_Address(a4)
- moveq #0,d0
- FNEnd: popem.l d2-d6/a2-a6
- rts
-
- _PreviousOccurrence:
- pushem.l d2-d6/a2-a6
-
- move.l 11*4(sp),a4 ; get Search pointer in a4
- move.l 12*4(sp),d2 ; get case flag in d2
-
- push.l sc_Address(a4)
- push.l sc_Line(a4)
- push.w sc_TextOffset(a4)
- move.l sc_String(a4),a3 ; get string in a3
- cldat d4
- move.w sc_StringSize(a4),d4 ; get string size in d4
- move.l sc_Line(a4),a5 ; get line in a5
- cldat d5
- sub.l d4,sc_Address(a4)
- sub.w d4,sc_TextOffset(a4)
- FPLoop: cmp.l sc_Text(a4),a5
- beq FPDone ; no more lines !
- move.l sc_Address(a4),a6 ; address in a6
- cldat d3
- move.w sc_TextOffset(a4),d5 ; text offset in d5
- move.w d5,d3 ; and in d3
- tst.w d3
- blt.s FPPrev ; when < 0 previous line
- FPSLoop: move.l a6,a0
- move.l a3,a1
- move.l d4,d0
- tst.w d2
- beq.s FPNoCase
- bsr StrnCmp ; compare (case dependant)
- bra.s FPChecked
- FPNoCase: bsr StrniCmp ; compare (case independant)
- FPChecked: tst.l d0
- beq.s FPCLoop
- move.l a5,sc_Line(a4) ; set line in struct
- FPNotSame: move.w d5,sc_TextOffset(a4) ; set offset in struct
- move.l a6,sc_Address(a4) ; set prev addres in struct
- add.l #10,sp
- moveq #1,d0 ; return TRUE
- bra.s FPEnd
- FPCLoop: dec.w d5 ; decrease offset counter
- dec.w a6 ; decrease text pointer
- dbra d3,FPSLoop
- FPPrev: cldat d5
- move.l ln_Prev(a5),a5 ; previous line in a5
- move.w ln_Size(a5),d0
- sub.w d4,d0
- move.w d0,sc_TextOffset(a4)
- move.l ln_Text(a5),d0 ; text address in struc
- add.w ln_Size(a5),d0
- sub.w d4,d0
- move.l d0,sc_Address(a4)
- bra FPLoop
- FPDone: pop.w sc_TextOffset(a4)
- pop.l sc_Line(a4)
- pop.l sc_Address(a4)
- moveq #0,d0
- FPEnd: popem.l d2-d6/a2-a6
- rts
-
- ToLower: cmp.b #'A',d0
- bmi.s NotUpAlp ; smaller than 'A'.. skip
- cmp.b #'Z',d0
- bhi.s NotUpAlp ; bigger than 'Z'.. skip
- add.b #' ',d0 ; make lower case
- NotUpAlp: rts
-
- StrLen: cldat d0
- SLen: tst.b (a0)+
- beq.s SLDone
- inc.l d0
- bra.s SLen
- SLDone: rts
-
- StrnCmp: dec.w d0
- Cmp: move.b (a0)+,d1
- cmp.b (a1)+,d1 ; are they the same ?
- bne.s Diff ; no..
- dbra d0,Cmp ; loop until "x" chars done
- Same: moveq #1,d0 ; they where the same
- rts
- Diff: cldat d0 ; they were different
- rts
-
- StrniCmp: push.l d2
- move.l d0,d2
- dec.w d2
- iCmp: move.b (a0)+,d0
- bsr ToLower ; convert char to lower case
- move.b d0,d1 ; put it in d1
- move.b (a1)+,d0
- bsr ToLower ; convert char to lower case
- cmp.b d0,d1
- bne.s iDiff ; two chars are different
- dbra d2,iCmp
- iSame: pop.l d2
- moveq #1,d0 ; strings where the same
- rts
- iDiff: pop.l d2
- cldat d0 ; strings where different
- rts
-