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
                                tax
                                
								lda hFDs-1,x
                                >SYSCALL GetMemPtr
                                >STYA ZPPtr1
                                lda (ZPPtr1)
                                cmp #S.FD.T.PIPE
                                bne .97
                                
                                ldy #S.PS.hStdIn
                                lda (pPS),y
                                sta 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
*--------------------------------------
CS.RUN.SEDParser
* 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, 
*          replaceidx contains the offset to the start of replacement str

                                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           .AS "Usage : SED [-I] s/pattern/replacement/ <File>\r\n"
                    .AS "   or : CMD|SED [-I] s/pattern/replacement/\r\n"
                    .AS "   -I : Ignore Case"
MSG.CRLF            .AZ "\r\n"
*--------------------------------------
                                .DUMMY
                                .OR 0
DS.START
DS.END                  .ED
*--------------------------------------
MAN
SAVE usr/src/bin/od.s
ASM
