mirror of https://github.com/GnoConsortium/gno.git
352 lines
6.7 KiB
NASM
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
|