Subversion Repositories Spectranet

[/] [branches/] [gnubinutils/] [modules/] [streams/] [io.asm] - Diff between revs 371 and 380

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 371 Rev 380
Line 18... Line 18...
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
;THE SOFTWARE.
;THE SOFTWARE.
; IO routines for streams
; IO routines for streams
J_modcall
.include        "spectranet.inc"
 
.include        "streamvars.inc"
 
.include        "zxsysvars.inc"
 
.include        "sysvars.inc"
 
.include        "zxrom.inc"
 
.include        "defs.inc"
 
.text
 
.globl J_modcall
 
J_modcall:
        call F_fetchpage        ; get our memory page
        call F_fetchpage        ; get our memory page
        bit 5, l                ; Control stream?
        bit 5, l                ; Control stream?
        jp nz, F_control
        jp nz, F_control
        bit 6, l                ; Listen stream?
        bit 6, l                ; Listen stream?
        jp nz, F_ctrlstream
        jp nz, F_ctrlstream
Line 32... Line 40...
        jp F_leave
        jp F_leave
 
 
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; F_input
; F_input
; Process input to a stream.
; Process input to a stream.
F_input
.globl F_input
 
F_input:
        push hl
        push hl
        ld hl, ZX_TV_FLAG       ; the mode is considered unchanged
        ld hl, ZX_TV_FLAG       ; the mode is considered unchanged
        res 3, (hl)
        res 3, (hl)
        pop hl
        pop hl
 
 
        call F_findmetadata     ; get a pointer to metadata in IX
        call F_findmetadata     ; get a pointer to metadata in IX
        ld d, (ix+STRM_WRITEBUF); get tx buffer number
        ld d, (ix+STRM_WRITEBUF); get tx buffer number
        ld a, (ix+STRM_WRITEPTR); get tx buffer pointer
        ld a, (ix+STRM_WRITEPTR); get tx buffer pointer
        and a                   ; if nonzero, flush the buffer
        and a                   ; if nonzero, flush the buffer
        call nz, .flush
        call nz, .flush1
 
 
.isinkey
.isinkey1:
        push hl
        push hl
        ld hl, (ZX_ERR_SP)      ; fetch the current ERR_SP
        ld hl, (ZX_ERR_SP)      ; fetch the current ERR_SP
        ld e, (hl)
        ld e, (hl)
        inc hl
        inc hl
        ld d, (hl)
        ld d, (hl)
        and a
        and a
        ld hl, 0x107F           ; Compare with ED_ERROR
        ld hl, 0x107F           ; Compare with ED_ERROR
        sbc hl, de
        sbc hl, de
        pop hl
        pop hl
        jp nz, .doinkey
        jp nz, .doinkey1
 
 
.input
.input1:
        ld d, (ix+STRM_READBUF) ; get the read buffer number
        ld d, (ix+STRM_READBUF) ; get the read buffer number
        ld e, (ix+STRM_READPTR) ; and the pointer
        ld e, (ix+STRM_READPTR) ; and the pointer
        ld a, (ix+STRM_FD)      ; get the fd
        ld a, (ix+STRM_FD)      ; get the fd
        ld (v_asave), a         ; save it for the loop operation
        ld (v_asave), a         ; save it for the loop operation
        xor a                   ; Is the buffer pointer at
        xor a                   ; Is the buffer pointer at
        cp e                    ; the start of the buffer?
        cp e                    ; the start of the buffer?
        jr z, .getdata          ; Yes - so read more data from the network
        jr z, .getdata1         ; Yes - so read more data from the network
 
 
        ld b, (ix+STRM_REMAINING) ; remaining bytes in buffer
        ld b, (ix+STRM_REMAINING) ; remaining bytes in buffer
        ex de, hl               ; and put the buffer pointer in HL
        ex de, hl               ; and put the buffer pointer in HL
        jr .unloadloop
        jr .unloadloop1
 
 
.getdata
.getdata1:
        ld a, (v_asave)         ; Get the descriptor
        ld a, (v_asave)         ; Get the descriptor
        ld bc, 255              ; read up to 255 chars
        ld bc, 255              ; read up to 255 chars
        ld l, (ix+STRM_FLAGS)   ; check flags bit
        ld l, (ix+STRM_FLAGS)   ; check flags bit
        bit BIT_ISFILE, l       ; is a file?
        bit BIT_ISFILE, l       ; is a file?
        jr nz, .readfromfile
        jr nz, .readfromfile1
        bit BIT_ISDIR, l        ; is a directory?
        bit BIT_ISDIR, l        ; is a directory?
        jr nz, .readdir
        jr nz, .readdir1
        push de                 ; save bufptr
        push de                 ; save bufptr
        call RECV
        call RECV
        pop hl                  ; retrieve bufptr into hl
        pop hl                  ; retrieve bufptr into hl
.readdone
.readdone1:
        jp c, .readerr
        jp c, .readerr1
.readdirdone
.readdirdone1:
        ld b, c                 ; get the length returned into B for djnz
        ld b, c                 ; get the length returned into B for djnz
 
 
.unloadloop
.unloadloop1:
        ld a, (hl)
        ld a, (hl)
        cp 0x0d                 ; This is how the Interface 1 does it...
        cp 0x0d                 ; This is how the Interface 1 does it...
        jr z, .checkformore     ; Either a CR
        jr z, .checkformore1    ; Either a CR
        cp 0x0a
        cp 0x0a
        jr z, .checkformore     ; or a linefeed
        jr z, .checkformore1    ; or a linefeed
        cp '"'
        cp '"'
        call z, .addquote       ; Escape the " character to prevent error C
        call z, .addquote1      ; Escape the " character to prevent error C
        push hl
        push hl
        push bc
        push bc
        rst CALLBAS
        rst CALLBAS
        defw 0x0F85             ; ROM ADD-CHAR subroutine
        defw 0x0F85             ; ROM ADD-CHAR subroutine
        pop bc
        pop bc
        pop hl
        pop hl
        inc l
        inc l
        djnz .unloadloop
        djnz .unloadloop1
        ld d, (ix+STRM_READBUF) ; reset everything to get the next set
        ld d, (ix+STRM_READBUF) ; reset everything to get the next set
        ld e, 0                 ; of bytes
        ld e, 0                 ; of bytes
        ld (ix+STRM_READPTR), e
        ld (ix+STRM_READPTR), e
        ld (ix+STRM_REMAINING), e
        ld (ix+STRM_REMAINING), e
        jr .getdata             ; go get it
        jr .getdata1            ; go get it
 
 
.addquote                       ; small routine to add an extra "
.addquote1:                     ; small routine to add an extra "
        push hl                 ; character to the input stream to
        push hl                 ; character to the input stream to
        push bc                 ; prevent C Nonsense in BASIC
        push bc                 ; prevent C Nonsense in BASIC
        rst CALLBAS
        rst CALLBAS
        defw 0x0F85
        defw 0x0F85
        pop bc
        pop bc
        pop hl
        pop hl
        ld a, '"'
        ld a, '"'
        ret
        ret
 
 
.readfromfile
.readfromfile1:
        push de
        push de
        push ix
        push ix
        call READ
        call READ
        pop ix
        pop ix
        pop hl                  ; unloadloop uses hl as pointer
        pop hl                  ; unloadloop uses hl as pointer
        jr .readdone
        jr .readdone1
.readdir
.readdir1:
        ld de, INTERPWKSPC      ; %opendir does not allocate a buffer
        ld de, INTERPWKSPC      ; %opendir does not allocate a buffer
        call READDIR            ; so use temporary workspace.
        call READDIR            ; so use temporary workspace.
        jp c, .readerr          ;
        jp c, .readerr1         ;
        ld hl, INTERPWKSPC
        ld hl, INTERPWKSPC
.readdirloop
.readdirloop1:
        ld a, (hl)              ; never have a partial read doing READDIR.
        ld a, (hl)              ; never have a partial read doing READDIR.
        and a                   ; End of string?
        and a                   ; End of string?
        jr z, .exitnopop        ; Return to BASIC
        jr z, .exitnopop1       ; Return to BASIC
        push hl
        push hl
        rst CALLBAS             ; Feed INPUT
        rst CALLBAS             ; Feed INPUT
        defw 0x0F85
        defw 0x0F85
        pop hl
        pop hl
        inc hl
        inc hl
        jr .readdirloop
        jr .readdirloop1
 
 
.exitnopop
.exitnopop1:
        ld a, 0x0d              ; BASIC expects this to end INPUT
        ld a, 0x0d              ; BASIC expects this to end INPUT
        ld l, 0                 ; signal "munge the stack"
        ld l, 0                 ; signal "munge the stack"
        scf
        scf
        jp F_leave
        jp F_leave
 
 
.checkformore
.checkformore1:
        dec b                   ; do what djnz would have done if it
        dec b                   ; do what djnz would have done if it
        xor a                   ; had got to the end...
        xor a                   ; had got to the end...
        cp b                    ; no more chars left?
        cp b                    ; no more chars left?
        jr z, .cleardown
        jr z, .cleardown1
        inc l                   ; next byte in the buffer
        inc l                   ; next byte in the buffer
        ld a, (hl)              ; see what it is
        ld a, (hl)              ; see what it is
        cp 0x0d
        cp 0x0d
        jr z, .checklastcr
        jr z, .checklastcr1
        cp 0x0a
        cp 0x0a
        jr z, .checklastcr
        jr z, .checklastcr1
.saveposition
.saveposition1:
        ld (ix+STRM_READPTR), l ; save the current position
        ld (ix+STRM_READPTR), l ; save the current position
        ld (ix+STRM_REMAINING), b       ; save bytes remaining
        ld (ix+STRM_REMAINING), b       ; save bytes remaining
        jr .exitnopop
        jr .exitnopop1
.cleardown
.cleardown1:
        ld (ix+STRM_READPTR), 0 ; clear bufpos
        ld (ix+STRM_READPTR), 0 ; clear bufpos
        ld (ix+STRM_REMAINING), 0       ; clear bufsz
        ld (ix+STRM_REMAINING), 0       ; clear bufsz
        jr .exitnopop
        jr .exitnopop1
 
 
.checklastcr
.checklastcr1:
        dec b                   ; have we finally finished?
        dec b                   ; have we finally finished?
        xor a
        xor a
        cp b
        cp b
        jr z, .cleardown        ; yes, just leave now.
        jr z, .cleardown1       ; yes, just leave now.
        inc l                   ; otherwise advance the buffer
        inc l                   ; otherwise advance the buffer
        jr .saveposition        ; and save where we got to
        jr .saveposition1       ; and save where we got to
 
 
.flush
.flush1:
        dec a                   ; make actual end position, not new char pos
        dec a                   ; make actual end position, not new char pos
        ld e, a                 ; make buffer LSB
        ld e, a                 ; make buffer LSB
        call F_flushbuffer
        call F_flushbuffer
        ret
        ret
 
 
.doinkey
.doinkey1:
        ld a, (ix+STRM_FD)      ; get the socket
        ld a, (ix+STRM_FD)      ; get the socket
        ld (v_asave), a         ; save it
        ld (v_asave), a         ; save it
        call POLLFD             ; anything to receive?
        call POLLFD             ; anything to receive?
        jr c, .readerr          ; Read error?
        jr c, .readerr1         ; Read error?
        jr z, .nodata           ; No hay nada
        jr z, .nodata1          ; No hay nada
 
 
        ld a, (v_asave)         ; get the fd back
        ld a, (v_asave)         ; get the fd back
        ld de, INTERPWKSPC
        ld de, INTERPWKSPC
        ld bc, 1                ; read one byte
        ld bc, 1                ; read one byte
        call RECV
        call RECV
        jr c, .readerr
        jr c, .readerr1
        ld a, (INTERPWKSPC)
        ld a, (INTERPWKSPC)
        ld l, 1                 ; signal "don't munge the stack"
        ld l, 1                 ; signal "don't munge the stack"
        scf                     ; signal 'character available'
        scf                     ; signal 'character available'
        ret
        ret
 
 
.nodata
.nodata1:
        xor a                   ; carry and zero reset - no data
        xor a                   ; carry and zero reset - no data
        ld l, 1                 ; signal "don't munge the stack"
        ld l, 1                 ; signal "don't munge the stack"
        jp F_leave
        jp F_leave
 
 
.readerrpop
.readerrpop1:
        pop hl                  ; fix the stack
        pop hl                  ; fix the stack
.readerr                        ; TODO error handling
.readerr1:                      ; TODO error handling
        ld hl, (oneof_line)     ; see if we have a line number to go to
        ld hl, (oneof_line)     ; see if we have a line number to go to
        ld a, h
        ld a, h
        or l
        or l
        jr nz, .eof_jump
        jr nz, .eof_jump1
 
 
        ld hl, INTERPWKSPC
        ld hl, INTERPWKSPC
        call ITOH8
        call ITOH8
        ld hl, INTERPWKSPC
        ld hl, INTERPWKSPC
        call PRINT42
        call PRINT42
        or 1                    ; reset carry, reset zero: EOF
        or 1                    ; reset carry, reset zero: EOF
        ld l, 1                 ; signal "don't munge the stack"
        ld l, 1                 ; signal "don't munge the stack"
        jp F_leave
        jp F_leave
 
 
.eof_jump
.eof_jump1:
        ld (ZX_NEWPPC), hl      ; set the line number
        ld (ZX_NEWPPC), hl      ; set the line number
        xor a
        xor a
        ld (ZX_NSPPC), a        ; and statement number to 0
        ld (ZX_NSPPC), a        ; and statement number to 0
        jp .exitnopop           ; exit *without* error
        jp .exitnopop1          ; exit *without* error
 
 
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; F_ctrlstream
; F_ctrlstream
; Handle a control stream (read only) - at the moment, only listening
; Handle a control stream (read only) - at the moment, only listening
; sockets.
; sockets.
F_ctrlstream
.globl F_ctrlstream
 
F_ctrlstream:
        ld a, l                 ; convert the function
        ld a, l                 ; convert the function
        and 0x0F                ; number to the stream number
        and 0x0F                ; number to the stream number
        rlca
        rlca
        rlca
        rlca
        rlca                    ; LSB of control stream metadata
        rlca                    ; LSB of control stream metadata
Line 244... Line 254...
        call POLLFD             ; Poll this fd and see if it's ready
        call POLLFD             ; Poll this fd and see if it's ready
 
 
        ld hl, ZX_TV_FLAG       ; the mode is considered unchanged
        ld hl, ZX_TV_FLAG       ; the mode is considered unchanged
        res 3, (hl)
        res 3, (hl)
 
 
        jr z, .nodata           ; Socket has no events
        jr z, .nodata2          ; Socket has no events
 
 
        ld a, '1'               ; indicate event
        ld a, '1'               ; indicate event
        ld l, 1                 ; signal "don't munge the stack"
        ld l, 1                 ; signal "don't munge the stack"
        scf                     ; signal 'character available'
        scf                     ; signal 'character available'
        ret
        ret
 
 
.nodata
.nodata2:
        xor a                   ; carry and zero reset - no data
        xor a                   ; carry and zero reset - no data
        ld l, 1                 ; signal "don't munge the stack"
        ld l, 1                 ; signal "don't munge the stack"
        jp F_leave
        jp F_leave
 
 
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
; F_findmetadata
; F_findmetadata
; Finds the data block for the stream in L
; Finds the data block for the stream in L
F_findmetadata
.globl F_findmetadata
 
F_findmetadata:
        ld a, l                 ; convert the function number to the
        ld a, l                 ; convert the function number to the
F_findmetadata_a                ; stream number.
.globl F_findmetadata_a
 
F_findmetadata_a:               ; stream number.
        and 0x0F
        and 0x0F
        rlca
        rlca
        rlca
        rlca
        rlca                    ; A now = LSB
        rlca                    ; A now = LSB
        ld h, 0x10              ; H now = MSB
        ld h, 0x10              ; H now = MSB