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
|