home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
USCX
/
FIGFORTH.ZIP
/
FORTH.ARC
/
ASM.SCR
< prev
next >
Wrap
Text File
|
1983-07-30
|
43KB
|
1 lines
/\/\/\/\/\/\/\/\/\/\/\/\/\/\ \ / / FORTH \ \ 8086 ASSEMBLER / / \ \/\/\/\/\/\/\/\/\/\/\/\/\/\/ ( 8086 Assembler ) --> Ray Duncan's assembler which appeared in Dr. Dobb's Journal No. 64, February 1982. Slightly modified by Joe Smith U. of Penn./Dept. of Chemistry 250 S. 33rd St. Philadelphia, PA 19104 ( 8086 Assembler -- LOAD SCREEN ) CR CR ." Assembler loading, please wait " CR 3 LOAD DECIMAL CR CR ." 8086 Assembler loaded, " SIZE? ;S ( 8086 Assembler -- variables ) FORTH DEFINITIONS VOCABULARY ASSEMBLER IMMEDIATE ASSEMBLER DEFINITIONS HEX 0 VARIABLE <#> ( immediate data flag ) 0 VARIABLE <TD> ( dest. addressing type ) 0 VARIABLE <TS> ( source addressing type ) 0 VARIABLE <RD> ( dest. reg. ) 0 VARIABLE <RS> ( source reg. ) 0 VARIABLE <W> ( word/byte flag ) 0 VARIABLE <WD> ( dest. word/byte flag ) 0 VARIABLE <OD> ( dest. offset ) 0 VARIABLE <OS> ( source offset ) 0 VARIABLE <D> ( direction flag ) 0 VARIABLE <SP> ( local stack pointer ) --> ( 8086 Assembler -- miscellaneous primitives ) ( save the current stack pointer as base of local stack ) : !<SP> SP@ <SP> ! ; ( return depth of local stack ) : ?<SP> <SP> @ SP@ - 2- 2 / ; --> ( 8086 Assembler -- error handling ) : ERR21 ABORT" ? 16-bit register not allowed" ; : ERR22 ABORT" ? 8-bit register not allowed" ; : ERR23 ABORT" ? address out of range" ; : ERR24 ABORT" ? immediate data not allowed" ; : ERR25 ABORT" ? missing source register" ; : ERR26 ABORT" ? missing destination register" ; : ERR27 ABORT" ? illegal operation" ; : ERR28 ABORT" ? illegal operand" ; : ERR29 ABORT" ? not implemented" ; : ERR2A ABORT" ? illegal destination register" ; : ERR2B ABORT" ? illegal source register" ; : ERR2C ABORT" ? illegal condition code" ; : ERR2D ABORT" ? register mismatch" ; : ERR2E ABORT" ? destination address missing" ; --> ( 8086 Assembler -- dest. reg. processing ) : DREG <BUILDS C, C, C, ( store input parameters ) DOES> DUP C@ DUP 0FF = ( is it word or byte? ) IF ( byte ) DROP ELSE DUP <W> ! <WD> ! THEN 1+ DUP C@ <TD> ! ( addressing type ) 1+ C@ <RD> ! ( set register code ) <#> @ ERR24 ( bad immediate ) <TD> @ 4 = ( indexed? ) IF ( indexed) ?<SP> 0 > ( check for displacement ) IF ( displacement ) <OD> ! THEN THEN ; --> ( 8086 Assembler -- source reg. processing ) : SREG <BUILDS C, C, C, ( store input parameters ) DOES> DUP C@ DUP 0FF = ( is it word or byte ) IF ( byte ) DROP ELSE ( word ) <W> ! THEN 1+ DUP C@ <TS> ! ( set addressing type ) 1+ C@ <RS> ! ( set reg. type ) <TS> @ 4 = ( indexed? ) IF ( indexed ) ?<SP> 0 > IF ( displacement ) <OS> ! THEN THEN ; --> ( 8086 Assembler -- source reg. definitions ) 0 3 1 SREG AX 0 2 0 SREG AL 4 2 0 SREG AH 1 3 1 SREG CX 1 2 0 SREG CL 5 2 0 SREG CH 2 3 1 SREG DX 2 2 0 SREG DL 6 2 0 SREG DH 3 3 1 SREG BX 3 2 0 SREG BL 7 2 0 SREG BH 4 3 1 SREG SP 5 3 1 SREG BP 6 3 1 SREG SI 7 3 1 SREG DI --> ( 8086 Assembler -- source reg. definitions ) 0 4 -1 SREG [BX+SI] 0 4 -1 SREG [SI+BX] 1 4 -1 SREG [BX+DI] 1 4 -1 SREG [DI+BX] 2 4 -1 SREG [BP+SI] 2 4 -1 SREG [SI+BP] 3 4 -1 SREG [BP+DI] 3 4 -1 SREG [DI+BP] 4 4 -1 SREG [SI] 5 4 -1 SREG [DI] 6 4 -1 SREG [BP] 7 4 -1 SREG [BX] --> ( 8086 Assembler -- segment reg. definitions ) 0 5 -1 SREG ES 0 5 -1 SREG ES, 1 5 -1 SREG CS 1 5 -1 SREG CS, 2 5 -1 SREG SS 2 5 -1 SREG SS, 3 5 -1 SREG DS 3 5 -1 SREG DS, --> ( 8086 Assembler -- dest. reg. definitions ) 0 3 1 DREG AX, 0 2 0 DREG AL, 4 2 0 DREG AH, 1 3 1 DREG CX, 1 2 0 DREG CL, 5 2 0 DREG CH, 2 3 1 DREG DX, 2 2 0 DREG DL, 6 2 0 DREG DH, 3 3 1 DREG BX, 3 2 0 DREG BL, 7 2 0 DREG BH, 4 3 1 DREG SP, 5 3 1 DREG BP, 6 3 1 DREG SI, 7 3 1 DREG DI, 0 4 -1 DREG [BX+SI], 0 4 -1 DREG [SI+BX], 1 4 -1 DREG [BX+DI], 1 4 -1 DREG [DI+BX], 2 4 -1 DREG [BP+SI], 2 4 -1 DREG [SI+BP], 3 4 -1 DREG [BP+DI], 3 4 -1 DREG [DI+BP], 4 4 -1 DREG [SI], 5 4 -1 DREG [DI], 6 4 -1 DREG [BP], 7 4 -1 DREG [BX], --> ( 8086 Assembler -- misc. operators ) : ?W <W> @ ; ( get word/byte flag ) : ?TD <TD> @ ; ( get dest. addr. type ) : ?TS <TS> @ ; ( source addr. type ) : ?RD <RD> @ ; ( dest. reg. code ) : ?RS <RS> @ ; ( source reg. code ) : ?OD <OD> @ ; ( dest. displacement ) : ?OS <OS> @ ; ( source displacement ) : +D <D> @ 2 * + ; ( merge direction flag ) : +W <W> @ + ; ( merge word/byte flag ) : +RD <RD> @ + ; ( merge dest. reg. code ) : +RS <RS> @ + ; ( merge source reg. code ) : MOD1 3F AND 40 OR ; ( set mod field to 01 ) : MOD2 3F AND 80 OR ; ( set mod field to 10 ) : MOD3 3F AND C0 OR ; ( set mod field to 11 ) --> ( 8086 Assembler -- misc. operators ) ( addressing modes ) 0 CONSTANT DIRECT 1 CONSTANT IMMED 2 CONSTANT REG8 3 CONSTANT REG16 4 CONSTANT INDEXED 5 CONSTANT SEGREG ( initialize variables ) : RESET 0 <#> ! 0 <W> ! 0 <OS> ! 0 <RD> ! 0 <TD> ! 0 <TS> ! 0 <OD> ! !<SP> 0 <D> ! 0 <WD> ! 0 <RS> ! ; ( initalize direction flag for mem/reg instr. ) : DSET ?TS INDEXED = <D> ! ; ( set direction flag true ) : Dt 1 <D> ! ; --> ( 8086 Assembler -- misc. operators ) ( calculate and store relative offset for branches and loops ) ( issue error message if target out of range ) : OFFSET8, HERE 1+ - DUP ABS 07F > ERR23 C, ; ( calculate and store 16-bit offset for JMP and CALL ) : OFFSET16, HERE 2+ - , ; ( calculate and store offset for mem/reg instructions ) : DISP, <D> @ IF ?OS ELSE ?OD THEN DUP ( get displ. ) IF ( disp>0 ) DUP ABS 07F > ( check size ) IF ( disp>127 ) SWAP MOD2 C, , ( two bytes ) ELSE SWAP MOD1 C, C, THEN ( one byte ) ELSE DROP DUP 7 AND 6 = ( no displ. ) IF ( [BP] ) MOD1 C, 0 C, ( except BP ) ELSE C, THEN ( always gets ) THEN ; ( one byte ) --> ( 8086 Assembler -- instruction groups 1-3 ) ( single byte instructions without operands ) : 1MI <BUILDS C, DOES> C@ C, RESET ; ( conditional jumps and loops: 1 byte + offset ) : 2MI <BUILDS C, DOES> C@ C, OFFSET8, RESET ; ( string instructions ) : 3MI <BUILDS C, DOES> C@ +W C, RESET ; --> ( 8086 Assembler -- instruction group 4 ) ( register PUSH and POP ) : 4MI <BUILDS C, C, DOES> ?TS CASE ( operand type ) REG16 OF 1+ C@ +RS C, ENDOF SEGREG OF C@ ?RS 8 * + C, ENDOF 1 ERR28 ( illegal operand ) ENDCASE RESET ; --> ( 8086 Assembler -- instruction group 5 ) ( intrasegment JMP and CALL, 16-bit offset or reg/mem ) ( intersegment long JMP's and the short JMP are not supported ) : 5MI <BUILDS C, C, DOES> ?TS CASE ( operand type ) DIRECT OF 1+ C@ C, OFFSET16, ENDOF REG16 OF 0FF C, C@ MOD3 +RS C, ENDOF INDEXED OF DSET 0FF C, C@ +RS DISP, ENDOF 1 ERR28 ENDCASE RESET ; --> ( 8086 Assembler -- instruction group 6 ) ( IN and OUT ) : 6MI <BUILDS C, C, DOES> DUP C@ 2 AND IF ( OUT ) ?TD ?TS ELSE ?TS ?TD THEN REG16 = <W> ! REG16 = IF ( via DX ) 1+ C@ +W C, ELSE C@ +W C, C, ( immediate port # ) THEN RESET ; --> ( 8086 Assembler -- instruction group 7 ) ( ADC, ADD, AND, CMP, OR, SBB, SUB, and XOR ) : 7MI <BUILDS C, C, C, DOES> ?TS IMMED = IF ( immediate data ) 1+ DUP 1+ C@ +W C, ?TD CASE REG8 OF C@ MOD3 +RD C, C, ENDOF REG16 OF C@ MOD3 +RD C, , ENDOF INDEXED OF DSET C@ +RD DISP, ?W IF , ELSE C, THEN ENDOF ERR28 ENDCASE ELSE ( source = reg/mem ) DSET C@ +D +W C, --> ( 8086 Assembler -- instruction group 7, cont. ) ?TD CASE ( check destination type ) REG8 OF ( 8-bit dest. reg. ) ?TS CASE ( 8-bit or indexed source ) REG8 OF ?RS 8 * +RD MOD3 C, ENDOF INDEXED OF ?RD 8 * +RS DISP, ENDOF ERR28 ENDCASE ENDOF REG16 OF ( 16-bit dest. reg. ) ?TS CASE ( 16-bit or indexed source ) REG16 OF ?RS 8 * +RD MOD3 C, ENDOF INDEXED OF ?RD 8 * +RS DISP, ENDOF ERR28 ENDCASE ENDOF --> ( 8086 Assembler -- instruction group 7, cont. ) INDEXED OF ( indexed dest. ) ?TS CASE ( 8 or 16-bit source ) REG8 OF ?RS 8 * +RD DISP, ENDOF REG16 OF ?RS 8 * +RD DISP, ENDOF ERR28 ENDCASE ENDOF ERR28 ENDCASE THEN RESET ; --> ( 8086 Assembler -- instruction group 8 ) ( DIV, IDIV, IMUL, MUL, NEG, and NOT ) : 8MI <BUILDS C, C, DOES> DUP 1+ C@ +W C, ?TS CASE ( source operand type ) REG8 OF C@ +RS MOD3 C, ENDOF REG16 OF C@ +RS MOD3 C, ENDOF INDEXED OF DSET C@ +RS DISP, ENDOF ERR28 ENDCASE RESET ; --> ( 8086 Assembler -- Instruction group 9 ) ( various shift instructions ) : 9MI <BUILDS C, C, DOES> DUP 1+ C@ <WD> @ + ( word/byte flag ) ?TS 1 > IF 2+ THEN C, ( shift 1 or count in CL? ) ?TD CASE ( 8,16-bit, or indexed dest. ) REG8 OF C@ MOD3 +RD C, ENDOF REG16 OF C@ MOD3 +RD C, ENDOF INDEXED OF DSET C@ +RD DISP, ENDOF ERR28 ( direct, immed. or seg. reg. illegal ) ENDCASE ?TS 2 < IF DROP THEN RESET ; ( clean up stack ) --> ( 8086 Assembler -- instruction group 10 ) ( 2-byte simple instructions without operands ) : 10MI <BUILDS C, C, DOES> DUP C@ SWAP 1+ C@ C, C, RESET ; --> ( 8086 Assembler -- instruction group 11 ) ( INC and DEC ) : 11MI <BUILDS C, C, DOES> ?TS CASE ( source operand type ) REG8 OF 0FE C, 1+ C@ MOD3 +RS C, ENDOF REG16 OF C@ +RS C, ENDOF INDEXED OF DSET 0FE +W C, 1+ C@ +RS DISP, ENDOF ERR28 ( direct, immed. or seg. reg. illegal ) ENDCASE RESET ; --> ( 8086 Assembler -- instruction group 12 ) ( MOV instructions reg./reg., reg./mem., reg./immed. ) : 12MI <BUILDS DOES> DROP DSET ?TD CASE ( dest. operand type ) DIRECT OF ?TS CASE ( source operand type ) REG8 OF ?RS IF 088 C, ?RS 8 * 6 + C, , ELSE 0A2 +W C, , THEN ENDOF REG16 OF ?RS IF 089 C, ?RS 8 * 6 + C, , ELSE 0A2 +W C, , THEN ENDOF SEGREG OF 08C C, ?RS 8 * 6 + C, , ENDOF ERR28 ENDCASE ENDOF --> ( 8086 Assembler -- instruction group 12, cont. ) REG8 OF ?TS CASE ( 8-bit general. reg. dest. ) ( source = memory direct ) DIRECT OF ?RD IF 08A C, ?RD 8 * 6 + C, , ELSE 0A0 +W C, , ENDIF ENDOF ( source = immediate data ) IMMED OF 0B0 +RD C, C, ENDOF ( source = 8-bit gen. reg. ) REG8 OF Dt 88 +D C, ?RD 8 * +RS MOD3 C, ENDOF REG16 OF 1 ERR2D ENDOF ( source = indexed address ) INDEXED OF 88 +D +W C, ?RD 8 * +RS DISP, ENDOF 1 ERR28 ENDCASE ENDOF --> ( 8086 Assembler -- instruction group 12, cont. ) REG16 OF ?TS CASE ( 16-bit gen. reg. dest. ) ( source = memory direct ) DIRECT OF ?RD IF 08B C, ?RD 8 * 6 + C, , ELSE 0A0 +W C, , ENDIF ENDOF ( source = immediate data ) IMMED OF 0B8 +RD C, , ENDOF ( source = 16-bit gen. reg. ) REG16 OF Dt 88 +W +D C, ?RD 8 * +RS MOD3 C, ENDOF ( source = indexed address ) INDEXED OF 88 +D +W C, ?RD 8 * +RS DISP, ENDOF ( source = seg. reg. ) SEGREG OF 8C C, ?RS 8 * +RD MOD3 C, ENDOF 1 ERR28 ENDCASE ENDOF --> ( 8086 Assembler -- instruction group 12, cont. ) INDEXED OF ?TS CASE ( indexed dest. ) ( source = immediate data ) IMMED OF 0C6 +W C, ?RD DISP, ?W IF , ELSE C, THEN ENDOF ( source = 8-bit gen. reg. ) REG8 OF 88 +D +W C, ?RS 8 * +RD DISP, ENDOF ( source = 16-bit gen. reg. ) REG16 OF 88 +D +W C, ?RS 8 * +RD DISP, ENDOF ( source = seg. reg. ) SEGREG OF 08C C, ?RS 8 * +RD DISP, ENDOF 1 ERR28 ENDCASE ENDOF --> ( 8086 Assembler -- instruction group 12, cont. ) SEGREG OF ?TS CASE ( dest. = seg. reg. ) ( source = memory direct ) DIRECT OF 08E C, ?RD 8 * 6 + C, , ENDOF ( source = 16-bit gen. reg. ) REG16 OF 08E C, ?RD 8 * +RS MOD3 C, ENDOF ( source = indexed addr. ) INDEXED OF 08E C, ?RD 8 * +RS DISP, ENDOF 1 ERR28 ENDCASE ENDOF 1 ERR28 ( illegal dest. types ) ENDCASE RESET ; --> ( 8086 Assembler -- instruction group 13 ) ( XCHG instructions ) : 13MI <BUILDS DOES> DROP DSET ?TD CASE ( if missing dest. reg. assume 16-bit reg. <-> acc. ) DIRECT OF ?TS REG16 = IF 90 +RS C, ELSE 1 ERR28 ENDIF ENDOF ( xchg of 8-bit gen. reg. with reg/mem ) REG8 OF 86 +W C, ?TS CASE ( source type ) REG8 OF ?RD 8 * +RS MOD3 C, ENDOF INDEXED OF ?RD 8 * +RS DISP, ENDOF 1 ERR28 ENDCASE ENDOF --> ( 8086 Assembler -- instruction group 13, cont. ) ( xchg 16-bit reg. with reg/mem ) REG16 OF 86 +W C, ?TS CASE REG16 OF ?RD 8 * +RS MOD3 C, ENDOF INDEXED OF ?RD 8 * +RS DISP, ENDOF 1 ERR28 ENDCASE ENDOF 1 ERR28 ENDCASE RESET ; --> ( 8086 Assembler -- instruction group 14 ) ( special routine for TEST instruction ) : 14MI <BUILDS DOES> DROP ?TS CASE IMMED OF 1 ERR28 ENDOF ( direct addr. illegal ) DIRECT OF 0F6 +W C, ?TD CASE ( immediate data ) REG8 OF ?RD MOD3 C, ?W IF , ELSE C, THEN ENDOF REG16 OF ?RD MOD3 C, ?W IF , ELSE C, THEN ENDOF INDEXED OF ?RD DISP, ?W IF , ELSE C, THEN ENDOF 1 ERR28 ENDCASE ENDOF SEGREG OF 1 ERR28 ENDOF ( seg. reg. illegal ) ?TD REG8 < ?TD REG16 > OR ERR28 ( others illegal ) 84 +W C, ?RD 8 * +RS ( TEST reg. with reg/mem ) ?TS INDEXED < IF MOD3 C, ( source = gen. reg. ) ELSE DISP, THEN ( source = indexed ) ENDCASE RESET ; --> ( 8086 Assembler -- instructions AAA to INC ) 37 1MI AAA 80 38 38 7MI CMP D5 0A 10MI AAD A6 3MI CMPS D4 0A 10MI AAM 99 1MI CWD 3F 1MI AAS 27 1MI DAA 80 10 10 7MI ADC 2F 1MI DAS 80 00 00 7MI ADD 08 48 11MI DEC 80 20 20 7MI AND F6 30 8MI DIV E8 10 5MI CALL ( ESC ) 98 1MI CBW F4 1MI HLT F8 1MI CLC F6 38 8MI IDIV FC 1MI CLD F6 28 8MI IMUL FA 1MI CLI EC E4 6MI IN F5 1MI CMC 00 40 11MI INC --> ( 8086 Assembler -- instructions INT to JNS ) ( INT ) E9 20 5MI JMP CE 1MI INTO 76 2MI JNA CF 1MI IRET 72 2MI JNAE 77 2MI JA 73 2MI JNB 73 2MI JAE 77 2MI JNBE 72 2MI JB 75 2MI JNE 76 2MI JBE 7E 2MI JNG E3 2MI JCXZ 7C 2MI JNGE 74 2MI JE 7D 2MI JNL 7F 2MI JG 7F 2MI JNLE 7D 2MI JGE 71 2MI JNO 7C 2MI JL 7B 2MI JNP 7E 2MI JLE 79 2MI JNS --> ( 8086 Assembler -- instructions JNZ to OUT ) 75 2MI JNZ E2 2MI LOOP 70 2MI JO E1 2MI LOOPE 7A 2MI JP E0 2MI LOOPNE 7A 2MI JPE E0 2MI LOOPNZ 7B 2MI JPO E1 2MI LOOPZ 78 2MI JS 12MI MOV 74 2MI JZ A4 3MI MOVS 9F 1MI LAHF F6 20 8MI MUL ( LDS ) F6 18 8MI NEG 8A 8A 8A 7MI LEA 90 1MI NOP ( LES ) F6 10 8MI NOT F0 1MI LOCK 80 08 08 7MI OR AC 3MI LODS EE E6 6MI OUT --> ( 8086 Assembler -- instructions POP to STOS ) 58 07 4MI POP D0 08 9MI ROR 9D 1MI POPF 9E 1MI SAHF 50 06 4MI PUSH D0 38 9MI SAR 9C 1MI PUSHF 80 18 18 7MI SBB D0 10 9MI RCL AE 3MI SCAS D0 18 9MI RCR ( SEG ) F3 1MI REP D0 20 9MI SAL F3 1MI REPE D0 20 9MI SHL F2 1MI REPNE D0 28 9MI SHR F2 1MI REPNZ F9 1MI STC F3 1MI REPZ FD 1MI STD C3 1MI RET FB 1MI STI D0 00 9MI ROL AA 3MI STOS --> ( 8086 Assembler -- instructions SUB to XOR ) 80 28 28 7MI SUB 14MI TEST 9B 1MI WAIT 13MI XCHG D7 1MI XLAT 80 30 30 7MI XOR : INT ( type -- ;added 7-7-83 jes ) ?TS ( source operand type ) REG8 < IF ( immed. or direct int type ) DUP 3 = IF ( breakpoint int. ) 0CC C, DROP ELSE 0CD C, C, THEN ELSE DROP 0 <TS> ! 1 ERR28 THEN RESET ; --> ( 8086 Assembler -- control structures ) ( IF...[ELSE]...ENDIF provides conditional execution ) ( based on the state of the CPU's Z flag ) : IF 074 C, 0 C, HERE RESET ; ( JZ ) : ELSE 0EB C, 0 C, DUP ( JMP ) HERE SWAP - DUP ABS 07F > ERR23 SWAP 1- C! HERE RESET ; : ENDIF DUP HERE SWAP - DUP ABS 07F > ERR23 SWAP 1- C! RESET ; ( resolve branches ) ( BEGIN...UNTIL construct provides controlled repetitive ) ( execution, exit from loop if Z flag is false ) : BEGIN HERE RESET ; ( leaves address ) : UNTIL 074 C, HERE 1+ - DUP ABS 07F > ERR23 C, RESET ; --> ( 8086 Assembler -- special operators ) ( force byte addressing mode ) : BYTE 0 <W> ! 0 <WD> ! ; ( force word addressing mode ) : WORD 1 <W> ! 0 <WD> ! ; ( set immediate data flag ) : # 1 <#> ! 1 <TS> ! ; ( comma delimits dest. field for direct addressing ) : , DEPTH 1 < ERR23 0 <TD> ! ; --> ( 8086 Assembler -- loading termination ) 012A CONSTANT @DPUSH 012B CONSTANT @APUSH 012C CONSTANT @NEXT ( CODE, ;CODE, NEXT delimit a code definition ) : NEXT 0E9 C, @NEXT OFFSET16, RESET ?EXEC ?CSP SMUDGE [COMPILE] FORTH ; IMMEDIATE FORTH DEFINITIONS : ;CODE ?CSP COMPILE (;CODE) [COMPILE] [ ASSEMBLER RESET FORTH [COMPILE] ASSEMBLER ; IMMEDIATE : CODE ?EXEC !CSP CREATE ASSEMBLER RESET FORTH [COMPILE] ASSEMBLER ; IMMEDIATE DECIMAL ;S