Facebook
From The8BitEnthusiast, 2 Months ago, written in Python.
Embed
Download Paste or View Raw
Hits: 108
  1. output1 = [0] * 32768
  2. output2 = [0] * 32768
  3.  
  4. # define opcodes
  5. LDA =  0b00001
  6. ADD =  0b00010
  7. SUB =  0b00011
  8. STA =  0b00100
  9. LDI =  0b00101
  10. JMP =  0b00110
  11. JZ  =  0b00111
  12. JC  =  0b01000
  13. OUT =  0b01110
  14. HALT = 0b01111
  15.  
  16. # define control signals
  17. HLT = 0b1000000000000000
  18. MI  = 0b0100000000000000
  19. RI  = 0b0010000000000000
  20. RO  = 0b0001000000000000
  21. IO  = 0b0000100000000000
  22. II  = 0b0000010000000000
  23. AI  = 0b0000001000000000
  24. AO  = 0b0000000100000000
  25. EO  = 0b0000000010000000
  26. SU  = 0b0000000001000000
  27. BI  = 0b0000000000100000
  28. OI  = 0b0000000000010000
  29. CE  = 0b0000000000001000
  30. CO  = 0b0000000000000100
  31. J   = 0b0000000000000010
  32. FI  = 0b0000000000000001
  33.  
  34. # define CPU flags EEPROM address bits
  35. CF_ADDR_BIT = 14
  36. ZF_ADDR_BIT = 13
  37.  
  38. # define microcode array
  39. microcode = [
  40.     [LDA, MI|CO, RO|II|CE, MI|CO, RO|MI|CE, RO|AI] ,
  41.     [ADD, MI|CO, RO|II|CE, MI|CO, RO|MI|CE, RO|BI, AI|EO|FI],
  42.     [SUB, MI|CO, RO|II|CE, MI|CO, RO|MI|CE, RO|BI, AI|EO|SU|FI],
  43.     [STA, MI|CO, RO|II|CE, MI|CO, RO|MI|CE, AO|RI],
  44.     [LDI, MI|CO, RO|II|CE, MI|CO, RO|AI|CE],
  45.     [JMP, MI|CO, RO|II|CE, MI|CO, RO|J],
  46.     [JZ,  MI|CO, RO|II|CE, CE],
  47.     [JC,  MI|CO, RO|II|CE, CE],
  48.     [OUT, MI|CO, RO|II|CE, AO|OI],
  49.     [HALT, MI|CO, RO|II|CE, HLT]
  50. ]
  51.  
  52. # populate ROM with the first two micro-instruction stages for all possible opcodes
  53. for i in range(4096):
  54.     address = i << 3
  55.     output1[address] = ((MI|CO) & 0xFF00) >> 8
  56.     output1[address+1] = ((RO|II|CE) & 0xFF00) >> 8
  57.     output2[address] = (MI|CO) & 0x00FF
  58.     output2[address+1] = (RO|II|CE) & 0x00FF
  59.  
  60. # load ROM with micro-instructions    
  61. for cf in [0,1]:
  62.     for zf in [0,1]:
  63.  
  64.         # calculate base address as a function of CF and ZF
  65.         base_addr = (cf * 2 ** CF_ADDR_BIT) | (zf * 2 ** ZF_ADDR_BIT)
  66.  
  67.         # set up JC microcode according to CF flag value
  68.         if cf == 1:
  69.             # override default JC micro-code for CF = 1
  70.             microcode[7] = [JC, MI|CO, RO|II|CE, MI|CO, RO|J]
  71.         else:
  72.             microcode[7] = [JC, MI|CO, RO|II|CE, CE]
  73.  
  74.         # set up JZ microcode according to ZF flag value
  75.         if zf == 1:
  76.             # override default JZ micro-code for ZF = 1
  77.             microcode[6] = [JZ, MI|CO, RO|II|CE, MI|CO, RO|J]
  78.         else:
  79.             microcode[6] = [JZ, MI|CO, RO|II|CE, CE]
  80.  
  81.         # populate micro-code
  82.         for inst in microcode:
  83.             opCode = inst[0]
  84.             signals = inst[1:]
  85.             for stage, signal in enumerate(signals):
  86.                 address = base_addr | (opCode << 3) | stage
  87.                 output1[address] = (signal & 0xFF00) >> 8
  88.                 output2[address] = signal & 0x00FF
  89.  
  90. with open('eeprom1.bin', 'wb') as file1:
  91.     for x in output1:
  92.         file1.write(x.to_bytes(1, byteorder='big', signed=False))
  93.  
  94. with open('eeprom2.bin', 'wb') as file2:
  95.     for x in output2:
  96.         file2.write(x.to_bytes(1, byteorder='big', signed=False))
  97.  
  98.