初学者裸机 pdp11 控制台输出
Beginner bare-metal pdp11 console output
我正在尝试了解使用 pdp-11 的基本知识(大学时学习了指令集,想重温一下),想从 TTO/DL11 中射出一些字符作为第一个程序(除非第一个程序太复杂了)。
运行 在 simh 上。显示开发人员有
TTO, address=17777564-17777567, vector=64
阅读文档 tx 缓冲区位于偏移量 566。在 Whosebug 和其他一些页面上看到其他代码 is/might 是高位地址中的 mmu space 说 177566(八进制)可能会放你在那里,因为寄存器是 16 位,而不是 show dev 暗示的 22 位。
mov [=11=]x32,r1
movb r1, @77566
mov 77566,r2
mov [=11=]x30,r3
movb r3,(r2)
mov [=11=]x31,r3
movb r3,(r2)
halt
什么也没有出来。
load test.bin
go
可以使用 set console telnet=4444 和 telnet 到那个,没有变化。毫无疑问,我无法解决超过 16 位的问题,但不太确定去哪里解决这个问题。
基本上我想,除非需要大量代码(数千行 asm)才能让一些字符从控制台中出来,否则我想从那里开始 "see" 一些东西,然后以此为基础。因此,如果我很接近但不是很接近,或者如果这不是最好的外围设备,去哪里,它们都在那个较高的地址 space.
我正在使用 gnu 工具
pdp11-aout-as --version
GNU assembler (GNU Binutils) 2.26.20160125
Copyright (C) 2015 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `pdp11-aout'.
所以语法有点goofy/non-standard。至少现在有几个版本的 binutils 支持 pdp11,希望也能利用它。 simh 的二进制文件格式并不难理解,单步执行它符合我想要的指令并提供 gnu 汇编程序。
在apt-got v3.8-1 版本的simh pdp11 和github got 4.0 版本上都试过了,结果一样。使用 pdp11 simulator/executable.
sim> show config
PDP-11 simulator configuration
CPU, 11/73, NOCIS, idle disabled, autoconfiguration enabled, 256KB
SYSTEM
RHA, address=17776700-17776753, vector=254
RHB, disabled
CLK, 60Hz, address=17777546-17777547, vector=100
PCLK, disabled
PTR, address=17777550-17777553, vector=70, not attached
PTP, address=17777554-17777557, vector=74, not attached
TTI, address=17777560-17777563, vector=60, 7b
TTO, address=17777564-17777567, vector=64, 7p
CR, address=17777160-17777167, vector=230, 285 cards per minute, translation 029, not attached, CR11, auto EOF, unknown format
LPT, address=17777514-17777517, vector=200, not attached
DLI, disabled
DLO, disabled
...
编辑
#define TKS (*((volatile unsigned *)0177560))
#define TKB (*((volatile unsigned *)0177562))
#define TPS (*((volatile unsigned *)0177564))
#define TPB (*((volatile unsigned *)0177566))
void punch ( unsigned x )
{
while((TPS&0x80)==0) continue;
TPB=x;
}
void notmain ( void )
{
//unsigned ra;
//for(ra=0x30;ra<0x37;ra++) punch(ra);
punch(0x30);
while((TPS&0x80)==0) continue;
return;
}
这使得
Disassembly of section .text:
00000000 <start.o>:
0: 15c6 2000 mov 000, sp
4: 09f7 001a jsr pc, 22 <_punch+0x18>
...
0000000a <_punch>:
a: 1166 mov r5, -(sp)
c: 1185 mov sp, r5
e: 17c0 ff74 mov *7564, r0
12: 45c0 ff7f bic $-201, r0
16: 03fb beq e <_punch+0x4>
18: 1d5f 0004 ff76 mov 4(r5), *7566
1e: 1585 mov (sp)+, r5
20: 0087 rts pc
22: 1166 mov r5, -(sp)
24: 1185 mov sp, r5
26: 17c0 ff74 mov *7564, r0
2a: 45c0 ff7f bic $-201, r0
2e: 03fb beq 26 <_punch+0x1c>
30: 15df 0030 ff76 mov , *7566
36: 17c0 ff74 mov *7564, r0
3a: 45c0 ff7f bic $-201, r0
3e: 03fb beq 36 <_punch+0x2c>
40: 1585 mov (sp)+, r5
42: 0087 rts pc
两个问题,一个是我没等到忙。在 init/reset 没关系,它不忙。我认为踢球者是我在它吐出角色之前停了下来。当我有循环时,它会吐出大部分字符。如果我发出一个字符并停止它不会出来,但如果我在(notmain() 中的最后一件事)之后等待忙碌变为零,那么该字符就会出现。
如果我改成这个
#define TKS (*((volatile unsigned *)0177560))
#define TKB (*((volatile unsigned *)0177562))
#define TPS (*((volatile unsigned *)0177564))
#define TPB (*((volatile unsigned *)0177566))
void punch ( unsigned x )
{
TPB=x;
while((TPS&0x80)==0) continue;
}
void notmain ( void )
{
unsigned ra;
for(ra=0x30;ra<0x37;ra++) punch(ra);
return;
}
它工作得很好...谢谢你让我开始。
手册中的注释:
In addition to the word length constraint on basic memory addressing
space, the uppermost 4K words of address space is always reserved for
UNIBUS 1/0 device registers. In a basic PDP-11/40 memory configura·
tion (without Management) all address references to the uppermost 4K
words of 16-bit address space (170000-177777) are converted to full
18-bit reference5 with bits 17 and 16 always set to 1. Thus, a 16·bit
reference to the 1/0 device register at address 173224 is automatically
internally converted to a full 18-bit reference to the register at address
773224. Accordingly, the basic PDP-11/40 configuration can directly
address up to 28K words of true memory, and 4K words of UNIBUS 1/0
device registers.
所以那个答案就在那里我没找对地方。
编辑 2:
在汇编中,为了实现从 tty 发送字符的目标,使用 gnu 汇编程序语法(* 代替 @ 和 $ 代替 #)
movb [=19=]x32,*77566
pwait:
tstb *77564
bpl pwait
halt
我认为问题是没有正确使用 DL11。你不能随便给它一个角色。您必须测试控制寄存器中的 "ready" 标志。然后,当它准备好发送字符。此外,您无法可靠地读回数据寄存器中的值。然后你将该字符用作内存指针(那里肯定会有内存,但写入它可能不是你想要的)。
您可能也有兴趣查看 Retrocomputing Stack Exchange 站点。我可能不是唯一一个有 PDP-11 经验的人,但我可能会在这里。
我正在尝试了解使用 pdp-11 的基本知识(大学时学习了指令集,想重温一下),想从 TTO/DL11 中射出一些字符作为第一个程序(除非第一个程序太复杂了)。
运行 在 simh 上。显示开发人员有
TTO, address=17777564-17777567, vector=64
阅读文档 tx 缓冲区位于偏移量 566。在 Whosebug 和其他一些页面上看到其他代码 is/might 是高位地址中的 mmu space 说 177566(八进制)可能会放你在那里,因为寄存器是 16 位,而不是 show dev 暗示的 22 位。
mov [=11=]x32,r1
movb r1, @77566
mov 77566,r2
mov [=11=]x30,r3
movb r3,(r2)
mov [=11=]x31,r3
movb r3,(r2)
halt
什么也没有出来。
load test.bin
go
可以使用 set console telnet=4444 和 telnet 到那个,没有变化。毫无疑问,我无法解决超过 16 位的问题,但不太确定去哪里解决这个问题。
基本上我想,除非需要大量代码(数千行 asm)才能让一些字符从控制台中出来,否则我想从那里开始 "see" 一些东西,然后以此为基础。因此,如果我很接近但不是很接近,或者如果这不是最好的外围设备,去哪里,它们都在那个较高的地址 space.
我正在使用 gnu 工具
pdp11-aout-as --version
GNU assembler (GNU Binutils) 2.26.20160125
Copyright (C) 2015 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `pdp11-aout'.
所以语法有点goofy/non-standard。至少现在有几个版本的 binutils 支持 pdp11,希望也能利用它。 simh 的二进制文件格式并不难理解,单步执行它符合我想要的指令并提供 gnu 汇编程序。
在apt-got v3.8-1 版本的simh pdp11 和github got 4.0 版本上都试过了,结果一样。使用 pdp11 simulator/executable.
sim> show config
PDP-11 simulator configuration
CPU, 11/73, NOCIS, idle disabled, autoconfiguration enabled, 256KB
SYSTEM
RHA, address=17776700-17776753, vector=254
RHB, disabled
CLK, 60Hz, address=17777546-17777547, vector=100
PCLK, disabled
PTR, address=17777550-17777553, vector=70, not attached
PTP, address=17777554-17777557, vector=74, not attached
TTI, address=17777560-17777563, vector=60, 7b
TTO, address=17777564-17777567, vector=64, 7p
CR, address=17777160-17777167, vector=230, 285 cards per minute, translation 029, not attached, CR11, auto EOF, unknown format
LPT, address=17777514-17777517, vector=200, not attached
DLI, disabled
DLO, disabled
...
编辑
#define TKS (*((volatile unsigned *)0177560))
#define TKB (*((volatile unsigned *)0177562))
#define TPS (*((volatile unsigned *)0177564))
#define TPB (*((volatile unsigned *)0177566))
void punch ( unsigned x )
{
while((TPS&0x80)==0) continue;
TPB=x;
}
void notmain ( void )
{
//unsigned ra;
//for(ra=0x30;ra<0x37;ra++) punch(ra);
punch(0x30);
while((TPS&0x80)==0) continue;
return;
}
这使得
Disassembly of section .text:
00000000 <start.o>:
0: 15c6 2000 mov 000, sp
4: 09f7 001a jsr pc, 22 <_punch+0x18>
...
0000000a <_punch>:
a: 1166 mov r5, -(sp)
c: 1185 mov sp, r5
e: 17c0 ff74 mov *7564, r0
12: 45c0 ff7f bic $-201, r0
16: 03fb beq e <_punch+0x4>
18: 1d5f 0004 ff76 mov 4(r5), *7566
1e: 1585 mov (sp)+, r5
20: 0087 rts pc
22: 1166 mov r5, -(sp)
24: 1185 mov sp, r5
26: 17c0 ff74 mov *7564, r0
2a: 45c0 ff7f bic $-201, r0
2e: 03fb beq 26 <_punch+0x1c>
30: 15df 0030 ff76 mov , *7566
36: 17c0 ff74 mov *7564, r0
3a: 45c0 ff7f bic $-201, r0
3e: 03fb beq 36 <_punch+0x2c>
40: 1585 mov (sp)+, r5
42: 0087 rts pc
两个问题,一个是我没等到忙。在 init/reset 没关系,它不忙。我认为踢球者是我在它吐出角色之前停了下来。当我有循环时,它会吐出大部分字符。如果我发出一个字符并停止它不会出来,但如果我在(notmain() 中的最后一件事)之后等待忙碌变为零,那么该字符就会出现。
如果我改成这个
#define TKS (*((volatile unsigned *)0177560))
#define TKB (*((volatile unsigned *)0177562))
#define TPS (*((volatile unsigned *)0177564))
#define TPB (*((volatile unsigned *)0177566))
void punch ( unsigned x )
{
TPB=x;
while((TPS&0x80)==0) continue;
}
void notmain ( void )
{
unsigned ra;
for(ra=0x30;ra<0x37;ra++) punch(ra);
return;
}
它工作得很好...谢谢你让我开始。
手册中的注释:
In addition to the word length constraint on basic memory addressing
space, the uppermost 4K words of address space is always reserved for
UNIBUS 1/0 device registers. In a basic PDP-11/40 memory configura·
tion (without Management) all address references to the uppermost 4K
words of 16-bit address space (170000-177777) are converted to full
18-bit reference5 with bits 17 and 16 always set to 1. Thus, a 16·bit
reference to the 1/0 device register at address 173224 is automatically
internally converted to a full 18-bit reference to the register at address
773224. Accordingly, the basic PDP-11/40 configuration can directly
address up to 28K words of true memory, and 4K words of UNIBUS 1/0
device registers.
所以那个答案就在那里我没找对地方。
编辑 2:
在汇编中,为了实现从 tty 发送字符的目标,使用 gnu 汇编程序语法(* 代替 @ 和 $ 代替 #)
movb [=19=]x32,*77566
pwait:
tstb *77564
bpl pwait
halt
我认为问题是没有正确使用 DL11。你不能随便给它一个角色。您必须测试控制寄存器中的 "ready" 标志。然后,当它准备好发送字符。此外,您无法可靠地读回数据寄存器中的值。然后你将该字符用作内存指针(那里肯定会有内存,但写入它可能不是你想要的)。
您可能也有兴趣查看 Retrocomputing Stack Exchange 站点。我可能不是唯一一个有 PDP-11 经验的人,但我可能会在这里。