cardiograph-computer/2023-09-03.md

265 lines
9.9 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dev notes — 2023-09-03
## Todos
- [ ] add yesterdays reading to dev notes
- chip8 stuff
- js stuff
- [x] reconsider revised ISA
- + a more-binary simulator
- [ ] set up semi-standard js eslint
- remember: meowbit
## Misc. references
TODO: organize these
- [Assembly in One Step](https://dwheeler.com/6502/oneelkruns/asm1step.html)
- [How to write an emulator (CHIP-8 interpreterhttp://www.emulator101.com/6502-addressing-modes.html)](https://web.archive.org/web/20180121070101/http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/)
- http://www.cosmacelf.com/publications/books/cosmac-elf-manual.pdf
- http://archive.6502.org/datasheets/wdc_w65c02s_mar_2000.pdf
- Weisbecker, Joseph, "[Build The COSMAC "ELF" A Low-Cost Experimenter's Microcomputer](http://www.exemark.com/Microcontrollers/PopularElecwebc.pdf)" (re-typed PDF)
- [The UNO1802: A Cosmac Elf for $13 in parts...](http://obsolescenceguaranteed.blogspot.com/2017/08/the-uno1802-cosmac-elf-for-15-in-parts.html)
- [Understanding the MAR and the MDR](https://web.archive.org/web/20170328171842/http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Overall/mar.html)
From earlier:
- [How does a microcontroller boot and startup, step by step?](https://electronics.stackexchange.com/questions/224156/how-does-a-microcontroller-boot-and-startup-step-by-step)
- http://www.6502.org
- [6502 PRIMER: Building your own 6502 computer](http://wilsonminesco.com/6502primer/index.html)
- http://visual6502.org/JSSim/
- [KIM-1 Microcomputer Module User Manual](http://retro.hansotten.nl/uploads/6502docs/usrman.htm) (HTML version)
- [How does a DMA controller work?](https://softwareengineering.stackexchange.com/questions/272470/how-does-a-dma-controller-work)
- [Photo of a KIM-1](http://retro.hansotten.nl/wp-content/uploads/2020/11/20201106_131253a-1-scaled.jpg)
- [Punched Cards & Paper Tape](https://www.computerhistory.org/revolution/memory-storage/8/326)
- [Semyon Korsakov](https://en.wikipedia.org/wiki/Semyon_Korsakov)
- [Punched Card Input/Output Devices](http://www.ibm1130.net/functional/Cards.html)
- [IBM Punched Card Stock Specifications](https://ibm1401.computerhistory.org/CardStockSpecifications.html)
- [The IBM 029 Key Punch](http://www.columbia.edu/cu/computinghistory/029.html)
- http://retro.hansotten.nl/6502-sbc/kim-1-manuals-and-software/kim-1-simulator/
- https://craftinginterpreters.com/a-map-of-the-territory.html
- "2023-08-10 cardiograph reference" tab group:
- [Inside the vintage 74181 ALU chip: how it works and why it's so strange](www.righto.com/2017/03/inside-vintage-74181-alu-chip-how-it.html?m=1)
- [Software woven into wire: Core rope and the Apollo Guidance Computer](www.righto.com/2019/07/software-woven-into-wire-core-rope-and.html?m=0)
- [Arithmetic logic unit - Wikipedia](en.m.wikipedia.org/wiki/Arithmetic_logic_unit)
- [29c05c9d7985b673e98f32fbf43ae628.jpg 1,960×2,014 pixels](i.pinimg.com/originals/29/c0/5c/29c05c9d7985b673e98f32fbf43ae628.jpg)
- [My First Program — ICL CES - Computer Education in Schools](iclces.uk/articles/first_cesil_program.html)
- [CSIRO Computing History Appendix 7: CSIRO Computing Museum / Artefacts CSIROpedia](csiropedia.csiro.au/csiro-computing-history-appendix-7-artefacts/)
- [CHIP-8 in Common Lisp: Input / Steve Losh](stevelosh.com/blog/2016/12/chip8-input/)
- [CHIP-8 virtual machine specification](tonisagrista.com/blog/2021/chip8-spec/)
- [Table of Contents - by Casey Muratori - Computer, Enhance!](www.computerenhance.com/p/table-of-contents)
- [Turing Complete](turingcomplete.game/)
- [6502 Registers](web.archive.org/web/20210626024532/http://www.obelisk.me.uk/6502/registers.html)
- [Easy 6502 by skilldrick](skilldrick.github.io/easy6502/)
- [bitsavers.org](www.bitsavers.org/components/rca/cosmac/COSMAC_VIP_Instruction_Manual_1978.pdf)
- [COSMAC Elf 2000](www.sparetimegizmos.com/Hardware/Elf2K.htm)
- [A Short Course In Programming by Tom Pittman | COSMAC ELF](www.cosmacelf.com/publications/books/short-course-in-programming.html)
- [A Short Course In Programming](www.ittybittycomputers.com/IttyBitty/ShortCor.htm)
- [exemark.com](www.exemark.com/Microcontrollers/PopularElecwebc.pdf)
- [Build The COSMAC "ELF" Part 1](billr.incolor.com/elf/html/elf-1-33.htm)
- [GitHub - tebl/RC1802-Cosmac-ELF: With the RC6502-project for making an Apple 1 replica done I wanted to do something different, so I started designing a simple version of the RCA 1802-based Cosmac ELF instead.](github.com/tebl/RC1802-Cosmac-ELF)
- [More musings of computers past: Popular Electronics, the COSMAC ELF | brainwagon](brainwagon.org/2014/07/27/more-musings-of-computers-past-popular-electronics-the-cosmac-elf/)
## Startup: correction
It doesnt execute “JMP $FF.” It just sets the IP to $FF on reset, and you put a JMP there in ROM.
- [ ] TODO: update docs elsewhere
## Detailed CPU design/low-level simulator
### Revising ISA
[See notes from 2023-08-23](2023-08-23.md)
### Instruction cycle
**For now, treat each instruction as taking one cycle.**
I started making notes on this, which I am leaving below… but this doesnt seem useful at this point so Im forgetting about it for now.
- references
- [Understanding the MAR and the MDR](https://web.archive.org/web/20170328171842/http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Overall/mar.html)
- https://en.wikipedia.org/wiki/Three-state_logic
* 1 cycle - fetch
* copy IP to MAR
* send Read command on memory control line
* copy data from data bus to instruction register
* calculate next IP (if no branch); IP += 2
* 1 cycle - decode
* (i think:) split instruction data into addressing mode, op, data
* calculate branch target
* 2 cycles - execute
* 1 cycle - memory read
* 1 cycle - compute
* 1 cycle - write back
### Sketch in JS
TODO:
- [ ] Figure out how to do DMA
- [ ] Learn more about how the 1802 does DMA
- http://www.cosmacelf.com/publications/books/cosmac-elf-manual.pdf
- http://www.exemark.com/Microcontrollers/PopularElecwebc.pdf
References:
- 6502 SYNC pin
- "The SYNC output is provided to identify those cycles during which the microprocessor is fetching an OpCode. The SYNC line goes high during the clock cycle of an opcode fetch and stays high for the entire cycle. If the RDY line is pulled low during the clock cycle in which SYNC went high, the processor will stop in its current state and will remain in the state until the RDY line goes high. In this manner, the SYNC signal can be used to control RDY to cause single instruction execution."
- -- http://archive.6502.org/datasheets/wdc_w65c02s_mar_2000.pdf
```
class CPU {
constructor (memory, addressBus, dataBus, memoryReadSignal, memoryWriteSignal, cpuWait) {
this.memory = memory;
// TODO: move buses etc to this.pins.foo
this.pins = {
dataBus : dataBus,
addressBus : addressBus,
memoryReadSignal : 0,
wait : cpuWait, // If 1, execution is paused (cf. 6502 RDY pin)
// readNotWrite : 0 // 1 if want to read mem // TODO lower level than i need right now?
}
this.reset();
}
IP = 0;
A = 0;
flags = 0b00000000;
instruction = 0x00;
//What do I want for interrupts…?
// interruptRequest = 0;
// TODO: can it be a simple setup with fixed instruction cycle length pls?
_instructionCycleStep = 0;
tickClock () {
if (this.wait) return false;
switch (this._instructionCycleStep) {
// Fetch
case (0) {
// this.instruction = this.memory.read(this.IP);
this.readWriteControl = 1; // TODO
break;
} case (1) {
// initiate read
this.pins.addressBus = this.IP;
this.pins.memoryReadSignal = 1;
} case (2) {
// complete read
this.pins.memoryReadSignal = 0;
this.instruction = this.dataBus;
}
// TODO: continue switch statement
// ...
/*
// decode
const op = this._decode(this.instruction);
// execute
op();
*/
}
}
reset () {
// this.IP = this.memory.read(0xFF);
this.IP = 0xFF;
this.A = 0;
this.flags = 0b00000000;
this.pins.dataBus = 0b00000000;
this._instructionCycleStep = 0;
this.debug.running = true;
}
_decode (instruction) {
const instrs = {
0x00: end,
// TODO etc
};
return instrs[instruction];
}
debug = {
// TODO include the rest of the stuff that I have here in the current version
running: false,
}
}
```
```
class Memory {
// ROM format: { addr: nn, data: nn }
constructor (sizeInBytes, ROM, addressBus, dataBus, readSignal, writeSignal) {
// memory format: [ { data: nn, type: str } ]
this.memory = new Array(sizeInBytes);
objectForEach(ROM, (byte) => {
this.memory[byte.addr] = { data: byte[data], type: ROM };
})
this.pins = {
addressBus: addressBus,
dataBus: dataBus,
readSignal: readSignal,
writeSignal: writeSignal,
}
}
tickClock () {
if (this.pins.readSignal) this._read();
if (this.pins.writeSignal) this._write();
}
_read () {
this.pins.dataBus = this.memory[this.pins.addressBus];
}
_write () {
if (this.memory[this.pins.addressBus].type === ROM) throw new Error(Attempted write to ROM);
this.memory[this.pins.addressBus].data = data;
}
}
function objectForEach (object, fn) {
return Object.keys(object).forEach(key => fn(key, object[key]));
}
```
```
/** DMA controller for screen, keypad... **/
class IO {
// TODO…
constructor (addressBus, dataBus, cpuWaitPin) {
// ...
}
}
```
cardiograph.js:
```
// TODO: these might all need to be functions?
let dataBus = 0;
let addressBus = 0;
let memoryReadSignal = 0;
let memoryWriteSignal = 0;
let cpuWait = 0;
let rom = // TODO read in…
let memory = new Memory(256, rom, addressBus, dataBus, memoryReadSignal, memoryWriteSignal);
let cpu = new CPU(memory, addressBus, dataBus, memoryReadSignal, memoryWriteSignal, cpuWait);
```
Sketch is missing:
- DMA stuff (IO)
- actual instruction decoding/execution