7cf148dfca09e287db5bd7675efa64cd66524041
[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 ;;; ========================================
74 ;;; Stream reading
75 ;;; READ-STREAM-CHAR ( stream -- ch )
76         
77         WORD p_read_stream_char,'READ-STREAM-CHAR',fasm
78         ;; ( stream -- ch )
79         pushr rsi
80         mov rax,qword [rsp]
81         mov rbx,[rax+16]        ; fill
82
83 p_read_stream_char.READ:
84         mov rcx,[rax+24]        ; current
85         cmp rbx,rcx
86         jg p_read_stream_char.CHAR
87
88         ;; pull in more from the source, if any
89         cmp qword [rax+8],-1    ; fd == -1 for "no source"
90         je p_read_stream_char.EOF
91         
92         push qword [rax+8]      ; fd
93         lea rbx,[rax+32]
94         push rbx                ; buffer
95         push qword [rax]        ; size
96         mov qword[rax+16],0
97         mov qword[rax+24],0
98         DOFORTH sys_read
99         pop rbx
100         mov rax,qword [rsp]
101         cmp rbx,0
102         jle p_read_stream_char.EOF
103         mov qword[rax+16],rbx
104         jmp p_read_stream_char.READ
105
106 p_read_stream_char.EOF:
107         mov qword [rsp],-1
108         popr rsi
109         next
110
111 p_read_stream_char.CHAR:
112         inc qword [rax+24]
113         add rcx,32
114         mov qword [rsp],0
115         mov bl,[rax+rcx]
116         mov byte [rsp],bl
117         popr rsi
118         next
119
120 ;;; ========================================
121 ;;; Input handling
122
123         WORD p_pad,'PAD',dovariable
124         ;; A buffer for holding a word
125         rb 1024
126
127         WORD p_read_word,'READ-WORD',fasm
128         ;; ( stream -- char* length )
129         ;; Read next word from the given stream into the PAD
130         pushr rsi
131         pop rax
132         push qword p_pad_DFA
133         push qword 0
134         push rax
135
136 p_read_word_skipblanks: 
137         FORTH
138         dq p_dup
139         dq p_read_stream_char
140         ENDFORTH
141         pop rbx
142         cmp bl,0
143         jl p_read_word_nomore
144         cmp bl,' '
145         jle p_read_word_skipblanks
146
147 p_read_word_readword:
148         ;; ( buffer length stream )
149         mov rax,qword [rsp+16]
150         mov rcx,qword [rsp+8]
151         mov [rax+rcx],bl
152         inc qword [rsp+8]
153         FORTH
154         dq p_dup
155         dq p_read_stream_char
156         ENDFORTH
157         pop rbx
158         cmp bl,0
159         jl p_read_word_nomore
160         cmp bl,' '
161         jg p_read_word_readword
162
163 p_read_word_nomore:
164         pop rax
165         popr rsi
166         next
167
168         WORD p_tell,'TELL',fasm
169         ;; ( chars* n -- )
170         ;; Write n bytes from chars* to stdout
171         pushr rsi
172         pop rbx
173         pop rax
174         push 1
175         push rax
176         push rbx
177         DOFORTH sys_write
178         pop rax
179         popr rsi
180         next
181
182 p_emit_buffer:  dq 0
183         
184         WORD p_emit,'EMIT',fasm
185         ;; ( c -- )
186         ;; Write byte to stdout
187         pushr rsi
188         pop rax
189         mov [p_emit_buffer],al
190         push 1
191         push p_emit_buffer
192         push 1
193         DOFORTH sys_write
194         pop rax
195         popr rsi
196         next
197