在上一节中,我们理解了字符映射与.data段的用法。接下来我们将看看另外两个好用的功能:表达式和零页
本节参考了Expressions、Advanced Memory Segments

表达式

Ophis允许书写表达式,这些表达式将在汇编之前完成计算。全部可用运算符如下

运算符 含义
[ ] 相当于( ),因为圆括号另有涵义
< > 取数的低8位/高8位
* / 乘除
+ - 加减
& | ^ 按位与、或、非

在介绍完零页之后,将在附录介绍一个表达式的用例。我们将用表达式实现打印内存中任意位置的字符串的子程序。

零页1

顾名思义,"零页"是指内存的第0页,即0x0000-0x00FF。位于零页的内存不仅访问速度更快(和寄存器速度相同),而且只有该部分内存能够使用间接偏移寻址。这种寻址方式对于编程而言十分重要,我们将在附录的用例中进行详细介绍。
然而,正因为零页十分重要,KERNALBASIC都使用了零页上的大量空间,留给我们的空间变得十分稀少(只有5个,位于02、fb、fc、fd、fe)。但是在机器代码运行时并不需要BASIC,因此我们可以另辟蹊径,在程序运行开始时将零页的BASIC数据区(到8f为止)搬移到内存的其他区域,在程序结束后进行恢复,从而得到该部分的零页空间的使用权。
不过,因为0001位置被映射到寄存器用于进行内存控制,所以实际可用范围为02-8f
Ophis采用如下语句标识零页位置

.data zp
.org $0002

然后即可进行零页搬移

./platform/c64_0.cph

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Commodore 64 Basic Runtime File
;;
;; Include this at the TOP of your C64 program, and it will handle
;; hiding away the BASIC ROM and data and restoring it at the end.
;;
;; You will have a contiguous block of RAM from $0800 to $CFFF, and
;; Zero Page access from $02 to $8F in the segment "zp"..include "c64header.oph".data zp ; Zero Page memory segment.
.org $0002.text.scope; Cache BASIC zero page underneath the KERNAL, while also; making RAM copies of the NMI routinesldx    #$00
*   lda $00, xsta   $e000, xinxbne  -; Swap out the BASIC ROM for RAMlda    $01and  #$feora #$06sta $01; Run the real programjsr    _main; Swap out KERNAL to expose cached BASIC ZP values; Block IRQs during this period. NMIs cannot be blocked,; but we copied enough of the processing code into the; RAM under the KERNAL that we can disable NMI processing; during this periodsei               ; Disable IRQslda   #$c1        ; Defang NMIssta    $318lda $01         ; Swap out KERNALand    #$fdsta $01; Restore BASIC zero pageldx #$8E
*   lda $e001, xsta $01, xdexbne    -; Restore BASIC ROM, KERNAL, and interruptslda $01ora  #$07sta $01lda  #$47    ; Restore NMI vectorsta $318cli         ; Re-enable interrupts; Back to BASIC. We do this by clearing the keyboard; buffer and then jumping through the warm start; vector. This will more cleanly handle case where; the program has somehow modified BASIC's state,; such as running through PUCRUNCH or a onefiler.stx  $c6     ; .X is zero from previous loopjmp  ($a002)_main:; Program follows...
.scend

./platform/c64header.oph

.word $0801
.org  $0801; BASIC program that just calls our machine language code
.scope.word _next, 10       ; Next line and current line number.byte $9e,"2061",0 ; SYS 2061
_next:  .word 0         ; End of program
.scend; Program follows...

在程序的最后,还需要如下语句检查是否越界

.data zp
.checkpc $80

附录

接下来我们将实现打印内存中任意位置的字符串的子程序。
由于内存地址为16位,因此需要使用两个8位的连续零页内存空间,按小端序存放该地址。

; PRINTSTR routine.  Accumulator stores the low byte of the address,
; X register stores the high byte..scope
.data zp
.space _ptr 2
.text
printstr:sta _ptrstx _ptr+1ldy #$00
_lp:    lda (_ptr),ybeq _donejsr chroutinybne _lp
_done:  rts
.scend

接下来,因为涉及到超过8位的参数,我们使用宏来调用该子程序。

.macro printlda #<_1  ; 取参数的低八位ldx #>_1    ; 取参数的高八位jsr printstr
.macend

前往下一节


  1. Zeropage - C64-Wiki ↩︎

利用 Ophis 编写 Commodore 64 programs PRG 程序(四)相关推荐

  1. 利用 Ophis 编写 Commodore 64 programs PRG 程序(一)

    参考Producing Commodore 64 programs.Writing the actual code 本节将实现简单的hello world程序,从而形成对ophis的初步认识 准备工作 ...

  2. 利用 Ophis 编写 Commodore 64 programs PRG 程序(二)

    在上一节中,我们利用ophis实现了简单的hello world程序.接下来我们将进一步了解ophis的更多出色功能,它们能大大降低开发难度. 本节参考了Labels and aliases.Head ...

  3. 利用 Ophis 编写 Commodore 64 programs PRG 程序(三)

    在上一节中,我们理解了标签.别名.头文件/库以及宏定义的用法.接下来我们将看看另外两个好用的功能:字符映射与.data段 本节参考了Character maps.Local variables and ...

  4. 利用 Ophis 编写 Commodore 64 programs PRG 程序(五)

    在上一节中,我们理解了表达式和零页,接下来让我们一起来看看一些汇编代码与高级语言的对应关系:分支.循环与栈 本节参考了Structured Programming.The stack.Procedur ...

  5. Commodore 64 programs PRG 程序文件结构分析

    参考Programming with Ophis-Producing Commodore 64 programs PRG程序文件的前两个字节是一个小端序的数字,指向程序起始地址(不会拷贝入内存),接下 ...

  6. 利用C#编写一个高斯正反算程序

    一.代码界面展示 整个界面控件为tabControl,groupBox,label,textbox,comboBox,button,richTextBook. 二.代码运算结果展示 数据结果采用国家统 ...

  7. 利用Python编写一个高斯正反算程序

    一.前言 这次的高斯正反算程序是使用的Python编写的. 环境信息是:Win10.PyCharm 2021.3.1.PySide6 6.3.1.Python 3.9.9,基于QT Designer设 ...

  8. linux终端程序如何编写,[LINUX]利用Ncursesw编写支持中文的终端程序

    1. Ncursesw库的安装与使用 Ncurses库的安装(Ubuntu): 查看相关软件包 sudo apt-cache search ncursesw 安装ncursew必须软件包 sudo a ...

  9. 向串口助手发送数据c语言程序,利用DSP2812编写直流电机PID调速程序(C语言)

    ==57) { Scia_VarRx=9; } kb=Scia_VarRx[0]*1000; hd=Scia_VarRx[1]*100; de=Scia_VarRx[2]*10; un=Scia_Va ...

最新文章

  1. idea内Maven的全局配置
  2. 纯CSS实现文字一行居中,多行左对齐的方法
  3. 【BIEE】报表导出数据只显示500行,如何解决?
  4. 线程池2--创建线程
  5. Java String 中的一些函数与正则的结合使用
  6. Starling GodRay 效果实现
  7. Linux sed 批量替换多个文件中的字符串【转载】
  8. js模拟ps吸管吸取颜色功能
  9. excel如何比对两列数据是否相同
  10. easyar android 开发,【EasyAR学习】安装Android SDK
  11. python处理时间格式转换,将xxxx年xx月xx日转化为xxxx-xx-xx格式
  12. 【项目管理】如何定义开放性问题和如何在项目中跟踪开放性问题
  13. paoding 中文分词学习
  14. 常用软件开发安装包+破解分享
  15. Python 查看已安装的软件包及版本
  16. m.2槽分类_什么是M.2扩展槽,如何使用?
  17. Maven引包问题.lastUpdated
  18. 计算机二级的Word知识点,计算机二级word知识点
  19. 中国“钱”途最光明10所大学
  20. 虚函数、虚函数表、虚继承

热门文章

  1. 颈椎病10级测评表,你到哪级了?
  2. 华大HC32F460RTC时钟实验
  3. 【PyTorch深度学习项目实战100例】—— 基于逻辑回归方法完成垃圾邮件过滤任务 | 第22例
  4. 【深度学习实践】文本图片去水印
  5. 稳定同位素溯源混合模型-R
  6. matlab按图像边缘抠图_ps快速选择工具|抠图常用工具(一)
  7. ssd测试软件4k 64线程是什么意思,固态硬盘的4K和4K64跑分是什么意识
  8. python excel查找一个值出现的位置_python怎么在excel中定位数据?
  9. 铁皮石斛家庭里养殖方法 在家养殖石斛方法技巧
  10. APM-GPS数据解析之一