备忘录 1:从零开始构建的 6502 计算机,使用 Minitel 作为终端。
Memo-1: A 6502 computer built from scratch, using a Minitel as its terminal

原始链接: https://github.com/MemoireMorte/Memo-1

**Memo-1** 是一款由 Benoit Aveline 设计的、基于 65C02 处理器的教育型微型计算机。该系统运行频率为 1MHz,配备 32KB RAM、16KB ROM、用于输入输出的 65C22 VIA,以及用于与 Minitel 1b 终端进行串行通信的 6551 ACIA。 其硬件架构将 64KB 的地址空间分配给了 RAM、VIA、ACIA、一个 8KB 的外部扩展槽以及系统 ROM。VIA 支持两个雅达利(Atari)风格的游戏摇杆接口,并通过音频发生器提供音频输出。 系统启动后,用户可以通过自定义菜单选择运行 WOZMON、MS-BASIC,或执行从扩展槽检测到的外部 ROM 中的代码。该系统专为爱好者设计,源代码兼容 `ca65`/`ld65` 工具链。项目提供硬件原理图、构建说明和 ROM 文件,供有兴趣自行组装的用户使用。该项目采用知识共享署名-非商业性使用-相同方式共享(BY-NC-SA)协议授权,旨在为学习 6502 架构和底层系统编程提供一个实用的实践工具。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Memo-1:一台从零构建的 6502 计算机,使用 Minitel 作为终端 (github.com/memoiremorte) 16 点,由 sciences44 发布于 1 小时前 | 隐藏 | 过往 | 收藏 | 1 条评论 帮助 drivers99 22 分钟前 [–] 非常酷。看到文末致谢 Ben Eater 并不意外。我谦逊地建议除了 Gerber 文件外,也一并提供 CAD (KiCad?) 源文件。 回复 考虑申请 YC 2026 年秋季班!申请截止日期为 7 月 27 日。 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

A simple 65C02 based computer for fun and learning purpose. A bill of materials and build instructions can be found alongside the roms here

The Memo-1 consists on a 65C02 CPU running at 1Mhz, crudely attached to 32K of ram, 16K of rom, and has a 65C22 via and a 6551 ACIA (NOT the W65C51). The system is thought to have 8k of rom available as extension, and to be linked to a Minitel 1b as terminal.

High nibble (A15..A12) | Hex range      | Selection
-----------------------+----------------+-----------------
0000 (0x0)             | 0000 - 0FFF    | RAM
0001 (0x1)             | 1000 - 1FFF    | RAM
0010 (0x2)             | 2000 - 2FFF    | RAM
0011 (0x3)             | 3000 - 3FFF    | RAM
0100 (0x4)             | 4000 - 4FFF    | RAM
0101 (0x5)             | 5000 - 5FFF    | RAM
0110 (0x6)             | 6000 - 6FFF    | RAM
0111 (0x7)             | 7000 - 7FFF    | RAM
-----------------------+----------------+-----------------
1000 (0x8)             | 8000 - 8FFF    | VIA
1001 (0x9)             | 9000 - 9FFF    | ACIA
-----------------------+----------------+-----------------
1010 (0xA)             | A000 - AFFF    | External slot
1011 (0xB)             | B000 - BFFF    | External slot
-----------------------+----------------+-----------------
1100 (0xC)             | C000 - CFFF    | ROM
1101 (0xD)             | D000 - DFFF    | ROM
1110 (0xE)             | E000 - EFFF    | ROM
1111 (0xF)             | F000 - FFFF    | ROM

The external slot is a 32-pin connector (J4) exposing the full CPU bus.

Pin | Signal      Pin | Signal
----+---------    ----+---------
  1 | A0           2 | D0
  3 | A1           4 | D1
  5 | A2           6 | D2
  7 | A3           8 | D3
  9 | A4          10 | D4
 11 | A5          12 | D5
 13 | A6          14 | D6
 15 | A7          16 | D7
 17 | A8          18 | GND
 19 | A9          20 | /Ext select
 21 | A10         22 | CLK
 23 | A11         24 | /IRQ
 25 | A12         26 | /NMI
 27 | A13         28 | /RES
 29 | A14         30 | R/W
 31 | A15         32 | +5V

Odd pins carry the address bus (A0–A15), even pins 2–16 carry the data bus (D0–D7), and the remaining even pins carry control signals. The /Ext select signal is asserted low when the CPU addresses $A000–$BFFF.

It can be used to run code from an external ROM (code must be compiled to be executed between A000 and BFFF). It is also the slot for the cassette tape extension (referenced as KCS, for the standard it's using). That extension allows to save/load code in BASIC, and to save / load raw dumps of code from anywhere in the address space.

The 65C22 VIA is accessible at address $8000 to $8003 and cannot trigger interrupts. It is used to provide 2 Atari CX40 Joysticks ports.

Port B RW ------------------ $8000
Port A RW ------------------ $8001
Data direction register B -- $8002
Data direction register A -- $8003
Timer 1 low byte ----------- $8004
Timer 1 high byte ---------- $8005
Auxiliary Control Register - $800B

Atari 2600 joystick 0 is on VIA Port A bit[0..4] and joystick 1 is on VIA Port B bit[0..4] as follow

Up ----- Bit0
Down --- Bit1
Left --- Bit2
Right -- Bit3
Fire --- Bit4

Basic function JOY() provides the same thing. JOY(0) for port A and JOY(1) for port B will return a number corresponding to the given port's status, masked on the 5 corresponding bits (this way, bits 5, 6 and 7 are still usable in the future without altering this implementation).
Sample:

10 A = JOY(0)
20 IF A = 31 THEN GOTO 10
30 IF A = 30 THEN PRINT "UP"
40 IF A = 29 THEN PRINT "DOWN"
50 IF A = 27 THEN PRINT "LEFT"
60 IF A = 23 THEN PRINT "RIGHT"
70 IF A = 15 THEN PRINT "FIRE"
80 GOTO 10
RUN

Basic routine TONE plays a square wave tone on Port B bit 7. At 1Mhz here is the equivalence table for each note:

DO 261.63Hz  = 1911
DO# 277.18Hz = 1808
RE 293.66Hz  = 1702
RE# 311.13Hz = 1607
MI 329.63Hz  = 1517
FA 349.23Hz  = 1432
FA# 369.99Hz = 1350
SOL 392.00Hz = 1275
SOL# 415.30Hz= 1203
LA 440Hz     = 1136
LA# 466.16Hz = 1073
SI 493.88Hz  = 1010

Play an A or LA 440 for a while then stop with TONE 0:

10 TONE 1136
20 K = 40
30 FOR I=0 TO K STEP 1
40   PRINT I
50 NEXT I
60 TONE 0
70 END
RUN
ACIA data register ----- $9000
ACIA status register --- $9001
ACIA command register -- $9002
ACIA control register -- $9003

Upon startup, the src/startup.s code inits the system and displays boot menu: the Memo-1 inits the ACIA, the VIA, sends commands to the Minitel to change the baud rate and disable local echo, then presents a simple menu system with several options: press '1' to launch WOZMON (a monitor program by Steve Wozniak for memory examination and modification), press '2' to start MS-BASIC (Microsoft BASIC interpreter), press '3' to execute code from an external ROM slot (this option only appears if an external ROM is detected at address $A000), or press 'A' to view an about screen with system information, license and credits.
The menu automatically detects an external ROM's presence and adapts the available options accordingly by looking at the first opcode at $A000. If it reads $A0 it assumes there is nothing there (6502 always read high nibble of the address when accessing an address where no hardware responds). If the start menu detects a ROM in external slot, it will read a personalised name from the header in the first 8 bytes of the rom, from $A000 to $A007. Menu entry will jump to $A008

This project is made to use a Minitel 1b as terminal. It implements a simple minitel driver for 65C02, assuming you are using the 6551 ACIA chip as UART (NOT the W65C51, which has 2 hardware incompatibilities with the Minitel).
The Minitel driver is the src/minitel.s file (yes I know, I'm the exentric one of the family).

Minitel printers support is still a work in progress.

The code is built to use ca65 and ld65 assembler and linker.
To assemble the code yourself, make sure you have both binaries in your path, or adapt the following commands.

First make sure you have an out directory next to the src. If you cloned this repository you should have it already as I wanted to share a binary release at least.

cd src
ca65 -D memo msbasic.s -o ../out/memo.o
ld65 -C memo.cfg ../out/memo.o -o ../out/memo.bin -Ln ../out/memo.lbl

If you get an error about the longbranch.mac not being included, you need to include the asminc folder. For exemple:

ca65 -I /usr/local/cc65/share/cc65/asminc -D memo msbasic.s -o ../out/memo.o

A 65C02 chip set based computer, for fun and for learning purposes.
By Benoit Aveline, aka Memoire Morte
(c) 2025 - Creative Commons BY-NC-SA

Special thanks to:

  • Ben Eater for his 6502 computer design and tutorials - CC-BY License
  • Ian Ward for his YouTube videos on 2004 lcd and 555 timer - No license found

Current source code is based on:

联系我们 contact @ memedata.com