commen editing
[rrq/rrqforth.git] / stdio.asm
1 ;;; ========================================
2 ;;; Dynamic memory management. Allocated with MALLOC and released with
3 ;;; MUNMAP (see below)
4
5         ;; ( size -- addr )
6         ;; Allocates memory (using brk)
7         WORD p_malloc,'MALLOC',fasm
8         pushr rsi               ; pretend it's a FORTH word since it
9                                 ; ends via sys_mmap_asm
10         pop rax
11         push qword 0            ; address of mapping (suggestion)
12         push rax                ; length of mapping
13         push qword 3            ; protection mode PROT_READ | PROT_WRITE
14         push qword 8226         ; flags PRIVATE | ANONYMOUS | LOCKED
15         push qword -1           ; fd -1
16         push qword 0            ; offset
17         jmp sys_mmap_asm        ; exit via sys_mmap
18
19 ;;; ========================================
20 ;;; Input stream handling.
21 ;;;
22 ;;; An input stream for a file descriptor has a stream buffer that is
23 ;;; gradually filled on needs basis. The stream buffer includes a
24 ;;; header portion with:
25 ;;; * size of buffer (excluding the 32 byte head)
26 ;;; * source file descriptor (or -1 for pure in-core data)
27 ;;; * current fill
28 ;;; * current read position
29 ;;;
30 ;;; An input stream for a memory block as a "detached" stream head
31 ;;; with:
32 ;;; * block address
33 ;;; * -1
34 ;;; * size of block
35 ;;; * current read position (starts at 8 = after block size)
36
37         WORD p_stream,'STREAM',fasm
38         ;; ( fd size -- addr ) or ( block -1 -- addr )
39         ;; Allocates a stream buffer of the given size and initializes
40         ;; it to be filled from the given input file descriptor.
41         pushr rsi
42         mov rax,[rsp]
43         cmp rax,-1
44         je p_stream_MEM
45         push rax
46         DOFORTH p_malloc        ; ( fd size addr )
47         push qword [rsp]
48         push qword [rsp+16]     ; ( fd size addr addr size )
49         DOFORTH p_erase         ; ( fd size addr )
50         pop rax                 ; addr ( fd size )
51         pop rbx                 ; size ( fd )
52         sub rbx,32              ; reduce by header size
53         mov [rax],rbx
54         pop rbx
55         mov [rax+8],rbx
56         push rax
57         jmp exit
58
59 p_stream_MEM:
60         push 32                 ; size of detached header (wastefull?)
61         DOFORTH p_malloc        ; ( block addr )
62         pop rax                 ; header address
63         pop rbx                 ; block address
64         mov rcx,[rbx]           ; block content size (excludes size field)
65         add rbx,8               ; block content address
66         mov qword [rax],rbx     ; save block content address
67         mov qword [rax+8],-1    ; -1 = memblock flag
68         mov qword [rax+16],rcx  ; save block content size
69         mov qword [rax+24],0    ; current position
70         push rax
71         jmp exit
72
73         WORD p_clear_stream,'CLEAR-STREAM',fasm
74         ;; ( stream -- )
75         ;; Clear buffer of input stream
76         pop rax
77         mov rbx,qword [rax+16]  ; copy fill
78         mov qword [rax+24],rbx  ; into current
79         next
80         
81 ;;; ========================================
82 ;;; Stream reading
83 ;;; READ-STREAM-CHAR ( stream -- ch )
84         
85         WORD p_read_stream_char,'READ-STREAM-CHAR',fasm
86         ;; ( stream -- ch )
87         pushr rsi
88         mov rax,qword [rsp]
89         mov rbx,[rax+16]        ; fill
90
91 p_read_stream_char.READ:
92         mov rcx,[rax+24]        ; current
93         cmp rbx,rcx
94         jg p_read_stream_char.CHAR
95
96         ;; pull in more from the source, if any
97         cmp qword [rax+8],-1    ; fd == -1 for "no source"
98         je p_read_stream_char.EOF
99         
100         push qword [rax+8]      ; fd
101         lea rbx,[rax+32]
102         push rbx                ; buffer
103         push qword [rax]        ; size
104         mov qword[rax+16],0
105         mov qword[rax+24],0
106         DOFORTH sys_read
107         pop rbx
108         mov rax,qword [rsp]
109         cmp rbx,0
110         jle p_read_stream_char.EOF
111         mov qword[rax+16],rbx
112         jmp p_read_stream_char.READ
113
114 p_read_stream_char.EOF:
115         mov qword [rsp],-1
116         popr rsi
117         next
118
119 p_read_stream_char.CHAR:
120         inc qword [rax+24]
121         add rcx,32
122         mov qword [rsp],0
123         mov bl,[rax+rcx]
124         mov byte [rsp],bl
125         popr rsi
126         next
127
128 ;;; ========================================
129 ;;; Input handling
130
131         WORD p_pad,'PAD',dovariable
132         ;; A buffer for holding a word
133         rb 1024
134
135         WORD p_read_word,'READ-WORD',fasm
136         ;; ( stream -- char* length )
137         ;; Read next word from the given stream into the PAD
138         pushr rsi
139         pop rax
140         push qword p_pad_DFA
141         push qword 0
142         push rax
143
144 p_read_word_skipblanks: 
145         FORTH
146         dq p_dup
147         dq p_read_stream_char
148         ENDFORTH
149         pop rbx
150         cmp bl,0
151         jl p_read_word_nomore
152         cmp bl,' '
153         jle p_read_word_skipblanks
154
155 p_read_word_readword:
156         ;; ( buffer length stream )
157         mov rax,qword [rsp+16]
158         mov rcx,qword [rsp+8]
159         mov [rax+rcx],bl
160         inc qword [rsp+8]
161         FORTH
162         dq p_dup
163         dq p_read_stream_char
164         ENDFORTH
165         pop rbx
166         cmp bl,0
167         jl p_read_word_nomore
168         cmp bl,' '
169         jg p_read_word_readword
170
171 p_read_word_nomore:
172         pop rax
173         popr rsi
174         next
175
176         WORD p_tell,'TELL',fasm
177         ;; ( chars* n -- )
178         ;; Write n bytes from chars* to stdout
179         pushr rsi
180         pop rbx
181         pop rax
182         push 1
183         push rax
184         push rbx
185         DOFORTH sys_write
186         pop rax
187         popr rsi
188         next
189
190 p_emit_buffer:  dq 0
191         
192         WORD p_emit,'EMIT',fasm
193         ;; ( c -- )
194         ;; Write byte to stdout
195         pushr rsi
196         pop rax
197         mov [p_emit_buffer],al
198         push 1
199         push p_emit_buffer
200         push 1
201         DOFORTH sys_write
202         pop rax
203         popr rsi
204         next
205
206         WORD p_nl,'NL',dovalue
207         ;; ( -- c )
208         ;; Pushes a newline character on the stack
209         dq 10
210
211         WORD p_sp,'SP',dovalue
212         ;; ( -- c )
213         ;; Pushes a space character on the stack
214         dq 10
215