; 8086predefs.sr

; by Larry Tesler 7/10/78, last amended 10/27/78


; Intel 8086 Definitions for BCA Cross-Assembler


	.rdx 16


@HIORDFIRST = 0


@bytereg = 00
@wordreg = 01
@accreg = 02
@segreg = 04
@basereg = 08
@indexreg = 010

	.reg AX @wordreg+@accreg 0
	.reg CX @wordreg 1
	.reg DX @wordreg 2
	.reg BX @wordreg+@basereg 3
	.reg SP @wordreg 4
	.reg BP @wordreg+@basereg 5
	.reg SI @wordreg+@indexreg 6
	.reg DI @wordreg+@indexreg 7

	.reg AL @bytereg+@accreg 0
	.reg CL @bytereg 1
	.reg DL @bytereg 2
	.reg BL @bytereg 3
	.reg AH @bytereg 4
	.reg CH @bytereg 5
	.reg DH @bytereg 6
	.reg BH @bytereg 7

	.reg ES @wordreg+@segreg 0
	.reg CS @wordreg+@segreg 1
	.reg SS @wordreg+@segreg 2
	.reg DS @wordreg+@segreg 3

; instruction operands

; label = unsigned16bitvalue
; disp = unsigned16bitvalue
; segbase = unsigned16bitvalue
; lit = ## signed16bitvalue | # signed8or16bitvalue
; byte = unsigned8bitvalue

; mem = disp [!base] [!index]


; Where 2 operands appear, order is {dest, source} unless noted

; arithclass [opcode different when word or lit]
	; reg, reg | lit | mem
	; mem, reg | lit

@ArithImmRshift = 8.
@ArithImmMask = 38
@ArithImmOffset = 08000

@ArithAccImmRshift = 8.
@ArithAccImmMask = 38
@ArithAccImmOffset = 004

	.def ADD @arithclass 00000 ; -00300, 004-005, 08000-08300
	.def ADC @arithclass 01000 ; -01300, 014-015, 08010-08310
	.def SBB @arithclass 01800 ; -01B00, 01C-01D, 08018-08318
	.def SUB @arithclass 02800 ; -2B00, 02C-02D, 08028-08328
	.def CMP @arithclass 03800 ; -03B00, 03C-03D, 08038-08338

; bumpclass [opcode different when reg]
	; reg
	; mem

@BumpRegRshift = 0.
@BumpRegMask = 8
@BumpRegOffset = 040

	.def INCW @bumpclass 0FF00 ; 040-047
	.def DECW @bumpclass 0FF08 ; 048-04F

; exchgclass [opcode different when word or when one reg is accumulator]
	; reg, reg
	; reg, mem

@ExchgAccOffset = -08570

	.def EXCHG @exchgclass 08600 ; -08700, 090-097

; extclass
	; disp

	.def RETP @extclass 0C2 ; return and pop intrasegment
	.def RETPS @extclass 0CA ; return and pop intersegment

; interclass
	; disp, segbase (i.e., segment offset, segment base)

	.def CALLS @interclass 09A ; call direct intersegment
	.def JMPS @interclass 0EA  ; jump direct intersegment

; ldclass
	; reg, mem

	.def LEA @ldclass 08D00
	.def LES @ldclass 0C400
	.def LDS @ldclass 0C500

; logicclass [opcode different when word or lit]
	; reg, reg | lit | mem
	; mem, reg | lit

 ;@  use ArithClass masks and offsets

	.def OR @logicclass 00800 ; -00B00, 00C-00D, 08008-08108
	.def AND @logicclass 02000 ; -02300, 024-025, 08020-08120
	.def XOR @logicclass 03000 ; -03300, 034-035, 08030-08130

; movclass [opcode different when word, lit, seg, or accumulator-to/from-mem]
	; reg, reg | lit | mem
	; mem, reg | lit
	; seg, reg | mem
	; reg | mem, seg

@MovImmOffset = 03E00
@MovRegImmOffset = -08750
@MovAccMemOffset = -08760
@MovMemAccOffset = -0875E
@MovSegFromOffset = 0600
@MovFromSegOffset = 0400

	.def MOV @movclass 08800; -08900,08C00,08E00,0A0-A3,0B0-0BF,0C600-0C700

; noparclass (one-byte opcode, no parameters)

	.def DAA @noparclass 027
	.def DAS @noparclass 02F
	.def AAA @noparclass 037
	.def AAS @noparclass 03F

	.def CBW @noparclass 098
	.def CWD @noparclass 099

	.def WAIT @noparclass 09B

	.def PUSHF @noparclass 09C
	.def POPF @noparclass 09D
	.def SAHF @noparclass 09E
	.def LAHF @noparclass 09F

	.def MOVB @noparclass 0A4
	.def MOVW @noparclass 0A5
	.def CMPB @noparclass 0A6
	.def CMPW @noparclass 0A7
	.def STOB @noparclass 0AA
	.def STOW @noparclass 0AB
	.def LODB @noparclass 0AC
	.def LODW @noparclass 0AD
	.def SCAB @noparclass 0AE
	.def SCAW @noparclass 0AF

	.def RET @noparclass 0C3
	.def RETS @noparclass 0CB

	.def INT3 @noparclass 0CC
	.def INTO @noparclass 0CE
	.def IRET @noparclass 0CF

	.def XLAT @noparclass 0D7

	.def IND @noparclass 0EC
	.def INDW @noparclass 0ED
	.def OUTD @noparclass 0EE
	.def OUTDW @noparclass 0EF

	.def LOCK @noparclass 0F0

	.def REP @noparclass 0F2 ; repeat MOV, LOD, or STO while CX nonzero
	.def REPNE @noparclass 0F2 ; repeat CMP or SCA while not equal
	.def REPE @noparclass 0F3 ; repeat CMP or SCA while equal

	.def HLT @noparclass 0F4

	.def CMC @noparclass 0F5
	.def CLC @noparclass 0F8
	.def STC @noparclass 0F9
	.def CLI @noparclass 0FA
	.def STI @noparclass 0FB
	.def CLD @noparclass 0FC
	.def STD @noparclass 0FD

; PCRelClass
	; label

	.def J @PCRelClass 0EB
	.def JO @PCRelClass 070
	.def JNO @PCRelClass 071
	.def JB @PCRelClass 072
	.def JC @PCRelClass 072
	.def JNAE @PCRelClass 072
	.def JNB @PCRelClass 073
	.def JNC @PCRelClass 073
	.def JAE @PCRelClass 073
	.def JE @PCRelClass 074
	.def JZ @PCRelClass 074
	.def JNE @PCRelClass 075
	.def JNZ @PCRelClass 075
	.def JBE @PCRelClass 076
	.def JNA @PCRelClass 076
	.def JNBE @PCRelClass 077
	.def JA @PCRelClass 077
	.def JS @PCRelClass 078
	.def JNS @PCRelClass 079
	.def JP @PCRelClass 07A
	.def JPE @PCRelClass 07A
	.def JNP @PCRelClass 07B
	.def JPO @PCRelClass 07B
	.def JL @PCRelClass 07C
	.def JNGE @PCRelClass 07C
	.def JNL @PCRelClass 07D
	.def JGE @PCRelClass 07D
	.def JLE @PCRelClass 07E
	.def JNG @PCRelClass 07E
	.def JNLE @PCRelClass 07F
	.def JG @PCRelClass 07F

	.def JCXZ @PCRelClass 0E3

	.def LOOP @PCRelClass 0E2
	.def LOOPZ @PCRelClass 0E1
	.def LOOPE @PCRelClass 0E1
	.def LOOPNZ @PCRelClass 0E0
	.def LOOPNE @PCRelClass 0E0

; pcrel16class
	; label

	.def CALL @pcrel16class 0E8 ; call direct intrasegment

; pcrel8or16class [opcode different when short displacement]
	; label
@PCRel8or16ShortOffset = 2

	.def JMP @pcrel8or16class 0E9 ; 0EB; jump direct intrasegment

; pgzclass
	; byte

	.def INT @pgzclass 0CD

	.def IN @pgzclass 0E4
	.def INW @pgzclass 0E5
	.def OUT @pgzclass 0E6
	.def OUTW @pgzclass 0E7

; rmclass
	; reg
	; mem

	.def ROL @rmclass 0D000 ; rotate left byte by 1
	.def ROR @rmclass 0D008
	.def RCL @rmclass 0D010
	.def RCR @rmclass 0D018
	.def SHL @rmclass 0D020
	.def SAL @rmclass 0D020
	.def SHR @rmclass 0D028
	.def SAR @rmclass 0D038
	.def ROLW @rmclass 0D100 ; rotate left word by 1
	.def RORW @rmclass 0D108
	.def RCLW @rmclass 0D110
	.def RCRW @rmclass 0D118
	.def SHLW @rmclass 0D120
	.def SALW @rmclass 0D120
	.def SHRW @rmclass 0D128
	.def SARW @rmclass 0D138
	.def ROLV @rmclass 0D200 ; rotate left byte variable by CL
	.def RORV @rmclass 0D208
	.def RCLV @rmclass 0D210
	.def RCRV @rmclass 0D218
	.def SHLV @rmclass 0D220
	.def SALV @rmclass 0D220
	.def SHRV @rmclass 0D228
	.def SARV @rmclass 0D238
	.def ROLVW @rmclass 0D300 ; rotate left word variable by CL
	.def RORVW @rmclass 0D308
	.def RCLVW @rmclass 0D310
	.def RCRVW @rmclass 0D318
	.def SHLVW @rmclass 0D320
	.def SALVW @rmclass 0D320
	.def SHRVW @rmclass 0D328
	.def SARVW @rmclass 0D338

	.def ESC @rmclass 0D800
	.def NOT @rmclass 0F610
	.def NEG @rmclass 0F618
	.def MUL @rmclass 0F620
	.def IMUL @rmclass 0F628
	.def DIV @rmclass 0F630
	.def IDIV @rmclass 0F638
	.def NOTW @rmclass 0F710
	.def NEGW @rmclass 0F718
	.def MULW @rmclass 0F720
	.def IMULW @rmclass 0F728
	.def DIVW @rmclass 0F730
	.def IDIVW @rmclass 0F738
	.def INC @rmclass 0FE00
	.def DEC @rmclass 0FE08

	.def CALLI @rmclass 0FF10 ; call indirect intrasegment
	.def CALLIS @rmclass 0FF18 ; call indirect intersegment
	.def JMPI @rmclass 0FF20 ; jump indirect intrasegment
	.def JMPIS @rmclass 0FF28 ; jump indirect intrasegment

; rmsclass [opcode different when reg or seg]
	; reg
	; mem
	; seg

@RmsRegRshift = 9.
@RmsRegMaskNot = 8
@RmsRegOffset = 050

@RmsSegRshift = 12.
@RmsSegMaskNot = 1
@RmsSegOffset = 006

	.def POP @rmsclass 08F00 ; 007, 00F, 017, 01F, 058-05F
	.def PUSH @rmsclass 0FF30 ; 006, 00E, 016, 01E, 050-057

; segclass (segment prefix)
	; seg

	.def SEG @segclass 026

; testclass [opcode different when word or lit]
	; reg, reg | lit | mem
	; mem, reg | lit

@TestImmRshift = 0.
@TestImmMask = 0
@TestImmOffset = 0F600

@TestAccImmRshift = 0.
@TestAccImmMask = 0
@TestAccImmOffset = 0A8

	.def TEST @testclass 08400 ; -08500, 0A8-0A9, 0F600-0F700

; twoonlyclass (two-byte opcode, no parameters)

	.def AAM @twoonlyclass 0D40A
	.def AAD @twoonlyclass 0D50A