跳转至内容

Aros/平台/68k 支持/开发者/库

来自 Wikibooks,开放世界中的开放书籍
用于 Aros wikibook 的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题
Aros 用户应用程序
Aros 用户 DOS Shell
Aros/用户/AmigaLegacy
Aros 开发文档
Aros 开发者文档
从 AmigaOS/SDL 移植软件
适用于 Zune 初学者
Zune .MUI 类
适用于 SDL 初学者
Aros 开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros Intel AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
摩托罗拉 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm Raspberry Pi 支持
PPC Power Architecture
其他
Aros 公共许可证

库/应用程序“自动”打开在编译时可用的库。如果存在问题,最简单的解决方法是将 graphics.library 的 AROS 版本降级到 39(在 graphics.conf 文件中),以用于“frankenrom”。另一种选择:在层中某处定义全局 GfxBase 变量 - 这应该可以阻止“自动”工作,因此您需要手动打开图形。

  • autoconfig(正在开发中,快速 RAM 扩展已经可以使用,自动引导 ROM 支持待开发。对于 UAE 硬盘测试非常重要)
  • expansion.library 当前设置为 noautolib。这是因为非 Amiga 系统不需要扩展(自动配置)还是需要以其他方式初始化?
  • utility.library 数学函数是一段糟糕的代码。双返回值(D0 和 D1) - 必须保留 A0 和 A1。糟糕。太糟糕了。看起来这里需要进行大量 ASM 工作才能用于 m68k。您是否检查过 arch/.unmaintained/m68k-native/utility?只需要动态选择 68020+ 和 68000/010 版本。

摆脱 rom 目录,因为不同的架构可能会在 rom 中放置或多或少的模块。某些架构甚至可以配置将哪些模块放入 rom,具体取决于可用多少非易失性存储空间。拥有 rom/ 目录使 m68k 端口更容易,仅仅因为只需要支持 librom.a 最小 AROS C 库,而不是完整的 AROS C。在 ABI V1 中,librom.a 不见了。arosstdc.library 中有一个库,所有模块都可以使用它。它将作为第一个模块之一进行初始化。因此,IO 函数也移动到基于磁盘的模块 arosstdcdos.library。您如何处理 ctype.h 系列函数?我希望看到仅限 LANG=C 的精简选项。

我认为应该为 TaggedOpenLibrary() 库 ID 号定义定义。(但是在哪里?它应该只由 rom 代码使用)。在 m68k-amiga 中这将非常有用,因为它使 rom 文件略小(目前这里和那里有很多库名称字符串)。UtilityBase = TaggedOpenLibrary(7); 看起来很丑陋..

workbench/libs/gallium:-Wall 清理。正在比较不同的枚举类型,编译器不满意。我查看了每种类型的枚举列表,它们看起来非常不同。在主 Mesa 存储库(workbench/libs/mesa/)的主干中,代码也是如此。

可ROM化

[编辑 | 编辑源代码]

对 genmodule 工具的以下更改将更好地支持可ROM化模块

我还有另一种解决方案,也用于 ABI V1 分支。唯一假设的是,我们在其中执行代码的库的 LIBBASE 为 A6(在 i386 上,它在 *(%ebx) 中)。

* LIBBASESIZE:
   - Would have space for an additional BPTR for the library's SegList
   - Space for an additional N struct Library * slots after
     the end of LIBBASETYPE, where N is the number of auto-opened libraries.
   - These slots would hold the opened library handles for the
     auto-opened libraries. But I don't like this change but won't veto it. 
     It can always be reverted when proper support for global variables is 
     implemented in ROM linking and the ROM bootstrap code. 
     To me write-only media and write-able global variables sounds mutually
     exclusive. Well, actually *read*-only media and write-able global 
     variables sounds even more mutually exclusive ;-)
     Please outline how it would work for an EEPROM or alike. 
     EEPROM Very easy. In your linker script you declare .bss and .data sections 
     in RAM, whereas .rodata and .text are in ROM. At startup, the Kickstart copy 
     the .data section stored somewhere in ROM into proper location in RAM and 
     zeroes the .bss section. And at the same time we could replace the ROMtag 
     scanner with a list of modules that is generated at link time; for example 
     using the AROS symbolsets.  I thought "binary compatibility" goes both ways, 
     original rom modules work with Aros rom modules and vice versa.. 
     IMHO this is the worst solution. Chip RAM is too valuable for that. 
     Either modules are going to be proper fully rommable or _everything_ can be
     relocated to RAM by tiny relocator and expansion RAM configuration code in
     ROM. Anyway, both solutions are bad ideas for basic A500/A1200 modes which will
     kill my interest instantly.

* set_open_libraries():
  - Would take LIBBASE as a parameter
  - Would OpenLibary() to the post-LIBBASETYPE Library *slots

* set_close_libraries()
  - Would take LIBBASE as a parameter
  - Would CloseLibary() the post-LIBBASETYPE Library *slots

* An additional header would be '-include libname_libraries.h', that
  would be autogenerated, and have lines like:

  #define GM_SEGLIST_SLOT (BPTR(((APTR *)(((IPTR)LIBBASE)+LIBBASESIZE))[0])
  #define UtilityBase     ((APTR *)(((IPTR)LIBBASE)+LIBBASESIZE))[1]
  #define GfxBase         ((APTR *)(((IPTR)LIBBASE)+LIBBASESIZE))[2]

  I tried to get rid of these
  '#define libbase' hacks. This code assumes that LIBBASE is available 
  in all functions that call a function of an auto-opened library. 
  This assumption is false. If you see no other way out please only 
  implement when compiling the kobjs on m68k. I mean, genmodule could 
  supported two types of libraries (or just make a second genrommodule 
  for the sake of it). Whatever assumption is made, it would only apply 
  to code that is explicitly written/modified against that assumption...
...

对我来说,在干净的代码中没有这些 #define 技巧的位置,它们改变了一些代码的语义(struct IntuitionBase *,指向 amiga 共享库中函数的函数指针,...)。它与 ABI V1 中 C 库的实现方式不兼容。库中基于栈的函数的存根代码需要全局 libbase,而 #define 不会被注意到。ABI V1 中的 C 库问题仍然存在。也许可以在 arch/m68k-native 树中重新引入静态 C 链接库,允许我拥有在我看来是正确的且干净的 m68k 分支。

约束

(1) 不想将 BSS 放入(宝贵的)芯片 RAM (2) 一些机器有快速 RAM,一些机器没有,因此我无法在*编译时*确定将 .BSS 链接到哪里。(3) 由于 (1) 和 (2),.text 不能对 BSS 中的任何内容进行绝对引用 - 即 FooBase、BarBase 等。

“#define 技巧”允许我满足所有约束条件,并且我计划不将它们添加到源代码本身 - 仅限 genmodule,并且仅在它针对只读 ROM 时。

所有这些的最终结果是 genmodule 将以两种(目标相关的)模式运行:.bss 模式用于磁盘可加载模块,以及 ROM 模块的 .rela.bss 模式。嗯... .rela.bss.... (/me 认为)

此外,我将能够*删除*代码库中已经存在的大量“#define 技巧”,因为只有 genmodule 需要关心将库句柄放置在何处。

替代方案。为 ROM 创建一个自定义链接脚本,将所有 kobjs 与链接到芯片 RAM 的第一页的 BSS 部分链接在一起。然后,引导代码需要将初始化值复制到此页面。在以后的阶段,在具有 MMU 的机器上,将 ROM 和 BSS 部分重新映射到快速 RAM。

在 _start.c 文件中,您将拥有以下内容

const IPTR UtilityBase_offset = LIBBASESIZE+1*sizeof(APTR);
const IPTR GfxBase_offset = LIBBASESIZE+2*sizeof(APTR);

然后代码应该执行

#include <proto/utility_rel.h>
#include <proto/gfx_rel.h>
in case of
#include <proto/utility.h>
#include <proto/gfx.h>

gfx_rel.h 将 #include <inline/gfx_rel.h>

在 inline/gfx_rel.h 中,您将拥有以下内容

static inline void RectFill(...)
{
    extern const IPTR GfxBase_offset;
    struct GfxBase *GfxBase = (struct GfxBase *)((char *)(GET_A6)+GfxBase_offset);
    AROS_LC5NR(void, RectFill, ...)
}

此最后一段代码无需内联也可以用作静态链接库中的存根。链接库将被称为 libgfx_rel.a 等。

如果您查看分支 branches/ABI_V1/trunk-genmodule_pob/AROS/tools/genmodule 中的存储库,您应该在那里找到大部分基础结构。只有 GET_A6 被称为 GET_LIBBASE,并且在 aros/$cpu/cpu.h 中实现为内联 asm(目前仅限 i386)。问题是,它无法在不破坏 i386/x86_64 中的 bin 兼容性的情况下引入主干,因为现在没有为该目的分配寄存器。

这会将自动打开的库移动到 LibBase,移出 BSS,从而使构建可 ROM 化库的过程变得更容易。无需对现有库进行任何代码更改,也不需要更改任何 ABI。

我认为您需要将 LIBBASE 作为参数显式传递给函数。您仍然可以执行此操作并将其放入 A6。唯一的怪癖是 .conf 文件中未列出的回调,例如,它希望获取库打开的 libbases 的句柄。这是如何处理的?或者这些回调应该在 .conf 中指定?ReadStruct/WriteStruct 是很好的例子。它们的回调例程(在 Hook 结构中)可能希望与 LibBase 类和 DOSBase 进行通信。

基本上,当前使用 libbases 的所有代码也应该提供使用 _offset 变量的替代代码。因此,在 ABI V1 分支中,现在为每个库生成 libxxx.a 和 libxxx_rel.a 静态链接库。前者将为库中的函数提供使用全局 libbase 的存根,后者使用 _offset 的存根。如果您使用后者 lib 链接代码但未定义 _offset 变量,则会出现链接器错误。m68k ROM 模块需要链接 -lxxx_rel(或使用libs=xxx_rel)。

对于钩子,我认为我们需要提供支持,以便在钩子数据中保存 A6/LIBBASE,并通过一个特殊的支持 HOOK 函数来恢复它。不知道这是否可行,以及是否会影响可以传递的参数数量。

对于我查看的钩子(datatypes.library),LibBase 已经在 Hook 的 h_Data 中了。所以我只是添加了

 struct DataTypesBase *DataTypesBase = hook->h_Data;

在钩子的开头手动添加,一切正常。

(我有一个 datatypes.library 的补丁,它使它可 ROM 化,使用“#define hack”,将 LibBase 显式地放在 LIBBASETYPE 中,并在库的初始化时显式地打开它们,并按上述方式修改钩子例程。

可以重新设计 BHFormat,使其在从 CLI 运行时不打开 muimaster.library 吗?系统可以提示插入不同的磁盘。可以包含 CLI 版本的格式化工具。可以重新设计 System/Format 以消除一些依赖项,或者至少与基本库一起工作(我认为 iffparse 或 datatypes 不应该需要格式化,但它们是 muimaster.library 的子依赖项)。如何重新设计 BHFormat 以使其具有 ./configure 选项,以便仅使用 gadtools.library 而不是 MUI Master?无论如何,我必须在 ROM 中拥有 gadtools 用于 AmigaOS 3.x。

我应该努力将哪些库制作成可 ROM 化的?

C/Shell - 是的!Shell 是一个不错的选择,因为它在原始的 Kickstart 中,并且在没有启动序列的情况下启动,它允许你执行操作而无需访问硬盘,这是一个不错的候选对象。

Libs/arosc.library - 我想,由于 arosc.library 可能被各种程序和系统组件使用,因此将其放在 ROM 中以能够从 shell 启动各种应用程序会很有趣。

Libs/datatypes.library - 我认为这需要磁盘上的 datatypes,所以我不确定将其放在 ROM 中是否有很大帮助。拥有它很好,因为需要它的程序不会加载失败,但是由于不会加载任何数据类型,所以我认为没有必要。

Libs/muimaster.library - MUI 使用外部类,我不知道它是否允许在没有外部类的情况下加载应用程序。如果可以,那么它可能有用,但如果不行,则跳过它。有很多依赖项。

Libs/asl.library - 使用更新的 Shell 和自动完成功能,这可能会非常方便……

Libs/diskfont.library - 优先级不高。如果你想从磁盘加载字体,你也可以将 diskfont.library 存储在同一磁盘上。

Libs/gadtools.library - 这对于一些基本应用程序可能有用。我不记得它是否在默认的 Kickstart 中存在,如果不存在,那么它的优先级就不那么高了。KS 3.0 似乎需要它在 ROM 中。以及 If、EndIf 和一些其他命令。

System/Format - 如果你有一个能够访问可写介质的系统,那么你将能够访问 ROM 外部的文件。拥有它是一件好事,但恕我直言,“格式化”不是优先事项。

可 ROM 化 shell 命令的基本基础设施。不过,似乎存在对齐问题,因为有时它可以正常工作(将“shellcommands”添加到 KRSRC),有时会挂起。有人可以审查我需要对 workbench/c/shellcommands/Shell 进行的“纯”更改吗?测试构建的 shell,它似乎可以执行简单的任务。

起初,发现用 .bss 和 .data 自由的 Pure 风格编程有点困难,因为我来自一个有 MMU 的操作系统(Linux),在那里共享的可执行页面很容易,并且 -fPIC 编译器实际上可以工作。但现在我真的很喜欢 Pure 风格,对于 AROS,我们应该更多地推广这种风格和优势。这里有一些 Pure 最好的部分,仅供参考

所有 Pure 程序/库都可以

  • 将其 .text 段标记为只读
  • 链接到 ROM 中
  • 可以有多个相同对象的执行,例如 Shell[1]、Shell[2]、Shell[3] 都共享相同的 .text 段

由于上述原因,对于低内存系统,Pure 绝对是一个胜利。在理想的世界里,编译器不支持 BSS 或数据段。所有这些 MMU 技巧等等都只是为了程序员的懒惰而提供的变通方法。不要让我开始谈论垃圾回收;-)是的,用 Pure 编码工作量稍微大一些,但我认为这是值得的。我完全不同意。在我看来,编译器和/或构建基础设施应该使纯程序能够使用全局变量、自动打开库等成为可能。那么,这将需要一个“-fPIC Data”风格,对吗?其中 .text 段可以链接到任何位置,并且有一个“任务全局”(要么是 struct Task 的成员,要么是寄存器)指向任务的“私有” .bss/.data 区域。这实际上类似于 Amiga BCPL 的支持,并且 tc_GlobVec 指针将只是要使用的字段,因为它本质上提供了相同的服务。但我不想成为为所有支持的 AROS 架构实现编译器更改以实现此目的的人。我更倾向于使用一个寄存器来存储全局指针。它也将是用于 libbase 的相同寄存器,因为它具有类似的功能。在 i386 ABI V1 中,我为此使用了 %ebx;它是一个栈指针 *(%ebx) 是存储基地址的地方。对于 m68k,将使用 A6。

-fPIC 在大多数架构下的 ELF 中希望使用“全局偏移表”和位置无关代码(这会占用另一个寄存器)。要制作“-fPIC-data” - 我不确定如何轻松地做到这一点。在 adtools 的 gcc 中有一个 --baserel 选项,但我对它的了解仅限于它存在。

另外,我认为在 ABI V1 分支中,基地址是为了使这成为可能。请尽量限制你转换为这种 Pure 方式的代码。

链接器可以合并 ROM 中相同的字符串吗?我注意到 ROM 中充满了 dos.library、intuition.library 等字符串?(以及各种调试字符串)。这难道不是 exec.library 的 TaggedOpenLibrary() 的目的吗?它接受一堆幻数并为该数字执行相应的 OpenLibrary("blah.library")。这将解决重复字符串的问题。

仅在真正需要向后兼容性时才手动打开库。不要为了好玩而这样做。主要目标是使程序纯净。这意味着 - 它现在可以使用 C:Resident 驻留。该命令非常小,我认为这是一个好主意。它与程序大小无关。问题是存储库中的代码经常被程序员作为开始新项目的起点。这样,不良习惯就会传播开来。过去,我花费了大量时间来消除这些手动打开库的操作,这些操作通常充满了错误,因为异常子句不在常见代码路径中。每次看到这段代码被重新添加,我都会感到非常痛苦。在 ABI V1 中,我确实考虑实现一个编译开关,允许创建无需执行任何操作即可包含的程序。

现在支持自动配置引导 ROM,UAE uaehf.device 正确初始化,但在初始化 dos.library 时崩溃。AROS dos.library 似乎是正常的自动初始化库,但官方 ROM 的做法有所不同。好吧,实际上发生的事情是引导块返回 D0(错误代码)和 A0(指向 Resident rt_Init 结构的指针),并且引导块加载程序应该使用传入的 rt_Init 调用 MakeLibrary()。(假设引导块返回 D0==0,那么它也返回了 A0 中的 Resident InitTable)。

所有自动引导硬盘的引导 ROM 代码在引导阶段结束时执行以下操作

d0 = FindResident("dos.library");
move.l d0,a0
move.l RT_INIT(a0),a0
jsr (a0)

aros dos rt_init 包含初始化表,而不是代码 -> 崩溃。dos rt_init 代码“手动”初始化 dos.library。InitResident() 未用于此。(dos 很奇怪,即使在 BCPL 消失之后)。首先要做的是为 genmodule 添加一个选项,以便它能够生成不依赖于 RTF_AUTOINIT 标志的库。其余部分非常简单。它不会损害其他端口。我为资源实现了反向操作(选项 resautoinit),它用于 battclock.resource。这很容易。可以使用现有的 genmodule 代码来处理资源。

如何在不破坏非 m68k 构建的情况下执行此操作?如何禁用自动初始化并将初始化代码指针放入 rt_init 中?硬盘引导代码在自动引导 ROM 中包含最终的 jsr 或 jmp。它无法被修补。

软盘引导代码确实在 A0 中返回 dos resident。这意味着它可以在不触碰 dos 的情况下修复。

但没有任何东西可以阻止软盘引导块也包含 jsr(a0),它不会返回,它只是这样设计以允许 strap 在启动 dos 之前释放临时资源(引导块缓冲区、trackdisk 等)。

请注意,用 AROS dos.library 替换 AOS dos.library 不会起作用,因为它在与文件系统、启动进程(如 Shell/CLI 东西)以及可能的其他东西交互方面存在很大的不兼容性。

MorphOS dos.library 基于 AROS,但与 AOS 的兼容性要高得多。你使用它会更有运气。也就是说……除非你想使用其他 AROS 组件(如使用 FSA 数据包 API 的文件系统),它们将不再起作用。

目前最新的问题是 NewAddTask() 简单地错误地获取或读取启动参数(启动 PC 等)并由于错误的初始 PC 而崩溃。

初始 ROM 是否可以主要作为基于磁盘的模块的加载程序?我很乐意这样做,但 afs.handler 依赖于 Intuition,Intuition 依赖于 Graphics、Layers,哎呀……这可能可以更改,以便 afs.handler 仅在处理程序想要显示请求者时 Intuition 已加载的情况下打开并使用 Intuition。它之前已经检查了第一个 Intuition 屏幕是否已打开。

workbench/libs/partition 是否应该在 rom/partition 中?是的,整个源代码树可能需要清理,并且之前在这个开发列表中讨论过这个问题。它看起来像是你想要的一个组件,以便能够从 m68k 上的硬盘启动。它不是必需的,这是自动引导硬盘驱动程序的任务。(读取分区表、添加分区、在 RDB 中添加可能的文件系统)。当然,我们不需要用未来的 ROM 内置驱动程序来模拟这一点。在现有的端口中,它被 strap 模块用于挂载分区,因此它需要成为内核的一部分(或者更准确地说,由引导加载程序加载)。

启动优先级已存储在分区表中。仅在 RDB 中存储。它不会以任何方式存储在 CD、USB 闪存等上。传统上,未分区可移动介质(如 CD 和软盘)的优先级取决于其所在驱动器的分配优先级。可引导 USB 闪存盘在 RDB 中使用 SFS,因此具有与内部硬盘相同的优先级。MBR 分区不存储优先级,但无论如何也不建议将其用于可引导卷还有其他原因(例如,无法选择自定义设备名称)。

所有现有的图形 HIDD 似乎都包含不可 ROM 化的 attrbases 表。(可写数据和 bss)。我们实际上在 m68k-amiga ROM 上有一个 BSS(讨厌)。如果您只需要处理 BSS,我们就可以了。关于性能损失的说明/警告。如果在可 ROM 化代码中使用 Hidd 存根,则现在不会生成错误/警告,但当它们正在使用时,性能会急剧下降。它们不会只初始化一次 methodID,而是在每次使用这些存根时都会调用 oop.library/GetMethodID()。这不可能很快……;) 明白了。我需要找到一种(干净的)方法来为类中所有存根的区域分配内存(),以用于存储它们的 MID。(仅供其他人了解,此减速仅会影响 m68k-amiga)。刚刚提交了对 Intuition、Hyperlayers 和 Graphics 的更改,消除了它们需要 .BSS 和 .DATA 段的需要。这对于将 AROS 放入 UAE 的两种 ROM 分割方法是必需的。

是否有某种框架用于编译和链接 ROM 内置驻留命令?(至少添加驻留和朋友似乎已实现。关于纯二进制文件,请查看 C:Dir,一些我从 MorphOS 反向移植的命令是纯的。简而言之,它们不使用启动代码和任何全局变量。这是事实的)。

大多数 KS2.0+ 可引导磁盘需要内置驻留命令,我猜引导 shell 也应该是一种驻留程序。workbench/c/shellcommands 中的程序可以集成到 shell 二进制文件中。查看那里的宏。它们在 shcommands_notembedded.h 中定义。还有一个文件,shcommands_embedded.h。我不知道使用此功能需要什么。看起来很久没人尝试过了。

查看 AROS/workbench/c/shellcommands/ 下,您会找到使用 AROS/compiler/include/aros/shcommands_notembedded.h 中定义的一组宏的程序。

这些宏公开了一个接口,应在 shcommands_embedded.h 中重新实现该接口,以便生成可以嵌入 ROM 的程序。

截至目前,这些宏让您可以毫不费力地生成可重入代码,除非您想按原样将生成的的这些文件嵌入 ROM 并对其使用 LoadSeg()(这可能是一个可行的选择,具体取决于您的需求),否则请编写这些宏的嵌入版本。

这些宏公开了一个接口,应在 shcommands_embedded.h 中重新实现该接口,以便生成可以嵌入 ROM 的程序。DOS/AddSegment() 也将非常有用。必须将 FindSegment() 挂接到 LDDaemon 以完成图片……) 我将确保在 LDDaemon 中将 FindSegment() 的优先级设置得*低于*磁盘上的可执行文件,以便我们不会锁定 ROM 版本。

Amiga IDE 支持也包含在我的“尽快实施”列表中。我是否需要在现有的 ata.device 中添加 #ifdef,还是需要做其他事情?(它似乎过于特定于 PC 硬件,而不是完全模块化的)。我会为 Amiga 创建一个单独的模块。ata.device 是一个“敏感”;) 主题 - 它已经被尝试改进的人多次破坏,并且在更改后似乎总是不够的测试人员可用;)

大多数这些故障都是由于需要而发生的,因为旧代码严重受限/设计不佳 - 我个人认为它现在运行得非常好,因为几乎没有关于它无法运行的报告 - 如果有的话。唯一(恕我直言)仍然需要做的事情是更正初始探测代码,以便在找到带有连接设备的 pci 控制器的情况下,不要添加尚未与 ata 控制器关联的旧端口。

我不确定 amiga 的内部 ide 实现有多么不同 - 但我想可以将不同的部分(探测、直接编程芯片组)移动到单独的文件中,并且仅在您的特定构建中包含这些部分..例如 dma_amiga.c

我也不知道 elbox 快速 ata 等控制器的工作原理,但如果 AROS 能够支持它们也很好(我还有 2 个,以及 2 个中介 PCI 总线板)。

我检查了 1.3 和 3.1 的 NKD 自动文档,在这两种情况下,这些函数都被描述为返回 BOOL。请注意,AROS 旨在与 3.1 兼容,而不是与 1.3 兼容。如果需要此类更改,您可能需要将 dos 库完全分离到 arch 树中。

我还认为此更改可能会破坏现有端口的二进制兼容性(BOOL 为 2 字节 AFK,而 LONG 为 4 字节)。1.3 和 3.1 的 NDK 自动文档,在这两种情况下,这些函数都被描述为返回 BOOL。请注意,AROS 旨在与 3.1 兼容,而不是与 1.3 兼容。如果需要此类更改,您可能需要将 dos 库完全分离到 arch 树中。

我该如何处理 dos.conf?Lock/Open(以及其他)不再是别名。(dos.conf 未提交)我认为最简单的方法是在 rom/dos/ 中为别名函数创建存根文件,然后您可以检查不包含别名的 dos.conf。

DevCD NDK 2.0 和 3.1 dos_protos.h:LONG Examine( BPTR lock, struct FileInfoBlock *fileInfoBlock ); LONG ExNext( BPTR lock, struct FileInfoBlock *fileInfoBlock ); LONG Info( BPTR lock, struct InfoData *parameterBlock ); SAS-C include/clib/dos_protos.h 中相同。事实上,BOOL 和 ULONG 返回类型在二进制上是兼容的。无论如何,该值都以 CPU 寄存器返回,因此它占据了整个寄存器。区别仅在于它是如何评估的。例如,在 m68k 上,WORD 将使用 tst.w 进行评估,ULONG 将使用 tst.l 进行评估。仅 NDK 3.1 定义保证寄存器的高半部分不包含垃圾。

WB3.0 C:Assign 似乎执行以下操作:如果 (AssignLock(whatever, NULL) != DOSTRUE) 则打印“无法取消 > ”。失败。不幸的是,AssignLock 返回类型为 BOOL。将其替换为 LONG(例如)并且 Assign 正确工作..似乎两者都已损坏,因为 BOOL 应被 typedef 为“short”,并且根据原始 AOS 包含文件,AssignLock() 确实应该是 LONG。啊,AssignLock 返回 LONG,但 AssignLate、AssignPath 和 AssignAdd 返回 BOOL。(在更高版本中修复的错误?)

测试 KS 3.1 CreateNewProc():CreateNewProc() 的 NP_Arguments 标记不会添加“\n”。Input() 确实返回 NP_Arguments 参数流。RunCommand():相同的结果。不添加“\n”,Input()+FGetC() 返回命令参数。存在细微差别:(可能是由于不同的输入句柄)CreateNewProc() FGetC() 在参数流结束时返回 EOF。RunCommand() FGetC() 等待更多字符(在 CLI 中按回车键返回一个换行符)SystemTagList() 测试结果:它似乎执行所有操作(或者它是 shell 执行的?)命令和参数之间的所有空格(空格和制表符)都被吞并。尾随空格不会被吞并。如果“\n”已存在于参数字符串中 = 参数字符串的结尾。如果参数字符串中没有“\n”= 在末尾添加一个。CreateNewProc() 的 NP_Arguments 标记不会添加“\n”。Input() 确实返回 NP_Arguments 参数流。此外,如果没有在参数字符串的末尾添加“\n”,RunCommand() FGets() 不会返回,直到按下回车键。

C:Run 执行此操作(也许其他操作也是?)

olddir = CurrentDir(toclone);
cis = Open("", FMF_READ);
CurrentDir(olddir);

这在 dos 数据包模式下无法工作。CurrentDir() 获取并返回文件锁,Open 返回文件句柄。

复制控制台句柄(并且仅复制控制台句柄)的 Dos 数据包方法是

old = SetConsoleTask(((struct FileHandle*)BADDR(toclone))->fh_Type);
cis = Open("*", MODE_OLDFILE);
SetConsoleTask(old);

我们需要复制控制台句柄的特殊函数吗?或者如何解决这种不兼容性?(至少在每个人都切换到 dos 数据包之前)目前 AROS C:Run 挂起,WB2.x/3.x 版本工作。

dos.library/MatchNext 在完成时并不总是返回 ERROR_NO_MORE_ENTRIES。(“退出 for(;;) 循环 -> MakeResult”不会设置 ERROR_NO_MORE_ENTRIES)它使 WB3.x:C/Dir 困惑。如果目录条目数为奇数,则“(null)”出现在最右列。没关系。这不是 MatchNext 错误(它工作正常,我又一次失明了)它是 WB3.x:C/Dir 错误使用(?) VFPrintf (RawDoFmt),期望 %s 带有 NULL 指针(而不是指向空字符串的指针)在输出中不产生任何内容。KS 3.1 已确认,如果字符串指针为 NULL,则 RawDoFmt 完全忽略 %s。它也不会尝试访问地址零(已通过 UAE 内存观察点确认)

jsr        %a6@(76 * -6)    /* Exec/DoIO() */

已经多次注意到这一点。请使用命名常量而不是数字和注释;这样,编译器可以检查偏移量是否正确,并且人们知道您正在调用哪个函数。首先我必须说:gcc 680x0 汇编语法很糟糕。(至少对于 1980 年代开始使用汇编语言为 Amiga 编写代码的人来说..)。对此表示抱歉,但我不知道(或不想知道,见上文)如何创建有效的常量。这是 Jason 的问题:D

GCC 68k 也自动理解 Motorola 68k 语法。您可以编写 jsr -(76*6)(a6) 最佳情况是将 68k 汇编代码作为单独的文件编写。GCC 汇编检测用于小型 .s 或大型 .S,如果您的汇编文件具有大型 .S(例如文件名为 myasm.S),则 C 定义预处理器也可以在汇编代码中使用。

#define offset -76

#ifdef ...

jsr offset(a6)

#endif

Open() FMF_x 参数在 m68k-amiga 下存在问题。(在 rom 模块和 aros 应用程序内部的许多地方使用)。它破坏了 SnoopDos,以及可能所有其他接管 dos/Open() 向量 的程序。

a) 完全删除它们?(它们实际上真的被使用了吗?)。选择这个。据我所知,新模式从未在 Open() Autodoc 中记录过。它们在文档中也有记录,并且也经常使用。我的意思是“使用”是指“实际上执行与在数据包处理程序中仅转换回 ACTION_FIND* 或在 afs.handler 的原始非 dos 数据包版本中大多数标志被忽略不同的操作”。不介意拥有某种带有新的更好/扩展模式标志的 NewOpen(),但使用原始 Open() 以及完全不同且不兼容的模式参数是不对的。

b) 添加一些包装器,在调用 Open() 之前将 FMF_ 内容转换为原始 MODE_xxxx 参数。(而不是将它们包装在 Open() 内部,这就是它在 dos 数据包模式下当前的工作方式)

我的建议……

1) dos.library 应该没有扩展,以便与 AmigaOS 3.1 达到二进制级别兼容(我多年前实现的该扩展也应该在二进制上兼容,但我没有考虑到会 SetFunction() 一些 dos.library 函数并接管它们的程序。

2) 可以实现 arosdos.library,或一些 hidd,或其他一些实现扩展的东西。

方案如下

    dos.library -----> packet wrapper ---\
                                          \
> aros dos handler
                                          /
    arosdos.library ---------------------/

每个 aros dos 处理程序应该有一个数据包处理程序包装器。如果 dos 处理程序仅基于数据包(来自 AmigaOS 的端口),那么一个特定于 aros 的数据包.handler 将充当它的包装器,我认为现在就是这样。

现在删除这些标志的直接结果是,我们将失去 arosc.library(或 Staf 的修改中如何称呼它)的功能,因为它们是在 dos.library 级别以系统范围的方式实现的,例如文件追加。管道文件将不再工作(但它无论如何都需要重新设计,因为它非常过时并且实际上运行不佳)。

想法是做到“面向未来”,而不是固守旧的Amigados数据包处理器。但是,如果没有一个明确的“新DOS”项目来推动发展,那么唯一可行的选择是:要么保持现状,尝试找到与AROS方式和AmigaOS方式兼容的方法,要么直接采用AmigaOS方式。

这是正在使用的映射

  #define FMF_MODE_OLDFILE   (FMF_AMIGADOS | FMF_WRITE | FMF_READ)
  #define FMF_MODE_READWRITE (FMF_MODE_OLDFILE | FMF_CREATE)
  #define FMF_MODE_NEWFILE   (FMF_MODE_READWRITE | FMF_LOCK | FMF_CLEAR)

如您所见,MODE_NEWFILE也会在文件不存在时创建文件,并在文件存在时清空它,因此您不应在那种情况下使用它。对于所有情况,请改用MODE_OLDFILE。

如何处理从栈中分配FileInfoBlock结构体的AROS代码?这不能保证所需的LONG对齐(BPTR和m68k-amiga)。用AllocDosObject()替换它们?但这又增加了另一个内存分配测试和内存释放调用,我认为它使简单的代码变得太复杂和丑陋了。

新的宏从栈中分配+隐藏对齐技巧?(最好是也适用于其他DOS结构(如InfoData)的宏)。

像(来自c/dir.c)这样的代码

UBYTE _fib[sizeof(struct FileInfoBlock) + 3];
struct FileInfoBlock *fib = (APTR) (((IPTR) _fib + 3) & ~3);

恕我直言,太丑了..

恕我直言,只需使用AllocDosObject(),因为分配。这真的是GCC的问题吗?对于很多东西,从int和long都有对齐选项 - 而且FileInfoBlock以LONG开头(-malign-int)。

BCPL_Action

[编辑 | 编辑源代码]

无论如何,2.0之前引入的所有DOS结构都应该使用AllocVec()分配,因为这是BCPL的方式。

尝试启动Workbench 1.3 ADF。我能够加载'Shell-Seg' Shell DOS进程,但它正在使用(几乎不可能用谷歌搜索到的)dos.library *BCPL*接口。

我认为提供从1.3 BCPL接口到库接口的“thunk”并非不可能。这只是一件小事而已。

如果……我们能找到文档……

这是一个转储,我在其中用调试调用替换了BCPL Action例程(存储在寄存器A5中)的存根。即

BCPL_Action 600 (0x77f6c, 0x1f007, 0x1f018, 0x1f033)
             D0  D1       D2       D3       D4

D0 = BCPL routine to call
D1..D4 arguments

[LoadSeg] Loading 'L:Shell-Seg'...
Try Function 00f93158
[ELF Loader] Not an ELF object
[InternalLoadSeg] FAILED loading 0001c8ee as an ELF object.
Try Function 00f92720
read_block(file=116974, buffer=00069e6a, size=4, func[0]=00059bb2)
  buf=00069e6a, subsize = 4 (of 4)
HUNK_HEADER:
    Hunk count: 1
    First hunk: 0
    Last hunk: 0
    Hunk 0 size: 0x001ba8 bytes in ANY memory
HUNK_CODE(0): Length: 0x001ba8 bytes in ANY memory
HUNK_END
[InternalLoadSeg] Succeeded loading 0001c8ee as an AOS object.
[LoadSeg] segs = 0001c905
pr_GlobVec = 0007c660
BCPL_Action 600 (0x77f6c, 0x1f007, 0x1f018, 0x1f033)
BCPL_Action 608 (0x0, 0x1f007, 0x1f018, 0x1f033)
BCPL_Action 696 (0x303782bc, 0x3ef0b3, 0x1f018, 0x1f033)
BCPL_Action 700 (0x11215381, 0xf, 0x1f018, 0x1f033)
BCPL_Action 700 (0x14, 0xd6847a03, 0x11215381, 0x1f033)
BCPL_Action 700 (0x48e72022, 0xffffffff, 0x11215381, 0x1f033)
BCPL_Action 712 (0x0, 0xffffffff, 0x11215381, 0x1f033)
BCPL_Action 700 (0x48, 0xffffffff, 0x11215381, 0x1f033)
BCPL_Action 700 (0xc, 0xd6847a03, 0x11215381, 0x1f033)
BCPL_Action 708 (0x0, 0xffffffff, 0x44854e04, 0xffffffff)
BCPL_Action 708 (0xe1898283, 0xffffffff, 0x44854e04, 0xffffffff)
BCPL_Action 708 (0x2, 0xffffffff, 0x44854e04, 0xffffffff)
BCPL_Action 708 (0x303782bd, 0xffffffff, 0x44854e04, 0xffffffff)
BCPL_Action 708 (0x0, 0xffffffff, 0x44854e04, 0xffffffff)
...

aminet.net上的'BCPL4Amiga.lha'档案是*宝藏库*

  • 如何调用BCPL例程
  • BCPL栈帧如何工作(eww!!!)
  • D0/A1是什么(它不是我所想的!)
  • 几乎所有pr_GlobVec AmigaDOS偏移量都做了什么!

我认为我可以从这里创建一个BCPL思维库,没问题!

如果我能添加此支持,它将使AROS m68k能够运行所有Amiga 1.0-1.3 BCPL CLI命令!

在我等待Toni完成图形驱动程序时,这将给我一些事情可做。

这个可能也有帮助。

实际上,在这种情况下,我相信Amiga Guru Book的印刷英文版本将是最好的信息来源。

嗯,实际上C=团队试图从AOS中删除所有BCPL内容,并明确地用C等效项替换了所有相关的CLI命令,这些命令通过DOSBase而不是GlobVec进行 - 如果我理解正确的话,在V37中只有4个BCPL处理程序在L:中保留。所有剩余的GlobVec遗留代码都在dos.library之上重新实现 - 因此也避免了保留跳转表本地副本的选项,该跳转表具有针对跳转向量的修改条目。

拥有一个全局(或本地)的非基于库的向量作为跳转表,其中包含公共和私有数据条目、BSS以及程序不同模块的覆盖加载能力,嗯,它可以被认为是两者兼而有之:非常灵活或完全损坏;-)Guru Book“BCPL和全局向量”的“第16章”以一句引言开头:“如果你理解它,它就过时了。”

恕我直言,拥有所有基于C的标准CLI命令和来自V37及更高版本的FileSystem驱动程序比旧的BCPL内容更有用。

AOS 1.0-1.3代码/工具不会为“Frankenrom”提供任何缺失的功能。

当然,其他非OS BCPL代码的兼容层可能有用 - 但再说一次,它可能只与特定硬件驱动程序相关,而这些驱动程序在UAE或大多数Amiga型号上都不可用。

基本上只是对于任何不了解V37且需要GlobVec而不是-1的内容。这值得额外的开销吗?

MorphOS如何(好)实现BCPL遗留代码?或者最多只能获得GlobVec -1?

我同意,但我未公开的目标之一是让AROS M68K能够运行Amiga Forever附带的所有Workbench ADF。

此外,许多“杂志磁盘”使用L:Shell-Seg。我现在将致力于仅支持来自AOS 1.3的L:Shell-Sig,因为这将为AROS m68k作为ROM替换带来最大优势。

BCPL thunk代码目前似乎没有占用太多代码空间,我将其放在arch/m68k-amiga/dos/中,因此它不会影响任何其他端口。

不要启用32位快速RAM板,由于一些未知原因,如果启用它,引导会挂起。这现在已修复。NIL处理程序中正常的指针到BCPL转换错误,仅偶然起作用。(找到这个花了很长时间..)我想BCPL指针错误将是最常见的错误,因为没有其他端口需要它们。也许可以添加一些BCPL指针调试检查宏?例如,在转换为BCPL指针时检查指针的最低两位是否为零,并检查BCPL指针是否指向预期的内存范围?(如果转换了两次或丢失,它们几乎总是指向不存在的RAM)

除了原始的Commodore BCPL WB 1.x程序和相关的软件(如处理程序)之外,没有其他程序。(除了Commodore之外,还有人拥有BCPL编译器吗?)它很可能没有阻止非BCPL程序使用BCPL功能。问题是找到它们(可能是非常旧的PD磁盘系列?)

应该记住,BPTR在(所有?)其他端口上并不真正存在..

它是第一个通过diskfont.library/newfontcontensts.c打开的文件。不知道具体是哪一个,文件名是20。

+    ((BPTR*)BADDR(hunktab[last]))[0] = BNULL;

当分配hunktab时,这应该已经被清零了。但它似乎没有清零,或者后来被覆盖了。

我添加了一些额外的调试消息,例如KrnUnregisterModules,这里有一个可能有所帮助的调试日志,您可以从地址中看出它是在64位机器上

[InternalLoadSeg] Succeeded loading 0000000040725b80 as an ELF object.
FixFonts Loading 20
        Hunk count: 1
allocmem 0000000040725bb0 24
        First hunk: 0
        Last hunk: 0
        Hunk 0 size: 0x001ff4 bytes in ANY memoryallocmem 000000004091d3b0 8192
@000000004091d3b4
HUNK_CODE(0): Length: 0x001ff4 bytes in ANY memory
HUNK_RELOC32:
        Hunk #0:
HUNK_END
freemem 0000000040725bb0 24
[InternalLoadSeg] Succeeded loading 0000000040728240 as an AOS object.
[KRN] KrnUnregisterModule(0x0x4091d3b4)
[KRN] Next segment pointer 0x0x4091d3b4
[KRN] Next segment pointer 0x0x754eff7000
[KRN] Trap signal 11, SysBase 0x406455b8, KernelBase 0x40646600
[KRN] Process 0x4072d590 (FixFonts)
    RSP=000000004094cf30  RBP=000000004094cf50  RIP=00000000404aac0c
    RAX=000000754eff7000  RBX=00000000405202a8  RCX=00007f0e99a91770 RDX=0000000000000000
    RDI=00007f0e99d36860  RSI=0000000000000000  RFLAGS=0000000000010246
    R8 =00007f0e9a140700  R9 =00000000404dc320  R10=0000000000000000 R11=0000000000000246
    R12=000000004071f9f0  R13=000000004071f910  R14=000000004072d6f8 R15=0000000000000000

许多AROS程序都有这个

AROS_UFH3(__startup static ULONG, _start,
      AROS_UFHA(char *, argstr, A0),
      AROS_UFHA(ULONG, argsize, D0),
      AROS_UFHA(struct ExecBase *, sysbase, A6))
{
<stuff>
}

A6在m68k-amiga端口中不包含也不可能包含SysBase。它包含BCPL魔法(实际上大多数地址寄存器都包含未公开的BCPL内容),并且无法在运行时检测正常程序和BCPL程序之间的区别。(有些程序可以先进行正常的C启动,然后稍后执行BCPL内容..)是否有任何端口*没有*用户空间可以访问的全局SysBase?在m68k上,在程序启动和库初始化时获取SysBase的唯一方法是通过绝对地址$4吗?我认为应该有一种方法可以将SysBase传递给新程序或库,而无需使用绝对地址。后者在托管平台上尤其困难。作为最后的手段,我们可以在loadseg期间再次执行此操作,以便符号名称SysBase通过加载程序获得正确的值。不过,我更喜欢当前的解决方案。

初始化sysbase的loadseg方式?没什么。如果您查看InternalLoadSeg_ELF,它已经处理了这种情况:rom/dos/internalloadseg_elf.c:第388-406行。因此,只有(a)HUNK架构(b)没有全局SysBase需要将SysBase传递给它们。我认为AROS下没有任何这样的架构。可执行文件的错误剥离将使其无法使用。这与我们计划将来切换到ELF可执行文件而不是可重定位对象的事实相结合。我们仍然需要文件中的重定位信息。

Intuition库

[编辑 | 编辑源代码]

不幸的是,Intuition和层存在其他m68k构建问题,导致gfx HIDD测试无法进行。OpenScreen()内部机制无法工作。它已经部分修复,但至少还有一个问题仍然存在。

更重要的问题是我似乎无法使鼠标工作(软件或硬件)。IntuitionBase->ActiveMonitor始终为NULL,intuition/misc.c仅在它不为NULL时设置鼠标。调用了MySetPointerPos(),当我移动鼠标时鼠标坐标会发生变化。看起来图形子系统认为鼠标与其他主机窗口共享。aoHidd_Gfx_IsWindowed设置为FALSE。

如果旧的modeid不可用,openworkbench()会选择640x200分辨率,但仍然使用原始保存的显示尺寸。

这会导致在某些RTG模式已被保存(例如1024x768)但我们现在禁用(或移除)RTG板的情况下出现视觉问题(以及巨大的芯片RAM使用量),结果是在普通640x200分辨率下出现巨大的Superbitmap原生芯片组屏幕。这非常烦人。如果模式丢失,它应该回退到原始标称尺寸和深度。

也许引导菜单屏幕选择和openworkbench屏幕模式选择应该合并?两者都需要类似的特殊代码来选择最佳模式,尤其是在使用Amiga硬件(PAL/NTSC/RTG)时

Amiga端口使用以下“默认”模式

  • 640x256(PAL)或x512(隔行扫描)
  • 640x200(NTSC)或x400(隔行扫描)

以上模式使用两个或四个平面。是的,引导菜单没问题,但问题是初始屏幕(Shell)的默认分辨率和aros引导图像分辨率。在NTSC机器上为640x200,在PAL机器上为640x256。(但如果芯片组支持PAL/NTSC更改,则会将PAL和NTSC模式都添加到模式数据库中 = ECS Agnus或更新版本)AROS m68k还添加了早期Picasso96驱动程序“RTG”支持,这意味着分辨率为640x480。并非所有RTG Picasso96驱动程序都支持类似PAL或NTSC的模式分辨率。只有gfx驱动程序知道哪个是最佳“默认”模式,除非在通用代码中添加一些丑陋的检查(例如当前引导屏幕分辨率选择所做的那样)。

最后,初始屏幕必须仅为2平面,原因是带宽和芯片内存使用量的原因,但AROS引导图像为16色,并假定像素为正方形(=需要隔行扫描)

其他受支持的平台可以使用更简单的解决方案,因为它们都支持至少256色屏幕,并且没有巨大的VRAM/Blitter带宽瓶颈。

仅在打开引导屏幕图像时才需要隔行扫描和4平面(以获得正确的纵横比)在OCS/ECS芯片组上,使用4平面高分辨率引导菜单或初始Shell速度太慢。

也许gfx hidd中的一些函数可以被询问类似“给我x的modeid+深度的数组”,其中x = 引导菜单、引导图像或初始Shell屏幕?(请记住,如果为平面模式,则需要深度)

640x480x8(如果为RTG模式,则可能不支持640x400或640x512)

Intuition/monitorclass.c/SetPointerPos()在HIDD_Gfx_SetCursorPos()坐标中包含热点偏移量,如果鼠标精灵分辨率与屏幕分辨率不同,则在Amiga芯片组上不起作用。(最常见的情况是低分辨率精灵和高分辨率屏幕)

热点应该以精灵分辨率像素为单位,而不是以屏幕分辨率像素为单位。

例如,如果热点为-3,屏幕为高分辨率,精灵为低分辨率:精灵向左移动-3个高分辨率像素,但它应该为-6个高分辨率像素或-3个低分辨率像素。(HIDD可以轻松自动转换,SetCursorShape已经包含热点偏移量数据)

如果删除SetPointerPos()“考虑HotSpot”并由HIDD处理热点偏移量,则amiga-m68k原生鼠标定位将在所有分辨率下正确工作。

HIDD坐标是精灵的左上角。图形驱动程序不知道热点(除了托管的,但它只用于输入报告)。精灵坐标应该以精灵的分辨率提供。只是以前没有单独的精灵分辨率。

精灵形状分辨率 != 精灵定位分辨率。精灵形状独立于定位(至少在 AGA 上,ECS 和更旧的版本有限制)请记住,AGA 机器上的精灵具有独立于屏幕分辨率的定位分辨率。这意味着即使在 LoRes 屏幕上,精灵也以 HiRes(甚至 SuperHiRes)分辨率移动。不过,必须设置一个标志才能使这种情况发生。默认设置是在 LoRes 和 HiRes 屏幕上使用 LoRes 精灵,在 SuperHighRes 屏幕上使用 HiRes 精灵。不过,分辨率是针对所有精灵全局设置的。

通常,精灵具有低分辨率像素,但具有高分辨率水平分辨率。

-> 图形驱动程序需要知道热点偏移量。(或者它需要知道鼠标指针分辨率,以便可以添加正确的偏移量)。精灵中没有“热点”。它只是一个精灵。热点是 Intuition 的东西。这是否意味着精灵位置应该以位图的分辨率指定?好吧,在“定位分辨率”中。猜测定位分辨率 == 屏幕分辨率。因此,Intuition 可以调整偏移量。事实上,移动鼠标指针实际上是 MoveSprite()。我仅为方便起见添加了 monitorclass 方法。添加这些方法到 monitorclass 中是为了从 ChangeExtSpriteA() 中移除热点规范。以前,热点规范是那里的私有扩展。请参阅 SVN 历史记录。

除非 Intuition 知道精灵分辨率,否则它无法做到,这就是问题所在。精灵位置始终以屏幕分辨率表示,这不是问题。(硬件可能不支持,但这不是 Intuition 的问题)

是的,这是一种非常倒退的做法(移动鼠标而不是移动热点),但正确的修复需要更新 Intuition 以使其知道鼠标分辨率,至少我不想触碰那些东西。此快速修复至少使 Amiga 本地模式可用(据我所知,没有其他人使用硬件光标,因此这不会影响其他平台)

以下是视觉解释,因为我仍然不确定我之前的解释是否过于混乱。

Lets say we have following lores sprite image (standard mode in AOS)

00X00000
00XX0000
00XXX000
00XXXX00

It has hotspot offset of (2,0)

Now lets see how it looks on hires screen at (0,0)

(without hotspot offset, wrong positioning)
S000XX0000000000
0000XXXX00000000
0000XXXXXX000000
0000XXXXXXXX0000

(with 2,0 _hires_ pixel hotspot offset, still wrong positioning. This is what happened previously)

00S0XX0000000000
0000XXXX00000000
0000XXXXXX000000
0000XXXXXXXX0000

(with 2,0 _lores_ pixel hotspot offset, or 4 pixel hires, finally we have correct hotspot positioning)
0000SX0000000000
0000XXXX00000000
0000XXXXXX000000
0000XXXXXXXX0000

(S = hotspot)

图标库

[编辑 | 编辑源代码]

在:workbench/libs/icon/./diskobjio.c 中,sdd_Stream 是指向文件的 BPTR、指向缓冲区的指针,还是两者兼而有之?sdd_Stream 来自哪里?这些东西来自编译器/arossupport 中的大端结构读取/写入支持。流的类型可以是任何类型,具体取决于挂钩函数希望它是什么类型(传递给 ReadStruct() 等函数)。

icon.library 使用 dostreamhook()(在 support.c 中),它需要流为 BPTR(文件句柄)。support.c/ReadIcon_WB() 执行初始 ReadStruct(),将“文件”参数(BPTR)作为流值传递。

只有当图标的 Gadget->MutalExclude 设置了 (1 << 31) 时,图标调整大小才会生效,因此所有旧图标都应继续逐像素显示。

ilbmtoicon 现在接受 --dpi x:y 参数(默认为 72:72,旧的 Macintosh 桌面出版分辨率),允许您指定图标的默认分辨率(以每英寸点数表示)。

这被转换为 Amiga 显示分辨率刻度,以便 icon.library 逻辑不需要进行任何单位转换。

图标缩放有点粗糙,但对于 C 代码来说速度很快。(如果有人为 CyberGfx/ScalePixelArray 实现 HIDD 挂钩,可能会更快)。

位图图标使用 BitMapScale() 进行缩放,ARGB 图标使用 Bresenham 重采样器进行缩放(在向上缩放时需要扩展到平均像素),因为 BitMapScale() 似乎会覆盖 ARGB 位图的“A”部分。

正如我在提交消息中提到的,我需要向 IconControl 添加一个额外的标记,以帮助 Wanderer 控制图标缩放。

我们还应该在 Prefs/ScreenMode 中添加一个覆盖,以允许通过 MonitorSpec ratioh/ratiov 参数调整屏幕 DPI/DPC。据我了解,显示宽度/高度比率定义(或影响)像素宽度/高度比率。例如,如果单个像素默认是正方形,则以与物理提供的分辨率不同的分辨率运行显示可能会改变该纵横比。

根据我在 AOS 3.9 上的测试,无论屏幕模式如何(即使 1280x200 NTSC 的 ratioh=16,ratiov=16),MonitorSpec 的 ratioh/ratiov 都不变(即始终为 RATIO_UNITY)。

因此,我相信这些参数不反映像素大小,而是显示器本身的大小。

至于 DRI 分辨率,我相信我发布的方程很好地近似了 AOS 的行为,并允许扩展到其他显示格式(宽屏、纵向模式等)

MonitorSpec ratioh 和 ratiov 是定点分数,由 RATIO_FIXEDPART 和 RATIO_UNITY 宏定义。

#define RATIO_FIXEDPART  4
#define RATIO_UNITY      (1 << RATIO_FIXEDPART)

它们是什么的比率仍然有点神秘。也许是“此显示器”与 1084S 的比率?

这有点关系。MonitorSpec 的 ratioh 和 ratiov 在 AOS 上始终显示为 RATIO_UNITY (1.0),因此我将让 AROS 这样计算 ratioh 和 ratiov

#define C_1084_HEIGHT    198 /* mm */
#define C_1084_WIDTH    264 /* mm */

if (GetMonitorEDIDSize(..,&MonitorEDIDWidthMM, &MonitorEDIDHeightMM)) {
  ms->ratiow = ((MonitorEDIDWidthMM)<<RATIO_FIXEDPART)/264;
  ms->ratioh = ((MonitorEDIDHeightMM)<<RATIO_FIXEDPART)/198;
} else {
  ms->ratiow = RATIO_UNITY;
  ms->ratioh = RATIO_UNITY;
}

符合 VESA EDID 规范的显示器将根据 EDID 信息设置 MonitorEDIDWidthMM 和 MonitorEDIDHeightMM,其他所有显示器将假定为 4:3 13 英寸显示器。

屏幕的 DrawInfo 'Resolution' 参数(以“刻度”为单位)将计算为

res.x = 44*320/screen_pixel_width
res.y = 44*256/screen_pixel_height

(对于 Amiga NTSC 屏幕,res.y 会略有不同,对于 200 行,值为 56 而不是 52,但这应该不是什么大问题)

有了这些信息,应用程序就可以计算显示器的 DPI,如下所示:

#define C_1084_WIDTH_FIN  0xa6  /* 10.4 " * 16 in hex */
#define C_1084_HEIGHT_FIN 0x7c  /*  7.8 " * 16 in hex */

DPI.x = (screen_pixel_width << (RATIO_FIXEDPART * 2)) / (ms->ratioh * C_1084_WIDTH_FIN);
DPI.y = (screen_pixel_height << (RATIO_FIXEDPART * 2)) / (ms->ratiov * C_1084_HEIGHT_FIN);

…然后,将有足够的信息根据屏幕的 DPI 和纵横比动态调整图标大小。

MonitorSpec:ratioh、ratiov - 1084S 的大小与当前显示器之间的比率(较大的分数表示较大的显示器,较小的分数表示较小的显示器)

DrawInfo Resolution:由于这与鼠标刻度有关,因此此计算与整体 DPI 成反比,而不是与显示器中的像素数量成反比,这样更有意义。

因此,DrawInfo.Resolution 将计算为

  res.x = (1280 * 11 * ratioh / pixel_width)  >> RATIO_FIXEDPART
  res.y = (1024 * 11 * ratiov / pixel_height) >> RATIO_FIXEDPART

屏幕 DPI 可以直接从 DrawInfo Resolution 计算得出,如下所示:

#define C_1084_WIDTH_CIN  104  /* 10.4 " in centi-inches */
#define C_1084_HEIGHT_CIN  78  /*  7.8 " in centi-inches */

  dpi.x = (11 * 1280 * 10) / C_1084_WIDTH_FIN  / res.x
  dpi.y = (11 * 1024 * 10) / C_1084_HEIGHT_FIN / res.y

屏幕 DPC(每厘米点数)计算如下:

#define C_1084_WIDTH_MM  264  /* 10.4 " in mm */
#define C_1084_HEIGHT_MM  198  /*  7.8 " in mm */

  dpc.x = 11 * 1280 * 10 / C_1084_WIDTH_MM  / res.x
  dpc.y = 11 * 1024 * 10 / C_1084_HEIGHT_MM / res.y

据我了解,显示宽度/高度比率定义(或影响)像素宽度/高度比率。例如,如果单个像素默认是正方形,则以与物理提供的分辨率不同的分辨率运行显示可能会改变该纵横比。

我认为,在解释图形/显示器中的类似值时,ILBM BMHD 块中的 xAspect/yAspect 字段是相关的。

参见:http://amigan.1emu.net/reg/ILBM.txt

“纵横比的典型值为宽度:高度 = 10:11(Amiga 320 x 200 显示器)和 1:1(Macintosh*)。“

以及来自 EA 的 ilbm.h

"/* Aspect ratios: The proper fraction xAspect/yAspect represents the pixel
* aspect ratio pixel_width/pixel_height.
*
* For the 4 Amiga display modes:
*  320 x 200: 10/11  (these pixels are taller than they are wide)
*  320 x 400: 20/11
*  640 x 200:  5/11
*  640 x 400: 10/11          */
#define x320x200Aspect 10L
#define y320x200Aspect 11L
#define x320x400Aspect 20L
#define y320x400Aspect 11L
#define x640x200Aspect  5L
#define y640x200Aspect 11L
#define x640x400Aspect 10L
#define y640x400Aspect 11L"

http://www.steguy.bravehost.com/Amiga_Files/V39_Support_Issues.txt

"-------------------------- getaspect -------------------------------

    bmhd->xAspect = 0;  /* So we can tell when we've got it */
    if(GfxBase->lib_Version >=36)
        {
        if(GetDisplayInfoData(NULL, (UBYTE *)&DI,
                sizeof(struct DisplayInfo), DTAG_DISP, modeid))
                {
                bmhd->xAspect =  DI.Resolution.x;
                bmhd->yAspect =  DI.Resolution.y;
                }
        }

    /* If running under 1.3 or GetDisplayInfoData failed, use old method
    * of guessing aspect ratio
    */
    if(! bmhd->xAspect)
        {
        bmhd->xAspect =  44;
        bmhd->yAspect =
                ((struct GfxBase *)GfxBase)->DisplayFlags & PAL ? 44 : 52;
        if(modeid & HIRES)      bmhd->xAspect = bmhd->xAspect >> 1;
        if(modeid & LACE)      bmhd->yAspect = bmhd->yAspect >> 1;
        }"

还有一个有趣的评论

http://vlists.pepperfish.net/pipermail/netsurf-commits-netsurf-browser.org/2011-July/010011.html

"/* AmigaOS sees 4:3 modes as square in the DisplayInfo database,
* so we correct 16:10 modes to square for widescreen displays. */
xres = (xres * 16) / 4;
yres = (yres * 10) / 3;"

(这会覆盖 DI.Resolution.x 和 DI.Resolution.y)

diskfont 库

[编辑 | 编辑源代码]

只有 fixed.font 还是所有字体都有同样的问题?Amiga 字体实际上是不是 hunk 二进制文件?

所有 hunk 二进制文件都失败还是只有非 m68k 端口上的某些字体失败?

启用 internalloadseg_aos.c 调试并包含相关的日志消息,这可能有助于查找问题(我仍然看不到任何错误:())

以下是 FixFonts 中段错误之前的日志

[DOS] DosInit: InitCode(RTF_AFTERDOS)
[DOSBoot] __dosboot_BootProcess: Booting from device 'EMU:'
    Hunk count: 1
    First hunk: 0
    Last hunk: 0
    Hunk 0 size: 0x0010d8 bytes in ANY memory @011d5064
HUNK_CODE(0): Length: 0x0010d8 bytes in ANY memory
HUNK_RELOC32:
    Hunk #0:
HUNK_END
[KRN] Trap signal 11, SysBase 0xf522dc, KernelBase 0xf52f38
[KRN] Process 0x1025508 (FixFonts)
     SP=011f0d30  FP=011f0d48  PC=b762e84e
     R0=4eff7000  R1=00000000  R2=b7631b6c  R3=00f531a4
     R4=011f0dd7  R5=011f0dd7

图形库

[编辑 | 编辑源代码]

BlkMaskBitMapRastPort() 修补程序对 pixbuf 进行动态分配

  • 消除了对 pixbuf 信号量的需求(提高并发性)
  • 根据需要动态分配 pixbuf
  • 将 NUMPIX 移动到 bltmaskbitmaprastport.c 文件中,并对其进行记录
  • 现在,我们可以处理宽度 * sizeof(HIDDT_Pixel) 超过 NUMPIX 的源图像,只要我们有足够的可用内存。

小评论:请创建图形的私有内存池并使用轮询内存分配函数,即 AllocPolled/FreePolled。非常频繁地调用常规的非轮询内存分配是导致性能下降的候选对象。AROS 应该获得一个更好的内存分配器。如果您频繁使用 C++ 程序所执行的 alloc/free,则当前的内存分配器会成为速度瓶颈。或者使用 arosc 进行 malloc 以获得更好的内存处理程序?如果是这样,Jason 执行的修补程序应该使用 malloc。修补程序中的内存分配可能太大而无法在池中工作。因此,即使使用了池内存,分配也大多会直接转到非池内存的分配。

池非常适合大小相同的项目集合,但这里的情况并非如此。

对于这种用法(可变大小,未知最大大小),池不是很有帮助。除非通过一些基准测试得到证明,否则这两个语句都只是理论。就我个人而言,我认为内存池是可取的,如果不是为了速度,而是为了内存碎片或能够使用一个 DeletePool 命令释放一大堆已分配的内存。后者在我看来在清理过程中最实用。

目前无法在 AROS 库中使用 malloc,因为它是在调用任务上下文中分配的。而 arosc malloc/free 只是使用内存池和 AllocPooled/FreePooled...

“NUMPIX”的最小尺寸是多少?默认值 (50000) 会导致在初始化 graphics.library 时分配 200000 字节。对于仅由少数几个函数使用的缓冲区来说,这有点多。这将为您提供 200x250 像素的位图,老实说,这并不多。也许您可以将实现更改为动态分配缓冲区?Root BitMap 类对几个调用(BM__Hidd_BitMap__PutAlphaImage、BM__Hidd_BitMap__PutTemplate、BM__Hidd_BitMap__PutAlphaTemplate 等)执行此操作。或者,请为 m68k 进行 ifdef - 一般情况下减少此值将意味着更多的小型 VRAM->RAM 读取实例,这可能会减慢操作速度。

workbench 库

[编辑 | 编辑源代码]

在第 58 行写入 Wanderer:Tools/Info 处有

#define USE_TEXTEDITOR 1

我想您可以尝试在那里使用 0

SYS:System/Wanderer/Tools/ExecuteStartup 缺少图标。(在修订版 34053 中删除,不应该有替换吗?)

没有图标 -> OpenWorkbenchObjectA() 会打开一个 CLI 输出窗口,因为 GetIconTags("ExecuteStartup") 返回 isDefaultIcon=TRUE。

只是想知道为什么以前没有人注意到这一点,除非隐藏控制台窗口有其他原因。(仅使用 m68k-amiga 端口进行测试)

没有图标

20-901 [513 226x165]: [WBLIB] OpenWorkbenchObjectA: name =
Wanderer:Tools/ExecuteStartup
20-905 [513 041x231]: [WBLIB] OpenWorkbenchObjectA: isDefaultIcon = 1
20-908 [513 060x281]: [WBLIB] OpenWorkbenchObjectA: it's a TOOL
20-912 [514 037x012]: [WBLIB] OpenWorkbenchObjectA: it's a CLI program
20-914 [514 008x061]: [Open] FH=1032b898 Process: 0x10100c08

“WANDERER:Wanderer”,窗口:0x00000000,名称:“CON:////Output Window/CLOSE/AUTO/WAIT”,模式:1005

添加了图标

10-571 [510 226x248]: [WBLIB] OpenWorkbenchObjectA: name =
Wanderer:Tools/ExecuteStartup
10-576 [511 040x007]: [WBLIB] OpenWorkbenchObjectA: isDefaultIcon = 0
10-579 [511 220x055]: [WBLIB] OpenWorkbenchObjectA: it's a TOOL
10-581 [511 226x103]: [WBLIB] OpenWorkbenchObjectA: it's a WB program
10-585 [511 226x159]: [WBLIB] OpenWorkbenchObjectA: stack size: 32768
Bytes, priority 0
10-590 [511 226x231]: [WBLIB]  WB_LaunchProgram: Success

查看 workbench.library/wanderer 作为源代码,并注意到 AppMenu 和 AppIcon 似乎还没有完全实现。看起来 wbhandler.h 应该添加一个类型以在更新 AppIcon 后更新 AppMenu,并且库代码应该在成功添加/删除其列表更改后向注册端口发送更新 (AppIcon|AppMenu) 消息以用于事件类型。是的,workbench.library 需要一些工作。'RegisterWorkbench()' 是 AROS 特定的改进,还是有 AOS 等效项?似乎是 AROS 特定的,旧的 AlohaWorkbench() 可以追溯到……嗯……很久以前,但它有意不记录,因为其唯一目的是注册……workbench,作为……workbench。附录 C,第 2 页……AlohaWorkbench() - 此例程允许 Workbench 工具将其存在和离开通知 Intuition。

AlohaWorkbench() - 在夏威夷语中,“aloha”既表示问候也表示告别。AlohaWorkbench() 例程允许 Workbench 程序通知 Intuition 它已变为活动状态以及它正在关闭。

此例程使用两种参数之一进行调用 - 指向已初始化的消息端口的指针(表示 Workbench 处于活动状态并且可以进行通信),或 NULL 表示 Workbench 工具正在关闭。

当消息端口处于活动状态时,Intuition 将向其发送 IntuiMessages。这些消息的 Class 字段将设置为 WBENCHMESSAGE。Code 字段将等于 WBENCHOPEN 或 WBENCHCLOSE,具体取决于 Workbench 应用程序是否应打开或关闭其窗口。Intuition 假设 Workbench 将遵守,因此一旦回复了消息,Intuition 就会继续执行,并期望窗口已相应地打开或关闭。

过程概要如下:

AlohaWorkbench(WBPort)

WBPort - a pointer to an initialized MsgPort structure in which the special communications are to take place. 

我不确定它是否是同一个函数,但 AmigaMail 或 DevCon 的一篇旧文章中写了一些关于类似功能的支持内容(这些年我的纸质副本丢失了)。Dopus Magellan 可能是真正商业客户端的最佳选择。

理想情况下,人们应该能够像在多屏幕 Workbench 程序中一样运行多个 workbench.library 客户端。

应用程序编写者可能希望实现 Workbench 抽屉导航和文件处理功能,以便在其自己的公共屏幕上使用,同时拥有其 AppWindows(不在 Workbench 屏幕上)以进行拖放,以代替文件请求器。他们可能希望尽可能地使用 PROGDIR: 作为根窗口,并使用自己的抽屉窗口代码等效项,并且仅显示其项目文件或仅支持的剪贴画文件类型,方法是显示实际的剪贴画而不是图标图像。

mathffp.library

[编辑 | 编辑源代码]

构建 mathffp.library。已修复,我忘记提交头文件修改了..(顺便问一下,谁能修复 lh_SysBase == NULL 问题?)。对 BPTR NULL 使用 BNULL。只需通过将其硬链接到绝对地址来添加对 ROM 中 .bss 的支持即可。不会发生这种情况。芯片 RAM 很宝贵,速度慢,并且是所有 Amiga 机型上唯一保证存在的 RAM。如果我硬链接了 .bss,我将不得不使用芯片 RAM,这将减少可用于 DMA 可寻址位图、软盘磁道和音频的 RAM 量。在库的句柄(如果可用则在 Fast RAM 中分配)中使用空间是一个更好的解决方案。然后,在库基址中存储方法 ID,并且不要使用存根(无论如何它们都不适用于没有 .bss 的 ROM 代码) :-D

这再次是 m68k-amiga 特定的,它不能期望 FPU 但仍然需要支持浮点数。这意味着我们需要以“Amiga 方式”执行此操作并使用 mathieeedoubxxx 库。(非 Amiga 方式将是捕获 FPU 异常,这仅在模拟缺少的 040/060 fpu 函数时才允许:))

是否可以通过用调用 IEEDP 库函数的存根替换 gcc math C 库函数来正确执行此操作?(并将 lib 基址放在 aros_privdata 中)

IEEEDP 函数随后使用软件版本或数学函数的内联汇编 fpu 版本(在打开库时用 FPU 函数替换 lib 向量)

数学库有一些已知的与 m68k 相关的问题。

Cmp() 和 Tst() 函数记录为返回正确的设置 68k 标志,这在使用普通 C SetSR() 时是不可能的,SetSR() 设置代码,但最终复制到 D0 会重置所有标志..(所有 math lib SetSR() 调用在 m68k C 代码中都是无用的)。

只有 FFP Cmp() 和 Tst() 具有汇编修复,其他 FFP 函数仍然至少返回错误的 N 标志(FFP 符号位是第 7 位,而不是第 31 位),幸运的是 IEEE 符号位是第 31 位。我稍后会尝试修复 IEEE Cmp() 和 Tst(),如果 Jason 仍然感兴趣,他可以尝试修复其他返回代码问题 :)

此外,Autodocs 略有不正确,例如 Cmp() 和 Tst() 被记录为始终返回 V=0,这是不可能的,因为 V 标志由 m68k CMP 设置/重置,并且 bgt 和其他分支命令需要它..(这些命令记录为可用于数学库!)

使用 -libm 链接应该可以解决此问题。如果它已使用 -libm 链接,那么我不知道为什么它不起作用。它尚未完成,因为这并不简单,正确的 m68k Amiga 方式是将编译器数学库重定向到 LIBS: 中的数学库(LIBS: 数学库随后使用软件或 FPU,具体取决于硬件配置)。

在 LC_LIBDEFS_FILE 可以在覆盖的 c 文件中工作之前,是否需要执行某些操作?我尝试覆盖 mathieeedoubbas/mathieeedoubbas_init.c(作为 arch/m68k-all/mathieeedoubbas/ mathieeedoubbas_init.c)以支持 m68k FPU 函数。已经包含的 ieeedpbas_fpu.c 不能在 m68k-amiga 上使用,因为 AOS C 库数学函数应该在内部调用数学库函数,而不是相反。

/home/twilen/aros/arch/m68k-all/mathieeedoubbas/./mathieeedoubbas_init.c:11:10: error: #include expects "FILENAME" or <FILENAME>. This definition is handled by the %build_module macro but not by the %build_archspecific macro. It will need to be implemented in config/make.tmpl if needed. 

糟糕,我忘记回复 LC_LIBDEFS_FILE 实际上并不需要。我覆盖了 if,因为我不想再添加另一个 idef _m68000,并且因为 m68k FPU 例程应该始终使用 FPU 指令,即使 m68k AROS 设置被编译为与 68000 兼容(这在今天是正确的)。初始化例程然后在运行时修补函数指针(如果检测到 FPU)。

顺便说一句,IEEE Div 和 Mul 软件版本未实现,谁能实现这些?

68040 和 68060 没有在硬件中实现旧 CPU 和 FPU 支持的所有指令(一些很少使用的指令和 FPU 指令,如 sin 和 cos)摩托罗拉分发了实现缺少指令的软件模拟的汇编代码(包括源代码),例如康柏和加速器制造商将其包含在 68040 或 68060.library 中。(我想每个人都知道这一点?)

摩托罗拉的模拟文件附带以下许可证,这与 AROS 兼容吗?应该是,例如它包含在 netbsd 中,但我想在它成为 m68k-all 的一部分之前得到确认。

  1. 08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)~

~

  1. 摩托罗拉微处理器与内存技术集团
  2. M68000 高性能微处理器部门
  3. M68060 软件包生产发布版
  4. M68060 软件包版权所有 (C) 1993、1994、1995、1996 摩托罗拉

公司

  1. 版权所有。
  2. 该软件按“原样”提供,不提供任何担保。
  3. 在适用法律允许的最大范围内,
  4. 摩托罗拉否认所有明示或暗示的担保,
  5. 包括对适销性或适用于
  6. 特定目的的默示保证,以及任何与
  7. 软件(包括其任何修改版本)
  8. 和任何附带的书面材料相关的侵权担保。
  9. 在适用法律允许的最大范围内,
  10. 在任何情况下,摩托罗拉均不对任何损害负责
  11. (包括但不限于因业务利润损失、
  12. 业务中断、业务信息丢失或其他

经济损失)

  1. 因使用或无法使用软件而产生。
  2. 摩托罗拉不对软件的维护和支持
  3. 承担任何责任。
  4. 特此授予您使用、修改和

分发

  1. 软件的版权许可,只要此完整通知在任何修改和/或重新分发的版本中
  2. 保持不变,并且此类修改的
  3. 版本被明确标识为如此。
  4. 根据

任何

  1. 摩托罗拉公司的专利或商标,均未暗示、禁止反言或以其他方式授予任何许可证。
  2. 08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)08:22, 2011年5月5日 (UTC)~

%build_module 不支持 asmfiles。谁能更熟悉地添加支持?

我需要 asmfiles 支持来构建 040/060 缺少的指令模拟模块。它是 m68k 独有的,没有要覆盖的内容,它需要 m68k 汇编。

我假设 r38541 和 r38542 是那些摩托罗拉代码,对吧?m68k-all/mathieeedoubbas 中的文件呢?这是否也是摩托罗拉代码?实际上,这只是“普通的 68882 FPU”指令。托尼谈论的是一个单独的问题,即来自摩托罗拉的模拟代码,用于在 68040 和 68060 上支持部分实现的 FPU 指令(它们拥有大部分,但并非所有 68882 FPU)。

是的,一些很少使用的非 FPU 指令丢失了。它们也由模拟代码处理。

<snip> 未实现的整数指令是

   64-bit divide
   64-bit multiply
   movep
   cmp2
   chk2
   cas (w/ a misaligned effective address)
   cas2

</snip>

lowlevel.library

[编辑 | 编辑源代码]
trunk/AROS/rom/devs/keyboard/keyboard.c
trunk/AROS/rom/devs/keyboard/keyboard_intern.h

Lowlevel.library 不是 ROM 模块(它仅在 cd32 中是 ROM),并且还没有 Amiga 硬件特定实现 = 必须支持磁盘上的原始版本。

如果没有此 hack,您只会获得随机的内存损坏,这在 lowlevel.library 被清除时很难调试(例如 whdload 在启动时会执行此操作)

更好的问题是:原始的 keyboard.device 如何存活?也许它不使用或不需要 opener 特定的结构?是否存在任何可用于比较 AROS 与 OS3.1 结果的测试用例/测试应用程序?我假设 RKMs/Guru Book 中没有关于此的内容,我们无法反汇编 KS 二进制文件以进行检查。在 KS3.1 上的多个 OpenDevice("keyboard.device") 在 io_Unit 字段中返回静态值。(相对于 keyboard.device 基址的指针)。我想说不需要 opener 特定的 KBUnit 结构。(也许原始的 keyboard.device 仅在存在单个 opener 时才能正常工作?)。

reqtools.library

[编辑 | 编辑源代码]

原始的 m68k reqtools.library 小部件也存在一些问题,所有按钮小部件都不可见,但单击时它们确实可以工作(并且在单击一次后它们甚至会永久可见)

这可能与此相关:Deluxe Paint 2 和 3(未测试其他版本,2 和 3 用于叠加测试)按钮小部件具有类似的图形故障。

按钮文本/标签在其被单击一次后(或如果小部件最初被绘制为活动状态)会永久不可见。

fid->fid_EdgesOnly 可能为 0。如果稍后绘制,则应为 1。

我想到了,frameiclass,对 AFA 进行了大量修改。我私下发送给你文件,也许你看到了区别。

有时我会发布 AFA 与 AROS 代码存在的问题。我认为这两个问题也可能是可能的。您是否检查过 AROS 68k 中是否存在这些问题?

我的意思是 wb 3.9 中关于 Req 的文本显示正确。

//RemoveClass(FindClass("itexticlass")); // wb 3.9 中的文本未写入。 //BOOPSI_ITextIClass_Startup_lib(); ////// //RemoveClass(FindClass("frbuttonclass")); // 小部件框太大 //BOOPSI_FrButtonClass_Startup_lib();

但在最后的函数中,由于不知道要修复什么,我禁用了它们。

我非常确定 reqtools 使用标准的 intuition 小部件(它很长时间以来都与 1.3 兼容),而不是 boopsi。reqtools 68k 调用此代码,也许您添加了一些调试代码来查看 fid->fid_EdgesOnly 是否为 0 或 1。我禁用了 EdgesOnly 测试:对隐藏的按钮小部件没有影响。

IPTR FrameIClass__IM_DRAW(Class *cl, struct Image *im, struct impDraw *msg)
{
    DEBUG_IFRAME(dprintf("dispatch_frameiclass: draw Width %ld Height %ld\n",im->Width,
im->Height));
    //kprintf("%ld %ld\n",im->Width,im->Height);
    return draw_frameiclass(cl, im, msg, im->Width, im->Height);
}

我注意到 RefreshBoolGadgetState() 在选择状态更改时被调用,并且在那个时候看起来没问题,但此调用后的某些操作清除了标签文本。也许您尝试跳过 draw_frameiclass(cl, im, msg, im->Width, im->Height) 对隐藏的按钮也没有效果(当然,小部件开始看起来很奇怪)。我刚刚注意到是填充模式覆盖了小部件,因为显示非填充窗口的 gadtools 演示部分可以正常工作。

它没有被很多软件使用,如果文本没有被覆盖,你可以确定frameiclass中有一些问题。看起来所有Aros原生程序如果之前没有人注意到的话,都会使用boopsi。

wbversion

[编辑 | 编辑源代码]

安装脚本不接受AROS的版本号。一条消息指示使用Kick 3.1。那么AROS wbversion 是否可能与AOS兼容,并显示AROS至少是Kick 3.1?

这里失败了

拥有KS3.1
(if (< #wbversion 40)
(   (exit #msg-badkick (quiet))
    ))

如何设置#wbversion?这是什么版本的Scalos,以及从哪里可以下载?

  1. wbversion 通过查看libs:version.library的版本来定义。

来自scalos的安装脚本

(set #wbversion (/ (getversion "Libs:version.library") 65536))

我认为AROS中没有version.library。我想这解释了失败的原因。

它没有任何函数,是吗?M68k软件肯定假设它存在。它没有额外的函数,但可以正常删除。

我用codesearch找到了这个

const char *amigaGetOSVersion(void)
{
   static const char *osver[] = { "2.0","2.0x","2.1","3.0","3.1","3.2","3.3","3.4","3.5","3.9","3.9","3.9","3.9","3.9","4.0pre","4.0pre","4.0" };
   int ver = SysBase->LibNode.lib_Version;
   #ifndef __amigaos4__
   if (ver >= 40 && ver < 50) {   // Detect OS 3.5/3.9
      struct Library *VersionBase;
      if ((VersionBase = OpenLibrary("version.library",0))) {
         ver = VersionBase->lib_Version;
         CloseLibrary(VersionBase);
      }
   }
   #endif
   #ifdef __POWERUP__
   if (FindResident("MorphOS") && ver > 45) ver = 45;
   #endif
   if (ver < 36) ver = 36;
   else if (ver > 51) ver = 51;
   return osver[ver-36];
}

看起来我们所要做的就是将lib_Version设置为40以用于OS3.1。

global.prefs与m68k-amiga不兼容。它包含了导致m68k-amiga TextEditor mui类崩溃的小端数据。例如,当TextEditor请求MUIM_GetConfigItem / MUICFG_TextEditor_UndoSize时,十进制数500将被读取为F4010000。类已修复(阻止了初始化),prefs问题是不同的问题,目前唯一的解决方法是删除prefs文件。如果它*确实*支持跨平台,所有数据都应该为大端(因为Classic AmigaOS是我们的最低公分母,并且大端更容易在十六进制转储中用肉眼读取!)

我看到其中一些地方IPTR被恢复为ULONG(可能在x86_64上不好?)。再次检查上面该代码中添加的#ifdef __AROS__行。

我相信SDI_hook.h和SDI_compiler.h的更改是稳定的,并且可以回传。我想建议我们在顶层workbench/libs/SDI中有一个包含AROS SDI头文件的“主”版本,这些文件安装在:Development/Include/中。当前使用SDI的包应该选择这些头文件,而不是其本地包含文件中的(可能已过时的)版本。当已经有编译器/包含文件时,这样做对我来说没有多大意义(从技术上讲,它不是一个库,所以workbench/libs不是放置它的位置)。AROS应该在其树中只有一个版本的SDI(希望是最新的!),而不是四个或修复不同版本的副本。

在另一个方面,我无法弄清楚如何使SDI可变参数VA_*宏适用于使用非统一可变参数数组的AROS架构。(特别是x86_64)。目前在AROS上,有以下几种情况的非常复杂的宏(和辅助函数)

IPTR func(LONG dummy, Tag tag1, ...)
{
   AROS_SLOWSTACKTAGS_PRE(tag1)
   retval = funcA(dummy, AROS_SLOWSTACKTAGS_ARG(tag1));
   AROS_SLOWSTACKTAGS_POST
}

以及

IPTR  func(Class *cl, Object *obj, ULONG MethodID, ...)
{
  AROS_SLOWSTACKMETHODS_PRE(MethodID)
  retval = funcA(cl, obj, AROS_SLOWSTACKMETHODS_ARG(MethodID))
  
  AROS_SLOWSTACKMETHODS_POST
}

Package-Startup从其父目录执行。因此它将“system:extras/Zune/MCC_NList/Classes”添加到Libs

启动序列的这一复杂部分读取env:sys/packages中的所有变量。这些变量包含s/Package-Startup的路径。

If EXISTS ENV:SYS/Packages
    List ENV:SYS/Packages NOHEAD FILES TO T:P LFORMAT="If EXISTS
${SYS/Packages/%N}*NCD ${SYS/Packages/%N}*NIf EXISTS
S/Package-Startup*NExecute S/Package-Startup*NEndif*NEndif*N"
    Execute T:P
    Delete T:P QUIET
    CD SYS:
EndIf

任何足够无聊的人应该帮助修复contrib中的m68k编译问题:) 你得到什么编译错误?也许你尝试使用旧编译器(最好关闭GCC中的优化器以避免程序损坏)和68k.cpu.h中的旧AROS 68k宏文件来编译contrib

我注意到Mason为GCC 4.5.0编写的宏不适用于编译AFA(使用GCC 3.4.0和GCC 4.5.0),只有旧的AROS宏和GCC 3.4.0可以正常工作。

但理论上,如果我更改libcall.h和cpu.h,它应该可以工作。

当使用选项-E编译时,宏错误变得更加明显,因此只执行预处理器部分并保存ascii[检查拼写]文件。这是发送给Jason但未回复的邮件

这个zune文件或arossupport.c

当我使用旧的libbcall.h时,所有内容都可以工作。我已将其附加(目前命名为libbcall.h_,因为我使用了你的文件)

这是amidevcpp的完整日志输出。

-E选项我用来获取预处理器错误输出。当我不用-E时,我只得到一个语法错误,它并不精确。奇怪的是,AROS可以工作。

Compiler: m68k-AmigaOS
Building Makefile: "E:\amiga\AmiDevCpp\usr\local\amiga\Makefile.win"
Executing  make...
mingw32-make.exe -f "E:\amiga\AmiDevCpp\usr\local\amiga\Makefile.win" all
m68k-amigaos-gcc-3.4.0 -c afa_os/arossupport.c -o aros/WORKBE~1/libs/MUIMAS~4/arossupport.o
-I"E:/amiga/AmiDevCpp/usr/local/amiga/m68k-amigaos/sys-include"
-I"E:/amiga/AmiDevCpp/usr/local/amiga/m68k-amigaos/include" -I"afa_os/include" -I"arosinclude"
-I"Aros/workbench/libs/muimaster" -I"Aros/workbench/libs/muimaster/classes"
-I"Aros/workbench/classes/zune/aboutwindow"  -m68020 -m68881 -D__AROS__ -fno-strict-aliasing -E -w -O2
afa_os/arossupport.c:18:43: macro "__AROS_LCA" requires 3 arguments, but only 1 given
afa_os/arossupport.c:18:43: macro "__AROS_LCA" requires 3 arguments, but only 1 given
afa_os/arossupport.c:23:42: macro "__AROS_LCA" requires 3 arguments, but only 1 given
afa_os/arossupport.c:23:42: macro "__AROS_LCA" requires 3 arguments, but only 1 given
afa_os/arossupport.c:172:21: macro "__AROS_LCA" requires 3 arguments, but only 1 given
afa_os/arossupport.c:180:44: macro "__AROS_LCA" requires 3 arguments, but only 1 given
afa_os/arossupport.c:180:44: macro "__AROS_LCA" requires 3 arguments, but only 1 given
.....
"""""

在第18行,只是简单地调用了它。

return MUI_NewObjectA(classname, &tag1);

但它也发生在LHA宏上。目前唯一可用的编译器是最新的+Jason的A6 gcc寄存器补丁。(这肯定与可能的编译器问题无关)

顺便说一句,当也使用原生AmigaOS库时,AROS mui或库中也存在一些问题。Scout由于在调用DisposeRegion(或ClearRegion)时区域指针损坏而崩溃。(我试图使用AmigaOS nlist,因为AROS版本无法编译)区域指针指向一些奇怪的字符串数据。调试内存溢出/损坏很无聊..

我认为这里的问题是sdi包含文件认为自己是68k并使用68k编译器语法。要查看真正的问题,请使用编译器选项-E并发布预处理器文件,因为sdi使用了如此多的嵌套宏。

如果functionheader中-E的输出显示如下内容并包含asm命令,则对于新编译器来说是错误的。

funcname(char *args __asm("a0") )

> /home/twilen/AROS/contrib/bgui/examples/FieldList.h:150:21: error: too > many arguments to function 'SetFLAttr'

这是不同的。可能是SetFLAttr的原型错误。如果不是这里,你也可以在makefile中设置编译器选项-E时查看,没有宏的完整源代码行是什么。

> > btw, there is something wrong with either aros mui or libraries when > also using native amigaos libraries. Scout crashes due to corrupt > region pointer when calling DisposeRegion (or was it ClearRegion).

据我记得,AROS上zune MUI API的lib插槽使用方式不同。我为AFA修复了偏移量,但不知道有什么不同。我发送给你AFA muimaster.h定义的私有文件,这里的附件不起作用。

因为Amiga中所有OOP的东西都是由于黑盒概念,并且添加功能需要大量工作,所以实现是有限的,并且缺少许多功能。这也是MOS MUI4上的一个问题。

在MUI和boopsi图片数据类型方面,使用它的开发人员开始进行hack并使用未公开的功能。

所以我建议在AROS 68k上,与AFA相同的方式进行操作。AROS MUI库名为zune.library。所有AROS程序都编译为在68k上使用zune.library。

这允许你通过使用MUI 68k获得最佳兼容性,并避免新功能无法添加到zune中,从而破坏某些程序。

用户可以像在AFA中一样使用zune启动器来告诉程序它应该使用zune.library而不是muimaster.library

因为AFA已经存在很长时间了,所以只有大约70-80%的MUI 68k程序在zune上完美运行。它也不喜欢OO的东西,很难找到问题,所以多年来我一直放弃让zune更兼容。

对于AROS上的bgui,我目前没有其他想法,因为问题来自AROS输入设备。我无法在AFA上测试。

librom.a库现在具有旧样式的“no %f/%g”printf系列,arosc.library具有浮点功能。因此,如果你想要%f,请使用“linklibs="arosc"”,而不是“linklibs="rom"”。如果有人意外地链接到它并使用“%f”格式,谨慎起见,最好让“rom”版本打印出“???”。只有openurl.library的Prefs需要%f。

仅供参考:不允许将模块(库、设备等)与arosc.library链接——这是因为arosc.library在调用任务中存储上下文。

TASK [arosc.library context]
|
|
\ /
module
|
|
\ /
arosc.library

因此,当任务死亡时,上下文也死亡,但模块已在该上下文中分配了内存。这就是为什么模块需要与librom.a链接(即使它们不在ROM中)并且librom.a中缺少的C库函数必须在模块中直接实现(例如,我必须对mesa.library执行此操作)。

“因此,如果你想要%f,请使用“linklibs="arosc"”,而不是“linklibs="rom"”不适用于它们。:) PS。用于显式禁用与arosc.library链接的模块构建的宏——这是有意的(这就是Kalamatee出现链接器错误的原因)

AOS下的RawDoFmt()打印什么?它不是像只是剥离了'%',即'f'吗?

所有bgui.library小部件都可见(有些存在小的对齐错误),但无法使用鼠标选择或激活它们。键盘快捷键有效(如果小部件设置了键盘快捷键)

bgui.library演示和FileMaster 3(“出于某种原因”,这是我的一个测试用例...)存在相同的BOOPSI问题。

它们处于正常的非按下状态。而且不仅仅是按钮小部件,所有bgui小部件类型都无法使用鼠标选择。

除了鼠标选择之外,其他所有内容都可以工作(或多或少)。例如,窗口打开时选中的字符串小部件的光标可见,甚至文本编辑也可以正常工作。

按下按钮小部件的快捷键可以工作,并且小部件的文本标签消失(这是错误的,它应该显示按下状态)在按下ESC的同时保持快捷键按下会取消按下事件,并且文本标签重新出现。

因此,bgui小部件至少存在两个不同的问题

  • 鼠标选择。
  • 按钮小部件(可能是其他小部件,在鼠标选择工作之前无法真正测试)按下状态渲染不正确。

我在AFA中激活了许多AROS函数和类进行测试(这会导致68k代码出现问题),但bgui addbuttons测试程序(我只将其用于测试)可以正常工作。因此,这些AROS函数中似乎没有问题。

AFA上的buttonclass gmhittest与AROS上的相同,并且都可正常工作。

我还恢复了一些AFA代码的兼容性增强功能。bgui仍然可以工作。我有时间时会在AROS 68k上测试。

如果它们无法点击会发生什么,当你点击它时,是否没有显示按下状态?

在这里你可以看到哪些问题是由某些程序中的某些AROS函数引起的。通常情况下,我会禁用所有这些已知存在错误的函数。

因此,如果你遇到这样的问题,它可能有助于找到导致此问题的功能。

这是稳定的AROS代码,没有已知的兼容性错误

              RemoveClass(FindClass("gadgetclass"));
              BOOPSI_GadgetClass_Startup_lib();
              RemoveClass(FindClass("sysiclass"));
              BOOPSI_SysIClass_Startup_lib();
              BOOPSI_TbiClass_Startup_lib();
              RemoveClass(FindClass("buttongclass"));
              BOOPSI_ButtonGClass_Startup_lib();
              RemoveClass(FindClass("imageclass"));
              BOOPSI_ImageClass_Startup_lib();

SETFUNC(DoGadgetMethodA,Intuition,IntuitionBase); // // editpad scrollbar after load full size
SETFUNC(RefreshGadgets,Intuition,IntuitionBase);
if (replacevisualprefs)
{
SETFUNC(AddGadget,Intuition,IntuitionBase);
SETFUNC(AddGList,Intuition,IntuitionBase);
}
SETFUNC(RemoveClass,Intuition,IntuitionBase);
SETFUNC(NextObject,Intuition,IntuitionBase);
SETFUNC(DisposeObject,Intuition,IntuitionBase);
SETFUNC(AddClass,Intuition,IntuitionBase);
SETFUNC(FreeClass,Intuition,IntuitionBase);
SETFUNC(MakeClass,Intuition,IntuitionBase);
SETFUNC(NewObjectA,Intuition,IntuitionBase);
SETFUNC(MakeClass,Intuition,IntuitionBase);
SETFUNC(SetGadgetAttrsA,Intuition,IntuitionBase);
SETFUNC(ObtainGIRPort,Intuition,IntuitionBase); // text is draw only on top of screen
SETFUNC(ReleaseGIRPort,Intuition,IntuitionBase);
SETFUNC(DrawImage,Intuition,IntuitionBase); //redraw errors on old icons on workbench
SETFUNC(DrawImageState,Intuition,IntuitionBase); //redraw errors on old icons on workbench
SETFUNC(ModifyIDCMP,Intuition,IntuitionBase);  //immediate redraw when scroll not work(MUI)

RemoveClass(FindClass("icclass"));  //kingcon scrollbar redraw not immediate.
BOOPSI_ICClass_Startup_lib();
RemoveClass(FindClass("rootclass"));
InitRootClass_lib();
RemoveClass(FindClass("groupgclass"));
BOOPSI_GroupGClass_Startup_lib();
RemoveClass(FindClass("modelclass"));
BOOPSI_ModelClass_Startup_lib();
RemoveClass(FindClass("itexticlass")); // text in WB 3.9 about is not written.
BOOPSI_ITextIClass_Startup_lib();
//////
RemoveClass(FindClass("frbuttonclass")); // gadget boxes are too large
BOOPSI_FrButtonClass_Startup_lib();
//
RemoveClass(FindClass("fillrectclass"));
BOOPSI_FillRectClass_Startup_lib();

WB3.1 Prefs/Palette显然手动创建DrawInfo结构,导致sysiclass_aros.c中崩溃,因为它假设dri_Screen有效。

当在openscreen.c中设置dri_version = DRI_VERSION + 1,并且仅在sysiclass_aros.c中允许“新的”drawinfo版本时,首选项程序不再崩溃。

这个更改可以吗?或者使用某种“扩展drawinfo”标志而不是更改版本号更好?不幸的是,这将破坏与旧AROS程序的向后兼容性。(如果找不到兼容的解决方案,我会将其放在AROS_FLAVOUR_BINCOMPAT ifdef中)

首选项/调色板停止崩溃并工作,除了颜色选择器圆圈完全是黑色的,首先绘制所有颜色,完成后,它被黑色覆盖。

WB3.1 首选项/调色板调用AreaCircle(或AreaEllipse)两次(用于在色轮周围绘制窄黑色边框),两者具有相同的中心坐标,一个具有少量像素,更大的半径,最后调用AreaEnd,它应该只填充窄区域边框区域。AROS版本填充两个圆圈,导致色轮完全变黑。(我不会碰这个)

显然AreaEnd()始终使用类似光栅的区域填充。

AOS工作台启动的程序也具有NULL pr_CurrentDir。

例如,非常常见的SAS-C启动代码(源代码随编译器提供)在从WB启动时执行以下操作

a0 = WB startup message
move.l     wa_Lock(a0),d1
callsys    DupLock
move.l     d0,__curdir(A4)
move.l     d0,d1
callsys    CurrentDir

不幸的是,在退出时,它不会恢复pr_CurrentDir,它只解锁了__curdir(a4)。这意味着除了使用NULL pr_CurrentDir之外,没有其他方法可以处理此问题。(目前它会导致双重解锁,至少UAE fs会忽略它而不会崩溃,其他情况不确定)。我现在已经确认了从WB启动时的以下进程变量

pr_CurrentDir = NULL
pr_HomeDir = set
pr_CIS = NULL
pr_COS = NULL
pr_ConsoleTask = NULL
pr_FileSystemTask = set

调试此问题,发现Wanderer(或其他程序)在选择执行后会调用ScreenToFront("wb screen")。似乎screendepth没有检查(至少没有正确检查)请求的屏幕是否已经在前面。调用跟踪为:screendepth()->RethinkDisplay()->MrgCop()

华夏公益教科书