首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >商品C64如何检测PAL或NTSC

商品C64如何检测PAL或NTSC
EN

Stack Overflow用户
提问于 2021-10-05 13:41:51
回答 1查看 239关注 0票数 1

背景信息

我目前正在为商品C64开发一个编程API,使用Beta中的KickC,以便更容易地开发小型程序、应用程序和可能的一些游戏;我突然意识到,我可能需要一种方法来检查我的代码是否运行在PAL或NTSC机器上,在后一种情况下,NTSC机器,因为旧的NTSC C64比较新的C64版本少一条扫描线。

在寻求帮助之后,Robin给我发送了一段代码片段,其中包括附带了一个CMD SuperCPU (我的最终目标机器)。当他将其作为程序集发送时,我不得不按原样使用其中的大部分,但在KickC中使用ASM指令,如下所示:

代码语言:javascript
复制
/**
 * This is the initialisation will
 * determine the machine type
 * by setting the getMachineType global
 * as follows:
 *  37 is PAL
 *  5 is NTSC (old)
 *  6 is NTSC (new)
 *  0 (or any other value) is unknown
 *
 * For safety, the initial value of 0xc000
 * is stored into the accumulator and
 * pushed onto the stack; it is then
 * restored after the getMachineType
 * global is set
 *
 * @author Robin Harbron
 */
void setMachineType() {
    asm {
        lda $c000
        pha
        sei
    __br1:
        lda $d011
        bmi __br1
    __br2:
        lda $d011
        bpl __br2
    __br3:
        lda $d012
        bit $d011
        bpl __ex1
        sta $c000
        bmi __br3
    __ex1:
        cli
    }
 
    getMachineType = peek(0xc000);
 
    asm {
        pla
        sta $c000
    }
}

在我的脚本顶部,我在全局声明了getMachineType,如下所示:

代码语言:javascript
复制
unsigned byte getMachineType;

目前,我的peek()函数是这样工作的:

代码语言:javascript
复制
/**
 * Returns a single byte from a specific
 * memory location
 */
unsigned char peek(unsigned short location) {
    unsigned char* memory = (char*)location;
    unsigned char returnByte = *memory;
 
    return returnByte;
}

因此,现在我可以确定运行我的程序的主机上可用的扫描线数,从而更容易地创建与PAL和NTSC兼容的可执行文件。

KickC可从CSDb.dk下载,并将使用踢汇编程序构建和组装。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-19 20:10:36

您共享的组装代码是使用国际中心-Ⅱ芯片的SCROLY寄存器($D011)和光栅寄存器($D012)。

$D011的高比特是当前光栅扫描线中最重要的位,而$D012包含较低的8位。

NTSC系统有262 (或261?)扫描线,PAL有312。

汇编程序例程等待设置高位的瞬间,即扫描线256。

如果设置了高位,它会循环,直到没有设置为止:

代码语言:javascript
复制
    __br1:
        lda $d011
        bmi __br1         // read $d011 again if high bit is set

然后在高比特清晰的时候循环,一旦设置好就退出循环:

代码语言:javascript
复制
    __br2:
        lda $d011
        bpl __br2         // read $ d011 again if high bit is clear

然后从$d012下载栅格扫描线的下8位。

这将在$c000中存储较低8位的扫描线值,同时测试高比特,直到它再次清除为止。如果已清除,请不要存储较低的8位,而是通过__ex1退出循环

代码语言:javascript
复制
    __br3:
        lda $d012
        bit $d011
        bpl __ex1
        sta $c000
        bmi __br3
    __ex1:
        cli

结果应该是观察到的最高扫描线的数目- 256。对于有262条扫描线的NTSC,这是返回值6(或者其他NTSC模型的返回值5)的地方,它是基于零的,所以5将是262 scanline NTSC版本的值。从零开始的扫描线312将是311,- 256 = 55,十六进制$37。那里的评论应该明确指出37是十六进制的。

您可以在优秀的"测绘商品64“一书中找到有关这些寄存器的信息。

您可以将所有这些汇编程序转换为C(除了设置中断禁用位并清除它:seicli),只需分配一个char *指针值0xD 011,另一个0xD 012,并使用C代码执行相同的操作。

代码语言:javascript
复制
char machineType = 0;
signed char * SCROLY = 0xd011;
char * RASTER = 0xd012;

asm {
  sei
}

while (*SCROLY < 0) ; // spin until scaline wraps
while (*SCROLY > 0) ; // spin until high bit set again
while (true) {
  char lines = *RASTER;
  if (*SCROLY > 0)
    break;
  machineType = lines;
}

asm {
  cli
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69451591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档