X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=stdio.asm;h=1773da2d3b76c9e98cdf5d3aa74872fd2f90fc19;hb=bf8a7c713298730826f02c4ece9f4735fcee2e4b;hp=fed8eda38df2fffa598e11bb4f8d7c8d4a26b19e;hpb=135bac77e9403714670d582b59255f2588ec83fb;p=rrq%2Frrqforth.git diff --git a/stdio.asm b/stdio.asm index fed8eda..1773da2 100644 --- a/stdio.asm +++ b/stdio.asm @@ -17,59 +17,78 @@ jmp sys_mmap_asm ; exit via sys_mmap ;;; ======================================== -;;; Mapping files - - ;; ( fd -- address ) - ;; Request memory mapping of a file - WORD p_mmap,'MMAP',fasm - pushr rsi ; pretend it's a FORTH word since it - ; ends via sys_mmap_asm - pop rax - push qword 0 ; address of mapping (suggestion) - push qword 10240 ; length of mapping - push qword 1 ; protection mode PROT_READ - push qword 2 ; flags MAP_PRIVATE - push rax ; fd - push qword 0 ; offset - jmp sys_mmap_asm ; exit via sys_mmap - -;;; ======================================== -;;; Input stream handling. An input stream has a stream buffer that is +;;; Input stream handling. +;;; +;;; An input stream for a file descriptor has a stream buffer that is ;;; gradually filled on needs basis. The stream buffer includes a ;;; header portion with: ;;; * size of buffer (excluding the 32 byte head) -;;; * source file descriptor +;;; * source file descriptor (or -1 for pure in-core data) ;;; * current fill ;;; * current read position +;;; +;;; An input stream for a memory block as a "detached" stream head +;;; with: +;;; * block address +;;; * -1 +;;; * size of block +;;; * current read position (starts at 8 = after block size) - WORD p_stream,'STREAM', - ;; ( fd size -- addr ) + WORD p_stream,'STREAM',fasm + ;; ( fd size -- addr ) or ( block -1 -- addr ) ;; Allocates a stream buffer of the given size and initializes ;; it to be filled from the given input file descriptor. - dq p_dup ; ( fd size size ) - dq p_malloc ; ( fd size addr ) - dq p_2dup ; ( fd size addr size addr ) - dq p_swap ; ( fd size addr addr size ) - dq p_erase ; ( fd size addr ) - ENDFORTH - pop rax ; ( fd size ) - pop rbx ; ( fd ) - sub rbx,32 + pushr rsi + mov rax,[rsp] + cmp rax,-1 + je p_stream_MEM + push rax + DOFORTH p_malloc ; ( fd size addr ) + push qword [rsp] + push qword [rsp+16] ; ( fd size addr addr size ) + DOFORTH p_erase ; ( fd size addr ) + pop rax ; addr ( fd size ) + pop rbx ; size ( fd ) + sub rbx,32 ; reduce by header size mov [rax],rbx pop rbx mov [rax+8],rbx push rax jmp exit +p_stream_MEM: + push 32 ; size of detached header (wastefull?) + DOFORTH p_malloc ; ( block addr ) + pop rax ; header address + pop rbx ; block address + mov rcx,[rbx] ; block content size (excludes size field) + add rbx,8 ; block content address + mov qword [rax],rbx ; save block content address + mov qword [rax+8],-1 ; -1 = memblock flag + mov qword [rax+16],rcx ; save block content size + mov qword [rax+24],0 ; current position + push rax + jmp exit + +;;; ======================================== +;;; Stream reading +;;; READ-STREAM-CHAR ( stream -- ch ) + WORD p_read_stream_char,'READ-STREAM-CHAR',fasm ;; ( stream -- ch ) pushr rsi mov rax,qword [rsp] mov rbx,[rax+16] ; fill + p_read_stream_char.READ: mov rcx,[rax+24] ; current cmp rbx,rcx jg p_read_stream_char.CHAR + + ;; pull in more from the source, if any + cmp qword [rax+8],-1 ; fd == -1 for "no source" + je p_read_stream_char.EOF + push qword [rax+8] ; fd lea rbx,[rax+32] push rbx ; buffer @@ -83,10 +102,12 @@ p_read_stream_char.READ: jle p_read_stream_char.EOF mov qword[rax+16],rbx jmp p_read_stream_char.READ + p_read_stream_char.EOF: mov qword [rsp],-1 popr rsi next + p_read_stream_char.CHAR: inc qword [rax+24] add rcx,32 @@ -96,16 +117,19 @@ p_read_stream_char.CHAR: popr rsi next - WORD p_line_buffer,'LINE-BUFFER',dovariable - ;; A buffer for holding a text line +;;; ======================================== +;;; Input handling + + WORD p_pad,'PAD',dovariable + ;; A buffer for holding a word rb 1024 WORD p_read_word,'READ-WORD',fasm - ;; ( stream -- addr length ) - ;; Read a text line from the stream into the line buffer + ;; ( stream -- char* length ) + ;; Read next word from the given stream into the PAD pushr rsi pop rax - push qword p_line_buffer_DFA + push qword p_pad_DFA push qword 0 push rax @@ -140,3 +164,44 @@ p_read_word_nomore: pop rax popr rsi next + + WORD p_tell,'TELL',fasm + ;; ( chars* n -- ) + ;; Write n bytes from chars* to stdout + pushr rsi + pop rbx + pop rax + push 1 + push rax + push rbx + DOFORTH sys_write + pop rax + popr rsi + next + +p_emit_buffer: dq 0 + + WORD p_emit,'EMIT',fasm + ;; ( c -- ) + ;; Write byte to stdout + pushr rsi + pop rax + mov [p_emit_buffer],al + push 1 + push p_emit_buffer + push 1 + DOFORTH sys_write + pop rax + popr rsi + next + + WORD p_nl,'NL',dovalue + ;; ( -- c ) + ;; Pushes a newline character on the stack + dq 10 + + WORD p_sp,'SP',dovalue + ;; ( -- c ) + ;; Pushes a space character on the stack + dq 10 +