Page 1 of 2
Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 12:19 am
by Very.Von
I designed an AppleII peripheral card with breakouts for the expansion slot and BluePill as an experimental project to interface the two:

- CardInSlot.jpg (77.39 KiB) Viewed 3430 times
The timing diagram for this type of computer is fairly well known (
see here, page 69,70)

- WriteToPeripheral.PNG (23.35 KiB) Viewed 3430 times
Problem is when the bus is read (GPIOB->IDR) via interrupt on *DS (Device Select) RISING the data returned doesn't change when bus data is changed.
Here's the sketch (I’m using the maple boot loader and DFU to load sketches onto the board using Arduino IDE.)
Code: Select all
// Control Signals
#define DS PB3 // *Device Select
#define RW PB4 // Read / Write (Read High, Write Low)
#define BUS01 PB5 // BUS 01 Clock
// Data Bus
#define D0 PB8
#define D1 PB9
#define D2 PB10
#define D3 PB11
#define D4 PB12
#define D5 PB13
#define D6 PB14
#define D7 PB15
// Device Select ISR
void DS_ISR()
{
noInterrupts();
uint32_t value = GPIOB->IDR;
interrupts();
displayBits32(value);
}
void setup()
{
Serial.begin(9600);
pinMode(DS, INPUT);
pinMode(RW, INPUT);
pinMode(BUS01, INPUT);
pinMode(D0, INPUT);
pinMode(D1, INPUT);
pinMode(D2, INPUT);
pinMode(D3, INPUT);
pinMode(D4, INPUT);
pinMode(D5, INPUT);
pinMode(D6, INPUT);
pinMode(D7, INPUT);
attachInterrupt(digitalPinToInterrupt(DS), DS_ISR, RISING);
delay(2000);
Serial.write("Booted 6\n");
}
void loop() {} // nothing
void displayBits32(uint32_t value) {
uint32_t c;
uint32_t displaymask = 1 << 31;
for (c = 1; c <=32; c++) {
if (value & displaymask)
Serial.print('1');
else
Serial.print('0');
value <<= 1;
if (c % 8 == 0)
Serial.print(' ');
}
Serial.write("\n");
}
Ran these machine language commands on the Apple2 to write data to slot 6:

- AppleCommands.JPG (57.24 KiB) Viewed 3430 times
Serial Output from the sketch. Notice that PB8-15 don't change:
Code: Select all
Booted 6
00000000 00000000 01000000 00011000
00000000 00000000 01000000 00011000
00000000 00000000 01000000 00011000
Is there some aspect of the circuitry, code or register configuration that I'm missing when reading this 5V data bus?
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 12:23 am
by Very.Von
Just to be sure the machine language code was correct I connected a logic analyzer to the bus for each command and confirmed the data bus is correct:
(Edit: the images are hard to read, I put a red circle around the data bus values which match up with the commands)
C0E0-00

- Apple Bus C0E0-00.jpg (84.82 KiB) Viewed 3429 times
C0E0-FF

- Apple Bus C0E0-FF.jpg (83.06 KiB) Viewed 3429 times
C0E0-55

- Apple Bus C0E0-55.jpg (83.26 KiB) Viewed 3429 times
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 1:03 am
by dannyf
no idea what you are doing. but a couple suggestions:
1. in DS_ISR(): you don't need to turn off / on interrupts.
2. as you are using serial (@9600bps) in the display routine, it is fairly slow. a better way is to set a flag and display in the main loop instead. I would just print out "value" in hex/decimal directly to make that faster.
the display routine can be sped up as well.
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 2:25 pm
by ag123
among the things stm32 is 3.3v, apple maybe 5v?
levels matter, or transistors may not switch.
a usual trick is to use a 'bridge' chip, e.g. 74HC(T)245
https://assets.nexperia.com/documents/d ... HCT245.pdf
that T in 74HCT245 is particularly important
coming from the other way 74LVC245
https://www.ti.com/lit/ds/symlink/sn74lvc245a.pdf
oh and stm32 even for stm32f103 is a 'whopping' 72 Mhz, speeds may matter
accordingly apple ][ is a whopping 1 Mhz
https://en.wikipedia.org/wiki/Apple_II
overclock an Apple ][ any one lol
it is moderately amazing that stm32 (even with f103) its ADC can probably play oscilloscope for apple signals.
beyond that modern day high frequency/speed signals are too fast to sample at 1-2 msps.
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 3:42 pm
by Bakisha
As i recall from 6502 timings, your goal is to read data bus at rising edge of BUS0. . Maybe you are reading data bus too late. Try to attach interrupt at falling edge of DS , and while BUS0 is low, keep reading data bus...
Code: Select all
attachInterrupt(digitalPinToInterrupt(DS), DS_ISR, FALLING);
volatile uint32_t value=0;
volatile bool data_ready = false;
// Device Select ISR
void DS_ISR()
{
while(digitalRead(BUS0)==LOW){ // or digitalReadFast
value = GPIOB->IDR;
}
data_ready = true;
}
void loop() {
if (data_ready){
data_ready = false;
displayBits32(value);
}
}
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 6:39 pm
by Very.Von
@Bakisha I tried your suggestion. Seems no matter what data I write the output is always:
Code: Select all
00000000 00000000 00100000 01011000
Sketch Code:
Code: Select all
// attach interrupt at falling edge of DS , and while BUS00 is low, keep reading data bus...
// output is always 00000000 00000000 00100000 01011000
// Control Signals
#define DS PB3
#define RW PB4
#define BUS01 PB5
#define BUS00 PB6
// Data Bus
#define D0 PB8
#define D1 PB9
#define D2 PB10
#define D3 PB11
#define D4 PB12
#define D5 PB13
#define D6 PB14
#define D7 PB15
volatile uint32_t value = 0;
volatile bool data_ready = false;
// Device Select ISR
void DS_ISR()
{
while(digitalReadFast(digitalPinToPinName(BUS00))==LOW) {
value = GPIOB->IDR;
}
data_ready = true;
}
void setup()
{
Serial.begin(9600);
pinMode(DS, INPUT);
pinMode(RW, INPUT);
pinMode(BUS01, INPUT);
pinMode(BUS00, INPUT);
pinMode(D0, INPUT);
pinMode(D1, INPUT);
pinMode(D2, INPUT);
pinMode(D3, INPUT);
pinMode(D4, INPUT);
pinMode(D5, INPUT);
pinMode(D6, INPUT);
pinMode(D7, INPUT);
attachInterrupt(digitalPinToInterrupt(DS), DS_ISR, FALLING);
delay(2000);
Serial.write("Booted DR 4\n");
}
void loop() {
if (data_ready) {
data_ready = false;
displayBits32(value);
}
}
void displayBits32(uint32_t value) {
uint32_t c;
uint32_t displaymask = 1 << 31;
for (c = 1; c <=32; c++) {
if (value & displaymask)
Serial.print('1');
else
Serial.print('0');
value <<= 1;
if (c % 8 == 0)
Serial.print(' ');
}
Serial.write("\n");
}
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 6:45 pm
by Very.Von
@ag123 thanks for bridge chip suggestion! As I understand it PortB is 5V "Tolerant" - does this mean I should have external 5V pull-up's on the pins?
Yes, the stm32 is 72x faster than the Apple2, so I'm sure we can read & write easily once the timing & circuitry is sorted
@dannyf I added the disabling of interrupts after reading this post:
Bluepill need help with interrupt
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 8:48 pm
by dannyf
Sketch Code:
some suggestions:
1. not sure why you needed the while loop in the DS_ISR() -> it wouldn't be triggered unless you are on a falling edge.
2. what if you feed the display routine with a known value. See if it will display correctly.
the structure of the code is more sound now.
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 9:41 pm
by Bakisha
This is little confusing for me:
Code: Select all
uint32_t displaymask = 1 << 31;
if (value & displaymask)
}
Did you mean
dannyf wrote: Wed Jul 05, 2023 8:48 pm
1. not sure why you needed the while loop in the DS_ISR() -> it wouldn't be triggered unless you are on a falling edge.
It's because 6502 timing. Adrress and RW is stable 300nS after start of clock cycle (first half-cycle) and data bus from 6502 is stable 300nS (max) after rising edge of clock (second half-cycle) and is stable 30nS after falling edge of clock.
In this case , clock is inverted (probably some glue logic), as i see from above attached pictures (BUS0). I meant to grab data bus on rising edge of BUS0. If it reads after, data bus is maybe in high-z or unknown state.
Also, try without
Code: Select all
while(digitalReadFast(digitalPinToPinName(BUS00))==LOW) {
digitalPinToPinName( need some execution time, maybe even more then 500nS.
Maybe with
Code: Select all
while(digitalReadFast(PB_5)==LOW){
Or even
Code: Select all
while( ( GPIOB->IDR)&(1<<5) {
value = GPIOB->IDR;
}
Re: Can’t read AppleII 8-bit Data Bus with Blue Pill
Posted: Wed Jul 05, 2023 9:58 pm
by Very.Von
@Bakisha I didn't write the displayBits32 function, but I did just test it:
Code: Select all
uint32_t test = 0x12345678;
displayBits32(test);
Output:
Code: Select all
00010010 00110100 01010110 01111000
So appears to be working?
I'm going to adjust the sketch with your changes and re-run, I'll post again shortly.