gno/bin/gsh/stdio.asm

352 lines
6.7 KiB
NASM

**************************************************************************
*
* The GNO Shell Project
*
* Developed by:
* Jawaid Bazyar
* Tim Meekins
*
* $Id: stdio.asm,v 1.6 1998/10/26 17:04:51 tribby Exp $
*
**************************************************************************
*
* STDIO.ASM
* By Tim Meekins
* Modified by Dave Tribby for GNO 2.0.6
*
* This is the custom stdio for the shell
*
* stdout buffer size: 512 bytes
* stderr buffer size: 256 bytes
* stdin buffer size: 128 bytes
*
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
* | | | | | |
* ^ ^ ^ ^ ^ ^
**************************************************************************
mcopy /obj/gno/bin/gsh/stdio.mac
dummystdio start ; ends up in .root
end
setcom 60
**************************************************************************
*
* putchar - output a character to standard out
* On entry: A = character
*
**************************************************************************
putchar START
using stdout
tay Note: lock destroys Acc
lock mutex Wait for others to leave, and lock.
tya
and #$FF Isolate the single character.
ldx index Get num of chars already in stream.
sta stream,x Store this char + null byte.
inx Bump length of stream by one.
cmp #13 If character was newline,
beq _flush go write the stream.
cpx #512 If length < 512,
bcc done all done.
_flush stx index Save current length.
Write WriteParm Write the stream.
ldx #0 Set new length to 0.
done stx index Save stream length in global.
unlock mutex Allow others through.
rts Return to caller.
END
**************************************************************************
*
* puts - output a c string to standard out
* On entry: A/X = pointer to string
*
**************************************************************************
puts START
using stdout
tay Note: lock destroys Acc
lock mutex Wait for others to leave, and lock.
sty getchar+1 Save low-order bytes of address.
txa
short a SWITCH TO SINGLE-BYTE MEMORY MODE.
sta getchar+3 Store high-order byte of address.
ora getchar+2 If string address
ora getchar+1 is 00/0000,
beq exit don't do the write.
ldy index Get current number of chars in stream.
ldx #0 Clear source string offset.
getchar lda >$FFFFFF,x Get next character from string.
beq done Done when we see a null byte.
sta stream,y Store in output stream.
iny Bump the stream and
inx string pointers.
cmp #13 If newline was encountered,
beq _flush go write & flush the stream.
cpy #512 If stream length < 512,
bcc getchar continue copying characters.
_flush sty index Save length of stream.
phx Hold source string offset on stack.
long a SWITCH TO FULL-WORD MEMORY MODE.
Write WriteParm Write the stream to stdout
Flush flushparm and flush it.
short a SWITCH TO SINGLE-BYTE MEMORY MODE.
plx Restore source string offset to X-reg.
ldy #0 Set stream length to 0.
bra getchar Continue copying characters.
; Arrive here when null character is encountered.
done sty index Save stream length in global.
exit long a SWITCH TO FULL-WORD MEMORY MODE.
unlock mutex Allow others through.
rts Return to caller.
END
**************************************************************************
*
* flush - flush stdout
*
**************************************************************************
flush START
using stdout
lock mutex
lda index
beq skip
Write WriteParm
Flush flushparm
stz index
skip unlock mutex
rts
END
**************************************************************************
*
* data for standard out
*
**************************************************************************
stdout PRIVDATA
mutex key
WriteParm dc i2'4'
dc i2'2' ;2 is standard out
dc i4'stream'
index dc i4'0'
dc i4'0'
flushparm dc i2'1'
dc i2'2'
stream ds 512+1
END
**************************************************************************
*
* errputchar - output a character to standard error
* On entry: A = character
*
**************************************************************************
errputchar START
using stderr
tay ;lock destroys Acc
lock errmutex
tya
and #$FF
ldx errindex
sta errstream,x
inx
cmp #13
beq _flush
cpx #256
bcc done
_flush stx errindex
Write errWriteParm
ldx #0
done stx errindex
unlock errmutex
rts
END
**************************************************************************
*
* errputs - output a c string to standard error
* On entry: A/X = pointer to string
*
**************************************************************************
errputs START
using stderr
tay ;lock destroys Acc
lock errmutex
sty getchar+1
txa
short a
sta getchar+3
ldy errindex
ldx #0
getchar lda >$FFFFFF,x
beq done
sta errstream,y
iny
inx
cmp #13
beq _flush
cpy #256
bcc getchar
_flush sty errindex
phx
long a
Write errWriteParm
short a
plx
ldy #0
bra getchar
done sty errindex
long a
unlock errmutex
rts
END
**************************************************************************
*
* errflush - flush stderr
*
**************************************************************************
errflush START
using stderr
lock errmutex
Write errWriteParm
stz errindex
unlock errmutex
rts
END
**************************************************************************
*
* data for standard error
*
**************************************************************************
stderr PRIVDATA
errmutex key
errWriteParm dc i2'4'
dc i2'3' ;3 is standard err
dc i4'errstream'
errindex dc i4'0'
dc i4'0'
errstream ds 256+1 ;not as large as stdout
END
**************************************************************************
*
* getchar - read a single character from standard input
* on exit: a = character, -1 if EOF
*
**************************************************************************
getchar START
using stdin
lock inmutex
lda insize ;any characters in stream?
bne grabchar ;yup
readloop Read inReadParm
bcc okread
ldy #-1 Return EOF if error code
cmp #$4C is "EOF encountered".
beq go_done2
ora #$FF00 For all other errors,
tay hi-byte is $FF, low-byte is error.
go_done2 jmp done2
okread stz inindex
lda insize
bne grabchar
cop $7F ;no characters ready, so wait
bra readloop
grabchar ldx inindex
lda instream,x
and #$7F
inc inindex
dec insize
tay
done2 unlock inmutex
tya
rts
END
**************************************************************************
*
* data for standard input
*
**************************************************************************
stdin PRIVDATA
inmutex key
inReadParm dc i2'4'
dc i2'1' ;1 is standard input
dc i4'instream'
inrequest dc i4'128'
insize dc i4'0'
inindex dc i2'0'
instream ds 128+1
END