************************************************************************** * * 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