commit 5bb56a54a36d6ec42148e3ea26e4a82d458356a0 Author: matthias@arch Date: Sat Dec 9 23:24:28 2023 +0100 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..648d67a --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# vim-ca6502 Support for the ca65 assembler +This plugin provides syntax highlighting, convenience functions and help pages for the ca65 assembler. +It is focused on the 65C02 processor, please open an issue/a pull request if you find anything that is missing. + +By default, the plugin loads for files having a `.s65` or `.h65` extension. +To load it for your preferred extension, write this into `~/.vim/ftdetect/ca6502.vim`: + + " in ~/.vim/ftdetect/ca6502.vim + au BufRead,BufNewFile *.myExtension setfiletype ca6502 + + +## Syntax +The syntax highlighting currently supports the 65C02 opcodes, the ca65 assembler functions +and the macro packs `generic` and `longbranch`. + +If the labels and instructions have the same color in your colorscheme, +link `ca65Opcode` or `ca65Label` to another class, eg: `hi link ca65Label Typedef`. + +## Convenience +This plugin provides the `b:match_words` variable for jumping between words. +Supported are the assembler commands like `.if` `.endif`, `.macro` `.endmacro` as well as stack instructions. +This allows for easier checking of stack push/pull order. + + +There is also a function that opens a header/source file with the same name in a vsplit. +For example if `~/project/main.s65` is opened, `~/project/main.h65` would be opened. +To use it, map it and set your preferred assembly filetypes. + + " in ~/.vim/ftplugin/ca6502.vim (or vimrc) + nnoremap h :call SplitHeader("h65", "s65") + +## Help +I compiled the datasheet of the WDC 65C02 into a vim help page. +Type `:help ` to see info about the opcode (addressing modes, updated flags...). diff --git a/doc/ca6502.txt b/doc/ca6502.txt new file mode 100644 index 0000000..d8b4d11 --- /dev/null +++ b/doc/ca6502.txt @@ -0,0 +1,42 @@ +*ca6502.txt* ca65 + 65C02 + +CONTENTS +Instruction list |ca6502-instructions| + ADC |ca6502-adc| +Addressing modes |ca6502-addressing-modes| +Status flags |ca6502-status-flags| + + +============================================================================== + +This help file provides information on the ca6502 processor instructions. +You can jump to each instruction by using the corresponding keyword. + +============================================================================== +INSTRUCTIONS *ca6502-instructions* +------------------------------------------------------------------------------ +ADC *ca6502-adc* +Add with Carry~ + A + M + C -> A `N V - - - - Z C` |ca6502-status-flags| + +Addressing Modes~ + a a,x a,y # zp (zp,x) zp,x (zp) (zp),y |ca6502-addresing-modes| +------------------------------------------------------------------------------ +AND *ca6502-and* +Add with Carry~ + A ^ M -> A ` N - - - - - Z -` |ca6502-status-flags| + +Addressing Modes~ + a a,x a,y # zp (zp,x) zp,x (zp) (zp),y |ca6502-addresing-modes| + +============================================================================== +ADDRESSING MODES *ca6502-addressing-modes* + +============================================================================== +Status flags *ca6502-status-flags* + +Use the following commands to navigate this help file: + +:help ADC Jump to the Add with Carry instruction +============================================================================== +vim:tw=78:sta:noet:ts=8:sts=0:ft=help:fen: diff --git a/doc/opcodes b/doc/opcodes new file mode 100644 index 0000000..cf69e01 --- /dev/null +++ b/doc/opcodes @@ -0,0 +1,81 @@ +load and store +LDA load accumulator with memory NZ +LDX load X register with memory NZ +LDY load Y register with memory NZ +STA STore Accumulator in memory - +STX STore X register in memory - +STY STore Y register in memory - +STZ store zero in memory - +Stack Operations +PHA push accumulator on stack - +PHX push X register on stack - +PHY push Y register on stack - +PHP push processor status on stack - +PLA pull accumulator from stack NZ +PLX pull X register from stack NZ +PLY pull Y register from stack NZ +PLP pull processor status from stack All +TSX transfer the stack pointer to the X register NZ +TXS transfer the X register to the stack pointer register - +Increment & Decrement Operations +INX increment X register by one NZ +INY increment Y register by one NZ +DEX decrement X register by one NZ +DEY decrement Y register by one NZ +INC increment memory or accumulator by one NZ +DEC decrement memory or accumulator by one NZ +Shift Operations +ASL arithmetic shift one bit left, memory or accumulator NZC +LSR logical shift one bit right, memory or accumulator N=0 ZC +ROL rotate one bit left memory or accumulator NZC +ROR rotate one bit right memory or accumulator NZC +Logical Operations +AND and accumulator with memory NZ +ORA or accumulator with memory NZ +EOR exclusive-or accumulator with memory NZ +BIT BIt Test N=M7 V=M6 Z +CMP compare accumulator with memory NZC +CPX compare X register with memory NZC +CPY compare Y register with memory NZC +TRB Test and Reset memory Bit x +TSB Test and Set memory Bit x +RMB reset memory bit x +SMB set memory bit x +Math Operations +ADC add memory to accumulator with carry NZCV +SBC subtract memory accumulator, with borrow (carry bit) NZCV +Flow Control Instructions +JMP jump to new location - +JSR jump to Subroutine - +RTS return from Subroutine - +RTI return from Interrupt +BRA branch Always - +BEQ branch if equal (Z == 0) - +BNE branch if not equal (Z == 1) - +BCC branch if carry clear (C == 0) - +BCS branch if carry set (C == 1) - +BVC branch if overflow clear (V == 0) - +BVS branch if overflow set (V == 1) - +BMI branch if minus (N == 1) - +BPL branch if plus (N == 0) - +BBR branch if bit reset - +BBS branch if bit set - +Processor Status Instructions +CLC clear carry flag C=0 +CLD clear decimal mode D=0 +CLI clear interrupt disable bit I=0 +CLV clear overflow flag V=0 +SEC set carry flag C=1 +SED set decimal mode D=1 +SEI set interrupt disable bit I=1 +Transfer Instructions +TAX transfer accumulator to X register NZ +TAY transfer accumulator to Y register NZ +TXA transfer X register to accumulator NZ +TYA transfer Y register to accumulator NZ +Misc Instructions +NOP no operation - +BRK break instruction B=1 +Interrupt +wai wait for interrupt +stp stop mode diff --git a/doc/tags b/doc/tags new file mode 100644 index 0000000..8f01373 --- /dev/null +++ b/doc/tags @@ -0,0 +1,6 @@ +ca6502-adc ca6502.txt /*ca6502-adc* +ca6502-addressing-modes ca6502.txt /*ca6502-addressing-modes* +ca6502-and ca6502.txt /*ca6502-and* +ca6502-instructions ca6502.txt /*ca6502-instructions* +ca6502-status-flags ca6502.txt /*ca6502-status-flags* +ca6502.txt ca6502.txt /*ca6502.txt* diff --git a/ftdetect/ca6502.vim b/ftdetect/ca6502.vim new file mode 100644 index 0000000..8efc561 --- /dev/null +++ b/ftdetect/ca6502.vim @@ -0,0 +1,2 @@ +au BufRead,BufNewFile *.h65 setfiletype ca6502 +au BufRead,BufNewFile *.s65 setfiletype ca6502 diff --git a/ftplugin/ca6502.vim b/ftplugin/ca6502.vim new file mode 100644 index 0000000..c28379a --- /dev/null +++ b/ftplugin/ca6502.vim @@ -0,0 +1,22 @@ +if !exists("*SplitHeader") + function! SplitHeader(header_ext, source_ext) + " check which filetype and then open header/source in vsplit + if (expand("%:e") == a:source_ext) + execute "vsplit %:r.".a:header_ext + elseif (expand("%:e") == a:header_ext) + execute "vsplit %:r.".a:source_ext + :exe "normal \r" + endif + endfunction +endif + +" navigation with % using matchit plugin +let b:match_words = '\:\,' + \ . '\.\:\.\:\.\:\.\,' + \ . '\.\:\.\,' + \ . '\.\:\.\,' + \ . '\.\:\.\,' + \ . '\.\:\.\,' + \ . '\.\:\.\,' + \ . '\.\:\.\,' + \ . '\.\:\.\' diff --git a/syntax/ca6502.vim b/syntax/ca6502.vim new file mode 100644 index 0000000..4013d38 --- /dev/null +++ b/syntax/ca6502.vim @@ -0,0 +1,111 @@ +" Vim syntax file +" Language: ca65: (MOS 65C02 assembler +" Maintainer: Matthias Quintern +" Latest Revision: December 2023 +" Originally by: Oyd E. Leven (2005) + +if exists("b:current_syntax") + finish +endif + +" Remove any old syntax stuff hanging about +syn clear +syn case ignore +syntax iskeyword @,48-57,192-255,$,_,.,* + +" custom macros +syn keyword customMacros Import Export Print Strf div + +" registers +syn keyword ca65Reg x y a + +" ******************************************************************************** +" OPCODES +" keywords that are used in regions will not be defined here +" ******************************************************************************** +" 650x +" ******************************************************************************** +syn keyword ca6502Opcode adc and asl bit brk clc cld cli clv cmp cpx cpy dec dex dey eor inc inx iny lda ldx ldy lsr nop ora pha php pla plp rol ror rti rts sbc sec sed sei sta stx sty tax tay tsx txa txs tya +syn region ca65BranchTarget matchgroup=ca6502Opcode start="\v(bcc|bcs|beq|bmi|bne|bpl|bvc|bvs|jmp|jsr)[ \t]+" end="$" contains=ca65Comment keepend + +" ******************************************************************************** +" Atari 800XL 'Sally' undocumented opcodes +" mnemonics taken from Trevin Beattie's 'Atari Technical Information' page +" at "http://www.xmission.com/~trevin/atari/atari.shtml" +" ******************************************************************************** +" syn keyword ca65SallyUndoc anc arr asr asx ax7 axe brk dcp jam las lax php rla rra sax slo sre sx7 sy7 xea xs7 + +" ******************************************************************************** +" 65C02 +" ******************************************************************************** +syn keyword ca65C02Opcode phx phy plx ply stz trb tsb stp wai +syn match ca65C02Opcode "bb[rs][0-7]" +syn region ca65i65C02BranchTarget matchgroup=ca65C02Opcode start="\(bra \)" end="$" contains=ca65Comment keepend +syn match ca65BitSetBranchTarget "\v(bb[rs][0-7][ \t]+[^,]+,[ \t]*)@<=[^;]+" + +" ******************************************************************************** +" ASSEMBLER +" ******************************************************************************** +syn match ca65Label "\v^\.?[a-z_][a-z0-9_]*:" +syn match ca65CheapLabel "^@[a-z_][a-z0-9_]*:" +syn match ca65UnnamedLabel "^:" +syn match ca65Comment ";.*" contains=ca65Todo +syn keyword ca65Todo contained todo fixme xxx warning danger note notice bug +syn region ca65String start=+"+ skip=+\\"+ end=+"+ +syn match ca65Char "'.'" + +syn match decNumber "\<\d\+\>" +syn match hexNumber "\$\x\+\>" " 'bug', but adding \< doesn't behave! +syn match binNumber "%[01]\+\>" +" syn region ca65Immediate start="\v((adc|and|bit|cmp|cpx|cpy|eor|lda|ldx|ldy|ora|sbc) +)@<=#" end="$" contains=ca65Comment,hexNumber,decNumber,binNumber,ca65Char,ca65Expression +syn match ca65Immediate "\v((adc|and|bit|cmp|cpx|cpy|eor|lda|ldx|ldy|ora|sbc)[ \t]+)@<=#" +" ******************************************************************************** +" ca65 +" ******************************************************************************** +syn keyword ca65ControlCommands .a16 .a8 .addr .align .asciiz .assert .autoimport .bankbytes .bss .byt .byte .case .charmap .code .condes .constructor .data .dbyt .debuginfo .define .delmac .delmacro .destructor .dword .else .elseif .end .endenum .endif .endmac .endmacro .endproc .endrep .endrepeat .endscope .endstruct .endunion .enum .error .exitmac .exitmacro .export .exportzp .faraddr .fatal .feature .fileopt .fopt .forceimport .global .globalzp .hibytes .i16 .i8 .if .ifblank .ifconst .ifdef .ifnblank .ifndef .ifnref .ifp02 .ifp4510 .ifp816 .ifpc02 .ifpdtv .ifpsc02 .ifref .import .importzp .incbin .include .interruptor .linecont .list .listbytes .literal .lobytes .local .localchar .macpack .mac .macro .org .out .p02 .p4510 .p816 .pagelen .pagelength .pc02 .pdtv .popcharmap .popcpu .popseg .psc02 .pushcharmap .pushcpu .pushseg .referto .refto .reloc .repeat .res .rodata .scope .segment .set .setcpu .smart .struct .tag .undef .undefine .union .warning .word .zeropage +syn keyword ca65PseudoVariables * .asize .cpu .isize .paramcount .time .version +syn keyword ca65PseudoFunctions .addrsize .bank .bankbyte .blank .concat .const .def,.defined .definedmacro .hibyte .hiword .ident .ismnem,.ismnemonic .left .lobyte .loword .match .max .mid .min .ref,.referenced .right .sizeof .sprintf .strat .string .strlen .tcount .xmatch +syn region ca65ProcLabel matchgroup=ca65ControlCommands start="\(\.proc\)" end="$" contains=ca65Comment keepend +" macro packs +syn region ca65MacLongbranchTarget matchgroup=ca65MacLongbranch start="\v(jcc|jcs|jeq|jmi|jne|jpl|jvc)[ \t]+" end="$" contains=ca65Comment keepend +syn region ca65MacGenericBranchTarget matchgroup=ca65MacGeneric start="\v(bge|blt|bgt|ble|bnz|bze)[ \t]+" end="$" contains=ca65Comment keepend + +" The default methods for highlighting. Can be overridden later +" LABELS: +hi link ca65CheapLabel ca65Label +hi link ca65UnnamedLabel ca65Label +hi link ca65BranchTarget ca65Label +hi link ca65i65C02BranchTarget ca65Label +hi link ca65BitSetBranchTarget ca65Label +hi link ca65ProcLabel ca65Label +hi link ca65MacLongbranchTarget ca65Label +hi link ca65MacGenericBranchTarget ca65Label +hi link ca65Label Label +" TYPES +hi link ca65String String +hi link ca65Char Character +hi link ca65Comment Comment +hi link hexNumber Number +hi link binNumber Number +hi link decNumber Number +" ASSEMBLER FUNCTIONS / MACROS +hi link ca65PseudoVariables PreProc +hi link ca65PseudoFunctions PreProc +hi link ca65ControlCommands PreProc +hi link ca65MacLongbranch PreProc +hi link ca65MacGeneric PreProc +hi link customMacros PreProc +" INSTRUCTIONS +hi link ca6502Opcode ca65Opcode +hi link ca65C02Opcode ca65Opcode +hi link ca65Opcode Statement +hi link ca65SallyUndoc Special + +hi link ca65Reg Identifier +hi link ca65Todo Todo + +hi link ca65Immediate Special +" hi link ca65Expression Special + + +let b:current_syntax = "ca65"