My Propeller talks kind of QBUS and yours ?
Ale
Posts: 2,363
in Propeller 1
I got fascinated with the russian produced pdp-11 clones, like the KR1801VMx. There are a number of sources for documentation, mostly in russian. Another world completely. I decided to try to build a BK-0010 or similar.
This processor has a QBUS interface, directly on die, meaning it does not have separated address/data and normal control lines. Some of the control lines are open-collector and some totem-pole. Of course, you can look at the recently captured schematic of the A or G versions, and peek at the verilog of a (quite) accurate replica for better understanding but hooking the processor to our propeller provides, I think, the ultimate level of gratification (if it works) .
It kind of works, I'd say. The address/data bus is inverted (to confuse the unwise )... I send 0xEFFE what I think should be mov r0,r1. Why do I like the pdp-11 so much ? No idea, maybe because I also like its direct descendant, the 68k...
I ordered one of this processor from ebay, it seems to work, and yeah the clock is 10 MHz there, that seems to work, I lowered to 5 and it started to not start correctly.
This processor has a QBUS interface, directly on die, meaning it does not have separated address/data and normal control lines. Some of the control lines are open-collector and some totem-pole. Of course, you can look at the recently captured schematic of the A or G versions, and peek at the verilog of a (quite) accurate replica for better understanding but hooking the processor to our propeller provides, I think, the ultimate level of gratification (if it works) .
It kind of works, I'd say. The address/data bus is inverted (to confuse the unwise )... I send 0xEFFE what I think should be mov r0,r1. Why do I like the pdp-11 so much ? No idea, maybe because I also like its direct descendant, the 68k...
I ordered one of this processor from ebay, it seems to work, and yeah the clock is 10 MHz there, that seems to work, I lowered to 5 and it started to not start correctly.
{{ QBUS to Propeller ============================================= Connection Diagram ============================================= ┌─────────┐ │ │ │ P30├─── Propeller's TX line │ P31├─── Propeller's RX line │ │ │ │ │ │ │ P23├─── DOUT Write │ P22├─── ACLO Assert to reset │ P21├─── DIN Read │ P20├─── WTST Sample on falling edge │ P19├─── SYNC Latch negated address on falling edge │ P18├─── RPLY Assert on Data on Bus for Reads or Writes │ P17├─── INIT Assert to reset peripherals │ P16├─── Clock 5 MHz └─────────┘ Propeller MCU (P8X32A) Memory Map: $1000..$2000 Components: N/A ============================================= }} CON 'Set up the clock mode _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 '5 MHz clock * 16x PLL = 80 MHz system clock speed VAR 'Globally accessible variables long rom[2048] OBJ 'in leiu of Parallax Serial Terminal, FullDuplexSerial is being used to communicate with the terminal serial : "FullDuplexSerial" PUB Main {{ Starts execution of FullDuplexSerialTest1.spin This is a very simple test. It starts the object, waits 1 second, prints two lines to the terminal, waits 1 more second, then shuts down. Set your terminal to a baud rate of 9600 baud to see the output. parameters: none return: none example usage: N/A - executes on startup }} 'start the FullDuplexSerial object serial.Start(31, 30, %0000, 115_200) 'requires 1 cog for operation waitcnt(cnt + (10 * clkfreq)) 'wait 1 second for the serial object to start serial.Str(STRING("Pacito's QBUS Interface Ready.")) 'print a test string serial.Tx($0D) 'print a new line cognew(@qbusm, @rom) serial.Str(STRING("All Done!")) waitcnt(cnt + (1 * clkfreq)) 'wait 1 second for the serial object to finish printing serial.Stop 'Stop the object CON P_DOUT = 23 P_ACLO = 22 P_DIN = 21 P_WTBT = 20 P_SYNC = 19 P_RPLY = 18 P_INIT = 17 P_CLK = 16 DAT org qbusm mov tstartrom, PAR mov CTRA, C_CTRA mov FRQA, C_FRQA ' generate 4 MHz clock ' force RESET, ACLO and INIT low for 40 ms or so mov DIRA, C_DIRA_RESET mov OUTA, #0 ' not really needed... mov tcnt, CNT add tcnt, C_40MS ' de-assert periph-reset and later power fail waitcnt tcnt, C_70MS or OUTA, C_INIT waitcnt tcnt, #1 or OUTA, C_ACLO qbus_wait mov taddr, C_FFFF waitpne C_SYNC, C_SYNC xor taddr, INA ' get normal address and wtst waitpne C_DIO, C_DIO ' wait for DIN or DON being asserted ' if read ' assume read xor OUTA, C_NOP or DIRA, C_FFFF_RPLY ' asserts RPLY waitpeq C_DIN, C_DIN ' wait till DIN is negated andn DIRA, C_RPLY ' negate RPLY andn DIRA, C_FFFF_RPLY ' set as inputs waitpeq C_SYNC, C_SYNC ' wait for SYNC to be negated qbus_e jmp #qbus_wait tcnt long 0 taddr long 0 twdata long 0 trdata long 0 tstartrom long 0 C_NOP long %1110_111_111_111_110 ' MOV R0, R1 '%0001_000_000_000_001 ' MOV R0, R1 C_FFFF long $ffff C_FFFF_RPLY long $ffff | (1 << P_RPLY) C_CTRA long %0_00010_011_00000000_000000_000_010000 C_FRQA long $10000000 ' All inputs except ACLO, INIT, CLK C_DIRA_RESET long (1<<P_CLK)|(1<<P_ACLO)|(1<<P_INIT) C_INIT long 1<<P_INIT C_ACLO long 1<<P_ACLO C_RPLY long 1<<P_RPLY C_SYNC long 1<<P_SYNC C_DIO long (1<<P_DIN)|(1<<P_DOUT) C_DIN long 1<<P_DIN C_DOUT long 1<<P_DOUT C_WTST long 1<<P_WTBT C_40MS long (80_000_000 / 40_000) C_70MS long (80_000_000 / 70_000)
Comments
What a neat bus interface.
Any pictures of this thing ?
Pictures?
Old Computer Museum
Of course there is quite a bit of information about these processors, and HDL models too, and schematics. But mostly is in russian, and not even in electronic readable form . Yeah, scans of type-written and hand-written docs. It took a lot of thinking and a bit of testing, now it really works.
What I mean is:
AD Bus is wired-or and pulled-high and uses negated logic, that's why you see FFFFs.
*RPLY has to be asserted (low) for every access that is not an internal access. It is wired-or, needs a pull-up (I'm using 453 R to a 3.3 V rail . It cannot be grounded like the DTACK on the 68 K !!!, the processor does not come out of reset, nor can it be grounded after reset.
The code I used didn't work as expected, I improved it a bit, now it asserts *RPLY correctly and sends a NOP.
The first access is to an internal register with internal generation of *RPLY to get the high bits of the initial PC, which happens to be zero, then it executes NOPs (what I'm feeding).
Now, let's see if I can convert this into a BK-0010 or similar.
The manual of the KR1801VM1 claims something like 1.7 MIPS: but it takes 11 clocks to fetch the next NOP... meaning less than 0.5 MIPS. A slight over-clock to 6 MHz didn't work, I couldn't catch the assertion of DIN. Maybe just waiting 2 instructions is enough to decide if is a read or write instruction. Read-modify-write instructions exist, they seem to keep *SYNC asserted, and they assert first *DIN and after negation of *DIN *DOUT is asserted. The small code I wrote do not recognized them. The propeller should only provide a video interface, so I will write in parallel to RAM and HUB memory, so I think it would not be necessary to acknowledge such cycles with the propeller. I could dedicate a cog just for that.
The PLAN
2 RAMS for 16 bit bus, 2 FLASH ROMs and the propeller as video controller, it should work, I think
How is your 1801 project going?
I bought some KM1801BM2 parts on ebay. Like yours but different. I started using a Prop but I needed more I/O, so I made a board with a dsPIC33, 2 32Kx8 SRAMs, and 2 HCT563 latches. The PIC runs at 140 MHz at 5V, so there are no interfacing issues. It also generates the 2X CPU clock for the 1801. The PIC uses DMA to modify the battery-backed RAM contents. It also implements a console, GPIO, etc. for the 1801.
I am still trying to understand the behavior of the 1801BM2. I can't find a proper data sheet anywhere, and I don't speak Russian!