• Please review our updated Terms and Rules here

Problems booting PDP-11 through tu58 emulator

The nice thing about the PDP-11 instruction set is that you can generally operate on any register just the same as any other register. The Z80 has a lot of 'special register instructions'.

I cut my teeth on a 6800 then a Z80 then a PDP-11.

Let's progress slowly, but surely.

Try your echo program with bpl and see ifvthat still works first.

Dave
Yeah that's really nice, the fact that you can address I/O as memory is really good too. That's interesting, I dont have any machine with a 6800 yet.

I changed all the beq to bpl and it still works fine. Took me a while to understand why it's a better solution but now I get it.

Code:
addr =176500

.ASECT
.=1000

clr     r0
mov     #addr,r1
LOOP:
        checkRCX:
            TSTB (r1)
            bpl checkRCX
        movb 02(r1),r2
        waitTxReady:
            TSTB 04(r1)
            bpl waitTxReady
        movb r2,06(r1)
        br LOOP
 
It is only testing ONE bit in the status register.

The tstb ensures that we only check the lower byte (and not any bits in the upper byte). Using the sign check instructions (e.g. bpl) makes sure we only test bit 7 - and not any of the other bits.

If this is working, I am going to suggest we try to make the Hello World program fail... Try replacing the tstb and bpl instructions with tst and beq.

After that, I would suggest writing your own TU58 bootstrap using tstb and bpl to see if the initial instruction sequence now works...

Dave
 
It is only testing ONE bit in the status register.

The tstb ensures that we only check the lower byte (and not any bits in the upper byte). Using the sign check instructions (e.g. bpl) makes sure we only test bit 7 - and not any of the other bits.

If this is working, I am going to suggest we try to make the Hello World program fail... Try replacing the tstb and bpl instructions with tst and beq.

After that, I would suggest writing your own TU58 bootstrap using tstb and bpl to see if the initial instruction sequence now works...

Dave
Thank you, I get I now.

I just tried the 'Hello world' test with tst and beq and it worked just fine. I'll try and make a bootstrap myself in next couple of days and report back. Thank you again for your help
 
>>> Thank you again for your help

No problem at all.

Your problem is not giving up its secret is it...

Dave
Indeed...

I checked some more things today:
  • In the tu58 user manual is stated that the second init can be replaced by the boot command instead so just one INIT and one BOOT should be fine, doesnt explain why only one gets sent with that bootloader anyway
  • Checked with an oscilloscope that the data actually got to the card and it does
  • Was able to send the necessary commands with my bootloader but not the data
I'm not an expert and didnt find much online but I was wondering if there was a way to get back to ODT after running some code. I thought that the HALT instruction would do something like that but it doesnt. Can't do anything on the front panel because I dont have one and I'm relying on the M8192 for initialization of the system.
If I was able to get to ODT I could at least check that the data is loaded into memory correctly.

This is my bootstrap so far, I tried using a routine for the wait part but that didnt work for some reason.
Code:
; Configuration parameters

tuAddr=176500
codeStart=1000

.ASECT
.=codeStart

mov #tuAddr,r0
wait2:
    tstb 04(r0)
    bpl wait2
mov #04,6(r0)                ; First init
wait3:
    tstb 04(r0)
    bpl wait3
mov #10,6(r0)                ; Boot 
wait4:
    tstb 04(r0)
    bpl wait4
mov #00,6(r0)

mov #00,r1                   ; Counter/mem pointer
dataLoop:
    checkRCX:
        TSTB (r0)
        bpl checkRCX
    movb 02(r0),(r1)
    inc r1
    cmp #1000,r1
    bne dataLoop
jmp #00
 
A HALT 'should' return you back to ODT - however, it does depend on the CPU configuration for what to do when the CPU executes a HALT. Or am I confusing HALT with RESET?

Let's have a look at the link/switch configuration of your CPU...

The other thing is a few errors or misunderstandings in your bootstrap code.

After the BOOT command, the PDP should send the drive number to boot from (0). EDIT: I see you are sending this, just not waiting for it to complete.

I think then the TU58 sends a CONT status followed by 512 (decimal) bytes of data.

You can use the instruction "movb 2(r0),(r1)+".

The + increments r1 after the transfer has completed (thus not requiring the inc r1 instruction).

You can also preload (say) r2 with #1000 (512 bytes) and use a SOB instruction to count. It makes the code much more compact...

Dave
 
Ignore most of what I said above about the TU58 boot protocol.

I have just had a look at the source code for the M9312 DD bootstrap (see https://ak6dn.github.io/PDP-11/M9312/).

If you need to call a subroutine, you need to initialise the stack pointer (r6) to point to some valid RAM. Don't forget that the stack moves downwards in memory...

The following protocol is used:

<BREAK>
<INIT> = OCTAL(04).
<BOOT> = OCTAL(10).
UNIT = OCTAL(00).

Wait for each of the bytes above to be transmitted (except for <BREAK> that requires a timeout).

Read and store each of the DECIMAL(512) bytes sent from the TU58 into address 0 upwards (waiting for the receiver to be ready before each byte is processed).

Jump to location 0.

Dave
 
Ignore most of what I said above about the TU58 boot protocol.

I have just had a look at the source code for the M9312 DD bootstrap (see https://ak6dn.github.io/PDP-11/M9312/).

If you need to call a subroutine, you need to initialise the stack pointer (r6) to point to some valid RAM. Don't forget that the stack moves downwards in memory...

The following protocol is used:

<BREAK>
<INIT> = OCTAL(04).
<BOOT> = OCTAL(10).
UNIT = OCTAL(00).

Wait for each of the bytes above to be transmitted (except for <BREAK> that requires a timeout).

Read and store each of the DECIMAL(512) bytes sent from the TU58 into address 0 upwards (waiting for the receiver to be ready before each byte is processed).

Jump to location 0.

Dave
Thank you for the suggestions I modified the code accordingly. I had to change a jumper on the CPU board but now the halt goes to ODT.
So I added an HALT instruction after receiving the 512 bytes and indeed it seems to work and load the received bytes into memory. The problem is that there are some discrepancies between file that was sent and what is stored in memory, I need to understand if that is because of memory problems or transmission problems, I would guess the latter since pdp11gui's memory test doesnt signal any error.

Sometimes a problem occurs where the third bit is flipped. For example a 000000 sometimes becomes a 000004 or a 000007 becomes a 000003. But then I tried doing it twice and errors were in the exact same spot so I dont know what to think.
 
Excellent.

We are always moving forwards, so we are going in the right direction!

Can you share your latest code with me so I can take a look?

Dave
 
I just tried changing the address and the wrong words move around... Most likely a memory problem

Or maybe not, why would the code work just fine if there were memory issues?
 
Last edited:
Excellent.

We are always moving forwards, so we are going in the right direction!

Can you share your latest code with me so I can take a look?

Dave
Code:
; Configuration parameters

tuAddr=176500
codeStart=1000

.ASECT
.=codeStart

mov #tuAddr,r0
wait2:
    tstb 04(r0)
    bpl wait2
mov #04,6(r0)                ; First init
wait3:
    tstb 04(r0)
    bpl wait3
mov #10,6(r0)
wait4:
    tstb 04(r0)
    bpl wait4
mov #00,6(r0)

mov #00,r1                   ; mem pointer
mov #1000,r2                 ; Loop counter
dataLoop:
    checkRCX:
        TSTB (r0)
        bpl checkRCX
    movb 02(r0),(r1)+
    sob r2,dataLoop
halt
jmp #00
 
Interesting...

I can't see anything particularly wrong with your code.

Just out of interest, how is the serial port configured (e.g. baud rate, number of data bits, number of stop bits, parity enable/disable/odd/even)?

Dave
 
Interesting...

I can't see anything particularly wrong with your code.

Just out of interest, how is the serial port configured (e.g. baud rate, number of data bits, number of stop bits, parity enable/disable/odd/even)?

Dave
The configuration on the tu58em is 4800 the rest is standard so I think it's 8n1.

And this is the M8028 configuration (should be up to date)

# Jumper setup (default configuration)

Address ==> Octal: 176500
Interrupt vector ==> 300
Common speed operation baud rate ==> 4800
Transmitter baud rate in slip speed operation or receiver and transmitter baud rate in maintenance mode ==> 9600
Break generation ==> Enabled
Parity ==> Disabled
Parity mode ==> Even
Data bits ==> 8
Programmable baud rate ==> disabled
Operation mode ==> Common speed operation
Halt mode ==> Enabled
Reboot on halt/error ==> Disabled
20ma loop RECEIVER ACTIVE ==> Enabled
20ma loop RECEIVER PASSIVE ==> Disabled
20ma loop TRANSMITTER ACTIVE ==> Enabled
20ma loop TRANSMITTER PASSIVE ==> Disabled
Enable 20ma loop operation ==> Enabled
Error in receive buffer ==> Enabled
 
Ok a little update, I dont think it's a transmission error. I modified the program to load the received data in two parts of memory at once and the memory content in the two locations were different. The strange beahaviour is that if I load the data both in 01000 and 02000 the results are the same but if I do that in 01000 and 02500 they are different...

Code:
[...]
mov #00,r1                   ; mem pointer
mov #2500,r4
mov #1000,r2                 ; Loop counter
dataLoop:
    checkRCX:
        TSTB (r0)
        bpl checkRCX
    movb 02(r0),r3
    movb r3,(r1)+
    movb r3,(r4)+
    sob r2,dataLoop
[...]
 
That is interesting.

Have you attempted to download the CPU and memory diagnostics using pdp11gui (since you mention it) and give them a run?

I can't see anything wrong with the M8028 configuration.

Dave
 
That is interesting.

Have you attempted to download the CPU and memory diagnostics using pdp11gui (since you mention it) and give them a run?

I can't see anything wrong with the M8028 configuration.

Dave
I'll give that a try tomorrow. Are they inside of pdp11gui or do I need to find diagnostics online?
 
Back
Top