home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG023.ARK
/
ASSEMBL.DOC
next >
Wrap
Text File
|
1984-04-29
|
13KB
|
542 lines
***************************************************************************
** COPYRIGHT (C) MASSACHUSETTS INSTITUTE OF TECHNOLOGY AND HARVARD **
** UNIVERSITY, BIOMEDICAL ENGINEERING CENTER 1977. ALL RIGHTS RESERVED. **
***************************************************************************
THE STOIC ASSEMBLER FOR THE INTEL 8080
J. SACHS 2/2/77
CODE DEFINITIONS
STOIC PROVIDES THE USER WITH A MEANS OF DEFINING
A NEW WORD IN TERMS OF THE ASSEMBLY LANGUAGE FOR THE
PARTICULAR MACHINE ON WHICH IT IS EXECUTING. THIS IS
PROVIDED BY THE ASSEMBLER AND THE CODE DEFINITION.
'NAME CODE< A1 A2 ... >
HERE A1, A2, ... ARE WORDS DEFINED WITHIN THE
ASSEMBLER AND "NAME" IS THE NAME OF THE WORD BEING
DEFINED. AS WITH EVERYTHING ELSE IN STOIC, THE
ASSEMBLER USES REVERSE POLISH NOTATION, GIVING THE
ADDRESSES AND ACCUMULATOR SPECIFIERS BEFORE THE
OPCODE.
THE ASSEMBLER WORDS DO NOT EXECUTE MACHINE
INSTRUCTIONS DIRECTLY; THEY MERELY CAUSE INSTRUCTIONS
TO BE ASSEMBLED ONTO THE END OF THE DICTIONARY. THUS
BEFORE MACHINE LANGUAGE INSTRUCTIONS CAN BE EXECUTED
FROM THE KEYBOARD THEY MUST FIRST BE ASSEMBLED INTO A
CODE DEFINITION.
ADDRESSES
AN ADDRESS IS NORMALLY THE NAME OF A WORD, OR AN
ABSOLUTE LOCATION. AN ADDRESS MAY HOWEVER BE ANY EXPRESSION
WHICH EVALUATES TO AN INTEGER.
ACCUMULATORS
WITHIN THE ASSEMBLER, THE NORMAL INTEL ACCUMULATOR
NAMES (A,B,C,D,E,H,L,M,SP,PSW) ARE USED TO SPECIFY 8080
REGISTERS.
INSTRUCTIONS WITHOUT ADDRESS OR ACCUMULATOR
INTEL STOIC
NOP NOP,
HLT HLT,
RLC RLC,
RRC RRC,
RAL RAL,
RAR RAR,
DAA DAA,
CMA CMA,
STC STC,
CMC CMC,
RET RET,
RNZ RNZ,
RZ RZ,
RNC RNC,
RC RC,
RPO RPO,
RPE RPE,
RP RP,
RM RM,
XTHL XTHL,
PCHL PCHL,
SPHL SPHL,
XCHG XCHG,
DI DI,
EI EI,
INSTRUCTIONS WITH ACCUMULATOR
INTEL STOIC
RST N N RST,
DAD ACC ACC DAD,
DCX ACC ACC DCX,
STAX ACC ACC STAX,
LDAX ACC ACC LDAX,
INR ACC ACC INR,
DCR ACC ACC DCR,
POP ACC ACC POP,
PUSH ACC ACC PUSH,
INX ACC ACC INX,
INSTRUCTIONS WITH AN ACCUMULATOR AND A 16-BIT VALUE
INTEL STOIC
LXI ACC,VALUE VALUE ACC LXI,
INSTRUCTIONS WITH TWO ACCUMULATORS
INTEL STOIC
MOV AC1,AC2 AC2 AC1 MOV,
INSTRUCTIONS WITH AN ADDRESS
INTEL STOIC
SHLD ADR ADR SHLD,
LHLD ADR ADR LHLD,
STA ADR ADR STA,
LDA ADR ADR LDA,
JMP ADR ADR JMP,
CALL ADR ADR CALL,
JNZ ADR ADR JNZ,
JZ ADR ADR JZ,
JNC ADR ADR JNC,
JC ADR ADR JC,
JPO ADR ADR JPO,
JPE ADR ADR JPE,
JP ADR ADR JP,
JM ADR ADR JM,
CNZ ADR ADR CNZ,
CZ ADR ADR CZ,
CNC ADR ADR CNC,
CC ADR ADR CC,
CPO ADR ADR CPO,
CPE ADR ADR CPE,
CP ADR ADR CP,
CM ADR ADR CM,
INSTRUCTIONS WITH ONE ACCUMULATOR AND ONE 8-BIT VALUE
INTEL STOIC
MVI ACC,VALUE VALUE ACC MVI,
INSTRUCTIONS WITH ONE ACCUMULATOR
INTEL STOIC
ADD ACC ACC ADD,
ADC ACC ACC ADC,
SUB ACC ACC SUB,
SBB ACC ACC SBB,
ANA ACC ACC ANA,
XRA ACC ACC XRA,
ORA ACC ACC ORA,
CMP ACC ACC CMP,
INSTRUCTIONS WITH ONE 8-BIT VALUE
INTEL STOIC
ADI VALUE VALUE ADI,
ACI VALUE VALUE ACI,
SUI VALUE VALUE SUI,
SBI VALUE VALUE SBI,
ANI VALUE VALUE ANI,
XRI VALUE VALUE XRI,
ORI VALUE VALUE ORI,
CPI VALUE VALUE CPI,
OUT N N OUT,
IN N N IN,
EXAMPLES:
STOIC ASSEMBLER INTEL ASSEMBLER
HLT, HLT
0 H LXI, LXI H,0
A B MOV, MOV B,A
M CPI, CPI M
H DCX, DCX H
. JMP, JMP $
FORWARD AND BACKWARD JUMPS
SINCE THE STOIC ASSEMBLER HAS NO LABELS, SPECIAL
ASSEMBLER WORDS ARE USED TO CONTROL FORWARD AND BACKWARD
JUMPS.
BACKWARD JUMPS ARE ACCOMPLISHED USING THE FOLLOWING CONSTRUCTION:
. ... JMP,
"." IS USED TO SAVE THE CURRENT LOCATION ON THE
STACK; THE FOLLOWING INSTRUCTIONS ARE ASSEMBLED
NORMALLY, AND THE "JMP," ASSEMBLES A JUMP BACK
TO THE SAVED LOCATION COUNTER VALUE. A CONDITIONAL
JUMP COULD JUST AS EASILY BE USED. SUCH BACKWARD
JUMPS MAY BE NESTED FOR MULTI-LEVEL LOOPS.
FORWARD JUMPS ARE ASSEMBLED USING THE FOLLOWING WORDS:
IF, UNCONDITIONAL FORWARD JUMP
IFNZ, FORWARD JUMP IF NON-ZERO
IFZ, FORWARD JUMP IF ZERO
IFNC, FORWARD JUMP IF NO CARRY
IFC, FORWARD JUMP IF CARRY
IFPO, FORWARD JUMP IF PARITY ODD
IFPE, FORWARD JUMP IF PARITY EVEN
IFP, FORWARD JUMP IF PLUS
IFM, FORWARD JUMP IF MINUS
THEN, SUPPLY TARGET FOR FORWARD JUMP
ELSE, GENERATE AN UNCOUNDITIONAL FORWARD JUMP
AND SUPPLY TARGET FOR PRECEDING FORWARD
JUMP.
THE NORMAL CONSTRUCTION FOR A FORWARD JUMP IS:
IF, ... THEN,
THE "IF," ASSEMBLES A "0 JMP," AND SAVES ON THE STACK THE
ADDRESS OF THE 0. "THEN," STORES THE VALUE OF THE CURRENT
LOCATION COUNTER (.) AT THE ADDRESS ON THE TOP OF THE
STACK, THUS COMPLETING THE ASSEMBLY OF THE JMP INSTRUCTION.
FORWARD JUMPS MAY BE NESTED IN EXACTLY THE SAME WAY AS
BACKWARD JUMPS.
"ELSE," IS USED AS FOLLOWS:
IF, ... ELSE, ... THEN,
HERE, THE "IF," GENERATES A FORWARD JUMP TO THE
INSTRUCTION IMMEDIATELY FOLLOWING THE "ELSE,". THE "ELSE,"
IN TURN CAUSES AN UNCONDITIONAL JUMP TO BE ASSEMBLED TO THE
INSTRUCTION FOLLOWING THE "THEN,". THE "IF," COULD, OF
COURSE, BE A CONDITIONAL JUMP.
EXAMPLES:
'TEST CODE< H POP, H A MOV, IFP, -1 H LXI, ELSE,
0 H LXI, THEN, PUSH JMP, >
THIS DEFINES A WORD CALLED "TEST" WHICH, IF
THE TOP OF THE STACK IS POSITIVE, PUSHES A 0,
OTHERWISE PUSHES A -1. THE GENERATED CODE IS:
POP H
MOV A,H
JP L1
LXI H,-1
JMP L2
L1: LXI H,0
L2: JMP PUSH
'WAIT CODE< H POP, . H DCX, H A MOV, L ORA, JNZ,
NEXT JMP, >
THE WORD "WAIT" IS DEFINED WHICH COUNTS DOWN ITS
ARGUMENT AND RETURNS WHEN THE RESULT IS 0. THE
GENERATED CODE IS:
POP H
L1: DCX H
MOV A,H
ORA L
JNZ L1
JMP NEXT
DEFINING SUBROUTINES
SOMETIMES A BLOCK OF INSTRUCTIONS MUST BE EXECUTED FROM
SEVERAL DIFFERENT CODE DEFINITIONS; IN THIS CASE IT IS FREQUENTLY
EFFICIENT TO DEFINE A SUBROUTINE. THIS IS DONE AS FOLLOWS:
. ASSEMBLER<
BODY OF SUBROUTINE
>
'SUBROUTINE-NAME CONSTANT
THE "." PUSHES ON THE STACK THE ADDRESS OF THE BEGINNING OF THE
SUBROUTINE, SUPPLYING THE VALUE FOR "CONSTANT". "ASSEMBLER<"
ACTIVATES THE ASSEMBLER VOCABULARY; NOTE THAT IT MUST BE FOLLOWED
BY A CARRAIGE RETURN. THE BODY OF THE SUBROUTINE FOLLOWS, WITH
RETURN INSTRUCTIONS INCLUDED. FINALLY, ">" DE-ACTIVATES THE
ASSEMBLER VOCABULARY AND THE CONSTANT IS DEFINED. SUBSEQUENTLY,
THE SUBROUTINE MAY BE INVOKED DIRECTLY BY:
SUBROUTINE-NAME CALL,
ASSEMBLING STRINGS
TO ASSEMBLE A STRING ONTO THE END OF THE DICTIONARY, THE
FOLLOWING TECHNIQUE IS USED:
. "STRING" S,
THIS PUSHES A POINTER TO THE BEGINNING OF THE STRING ON THE STACK,
AND COPIES THE GIVEN STRING FROM THE COMPILE BUFFER ONTO THE END
OF THE DICTIONARY.
REPEATING INSTRUCTIONS
INTERATION BRACKETS AND/OR DO LOOPS MAY BE USED WITHIN
THE ASSEMBLER TO PERFORM REPETITIVE ASSEMBLY:
'DELAY CODE< 100 ( NOP, ) >
THIS ASSEMBLES A WORD "DELAY" WHICH EXECUTES 100 NOP'S.
. 10 0 DO I , LOOP
THIS EXAMPLE LEAVES ON THE STACK THE ADDRESS OF THE BEGINNING OF
A TABLE OF NUMBERS FROM 0 TO RADIX - 1.
CONDITIONAL ASSEMBLY
CONDITIONAL ASSEMBLY IS OBTAINED BY USING THE NORMAL STOIC
"IF", "ELSE", AND "THEN". FOR EXAMPLE, SUPPOSE WE HAVE A VARIABLE
"TEST" WHICH THE USER WILL SET TO EITHER 0 OR -1:
'PARAM CODE< TEST @ IF 100 ELSE 200 THEN H LXI, PUSH JMP, >
HERE, THE CODE DEFINITION, "PARAM" IS DEFINED TO PUSH A 100 IF TEST
IS NON-ZERO, A 200 OTHERWISE.
MACROS
ASSEMBLER MACROS ARE PROVIDED BY USING COLON DEFINITIONS
AS FOLLOWS:
ASSEMBLER< DEFINITIONS
'-HL, : H A MOV, CMA, A H MOV, L A MOV, CMA, A L MOV,
H INX, ;
> DEFINITIONS
THUS,
'MINUS CODE< H POP, -HL, PUSH JMP, >
DEFINES A WORD WHICH NEGATES THE TOP OF THE STACK.
LOCATIONS INTERNAL TO STOIC WHICH ARE AVAILABLE TO THE USER:
-HL CALL, NEGATES (H,L)
HL 1+ CALL, COMPLEMENTS (H,L)
-DE CALL, NEGATES (D,E)
DE 1+ CALL, COMPLEMENTS (D,E)
-BC CALL, NEGATES (B,C)
BC 1+ CALL, COMPLEMENTS (B,C)
-HLDE CALL, NEGATES (H,L,D,E)
(TTI) CALL, GET A CHARACTER FORM THE KEYBOARD;
CHARACTER RETURNED IN A REGISTER.
(TTO) CALL, TYPE A CHARACTER ON THE TERMINAL;
CHARACTER PASSED IN A REGISTER.
RETURN AUTOMATICALLY FOLLOWED BY LINE FEED.
(MSG) CALL, TYPES A MESSAGE ON THE TERMINAL;
POINTER TO STRING PASSED IN (H,L).
MUL CALL, UNSIGNED MULTIPLY
SMUL CALL, SIGNED MULTIPLY
(H,L)*(D,E) -> (H,L,D,E)
DIV CALL, UNSIGNED DIVIDE
SDIV CALL, SIGNED DIVIDE
(H,L,D,E)/(B,C) -> (H,L) REMAINDER; (D,E) QUOTIENT
(B,) CALL, OUTPUT A REGISTER TO END OF DICTIONARY
(,) CALL, OUTPUT (H,L) TO END OF DICTIONARY
ERROR JMP, SIMULATES "STRING" ERR
ADDRESS OF STRING IN (H,L).
(READ) CALL, READ A BLOCK FROM MASS STORAGE DEVICE
(WRITE) CALL, WRITE A BLOCK TO MASS STORAGE DEVICE
(H,L) = BLOCK #
(D,E) = BUFFER ADDRESS
ON RETURN, A = ERROR CODE (0 = OK)
(RBLOCK) CALL, BLOCK # IN (D,E), BUFFER
(WBLOCK) CALL, ADDRESS RETURNED IN (D,E).
T1 TEMPORARY #1
9 ADDITIONAL 16-BIT TEMPORARIES FOLLOW
IN MAKING A CODE DEFINITION OF HIS OWN, THE USER
SHOULD BE AWARE OF THE FOLLOWING FACTS:
1) THE PARAMETER STACK POINTER IS PASSED IN SP. SP
MUST CONTAIN THE STACK POINTER ON EXIT.
2) PARAMETERS ON THE STACK ARE AVAILABLE BY INDEXING OFF
SP. THE TOP OF THE STACK IS AT OFFSET 0, NEXT TO TOP
AT OFFSET +2, ETC.
3) TEN TEMPORARIES, STARTING AT "T1" ARE AVAILABLE IF
NECESSARY.
4) ALL CODE DEFINITIONS MUST EXIT BY JUMPING TO ONE OF
THE FOLLOWING ADDRESSES IN THE STOIC INTERPRETER:
NEXT NORMAL TERMINATION
PUSH PUSH (H,L), JUMP TO NEXT
DPUSH PUSH (D,E), PUSH (H,L), JUMP TO NEXT
PUSHD PUSH (D,E), JUMP TO NEXT
@PUSH PUSH @(H,L), JUMP TO NEXT
0PUSH PUSH 0, JUMP TO NEXT
-1PUSH PUSH -1, JUMP TO NEXT
5) A POINTER TO THE PARAMETER FIELD OF THE CURRENT WORD
IS PASSED IN (D,E). (D,E) NEED NOT BE PRESERVED.
EXAMPLES OF CODE DEFINITIONS:
'+ CODE< H POP, D POP, D DAD, PUSH JMP, >
THE WORD "+" ADDS THE TOP TWO STACK ENTRIES
AND LEAVES THE RESULT ON THE STACK.
'ABS CODE< H POP, H A MOV, A ORA, IFP,
-HL CALL, THEN, PUSH JMP, >
THE WORD "ABS" REPLACES THE TOP OF THE STACK
WITH ITS ABSOLUTE VALUE.
;CODE<
THE WORD ";CODE<" IS USED TO DEFINE NEW CLASSES
OF WORDS. "VARIABLE", "CONSTANT", AND "USER", FOR
EXAMPLE ARE DEFINED USING ";CODE<". THE FORMAT FOR ITS
USE IS AS FOLLOWS:
'NAME : ... ;CODE< ... >
THE WORDS BETWEEN "NAME" AND ";CODE<" ARE IN
HIGHER LEVEL STOIC; THE WORDS BETWEEN ";CODE< AND ">"
ARE ASSEMBLER WORDS.
WHEN EXECUTED, ";CODE<" OUTPUTS THE ADDRESS OF
"(;CODE<)" TO THE COMPILE BUFFER, TERMINATES THE CURRENT
COLON DEFINITION, AND PUSHES THE ADDRESS OF "ASSEMBLER<" ON
THE VOCABULARY STACK.
THE NAMELESS DICTIONARY ENTRY "(;CODE<)"
SETS THE CODE ADDRESS WORD OF THE MOST RECENTLY
DEFINED WORD TO THE CONTENTS OF "I" + 2, AND POPS
"I" FROM THE RETURN STACK.
EXAMPLE:
'VARIABLE : CONSTANT ;CODE< PUSHD JMP, >
THIS IS THE DEFINITION OF "VARIABLE". THE
DICTIONARY ENTRY FOR "VARIABLE" THEN LOOKS
AS FOLLOWS:
<8>V
AR
IA
LINK TO PREVIOUS ENTRY
ADDRESS OF (:)
VAR: ADDRESS OF CONSTANT
ADDRESS OF (;CODE<)
(VAR): JMP PUSHD
NOW, SUPPOSE THAT X IS DEFINED AS FOLLOWS:
20 'X VARAIBLE
"VARIABLE" INVOKES "CONSTANT" WHICH BUILDS A
DICTIONARY ENTRY CALLED "X", STORES THE
VALUE "20" IN THE PARAMETER FIELD, AND SETS
THE CODE ADDRESS WORD TO POINT TO MACHINE
INSTRUCTIONS WHICH PUSH THE VALUE OF THE
PARAMETER FIELD ON THE STACK. ";CODE<" THEN
OVERWRITES THE CODE ADDRESS WORD WITH THE
ADDRESS OF (VAR). THUS, THE RESULTANT
DICTIONARY ENTRY FOR "X" IS:
<1>X
0
0
LINK TO PREVIOUS ENTRY
(VAR)
X: 20
WHEN "X" IS IN TURN EXECUTED, CONTROL PASSES
TO (VAR) VIA THE CODE ADDRESS WORD, WITH THE
ADDRESS OF "X" IN (D,E), THE ADDRESS OF "X" IS
PUSHED, AND CONTROL PASSES TO "NEXT".
;:
";:" IS ANALOGOUS TO ";CODE<" EXCEPT THAT IT
USES HIGHER LEVEL STOIC TO DEFINE THE ACTION TAKEN
BY THE CLASS OF WORDS BEING DEFINED. THE SYNTAX IS
AS FOLLOWS:
'NAME : ... ;: ... ;
HERE, BOTH SETS OF WORDS ARE IN HIGHER LEVEL
STOIC.
EXAMPLE:
0> 'SQPRINT : ;: DUP * = ;
0> 5 'X SQPRINT
0> X
25
";:" IS MAINLY USEFUL IN DEFINING A NUMBER OF WORDS WHICH
DIFFER ONLY IN A SINGLE CONSTANT VALUE, E.G. ASSEMBLER WORDS WITH
DIFFERENT OPCODES.
***EOF***