Lesson 3. The card in the slot: the computer draws
In picturesAfter this lesson the plotter is connected to the Apple ][ through a card in slot 1, like a real one. The REMOTE switch hands control to the computer: POKE moves the pens and picks the colour, PEEK reads the limit switches and BUSY. Switch REMOTE off — the panel works again.
3.1. Idea: the card has three addresses
The Apple processor talks to everything around it through addresses: memory, keyboard, disk. Slot 1 owns the addresses $C090…$C09F; the plotter card takes four of them:
| Address | BASIC | What |
|---|---|---|
| $C090 | 49296 | write: X step, X direction, Y step, Y dir., pen |
| $C091 | 49297 | read: limit switches XL0 XL1 YL0 YL1 and BUSY |
| $C092 | 49298 | write: colour 0–3 |
| $C093 | 49299 | unused |
3.2. Idea: the decoder — «no bit differs»
$C090…$C093 in binary is 1100 0000 1001 00xx: the top 14 bits are fixed, the two lowest pick the register. Checking 14 bits at once is easier the other way round: look for at least one wrong bit. A bit that must be 1 is wrong when it is 0 (take its inverse from the CD4069: NA15, NA14, NA7, NA4); a bit that must be 0 is wrong when it is 1 (take it as it is). All 14 «wrongs» go into ORs:
G1 = NA15 OR NA14 OR ADDR13 OR ADDR12,G2 = ADDR11 OR … OR ADDR8— CD4072 (4-input OR);G3 = NA7 OR ADDR6 OR ADDR5 OR NA4,G4 = ADDR3 OR ADDR2;ANYB = G1 OR G2 OR G3 OR G4(CD4071) — «at least one bit is wrong»;SELP = NOT ANYB— the address is ours.
3.3. Idea: writing to a register
A register is CD4013 D flip-flops: on a rising edge at CL they store what is on D. On D — the processor’s data DOUT0…DOUT4, and the clock must come only when the processor writes to exactly this address:
SELW = SELP AND NOT ADDR0—$C090or$C092;WR = SELW AND write— and it is a write;WE0 = WR AND NOT ADDR1—$C090,WE2 = WR AND ADDR1—$C092;- register clocks:
LCK0 = WE0 AND CLK,LCK2 = WE2 AND CLK— the rising edge of the machine clock, when the data on the bus has settled.
$C090 is five flip-flops (AXS, AXD, AYS, AYD, APEN), $C092 is two (AC0, AC1). The machine’s RST clears them: pen up, colour black.
3.4. Idea: reading $C091 — onto the same bus
When the processor reads $C091, the card must put its bits onto the data bus DIN0…DIN4, and at all other times it must not disturb the machine:
SELR1 = SELP AND ADDR0 AND NOT ADDR1—$C091;OEP = SELR1 AND RnW— and it is a read;- a card bit onto the bus:
PRD0 = XL0 AND OEP, …PRD4 = BUSY AND OEP— at any other address allPRD = 0; - the bus to the processor:
DIN = MUX OR PRD(CD4071).MUXis what the machine itself gives (the DataInMux chip); at address$C091it has nothing — zeros — so the card’s bits pass. At other addressesPRD = 0— the machine’s data passes.
That is why the machine’s DataInMux outputs are renamed to MUX0…MUX4: the name DIN now belongs to the OR output.
3.5. Idea: who drives — the CD4019
The CD4019 has four «AND-OR» cells: D = A AND KA OR B AND KB. With KA = REMOTE and KB = NOT REMOTE, a cell is a switch:
| REMOTE | KA | KB | D |
|---|---|---|---|
| 1 | 1 | 0 | A — the computer’s reg. |
| 0 | 0 | 1 | B — the panel |
Two CD4019s are seven switches: X and Y step and direction, the pen, two colour bits. Their outputs XSTEP, XDIR, YSTEP, YDIR, PEN, COL0, COL1 now drive the plotter — that is why the pins of the axes, the pen and the colour compare are rewired to them. The turret, BUSY and the limit switches work as before — they don’t care who named the colour.
3.6. Build
On top of lesson 2. The card sits in slot 1 of the machine: it listens to the Apple bus (address ADDR0…ADDR15, data DOUT0…DOUT4, write, RnW, CLK, RST — the machine's labels) and answers on DIN0…DIN4. The REMOTE switch picks who drives the plotter: the computer or the panel.
Step 1. The address decoder
| Part | Pin / action | Label / where |
|---|---|---|
| TI CD4069UB | A G B H C I D J E K F L | ADDR15 NA15 ADDR14 NA14 ADDR7 NA7 ADDR4 NA4 ANYB SELP ADDR0 NA0 |
| TI CD4072B | A B C D J E F G H K | NA15 NA14 ADDR13 ADDR12 G1 ADDR11 ADDR10 ADDR9 ADDR8 G2 |
| TI CD4072B | A B C D J E F G H K | NA7 ADDR6 ADDR5 NA4 G3 ADDR3 ADDR2 GND GND G4 |
| TI CD4071B | A B J C D K E F L G H M | G1 G2 H1 G3 G4 H2 H1 H2 ANYB MUX0 PRD0 DIN0 |
| Part | Pin | Detach from | Attach to |
|---|---|---|---|
| TI CD4069UB, the one whose output = NBUSY | A | GND | ADDR1 |
| TI CD4069UB, the one whose output = NBUSY | G | — (not connected) | NA1 |
| TI CD4069UB, the one whose output = NBUSY | B | GND | REMOTE |
| TI CD4069UB, the one whose output = NBUSY | H | — (not connected) | NREM |
Step 2. Writing and reading
| Part | Pin / action | Label / where |
|---|---|---|
| TI CD4081B | A B J C D K E F L G H M | SELP NA0 SELW SELW write WR WR NA1 WE0 WR ADDR1 WE2 |
| TI CD4081B | A B J C D K E F L G H M | WE0 CLK LCK0 WE2 CLK LCK2 SELP ADDR0 SELR SELR NA1 SELR1 |
| TI CD4081B | A B J C D K E F L G H M | SELR1 RnW OEP XL0 OEP PRD0 XL1 OEP PRD1 YL0 OEP PRD2 |
| TI CD4071B | A B J C D K E F L G H M | MUX1 PRD1 DIN1 MUX2 PRD2 DIN2 MUX3 PRD3 DIN3 MUX4 PRD4 DIN4 |
| Part | Pin | Detach from | Attach to |
|---|---|---|---|
| TI CD4081B, the one whose output = LXS | A | GND | YL1 |
| TI CD4081B, the one whose output = LXS | B | GND | OEP |
| TI CD4081B, the one whose output = LXS | J | — (not connected) | PRD3 |
| TI CD4081B, the one whose output = LXS | C | GND | BUSYH |
| TI CD4081B, the one whose output = LXS | D | GND | OEP |
| TI CD4081B, the one whose output = LXS | K | — (not connected) | PRD4 |
Step 3. Registers
| Part | Pin / action | Label / where |
|---|---|---|
| TI CD4013B | S1 R1 D1 CL1 Q1 S2 R2 D2 CL2 Q2 | GND RST DOUT0 LCK0 AXS GND RST DOUT1 LCK0 AXD |
| TI CD4013B | S1 R1 D1 CL1 Q1 S2 R2 D2 CL2 Q2 | GND RST DOUT2 LCK0 AYS GND RST DOUT3 LCK0 AYD |
| TI CD4013B | S1 R1 D1 CL1 Q1 S2 R2 D2 CL2 Q2 | GND RST DOUT4 LCK0 APEN GND RST DOUT0 LCK2 AC0 |
| Part | Pin | Detach from | Attach to |
|---|---|---|---|
| TI CD4013B, the one whose output = MOVED | R1 | GND | RST |
| TI CD4013B, the one whose output = MOVED | D1 | GND | DOUT1 |
| TI CD4013B, the one whose output = MOVED | CL1 | GND | LCK2 |
| TI CD4013B, the one whose output = MOVED | Q1 | — (not connected) | AC1 |
Leave unconnected: QN1, QN2 on each of the three CD4013Bs.
Step 4. REMOTE and the CD4019
The switch is an Input from the palette.
| Part | Pin / action | Label / where |
|---|---|---|
| Input (switch) | output | REMOTE |
| TI CD4019B | KA KB A1 B1 D1 A2 B2 D2 A3 B3 D3 A4 B4 D4 | REMOTE NREM AXS LXS XSTEP AXD RIGHT XDIR AYS LYS YSTEP AYD DOWN YDIR |
| TI CD4019B | KA KB A1 B1 D1 A2 B2 D2 A3 B3 D3 A4 B4 | REMOTE NREM APEN LPEN PEN AC0 LC0 COL0 AC1 LC1 COL1 GND GND |
Leave unconnected: D4 on the CD4019B.
Step 5. Axes, pen and colour — from the CD4019
Mechanics pins are renamed the same way: double-click the label on the pin.
| Part | Pin | Detach from | Attach to |
|---|---|---|---|
| Linear axis — X axis | STEP | LXS | XSTEP |
| Linear axis — X axis | DIR | RIGHT | XDIR |
| Linear axis — Y axis | STEP | LYS | YSTEP |
| Linear axis — Y axis | DIR | DOWN | YDIR |
| TI CD4081B, the one whose output = STEPT | C | LPEN | PEN |
| TI CD4070B, the one whose output = X0 | A | LC0 | COL0 |
| TI CD4070B, the one whose output = X0 | C | LC1 | COL1 |
Step 6. The Apple data bus
On the machine chip DataInMux, rename the labels DIN0…DIN4 on its outputs to MUX0…MUX4 (the MOS6502 processor keeps its DIN0…DIN4 labels). Now data reaches the processor through the card: the CD4071 ORs the card’s read bits with the machine’s data.
| Part | Pin | Detach from | Attach to |
|---|---|---|---|
| DataInMux (machine chip), the one whose output = DIN0 | DIN0 | DIN0 | MUX0 |
| DataInMux (machine chip), the one whose output = DIN1 | DIN1 | DIN1 | MUX1 |
| DataInMux (machine chip), the one whose output = DIN2 | DIN2 | DIN2 | MUX2 |
| DataInMux (machine chip), the one whose output = DIN3 | DIN3 | DIN3 | MUX3 |
| DataInMux (machine chip), the one whose output = DIN4 | DIN4 | DIN4 | MUX4 |
3.7. Check
- Turbo mode, switch the power on. REMOTE is off — the plotter obeys the panel, as in lesson 2.
- Switch REMOTE on. When the machine has booted, type in BASIC (Return after each line):
PRINT PEEK(49297)POKE 49298,2PRINT PEEK(49297)- The first number is 5 if both carriages are at the motors (the XL0 and YL0 limit switches are on); if you moved the carriages with the panel, it is a different one.
POKE 49298,2— the computer named green: BUSY lights up, the head turns. While it turns,PEEKgives a number 16 higher (the BUSY bit); when it stops — the old one again. - A short program — a green square:
10 FOR I = 1 TO 40: POKE 49296,19: POKE 49296,18: NEXT20 FOR I = 1 TO 40: POKE 49296,28: POKE 49296,24: NEXT30 FOR I = 1 TO 40: POKE 49296,17: POKE 49296,16: NEXT40 FOR I = 1 TO 40: POKE 49296,20: POKE 49296,16: NEXT50 POKE 49296,0RUN| Command | What the plotter does |
|---|---|
| POKE 49296,V | $C090: bits of V — X step, X direction, Y step, Y direction, pen (1, 2, 4, 8, 16) |
| POKE 49298,C | $C092: colour 0–3 — the head turns to it |
| PEEK(49297) | $C091: XL0 1, XL1 2, YL0 4, YL1 8, BUSY 16 |
| REMOTE off | the panel, as in lessons 1–2 |
Lesson 3 paste (Cmd+I)
Paste into the Apple ][ machine (the DEMO button) instead of lessons 1–3: it places the whole device and renames the DataInMux outputs.
# Lesson 3 - the card in the slot: decoder $C090-$C093, registers, reading the limit switches and BUSY; REMOTE/LOCAL on the CD4019.# $C090 write: 0 XSTEP 1 XDIR 2 YSTEP 3 YDIR 4 PEN. $C091 read: 0 XL0 1 XL1 2 YL0 3 YL1 4 BUSY. $C092 write: 0-1 colour.# ---------- mechanics: X axis, Y axis on its carriage, the head on the Y carriage, black pen, paper ----------maxis ax{len=400}(STEP=XSTEP, DIR=XDIR, L0=XL0, L1=XL1, STALL=XSTALL)maxis ay{len=300, ang=90}(STEP=YSTEP, DIR=YDIR, L0=YL0, L1=YL1, STALL=YSTALL)mount(ay, ax.car)mtable tt(A=NJ1, B=NJ2, C=J1, D=J2)mount(tt, ay.car)mpen k0{color=black}(DOWN=DOWN0)mount(k0, tt.d0)mpaper p{w=460, h=360}at(p, 0, 0)at(ax, p, -41, -138)# ---------- panel: step clock, arrows, PEN UP/DOWN ----------clock{rt=60}(CKL)button{label="LEFT"}(LEFT)button{label="RIGHT"}(RIGHT)button{label="UP"}(UP)button{label="DOWN"}(DOWN)button{label="PEN UP/DOWN"}(PENB)# ---------- CD4071: an X arrow pressed, a Y arrow pressed; ERROR - a carriage is stuck ----------"TI CD4071B"(A=LEFT, B=RIGHT, J=LR, C=UP, D=DOWN, K=UD, E=XSTALL, F=YSTALL, L=ERROR, G=Q6, H=RST, M=QR)# ---------- CD4081: steps - the 60 Hz clock while an arrow is pressed ----------"TI CD4081B"(A=YL1, B=OEP, C=BUSYH, D=OEP, E=CKL, F=LR, L=LXS, G=CKL, H=UD, M=LYS, J=PRD3, K=PRD4)# ---------- CD4013: PEN UP/DOWN - a toggle flip-flop ----------"TI CD4013B"(S1=GND, R1=RST, D1=NLPEN, CL1=PENB, Q1=LPEN, QN1=NLPEN, S2=GND, R2=RST, D2=NLC0, CL2=SELB, Q2=LC0, QN2=NLC0)# ---------- POWER and ERROR LEDs ----------led{color=green}(VCC)led{color=red}(ERROR)# ---------- the SELECT button ----------button{label="SELECT"}(SELB)# ---------- CD4013: the high bit of the colour ----------"TI CD4013B"(S1=GND, R1=RST, D1=NLC1, CL1=NLC0, Q1=LC1, QN1=NLC1, S2=GND, R2=GND, D2=GND, CL2=GND)# ---------- the turret motor clock ----------clock{rt=10}(CKT)# ---------- CD4070: colour differs from the pen at the work point ----------"TI CD4070B"(A=COL0, B=CP0, J=X0, C=COL1, D=CP1, K=X1, E=GND, F=GND, G=GND, H=GND)# ---------- CD4071: MOVE - turn; BUSY - turning or has just finished ----------"TI CD4071B"(A=X0, B=X1, J=MOVE, C=MOVE, D=MOVED, K=BUSYH, E=GND, F=GND, G=GND, H=GND)# ---------- CD4013: MOVED - MOVE half a tick ago (second flip-flop; the first one - lesson 3) ----------"TI CD4013B"(S1=GND, R1=RST, D1=DOUT1, CL1=LCK2, S2=GND, R2=RST, D2=MOVE, CL2=NCKT, Q2=MOVED, Q1=AC1)# ---------- CD4069: NOT BUSY, NOT the clock (inputs A and B - lesson 3) ----------"TI CD4069UB"(A=ADDR1, B=REMOTE, C=BUSYH, I=NBUSY, D=CKT, J=NCKT, E=GND, F=GND, G=NA1, H=NREM)# ---------- CD4081: motor step, the pen may go down, a pair of pens ----------"TI CD4081B"(A=CKT, B=MOVE, J=STEPT, C=PEN, D=NBUSY, K=PDN, E=PDN, F=NCP1, L=E0, G=PDN, H=CP1, M=E1)# ---------- CD4081: which pen to lower ----------"TI CD4081B"(A=E0, B=NCP0, J=DOWN0, C=E0, D=CP0, K=DOWN1, E=E1, F=NCP0, L=DOWN2, G=E1, H=CP0, M=DOWN3)# ---------- CD4013: motor phases - two flip-flops in a ring ----------"TI CD4013B"(S1=GND, R1=RST, D1=NJ2, CL1=STEPT, Q1=J1, QN1=NJ1, S2=GND, R2=RST, D2=J1, CL2=STEPT, Q2=J2, QN2=NJ2)# ---------- CD4017: a quarter turn = 6 steps ----------"TI CD4017B"(CLOCK=STEPT, RESET=QR, INH=GND, O6=Q6, CO=QCO)# ---------- CD4013: the number of the pen at the work point ----------"TI CD4013B"(S1=GND, R1=RST, D1=NCP0, CL1=QCO, Q1=CP0, QN1=NCP0, S2=GND, R2=RST, D2=NCP1, CL2=NCP0, Q2=CP1, QN2=NCP1)# ---------- the BUSY LED ----------led{color=yellow}(BUSYH)# ---------- pens: red, green, blue ----------mpen k1{color=red}(DOWN=DOWN1)mount(k1, tt.d3)mpen k2{color=green}(DOWN=DOWN2)mount(k2, tt.d2)mpen k3{color=blue}(DOWN=DOWN3)mount(k3, tt.d1)# ---------- address decoder $C090-$C093 ----------"TI CD4069UB"(A=ADDR15, G=NA15, B=ADDR14, H=NA14, C=ADDR7, I=NA7, D=ADDR4, J=NA4, E=ANYB, K=SELP, F=ADDR0, L=NA0)"TI CD4072B"(A=NA15, B=NA14, C=ADDR13, D=ADDR12, J=G1, E=ADDR11, F=ADDR10, G=ADDR9, H=ADDR8, K=G2)"TI CD4072B"(A=NA7, B=ADDR6, C=ADDR5, D=NA4, J=G3, E=ADDR3, F=ADDR2, G=GND, H=GND, K=G4)"TI CD4071B"(A=G1, B=G2, J=H1, C=G3, D=G4, K=H2, E=H1, F=H2, L=ANYB, G=MUX0, H=PRD0, M=DIN0)# ---------- CD4081: write to $C090 and to $C092 ----------"TI CD4081B"(A=SELP, B=NA0, J=SELW, C=SELW, D=write, K=WR, E=WR, F=NA1, L=WE0, G=WR, H=ADDR1, M=WE2)# ---------- CD4081: register clocks, read $C091 ----------"TI CD4081B"(A=WE0, B=CLK, J=LCK0, C=WE2, D=CLK, K=LCK2, E=SELP, F=ADDR0, L=SELR, G=SELR, H=NA1, M=SELR1)# ---------- CD4081: read bits ----------"TI CD4081B"(A=SELR1, B=RnW, J=OEP, C=XL0, D=OEP, K=PRD0, E=XL1, F=OEP, L=PRD1, G=YL0, H=OEP, M=PRD2)# ---------- CD4071: read bits - onto the data bus ----------"TI CD4071B"(A=MUX1, B=PRD1, J=DIN1, C=MUX2, D=PRD2, K=DIN2, E=MUX3, F=PRD3, L=DIN3, G=MUX4, H=PRD4, M=DIN4)# ---------- register $C090: steps, directions, pen ----------"TI CD4013B"(S1=GND, R1=RST, D1=DOUT0, CL1=LCK0, Q1=AXS, S2=GND, R2=RST, D2=DOUT1, CL2=LCK0, Q2=AXD)"TI CD4013B"(S1=GND, R1=RST, D1=DOUT2, CL1=LCK0, Q1=AYS, S2=GND, R2=RST, D2=DOUT3, CL2=LCK0, Q2=AYD)"TI CD4013B"(S1=GND, R1=RST, D1=DOUT4, CL1=LCK0, Q1=APEN, S2=GND, R2=RST, D2=DOUT0, CL2=LCK2, Q2=AC0)# ---------- the REMOTE switch ----------input(REMOTE)# ---------- CD4019: who drives - the computer (REMOTE = 1) or the panel ----------"TI CD4019B"(KA=REMOTE, KB=NREM, A1=AXS, B1=LXS, D1=XSTEP, A2=AXD, B2=RIGHT, D2=XDIR, A3=AYS, B3=LYS, D3=YSTEP, A4=AYD, B4=DOWN, D4=YDIR)"TI CD4019B"(KA=REMOTE, KB=NREM, A1=APEN, B1=LPEN, D1=PEN, A2=AC0, B2=LC0, D2=COL0, A3=AC1, B3=LC1, D3=COL1, A4=GND, B4=GND)reconnect(DIN0.DIN0 = MUX0)reconnect(DIN1.DIN1 = MUX1)reconnect(DIN2.DIN2 = MUX2)reconnect(DIN3.DIN3 = MUX3)reconnect(DIN4.DIN4 = MUX4)Stuck? Something doesn't work →