NEW
  AUTO 3,1
				.LIST OFF
				.OP 65C02
				.OR $2000
				.TF bin/sed
*--------------------------------------
				.INB inc/macros.i
				.INB inc/a2osx.i
				.INB inc/kernel.i
				.INB inc/mli.i
				.INB inc/mli.e.i
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ArgIndex        .BS 1
ArgPattern      .BS 1
ZPPtr1          .BS 2
ZPPatternPtr    .BS 2
ZPBufPtr        .BS 2
hFile           .BS 1
hBuf            .BS 1
LineNum         .BS 2
char            .BS 1
delimiter       .BS 1
replaceidx      .BS 1

bIgnoreCase     .BS 1

ZS.END          .ED
*--------------------------------------
*  File Header (16 Bytes)
*--------------------------------------
CS.START    	cld
				jmp (.1,x)
				.DA #$61                 6502,Level 1 (65c02)
				.DA #1                   BIN Layout Version 1
				.DA #0                   S.PS.F.EVENT
				.DA #0
				.DA CS.END-CS.START      Code Size (without Constants)
				.DA DS.END-DS.START      Data Segment Size
				.DA #16                  Stack Size
				.DA #ZS.END-ZS.START     Zero Page Size
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1              .DA CS.INIT
                .DA CS.RUN
                .DA CS.DOEVENT          
                .DA CS.QUIT
L.MSG.USAGE     .DA MSG.USAGE
L.MSG.CRLF      .DA MSG.CRLF
                .DA 0
*--------------------------------------
CS.INIT         clc
                rts
*--------------------------------------
CS.RUN          jsr CS.RUN.CheckArgs
                bcs CS.RUN.LOOP.RTS

                stz LineNum
                stz LineNum+1

CS.RUN.LOOP     >SLEEP

                >PUSHB hFile
                >PUSHW ZPBufPtr
                >PUSHWI 256
                >SYSCALL FGetS
                bcs .9

                inc LineNum
                bne .2

                inc LineNum+1

.2              jsr CS.RUN.PRINT

                bcc CS.RUN.LOOP
                rts

.9              cmp #MLI.E.EOF
                bne .99

                lda #0                    Exit with no Error

.99             sec
CS.RUN.LOOP.RTS rts
*--------------------------------------
CS.RUN.CheckArgs
                jsr CS.RUN.NextArg
                bcs .4

                lda (ZPPtr1)
                cmp #'-'
                beq .1

                lda ArgPattern
                bne .11

                lda ArgIndex
                sta ArgPattern
                >LDYA ZPPtr1
                >STYA ZPPatternPtr
                jsr CS.RUN.SEDParser
                bcs .97
                bra CS.RUN.CheckArgs

.11             lda hFile
                bne .97

                >LDYA ZPPtr1
                jsr CS.RUN.OPEN
                bcs .9

                sta hFile
                bra CS.RUN.CheckArgs

.1              ldy #1 
                lda (ZPPtr1),y

                ldx #OptionList.Cnt-1

.2              cmp OptionList,x
                beq .3

                dex
                bpl .2

                bra .97

.3              txa
                lsr
                beq .98

                tax
                lda #$80
                sta bIgnoreCase-1,x 
                bra CS.RUN.CheckArgs
                
.4              lda hFile
                bne .80

                ldy #S.PS.hStdIn
                lda (pPS),y
                tay
				ldx FILEs.hFD-1,y
				lda FDs.pLO-1,x
				sta ZPPtr1
				lda FDs.pHI-1,x
                sta ZPPtr1+1
                
				lda (ZPPtr1)
                cmp #S.FD.T.PIPE
                bne .97
                
                sty hFile
        
.80             >LDYAI 256
                >SYSCALL GetMem
                bcs .9

                >STYA ZPBufPtr
                stx hBuf

*               clc

.9              rts

.97             lda #E.SYN

.98             pha
                >PUSHW L.MSG.USAGE
                >PUSHBI 0
                >SYSCALL PrintF
                pla
                sec
                rts
*--------------------------------------
CS.RUN.NextArg  inc ArgIndex
                lda ArgIndex
                >SYSCALL ArgV
                bcs .9

                >STYA ZPPtr1

.9              rts
*--------------------------------------
* On entry, the expression is in ZPPatternPtr
* We are looking for "s/search string/replace string/"
* The '/' delimiter can be any char
* On exit. ZPPatternPtr points to delimiter-terminated search string, 
*  replace idx contains the offset to the start of replacement str

CS.RUN.SEDParser
                stz LineNum               Reusing this as cntr

                lda (ZPPatternPtr)
                cmp #'s'                  Substitute cmd
                bne .8                    If not, error

                ldy #$01                  Delimiter char
                lda (ZPPatternPtr),y
                sta delimiter             Stash for later

.2              iny
                lda (ZPPatternPtr),y
                beq .4                    End of string
                cmp delimiter             Is it delimiter?
                bne .2

                inc LineNum               Keep count
                lda LineNum
                cmp #$01                  Second delim
                bne .2

                sty replaceidx
                bra .2

.4              lda LineNum               Check # of delims
                cmp #$02
                bne .8

                inc ZPPatternPtr          Eat 's/'
                bne .5
                inc ZPPatternPtr+1
.5              inc ZPPatternPtr
                bne .7
                inc ZPPatternPtr+1

.7              clc
                rts                       No error return

.8              sec
                rts
*--------------------------------------
CS.RUN.OPEN     >PUSHYA
                >PUSHBI O.RDONLY+O.TEXT
                >PUSHBI S.FI.T.TXT
                >PUSHWZ                         Aux type
                >SYSCALL FOpen
                bcs .9

                sta hFile

.9              rts
*--------------------------------------
CS.RUN.PRINT    >LDYA ZPBufPtr
                >STYA ZPPtr1

                lda (ZPPtr1)            If null first time
                beq .8

.1              lda (ZPPtr1)
                beq .7                  EOL. No match.

                ldy #$ff

.2              iny
                lda (ZPPtr1),y
                bne .3

                lda (ZPPatternPtr),y    EOL
                cmp delimiter
                bne .7                  Not end of pattern
*                                       No match.

.3              lda (ZPPatternPtr),y
                cmp delimiter
                beq .5                  Match

                jsr CS.RUN.toUpper
                sta char
                lda (ZPPtr1),y
                jsr CS.RUN.toUpper
                cmp char
                beq .2

                bra .6                  No match
 
* Found a match               
.5              jsr CS.RUN.GotMatch
                bra .1
 
* Mismatch with pattern, keep going
.6              jsr CS.RUN.NoMatch
                bra .1

* Hit EOL but not end of pattern, return
.7              jsr CS.RUN.NoMatch
.8              lda #C.CR
                >SYSCALL PutChar
                lda #C.LF
                >SYSCALL PutChar

.9              clc
                rts
*--------------------------------------
CS.RUN.GotMatch phy
                ldy replaceidx
                dey
.1              lda (ZPPatternPtr),y
                cmp delimiter
                beq .5
                phy
                >SYSCALL PutChar
                ply
                iny
                bra .1

.5              ply
                tya                  Advance ZPPtr1 by Y
                clc
                adc ZPPtr1
                sta ZPPtr1
                lda #$00
                adc ZPPtr1+1
                sta ZPPtr1+1
                ldy #$00
                rts
*--------------------------------------
CS.RUN.NoMatch  lda (ZPPtr1)         Print ZPPtr1->ZPPtr1+Y
                phy
                >SYSCALL PutChar
                ply
                inc ZPPtr1
                bne .2
                inc ZPPtr1+1
.2              dey
                cpy #$ff
                bne CS.RUN.NoMatch
                ldy #$00
                rts
*--------------------------------------
CS.RUN.toUpper  bit bIgnoreCase
                bpl .9

                cmp #'a'
                bcc .9

                cmp #'z'+1
                bcs .9

                eor #$20

.9              rts     
*--------------------------------------
CS.QUIT         lda hFile
                beq .1

                >SYSCALL FClose

.1              lda hBuf
                beq .8

                >SYSCALL FreeMem

.8              clc
                rts
*--------------------------------------
CS.DOEVENT      sec
                rts
*--------------------------------------
CS.END
*--------------------------------------
OptionList      .AS "HhIi"
OptionList.Cnt  .EQ *-OptionList
*--------------------------------------
MSG.USAGE       .CS "Usage : SED [-I] s/pattern/replacement/ <File>\r\n"
                .CS "   or : CMD|SED [-I] s/pattern/replacement/\r\n"
                .CS "   -I : Ignore Case"
MSG.CRLF        .CZ "\r\n"
*--------------------------------------
                .DUMMY
                .OR 0
DS.START
DS.END          .ED
*--------------------------------------
MAN
SAVE usr/src/bin/sed.s
ASM
