File:  [gforth] / gforth / arch / 8086 / asm.fs
Revision 1.2: download - view: text, annotated - select for diffs
Sun Dec 14 18:35:13 2008 UTC (15 years, 4 months ago) by pazsan
Branches: MAIN
CVS tags: HEAD
Common idiom for makefile.dos/os2

    1: \ **************************************************************
    2: \ File:         ASM.FS
    3: \                 8086-Assembler for PC
    4: \ Autor:        Klaus Kohl (adaptet from volksFORTH_PC)
    5: \ Log:          30.07.97 KK: file generated
    6: \
    7: \ * Register using see PRIMS.FS
    8: \ This file is in the public domain, like the original volksForth
    9: 
   10: 
   11: include asm/basic.fs
   12: 
   13: also  Assembler Definitions
   14: 
   15: : | ;
   16: : restrict ;
   17: : u2/   1 rshift ;
   18: : 8/    3 rshift ;
   19: : 8*    3 lshift ;
   20: : case? over = IF drop TRUE ELSE FALSE THEN ;
   21: : (0<   $8000 and  $8000 = ;
   22: 
   23: \ 8086 registers
   24:   0 Constant ax   1 Constant cx   2 Constant dx   3 Constant bx
   25:   4 Constant sp   5 Constant bp   6 Constant si   7 Constant di
   26:   8 Constant al   9 Constant cl  $a Constant dl  $b Constant bl
   27:  $c Constant ah  $d Constant ch  $e Constant dh  $f Constant bh
   28: 
   29:  $100 Constant es          $101 Constant cs
   30:  $102 Constant ss          $103 Constant ds
   31: 
   32: | Variable isize        ( specifies Size by prefix)
   33: | : Size: ( n -- )  Create c,  Does>  c@ isize ! ;
   34:   0 Size: byte      1 Size: word  word    2 Size: far
   35: 
   36: 
   37: \ 8086 Assembler  System variables              ( 10.08.90/kk )
   38: | Variable direction    \ 0 reg>EA, -1 EA>reg
   39: | Variable size         \ 1 word, 0 byte, -1 undefined
   40: | Variable displaced    \ 1 direct, 0 nothing, -1 displaced
   41: | Variable displacement
   42: 
   43: | : setsize              isize @  size ! ;
   44: | : long?   ( n -- f )   $FF80 and dup (0< invert ?exit $FF80 xor ;
   45: | : ?range               dup long? abort" out of range" ;
   46: | : wexit                rdrop word ;
   47: | : moderr               word true Abort" invalid" ;
   48: | : ?moderr ( f -- )     IF moderr THEN ;
   49: | : ?word                size @ 1- ?moderr ;
   50: | : far?    ( -- f )     size @ 2 = ;
   51: 
   52: 
   53: \ 8086 addressing modes                         ( 24.05.91/KK )
   54: | Create (ea  7 c, 0 c, 6 c, 4 c, 5 c,
   55: | : ()  ( 8b1 -- 8b2 )
   56:      3 - dup 4 u> over 1 = or ?moderr (ea + c@ ;
   57: 
   58:  -1 Constant #       $c6 Constant #)       -1 Constant c*
   59: 
   60:   : )   ( u1 -- u2 )
   61:      () 6 case? IF  0 $86 exit  THEN  $C0 or ;
   62:   : I)  ( u1 u2 -- u3 )  + 9 - dup 3 u> ?moderr $C0 or ;
   63: 
   64:   : D)  ( n u1 -- n u2 )
   65:      () over long? IF  $40  ELSE  $80  THEN or ;
   66:   : DI) ( n u1 u2 -- n u3 )
   67:      I) over long? IF  $80  ELSE  $40  THEN xor ;
   68: 
   69: \ 8086 Registers and addressing modes             ks 25 mai 87
   70: 
   71: | : displaced?  ( [n] u1 -- [n] u1 f )
   72:      dup #) = IF  1 exit  THEN
   73:      dup $C0 and dup $40 = swap $80 = or ;
   74: 
   75: | : displace    ( [n] u1 -- u1 )
   76:      displaced? ?dup
   77:      IF displaced @ ?moderr   displaced !   swap displacement ! THEN ;
   78: 
   79: | : rmode   ( u1 -- u2 )
   80:      1 size !  dup 8 and
   81:      IF  size off  $FF07 and  THEN ;
   82: 
   83: | : mmode?  ( 9b - 9b f)     dup $C0 and ;
   84: 
   85: | : rmode?  ( 8b1 - 8b1 f)   mmode? $C0 = ;
   86: 
   87: 
   88: \ 8086  decoding addressing modes                 ks 25 mai 87
   89: | : 2address  ( [n] source [displ] dest -- 15b / [n] 16b )
   90:      size on   displaced off   dup # = ?moderr   mmode?
   91:      IF  displace False  ELSE  rmode True  THEN  direction !
   92:      >r # case?  IF    r> $80C0 xor  size @  1+ ?exit  setsize exit
   93:                  THEN  direction @
   94:      IF  r> 8* >r mmode? IF  displace
   95:          ELSE  dup 8/ 1 and  size @ = ?moderr $FF07 and  THEN
   96:      ELSE  rmode 8*
   97:      THEN  r> or $C0 xor ;
   98: 
   99: | : 1address  ( [displ] 9b -- 9b )
  100:      # case? ?moderr   size on   displaced off   direction off
  101:      mmode? IF  displace setsize  ELSE  rmode  THEN  $C0 xor ;
  102: 
  103: 
  104: \ 8086 assembler                                  ks 25 mai 87
  105: | : immediate?   ( u -- u f )  dup (0< ;
  106: 
  107: | : nonimmediate ( u -- u )    immediate? ?moderr ;
  108: 
  109: | : r/m                        7 and ;
  110: 
  111: | : reg                        $38 and ;
  112: 
  113: | : ?akku  ( u -- u ff / tf )  dup r/m 0= dup IF nip THEN ;
  114: 
  115: | : smode? ( u1 -- u1 ff / u2 tf )  dup $F00 and
  116:      IF  dup $100 and IF  dup r/m 8* swap reg 8/
  117:                           or $C0 or  direction off
  118:                       THEN  True exit
  119:      THEN  False ;
  120: 
  121: \ 8086 Registers and addressing modes             ks 25 mai 87
  122: | : w,          size @ or  X c, ;
  123: 
  124: | : dw,         size @  or  direction @ IF  2 xor  THEN  X c, ;
  125: 
  126: | : ?word,  ( u1 f -- )  IF   X ,  exit  THEN  X c, ;
  127: 
  128: | : direct,
  129:      displaced @
  130:      IF  displacement @ dup long?  displaced @ 1+ or ?word, THEN ;
  131: 
  132: | : r/m,        X c,  direct, ;
  133: 
  134: | : data,       size @ ?word, ;
  135: 
  136: 
  137: 
  138: \ 8086 Arithmetic instructions                  ( 24.05.91/KK )
  139: | : Arith: ( code -- )
  140:     Create [ FORTH ] , [ Assembler ]
  141:     Does> @ >r   2address  immediate?
  142:      IF  rmode? IF  ?akku IF  r> size @
  143:                               IF  5 or  X c,  X ,  wexit  THEN
  144:                               4 or  X c,  X c, wexit  THEN THEN
  145:          r@ or  $80 size @ or   r> (0<
  146:          IF  size @ IF  2 pick long? 0= IF  2 or  size off  THEN
  147:          THEN       THEN  X c,  X c, direct,  data,  wexit
  148:      THEN  r> dw, r/m,  wexit ;
  149: 
  150:   $8000 Arith: add,     $0008 Arith: or,
  151:   $8010 Arith: adc,     $8018 Arith: sbb,
  152:   $0020 Arith: and,     $8028 Arith: sub,
  153:   $0030 Arith: xor,     $8038 Arith: cmp,
  154: 
  155: \ 8086 move push pop                            ( 24.05.91/KK )
  156:   : mov,
  157:      2address  immediate?
  158:      IF    rmode? IF  r/m $B0 or size @ IF  8 or  THEN
  159:                     X c, data,  wexit
  160:                 THEN  $C6 w, r/m, data, wexit
  161:      THEN  6 case? IF  $A2 dw, direct, wexit  THEN
  162:      smode? IF  $8C direction @ IF  2 or  THEN  X c,  r/m, wexit
  163:             THEN  $88 dw,  r/m,  wexit ;
  164: 
  165: | : pupo
  166:      >r  1address  ?word
  167:      smode? IF  reg 6 r> IF  1+  THEN  or  X c,  wexit  THEN
  168:      rmode? IF  r/m $50 or r> or  X c,  wexit  THEN
  169:      r> IF  $8F  ELSE  $30 or $FF  THEN  X c,  r/m, wexit ;
  170: 
  171:   : push, 0 pupo ;        : pop,  8 pupo ;
  172: 
  173: \ 8086 inc & dec , effective addresses          ( 24.05.91/KK )
  174: | : inc/dec
  175:      >r 1address   rmode?
  176:      IF  size @ IF  r/m $40 or r> or  X c,  wexit  THEN
  177:      THEN  $FE w, r> or r/m, wexit ;
  178: 
  179:   : dec,  8 inc/dec ;         : inc,  0 inc/dec ;
  180: 
  181: | : EA:  ( code -- )
  182:     Create c,
  183:     Does> >r 2address nonimmediate
  184:      rmode? direction @ 0= or ?moderr r> c@  X c,  r/m, wexit ;
  185: 
  186:   $c4 EA: les,  $8d EA: lea,  $c5 EA: lds,
  187: 
  188: 
  189: \ 8086  xchg  segment prefix                    ( 24.05.91/KK )
  190:   : xchg,
  191:    2address nonimmediate rmode?
  192:    IF  size @ IF  dup r/m 0=
  193:                   IF  8/ true  ELSE  dup $38 and 0=  THEN
  194:                   IF  r/m $90 or  X c,  wexit  THEN
  195:    THEN       THEN  $86 w, r/m, wexit ;
  196: 
  197: | : 1addr:  ( code -- )
  198:     Create c,
  199:     Does> c@ >r 1address $F6 w, r> or r/m, wexit ;
  200: 
  201:   $10 1addr: com,    $18 1addr: neg,
  202:   $20 1addr: mul,    $28 1addr: imul,
  203:   $38 1addr: idiv,   $30 1addr: div,
  204: 
  205:   : seg,  ( 8b -)
  206:      $100 xor dup $FFFC and ?moderr  8* $26 or X c, ;
  207: 
  208: \ 8086  test not neg mul imul div idiv          ( 24.05.91/KK )
  209:   : test,
  210:      2address immediate?
  211:      IF  rmode? IF  ?akku IF  $a8 w, data, wexit  THEN THEN
  212:          $f6 w, r/m, data, wexit
  213:      THEN  $84 w, r/m, wexit ;
  214: 
  215: | : in/out
  216:      >r 1address setsize
  217:      $C2 case? IF  $EC r> or w, wexit  THEN
  218:      6 - ?moderr  $E4 r> or w,  displacement @  X c,  wexit ;
  219: 
  220:   : out, 2 in/out ;          : in,  0 in/out ;
  221: 
  222:   : int,   3 case? IF  $cc  X c,  wexit  THEN  $cd  X c,   X c,  wexit ;
  223: 
  224: 
  225: \ 8086 shifts  and  string instructions         ( 24.05.91/KK )
  226: | : Shifts:  ( code -- )
  227:     Create c,
  228:     Does> c@ >r C* case? >r 1address
  229:         r> direction !  $D0 dw, r> or r/m, wexit ;
  230: 
  231:   $00 Shifts: rol,    $08 Shifts: ror,
  232:   $10 Shifts: rcl,    $18 Shifts: rcr,
  233:   $20 Shifts: shl,    $28 Shifts: shr,
  234:   $38 Shifts: sar,    ' shl, Alias sal,
  235: 
  236: | : Str:  ( code -- )   Create c,
  237:   Does> c@ setsize w, wexit ;
  238: 
  239:   $a6 Str: cmps,     $ac Str: lods,    $a4 Str: movs,
  240:   $ae Str: scas,     $aa Str: stos,
  241: 
  242: \ implied 8086 instructions                     ( 24.05.91/KK )
  243:   : Byte:  ( code -- )
  244:     Create c,
  245:     Does> c@  X c,  ;
  246:   : Word:  ( code -- )
  247:     Create [ FORTH ] , [ Assembler ]
  248:     Does> @  X ,  ;
  249: 
  250:  $37 Byte: aaa,   $ad5 Word: aad,   $ad4 Word: aam,
  251:  $3f Byte: aas,    $98 Byte: cbw,    $f8 Byte: clc,
  252:  $fc Byte: cld,    $fa Byte: cli,    $f5 Byte: cmc,
  253:  $99 Byte: cwd,    $27 Byte: daa,    $2f Byte: das,
  254:  $f4 Byte: hlt,    $ce Byte: into,   $cf Byte: iret,
  255:  $9f Byte: lahf,   $f0 Byte: lock,   $90 Byte: nop,
  256:  $9d Byte: popf,   $9c Byte: pushf,  $9e Byte: sahf,
  257:  $f9 Byte: stc,    $fd Byte: std,    $fb Byte: sti,
  258:  $9b Byte: wait,   $d7 Byte: xlat,
  259:  $c3 Byte: ret,    $cb Byte: lret,
  260:  $f2 Byte: rep,    $f2 Byte: 0<>rep, $f3 Byte: 0=rep,
  261: 
  262: \ 8086  jmp call  conditions                    ( 24.05.91/KK )
  263: | : jmp/call
  264:      >r setsize # case?
  265:      IF  far? IF  r> IF $EA ELSE $9A THEN   X c,  swap  X ,   X ,  wexit
  266:               THEN   X here  X cell+  - r>
  267:          IF  dup long? 0= IF  $EB  X c,   X c,  wexit  THEN  $E9
  268:          ELSE  $E8  THEN   X c,  1-  X ,  wexit
  269:      THEN  1address $FF  X c,  $10 or r> +
  270:      far? IF  8 or  THEN  r/m, wexit ;
  271:   : call,   0 jmp/call ;         : jmp,  $10 jmp/call ;
  272: 
  273:  $75 Constant 0=   $74 Constant 0<>   $79 Constant 0<
  274:  $78 Constant 0>=  $7d Constant <     $7c Constant >=
  275:  $7f Constant <=   $7e Constant >     $73 Constant u<
  276:  $72 Constant u>=  $77 Constant u<=   $76 Constant u>
  277:  $71 Constant ov   $70 Constant nov   $e1 Constant <>c0=
  278:  $e2 Constant c0=  $e0 Constant ?c0=  $e3 Constant C0<>
  279: 
  280: \ 8086 conditional branching                    ( 24.05.91/KK )
  281:   : +ret,    $c2  X c,   X ,  ;
  282:   : +lret,   $ca  X c,   X ,  ;
  283: 
  284:   : IF,          X ,   X here  1- ;
  285:   : THEN,        X here  over 1+ - ?range swap X c!  ;
  286:   : ELSE,       $eb IF, swap THEN, ;
  287:   : WHILE,      IF, swap ;
  288:   : BEGIN,       X here  ;
  289:   : UNTIL,       X c,   X here  1+ - ?range  X c,  ;
  290:   : AGAIN,      $eb UNTIL, ;
  291:   : REPEAT,     AGAIN, THEN, ;
  292: 
  293:   : j,          1 xor  UNTIL, ;
  294: 
  295: 
  296: \ (Code)-8086   (End-Code)-8086
  297:   : (Code)-8086
  298:     (code)-1 ;          ' (Code)-8086 IS (code)
  299: 
  300:   : (End-Code)-8086
  301:     (end-code)-1 ;      ' (End-Code)-8086 IS (end-code)
  302: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>