diff --git a/HISTORY.md b/HISTORY.md index 50cdde1..e2c2dbc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,6 +8,7 @@ History of SixtyPical be used in most places where literal values can be used. * Specifying multiple SixtyPical source files will produce a single compiled result from their combination. +* Added `nop` opcode, which compiles to `NOP` (mainly for timing.) * Rudimentary support for Atari 2600 prelude in a 4K cartridge image, and start of an example program in `eg/atari2600` directory. diff --git a/eg/atari2600/.gitignore b/eg/atari2600/.gitignore new file mode 100644 index 0000000..92ac558 --- /dev/null +++ b/eg/atari2600/.gitignore @@ -0,0 +1,2 @@ +*.bin +*.disasm.txt diff --git a/eg/atari2600/atari-2600-example.60p b/eg/atari2600/atari-2600-example.60p index 04b94a0..59d8179 100644 --- a/eg/atari2600/atari-2600-example.60p +++ b/eg/atari2600/atari-2600-example.60p @@ -26,7 +26,7 @@ byte colour @ $80 byte luminosity @ $81 byte joystick_delay @ $82 -byte table[8] image_data : "ZZZZUUUU" +byte table[8] image_data : "ZZZZUUUU" // [126, 129, 153, 165, 129, 165, 129, 126] // %01111110 // %10000001 // %10011001 @@ -89,21 +89,21 @@ define display_frame routine //; we draw it. //; - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop - //// nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop //; //; OK, *now* display the player. diff --git a/eg/atari2600/atari-2600-example.oph b/eg/atari2600/atari-2600-example.oph index 836a64a..ae33962 100644 --- a/eg/atari2600/atari-2600-example.oph +++ b/eg/atari2600/atari-2600-example.oph @@ -114,7 +114,7 @@ zero_loop: main: jsr vertical_blank jsr display_frame - jsr read_joystick + ;;; jsr read_joystick jmp main ; @@ -255,63 +255,63 @@ _image_loop: ; of the player. ; -.scope -read_joystick: - lda joystick_delay - beq _continue - - dec joystick_delay - rts - -_continue: - lda SWCHA - and #$f0 - cmp #$e0 - beq _up - cmp #$d0 - beq _down - cmp #$b0 - beq _left - cmp #$70 - beq _right - jmp _tail - -_up: - inc luminosity - jmp _tail -_down: - dec luminosity - jmp _tail -_left: - dec colour - jmp _tail -_right: - inc colour - ;jmp _tail - -_tail: - lda colour - and #$0f - sta colour - - lda luminosity - and #$0f - sta luminosity - - lda colour - clc - rol - rol - rol - rol - ora luminosity - sta COLUP0 - - lda #$06 - sta joystick_delay - - rts -.scend +;;; .scope +;;; read_joystick: +;;; lda joystick_delay +;;; beq _continue +;;; +;;; dec joystick_delay +;;; rts +;;; +;;; _continue: +;;; lda SWCHA +;;; and #$f0 +;;; cmp #$e0 +;;; beq _up +;;; cmp #$d0 +;;; beq _down +;;; cmp #$b0 +;;; beq _left +;;; cmp #$70 +;;; beq _right +;;; jmp _tail +;;; +;;; _up: +;;; inc luminosity +;;; jmp _tail +;;; _down: +;;; dec luminosity +;;; jmp _tail +;;; _left: +;;; dec colour +;;; jmp _tail +;;; _right: +;;; inc colour +;;; ;jmp _tail +;;; +;;; _tail: +;;; lda colour +;;; and #$0f +;;; sta colour +;;; +;;; lda luminosity +;;; and #$0f +;;; sta luminosity +;;; +;;; lda colour +;;; clc +;;; rol +;;; rol +;;; rol +;;; rol +;;; ora luminosity +;;; sta COLUP0 +;;; +;;; lda #$06 +;;; sta joystick_delay +;;; +;;; rts +;;; .scend ; ; Player (sprite) data. diff --git a/eg/atari2600/build.sh b/eg/atari2600/build.sh new file mode 100755 index 0000000..1f141c1 --- /dev/null +++ b/eg/atari2600/build.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +sixtypical --prelude=atari2600 atari-2600-example.60p > atari-2600-example-60p.bin +if [ "x$COMPARE" != "x" ]; then + ophis atari-2600-example.oph -o atari-2600-example.bin + dcc6502 -o 0xf000 -m 200 atari-2600-example.bin > atari-2600-example.bin.disasm.txt + dcc6502 -o 0xf000 -m 200 atari-2600-example-60p.bin > atari-2600-example-60p.bin.disasm.txt + paste atari-2600-example.bin.disasm.txt atari-2600-example-60p.bin.disasm.txt | pr -t -e24 +fi diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 3c4394b..b78cf95 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -599,6 +599,8 @@ class Analyzer(object): elif opcode == 'trash': context.set_touched(instr.dest) context.set_unmeaningful(instr.dest) + elif opcode == 'nop': + pass else: raise NotImplementedError(opcode) diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 11d2e9e..b02e717 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -18,6 +18,7 @@ from sixtypical.gen6502 import ( BCC, BCS, BNE, BEQ, JMP, JSR, RTS, SEI, CLI, + NOP, ) @@ -354,6 +355,8 @@ class Compiler(object): self.compile_copy(instr, instr.src, instr.dest) elif opcode == 'trash': pass + elif opcode == 'nop': + self.emitter.emit(NOP()) else: raise NotImplementedError(opcode) diff --git a/src/sixtypical/gen6502.py b/src/sixtypical/gen6502.py index 8659ab6..c880e18 100644 --- a/src/sixtypical/gen6502.py +++ b/src/sixtypical/gen6502.py @@ -312,6 +312,12 @@ class RTS(Instruction): } +class NOP(Instruction): + opcodes = { + Implied: 0xEA, + } + + class SBC(Instruction): opcodes = { Immediate: 0xe9, diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index 084af49..d879392 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -440,6 +440,10 @@ class Parser(object): self.scanner.scan() dest = self.locexpr() return SingleOp(self.scanner.line_number, opcode=opcode, dest=dest, src=None) + elif self.scanner.token in ("nop"): + opcode = self.scanner.token + self.scanner.scan() + return SingleOp(self.scanner.line_number, opcode=opcode, dest=None, src=None) elif self.scanner.token in ("call", "goto"): opcode = self.scanner.token self.scanner.scan() diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 2cbba37..82ad7ec 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -1010,7 +1010,7 @@ Can't `dec` a `word` type. ### cmp ### -Some rudimentary tests for cmp. +Some rudimentary tests for `cmp`. | routine main | inputs a @@ -1037,7 +1037,7 @@ Some rudimentary tests for cmp. ### and ### -Some rudimentary tests for and. +Some rudimentary tests for `and`. | routine main | inputs a @@ -1064,7 +1064,7 @@ Some rudimentary tests for and. ### or ### -Writing unit tests on a train. Wow. +Some rudimentary tests for `or`. | routine main | inputs a @@ -1091,7 +1091,7 @@ Writing unit tests on a train. Wow. ### xor ### -Writing unit tests on a train. Wow. +Some rudimentary tests for `xor`. | routine main | inputs a @@ -1118,7 +1118,7 @@ Writing unit tests on a train. Wow. ### shl ### -Some rudimentary tests for shl. +Some rudimentary tests for `shl`. | routine main | inputs a, c @@ -1146,7 +1146,7 @@ Some rudimentary tests for shl. ### shr ### -Some rudimentary tests for shr. +Some rudimentary tests for `shr`. | routine main | inputs a, c @@ -1172,6 +1172,16 @@ Some rudimentary tests for shr. | } ? UnmeaningfulReadError: c +### nop ### + +Some rudimentary tests for `nop`. + + | routine main + | { + | nop + | } + = ok + ### call ### When calling a routine, all of the locations it lists as inputs must be diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index 0021f0c..ee26696 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -18,6 +18,15 @@ Null program. | } = $080D RTS +`nop` program. + + | routine main + | { + | nop + | } + = $080D NOP + = $080E RTS + Rudimentary program. | routine main diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md index fd2b432..f4b496d 100644 --- a/tests/SixtyPical Syntax.md +++ b/tests/SixtyPical Syntax.md @@ -78,6 +78,14 @@ Trash. | } = ok +`nop`. + + | routine main + | { + | nop + | } + = ok + If with not | routine foo {