summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FC/GETL.ASM
blob: 508eca9509035ac7d71817d82c92a2da0a07bd27 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
;
; blindingly fast assembly help for Z
;

.xlist
include	version.inc
include cmacros.inc
.list

sBegin  data
assumes ds,data

bufstart    dd     ?
staticW bufsrc,?
staticW buflen,?
staticW buflength,?
staticW buffh,?
globalB fGetlCR,?
bufpos      dd      ?

sEnd
sBegin code

assumes cs,code

;
; getlpos returns current seek position in file
;
cProc   getlpos,<PUBLIC>
cBegin
        mov     dx,word ptr bufpos+2
        mov     ax,word ptr bufpos
cEnd

;
; getlinit (buf, len, fh) initializes the getl routine for buffer buf and fh fh
;
cProc   getlinit,<PUBLIC>
parmD   buf
parmW   len
parmW   fh
cBegin
        mov     ax,off_buf
        mov     word ptr bufstart,ax
        mov     ax,seg_buf
        mov     word ptr bufstart+2,ax
        mov     ax,fh
        mov     buffh,ax
        mov     ax,len
        mov     buflength,ax
        mov     buflen,0
        mov     word ptr bufpos,0
        mov     word ptr bufpos+2,0
        mov     fGetlCR,0
cEnd

;
; getl (dst, len) returns TRUE if a line was read.
;
cProc   getl,<PUBLIC>,<DS,SI,DI>
parmW   dst
parmW   dstlen
cBegin
        assumes ss,data
        cld
        push    ds
        pop     es
        mov     ds,word ptr bufstart+2
        assumes ds,nothing
        mov     si,bufsrc
        mov     di,dst
        mov     cx,buflen
        mov     dx,dstlen
        dec     dx                  ; room for NUL at end
        jcxz    fill

movc:   lodsb                       ; get a byte
        cmp     al,13               ; is it special?
        jbe     spec                ; yes, go handle special case
stoc:   stosb                       ; put character in buffer
        dec     dx                  ; one less space in buffer
endl:   loopnz  movc                ; go back for more characters
        jnz     fill                ; no more characters => go fill buffer
                                    ; cx = 0, buflen = length moved
fin:    dec     cx
fin1:   xor     ax,ax
        stosb
        mov     bufsrc,si           ; length moved = buflen - cx
        xchg    buflen,cx
        sub     cx,buflen
        add     word ptr bufpos,cx
        adc     word ptr bufpos+2,0
        not     ax
        jmp     short getldone

fill:
        mov     cx, buflen          ; add length moved to bufpos
        add     word ptr bufpos,cx
        adc     word ptr bufpos+2,0
        push    dx
        mov     dx,word ptr bufstart
        mov     cx,buflength
        mov     bx,buffh
        mov     ah,3Fh
        int     21h
        mov     cx,ax
        mov     buflen,ax
        mov     si,dx
        pop     dx
        or      ax,ax
        jnz     movc
; if we've stored chars then terminate line else return with 0
        cmp     di,dst
        jnz     fin1
        jmp     short getldone

setnz:  or      al,1
        mov     fGetlCR,-1              ; indicate we've seen a CR
        jmp     endl

spec:   jz      setnz
        cmp     al,10
        jz      fin
        cmp     al,9
        jnz     stoc
        push    cx
        mov     ax,di
        sub     ax,dst
        and     ax,7
        mov     cx,8
        sub     cx,ax
        cmp     cx,dx
        jbe     ok
        mov     cx,dx
ok:     sub     dx,cx
        mov     al," "
        rep     stosb
        pop     cx
        jmp     endl

getldone:
cEnd

sEnd

end