block IO { // void newline() { // putChar( '\n' ); // } public block newline uses proc, CALLSYS { code { public enter: lda $sp, -sav0($sp); stq $ra, savRA($sp); body: mov '\n', $a0; bsr Sys.putChar.enter; return: ldq $ra, savRA($sp); lda $sp, +sav0($sp); ret; } } // void print( char *s ) { // register long i; // while ( *s != 0 ) { // putChar( *s ); // s++; // } // } // public block print uses proc { abs { s = s0; } code { public enter: lda $sp, -sav1($sp); stq $ra, savRA($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, savRA($sp); lda $sp, +sav1($sp); ret; } } // void println( char *s ) { // print( s ); // newline(); // } // public block println uses proc { abs { s = s0; } code { public enter: lda $sp, -sav0($sp); stq $ra, savRA($sp); body: bsr print.enter; bsr newline.enter; return: ldq $ra, savRA($sp); lda $sp, +sav0($sp); ret; } } // void error( char *s ) { // print( s ); // exit( -1 ); // public block error uses proc { code { public enter: lda $sp, -sav0($sp); stq $ra, savRA($sp); body: bsr print.enter; negq 1, $a0; bsr Sys.exit.enter; return: ldq $ra, savRA($sp); lda $sp, +sav0($sp); ret; } } // void readLine( char *s, long max ) { // register long i = 0; // register long c; // while ( TRUE ) { // c = getchar(); // if ( c == '\n' ) // break; // if ( i < max ) // s[ i ] = c; // i++; // } // if ( i < max ) // s[ i ] = '\0'; // else // s[ max ] = '\0'; // } // public block readLine uses proc { abs { s = s0; max = s1; i = s2; } code { public enter: lda $sp, -sav3($sp); stq $ra, savRA($sp); stq $s0, sav0($sp); stq $s1, sav1($sp); stq $s2, sav2($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 cmpeq $v0, '\n', $t0; // Break if newline blbs $t0, end; do: { if: cmpult $i, $max, $t0; // If within buffer blbc $t0, end; then: addq $s, $i, $t0; // Store the character stb $v0, ($t0); end: } addq $i, 1; // Increment count br while; end: } { if: cmpult $i, $max, $t0; // If within buffer blbc $t0, else; then: addq $s, $i, $t0; // T0 = end of input br end; else: // else addq $s, $max, $t0; // T0 = end of buffer end: } stb $zero, ($t0); // Append null char return: ldq $s2, sav2($sp); ldq $s1, sav1($sp); ldq $s0, sav0($sp); ldq $ra, savRA($sp); lda $sp, +sav3($sp); ret; } } // #define BUFFERSIZE 200 // void printf( char *s, long param0, long param1, long param2, long param3, long param4, ... ) { // static long param[ 5 ]; // static char buffer[ BUFFERSIZE + 1 ]; // char *out = buffer; // long *p = param; // long fieldWidth; // char *result; // param[ 0 ] = param0; // param[ 1 ] = param1; // param[ 2 ] = param2; // param[ 3 ] = param3; // param[ 4 ] = param4; // while ( *s != NULL ) { // if ( *s == '%' ) { // s++; // fieldWidth = 0; // while ( '0' <= *s && *s <= '9' ) { // fieldWidth = fieldWidth * 10 + *s - '0'; // s++; // } // switch ( *s ) { // case 'b': // result = Number.toUnsigned( *p++, 2 ); // result = String.padLeft( result, '0', fieldWidth ); // break; // case 'o': // result = Number.toUnsigned( *p++, 8 ); // result = String.padLeft( result, '0', fieldWidth ); // break; // case 'd': // result = Number.toSigned( *p++, 10 ); // result = String.padLeft( result, ' ', fieldWidth ); // break; // case 'x': // result = Number.toUnsigned( *p++, 16 ); // result = String.padLeft( result, '0', fieldWidth ); // break; // case 'c': // result = String.fromChar( *p++ ); // result = String.padRight( result, ' ', fieldWidth ); // break; // case 's': // result = String.padRight( *p++, ' ', fieldWidth ); // break; // default: // result = String.fromChar( *s ); // } // s++; // String.copy( out, result ); // out += String.length( result ); // } // else { // *out++ = *s++; // } // *out = NULL; // print( buffer ); // } public block printf uses proc { abs { BUFFERSIZE = 200; s = s0; out = s1; p = s2; fieldWidth = s3; result = s4; } data { align quad; buffer: byte [ BUFFERSIZE + 1 ]; align quad; param: quad [ 5 ]; } code { public enter: lda $sp, -sav5($sp); stq $ra, savRA($sp); stq $s0, sav0($sp); stq $s1, sav1($sp); stq $s2, sav2($sp); stq $s3, sav3($sp); stq $s4, sav4($sp); decls: mov $a0, $s; ldiq $t0, param; stq $a1, ($t0); addq $t0, 8; stq $a2, ($t0); addq $t0, 8; stq $a3, ($t0); addq $t0, 8; stq $a4, ($t0); addq $t0, 8; stq $a5, ($t0); ldiq $out, buffer; ldiq $p, param; body: { while: ldbu $t0, ($s); beq $t0, end; do: { if: cmpeq $t0, '%', $t1; blbc $t1, else; then: addq $s, 1; clr $fieldWidth; { while: ldbu $t0, ($s); cmpult $t0, '0', $t1; blbs $t1, end; cmpule $t0, '9', $t1; blbc $t1, end; do: mulq $fieldWidth, 10; addq $fieldWidth, $t0; subq $fieldWidth, '0'; continue: addq $s, 1; br while; end: } ldbu $t0, ($s); { 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, ($p); addq $p, 8; ldiq $a1, 2; bsr Number.toUnsigned.enter; mov $v0, $result; mov $result, $a0; ldiq $a1, '0'; mov $fieldWidth, $a2; bsr String.padLeft.enter; mov $v0, $result; br end; caseD: ldq $a0, ($p); addq $p, 8; ldiq $a1, 10; bsr Number.toSigned.enter; mov $v0, $result; mov $result, $a0; ldiq $a1, ' '; mov $fieldWidth, $a2; bsr String.padLeft.enter; mov $v0, $result; br end; caseX: ldq $a0, ($p); addq $p, 8; ldiq $a1, 16; bsr Number.toUnsigned.enter; mov $v0, $result; mov $result, $a0; ldiq $a1, '0'; mov $fieldWidth, $a2; bsr String.padLeft.enter; mov $v0, $result; br end; caseO: ldq $a0, ($p); addq $p, 8; ldiq $a1, 8; bsr Number.toUnsigned.enter; mov $v0, $result; mov $result, $a0; ldiq $a1, '0'; mov $fieldWidth, $a2; bsr String.padLeft.enter; mov $v0, $result; br end; caseC: ldq $a0, ($p); addq $p, 8; bsr String.fromChar.enter; mov $v0, $result; mov $result, $a0; ldiq $a1, ' '; mov $fieldWidth, $a2; bsr String.padRight.enter; mov $v0, $result; br end; caseS: ldq $a0, ($p); addq $p, 8; ldiq $a1, ' '; mov $fieldWidth, $a2; bsr String.padRight.enter; mov $v0, $result; br end; default: ldbu $a0, ($s); bsr String.fromChar.enter; mov $v0, $result; end: } addq $s, 1; mov $out, $a0; mov $result, $a1; bsr String.copy.enter; mov $result, $a0; bsr String.length.enter; addq $out, $v0; br end; else: ldbu $t0, ($s); stb $t0, ($out); addq $s, 1; addq $out, 1; end: } br while; end: } stb $zero, ($out); ldiq $a0, buffer; bsr IO.print.enter; return: ldq $s4, sav4($sp); ldq $s3, sav3($sp); ldq $s2, sav2($sp); ldq $s1, sav1($sp); ldq $s0, sav0($sp); ldq $ra, savRA($sp); lda $sp, +sav5($sp); ret; } } }