block IO { // void newline() { // putChar( '\n' ); // } public block newline uses proc, CALLSYS { code { public enter: lda $sp, -sav0($sp); stq $ra, savRet($sp); body: mov '\n', $a0; bsr Sys.putChar.enter; return: ldq $ra, savRet($sp); lda $sp, +sav0($sp); ret; } code } block newline // void print( char *s ) { // while ( *s != 0 ) { // putChar( *s ); // s++; // } // } // public block print uses proc { abs { s = s0; } abs code { public enter: lda $sp, -sav1($sp); stq $ra, savRet($sp); stq $s0, sav0($sp); body: mov $a0, $s; // Pointer to char in string { while: ldbu $a0, ($s); // Get character beq $a0, end; // Break if at end of string do: bsr Sys.putChar.enter; // Print char addq $s, 1; // Increment pointer br while; end: } return: ldq $s0, sav0($sp); ldq $ra, savRet($sp); lda $sp, +sav1($sp); ret; } code } block print // char *readLine( char *s, int max ) { // register int i = 0; // register int c; // while ( TRUE ) { // c = getchar(); // if ( c < 0 || c == '\n' ) // break; // if ( i < max ) // s[ i ] = c; // i++; // } // if ( i > max ) // i = max; // s[ i ] = '\0'; // if ( c < 0 ) // return NULL; // else // return s + i; // } // public block readLine uses proc { abs { s = s0; max = s1; i = s2; c = s3; } abs code { public enter: lda $sp, -sav4($sp); stq $ra, savRet($sp); stq $s0, sav0($sp); stq $s1, sav1($sp); stq $s2, sav2($sp); stq $s3, sav3($sp); body: mov $a0, $s; // Pointer to character mov $a1, $max; // Size of input buffer clr $i; // Count of characters read { while: bsr Sys.getChar.enter; // Get a char mov $v0, $c; blt $c, end; cmpeq $c, '\n', $t0; // Break if newline blbs $t0, end; do: { if: cmplt $i, $max, $t0; // If within buffer blbc $t0, end; then: addq $s, $i, $t0; // Store the character stb $c, ($t0); end: } addq $i, 1; // Increment count br while; end: } { if: cmple $i, $max, $t0; // If not within buffer blbs $t0, end; then: mov $max, $i; end: } addq $s, $i, $t0; stb $zero, ($t0); // Append null char { if: bge $c, else; then: clr $v0; br end; else: mov $t0, $v0; end: } return: ldq $s3, sav3($sp); ldq $s2, sav2($sp); ldq $s1, sav1($sp); ldq $s0, sav0($sp); ldq $ra, savRet($sp); lda $sp, +sav4($sp); ret; } code } block readLine // #define LEFT -1 // #define UNKNOWN 0 // #define RIGHT +1 // void vsprintf( char *dest, char *format, int *params ) { // int defaultAlign; // int alignment; // char padChar; // int fieldWidth; // char *result; // while ( *format != NULL ) { // if ( *format == '%' ) { // format++; // if ( *format == '+' ) { // alignment = RIGHT; // format++; // } // else if ( *format == '-' ) { // alignment = LEFT; // format++; // } // else // alignment = UNKNOWN; // if ( *format =='0' ) // padChar = '0'; // else // padChar = ' '; // fieldWidth = 0; // while ( '0' <= *format && *format <= '9' ) { // fieldWidth = fieldWidth * 10 + *format - '0'; // format++; // } // switch ( *format ) { // case 'b': // result = Number.toUnsigned( *params++, 2 ); // defaultAlign = RIGHT; // break; // case 'o': // result = Number.toUnsigned( *params++, 8 ); // defaultAlign = RIGHT; // break; // case 'd': // result = Number.toSigned( *params++, 10 ); // defaultAlign = RIGHT; // break; // case 'x': // result = Number.toUnsigned( *params++, 16 ); // defaultAlign = RIGHT; // break; // case 'c': // result = String.fromChar( *params++ ); // defaultAlign = LEFT; // break; // case 's': // result = *params++; // defaultAlign = LEFT; // break; // default: // result = String.fromChar( *format ); // defaultAlign = LEFT; // } // format++; // if ( alignment == UNKNOWN ) // alignment = defaultAlign; // if ( alignment == RIGHT ) // result = String.padLeft( result, padChar, fieldWidth ); // else // result = String.padRight( result, padChar, fieldWidth ); // dest = String.copy( dest, result ); // } // else { // *dest++ = *format++; // *dest = 0; // } // } // } public block vsprintf extends proc.sav6 uses proc { abs { LEFT = -1; UNKNOWN = 0; RIGHT = +1; dest = s0; format = s1; params = s2; alignment = s3; fieldWidth = s4; result = s5; } abs local { defaultAlign: quad; padChar: quad; size: } local code { public enter: lda $sp, -size($sp); stq $ra, savRet($sp); stq $fp, savFP($sp); stq $s0, sav0($sp); stq $s1, sav1($sp); stq $s2, sav2($sp); stq $s3, sav3($sp); stq $s4, sav4($sp); stq $s5, sav5($sp); mov $sp, $fp; init: mov $a0, $dest; mov $a1, $format; mov $a2, $params; body: { while: ldbu $t0, ($format); beq $t0, end; do: { if: cmpeq $t0, '%', $t1; blbc $t1, else; then: addq $format, 1; { if: ldbu $t0, ($format); cmpeq $t0, '+', $t1; blbs $t1, plus; cmpeq $t0, '-', $t1; blbs $t1, minus; br else; plus: ldiq $alignment, RIGHT; addq $format, 1; br end; minus: ldiq $alignment, LEFT; addq $format, 1; br end; else: ldiq $alignment, UNKNOWN; end: } { if: ldbu $t0, ($format); cmpeq $t0, '0', $t1; blbc $t1, else; then: mov '0', $t0; addq $format, 1; br end; else: mov ' ', $t0; end: } stq $t0, padChar($fp); { for: clr $fieldWidth; while: ldbu $t0, ($format); cmplt $t0, '0', $t1; blbs $t1, end; cmple $t0, '9', $t1; blbc $t1, end; do: mulq $fieldWidth, 10; addq $fieldWidth, $t0; subq $fieldWidth, '0'; continue: addq $format, 1; br while; end: } ldbu $t0, ($format); { switch: cmpeq $t0, 'b', $t1; blbs $t1, caseB; cmpeq $t0, 'd', $t1; blbs $t1, caseD; cmpeq $t0, 'x', $t1; blbs $t1, caseX; cmpeq $t0, 'o', $t1; blbs $t1, caseO; cmpeq $t0, 'c', $t1; blbs $t1, caseC; cmpeq $t0, 's', $t1; blbs $t1, caseS; br default; caseB: ldq $a0, ($params); addq $params, 8; ldiq $a1, 2; bsr Number.toUnsigned.enter; mov $v0, $result; ldiq $t0, RIGHT; stq $t0, defaultAlign($fp); br end; caseD: ldq $a0, ($params); addq $params, 8; ldiq $a1, 10; bsr Number.toSigned.enter; mov $v0, $result; ldiq $t0, RIGHT; stq $t0, defaultAlign($fp); br end; caseX: ldq $a0, ($params); addq $params, 8; ldiq $a1, 16; bsr Number.toUnsigned.enter; mov $v0, $result; ldiq $t0, RIGHT; stq $t0, defaultAlign($fp); br end; caseO: ldq $a0, ($params); addq $params, 8; ldiq $a1, 8; bsr Number.toUnsigned.enter; mov $v0, $result; ldiq $t0, RIGHT; stq $t0, defaultAlign($fp); br end; caseC: ldq $a0, ($params); addq $params, 8; bsr String.fromChar.enter; mov $v0, $result; ldiq $t0, LEFT; stq $t0, defaultAlign($fp); br end; caseS: ldq $result, ($params); addq $params, 8; ldiq $t0, LEFT; stq $t0, defaultAlign($fp); br end; default: ldbu $a0, ($format); bsr String.fromChar.enter; mov $v0, $result; ldiq $t0, LEFT; stq $t0, defaultAlign($fp); end: } addq $format, 1; { if: cmpeq $alignment, UNKNOWN, $t0; blbc $t0, end; then: ldq $alignment, defaultAlign($fp); end: } { if: cmpeq $alignment, RIGHT, $t0; blbc $t0, else; then: mov $result, $a0; ldq $a1, padChar($fp); mov $fieldWidth, $a2; bsr String.padLeft.enter; br end; else: mov $result, $a0; ldq $a1, padChar($fp); mov $fieldWidth, $a2; bsr String.padRight.enter; end: } mov $dest, $a0; mov $v0, $a1; bsr String.copy.enter; mov $v0, $dest; br end; else: ldbu $t0, ($format); addq $format, 1; stb $t0, ($dest); addq $dest, 1; stb $zero, ($dest); end: } br while; end: } return: mov $fp, $sp; ldq $s5, sav5($sp); ldq $s4, sav4($sp); ldq $s3, sav3($sp); ldq $s2, sav2($sp); ldq $s1, sav1($sp); ldq $s0, sav0($sp); ldq $fp, savFP($sp); ldq $ra, savRet($sp); lda $sp, +size($sp); ret; } code } block vsprintf // void vprintf( char *format, int *params ) { // static char dest[ 400 ]; // vsprintf( dest, format, params ); // print( dest ); // } public block vprintf uses proc { data { align; dest: byte[ 400 ]; align; } data code { public enter: lda $sp, -sav0($sp); stq $ra, savRet($sp); body: mov $a1, $a2; mov $a0, $a1; ldiq $a0, dest; bsr vsprintf.enter; ldiq $a0, dest; bsr print.enter; return: ldq $ra, savRet($sp); lda $sp, +sav0($sp); ret; } code } block vprintf // void sprintf( char *dest, char *format, ... ) { // va_list argList; // va_start( argList, format ); // vsprintf( dest, format, argList ); // va_end( argList ); } // public block sprintf uses proc { code { public enter: lda $sp, -sav6($sp); stq $ra, savRet($sp); stq $a0, sav0($sp); stq $a1, sav1($sp); stq $a2, sav2($sp); stq $a3, sav3($sp); stq $a4, sav4($sp); stq $a5, sav5($sp); body: lda $a2, sav2($sp); bsr vsprintf.enter; return: ldq $a5, sav5($sp); ldq $a4, sav4($sp); ldq $a3, sav3($sp); ldq $a2, sav2($sp); ldq $a1, sav1($sp); ldq $a0, sav0($sp); ldq $ra, savRet($sp); lda $sp, +sav6($sp); ret; } code } block sprintf // void printf( char *format, ... ) { // va_list argList; // va_start( argList, format ); // vprintf( format, argList ); // va_end( argList ); // } // public block printf uses proc { code { public enter: lda $sp, -sav6($sp); stq $ra, savRet($sp); stq $a0, sav0($sp); stq $a1, sav1($sp); stq $a2, sav2($sp); stq $a3, sav3($sp); stq $a4, sav4($sp); stq $a5, sav5($sp); body: lda $a1, sav1($sp); bsr vprintf.enter; return: ldq $a5, sav5($sp); ldq $a4, sav4($sp); ldq $a3, sav3($sp); ldq $a2, sav2($sp); ldq $a1, sav1($sp); ldq $a0, sav0($sp); ldq $ra, savRet($sp); lda $sp, +sav6($sp); ret; } code } block printf // void error( char *format, ... ) { // va_list argList; // va_start( argList, format ); // printf( "\n" ); // vprintf( format, argList ); // printf( "\n" ); // exit( 0 ); // } public block error uses proc { code { public enter: lda $sp, -sav6($sp); stq $ra, savRet($sp); stq $a0, sav0($sp); stq $a1, sav1($sp); stq $a2, sav2($sp); stq $a3, sav3($sp); stq $a4, sav4($sp); stq $a5, sav5($sp); body: bsr newline.enter; ldq $a0, sav0($sp); lda $a1, sav1($sp); bsr vprintf.enter; bsr newline.enter; clr $a0; bsr Sys.exit.enter; return: ldq $a5, sav5($sp); ldq $a4, sav4($sp); ldq $a3, sav3($sp); ldq $a2, sav2($sp); ldq $a1, sav1($sp); ldq $a0, sav0($sp); ldq $ra, savRet($sp); lda $sp, +sav6($sp); ret; } code } block error } block IO