home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d6xx
/
d658
/
view.lha
/
View
/
Source
/
ascii.s
< prev
next >
Wrap
Text File
|
1992-05-15
|
29KB
|
654 lines
opt l+,o+,ow-,inconce
*-- 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.1c
* Translator : Devpac 3 version 3.01
*
* REVISION HISTORY
*
* Date Version Comment
* --------- ------- ------------------------------------------
* 16-Apr-92 1.1c Output code size = 1672 bytes
* 16-Apr-92 1.1c Fixed a few screw-ups.
* 27-Mar-92 1.1b Output code size = 1660 bytes.
* 27-Mar-92 1.1b Now assebles under Devpac 3
* 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! (Kickstart 1.2, 1.3 & 2.0 compatible!)
*
*-- REV_END --*
incdir 'sys:asm20/'
include 'mymacros.i'
include 'exec/types.i'
include 'libraries/dos.i'
include 'libraries/nofrag.i'
include 'exec/exec_lib.i'
include 'dos/dos_lib.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
_SysBase equ $0004
_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
tst.l d0
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
tst.l d0
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
tst.l d0
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
tst.l d0
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
tst.l d0
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)
tst.l d0
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: or.w #LNF_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