Advertisement
Guest User

Untitled

a guest
Feb 1st, 2021
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.28 KB | None | 0 0
  1.  
  2. private final int ram_size_in_bytes = 0x4000;
  3. private final int kbd_buf_head_addr = 0x7000;
  4. private final int kbd_buf_tail_addr = 0x7002;
  5. private final int kbd_buf_out_addr = 0x7004;
  6. private final int wai_addr = 0x7008;
  7. private final int utime_addr = 0x700A;
  8. private final int bus_output_addr = 0x7500;
  9. private final int bus_input_addr = 0x7600;
  10.  
  11. // Video RAM.
  12. public byte[] video_ram = new byte[10240];
  13. // Main RAM.
  14. public short[] ram = new short[ram_size_in_bytes / 2];
  15. // Bus input window.
  16. public short[] cpu_bus_window = new short[128];
  17.  
  18. // Ring buffer keyboard.
  19. public byte[] keyboard_buf = new byte[16];
  20. public byte keyboard_buf_head = 0;
  21. public byte keyboard_buf_tail = 0;
  22.  
  23. // Address input and output windows on bus.
  24. public int peripheral_id = 1;
  25. public int cpu_id = 0;
  26.  
  27. // CPU.
  28. // Program counter.
  29. public short pc = 0;
  30. // Return stack.
  31. public short[] rstack = new short[32];
  32. public byte rstack_pointer = 0;
  33. // Data stack.
  34. public short[] dstack = new short[32];
  35. public short dstack_T = 0;
  36. public short dstack_N = 0;
  37. public byte dstack_depth = 0;
  38.  
  39. private final short forth_true = (short)0xFFFF;
  40. private final short forth_false = 0;
  41.  
  42. private boolean wai_flag = false;
  43.  
  44. public boolean isTurnedOn = false;
  45.  
  46. private String inventoryName = "CPU";
  47. public ItemStack[] inventory;
  48.  
  49. private boolean busTimeout = false;
  50. private INedoPeripheral peripheralCache = null;
  51.  
  52. private int conMask = 0;
  53.  
  54. public TileEntityCPU() {
  55. for (int i = 0; i < video_ram.length; i++) video_ram[i] = ' ';
  56. video_ram[0x2600] = 0; video_ram[0x2602] = 0; video_ram[0x2604] = 0;
  57. inventory = new ItemStack[getSizeInventory()];
  58. }
  59.  
  60. private void write_mem(int addr, short data) {
  61. if (addr < ram_size_in_bytes) {
  62. ram[addr >>> 1] = data;
  63. } else if ((addr >= ram_size_in_bytes) && (addr < ram_size_in_bytes + video_ram.length)) {
  64. video_ram[addr - ram_size_in_bytes] = (byte)data;
  65. } else if ((addr & 0xFFFE) == kbd_buf_head_addr) {
  66. keyboard_buf_head = (byte)(data & 0x0F);
  67. } else if ((addr & 0xFFFE) == wai_addr) {
  68. wai_flag = true;
  69. } else if ((addr & 0xFFFE) == 0x7012) {
  70. // Map device to bus window.
  71. if (peripheral_id != data) {
  72. if (peripheralCache != null) busTimeout = true;
  73. peripheral_id = data & 0xFF;
  74. }
  75. } else if ((addr >= bus_output_addr) && (addr <= bus_output_addr + 0xFF) && (cpu_id != peripheral_id)) {
  76. if (peripheralCache == null) {
  77. peripheralCache = NedoBusUtils.searchPeripheralBlock(worldObj,
  78. new ChunkCoordinates(xCoord, yCoord, zCoord), conMask, peripheral_id);
  79. }
  80. if (peripheralCache == null) {
  81. busTimeout = true;
  82. } else {
  83. peripheralCache.busWrite(addr - bus_output_addr, data);
  84. }
  85. } else if ((addr >= bus_input_addr) && (addr <= bus_input_addr + 0xFF)) {
  86. cpu_bus_window[(addr - bus_input_addr) >>> 1] = data;
  87. }
  88. }
  89.  
  90. private short read_mem(int addr) {
  91. if (addr < ram_size_in_bytes) return ram[addr >>> 1];
  92. if ((addr & 0xFFFE) == kbd_buf_head_addr) return keyboard_buf_head;
  93. if ((addr & 0xFFFE) == kbd_buf_tail_addr) return keyboard_buf_tail;
  94. if ((addr & 0xFFFE) == kbd_buf_out_addr) return keyboard_buf[keyboard_buf_head];
  95. if ((addr >= bus_output_addr) && (addr <= bus_output_addr + 0xFF) && (cpu_id != peripheral_id)) {
  96. if (peripheralCache == null) {
  97. peripheralCache = NedoBusUtils.searchPeripheralBlock(worldObj,
  98. new ChunkCoordinates(xCoord, yCoord, zCoord), conMask, peripheral_id);
  99. }
  100. if (peripheralCache == null) {
  101. busTimeout = true;
  102. return 0;
  103. } else {
  104. return peripheralCache.busRead(addr - bus_output_addr);
  105. }
  106. } else if ((addr >= bus_input_addr) && (addr <= bus_input_addr + 0xFF)) {
  107. return cpu_bus_window[(addr - bus_input_addr) >>> 1];
  108. }
  109. if ((addr & 0xFFFE) == utime_addr) return (short)((System.currentTimeMillis() / 1000L) & 0xFFFF);
  110. if ((addr & 0xFFFE) == utime_addr + 2) return (short)((System.currentTimeMillis() / 1000L) >>> 16 );
  111. return 0;
  112. }
  113.  
  114. private short ALU(int op) {
  115. switch (op) {
  116. case 0: return dstack_T;
  117. case 1: return dstack_N;
  118. case 2: return (short)(dstack_T + dstack_N);
  119. case 3: return (short)(dstack_T & dstack_N);
  120. case 4: return (short)(dstack_T | dstack_N);
  121. case 5: return (short)((dstack_T << 8) | ((dstack_T >> 8) & 0xFF));
  122. case 6: return (short)~dstack_T;
  123. case 7: return (dstack_N == dstack_T) ? forth_true : forth_false;
  124. case 8: return (dstack_N < dstack_T) ? forth_true : forth_false;
  125. case 9: return (short)((dstack_T >> 1) & 0x7FFF);
  126. case 10: return (short)(dstack_T - 1);
  127. case 11: return rstack[rstack_pointer];
  128. case 12: return read_mem(((int)dstack_T) & 0xFFFF);
  129. case 13: return (short)(dstack_T << 1);
  130. case 14: return dstack_depth;
  131. case 15: return (((int)dstack_N & 0xFFFF) < ((int)dstack_T & 0xFFFF)) ? forth_true : forth_false;
  132. default: return 0;
  133. }
  134. }
  135.  
  136. private void execute_insn() {
  137. short dstack_T_buf = dstack_T;
  138. short istr = read_mem(pc << 1);
  139. if ((istr & 0x8000) != 0) {
  140. // literal.
  141. dstack_depth = (byte)((dstack_depth + 1) & 0x1F);
  142. dstack[dstack_depth] = dstack_N;
  143. dstack_N = dstack_T;
  144. dstack_T = (short)(istr & 0x7FFF);
  145. pc = (short)((pc + 1) & 0x1FFF);
  146. } else if ((istr & 0xE000) == 0) {
  147. // jump.
  148. pc = (short)(istr & 0x1FFF);
  149. } else if ((istr & 0xE000) == 0x2000) {
  150. // conditional jump.
  151. if (dstack_T != 0) {
  152. pc = (short)((pc + 1) & 0x1FFF);
  153. } else {
  154. pc = (short)(istr & 0x1FFF);
  155. }
  156. dstack_T = dstack_N;
  157. dstack_N = dstack[dstack_depth];
  158. dstack_depth = (byte)((dstack_depth - 1) & 0x1F);
  159. } else if ((istr & 0xE000) == 0x4000) {
  160. // call.
  161. rstack_pointer = (byte)((rstack_pointer + 1) & 0x1F);
  162. rstack[rstack_pointer] = (short)(((pc + 1) & 0x1FFF) << 1);
  163. pc = (short)(istr & 0x1FFF);
  164. } else if ((istr & 0xE000) == 0x6000) {
  165. // ALU.
  166. // N -> [T]
  167. if ((istr & (1 << 5)) != 0 ) {
  168. write_mem(((int)dstack_T) & 0xFFFF, dstack_N);
  169. }
  170. // dstack+-
  171. if ((istr & 3) == 0) {
  172. dstack_T = ALU((istr >> 8) & 0x0F);
  173. if ((istr & (1 << 7)) != 0 ) dstack_N = dstack_T_buf; // T -> N
  174. } else if ((istr & 3) == 1) {
  175. dstack_T = ALU((istr >> 8) & 0x0F);
  176. dstack_depth = (byte)((dstack_depth + 1) & 0x1F);
  177. dstack[dstack_depth] = dstack_N;
  178. if ((istr & (1 << 7)) != 0 ) dstack_N = dstack_T_buf; // T -> N
  179. } else if ((istr & 3) == 2) {
  180. // Error.
  181. } else if ((istr & 3) == 3) {
  182. dstack_T = ALU((istr >> 8) & 0x0F);
  183. dstack_N = dstack[dstack_depth];
  184. dstack_depth = (byte)((dstack_depth - 1) & 0x1F);
  185. }
  186. // R -> PC
  187. if ((istr & (1 << 12)) != 0 ) {
  188. pc = (short)(rstack[rstack_pointer] >> 1);
  189. } else {
  190. pc = (short)((pc + 1) & 0x1FFF);
  191. }
  192. // rstack+-
  193. if (((istr >> 2) & 3) == 1) {
  194. rstack_pointer = (byte)((rstack_pointer + 1) & 0x1F);
  195. rstack[rstack_pointer] = dstack_T_buf;
  196. } else if (((istr >> 2) & 3) == 3) {
  197. rstack_pointer = (byte)((rstack_pointer - 1) & 0x1F);
  198. }
  199. }
  200. }
  201.  
  202. public void turnOn() throws IOException {
  203. if (inventory[0] == null) return;
  204. if (!(inventory[0].getItem() instanceof ItemEEPROM ||
  205. inventory[0].getItem() instanceof ItemForthROM)) return;
  206. for (int i = 0; i < video_ram.length; i++) video_ram[i] = ' ';
  207. video_ram[0x2600] = 0; video_ram[0x2602] = 0; video_ram[0x2604] = 0;
  208. keyboard_buf_head = 0; keyboard_buf_tail = 0;
  209. for (int i = 0; i < keyboard_buf.length; i++) keyboard_buf[i] = 0;
  210. pc = 0;
  211. rstack_pointer = 0;
  212. for (int i = 0; i < rstack.length; i++) rstack[i] = 0;
  213. dstack_depth = 0; dstack_N = 0; dstack_N = 0;
  214. for (int i = 0; i < dstack.length; i++) dstack[i] = 0;
  215. if (inventory[0].getItem() instanceof ItemForthROM) {
  216. InputStream input =
  217. getClass().getResourceAsStream("/assets/nedocomputers/forth/forth.bin");
  218. DataInputStream d_stream = new DataInputStream(input);
  219. try {
  220. for (int i = 0; i < ram.length; i++) {
  221. byte b1 = d_stream.readByte();
  222. byte b2 = d_stream.readByte();
  223. ram[i] = (short)(((int)b1 & 0xFF) + ((int)b2 & 0xFF) * 256);
  224. }
  225. } catch (IOException e) {
  226. e.printStackTrace();
  227. }
  228. isTurnedOn = true;
  229. } else if (inventory[0].getItem() instanceof ItemEEPROM) {
  230. if (inventory[0].hasTagCompound()) {
  231. NBTTagCompound nbtTag = inventory[0].getTagCompound();
  232. if (nbtTag.hasKey("id")) {
  233. String id = nbtTag.getString("id");
  234. List files = new ArrayList();
  235. File dir = new File(DimensionManager.getCurrentSaveRootDirectory(), Settings.EEPROM_DIR);
  236. if (!dir.exists() || !dir.isDirectory())
  237. dir.mkdirs();
  238. for (File f : dir.listFiles())
  239. if (f.isFile())
  240. files.add(f.getName());
  241. if (files.contains(id.concat(".bin"))) {
  242. byte[] ram_buf = new byte[ram.length * 2];
  243. FileInputStream fs = new FileInputStream(new File(dir, id.concat(".bin")));
  244. fs.read(ram_buf, 0, ram_size_in_bytes);
  245. fs.close();
  246. ByteBuffer.wrap(ram_buf).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(ram);
  247. isTurnedOn = true;
  248. }
  249. } else if (nbtTag.hasKey("ram")) {
  250. byte[] ram_buf = nbtTag.getByteArray("ram");
  251. ByteBuffer.wrap(ram_buf).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(ram);
  252. isTurnedOn = true;
  253. }
  254. }
  255. }
  256. }
  257.  
  258. public void turnOff() {
  259. for (int i = 0; i < video_ram.length; i++) video_ram[i] = ' ';
  260. video_ram[0x2600] = 0; video_ram[0x2602] = 0; video_ram[0x2604] = 0;
  261. this.isTurnedOn = false;
  262. }
  263.  
  264. public void reset() {
  265. for (int i = 0; i < video_ram.length; i++) video_ram[i] = ' ';
  266. video_ram[0x2600] = 0; video_ram[0x2602] = 0; video_ram[0x2604] = 0;
  267. pc = 0;
  268. rstack_pointer = 0;
  269. for (int i = 0; i < rstack.length; i++) rstack[i] = 0;
  270. dstack_depth = 0; dstack_N = 0; dstack_N = 0;
  271. for (int i = 0; i < dstack.length; i++) dstack[i] = 0;
  272. }
  273.  
  274.  
  275.  
  276. @Override
  277. public void updateEntity() {
  278. int cnt = Settings.INSTRUCTIONS_PER_TICK;
  279. wai_flag = false;
  280. busTimeout = false;
  281. peripheralCache = null;
  282. while ((cnt > 0) && !wai_flag && !busTimeout && isTurnedOn) {
  283. execute_insn();
  284. cnt--;
  285. }
  286. }
  287.  
  288. public void KeyTyped(byte chr) {
  289. if (isTurnedOn) {
  290. if ((chr != 0xFF) && (((keyboard_buf_tail + 1) % keyboard_buf.length) != keyboard_buf_head)) {
  291. keyboard_buf_tail = (byte)((keyboard_buf_tail + 1) % keyboard_buf.length);
  292. keyboard_buf[keyboard_buf_tail] = chr;
  293. }
  294. }
  295. }
  296.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement