1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-26 08:32:00 +00:00
cc65/libsrc/apple2/read.s
Oliver Schmidt 0f4cb443b4 Improved device I/O under DOS 3.3
Certain scenarios (e.g. not running any Applesoft program at all since booting DOS 3.3) can make DOS 3.3 consider cc65 device input (e.g. getchar()) that reads a CR interpreting the command in the keyboard buffer. Setting the hibyte of the Applesoft currently executed line number to some value <> $FF (beside setting the input prompt to some value <> ']') makes DOS 3.3 understand that we're not in intermediate mode and that therefore I/O not preceded with ctrl-d mustn't be fiddled with (see DOS 3.3 routine at $A65E).
2020-12-19 19:54:12 +01:00

111 lines
2.5 KiB
ArmAsm

;
; Oliver Schmidt, 12.01.2005
;
; int __fastcall__ read (int fd, void* buf, unsigned count);
;
.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 "ONCE"
initprompt:
; Set prompt <> ']' and currently executed Applesoft
; line number hibyte <> $FF to let DOS 3.3 (at $A65E)
; 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
sta CURLIN+1 ; Any value <> $FF will do
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