1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-01 13:41:34 +00:00
cc65/libsrc/cbm/write.s
Oliver Schmidt 0ee9b2e446 Changed run location of INIT segment.
So far the INIT segment was run from the later heap+stack. Now the INIT segment is run from the later BSS. The background is that so far the INIT segment was pretty small (from $80 to $180 bytes). But upcoming changes will increase the INIT segment in certain scenarios up to ~ $1000 bytes. So programs with very limited heap+stack might just not been able to move the INIT segment to its run location. But moving the INIT segment to the later BSS allows it to occupy the later BSS+heap+stack.

In order to allow that the constructors are _NOT_ allowed anymore to access the BSS. Rather they must use the DATA segment or the new INITBSS segment. The latter isn't cleared at any point so the constructors may use it to expose values to the main program. However they must make sure to always write the values as they are not pre-initialized.
2015-10-14 22:52:09 +02:00

119 lines
2.7 KiB
ArmAsm

;
; Ullrich von Bassewitz, 16.11.2002
;
; int write (int fd, const void* buf, unsigned count);
;
.export _write
.constructor initstdout
.import SETLFS, OPEN, CKOUT, BSOUT, READST, CLRCH
.import rwcommon
.importzp sp, ptr1, ptr2, ptr3
.include "cbm.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "filedes.inc"
;--------------------------------------------------------------------------
; initstdout: Open the stdout and stderr file descriptors for the screen.
.segment "INIT"
.proc initstdout
lda #STDOUT_FILENO + LFN_OFFS
jsr @L1
lda #STDERR_FILENO + LFN_OFFS
@L1: ldx #CBMDEV_SCREEN
ldy #$FF
jsr SETLFS
jmp OPEN ; Will always succeed
.endproc
;--------------------------------------------------------------------------
; _write
.code
.proc _write
jsr rwcommon ; Pop params, check handle
bcs invalidfd ; Invalid handle
; Check if the LFN is valid and the file is open for writing
adc #LFN_OFFS ; Carry is already clear
tax
lda fdtab-LFN_OFFS,x; Get flags for this handle
and #LFN_WRITE ; File open for writing?
beq invalidfd
; Valid lfn. Make it the output file
jsr CKOUT
bcc @L2
@error: jmp __mappederrno ; Store into __oserror, map to errno, return -1
; Output the next character from the buffer
@L0: ldy #0
lda (ptr2),y
inc ptr2
bne @L1
inc ptr2+1 ; A = *buf++;
@L1: jsr BSOUT
; Check the status
pha
jsr READST
lsr a ; Bit zero is write timeout
bne devnotpresent2
pla
bcs @L3
; Count characters written
inc ptr3
bne @L2
inc ptr3+1
; Decrement count
@L2: inc ptr1
bne @L0
inc ptr1+1
bne @L0
; Wrote all chars or disk full. Close the output channel
@L3: jsr CLRCH
; Clear _oserror and return the number of chars written
lda #0
sta __oserror
lda ptr3
ldx ptr3+1
rts
; Error entry: Device not present
devnotpresent2:
pla
devnotpresent:
lda #ENODEV
jmp __directerrno ; Sets _errno, clears _oserror, returns -1
; Error entry: The given file descriptor is not valid or not open
invalidfd:
lda #EBADF
jmp __directerrno ; Sets _errno, clears _oserror, returns -1
.endproc