; 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