Got IC Sockets in today, together with other goodies.
So i soldered the C64 Cartridge print.
Putting a bin on the eeprom
sudo minipro -p AT28C64 -w 8kcart.bin
Welll .. allmost working.
Some strange artifacts, but is running.
Got IC Sockets in today, together with other goodies.
So i soldered the C64 Cartridge print.
Putting a bin on the eeprom
sudo minipro -p AT28C64 -w 8kcart.bin
Welll .. allmost working.
Some strange artifacts, but is running.
Added second VIA chip. (For hex keyboard)
Skipped the sound setups with simple components or the Yamaha chip. Straight to the commodore SID chip. Added a amplifier and a speaker.
Added ROM functions for line printing. Picture with 2 lines, and my name in Japanese
Now I have to wait for components. I’ve made a simulation for a address decoder.
Rest I’ve put in previous posts as updates.
Meanwhile testing 6502 apps on Android
For accessing the different components in computers you have to use the Address Bus.
In most 8 bits computers there are 16 address lines.
The CPU on a 6502 can access 65536 addresses (16 bit ). But most chips in the circuit have just a few address lines.
So the chip to use has to be selected using a CE (chip Enable) signal.
Old article i found on my fileserver from 1984
74 Series logic
Above example uses A15 combined with A14 to address the 16K ROM
When using a 32k rom in the upper part of the memory, a15 can be used as CE
The 74ALS133 is a widely used decoder due to it’s many inputs.
Sometimes not all address lines are used for decoding, then you will get a repetition of the device in the memory map.
Above 6522 VIA has only 4 address lines RS0-RS3. But 2 chipselect pins (CS).
If you connect the chip as below.
A15 A14 A13 A12 A11 A10 A09 A08 A07 A06 A05 A04 A03 A02 A01 A00
CS1 CS2 NC NC NC NC NC NC NC NC NC NC CR3 CR2 CR1 CR0
(NC - not connected, and CS2 is inverted!)
The chip would be selected when A15 is 1 and A14 is 0, A13-A04 it would not listen to. So its 4 bits addresses (total 16), would be repeated in a block $8000-$BFFF (10xx xxxx xxxx aaaa) 16384 addresses for 16 addresses on the 6522
ROM
Another simple solution to get a more precise address decoder without using a lot of components is using a ROM.
But this wil only work for low speeds!
A eeprom is relative cheap
PAL PLA GAL
With these devices you can “program” a schematic which works as above example’s of the 74 series. But now you can do it using only one component.
PALs and PLAs are fuse-programmed, some are erasable like (e)eprom.
Below a example of the code.
Most of the PAL/PLA/GAL are hard to get and obsolete
;PALASM Design Description ;---------------------------------- Declaration Segment ------------ TITLE pRAM PC_interface Address Decoder PATTERN pRAM97A.pds REVISION H AUTHOR Trevor Clarkson COMPANY EEE KCL DATE 30/05/97 CHIP decode PALCE20V8 ;---------------------------------- PIN Declarations --------------- PIN 1 AEN COMBINATORIAL ; INPUT PIN 2 A9 COMBINATORIAL ; INPUT PIN 3 A8 COMBINATORIAL ; INPUT PIN 4 A7 COMBINATORIAL ; INPUT PIN 5 A6 COMBINATORIAL ; INPUT PIN 6 A5 COMBINATORIAL ; INPUT PIN 7 A4 COMBINATORIAL ; INPUT PIN 8 A3 COMBINATORIAL ; INPUT PIN 9 A2 COMBINATORIAL ; INPUT PIN 10 A1 COMBINATORIAL ; INPUT PIN 11 IOW COMBINATORIAL ; INPUT PIN 12 GND PIN 13 IOR COMBINATORIAL ; INPUT PIN 14 ACK_HALT COMBINATORIAL ; INPUT PIN 15 PLS_EN COMBINATORIAL ; OUTPUT PIN 16 BRDW COMBINATORIAL ; OUTPUT PIN 17 MOD_CTRL COMBINATORIAL ; OUTPUT PIN 18 RAM_ACCESS COMBINATORIAL ; OUTPUT PIN 19 IO_16 COMBINATORIAL ; OUTPUT PIN 20 LATCH_MOD COMBINATORIAL ; OUTPUT PIN 21 LATCH_ADD COMBINATORIAL ; OUTPUT PIN 22 P300 COMBINATORIAL ; OUTPUT PIN 23 P300IN COMBINATORIAL ; INPUT PIN 24 VCC ;PC address decoding functions (not all in this PAL) ;uses latched address to provide low-order address lines to pRAM/RAM ; A3 A2 A1 R/W Addr Function ; 0 0 0 R 300 MFF_0 ; W not used ; 0 0 1 R 302 MFF_1 ; W not used ; 0 1 0 R 304 MFF_2 ; W not used ; 0 1 1 R 306 MFF_3 ; W Latch Module Number ; 1 0 0 R 308 PLS_Status (pRAM status) ; W PLS_Control (pRAM control) ; 1 0 1 R 30A Weight/Connection- ; W Pointer RAM access ; 1 1 0 R 30C not used ; W Latched RAM address ; 1 1 1 R 30E not used ; W pRAM_256 module control ; ; NB. IO_16 must be tri-stated when not in use ;----------------------------------- Boolean Equation Segment ------ EQUATIONS /P300 = A9*A8*/A7*/A6*/A5*/A4*/IOR + A9*A8*/A7*/A6*/A5*/A4*/IOW /BRDW = /P300IN * /IOW /PLS_EN = /P300IN*/A3*/IOR + /P300IN*A3*/A2*/A1 ; MOD_CTRL is active HIGH MOD_CTRL = ACK_HALT * /BRDW * A3 * A2 * A1 * /IOW ; RAM_ACCESS is active HIGH RAM_ACCESS = ACK_HALT * /P300IN * A3 * /A2 * A1 IO_16 = GND IO_16.TRST = /P300IN ; enable 16-bit transfers ; LATCH_MOD is active HIGH LATCH_MOD = /BRDW * /A3 * A2 * A1 ; LATCH_ADD is active HIGH LATCH_ADD = /BRDW * A3 * A2 * /A1 ;----------------------------------- Simulation Segment ------------ SIMULATION TRACE_ON A9 A8 A7 A6 A5 A4 IOR /IOW /BRDW /PLS_EN MOD_CTRL RAM_ACCESS IO_16 LATCH_MOD LATCH_ADD ACK_HALT /P300 /P300IN SETF /A9 /A8 /A7 /A6 /A5 /A4 /A3 /A2 /A1 IOR IOW /ACK_HALT /P300IN SETF /IOW ; test P300 doesn't respond SETF IOW /IOR ; test P300 doesn't respond SETF IOR SETF A9 A8 /A7 /A6 /A5 /A4 /IOR /P300IN SETF A1 SETF A2 /A1 SETF A1 ; read mff0-3 SETF IOR /IOW ; test P300 and BRDW SETF /A3 A2 A1 ; test Latch Module No SETF IOW A3 A2 A1 ; MOD-CTRL not active until ACK_HALT SETF ACK_HALT /IOW SETF IOW /ACK_HALT SETF A3 /A2 A1 ; check RAM_ACCESS SETF ACK_HALT /IOW SETF /ACK_HALT IOW SETF ACK_HALT /IOR ; check READ and WRITE to RAM SETF IOR P300IN SETF /A3 A2 A1 SETF /ACK_HALT /P300IN SETF IOW SETF /A3 A2 A1 /IOW ; check LATCH_MOD SETF IOW SETF A3 A2 /A1 SETF /IOW ; check LATCH_ADD SETF /A3 /A2 /A1 ; shouldn't happen normally TRACE_OFF ;-------------------------------------------------------------------
FPGA
Example FPGA code. A solution which is too fancy for my 6502.
// Verilog code for decoder // 5-input AND gate module AND_5_input(g,a,b,c,d,e); output g; input a,b,c,d,e; and #(50) and1(f1,a,b,c,d), and2(g,f1,e); endmodule // fpga4student.com: FPGA projects, Verilog projects, VHDL projects // Verilog code for decoder // Decoder top level Verilog code using 5-input AND gates module dec5to32(Out,Adr); input [4:0] Adr; // Adr=Address of register output [31:0] Out; not #(50) Inv4(Nota, Adr[4]); not #(50) Inv3(Notb, Adr[3]); not #(50) Inv2(Notc, Adr[2]); not #(50) Inv1(Notd, Adr[1]); not #(50) Inv0(Note, Adr[0]); AND_5_input a0(Out[0], Nota,Notb,Notc,Notd,Note); // 00000 AND_5_input a1(Out[1], Nota,Notb,Notc,Notd,Adr[0]); // 00001 AND_5_input a2(Out[2], Nota,Notb,Notc,Adr[1],Note); //00010 AND_5_input a3(Out[3], Nota,Notb,Notc,Adr[1],Adr[0]); AND_5_input a4(Out[4], Nota,Notb,Adr[2],Notd,Note); AND_5_input a5(Out[5], Nota,Notb,Adr[2],Notd,Adr[0]); AND_5_input a6(Out[6], Nota,Notb,Adr[2],Adr[1],Note); AND_5_input a7(Out[7], Nota,Notb,Adr[2],Adr[1],Adr[0]); AND_5_input a8(Out[8], Nota,Adr[3],Notc,Notd,Note); AND_5_input a9(Out[9], Nota,Adr[3],Notc,Notd,Adr[0]); AND_5_input a10(Out[10], Nota,Adr[3],Notc,Adr[1],Note); AND_5_input a11(Out[11], Nota,Adr[3],Notc,Adr[1],Adr[0]); AND_5_input a12(Out[12], Nota,Adr[3],Adr[2],Notd,Note); AND_5_input a13(Out[13], Nota,Adr[3],Adr[2],Notd,Adr[0]); AND_5_input a14(Out[14], Nota,Adr[3],Adr[2],Adr[1],Note); AND_5_input a15(Out[15], Nota,Adr[3],Adr[2],Adr[1],Adr[0]); AND_5_input a16(Out[16], Adr[4],Notb,Notc,Notd,Note); AND_5_input a17(Out[17], Adr[4],Notb,Notc,Notd,Adr[0]); AND_5_input a18(Out[18], Adr[4],Notb,Notc,Adr[1],Note); AND_5_input a19(Out[19], Adr[4],Notb,Notc,Adr[1],Adr[0]); AND_5_input a20(Out[20], Adr[4],Notb,Adr[2],Notd,Note); AND_5_input a21(Out[21], Adr[4],Notb,Adr[2],Notd,Adr[0]); AND_5_input a22(Out[22], Adr[4],Notb,Adr[2],Adr[1],Note); AND_5_input a23(Out[23], Adr[4],Notb,Adr[2],Adr[1],Adr[0]); AND_5_input a24(Out[24], Adr[4],Adr[3],Notc,Notd,Note); AND_5_input a25(Out[25], Adr[4],Adr[3],Notc,Notd,Adr[0]); AND_5_input a26(Out[26], Adr[4],Adr[3],Notc,Adr[1],Note); AND_5_input a27(Out[27], Adr[4],Adr[3],Notc,Adr[1],Adr[0]); AND_5_input a28(Out[28], Adr[4],Adr[3],Adr[2],Notd,Note); AND_5_input a29(Out[29], Adr[4],Adr[3],Adr[2],Notd,Adr[0]); AND_5_input a30(Out[30], Adr[4],Adr[3],Adr[2],Adr[1],Note); AND_5_input a31(Out[31], Adr[4],Adr[3],Adr[2],Adr[1],Adr[0]); // 11111 endmodule
Example of Ice studio FPGA programming
Conslusion:
For now i will use the 74 logic. But i definitely will revisit FPGA’s
Searching for parts .. from other projects
I want to make a new clock module using a bare ATmega328 running on a 16mhz crystal. This to provide a clock for my 6502 computer.
Using a display and a rotary encoder I want to create a clock module which generates a 50/50 duty cycle clock 1Hz – 1 MHz.
Input module for my 6502 will be 5 buttons. (For now) that’s what’s left on the VIA on port A. (Rest is used by the display). The display i’m going to place directly on the bus. But I already ordered a second VIA. Matrix keyboard will be next. Then I will use the buttons in the picture for shift/alternate buttons. Because I’ll need about 25 keys. (See other posts) . I’ll probably end up making that one myself.
The lost ancient art of wire wrapping.
{funny story]
In 2019 i wanted to make a simple probe, which could detect 0 or 1 or a pulse. I wanted to make this on a little print using wirewrap wires and IC sockets. (I still have the tool which i used in the 90s.)
When going to a well-known electronics shop in Den Hague. A great shop to get all kinds of oldskool electronics. But i’m getting ahead of the story.
This shop has a lot of components for all kinds of electronics. New and what it looked like de-soldered component from boards or bought from old going-out-of-business shops or factories. Stuff you needed for 60s equipment.
Well i was at the counter, asking a old guy.
“Do you have wire-wrap wire”
He said: ” No that’s old skool” ….
{/funny story]
The wirewrap tool has a cable stripper. After stripping you would put a short part in the tool, place the tool over a IC pin and turning would wrap the wire on the pins.
You could stack multiple connections on one pin.
Removing could be done by turning the tool counterclockwise.
Sometimes you had to remove the one closest to the print, replacing all wires. (Or cut the wrong/not needed wire and leave it in place … )
I’m thinking of moving my breadboard 6502 to a wirewrapped version.
All my old boards are gone .. before i got a digital camera .. 🙁
Example from a 8031 setup of a friend of mine
UPDATE: 20220815, 20220814, 20220815, 20230202
Flashing ROMs .. (eeproms). It used to be a pain in the *$$.
Burning took a looong time. But clearing one with UV took .. 20 minutes or so. Using one of these:
Altered clock module
Changed Rom/Ram
VIC 6522
Display
Generic improvements
To do’s or ‘have to look into’s’
Notes about the movie:
Left side is Arduino IDE monitor reading Addressbus and Databus.
(I’m going to try to rewrite this to realtime disassemble)
Resetting system.
Stepping CPU with manual clock pulses.
Start vector being read at $FFFC/$FFFD.
Program being run from $8000.
Set clock on automatic ( ~ about 150 Hz )
Last opcodes you see a JMP loop 4C 2F 80, that is JMP $802F
Display enlarged on video, was not visible on movie i took on mobile.
(Wrong angle?)
Breadboard overview
Clock module | Reset module + Crystal |
CPU + nmi/int buttons | RAM and ROM |
Address decode + Bus divide | Addres/Data bus leds |
6522 VIA + Display | 2nd via + Buttons |
? | (sound board) |
TIL: 6502 can run without ram only rom,expect when using JSR … which uses a program stack in RAM
TODO:
I’ve got the tools and Bigred made me enthusiastic again.
My goal is to make a C64 Cartridge from a PRG. And Not any program, it is the 8085 Emulator from Sepp.
Serveral problems i have to ‘fix’
Luckily i have the source! How cool is that
For version 4.73 it states : Starting at $0820 .. but my hexdump is off by one??!?
root@battlestation:/home/fash/Projects/minipro# hexdump -C /tmp/8085.prg | head 00000000 01 08 1e 08 c5 07 9e 32 30 38 30 20 42 59 20 4d |.......2080 BY M| 00000010 41 52 54 49 4e 20 4d 45 59 45 52 49 4e 4b 00 00 |ARTIN MEYERINK..| 00000020 00 20 ec 08 20 7f 19 20 2b 2c 20 11 19 20 b8 08 |. .. .. +, .. ..| 00000030 20 20 2c 20 a0 2c 20 f2 2c 20 11 e1 4c 00 15 aa | , ., ., ..L...| 00000040 aa a2 06 ad b7 08 9d 48 d8 bd 48 04 20 88 39 9d |.......H..H. .9.| 00000050 48 04 ca 10 ee a9 60 8d 4c 04 4c 50 47 00 a9 d0 |H.....`.L.LPG...| 00000060 2c a9 f0 8d 45 1f 4c 11 e1 1e 93 0d 20 20 4d 41 |,...E.L..... MA| 00000070 52 54 49 4e 20 4d 45 59 45 52 49 4e 4b 27 53 0d |RTIN MEYERINK'S.| 00000080 0d 20 38 30 38 35 20 45 4d 55 4c 41 54 4f 52 20 |. 8085 EMULATOR | 00000090 20 56 34 2e 38 30 0d 0d 20 20 28 43 29 20 31 20 | V4.80.. (C) 1 |
00000020 00 20 ec starts with 00 at $0020 .. and not 20 ?!?!
Tools used until now:
Card Low starts at $8000, so that’s the place where those roms are going to be.
To place on this address:
Copy routine : from ($8000 + this copy routine) to $0820
When to decompress??
jmp routine to $0820
Also nice: Magic Desk Cartridge Generator V3.0
UPDATE: 20220811
exomizer sfx 0x0820 8085.prg -o data.exo # Compress and start at 0x0820 xa frame.asm -o frame.bin # Add code and write binary x64 --cart16 frame.bin # Test cartridge with Vice
frame.asm
;---------------------------------------------------------- ; example usage ; xa frame.asm -o frame.bin ; cartconv -t normal -i frame.bin -n 'my cart' -o frame.crt ; x64 -cartcrt frame.crt ;---------------------------------------------------------- ;no load-adress for bin-file, so no header here *=$8000 .word launcher ;cold start .word launcher ;warm start .byte $c3 ;c .byte $c2 ;b .byte $cd ;m .byte $38 ;8 .byte $30 ;0 launcher stx $d016 jsr $fda3 ;prepare irq jsr $fd50 ;init memory jsr $fd15 ;init i/o jsr $ff5b ;init video ;make sure this sets up everything you need, ;the calls above are probably sufficient ldx #$fb txs ;set up starting code outside of cartridge-area move_starter ldx #(starter_end-starter_start) loop1 lda starter_start,x sta $100,x dex bpl loop1 jmp $100 ;--------------------------------- starter_start ldx #$40 ;64 pages = 256 * 64 = 16384 Bytes ldy #0 loop src lda exomized_data,y dst sta $801,y iny bne loop inc src+2-starter_start+$100 inc dst+2-starter_start+$100 dex bpl loop ;make sure settings for $01 and IRQ etc are correct for your code ;remember THIS table from AAY64: ; Bit+-------------+-----------+------------+ ; 210| $8000-$BFFF |$D000-$DFFF|$E000-$FFFF | ; +---+---+-------------+-----------+------------+ ; | 7 |111| Cart.+Basic | I/O | Kernal ROM | ; +---+---+-------------+-----------+------------+ ; | 6 |110| RAM | I/O | Kernal ROM | ; +---+---+-------------+-----------+------------+ ; | 5 |101| RAM | I/O | RAM | ; +---+---+-------------+-----------+------------+ ; | 4 |100| RAM | RAM | RAM | ; +---+---+-------------+-----------+------------+ ; | 3 |011| Cart.+Basic | Char. ROM | Kernal ROM | ; +---+---+-------------+-----------+------------+ ; | 2 |010| RAM | Char. ROM | Kernal ROM | ; +---+---+-------------+-----------+------------+ ; | 1 |001| RAM | Char. ROM | RAM | ; +---+---+-------------+-----------+------------+ ; | 0 |000| RAM | RAM | RAM | ; +---+---+-------------+-----------+------------+ lda #$35 ;cart is always on instead of BASIC unless it can be switched off via software sta $01 jmp $80d ;for exomizer, i.e. starter_end ;---------------------------------- exomized_data .bin 2,0,"data.exo" ;syntax for exomizer 2.0.1: ;exomizer sfx sys game.prg -o data.exo main_file_end ;fill up full $4000 bytes for bin file ($c000-$8000=$4000) .dsb ($c000-main_file_end),0
Exomiser info
Reading "8085.prg", loading from $0801 to $4CE9.
Crunching from $0801 to $4CE9.
Phase 1: Instrumenting file
-----------------------------
Length of indata: 17640 bytes.
[building.directed.acyclic.graph.building.directed.acyclic.graph.]
Instrumenting file, done.
Phase 2: Calculating encoding
-----------------------------
pass 1: optimizing ..
[finding.shortest.path.finding.shortest.path.finding.shortest.pat]
size 80273.0 bits ~10035 bytes
pass 2: optimizing ..
[finding.shortest.path.finding.shortest.path.finding.shortest.pat]
size 80039.0 bits ~10005 bytes
pass 3: optimizing ..
Calculating encoding, done.
Phase 3: Generating output file
------------------------------
Encoding: 1101112133423160,1122,2010223445667788,032144406789BBCD
Length of crunched data: 10034 bytes.
Crunched data reduced 7606 bytes (43.12%)
Target is self-decrunching C64 executable,
jmp address $0820.
Writing "data.exo" as prg, saving from $0801 to $304C.
Memory layout: |Start |End |
Crunched data | $07E7| $2F18|
Decrunched data | $0801| $4CE9|
Decrunch table | $0334| $03D0|
Decruncher | $00FD| $01C0| and $9F,$A7,$AE,$AF
Decrunch effect writes to $DBE7.
Decruncher: |Enter |During|Exit |
RAM config | $37| $37| $37|
IRQ enabled | 1| 1| 1|
UPDATE:20230126
; CODE COPY FROM http://www.lemon64.com/forum/viewtopic.php?t=60786&sid=2559442c8b963d7aac27cb13b493f372 ; Thanks for posting: Richard of TND ; this is for a 16KB cart, using ACME!! !to "mycart.crt",cart16crt scr = $0400 DecrunchADDR = 2061 ;SYS 2061 (HEX $080D) *=$8000 !word launcher !word launcher !byte $c3,$c2,$cd,$38,$30 ;CBM 80 launcher sei stx $d016 jsr $fda3 ;prepare irq jsr $fd50 ;input memory jsr $fd15 ;initialise i/o jsr $ff5b ;initialise video memory ;For a more professional boot up. Make ;the border and screen black. AFTER ;the video memory, etc has finished. lda #$00 sta $d020 sta $d021 cli ;Switch off the screen. lda $d011 and #%11101111 sta $d011 ;Move transfer code over to the screen ;memory. ldx #$00 tloop lda transfer,x sta scr,x inx bne tloop jmp scr transfer ldx #$00 tr1 lda linkedgame,x ;Move from linked address sta $0801,x ;Direct to BASIC start address inx bne tr1 inc scr+4 inc scr+7 lda scr+4 bne transfer jsr $e453 ;load basic vectors jsr $e3bf ;init basic ram ldx #$fb txs ;Execute the game, by jumping to the ;de-cruncher's start address. ;jmp $0820 jmp DecrunchADDR ;Link crunched game as a PRG file to memory after ;the cartridge build code. linkedgame !bin "8085sys.prg",,2 FileSize = * !if FileSize >$c000 { !error "FILE SIZE IS TOO BIG TO FIT 16KB CARTRIDGE" } else { *=$c000 }
Exomizer:
exomizer sfx sys 8085.prg -o 8085sys.prg Reading "8085.prg", loading from $0801 to $4CE9. Crunching from $0801 to $4CE9. Phase 1: Instrumenting file ----------------------------- Length of indata: 17640 bytes. [building.directed.acyclic.graph.building.directed.acyclic.graph.] Instrumenting file, done. Phase 2: Calculating encoding ----------------------------- pass 1: optimizing .. [finding.shortest.path.finding.shortest.path.finding.shortest.pat] size 80273.0 bits ~10035 bytes pass 2: optimizing .. [finding.shortest.path.finding.shortest.path.finding.shortest.pat] size 80039.0 bits ~10005 bytes pass 3: optimizing .. Calculating encoding, done. Phase 3: Generating output file ------------------------------ Encoding: 1101112133423160,1122,2010223445667788,032144406789BBCD Length of crunched data: 10034 bytes. Crunched data reduced 7606 bytes (43.12%) Target is self-decrunching C64 executable, jmp address $0820. Writing "8085sys.prg" as prg, saving from $0801 to $304C. Memory layout: |Start |End | Crunched data | $07E7| $2F18| Decrunched data | $0801| $4CE9| Decrunch table | $0334| $03D0| Decruncher | $00FD| $01C0| and $9F,$A7,$AE,$AF Decrunch effect writes to $DBE7. Decruncher: |Enter |During|Exit | RAM config | $37| $37| $37| IRQ enabled | 1| 1| 1|
exomizer sfx $\0801 8085.prg -o 8085out.prg Reading "8085.prg", loading from $0801 to $4CE9. Crunching from $0801 to $4CE9. Phase 1: Instrumenting file ----------------------------- Length of indata: 17640 bytes. [building.directed.acyclic.graph.building.directed.acyclic.graph.] Instrumenting file, done. Phase 2: Calculating encoding ----------------------------- pass 1: optimizing .. [finding.shortest.path.finding.shortest.path.finding.shortest.pat] size 80273.0 bits ~10035 bytes pass 2: optimizing .. [finding.shortest.path.finding.shortest.path.finding.shortest.pat] size 80039.0 bits ~10005 bytes pass 3: optimizing .. Calculating encoding, done. Phase 3: Generating output file ------------------------------ Encoding: 1101112133423160,1122,2010223445667788,032144406789BBCD Length of crunched data: 10034 bytes. Crunched data reduced 7606 bytes (43.12%) Target is self-decrunching C64 executable, jmp address $0801. Writing "8085out.prg" as prg, saving from $0801 to $304C. Memory layout: |Start |End | Crunched data | $07E7| $2F18| Decrunched data | $0801| $4CE9| Decrunch table | $0334| $03D0| Decruncher | $00FD| $01C0| and $9F,$A7,$AE,$AF Decrunch effect writes to $DBE7. Decruncher: |Enter |During|Exit | RAM config | $37| $37| $37| IRQ enabled | 1| 1| 1|
This looks okay: (monitor in vice)
Attaching crt in vice
Maybe one of these problems:
1) you CAN NOT use BASIC routines when a cart is inserted (without weird tricks, i.e.
storing BASIC routines on cart etc)
2) you need to be careful about $01 as you may map in ROM at $8000 without expecting it.
Please refer to this if in doubt:
http://unusedino.de/ec64/technical/aay/c64/memcfg.html
[3] You should also be careful about the usage of KERNAL routines as some of them
sweep across BASIC-code as well!
After a whole day soldering yesterday, ending up with a wire mess.
Which didn’t work at the end…
Starting measuring some things, and create some test sketches (led blinky tests)
I found out that the main problem was not having the red switches connected to GND.
Blue switches where upside down, this was a easy fix. Because these are ON-ON switches, and where already connected to a common line.
Then a mixup between D0 and D6 (wires crossed)
And it is working! Made some lines and lettering on the frontplate after some playing around.
Weird to input stuff in octal (group of 3 bits)
The Altair 8800 is a microcomputer designed in 1974 by MITS and based on the Intel 8080CPU. Interest grew quickly after it was featured on the cover of the January 1975 issue of Popular Electronics and was sold by mail order through advertisements there, in Radio-Electronics, and in other hobbyist magazines.
UPDATE: 20220804 – Added Octal sheet
I alway loved the simple setup of this computer.
There was no screen and no keyboard.
Only later additions to the machine provided these.
One explanation of the Altair name, is that the name was inspired by Star Trek episode “Amok Time“, where the Enterprise crew went to Altair (Six).
There are only a few differences between the used 8080 CPU and the 8085 CPU of a machine i learned machinecode on.
So for a really long time i wanted to have a Altair alike machine. There are do it yourself kits for sale. Which look like perfect relica’s and there are virtual machines and emulators. But i wanted to have the feeling of throwing the switches.
You can find a emulator here (https://s2js.com/altair/)
So i bought the components, a poker case which can hold the machine. And started building today.
The backend is a arduino based emulator, but with real leds and switches!
(https://create.arduino.cc/projecthub/david-hansel/arduino-altair-8800-simulator-3594a6)
Next to do:
And then … programming 🙂
UPDATE: 20220804 – Added Octal sheet
The Altair is a octal based machine, but i couldn’t find a opcode list in Octal. So i generated one.
When entering a MOV D,M instruction for example, you have to enter
x 0 1 0 1 0 1 1 0 using the switches
Thats 126 in octal but most tables are in hex ( MOV D,M is 56, which is 0101 0110 but not that clear on the switches)
Opcode (oct) | Instruction | function | size | flags | Opcode |
000 | NOP | 1 | 0x00 | ||
001 | LXI B,D16 | B <- byte 3, C <- byte 2 | 3 | 0x01 | |
002 | STAX B | (BC) <- A | 1 | 0x02 | |
003 | INX B | BC <- BC+1 | 1 | 0x03 | |
004 | INR B | B <- B+1 | 1 | Z, S, P, AC | 0x04 |
005 | DCR B | B <- B-1 | 1 | Z, S, P, AC | 0x05 |
006 | MVI B, D8 | B <- byte 2 | 2 | 0x06 | |
007 | RLC | A = A << 1; bit 0 = prev bit 7; CY = prev bit 7 | 1 | CY | 0x07 |
010 | – | 0x08 | |||
011 | DAD B | HL = HL + BC | 1 | CY | 0x09 |
012 | LDAX B | A <- (BC) | 1 | 0x0a | |
013 | DCX B | BC = BC-1 | 1 | 0x0b | |
014 | INR C | C <- C+1 | 1 | Z, S, P, AC | 0x0c |
015 | DCR C | C <-C-1 | 1 | Z, S, P, AC | 0x0d |
016 | MVI C,D8 | C <- byte 2 | 2 | 0x0e | |
017 | RRC | A = A >> 1; bit 7 = prev bit 0; CY = prev bit 0 | 1 | CY | 0x0f |
020 | – | 0x10 | |||
021 | LXI D,D16 | D <- byte 3, E <- byte 2 | 3 | 0x11 | |
022 | STAX D | (DE) <- A | 1 | 0x12 | |
023 | INX D | DE <- DE + 1 | 1 | 0x13 | |
024 | INR D | D <- D+1 | 1 | Z, S, P, AC | 0x14 |
025 | DCR D | D <- D-1 | 1 | Z, S, P, AC | 0x15 |
026 | MVI D, D8 | D <- byte 2 | 2 | 0x16 | |
027 | RAL | A = A << 1; bit 0 = prev CY; CY = prev bit 7 | 1 | CY | 0x17 |
030 | – | 0x18 | |||
031 | DAD D | HL = HL + DE | 1 | CY | 0x19 |
032 | LDAX D | A <- (DE) | 1 | 0x1a | |
033 | DCX D | DE = DE-1 | 1 | 0x1b | |
034 | INR E | E <-E+1 | 1 | Z, S, P, AC | 0x1c |
035 | DCR E | E <- E-1 | 1 | Z, S, P, AC | 0x1d |
036 | MVI E,D8 | E <- byte 2 | 2 | 0x1e | |
037 | RAR | A = A >> 1; bit 7 = prev bit 7; CY = prev bit 0 | 1 | CY | 0x1f |
040 | – | 0x20 | |||
041 | LXI H,D16 | H <- byte 3, L <- byte 2 | 3 | 0x21 | |
042 | SHLD adr | (adr) <-L; (adr+1)<-H | 3 | 0x22 | |
043 | INX H | HL <- HL + 1 | 1 | 0x23 | |
044 | INR H | H <- H+1 | 1 | Z, S, P, AC | 0x24 |
045 | DCR H | H <- H-1 | 1 | Z, S, P, AC | 0x25 |
046 | MVI H,D8 | H <- byte 2 | 2 | 0x26 | |
047 | DAA | special | 1 | 0x27 | |
050 | – | 0x28 | |||
051 | DAD H | HL = HL + HI | 1 | CY | 0x29 |
052 | LHLD adr | L <- (adr); H<-(adr+1) | 3 | 0x2a | |
053 | DCX H | HL = HL-1 | 1 | 0x2b | |
054 | INR L | L <- L+1 | 1 | Z, S, P, AC | 0x2c |
055 | DCR L | L <- L-1 | 1 | Z, S, P, AC | 0x2d |
056 | MVI L, D8 | L <- byte 2 | 2 | 0x2e | |
057 | CMA | A <- !A | 1 | 0x2f | |
060 | – | 0x30 | |||
061 | LXI SP, D16 | SP.hi <- byte 3, SP.lo <- byte 2 | 3 | 0x31 | |
062 | STA adr | (adr) <- A | 3 | 0x32 | |
063 | INX SP | SP = SP + 1 | 1 | 0x33 | |
064 | INR M | (HL) <- (HL)+1 | 1 | Z, S, P, AC | 0x34 |
065 | DCR M | (HL) <- (HL)-1 | 1 | Z, S, P, AC | 0x35 |
066 | MVI M,D8 | (HL) <- byte 2 | 2 | 0x36 | |
067 | STC | CY = 1 | 1 | CY | 0x37 |
070 | – | 0x38 | |||
071 | DAD SP | HL = HL + SP | 1 | CY | 0x39 |
072 | LDA adr | A <- (adr) | 3 | 0x3a | |
073 | DCX SP | SP = SP-1 | 1 | 0x3b | |
074 | INR A | A <- A+1 | 1 | Z, S, P, AC | 0x3c |
075 | DCR A | A <- A-1 | 1 | Z, S, P, AC | 0x3d |
076 | MVI A,D8 | A <- byte 2 | 2 | 0x3e | |
077 | CMC | CY=!CY | 1 | CY | 0x3f |
100 | MOV B,B | B <- B | 1 | 0x40 | |
101 | MOV B,C | B <- C | 1 | 0x41 | |
102 | MOV B,D | B <- D | 1 | 0x42 | |
103 | MOV B,E | B <- E | 1 | 0x43 | |
104 | MOV B,H | B <- H | 1 | 0x44 | |
105 | MOV B,L | B <- L | 1 | 0x45 | |
106 | MOV B,M | B <- (HL) | 1 | 0x46 | |
107 | MOV B,A | B <- A | 1 | 0x47 | |
110 | MOV C,B | C <- B | 1 | 0x48 | |
111 | MOV C,C | C <- C | 1 | 0x49 | |
112 | MOV C,D | C <- D | 1 | 0x4a | |
113 | MOV C,E | C <- E | 1 | 0x4b | |
114 | MOV C,H | C <- H | 1 | 0x4c | |
115 | MOV C,L | C <- L | 1 | 0x4d | |
116 | MOV C,M | C <- (HL) | 1 | 0x4e | |
117 | MOV C,A | C <- A | 1 | 0x4f | |
120 | MOV D,B | D <- B | 1 | 0x50 | |
121 | MOV D,C | D <- C | 1 | 0x51 | |
122 | MOV D,D | D <- D | 1 | 0x52 | |
123 | MOV D,E | D <- E | 1 | 0x53 | |
124 | MOV D,H | D <- H | 1 | 0x54 | |
125 | MOV D,L | D <- L | 1 | 0x55 | |
126 | MOV D,M | D <- (HL) | 1 | 0x56 | |
127 | MOV D,A | D <- A | 1 | 0x57 | |
130 | MOV E,B | E <- B | 1 | 0x58 | |
131 | MOV E,C | E <- C | 1 | 0x59 | |
132 | MOV E,D | E <- D | 1 | 0x5a | |
133 | MOV E,E | E <- E | 1 | 0x5b | |
134 | MOV E,H | E <- H | 1 | 0x5c | |
135 | MOV E,L | E <- L | 1 | 0x5d | |
136 | MOV E,M | E <- (HL) | 1 | 0x5e | |
137 | MOV E,A | E <- A | 1 | 0x5f | |
140 | MOV H,B | H <- B | 1 | 0x60 | |
141 | MOV H,C | H <- C | 1 | 0x61 | |
142 | MOV H,D | H <- D | 1 | 0x62 | |
143 | MOV H,E | H <- E | 1 | 0x63 | |
144 | MOV H,H | H <- H | 1 | 0x64 | |
145 | MOV H,L | H <- L | 1 | 0x65 | |
146 | MOV H,M | H <- (HL) | 1 | 0x66 | |
147 | MOV H,A | H <- A | 1 | 0x67 | |
150 | MOV L,B | L <- B | 1 | 0x68 | |
151 | MOV L,C | L <- C | 1 | 0x69 | |
152 | MOV L,D | L <- D | 1 | 0x6a | |
153 | MOV L,E | L <- E | 1 | 0x6b | |
154 | MOV L,H | L <- H | 1 | 0x6c | |
155 | MOV L,L | L <- L | 1 | 0x6d | |
156 | MOV L,M | L <- (HL) | 1 | 0x6e | |
157 | MOV L,A | L <- A | 1 | 0x6f | |
160 | MOV M,B | (HL) <- B | 1 | 0x70 | |
161 | MOV M,C | (HL) <- C | 1 | 0x71 | |
162 | MOV M,D | (HL) <- D | 1 | 0x72 | |
163 | MOV M,E | (HL) <- E | 1 | 0x73 | |
164 | MOV M,H | (HL) <- H | 1 | 0x74 | |
165 | MOV M,L | (HL) <- L | 1 | 0x75 | |
166 | HLT | special | 1 | 0x76 | |
167 | MOV M,A | (HL) <- A | 1 | 0x77 | |
170 | MOV A,B | A <- B | 1 | 0x78 | |
171 | MOV A,C | A <- C | 1 | 0x79 | |
172 | MOV A,D | A <- D | 1 | 0x7a | |
173 | MOV A,E | A <- E | 1 | 0x7b | |
174 | MOV A,H | A <- H | 1 | 0x7c | |
175 | MOV A,L | A <- L | 1 | 0x7d | |
176 | MOV A,M | A <- (HL) | 1 | 0x7e | |
177 | MOV A,A | A <- A | 1 | 0x7f | |
200 | ADD B | A <- A + B | 1 | Z, S, P, CY, AC | 0x80 |
201 | ADD C | A <- A + C | 1 | Z, S, P, CY, AC | 0x81 |
202 | ADD D | A <- A + D | 1 | Z, S, P, CY, AC | 0x82 |
203 | ADD E | A <- A + E | 1 | Z, S, P, CY, AC | 0x83 |
204 | ADD H | A <- A + H | 1 | Z, S, P, CY, AC | 0x84 |
205 | ADD L | A <- A + L | 1 | Z, S, P, CY, AC | 0x85 |
206 | ADD M | A <- A + (HL) | 1 | Z, S, P, CY, AC | 0x86 |
207 | ADD A | A <- A + A | 1 | Z, S, P, CY, AC | 0x87 |
210 | ADC B | A <- A + B + CY | 1 | Z, S, P, CY, AC | 0x88 |
211 | ADC C | A <- A + C + CY | 1 | Z, S, P, CY, AC | 0x89 |
212 | ADC D | A <- A + D + CY | 1 | Z, S, P, CY, AC | 0x8a |
213 | ADC E | A <- A + E + CY | 1 | Z, S, P, CY, AC | 0x8b |
214 | ADC H | A <- A + H + CY | 1 | Z, S, P, CY, AC | 0x8c |
215 | ADC L | A <- A + L + CY | 1 | Z, S, P, CY, AC | 0x8d |
216 | ADC M | A <- A + (HL) + CY | 1 | Z, S, P, CY, AC | 0x8e |
217 | ADC A | A <- A + A + CY | 1 | Z, S, P, CY, AC | 0x8f |
220 | SUB B | A <- A – B | 1 | Z, S, P, CY, AC | 0x90 |
221 | SUB C | A <- A – C | 1 | Z, S, P, CY, AC | 0x91 |
222 | SUB D | A <- A + D | 1 | Z, S, P, CY, AC | 0x92 |
223 | SUB E | A <- A – E | 1 | Z, S, P, CY, AC | 0x93 |
224 | SUB H | A <- A + H | 1 | Z, S, P, CY, AC | 0x94 |
225 | SUB L | A <- A – L | 1 | Z, S, P, CY, AC | 0x95 |
226 | SUB M | A <- A + (HL) | 1 | Z, S, P, CY, AC | 0x96 |
227 | SUB A | A <- A – A | 1 | Z, S, P, CY, AC | 0x97 |
230 | SBB B | A <- A – B – CY | 1 | Z, S, P, CY, AC | 0x98 |
231 | SBB C | A <- A – C – CY | 1 | Z, S, P, CY, AC | 0x99 |
232 | SBB D | A <- A – D – CY | 1 | Z, S, P, CY, AC | 0x9a |
233 | SBB E | A <- A – E – CY | 1 | Z, S, P, CY, AC | 0x9b |
234 | SBB H | A <- A – H – CY | 1 | Z, S, P, CY, AC | 0x9c |
235 | SBB L | A <- A – L – CY | 1 | Z, S, P, CY, AC | 0x9d |
236 | SBB M | A <- A – (HL) – CY | 1 | Z, S, P, CY, AC | 0x9e |
237 | SBB A | A <- A – A – CY | 1 | Z, S, P, CY, AC | 0x9f |
240 | ANA B | A <- A & B | 1 | Z, S, P, CY, AC | 0xa0 |
241 | ANA C | A <- A & C | 1 | Z, S, P, CY, AC | 0xa1 |
242 | ANA D | A <- A & D | 1 | Z, S, P, CY, AC | 0xa2 |
243 | ANA E | A <- A & E | 1 | Z, S, P, CY, AC | 0xa3 |
244 | ANA H | A <- A & H | 1 | Z, S, P, CY, AC | 0xa4 |
245 | ANA L | A <- A & L | 1 | Z, S, P, CY, AC | 0xa5 |
246 | ANA M | A <- A & (HL) | 1 | Z, S, P, CY, AC | 0xa6 |
247 | ANA A | A <- A & A | 1 | Z, S, P, CY, AC | 0xa7 |
250 | XRA B | A <- A ^ B | 1 | Z, S, P, CY, AC | 0xa8 |
251 | XRA C | A <- A ^ C | 1 | Z, S, P, CY, AC | 0xa9 |
252 | XRA D | A <- A ^ D | 1 | Z, S, P, CY, AC | 0xaa |
253 | XRA E | A <- A ^ E | 1 | Z, S, P, CY, AC | 0xab |
254 | XRA H | A <- A ^ H | 1 | Z, S, P, CY, AC | 0xac |
255 | XRA L | A <- A ^ L | 1 | Z, S, P, CY, AC | 0xad |
256 | XRA M | A <- A ^ (HL) | 1 | Z, S, P, CY, AC | 0xae |
257 | XRA A | A <- A ^ A | 1 | Z, S, P, CY, AC | 0xaf |
260 | ORA B | A <- A | B | 1 | Z, S, P, CY, AC | 0xb0 |
261 | ORA C | A <- A | C | 1 | Z, S, P, CY, AC | 0xb1 |
262 | ORA D | A <- A | D | 1 | Z, S, P, CY, AC | 0xb2 |
263 | ORA E | A <- A | E | 1 | Z, S, P, CY, AC | 0xb3 |
264 | ORA H | A <- A | H | 1 | Z, S, P, CY, AC | 0xb4 |
265 | ORA L | A <- A | L | 1 | Z, S, P, CY, AC | 0xb5 |
266 | ORA M | A <- A | (HL) | 1 | Z, S, P, CY, AC | 0xb6 |
267 | ORA A | A <- A | A | 1 | Z, S, P, CY, AC | 0xb7 |
270 | CMP B | A – B | 1 | Z, S, P, CY, AC | 0xb8 |
271 | CMP C | A – C | 1 | Z, S, P, CY, AC | 0xb9 |
272 | CMP D | A – D | 1 | Z, S, P, CY, AC | 0xba |
273 | CMP E | A – E | 1 | Z, S, P, CY, AC | 0xbb |
274 | CMP H | A – H | 1 | Z, S, P, CY, AC | 0xbc |
275 | CMP L | A – L | 1 | Z, S, P, CY, AC | 0xbd |
276 | CMP M | A – (HL) | 1 | Z, S, P, CY, AC | 0xbe |
277 | CMP A | A – A | 1 | Z, S, P, CY, AC | 0xbf |
300 | RNZ | if NZ, RET | 1 | 0xc0 | |
301 | POP B | C <- (sp); B <- (sp+1); sp <- sp+2 | 1 | 0xc1 | |
302 | JNZ adr | if NZ, PC <- adr | 3 | 0xc2 | |
303 | JMP adr | PC <= adr | 3 | 0xc3 | |
304 | CNZ adr | if NZ, CALL adr | 3 | 0xc4 | |
305 | PUSH B | (sp-2)<-C; (sp-1)<-B; sp <- sp – 2 | 1 | 0xc5 | |
306 | ADI D8 | A <- A + byte | 2 | Z, S, P, CY, AC | 0xc6 |
307 | RST 0 | CALL $0 | 1 | 0xc7 | |
310 | RZ | if Z, RET | 1 | 0xc8 | |
311 | RET | PC.lo <- (sp); PC.hi<-(sp+1); SP <- SP+2 | 1 | 0xc9 | |
312 | JZ adr | if Z, PC <- adr | 3 | 0xca | |
313 | – | 0xcb | |||
314 | CZ adr | if Z, CALL adr | 3 | 0xcc | |
315 | CALL adr | (SP-1)<-PC.hi;(SP-2)<-PC.lo;SP<-SP-2;PC=adr | 3 | 0xcd | |
316 | ACI D8 | A <- A + data + CY | 2 | Z, S, P, CY, AC | 0xce |
317 | RST 1 | CALL $8 | 1 | 0xcf | |
320 | RNC | if NCY, RET | 1 | 0xd0 | |
321 | POP D | E <- (sp); D <- (sp+1); sp <- sp+2 | 1 | 0xd1 | |
322 | JNC adr | if NCY, PC<-adr | 3 | 0xd2 | |
323 | OUT D8 | special | 2 | 0xd3 | |
324 | CNC adr | if NCY, CALL adr | 3 | 0xd4 | |
325 | PUSH D | (sp-2)<-E; (sp-1)<-D; sp <- sp – 2 | 1 | 0xd5 | |
326 | SUI D8 | A <- A – data | 2 | Z, S, P, CY, AC | 0xd6 |
327 | RST 2 | CALL $10 | 1 | 0xd7 | |
330 | RC | if CY, RET | 1 | 0xd8 | |
331 | – | 0xd9 | |||
332 | JC adr | if CY, PC<-adr | 3 | 0xda | |
333 | IN D8 | special | 2 | 0xdb | |
334 | CC adr | if CY, CALL adr | 3 | 0xdc | |
335 | – | 0xdd | |||
336 | SBI D8 | A <- A – data – CY | 2 | Z, S, P, CY, AC | 0xde |
337 | RST 3 | CALL $18 | 1 | 0xdf | |
340 | RPO | if PO, RET | 1 | 0xe0 | |
341 | POP H | L <- (sp); H <- (sp+1); sp <- sp+2 | 1 | 0xe1 | |
342 | JPO adr | if PO, PC <- adr | 3 | 0xe2 | |
343 | XTHL | L <-> (SP); H <-> (SP+1) | 1 | 0xe3 | |
344 | CPO adr | if PO, CALL adr | 3 | 0xe4 | |
345 | PUSH H | (sp-2)<-L; (sp-1)<-H; sp <- sp – 2 | 1 | 0xe5 | |
346 | ANI D8 | A <- A & data | 2 | Z, S, P, CY, AC | 0xe6 |
347 | RST 4 | CALL $20 | 1 | 0xe7 | |
350 | RPE | if PE, RET | 1 | 0xe8 | |
351 | PCHL | PC.hi <- H; PC.lo <- L | 1 | 0xe9 | |
352 | JPE adr | if PE, PC <- adr | 3 | 0xea | |
353 | XCHG | H <-> D; L <-> E | 1 | 0xeb | |
354 | CPE adr | if PE, CALL adr | 3 | 0xec | |
355 | – | 0xed | |||
356 | XRI D8 | A <- A ^ data | 2 | Z, S, P, CY, AC | 0xee |
357 | RST 5 | CALL $28 | 1 | 0xef | |
360 | RP | if P, RET | 1 | 0xf0 | |
361 | POP PSW | flags <- (sp); A <- (sp+1); sp <- sp+2 | 1 | 0xf1 | |
362 | JP adr | if P=1 PC <- adr | 3 | 0xf2 | |
363 | DI | special | 1 | 0xf3 | |
364 | CP adr | if P, PC <- adr | 3 | 0xf4 | |
365 | PUSH PSW | (sp-2)<-flags; (sp-1)<-A; sp <- sp – 2 | 1 | 0xf5 | |
366 | ORI D8 | A <- A | data | 2 | Z, S, P, CY, AC | 0xf6 |
367 | RST 6 | CALL $30 | 1 | 0xf7 | |
370 | RM | if M, RET | 1 | 0xf8 | |
371 | SPHL | SP=HL | 1 | 0xf9 | |
372 | JM adr | if M, PC <- adr | 3 | 0xfa | |
373 | EI | special | 1 | 0xfb | |
374 | CM adr | if M, CALL adr | 3 | 0xfc | |
375 | – | 0xfd | |||
376 | CPI D8 | A – data | 2 | Z, S, P, CY, AC | 0xfe |
377 | RST 7 | CALL $38 | 1 | 0xff |
Way back in 2018 i was playing around with i2c and touch.
I remembered that VGA was using i2c to get information from monitors like brand/type and connection information.
I managed to access the cap1188 up to my Laptop via VGA.
The final python code i used to play with the variables and playing sound i can’t find.
But below is the test code
#!/usr/bin/python # NOTE: i did a address scan, now i have 3v3 connected to AD, so probably the address is 0x28 !! import smbus bus = smbus.SMBus(1) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1) DEVICE_ADDRESS = 0x29 DEVICEx = 0x10 DEVICE_REG_MODE1 = 0x00 DEVICE_REG_LEDOUT0 = 0x1d #Write a single register bus.write_byte_data(DEVICE_ADDRESS, 0x1f, 0x3F) #Write an array of registers #ledout_values = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] #bus.write_i2c_block_data(DEVICE_ADDRESS, DEVICE_REG_LEDOUT0, ledout_values) while True: print bus.read_byte_data(DEVICE_ADDRESS,0x10), bus.read_byte_data(DEVICE_ADDRESS,0x11) , bus.read_byte_data(DEVICE_ADDRESS,0x12), bus.read_byte_data(DEVICE_ADDRESS,0x13), bus.read_byte_data(DEVICE_ADDRESS,0x14), bus.read_byte_dat a(DEVICE_ADDRESS,0x15), bus.read_byte_data(DEVICE_ADDRESS,0x16), bus.read_byte_data(DEVICE_ADDRESS,0x17)
Today i connected the cap1188 to a ESP32 and a piezo buzzer.
/*** Based on below library ***/ /*** Changed pins and added sound ***/ /*************************************************** This is a library for the CAP1188 I2C/SPI 8-chan Capacitive Sensor Designed specifically to work with the CAP1188 sensor from Adafruit ----> https://www.adafruit.com/products/1602 These sensors use I2C/SPI to communicate, 2+ pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ #include <Wire.h> #include <SPI.h> #include <Adafruit_CAP1188.h> const int TONE_OUTPUT_PIN = 26; const int TONE_PWM_CHANNEL = 0; int freq = 0; // Reset Pin is used for I2C or SPI #define CAP1188_RESET 9 // CS pin is used for software or hardware SPI #define CAP1188_CS 10 // These are defined for software SPI, for hardware SPI, check your // board's SPI pins in the Arduino documentation #define CAP1188_MOSI 11 #define CAP1188_MISO 12 #define CAP1188_CLK 13 // For I2C, connect SDA to your Arduino's SDA pin, SCL to SCL pin // On UNO/Duemilanove/etc, SDA == Analog 4, SCL == Analog 5 // On Leonardo/Micro, SDA == Digital 2, SCL == Digital 3 // On Mega/ADK/Due, SDA == Digital 20, SCL == Digital 21 // Use I2C, no reset pin! Adafruit_CAP1188 cap = Adafruit_CAP1188(); // Or...Use I2C, with reset pin //Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_RESET); // Or... Hardware SPI, CS pin & reset pin // Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_CS, CAP1188_RESET); // Or.. Software SPI: clock, miso, mosi, cs, reset //Adafruit_CAP1188 cap = Adafruit_CAP1188(CAP1188_CLK, CAP1188_MISO, CAP1188_MOSI, CAP1188_CS, CAP1188_RESET); void setup() { Serial.begin(9600); Serial.println("CAP1188 test!"); ledcAttachPin(TONE_OUTPUT_PIN, TONE_PWM_CHANNEL); // Initialize the sensor, if using i2c you can pass in the i2c address if (!cap.begin(0x28)){ //if (!cap.begin()) { Serial.println("CAP1188 not found"); while (1); } Serial.println("CAP1188 found!"); } void loop() { uint8_t touched = cap.touched(); if (touched == 0) { // No touch detected return; } for (uint8_t i=0; i<8; i++) { if (touched & (1 << i)) { Serial.print(touched); Serial.print("\t"); freq = (i * 100); ledcWriteTone(TONE_PWM_CHANNEL, freq); delay(100); } } Serial.println(); delay(50); }
Finding the right pins or above pinout was the hardest part.
The sketch reads the pins binary so value 129 is first and last bit.
Now i have to get the sound sounding a little better and add frequencies and fingersettings to the sketch to get a minimal electronic bagpipe. (V3 it is .. )
To be continued ..