VolksForth/sources/msdos/f83asm.fb.src

579 lines
37 KiB
Plaintext
Raw Normal View History

2017-04-23 22:25:49 +00:00
Screen 0 not modified
0 \ 8086 Assembler cas 10nov05
1
2 The 8086 Assembler was written by Mike Perry.
3 To create and assembler language definition, use the defining
4 word CODE. It must be terminated with either END-CODE or
5 its synonym C;. How the assembler operates is a very
6 interesting example of the power of CREATE DOES> Basically
7 the instructions are categorized and a defining word is
8 created for each category. When the nmemonic for the
9 instruction is interpreted, it compiles itself.
10
11 Adapted for volksFORTH by Klaus Schleisiek
12
13 No really tested, but
14 CODE TEST TOS PUSH 1 # TOS MOV NEXT END-CODE
15 works!
Screen 1 not modified
0 \ 8086 Assembler ks cas 10nov05
1 Onlyforth
2 Vocabulary Assembler
3 : octal 8 Base ! ;
4
5 decimal 1 14 +THRU clear
6
7 Onlyforth
8
9 : Code Create [ Assembler ] here dup 2- ! Assembler ;
10
11 CR .( 8086 Assembler loaded )
12 Onlyforth
13
14
15
Screen 2 not modified
0 \ 8086 Assembler ks 19 m<>r 88
1 : LABEL CREATE ASSEMBLER ;
2 \ 232 CONSTANT DOES-OP
3 \ 3 CONSTANT DOES-SIZE
4 \ : DOES? ( IP -- IP' F )
5 \ DUP DOES-SIZE + SWAP C@ DOES-OP = ;
6 ASSEMBLER ALSO DEFINITIONS
7 : C; ( -- ) END-CODE ;
8 OCTAL
9 DEFER C, FORTH ' C, ASSEMBLER IS C,
10 DEFER , FORTH ' , ASSEMBLER IS ,
11 DEFER HERE FORTH ' HERE ASSEMBLER IS HERE
12 DEFER ?>MARK
13 DEFER ?>RESOLVE
14 DEFER ?<MARK
15 DEFER ?<RESOLVE
Screen 3 not modified
0 \ 8086 Assembler Register Definitions ks 19 m<>r 88
1 | : REG 11 * SWAP 1000 * OR CONSTANT ;
2 | : REGS ( MODE N -- ) SWAP 0 DO DUP I REG LOOP DROP ;
3
4 10 0 REGS AL CL DL BL AH CH DH BH
5 10 1 REGS AX CX DX BX SP BP SI DI
6 10 2 REGS [BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI] [BP] [BX]
7 4 2 REGS [SI+BX] [DI+BX] [SI+BP] [DI+BP]
8 4 3 REGS ES CS SS DS
9 3 4 REGS # #) S#)
10
11 BP Constant UP [BP] Constant [UP] \ User Pointer
12 SI CONSTANT IP [SI] CONSTANT [IP] ( INTERPRETER POINTER )
13 DI Constant W [DI] Constant [W] \ WORKING REGISTER
14 BX Constant RP [BX] Constant [RP] \ Return Stack Pointer
15 DX Constant TOS \ Top Of Stack im Register
Screen 4 not modified
0 \ Addressing Modes ks 19 m<>r 88
1 | : MD CREATE 1000 * , DOES> @ SWAP 7000 AND = 0<> ;
2 | 0 MD R8? | 1 MD R16? | 2 MD MEM? | 3 MD SEG? | 4 MD #?
3 | : REG? ( n -- f ) 7000 AND 2000 < 0<> ;
4 | : BIG? ( N -- F ) ABS -200 AND 0<> ;
5 | : RLOW ( n1 -- n2 ) 7 AND ;
6 | : RMID ( n1 -- n2 ) 70 AND ;
7 | VARIABLE SIZE SIZE ON
8 : BYTE ( -- ) SIZE OFF ;
9 | : OP, ( N OP -- ) OR C, ;
10 | : W, ( OP MR -- ) R16? 1 AND OP, ;
11 | : SIZE, ( OP -- OP' ) SIZE @ 1 AND OP, ;
12 | : ,/C, ( n f -- ) IF , ELSE C, THEN ;
13 | : RR, ( MR1 MR2 -- ) RMID SWAP RLOW OR 300 OP, ;
14 | VARIABLE LOGICAL
15 | : B/L? ( n -- f ) BIG? LOGICAL @ OR ;
Screen 5 not modified
0 \ Addressing ks 19 m<>r 88
1 | : MEM, ( DISP MR RMID -- ) OVER #) =
2 IF RMID 6 OP, DROP ,
3 ELSE RMID OVER RLOW OR -ROT [BP] = OVER 0= AND
4 IF SWAP 100 OP, C, ELSE SWAP OVER BIG?
5 IF 200 OP, , ELSE OVER 0=
6 IF C, DROP ELSE 100 OP, C,
7 THEN THEN THEN THEN ;
8 | : WMEM, ( DISP MEM REG OP -- ) OVER W, MEM, ;
9 | : R/M, ( MR REG -- )
10 OVER REG? IF RR, ELSE MEM, THEN ;
11 | : WR/SM, ( R/M R OP -- ) 2 PICK DUP REG?
12 IF W, RR, ELSE DROP SIZE, MEM, THEN SIZE ON ;
13 | VARIABLE INTER
14 : FAR ( -- ) INTER ON ;
15 | : ?FAR ( n1 -- n2 ) INTER @ IF 10 OR THEN INTER OFF ;
Screen 6 not modified
0 \ Defining Words to Generate Op Codes ks 19 m<>r 88
1 | : 1MI CREATE C, DOES> C@ C, ;
2 | : 2MI CREATE C, DOES> C@ C, 12 C, ;
3 | : 3MI CREATE C, DOES> C@ C, HERE - 1-
4 DUP -200 177 uWITHIN NOT ABORT" Branch out of Range" C, ;
5 | : 4MI CREATE C, DOES> C@ C, MEM, ;
6 | : 5MI CREATE C, DOES> C@ SIZE, SIZE ON ;
7 | : 6MI CREATE C, DOES> C@ SWAP W, ;
8 | : 7MI CREATE C, DOES> C@ 366 WR/SM, ;
9 | : 8MI CREATE C, DOES> C@ SWAP R16? 1 AND OR SWAP # =
10 IF C, C, ELSE 10 OR C, THEN ;
11 | : 9MI CREATE C, DOES> C@ OVER R16?
12 IF 100 OR SWAP RLOW OP, ELSE 376 WR/SM, THEN ;
13 | : 10MI CREATE C, DOES> C@ OVER CL =
14 IF NIP 322 ELSE 320 THEN WR/SM, ;
15
Screen 7 not modified
0 \ Defining Words to Generate Op Codes ks 19 m<>r 88
1 | : 11MI CREATE C, C, DOES> OVER #) =
2 IF NIP C@ INTER @
3 IF 1 AND IF 352 ELSE 232 THEN C, SWAP , , INTER OFF
4 ELSE SWAP HERE - 2- SWAP 2DUP 1 AND SWAP BIG? NOT AND
5 IF 2 OP, C, ELSE C, 1- , THEN THEN
6 ELSE OVER S#) = IF NIP #) SWAP THEN
7 377 C, 1+ C@ ?FAR R/M, THEN ;
8 | : 12MI CREATE C, C, C, DOES> OVER REG?
9 IF C@ SWAP RLOW OP, ELSE 1+ OVER SEG?
10 IF C@ RLOW SWAP RMID OP,
11 ELSE COUNT SWAP C@ C, MEM,
12 THEN THEN ;
13 | : 14MI CREATE C, DOES> C@
14 DUP ?FAR C, 1 AND 0= IF , THEN ;
15
Screen 8 not modified
0 \ Defining Words to Generate Op Codes ks 19 m<>r 88
1 | : 13MI CREATE C, C, DOES> COUNT >R C@ LOGICAL ! DUP REG?
2 IF OVER REG?
3 IF R> OVER W, SWAP RR, ELSE OVER DUP MEM? SWAP #) = OR
4 IF R> 2 OR WMEM, ELSE ( # ) NIP DUP RLOW 0= ( ACC? )
5 IF R> 4 OR OVER W, R16? ,/C,
6 ELSE OVER B/L? OVER R16? 2DUP AND
7 -ROT 1 AND SWAP NOT 2 AND OR 200 OP,
8 SWAP RLOW 300 OR R> OP, ,/C,
9 THEN THEN THEN
10 ELSE ( MEM ) ROT DUP REG?
11 IF R> WMEM,
12 ELSE ( # ) DROP 2 PICK B/L? DUP NOT 2 AND 200 OR SIZE,
13 -ROT R> MEM, SIZE @ AND ,/C, SIZE ON
14 THEN THEN ;
15
Screen 9 not modified
0 \ Instructions ks 19 m<>r 88
1 : TEST ( source dest -- ) DUP REG?
2 IF OVER REG?
3 IF 204 OVER W, SWAP RR, ELSE OVER DUP MEM? SWAP #) = OR
4 IF 204 WMEM, ELSE ( # ) NIP DUP RLOW 0= ( ACC? )
5 IF 250 OVER W,
6 ELSE 366 OVER W, DUP RLOW 300 OP,
7 THEN R16? ,/C, THEN THEN
8 ELSE ( MEM ) ROT DUP REG?
9 IF 204 WMEM,
10 ELSE ( # ) DROP 366 SIZE, 0 MEM, SIZE @ ,/C, SIZE ON
11 THEN THEN ;
12
13
14
15
Screen 10 not modified
0 \ Instructions ks 19 m<>r 88
1 HEX
2 : ESC ( source ext-opcode -- ) RLOW 0D8 OP, R/M, ;
3 : INT ( N -- ) 0CD C, C, ;
4 : SEG ( SEG -- ) RMID 26 OP, ;
5 : XCHG ( MR1 MR2 -- ) DUP REG?
6 IF DUP AX =
7 IF DROP RLOW 90 OP, ELSE OVER AX =
8 IF NIP RLOW 90 OP, ELSE 86 WR/SM, THEN THEN
9 ELSE ROT 86 WR/SM, THEN ;
10
11 : CS: CS SEG ;
12 : DS: DS SEG ;
13 : ES: ES SEG ;
14 : SS: SS SEG ;
15
Screen 11 not modified
0 \ Instructions ks 19 m<>r 88
1 : MOV ( S D -- ) DUP SEG?
2 IF 8E C, R/M, ELSE DUP REG?
3 IF OVER #) = OVER RLOW 0= AND
4 IF A0 SWAP W, DROP , ELSE OVER SEG?
5 IF SWAP 8C C, RR, ELSE OVER # =
6 IF NIP DUP R16? SWAP RLOW OVER 8 AND OR B0 OP, ,/C,
7 ELSE 8A OVER W, R/M, THEN THEN THEN
8 ELSE ( MEM ) ROT DUP SEG?
9 IF 8C C, MEM, ELSE DUP # =
10 IF DROP C6 SIZE, 0 MEM, SIZE @ ,/C,
11 ELSE OVER #) = OVER RLOW 0= AND
12 IF A2 SWAP W, DROP , ELSE 88 OVER W, R/M,
13 THEN THEN THEN THEN THEN SIZE ON ;
14
15
Screen 12 not modified
0 \ Instructions 12Oct83map
1 37 1MI AAA D5 2MI AAD D4 2MI AAM 3F 1MI AAS
2 0 10 13MI ADC 0 00 13MI ADD 2 20 13MI AND 10 E8 11MI CALL
3 98 1MI CBW F8 1MI CLC FC 1MI CLD FA 1MI CLI
4 F5 1MI CMC 0 38 13MI CMP A6 5MI CMPS 99 1MI CWD
5 27 1MI DAA 2F 1MI DAS 08 9MI DEC 30 7MI DIV
6 ( ESC ) F4 1MI HLT 38 7MI IDIV 28 7MI IMUL
7 E4 8MI IN 00 9MI INC ( INT ) 0CE 1MI INTO
8 0CF 1MI IRET 77 3MI JA 73 3MI JAE 72 3MI JB
9 76 3MI JBE E3 3MI JCXZ 74 3MI JE 7F 3MI JG
10 7D 3MI JGE 7C 3MI JL 7E 3MI JLE 20 E9 11MI JMP
11 75 3MI JNE 71 3MI JNO 79 3MI JNS 70 3MI JO
12 7A 3MI JPE 7B 3MI JPO 78 3MI JS 9F 1MI LAHF
13 C5 4MI LDS 8D 4MI LEA C4 4MI LES F0 1MI LOCK
14 0AC 6MI LODS E2 3MI LOOP E1 3MI LOOPE E0 3MI LOOPNE
15
Screen 13 not modified
0 \ Instructions 12Apr84map
1 ( MOV ) 0A4 5MI MOVS 20 7MI MUL 18 7MI NEG
2 90 1MI NOP 10 7MI NOT 2 08 13MI OR E6 8MI OUT
3 8F 07 58 12MI POP 9D 1MI POPF
4 0FF 36 50 12MI PUSH 9C 1MI PUSHF
5 10 10MI RCL 18 10MI RCR
6 F2 1MI REP F2 1MI REPNZ F3 1MI REPZ
7 C3 14MI RET 00 10MI ROL 8 10MI ROR 9E 1MI SAHF
8 38 10MI SAR 0 18 13MI SBB 0AE 5MI SCAS ( SEG )
9 20 10MI SHL 28 10MI SHR F9 1MI STC FD 1MI STD
10 FB 1MI STI 0AA 6MI STOS 0 28 13MI SUB ( TEST )
11 9B 1MI WAIT ( XCHG ) D7 1MI XLAT 2 30 13MI XOR
12 C2 14MI +RET
13
14
15
Screen 14 not modified
0 \ Structured Conditionals ks 19 m<>r 88
1 : A?>MARK ( -- f addr ) TRUE HERE 0 C, ;
2 : A?>RESOLVE ( f addr -- ) HERE OVER 1+ - SWAP C! true ?pairs ;
3 : A?<MARK ( -- f addr ) TRUE HERE ;
4 : A?<RESOLVE ( f addr -- ) HERE 1+ - C, true ?pairs ;
5 ' A?>MARK ASSEMBLER IS ?>MARK
6 ' A?>RESOLVE ASSEMBLER IS ?>RESOLVE
7 ' A?<MARK ASSEMBLER IS ?<MARK
8 ' A?<RESOLVE ASSEMBLER IS ?<RESOLVE
9 HEX
10 75 CONSTANT 0= 74 CONSTANT 0<> 79 CONSTANT 0<
11 78 CONSTANT 0>= 7D CONSTANT < 7C CONSTANT >=
12 7F CONSTANT <= 7E CONSTANT > 73 CONSTANT U<
13 72 CONSTANT U>= 77 CONSTANT U<= 76 CONSTANT U>
14 71 CONSTANT OV
15 DECIMAL
Screen 15 not modified
0 \ Structured Conditionals cas 10nov05
1 HEX
2 : IF C, ?>MARK ;
3 : THEN ?>RESOLVE ;
4 : ELSE 0EB IF 2SWAP THEN ;
5 : BEGIN ?<MARK ;
6 : UNTIL C, ?<RESOLVE ;
7 : AGAIN 0EB UNTIL ;
8 : WHILE IF ;
9 : REPEAT 2SWAP AGAIN THEN ;
10 : DO # CX MOV HERE ;
11 : Next AX lods AX DI xchg 0 [DI] jmp
12 [ Assembler ] here next-link @ , next-link ! ;
13 \ volksFORTH uses "inline" Next and a linked list, to find all
14 \ existing NEXT for the debugger.
15 DECIMAL
Screen 16 not modified
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 17 not modified
0 \ 8086 Assembler 08OCT83HHL
1 LABEL marks the start of a subroutine whose name returns its
2 address.
3 DOES-OP Is the op code of the call instruction used for DOES> U
4 C; A synonym for END-CODE
5
6 Deferring the definitions of the commas, marks, and resolves
7 allows the same assembler to serve for both the system and the
8 Meta-Compiler.
9
10
11
12
13
14
15
Screen 18 not modified
0 \ 8086 Assembler Register Definitions 12Oct83map
1
2 On the 8086, register names are cleverly defined constants.
3
4 The value returned by registers and by modes such as #) contains
5 both mode and register information. The instructions use the
6 mode information to decide how many arguments exist, and what to
7 assemble.
8 Like many CPUs, the 8086 uses many 3 bit fields in its opcodes
9 This makes octal ( base 8 ) natural for describing the registers
10
11
12 We redefine the Registers that FORTH uses to implement its
13 virtual machine.
14
15
Screen 19 not modified
0 \ Addressing Modes 16Oct83map
1 MD defines words which test for various modes.
2 R8? R16? MEM? SEG? #? test for mode equal to 0 thru 4.
3 REG? tests for any register mode ( 8 or 16 bit).
4 BIG? tests offsets size. True if won't fit in one byte.
5 RLOW mask off all but low register field.
6 RMID mask off all but middle register field.
7 SIZE true for 16 bit, false for 8 bit.
8 BYTE set size to 8 bit.
9 OP, for efficiency. OR two numbers and assemble.
10 W, assemble opcode with W field set for size of register.
11 SIZE, assemble opcode with W field set for size of data.
12 ,/C, assemble either 8 or 16 bits.
13 RR, assemble register to register instruction.
14 LOGICAL true while assembling logical instructions.
15 B/L? see 13MI
Screen 20 not modified
0 \ Addressing 16Oct83map
1 These words perform most of the addressing mode encoding.
2 MEM, handles memory reference modes. It takes a displacement,
3 a mode/register, and a register, and encodes and assembles
4 them.
5
6
7 WMEM, uses MEM, after packing the register size into the opcode
8 R/M, assembles either a register to register or a register to
9 or from memory mode.
10 WR/SM, assembles either a register mode with size field, or a
11 memory mode with size from SIZE. Default is 16 bit. Use BYTE
12 for 8 bit size.
13 INTER true if inter-segment jump, call, or return.
14 FAR sets INTER true. Usage: FAR JMP, FAR CALL, FAR RET.
15 ?FAR sets far bit, clears flag.
Screen 21 not modified
0 \ Defining Words to Generate Op Codes 12Oct83map
1 1MI define one byte constant instructions.
2 2MI define ascii adjust instructions.
3 3MI define branch instructions, with one byte offset.
4 4MI define LDS, LEA, LES instructions.
5 5MI define string instructions.
6 6MI define more string instructions.
7 7MI define multiply and divide instructions.
8 8MI define input and output instructions.
9
10 9MI define increment/decrement instructions.
11
12 10MI define shift/rotate instructions.
13 *NOTE* To allow both 'ax shl' and 'ax cl shl', if the register
14 on top of the stack is cl, shift second register by cl. If not,
15 shift top ( only) register by one.
Screen 22 not modified
0 \ Defining Words to Generate Op Codes 09Apr84map
1 11MI define calls and jumps.
2 notice that the first byte stored is E9 for jmp and E8 for call
3 so C@ 1 AND is zero for call, 1 for jmp.
4 syntax for direct intersegment: address segment #) FAR JMP
5
6
7
8 12MI define pushes and pops.
9
10
11
12
13 14MI defines returns.
14 RET FAR RET n +RET n FAR +RET
15
Screen 23 not modified
0 \ Defining Words to Generate Op Codes 16Oct83map
1 13MI define arithmetic and logical instructions.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 24 not modified
0 \ Instructions 16Oct83map
1 TEST bits in dest
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 25 not modified
0 \ Instructions 16Oct83map
1
2 ESC
3 INT assemble interrupt instruction.
4 SEG assemble segment instruction.
5 XCHG assemble register swap instruction.
6
7
8
9
10
11 CS: DS: ES: SS: assemble segment over-ride instructions.
12
13
14
15
Screen 26 not modified
0 \ Instructions 12Oct83map
1 MOV as usual, the move instruction is the most complicated.
2 It allows more addressing modes than any other, each of which
3 assembles something more or less unique.
4
5
6
7
8
9
10
11
12
13
14
15
Screen 27 not modified
0 \ Instructions 12Oct83map
1 Most instructions are defined on these two screens. Mnemonics in
2 parentheses are defined earlier or not at all.
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 28 not modified
0 \ Instructions 12Oct83map
1 Most instructions are defined on these two screens. Mnemonics in
2 parentheses are defined earlier or not at all.
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 29 not modified
0 \ Structured Conditionals 16Oct83map
1 A?>MARK assembler version of forward mark.
2 A?>RESOLVE assembler version of forward resolve.
3 A?<MARK assembler version of backward mark.
4 A?<RESOLVE assembler version of backward resolve.
5
6
7
8
9
10 These conditional test words leave the opcodes of conditional
11 branches to be used by the structured conditional words.
12 For example,
13 5 # CX CMP 0< IF AX BX ADD ELSE AX BX SUB THEN
14
15
Screen 30 not modified
0 \ Structured Conditionals 12Oct83map
1
2 One of the very best features of FORTH assemblers is the ability
3 to use structured conditionals instead of branching to nonsense
4 labels.
5
6
7
8
9
10
11
12
13
14
15
Screen 31 not modified
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 32 not modified
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Screen 33 not modified
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15