Execute Computer/Zero: Difference between revisions
Content added Content deleted
(Dialects of BASIC moved to the BASIC section.) |
(Added PL/M) |
||
Line 1,715: | Line 1,715: | ||
0-1: 255 |
0-1: 255 |
||
1+255: 0 |
1+255: 0 |
||
</pre> |
|||
=={{header|PL/M}}== |
|||
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator) |
|||
Uses PL/M's macro facility to provide "inline assembler" for the computerZero instructions. |
|||
The assembler code is enclosed by CODE-EDOC brackets (CODE-EDOC bracketing for inline assembler was used in some Algol 68 compilers - EDOC being CODE backwards). |
|||
<br>An additional pseudo-instruction: VAL is used to indicate literal values. |
|||
<br>As all PL/M arithmetic is unsigned and the BYTE type is 8-bits, computations are naturally MOD 255 and so there is no need to force the results to be in the range 0-255. |
|||
<syntaxhighlight lang="plm"> |
|||
100H: /* EXECUTE SOME COMPUTERZERO PROGRAMS */ |
|||
/* CP/M SYSTEM CALL AND I/O ROUTINES */ |
|||
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END; |
|||
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END; |
|||
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END; |
|||
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END; |
|||
PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH */ |
|||
DECLARE N ADDRESS; |
|||
DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE; |
|||
V = N; |
|||
W = LAST( N$STR ); |
|||
N$STR( W ) = '$'; |
|||
N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); |
|||
DO WHILE( ( V := V / 10 ) > 0 ); |
|||
N$STR( W := W - 1 ) = '0' + ( V MOD 10 ); |
|||
END; |
|||
CALL PR$STRING( .N$STR( W ) ); |
|||
END PR$NUMBER; |
|||
/* TASK */ |
|||
DECLARE FALSE LITERALLY '0' |
|||
, TRUE LITERALLY '0FFH' |
|||
; |
|||
DECLARE NOP$C LITERALLY '0' /* INSTRUCTION CODES */ |
|||
, LDA$C LITERALLY '32' |
|||
, STA$C LITERALLY '(2*32)' |
|||
, ADD$C LITERALLY '(3*32)' |
|||
, SUB$C LITERALLY '(4*32)' |
|||
, BRZ$C LITERALLY '(5*32)' |
|||
, JMP$C LITERALLY '(6*32)' |
|||
, STP$C LITERALLY '(7*32)' |
|||
; |
|||
DECLARE CODE LITERALLY 'PC=255' /* ASSEMBLER MNEMONICS */ |
|||
, LOAD LITERALLY 'PC=PC+1;PGM(PC)=' |
|||
, NOP LITERALLY 'LOAD NOP$C' |
|||
, LDA LITERALLY 'LOAD LDA$C+' |
|||
, STA LITERALLY 'LOAD STA$C+' |
|||
, ADD LITERALLY 'LOAD ADD$C+' |
|||
, SUB LITERALLY 'LOAD SUB$C+' |
|||
, BRZ LITERALLY 'LOAD BRZ$C+' |
|||
, JMP LITERALLY 'LOAD JMP$C+' |
|||
, STP LITERALLY 'LOAD STP$C ' |
|||
, VAL LITERALLY 'LOAD ' |
|||
, EDOC LITERALLY 'CALL EXECUTE' |
|||
; |
|||
DECLARE PGM (32)BYTE; /* THE PROGRAM */ |
|||
DECLARE PC BYTE; /* PROGRAM COUNTER */ |
|||
EXECUTE: PROCEDURE; /* EXECUTES THE PROGRAM */ |
|||
DECLARE ( RUNNING, A, OP, OPERAND ) BYTE; |
|||
PC, A = 0; |
|||
RUNNING = TRUE; |
|||
DO WHILE RUNNING; |
|||
OP = PGM( PC ) AND 0E0H; |
|||
OPERAND = PGM( PC ) AND 1FH; |
|||
PC = ( PC + 1 ) MOD 32; |
|||
IF OP = NOP$C THEN DO; /* NOTHING */ END; |
|||
ELSE IF OP = LDA$C THEN A = PGM( OPERAND ); |
|||
ELSE IF OP = STA$C THEN PGM( OPERAND ) = A; |
|||
ELSE IF OP = ADD$C THEN A = A + PGM( OPERAND ); |
|||
ELSE IF OP = SUB$C THEN A = A - PGM( OPERAND ); |
|||
ELSE IF OP = BRZ$C THEN DO; IF A = 0 THEN PC = OPERAND MOD 32; END; |
|||
ELSE IF OP = JMP$C THEN PC = OPERAND MOD 32; |
|||
ELSE DO; /* MUST BE STP$C */ |
|||
RUNNING = FALSE; |
|||
CALL PR$NUMBER( A ); |
|||
CALL PR$NL; |
|||
END; |
|||
END; |
|||
END EXECUTE ; |
|||
/* TEST PROGRAMS (FROM THE COMPUTER ZERO WEBSITE) */ |
|||
CALL PR$STRING( .' 2+2: $' ); |
|||
CODE; LDA 3; ADD 4; STP; VAL 2; VAL 2; EDOC; |
|||
CALL PR$STRING( .' 7*8: $' ); |
|||
CODE; LDA 12; ADD 10; STA 12; LDA 11; SUB 13; STA 11; BRZ 8; JMP 0; |
|||
LDA 12; STP; VAL 8; VAL 7; VAL 0; VAL 1; |
|||
EDOC; |
|||
CALL PR$STRING( .' FIBONACCI: $' ); |
|||
CODE; LDA 14; STA 15; ADD 13; STA 14; LDA 15; STA 13; LDA 16; SUB 17; |
|||
BRZ 11; STA 16; JMP 0; LDA 14; STP; |
|||
VAL 1; VAL 1; VAL 0; VAL 8; VAL 1; |
|||
EDOC; |
|||
CALL PR$STRING( .'LINKEDLIST: $' ); |
|||
CODE; LDA 13; ADD 15; STA 5; ADD 16; STA 7; NOP; STA 14; NOP; |
|||
BRZ 11; STA 15; JMP 0; LDA 14; STP; LDA 0; VAL 0; VAL 28; |
|||
VAL 1; VAL 0; VAL 0; VAL 0; VAL 6; VAL 0; VAL 2; VAL 26; |
|||
VAL 5; VAL 20; VAL 3; VAL 30; VAL 1; VAL 22; VAL 4; VAL 24; |
|||
EDOC; |
|||
CALL PR$STRING( .' PRISONER: $' ); |
|||
CODE; NOP; NOP; STP; VAL 0; LDA 3; SUB 29; BRZ 18; LDA 3; |
|||
STA 29; BRZ 14; LDA 1; ADD 31; STA 1; JMP 2; LDA 0; ADD 31; |
|||
STA 0; JMP 2; LDA 3; STA 29; LDA 1; ADD 30; ADD 3; STA 1; |
|||
LDA 0; ADD 30; ADD 3; STA 0; JMP 2; VAL 0; VAL 1; VAL 3; |
|||
EDOC; |
|||
/* SUBTRACTIONS YIELDING NEGATIVE RESULTS */ |
|||
CALL PR$STRING( .' 0-255: $' ); |
|||
CODE; LDA 3; SUB 4; STP; VAL 0; VAL 255; EDOC; |
|||
CALL PR$STRING( .' 0-1: $' ); |
|||
CODE; LDA 3; SUB 4; STP; VAL 0; VAL 1; EDOC; |
|||
/* OVERFLOW ON ADDITION */ |
|||
CALL PR$STRING( .' 1+255: $' ); |
|||
CODE; LDA 3; ADD 4; STP; VAL 1; VAL 255; EDOC; |
|||
EOF |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
2+2: 4 |
|||
7*8: 56 |
|||
FIBONACCI: 55 |
|||
LINKEDLIST: 6 |
|||
PRISONER: 0 |
|||
0-255: 1 |
|||
0-1: 255 |
|||
1+255: 0 |
|||
</pre> |
</pre> |
||