;
-; Ullrich von Bassewitz, 30.05.1998
+; Oliver Schmidt, 12.01.2005
;
-; int read (int fd, void* buf, int count);
-;
-; THIS IS A HACK!
+; int __fastcall__ read (int fd, void* buf, unsigned count);
;
- .export _read
- .import popax, _cputc
- .importzp ptr1, ptr2, ptr3
-
- .include "apple2.inc"
-
-_read: jsr popax ; get count
- sta ptr2
- stx ptr2+1 ; save it for later
- jsr popax ; get buf
- sta ptr1
- stx ptr1+1
- jsr popax ; get fd and discard it
- lda #$00
- sta ptr3
- sta ptr3+1 ; set count
-
-L1: lda ptr2
- ora ptr2+1 ; count zero?
- beq L9
- jsr RDKEY
- and #$7F ; clear high bit.
- pha
- jsr _cputc
- pla
- ldy #$00 ; offset into string
- sta (ptr1),y ; save char
- inc ptr1
- bne L2
- inc ptr1+1
-L2: inc ptr3 ; increment count
- bne L3
- inc ptr3+1
-L3: cmp #$0D ; CR?
- bne L1
-
-; Done, return the count
-
-L9: lda ptr3
- ldx ptr3+1
- rts
+ .constructor initprompt
+ .export _read
+ .import rwprolog, rwcommon
+ .import RDKEY, COUT
+
+ .include "zeropage.inc"
+ .include "errno.inc"
+ .include "fcntl.inc"
+ .include "mli.inc"
+ .include "filedes.inc"
+ .include "apple2.inc"
+
+ .segment "INIT"
+
+initprompt:
+ ; Set prompt <> ']' to let DOS 3.3 know that we're
+ ; not in Applesoft immediate mode and thus keep it
+ ; from scanning our device I/O for DOS commands.
+ lda #$80 ; Same value used at $D52C
+ sta PROMPT
+ rts
+
+ .code
+
+_read:
+ ; Get parameters
+ jsr rwprolog
+ bcs errno
+ tax ; Save fd
+
+ ; Check for read access
+ lda fdtab + FD::FLAGS,y
+ and #O_RDONLY
+ beq einval
+
+ ; Check for device
+ txa ; Restore fd
+ bmi device
+
+ ; Do read
+ ldy #READ_CALL
+ jmp rwcommon
+
+ ; Device succeeds always
+device: lda #$00
+ sta __oserror
+
+ ; Set counter to zero
+ sta ptr3
+ sta ptr3+1
+
+ ; Check for zero count
+ lda ptr2
+ ora ptr2+1
+ beq check
+
+ ; Read from device and echo to device
+next: jsr RDKEY
+ jsr COUT
+
+ ; Clear hi bit and check for '\r'
+ and #$7F
+ cmp #$0D
+ bne :+
+
+ ; Replace with '\n' and set count to zero
+ lda #$0A
+ ldy #$00
+ sty ptr2
+ sty ptr2+1
+
+ ; Put char into buf
+: ldy #$00
+ sta (ptr1),y
+
+ ; Increment pointer
+ inc ptr1
+ bne :+
+ inc ptr1+1
+
+ ; Increment counter
+: inc ptr3
+ bne check
+ inc ptr3+1
+
+ ; Check for counter less than count
+check: lda ptr3
+ cmp ptr2
+ bcc next
+ ldx ptr3+1
+ cpx ptr2+1
+ bcc next
+ ; Return success, AX already set
+ rts
+ ; Load errno code
+einval: lda #EINVAL
+ ; Set __errno
+errno: jmp __directerrno