diff --git a/README.md b/README.md index e176bcc..f23484b 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,13 @@ The problem is that I/O is pretty difficult. No one with one of these machines has come forward with the ability to get anything into or out of the existing serial port. -The goal: get data of the TLC out of the machine. Hard to do without functional I/O. +The goal: get data into and out of the TLC machine. Hard to do without functional I/O. -### Audio to the rescue +### Audio and Joystick to the rescue One thing the TLC _does_ have is sound. And a headphone jack. So we have... output. +Looming on the horizon is bit-banged serial data via the joystick port. So we have... +input. #### A long time ago... diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 0000000..57f5dad --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,3 @@ +tlc.dsk +*.lst +*.bin diff --git a/build/Makefile b/build/Makefile new file mode 100644 index 0000000..1d0dafb --- /dev/null +++ b/build/Makefile @@ -0,0 +1,18 @@ +AC_JAR ?= lib/AppleCommander/AppleCommander-1.3.5.13-ac.jar + +.PHONY: +all: + ca65 ../src/tapeout.asm --listing tapeout.lst + ld65 ../src/tapeout.o -o tapeout.bin -C area_300.cfg + ca65 ../src/bitbangr.asm --listing bitbangr.lst + ld65 ../src/bitbangr.o -o bitbangr.bin -C area_300.cfg + + @cp tlcBase.dsk tlc.dsk + cat bitbangr.bin | java -jar ${AC_JAR} -p tlc.dsk BITB BIN 0x0300 + +.PHONY: +clean: + -rm ../src/*.o + -rm *.lst + -rm bitbangr.bin + -rm tapeout.bin diff --git a/src/tapeout.cfg b/build/area_300.cfg similarity index 100% rename from src/tapeout.cfg rename to build/area_300.cfg diff --git a/build/lib/AppleCommander/AppleCommander-1.3.5.13-ac.jar b/build/lib/AppleCommander/AppleCommander-1.3.5.13-ac.jar new file mode 100644 index 0000000..5813ca9 Binary files /dev/null and b/build/lib/AppleCommander/AppleCommander-1.3.5.13-ac.jar differ diff --git a/build/tlcBase.dsk b/build/tlcBase.dsk new file mode 100644 index 0000000..b7a8b55 Binary files /dev/null and b/build/tlcBase.dsk differ diff --git a/doc/cable.txt b/doc/cable.txt new file mode 100644 index 0000000..c9b2569 --- /dev/null +++ b/doc/cable.txt @@ -0,0 +1,22 @@ +BOM +--- +2N4401 NPN transistor +RS-232/TTL Level Shifter +Male DE9 connector + +Connections +----------- +Switch is from collector to emitter, governed by base +4401 Collector - DE9 pin 2 (+5v) +4401 Emitter - DE9 pin 7 (PB0*) +4401 Base - Level Shifter out + +Level Shifter GND - DE9 pin 3 (GND) and External Power ground +Level Shifter out - 4401 Base +Level Shifter Vcc - (External Power) + +DE9 pin 3 (GND) - Level Shifter GND +DE9 pin 7 (PB0*) - 4402 Emitter +DE9 pin 2 (+5v) - 4402 Collector + +* Consider using PB1 instead of PB0; PB0 held high is like holding down the open-apple key, turns ctrl-reset into ctrl-openapple-reset all the time diff --git a/src/.gitignore b/src/.gitignore index 31e46f1..8f6c79b 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,3 @@ -/tapeout.o -/tapeout.bin -/tapeout.lst +/*.o +/*.bin +/*.lst diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index f759198..0000000 --- a/src/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -.PHONY: -all: - ca65 tapeout.asm --listing tapeout.lst - ld65 tapeout.o -o tapeout.bin -C tapeout.cfg diff --git a/src/bitbangr.asm b/src/bitbangr.asm new file mode 100644 index 0000000..7786c8b --- /dev/null +++ b/src/bitbangr.asm @@ -0,0 +1,108 @@ +; +; Bitbang RS-232 (using a pushbutton input in our case) +; + +; +; CPU cycle counting must be done to meet bit-time requirements on the wire. +; Bit time is defined as (1 / baud) seconds, or (1000000 / baud) microseconds. +; So at 9600 baud, we get a bit time 0.000104166 seconds, or 104.166 microseconds. +; With a 6502 CPU running at about 1MHz, each CPU clock cycle is about 1.023 +; microseconds long. +; + +.org $300 ; For now + +; Some system constants +WAIT = $FCA8 +CROUT = $FD8E +PRBYTE = $FDDA +PRHEX = $FDE3 +COUT = $FDED +PRERR = $FF2D +PB0 = $C061 ; Paddle 0 PushButton: HIGH/ON if > 127, LOW/OFF if < 128. + +start: + lda #$09 ; We'll be watching for 8 bits plus one stop bit + sta bits + clc + jsr pb0_recv ; Pull a byte from PB0 + bcs printit ; Carry set means we got a '1' stop bit, so we're good + jsr CROUT + jsr PRERR ; Else we got a framing error + +printit: + ora #$80 + jsr COUT ; PRBYTE + lda $25 + cmp #$17 + bne start + lda #$00 + sta $25 + beq start +done: rts + +pb0_recv: + +; State is unknown + +poll_for_1: +; sample state + lda PB0 + bpl poll_for_1 ; if not negative, branch to wait_for_1 + +; State is now 1 + +poll_for_0: +; sample state + lda PB0 + bmi poll_for_0 ; if negative, branch to wait_for_0 + +; State just became 0 (start bit) + +; Wait 1.5 bit times (104.2 + 52.1 = 156.3us at 9600 baud) to get into the middle of the first bit +; Approximately 152.8 ($99) CPU cycles +; When falling through to here, the above branch was not taken - consuming 2 cycles to get here + ldx #$14 ; 2 loop count +: nop ; 2 \ + dex ; 2 |-- 7 * loop count + bne :- ; 3 / final exit of the loop adds 2, branch not taken +; $90 cycles to get here; need to burn 7 more + beq :+ ; 3 +: nop ; 2 + nop ; 2 +; $97 cycles to get here; save 2 for upcoming clc +pull_byte: +; We now have one bit time (104.2us at 9600 baud) to process this bit +; Approximately 106.6 ($6B) CPU cycles + clc ; 2 + lda PB0 ; 4 + bmi :+ ; 2 if positive, 3 if negative + jmp push_bit ; 3 +: sec ; 2 bit was low/negative +push_bit: ; We now have a bit in the carry + dec bits ; 6 + beq byte_complete ; Have we read all 8 bits? Then this bit is the stop bit; leave with carry set + ; 2 (in the case we care about, i.e. more bits to read) + lda ring ; 4 + ror ; 2 + sta ring ; 4 +; $1C/$1D cycles to get here (since center of bit time) +; We are now done with processing that bit; we need to cool our heels for the rest ($6B - $1C = $4F) of the +; bit time in order to get into the middle of the next bit + ldx #$0A ; 2 loop count +: nop ; 2 \ + dex ; 2 |-- 7 * loop count + bne :- ; 3 / final exit of the loop adds 2, branch not taken +; $48 cycles to get here + nop ; 2 + nop ; 2 + jmp pull_byte ; 3 Loop around for another bit - we burned $4F cycles +; $6B +byte_complete: + ; Carry now holds stop bit (clear/0 indicates framing error, because we end with set/1) + lda ring ; Exit with the assembled byte in A + rts + +pb_state: .byte $00 +ring: .byte $55 +bits: .byte $00 diff --git a/src/rs232.png b/src/rs232.png new file mode 100644 index 0000000..c58974d Binary files /dev/null and b/src/rs232.png differ