/FILE 3 NAME(IN) OLD(CREATE) DEFAULT /FILE 10 NAME(P) DEFAULT /FILE 11 NAME(OUT) OLD(CREATE) DEFAULT /SYS REGION=400K /INCLUDE WATFIV C C Initialise variables and 'memory' C IMPLICIT INTEGER (A-Z) INTEGER REG(7),TREG(7),MEM*2(65536),INDEX(2) CHARACTER*59 FORMAT(5),FORM(1) LOGICAL COND COMMON PC,OPAND DATA MEM/32767*0,32767*0,2*0/ DATA REG,TREG,C,V,S,N,H,Z,PC,OPAND,OP,INDEX,R/26*0/ DATA IV,NMICNT,INTCNT,IMODE,IFF1,IFF2,NMI,INT/7*0,10/ DATA SP/ZFFFF/ DATA FORMAT/ $'(1X,Z4,1(1X,Z2),T20,7(1X,Z2),2X,2(Z4,1X),1X,Z4,2X,6(I1,1X))', $'(1X,Z4,2(1X,Z2),T20,7(1X,Z2),2X,2(Z4,1X),1X,Z4,2X,6(I1,1X))', $'(1X,Z4,3(1X,Z2),T20,7(1X,Z2),2X,2(Z4,1X),1X,Z4,2X,6(I1,1X))', $'(1X,Z4,4(1X,Z2),T20,7(1X,Z2),2X,2(Z4,1X),1X,Z4,2X,6(I1,1X))', $'(1X,Z4,5(1X,Z2),T20,7(1X,Z2),2X,2(Z4,1X),1X,Z4,2X,6(I1,1X))'/ C C ###################################################################### C C Read machine code program into memory starting at 0000 hex C READ(10,10,END=1)MEM 10 FORMAT(24(Z2,1X)) C C Read opcodes from memory and execute C 1 WHILE (OP.NE.118) R=R+1 INTCNT=INTCNT+1 NMICNT=NMICNT+1 OLDPC=PC OP=MEM(PC+1) CALL INCPC(1) OPAND=0 C C ***** Indexed instruction set **************************************** C IF (OP.EQ.221) THEN INDREG=1 OP=MEM(PC+1) CALL INCPC(1) ELSEIF (OP.EQ.253) THEN INDREG=2 OP=MEM(PC+1) CALL INCPC(1) ELSE INDREG=0 ENDIF C C ***** Bit-type instruction set *************************************** C IF (OP.EQ.203) THEN IF(INDREG.NE.0)THEN OFF=MEM(PC+1) CALL INCPC(1) ENDIF OP=MEM(PC+1) CALL INCPC(1) IF (OP.LT.8) THEN EXECUTE RLC ELSEIF (OP.LT.16) THEN EXECUTE RRC ELSEIF (OP.LT.24) THEN EXECUTE RL ELSEIF (OP.LT.32) THEN EXECUTE RR ELSE IF(OP.LT.40) THEN EXECUTE SLA ELSEIF (OP.LT.48) THEN EXECUTE SRA ELSEIF ((OP.GT.56).AND.(OP.LT.64)) THEN EXECUTE SRL ELSEIF (OP.LT.128) THEN EXECUTE BIT ELSEIF (OP.LT.192) THEN EXECUTE RES ELSEIF (OP.LT.256) THEN EXECUTE SET ENDIF C C ***** Main instruction set ******************************************* C ELSEIF (OP.LT.1) THEN C NOP C LD (rr),A ---------------------------------------------------------- ELSEIF ((OP.EQ.2).OR.(OP.EQ.18)) THEN MEM(IAND(DOUBLE(OP,REG,SP),65535)+1)=REG(1) ELSEIF (OP.EQ.8) THEN EXECUTE EXAF ELSEIF (IAND(OP,207).EQ.9) THEN EXECUTE ADDD C LD A,(rr) ---------------------------------------------------------- ELSEIF ((OP.EQ.10).OR.(OP.EQ.26)) THEN REG(1)=MEM(IAND(DOUBLE(OP,REG,SP),65535)+1) ELSEIF (IAND(OP,207).EQ.1)THEN EXECUTE LOADD ELSEIF (IAND(OP,207).EQ.3) THEN EXECUTE INCD ELSEIF (IAND(OP,231).EQ.32.OR.OP.EQ.24) THEN EXECUTE JR ELSEIF (IAND(OP,199).EQ.4) THEN EXECUTE INC ELSEIF (IAND(OP,199).EQ.5) THEN EXECUTE DEC ELSEIF (IAND(OP,199).EQ.6) THEN EXECUTE LDIMM ELSEIF (OP.EQ.7) THEN EXECUTE RLCA ELSEIF (OP.EQ.16) THEN EXECUTE DJNZ ELSEIF (OP.EQ.23) THEN EXECUTE RLA C SCF ---------------------------------------------------------- ELSEIF (OP.EQ.55) THEN C=1 H=0 N=0 ELSEIF (IAND(OP,207).EQ.11) THEN EXECUTE DECD ELSEIF (OP.EQ.15) THEN EXECUTE RRCA ELSEIF (OP.EQ.34) THEN EXECUTE LDMEHL ELSEIF (OP.EQ.31) THEN EXECUTE RRA ELSEIF (OP.EQ.39) THEN EXECUTE DAA ELSEIF (OP.EQ.42) THEN EXECUTE LDHLME C CPL ---------------------------------------------------------- ELSEIF (OP.EQ.47) THEN REG(1)=IEOR(REG(1),255) H=1 N=1 C LD (nn),A ---------------------------------------------------------- ELSEIF (OP.EQ.50) THEN K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) MEM(IAND(K,65535)+1)=REG(1) CALL INCPC(2) C LD A,(nn) ---------------------------------------------------------- ELSEIF (OP.EQ.58) THEN K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) REG(1)=MEM(IAND(K,65535)+1) CALL INCPC(2) C CCF ---------------------------------------------------------- ELSEIF (OP.EQ.63) THEN C=IEOR(C,1) N=0 ELSEIF (OP.EQ.118) THEN C HALT ELSEIF (OP.LT.128) THEN EXECUTE LOAD ELSEIF ((OP.LT.144).OR.(IAND(OP,247).EQ.198)) THEN EXECUTE ADD ELSEIF ((OP.LT.160).OR.(IAND(OP,247).EQ.214)) THEN EXECUTE SUB ELSEIF ((OP.LT.168).OR.(OP.EQ.230)) THEN EXECUTE ANDA ELSEIF ((OP.LT.176).OR.(OP.EQ.238)) THEN EXECUTE XORA ELSEIF ((OP.LT.184).OR.(OP.EQ.246)) THEN EXECUTE ORA ELSEIF ((OP.LT.192).OR.(OP.EQ.254)) THEN EXECUTE CP ELSEIF (IAND(OP,199).EQ.192.OR.OP.EQ.201) THEN EXECUTE RET ELSEIF (IAND(OP,207).EQ.193) THEN EXECUTE POP ELSEIF (IAND(OP,199).EQ.194.OR.OP.EQ.195.OR.OP.EQ.233) THEN EXECUTE JP ELSEIF (IAND(OP,199).EQ.196.OR.OP.EQ.205) THEN EXECUTE CALL ELSEIF (IAND(OP,207).EQ.197) THEN EXECUTE PUSH ELSEIF (IAND(OP,199).EQ.199) THEN EXECUTE RST ELSEIF (OP.EQ.217) THEN EXECUTE EXX C IN A,(n) ---------------------------------------------------------- ELSEIF (OP.EQ.219) THEN ADDR=MEM(PC+1) REG(1)=PORTI(ADDR,R) CALL INCPC(1) ELSEIF (OP.EQ.227) THEN EXECUTE EXSPHL ELSEIF (OP.EQ.235) THEN EXECUTE EXDEHL ELSEIF (OP.EQ.249) THEN EXECUTE LDSPHL C OUT (n),A ---------------------------------------------------------- ELSEIF (OP.EQ.211) THEN CALL PORTO(MEM(PC+1),REG(1)) CALL INCPC(1) C EI ---------------------------------------------------------- ELSEIF (OP.EQ.251) THEN IFF1=1 IFF2=1 C DI ---------------------------------------------------------- ELSEIF (OP.EQ.243) THEN IFF1=0 IFF2=0 C C ***** Auxillary instruction set ************************************* C ELSEIF (OP.EQ.237) THEN OP=MEM(PC+1) CALL INCPC(1) IF (IAND(OP,199).EQ.65)THEN EXECUTE OUT ELSEIF (IAND(OP,199).EQ.64)THEN EXECUTE IN ELSEIF ((IAND(OP,207).EQ.67).OR.(IAND(OP,207).EQ.75))THEN EXECUTE LDMEM C NEG ---------------------------------------------------------- ELSEIF (OP.EQ.68)THEN CALL DIFF(8,0,REG(1),0,REG(1),C,V,S,N,H,Z) C SBC HL,rr ---------------------------------------------------------- ELSEIF (IAND(OP,207).EQ.66) THEN HL=REG(3)+256*REG(2) CALL DIFF(16,HL,DOUBLE(OP,REG,SP),8,K,C,V,S,N,H,Z) CALL SINGLE(K,OP,REG,SP) C IM 0,1,2 ---------------------------------------------------------- ELSEIF ((OP.EQ.70).OR.(OP.EQ.86).OR.(OP.EQ.94)) THEN IMODE=IAND(OP,8)/8+IAND(OP,16)/16 C RETN ---------------------------------------------------------- ELSEIF (OP.EQ.69) THEN PC=MEM(IAND(SP,65535)+1)+256*MEM(IAND(SP+1,65535)+1) SP=SP+2 IFF1=IFF2 C LD I,A ---------------------------------------------------------- ELSEIF (OP.EQ.71) THEN I=REG(1) C RETI ---------------------------------------------------------- ELSEIF (OP.EQ.77) THEN PC=MEM(IAND(SP,65535)+1)+256*MEM(IAND(SP+1,65535)+1) SP=SP+2 C ADC HL,rr ---------------------------------------------------------- ELSEIF (IAND(OP,207).EQ.76) THEN HL=REG(3)+256*REG(2) CALL SUM(16,HL,DOUBLE(OP,REG,SP),8,K,C,V,S,N,H,Z) CALL SINGLE(K,OP,REG,SP) ELSEIF (OP.EQ.87) THEN EXECUTE LDAI ELSEIF (OP.EQ.95) THEN EXECUTE LDAR C LD R,A ---------------------------------------------------------- ELSEIF (OP.EQ.79) THEN R=REG(1) ELSEIF (OP.EQ.103) THEN EXECUTE RRD ELSEIF (OP.EQ.111) THEN EXECUTE RLD ELSEIF (IAND(OP,231).EQ.160) THEN EXECUTE LDD ELSEIF (IAND(OP,231).EQ.161) THEN EXECUTE CPD ELSEIF (IAND(OP,231).EQ.162) THEN EXECUTE INI ELSEIF (IAND(OP,231).EQ.163) THEN EXECUTE OUTR ENDIF ENDIF C C Display instruction, registers and flags on screen C 200 BYTES=OPAND+1 FORM(1)=FORMAT(BYTES) WRITE(6,FORM)OLDPC,(MEM(IAND(OLDPC+J-1,65535)+1),J=1,BYTES), $ REG(1),(REG(IEOR(J-1,6)),J=1,6),INDEX,SP,C,V,S,N,H,Z C C Check for interrupt condition and take appropriate action C IF(NMICNT.EQ.NMI) THEN WRITE (6,*)'* NMI acknowledge *' MEM(IAND(SP-1,65535)+1)=PC/256 MEM(IAND(SP-2,65535)+1)=PC SP=SP-2 IFF2=IFF1 NMICNT=0 PC=102 ELSEIF (INTCNT.GE.INT.AND.INT.NE.0.AND.IFF1.EQ.1.AND.R.GT.1)THEN WRITE (6,*)'* INT acknowledge *' INTCNT=0 IFF1=0 IFF2=0 IF (IMODE.EQ.0) THEN OP=0 GOTO 200 ELSEIF(IMODE.EQ.1) THEN MEM(IAND(SP-1,65535)+1)=PC/256 MEM(IAND(SP-2,65535)+1)=PC SP=SP-2 PC=56 ELSEIF(IMODE.EQ.2) THEN MEM(IAND(SP-1,65535)+1)=PC/256 MEM(IAND(SP-2,65535)+1)=PC SP=SP-2 READ(9,*) K K=IAND(I,255)*256+IAND(K,254) PC=IAND(MEM(K+1)+MEM(K+1+1)*256,65535) ENDIF ENDIF ENDWHILE C C End of main instruction loop C STOP C C ###################################################################### C C OUTR ---------------------------------------------------------- REMOTE BLOCK OUTR HL=IAND(REG(2)*256+REG(3),65535) CALL PORTO(IAND(REG(7),255),MEM(HL+1)) ID=1-IAND(OP,8)/4 CALL SINGLE(IAND(HL+ID,65535),32,REG,SP) REG(6)=IAND(REG(6)-1,255) N=1 Z=ZERO(REG(6),8) IF(IAND(OP,247).NE.163.AND.Z.EQ.0) PC=PC-2 END BLOCK C INI ---------------------------------------------------------- REMOTE BLOCK INI HL=IAND(REG(2)*256+REG(3),65535) MEM(HL+1)=PORTI(IAND(REG(7),255),TIME) ID=1-IAND(OP,8)/4 CALL SINGLE(IAND(HL+ID,65535),32,REG,SP) REG(6)=IAND(REG(6)-1,255) N=1 Z=ZERO(REG(6),8) IF(IAND(OP,247).NE.162.AND.Z.EQ.0) PC=PC-2 END BLOCK C CPD ---------------------------------------------------------- REMOTE BLOCK CPD HL=IAND(REG(2)*256+REG(3),65535) BC=IAND(REG(6)*256+REG(7),65535) K=MEM(HL+1) CALL DIFF(16,IAND(REG(1),255),K,0,K,X,X,S,N,H,Z) V=IEOR(ZERO(BC-1,16),1) ID=1-IAND(OP,8)/4 CALL SINGLE(IAND(HL+ID,65535),32,REG,SP) CALL SINGLE(IAND(BC-1,65535),0,REG,SP) IF (V.EQ.1.AND.IAND(OP,247).NE.161.AND.Z.EQ.0) PC=PC-2 END BLOCK C LDD ---------------------------------------------------------- REMOTE BLOCK LDD DE=IAND(REG(4)*256+REG(5),65535) HL=IAND(REG(2)*256+REG(3),65535) BC=IAND(REG(6)*256+REG(7),65535) MEM(DE+1)=MEM(HL+1) ID=1-IAND(OP,8)/4 CALL SINGLE(IAND(DE+ID,65535),16,REG,SP) CALL SINGLE(IAND(HL+ID,65535),32,REG,SP) CALL SINGLE(IAND(BC-1,65535),0,REG,SP) N=0 H=0 V=IEOR(ZERO(BC-1,16),1) IF ((V.EQ.1).AND.(IAND(OP,247).NE.160)) PC=PC-2 END BLOCK C RLD ---------------------------------------------------------- REMOTE BLOCK RLD K=IAND(REG(2)*256+REG(3),65535) LACC=IAND(REG(1),15) TEMP=MEM(K+1) REG(1)=IAND(TEMP,240)/16+IAND(REG(1),240) MEM(K+1)=IAND(TEMP,15)*16+LACC H=0 N=0 V=PARITY(REG(1)) Z=ZERO(REG(1),8) S=SGN(REG(1),8) END BLOCK C RRD ---------------------------------------------------------- REMOTE BLOCK RRD K=IAND(REG(2)*256+REG(3),65535) LACC=IAND(REG(1),15) TEMP=MEM(K+1) REG(1)=IAND(TEMP,15)+IAND(REG(1),240) MEM(K+1)=IAND(TEMP,240)/16+LACC*16 H=0 N=0 V=PARITY(REG(1)) Z=ZERO(REG(1),8) S=SGN(REG(1),8) END BLOCK C LD A,R ---------------------------------------------------------- REMOTE BLOCK LDAR REG(1)=IAND(R,255) H=0 N=0 S=SGN(REG(1),8) Z=ZERO(REG(1),8) V=IFF2 END BLOCK C LD A,I ---------------------------------------------------------- REMOTE BLOCK LDAI REG(1)=I H=0 N=0 S=SGN(REG(1),8) Z=ZERO(REG(1),8) V=IFF2 END BLOCK C LD SP,HL ---------------------------------------------------------- REMOTE BLOCK LDSPHL IF (INDREG.NE.0) THEN SP=INDEX(INDREG) ELSE SP=REG(3)+256*REG(2) ENDIF END BLOCK C EX DE,HL ---------------------------------------------------------- REMOTE BLOCK EXDEHL HTEMP=REG(2) LTEMP=REG(3) REG(2)=REG(4) REG(3)=REG(5) REG(4)=HTEMP REG(5)=LTEMP END BLOCK C EXX ---------------------------------------------------------- REMOTE BLOCK EXX DO 555 J=1,7 TEMP=REG(J) REG(J)=TREG(J) TREG(J)=TEMP 555 CONTINUE TEMP=C+N*2+V*4+H*16+Z*64+S*128 C=IAND(TFLAG,1) N=IAND(TFLAG,2)/2 V=IAND(TFLAG,4)/4 H=IAND(TFLAG,16)/16 Z=IAND(TFLAG,64)/64 S=IAND(TFLAG,128)/128 TFLAG=TEMP END BLOCK C EX (SP),HL ---------------------------------------------------------- REMOTE BLOCK EXSPHL IF (INDREG.NE.0) THEN TIND=INDEX(INDREG) TEMP=MEM(IAND(SP+1,65535)+1)*256+MEM(IAND(SP,65535)+1) INDEX(INDREG)=TEMP MEM(IAND(SP+1,65535)+1)=TIND/256 MEM(IAND(SP,65535)+1)=IAND(TIND,255) ELSE HTEMP=REG(2) LTEMP=REG(3) REG(2)=MEM(IAND(SP+1,65535)+1) REG(3)=MEM(IAND(SP,65535)+1) MEM(IAND(SP+1,65535)+1)=HTEMP MEM(IAND(SP,65535)+1)=LTEMP ENDIF END BLOCK C LD HL,(nn) ---------------------------------------------------------- REMOTE BLOCK LDHLME K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) IF(INDREG.NE.0) THEN INDEX(INDREG)=MEM(IAND(K,65535)+1)+256*MEM(IAND(K+1,65535)+1) ELSE REG(3)=MEM(IAND(K,65535)+1) REG(2)=MEM(IAND(K+1,65535)+1) ENDIF CALL INCPC(2) END BLOCK C DAA ---------------------------------------------------------- REMOTE BLOCK DAA IF (N.EQ.0) THEN IF (IAND(REG(1),15).GT.9.OR.H.EQ.1) THEN REG(1)=REG(1)+6 H=1 ENDIF IF (IAND(REG(1),240).GT.144.OR.C.EQ.1) THEN REG(1)=REG(1)+96 C=1 ENDIF ELSE IF (H.EQ.1) REG(1)=REG(1)-6 IF (C.EQ.1) REG(1)=REG(1)-96 ENDIF END BLOCK C RRA ---------------------------------------------------------- REMOTE BLOCK RRA TEMPV=V TEMPS=S TEMPZ=Z EXECUTE RR V=TEMPV S=TEMPS Z=TEMPZ END BLOCK C LD (nn),HL ---------------------------------------------------------- REMOTE BLOCK LDMEHL K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) IF(INDREG.NE.0) THEN MEM(IAND(K,65535)+1)=INDEX(INDREG)/256 MEM(IAND(K+1,65535)+1)=IAND(INDEX(INDREG),255) ELSE MEM(IAND(K,65535)+1)=REG(3) MEM(IAND(K+1,65535)+1)=REG(2) ENDIF CALL INCPC(2) END BLOCK C RRCA ---------------------------------------------------------- REMOTE BLOCK RRCA TEMPV=V TEMPS=S TEMPZ=Z EXECUTE RRC V=TEMPV S=TEMPS Z=TEMPZ END BLOCK C RLA ---------------------------------------------------------- REMOTE BLOCK RLA TEMPV=V TEMPS=S TEMPZ=Z EXECUTE RL V=TEMPV S=TEMPS Z=TEMPZ END BLOCK C DJNZ h ---------------------------------------------------------- REMOTE BLOCK DJNZ ZTEMP=Z CALL DIFF(8,REG(6),1,0,REG(6),X,X,X,X,X,Z) OP=32 EXECUTE JR Z=ZTEMP END BLOCK C RLCA ---------------------------------------------------------- REMOTE BLOCK RLCA TEMPV=V TEMPS=S TEMPZ=Z EXECUTE RLC V=TEMPV S=TEMPS Z=TEMPZ END BLOCK C EX AF,AF' ---------------------------------------------------------- REMOTE BLOCK EXAF TEMP=REG(1) REG(1)=TREG(1) TREG(1)=TEMP TEMP=C+N*2+V*4+H*16+Z*64+S*128 C=IAND(TFLAG,1) N=IAND(TFLAG,2)/2 V=IAND(TFLAG,4)/4 H=IAND(TFLAG,16)/16 Z=IAND(TFLAG,64)/64 S=IAND(TFLAG,128)/128 TFLAG=TEMP END BLOCK C RET c ----------------------------------------------------------- REMOTE BLOCK RET IF (COND(IAND(OP,56)/8,C,V,S,Z).OR.OP.EQ.201) THEN PC=MEM(IAND(SP,65535)+1)+256*MEM(IAND(SP+1,65535)+1) SP=SP+2 ENDIF END BLOCK C RST n ----------------------------------------------------------- REMOTE BLOCK RST J=IAND(OP,56) MEM(IAND(SP-1,65535)+1)=PC/256 MEM(IAND(SP-2,65535)+1)=PC PC=J SP=SP-2 END BLOCK C JR c,h ----------------------------------------------------------- REMOTE BLOCK JR CALL INCPC(1) IF (COND(IAND(OP,24)/8,C,V,S,Z).OR.OP.EQ.24) THEN K=MEM(IAND(PC-1,65535)+1) IF (K.GT.127) K=K-256 PC=IAND(PC+K,65535) ENDIF END BLOCK C POP rr ----------------------------------------------------------- REMOTE BLOCK POP K=MEM(IAND(SP+0,65535)+1)+256*MEM(IAND(SP+1,65535)+1) IF (INDREG.NE.0) THEN INDEX(INDREG)=K ELSE IF (OP.EQ.241) THEN REG(1)=K/256 S=IAND(K,128)/128 Z=IAND(K,64)/64 H=IAND(K,16)/16 V=IAND(K,4)/4 N=IAND(K,2)/2 C=IAND(K,1) ELSE CALL SINGLE(K,OP,REG,SP) ENDIF ENDIF SP=SP+2 END BLOCK C PUSH rr ----------------------------------------------------------- REMOTE BLOCK PUSH IF(INDREG.NE.0)THEN K=IAND(INDEX(INDREG)) ELSE IF (OP.EQ.245) THEN K=REG(1)*256+C*128+Z*64+0*32+H*16+0*8+V*4+N*2+C ELSE K=DOUBLE(OP,REG,SP) ENDIF ENDIF SP=SP-2 MEM(IAND(SP+1,65535)+1)=K/256 MEM(IAND(SP+0,65535)+1)=IAND(K,255) END BLOCK C LD rr,dd ----------------------------------------------------------- REMOTE BLOCK LOADD K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) IF (INDREG.NE.0) THEN INDEX(INDREG)=K ELSE CALL SINGLE(K,OP,REG,SP) ENDIF CALL INCPC(2) END BLOCK C INC rr ----------------------------------------------------------- REMOTE BLOCK INCD IF (INDREG.NE.0) THEN CALL SUM(16,INDEX(INDREG),1,0,INDEX(INDREG),X,X,X,X,X,X) ELSE CALL SUM(16,DOUBLE(OP,REG,SP),1,0,K,X,X,X,X,X,X) CALL SINGLE(K,OP,REG,SP) ENDIF END BLOCK C DEC rr ----------------------------------------------------------- REMOTE BLOCK DECD IF (INDREG.NE.0) THEN CALL DIFF(16,INDEX(INDREG),1,0,INDEX(INDREG),X,X,X,X,X,X) ELSE CALL DIFF(16,DOUBLE(OP,REG,SP),1,0,K,X,X,X,X,X,X) CALL SINGLE(K,OP,REG,SP) ENDIF END BLOCK C LD r,r ----------------------------------------------------------- REMOTE BLOCK LOAD K=IEOR(IAND(OP,56)/8,6) J=IEOR(IAND(OP,7),6) IF (K.EQ.0) THEN IF (INDREG.EQ.0) THEN MEM(REG(2)*256+REG(3)+1)=REG(J) ELSE MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1)=REG(J) CALL INCPC(1) ENDIF ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN REG(K)=MEM(REG(2)*256+REG(3)+1) ELSE REG(K)=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE REG(K)=REG(J) ENDIF END BLOCK C ADD A,r ----------------------------------------------------------- REMOTE BLOCK ADD J=IEOR(IAND(OP,7),6) IF (IAND(OP,247).EQ.198) THEN C ADD A,dd or ADC A,dd K=MEM(PC+1) CALL INCPC(1) ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE K=REG(J) ENDIF CALL SUM(8,REG(1),K,OP,REG(1),C,V,S,N,H,Z) END BLOCK C SUB A,r ----------------------------------------------------------- REMOTE BLOCK SUB J=IEOR(IAND(OP,7),6) IF (IAND(OP,247).EQ.214) THEN C SUB A,dd or SBC A,dd K=MEM(PC+1) CALL INCPC(1) ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE K=REG(J) ENDIF CALL DIFF(8,REG(1),K,OP,REG(1),C,V,S,N,H,Z) END BLOCK C AND A,r ----------------------------------------------------------- REMOTE BLOCK ANDA J=IEOR(IAND(OP,7),6) IF (OP.EQ.230)THEN C AND A,dd K=MEM(PC+1) CALL INCPC(1) ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE K=REG(J) ENDIF REG(1)=IAND(REG(1),K) C=0 V=PARITY(REG(1)) S=SGN(REG(1),8) N=0 H=1 Z=ZERO(REG(1),8) END BLOCK C XOR A,r ----------------------------------------------------------- REMOTE BLOCK XORA J=IEOR(IAND(OP,7),6) IF (OP.EQ.238) THEN C XOR A,dd K=MEM(PC+1) CALL INCPC(1) ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE K=REG(J) ENDIF REG(1)=IEOR(REG(1),K) C=0 V=PARITY(REG(1)) S=SGN(REG(1),8) N=0 H=0 Z=ZERO(REG(1),8) END BLOCK C OR A,r ----------------------------------------------------------- REMOTE BLOCK ORA J=IEOR(IAND(OP,7),6) IF (OP.EQ.246) THEN C OR A,dd K=MEM(PC+1) CALL INCPC(1) ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE K=REG(J) ENDIF REG(1)=IOR(REG(1),K) C=0 V=PARITY(REG(1)) S=SGN(REG(1),8) N=0 H=1 Z=ZERO(REG(1),8) END BLOCK C CP A,r ----------------------------------------------------------- REMOTE BLOCK CP J=IEOR(IAND(OP,7),6) IF (OP.EQ.254) THEN C CP A,dd K=MEM(PC+1) CALL INCPC(1) ELSEIF (J.EQ.0) THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+MEM(PC+1),65535)+1) CALL INCPC(1) ENDIF ELSE K=REG(J) ENDIF CALL DIFF(8,REG(1),K,0,K,C,V,S,N,H,Z) END BLOCK C BIT b,r ----------------------------------------------------------- REMOTE BLOCK BIT L=IAND(OP,56)/8 J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=MEM(REG(2)*256+REG(3)+1) ELSE K=MEM(IAND(INDEX(INDREG)+OFF,65535)+1) ENDIF Z=ZERO(IAND(K,2**L),8) ELSE Z=ZERO(IAND(REG(J),2**L),8) ENDIF H=1 N=0 END BLOCK C RES b,r ----------------------------------------------------------- REMOTE BLOCK RES L=IAND(OP,56)/8 J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF MEM(K)=IAND(MEM(K),255-2**L) ELSE REG(J)=IAND(REG(J),255-2**L) ENDIF END BLOCK C SET b,r ----------------------------------------------------------- REMOTE BLOCK SET L=IAND(OP,56)/8 J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF MEM(K)=IOR(MEM(K),2**L) ELSE REG(J)=IOR(REG(J),2**L) ENDIF END BLOCK C RLC r ----------------------------------------------------------- REMOTE BLOCK RLC J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF C=IAND(MEM(K),128)/128 MEM(K)=MEM(K)*2+C V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE C=IAND(REG(J),128)/128 REG(J)=REG(J)*2+C V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF H=0 N=0 END BLOCK C RRC r ----------------------------------------------------------- REMOTE BLOCK RRC J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF C=IAND(MEM(K),1) MEM(K)=IAND(MEM(K)/2,127)+C*128 V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE C=IAND(REG(J),1) REG(J)=IAND(REG(J)/2,127)+C*128 V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF H=0 N=0 END BLOCK C RL r ----------------------------------------------------------- REMOTE BLOCK RL J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF MEM(K)=MEM(K)*2+C C=IAND(MEM(K),256)/256 V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE REG(J)=REG(J)*2+C C=IAND(REG(J),256)/256 V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF H=0 N=0 END BLOCK C RR r ----------------------------------------------------------- REMOTE BLOCK RR J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF M=IAND(MEM(K),255)+C*256 C=IAND(M,1) MEM(K)=M/2 V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE M=IAND(REG(J),255)+C*256 C=IAND(M,1) REG(J)=M/2 V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF H=0 N=0 END BLOCK C SLA r ----------------------------------------------------------- REMOTE BLOCK SLA J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF MEM(K)=MEM(K)*2 C=IAND(MEM(K),256)/256 V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE REG(J)=REG(J)*2 C=IAND(REG(J),256)/256 V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF H=0 N=0 END BLOCK C SRA r ----------------------------------------------------------- REMOTE BLOCK SRA J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF C=IAND(MEM(K),1) MEM(K)=IAND(MEM(K)/2,127)+IAND(MEM(K),128) V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE C=IAND(REG(J),1) REG(J)=IAND(REG(J)/2,127)+IAND(REG(J),128) V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF N=0 END BLOCK C SRL r ----------------------------------------------------------- REMOTE BLOCK SRL J=IEOR(IAND(OP,7),6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+OFF,65535)+1 ENDIF C=IAND(MEM(K),1) MEM(K)=IAND(MEM(K)/2,127) V=PARITY(MEM(K)) S=SGN(MEM(K),8) Z=ZERO(MEM(K),8) ELSE C=IAND(REG(J),1) REG(J)=IAND(REG(J)/2,127) V=PARITY(REG(J)) S=SGN(REG(J),8) Z=ZERO(REG(J),8) ENDIF H=0 N=0 END BLOCK C LD r,d ----------------------------------------------------------- REMOTE BLOCK LDIMM J=IEOR(IAND(OP,56)/8,6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+MEM(PC+1),65535)+1 CALL INCPC(1) ENDIF MEM(K)=MEM(PC+1) ELSE REG(J)=MEM(PC+1) ENDIF CALL INCPC(1) END BLOCK C INC r ----------------------------------------------------------- REMOTE BLOCK INC J=IEOR(IAND(OP,56)/8,6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+MEM(PC+1),65535)+1 CALL INCPC(1) ENDIF CALL SUM(8,MEM(K),1,0,MEM(K),X,V,S,N,H,Z) ELSE CALL SUM(8,REG(J),1,0,REG(J),X,V,S,N,H,Z) ENDIF END BLOCK C DEC r ----------------------------------------------------------- REMOTE BLOCK DEC J=IEOR(IAND(OP,56)/8,6) IF(J.EQ.0)THEN IF (INDREG.EQ.0) THEN K=REG(2)*256+REG(3)+1 ELSE K=IAND(INDEX(INDREG)+MEM(PC+1),65535)+1 CALL INCPC(1) ENDIF CALL DIFF(8,MEM(K),1,0,MEM(K),X,V,S,N,H,Z) ELSE CALL DIFF(8,REG(J),1,0,REG(J),X,V,S,N,H,Z) ENDIF END BLOCK C JP c,nn ----------------------------------------------------------- REMOTE BLOCK JP IF (OP.EQ.233) THEN IF (INDREG.NE.0) THEN K=INDEX(INDREG) ELSE K=REG(3)+256*REG(2) ENDIF PC=IAND(MEM(IAND(K,65535)+1)+256*MEM(IAND(K+1,65535)+1),65535) ELSE CALL INCPC(2) IF (COND(IAND(OP,56)/8,C,V,S,Z).OR.OP.EQ.195) PC= $ IAND(MEM(IAND(PC-2,65535)+1)+256*MEM(IAND(PC-1,65535)+1),65535) ENDIF END BLOCK C CALL c,nn ----------------------------------------------------------- REMOTE BLOCK CALL J=IAND(OP,56)/8 PC=PC+2 OPAND=OPAND+2 IF (COND(J,C,V,S,Z).OR.OP.EQ.205) THEN MEM(IAND(SP-1,65535)+1)=PC/256 MEM(IAND(SP-2,65535)+1)=PC PC= $ IAND(MEM(IAND(PC-2,65535)+1)+256*MEM(IAND(PC-1,65535)+1),65535) SP=SP-2 ENDIF END BLOCK C IN r,(C) ----------------------------------------------------------- REMOTE BLOCK IN J=IEOR(IAND(OP,56)/8,6) K=REG(7) REG(J)=PORTI(K,R) V=PARITY(REG(J)) S=SGN(REG(J),8) N=0 H=0 Z=ZERO(REG(J),8) END BLOCK C OUT (C),r ----------------------------------------------------------- REMOTE BLOCK OUT ADDR=REG(7) J=IEOR(IAND(OP,56)/8,6) CALL PORTO(ADDR,REG(J)) END BLOCK C LD rr,(nn) ----------------------------------------------------------- REMOTE BLOCK LDMEM IF (IAND(OP,207).EQ.75) THEN K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) K=MEM(IAND(K,65535)+1)+256*MEM(IAND(K+1,65535)+1) CALL SINGLE(K,OP,REG,SP) ELSE C LD (nn),rr D=DOUBLE(OP,REG,SP) K=MEM(PC+1)+256*MEM(IAND(PC+1,65535)+1) MEM(IAND(K,65535)+1)=D MEM(IAND(K+1,65535)+1)=D/256 ENDIF CALL INCPC(2) END BLOCK C ADD HL,rr ----------------------------------------------------------- REMOTE BLOCK ADDD IF (INREG.NE.0) THEN K=INDEX(INDREG) ELSE K=REG(3)+256*REG(2) ENDIF CALL SUM(16,K,DOUBLE(OP,REG,SP),0,J,C,V,S,N,H,Z) CALL SINGLE(J,OP,REG,SP) END BLOCK C END C C Sum I and J into K (& carry if appropriate). Set flags. C B = no. of bits. SUBROUTINE SUM(B,I,J,OP,K,C,V,S,N,H,Z) IMPLICIT INTEGER (A-Z) K=IAND(I,2**B-1)+IAND(J,2**B-1) IF (IAND(OP,8).EQ.8) K=K+C C=IAND(K,2**B)/2**B V=OVER(B,I,J,K) S=SGN(K,B) N=0 H=IAND(IAND(I,2**(B-4)-1)+IAND(J,2**(B-4)-1),2**(B-4))/2**(B-4) Z=ZERO(K,B) RETURN END C C Subtract J from I put in K (& carry if appropriate). Set flags. C B = no. of bits. C SUBROUTINE DIFF(B,I,J,OP,K,C,V,S,N,H,Z) IMPLICIT INTEGER (A-Z) K=IAND(I,2**B-1)-IAND(J,2**B-1) IF (IAND(OP,8).EQ.8) K=K-C C=IAND(K,2**B)/2**B V=OVER(B,I,-J,K) S=SGN(K,B) N=1 H=IAND(IAND(I,2**(B-4)-1)-IAND(J,2**(B-4)-1),2**(B-4))/2**(B-4) Z=ZERO(K,B) RETURN END C C Check for 2's compliment overflow to set P/V flag C FUNCTION OVER(L,I,J,K) INTEGER SGN,OVER IF (SGN(I,L).EQ.SGN(J,L).AND.SGN(K,L).NE.SGN(I,L)) THEN OVER=1 ELSE OVER=0 ENDIF RETURN END C C Perform integer bitwise AND function C FUNCTION IAND(I,J) EQUIVALENCE(A,IAND) A=AND(I,J) RETURN END C C Perform integer bitwise exclusive OR function C FUNCTION IEOR(I,J) EQUIVALENCE(A,IEOR) A=EOR(I,J) RETURN END C C Perform integer bitwise OR function C FUNCTION IOR(I,J) EQUIVALENCE(A,IOR) A=OR(I,J) RETURN END C C Find sign of an 8 or 16 bit number for S flag C FUNCTION SGN(I,J) INTEGER SGN SGN=IAND(I,2**(J-1))/2**(J-1) RETURN END C C Check for an 8 or 16 bit number being zero for Z flag C FUNCTION ZERO(I,J) INTEGER ZERO IF (IAND(I,2**J-1).EQ.0) THEN ZERO=1 ELSE ZERO=0 ENDIF RETURN END C C Calculate parity for an 8 bit number C FUNCTION PARITY(I) INTEGER PARITY K=0 DO 56 J=1,8 K=K+(IAND(I,2**(J-1))/2**(J-1)) 56 CONTINUE PARITY=IAND(K,1) RETURN END C C Get a byte from port ADDR at time TIME C FUNCTION PORTI(ADDR,TIME) INTEGER ADDR,PORTI,TIME IF (ADDR.EQ.1) THEN READ(3,347) PORTI ELSEIF (ADDR.EQ.2) THEN PORTI= $ IFIX(127.5+127.5*SIN(2.0*3.14159*50*(FLOAT(TIME)/1000.0))+.5) ELSEIF (ADDR.EQ.3) THEN PORTI=127 ELSE READ(9,347) PORTI 347 FORMAT(Z2) ENDIF RETURN END C C Output a byte to port ADDR C SUBROUTINE PORTO(ADDR,REG) INTEGER ADDR,REG WRITE(6,*)ADDR,REG IF (ADDR.EQ.1) THEN WRITE(11,345) ADDR,REG ELSE WRITE(6,345) ADDR,REG 345 FORMAT(' ',Z4,4X,Z2) ENDIF RETURN END C C Check flags for condition specified by J and return true or false C FUNCTION COND(J,C,V,S,Z) LOGICAL COND INTEGER C,V,S,Z I=IAND(J,6) IF (I.EQ.0) THEN K=Z ELSEIF (I.EQ.2) THEN K=C ELSEIF (I.EQ.4) THEN K=V ELSE K=S ENDIF K=IEOR(K,J-I) IF (K.EQ.0) THEN COND=.TRUE. ELSE COND=.FALSE. ENDIF RETURN END C C Write double byte number out to two registers or stack pointer C depending on opcode being executed C FUNCTION DOUBLE(OP,REG,SP) INTEGER OP,REG(7),DOUBLE,SP J=IEOR(IAND(OP/8,6),6) IF (J.EQ.0) THEN DOUBLE=SP ELSE DOUBLE=REG(J+1)+256*REG(J) ENDIF RETURN END C C Read double byte from two registers or stack pointer C depending on opcode being executed C SUBROUTINE SINGLE(D,OP,REG,SP) INTEGER D,OP,REG(7),SP J=IEOR(IAND(OP/8,6),6) IF (J.EQ.0) THEN SP=D ELSE REG(J)=D/256 REG(J+1)=IAND(D,255) ENDIF RETURN END C C Increment PC and operands counter by INC C SUBROUTINE INCPC(INC) COMMON PC,OPAND INTEGER PC,OPAND,INC PC=IAND(PC+INC,65535) OPAND=OPAND+INC RETURN END