; D1simasm.asm -- hand-coded procedures for simulator
;	Last edited: 19 July 1979

dOff = 0
.get "d1dmux.d"
.get "masmcommon.d"

.bextz DMuxTab

.ent SimALU

.srel

SimALU:		.SimALU

.nrel

c37:		37

; SimALU(lvOvf,lvCarryOut,lvResult,Carry20) computes the result of the
; alu operation described in DMuxTab and returns true if the operation
; is arithmetic, false if logical.  Overflow and carry-out are also
; computed on an arithmetic operation.
.SimALU:
	sta 3 1 2
	jsr @GetFrame
	 27
	jsr @StArgs
	lda 3 DMuxTab
	lda 0 dALUA 3
	sta 0 10 2	; A
	lda 1 dALUB 3
	sta 1 11 2	; B
	com 1 3
	sta 3 13 2	; not B
	and 0 3
	sta 3 14 2	; A & not B
	mov 1 3
	and 0 3
	sta 3 15 2	; A & B
	com 0 3
	and 1 3
	com 3 3
	sta 3 16 2	; A % (not B)
	com 0 3
	com 1 1
	and 1 3
	com 3 3
	sta 3 17 2	; A % B
	lda 3 DMuxTab
	lda 0 dALUCON 3
	lda 1 c37
	and 0 1		; alu controls
	sta 1 20 2
	movs 0 0	; aluCin into sign bit
	movl 0 0 szc
	mkone 0 0 skp
	mkzero 0 0
	sta 0 12 2
; Now have:
;  A		10 2
;  B		11 2
;  aluCin	12 2
;  not B	13 2
;  A & not B	14 2
;  A & B	15 2
;  A % (not B)	16 2
;  A % B	17 2
;  alu controls	20 2
	jsr FetAB

	lda 0 10 2	; 0/ A+0
	mkzero 1 1
	jmp Arith

	lda 0 10 2	; 1/ not A
	mkminusone 1 1
	jmp Logic

	lda 0 10 2	; 2/ A+(A & not B)
	lda 1 14 2
	jmp Arith

	lda 0 15 2	; 3/ not (A & B)
	mkminusone 1 1
	jmp Logic

	lda 0 10 2	; 4/ A+(A & B)
	lda 1 15 2
	jmp Arith

	lda 0 14 2	; 5/ not (A & not B)
	mkminusone 1 1
	jmp Logic

	lda 0 10 2	; 6/ A+A
	mov 0 1
	jmp Arith

	mkzero 0 0	; 7/ -1
	mkminusone 1 1
	jmp Logic

	lda 0 17 2	; 10/ (A % B)+0
	mkzero 1 1
	jmp Arith

	lda 0 17 2	; 11/ not (A % B)
	mkminusone 1 1
	jmp Logic

	lda 0 17 2	; 12/ (A % B)+(A & not B)
	lda 1 14 2
	jmp Arith

	lda 0 11 2	; 13/ not B
	mkminusone 1 1
	jmp Logic

	lda 0 10 2	; 14/ A+B
	lda 1 11 2
	jmp Arith

	lda 0 10 2	; 15/ A xor (not B)
	lda 1 13 2
	jmp Logic

	lda 0 10 2	; 16/ A+(A % B)
	lda 1 17 2
	jmp Arith

	lda 0 16 2	; 17/ A % not B
	mkzero 1 1
	jmp Logic

	lda 0 16 2	; 20/ (A % not B)+0
	mkzero 1 1
	jmp Arith

	lda 0 16 2	; 21/ not (A % not B)
	mkminusone 1 1
	jmp Logic

	lda 0 10 2	; 22/ A+(not B)
	lda 1 13 2
	jmp Arith

	lda 0 10 2	; 23/ A xor B
	lda 1 11 2
	jmp Logic

	lda 0 16 2	; 24/ (A % not B)+(A & B)
	lda 1 15 2
	jmp Arith

	lda 0 11 2	; 25/ B
	mkzero 1 1
	jmp Logic

	lda 0 10 2	; 26/ A+(A % not B)
	lda 1 16 2
	jmp Arith

	lda 0 17 2	; 27/ A % B
	mkzero 1 1
	jmp Logic

	mkminusone 0 0	; 30/ -1+0
	mkzero 1 1
	jmp Arith

	mkzero 0 0	; 31/ 0
	mkzero 1 1
	jmp Logic

	lda 0 14 2	; 32/ (A & not B)-1
	mkminusone 1 1
	jmp Arith

	lda 0 14 2	; 33/ A & not B
	mkzero 1 1
	jmp Logic

	lda 0 15 2	; 34/ (A & B)-1
	mkminusone 1 1
	jmp Arith

	lda 0 15 2	; 35/ A & B
	mkzero 1 1
	jmp Logic

	lda 0 10 2	; 36/ A-1
	mkminusone 1 1
	jmp Arith

	lda 0 10 2	; 37/ A
	mkzero 1 1
	jmp Logic

FetAB:	add 1 3
	add 1 3
	add 1 3		; Table + 3*aluop
	jmp 0 3

; For logical ops, xor the numbers in 0 & 1 and return false
Logic:	mov 0 3
	andzl 1 3
	add 1 0
	sub 3 0		; Xor = arg1+arg2-2*(arg1 & arg2)
	sta 0 @6 2
	mkzero 0 0
	jsr @Return

; For arithmetic ops, compute T = arg1 & 177760, U = arg2 & 177760, and
; V = ((arg1 & 17)+(arg2 & 17)+Carryin) % Carry20.  Then
; Result = T+U+V, getting carryout at the same time.  Overflow would
; be correctly computed as carryout unequal to carryin to bit 0, but
; hardware kludge instead xor's aluF0, alua.00, alub.00, alu.00, and
; aluCout (which is correct overflow only for A+B and A-B operations).
Arith:	lda 3 c177760
	and 0 3
	sub 3 0
	sta 3 13 2	; T
	lda 3 c177760
	and 1 3
	sub 3 1
	sta 3 14 2	; U
	add 1 0
	lda 1 12 2
	add 1 0
	lda 1 7 2	; 20 if Carry20 else 0
	com 1 1
	com 0 0
	and 1 0
	com 0 0		; V
	lda 1 14 2
	mkzero 3 3
	add 1 0 szc
	mkone 3 3
	lda 1 13 2
	add 1 0 szc
	mkone 3 3
	sta 0 @6 2	; Result
	sta 3 @5 2	; Carry out (1 or 0)
	movzl 0 0
	movl 0 0	; alu.00 into bit 15
	add 0 3		; in bit 15, sum = xor(aluCout,alu.00)
	lda 0 20 2	; aluFM.aluF0-3
	cycle 13	; aluF0 into bit 15
	add 0 3		; ac3 bit 15 = xor(aluCout,alu.00,aluF0)
	lda 0 10 2
	movzl 0 0
	movl 0 0	; alua.00 into ac0 bit 15
	lda 1 11 2
	movzl 1 1
	movl 1 1	; alub.00 into ac1 bit 15
	add 1 0		; in ac0 bit 15 have xor(alua.00,alub.00)
	add 3 0		; xor(alua.00,alub.00,aluCout,alu.00,aluF0)
	sta 0 @4 2	; SignedCarry in bit 15 (garbage in other bits)
	mkminusone 0 0
	jsr @Return

c177760:	177760

.end