diff --git a/apps/zasm/README.md b/apps/zasm/README.md index 7b3f35d..89b4d30 100644 --- a/apps/zasm/README.md +++ b/apps/zasm/README.md @@ -178,4 +178,17 @@ arguments are separated by commas. To assemble an AVR assembler, use the `gluea.asm` file instead of the regular one. +Note about AVR and PC: In most assemblers, arithmetics for instructions +addresses have words (two bytes) as their basic unit because AVR instructions +are either 16bit in length or 32bit in length. All addresses constants in +upcodes are in words. However, in zasm's core logic, PC is in bytes (because z80 +upcodes can be 1 byte). + +The AVR assembler, of course, correctly translates byte PCs to words when +writing upcodes, however, when you write your expressions, you need to remember +to treat with bytes. For example, in a traditional AVR assembler, jumping to +the instruction after the "foo" label would be "rjmp foo+1". In zasm, it's +"rjmp foo+2". If your expression results in an odd number, the low bit of your +number will be ignored. + [libz80]: https://github.com/ggambetta/libz80 diff --git a/apps/zasm/avr.asm b/apps/zasm/avr.asm index cd84c72..c979322 100644 --- a/apps/zasm/avr.asm +++ b/apps/zasm/avr.asm @@ -32,7 +32,7 @@ instrNames: .equ I_BRBS 16 .db "BRBS", 0 .db "BRBC", 0 -; Rd(5) + Rr(5) +; Rd(5) + Rr(5) (from here, instrUpMasks1) .equ I_ADC 18 .db "ADC", 0 .db "ADD", 0 @@ -47,8 +47,16 @@ instrNames: .db "OR", 0 .db "SBC", 0 .db "SUB", 0 -; no arg -.equ I_BREAK 31 +.equ I_ANDI 31 +.db "ANDI", 0 +.db "CPI", 0 +.db "LDI", 0 +.db "ORI", 0 +.db "SBCI", 0 +.db "SBR", 0 +.db "SUBI", 0 +; no arg (from here, instrUpMasks2) +.equ I_BREAK 38 .db "BREAK", 0 .db "CLC", 0 .db "CLH", 0 @@ -76,7 +84,7 @@ instrNames: .db "SLEEP", 0 .db "WDR", 0 ; Rd(5) -.equ I_ASR 57 +.equ I_ASR 64 .db "ASR", 0 .db "COM", 0 .db "DEC", 0 @@ -111,6 +119,14 @@ instrUpMasks1: .db 0b00101000 ; OR .db 0b00001000 ; SBC .db 0b00011000 ; SUB +; Rd(5) + K(8): XXXXKKKK ddddKKKK +.db 0b01110000 ; ANDI +.db 0b00110000 ; CPI +.db 0b11100000 ; LDI +.db 0b01100000 ; ORI +.db 0b01000000 ; SBCI +.db 0b01100000 ; SBR +.db 0b01010000 ; SUBI ; 16-bit constant masks associated with each instruction. In the same order as ; in instrNames @@ -217,8 +233,10 @@ parseInstruction: ld bc, 0 cp I_ADC jp c, .BR - cp I_BREAK + cp I_ANDI jr c, .spitRd5Rr5 + cp I_BREAK + jr c, .spitRdK8 cp I_ASR jr c, .spitNoArg ; spitRd5 @@ -231,6 +249,7 @@ parseInstruction: .spitNoArg: call .getUp2 jr .spit + .spitRd5Rr5: ld d, a ; save A for later call .readR5 @@ -255,6 +274,36 @@ parseInstruction: call .getUp1 ; now that's our MSB jr .spitMSB + +.spitRdK8: + ld d, a ; save A for later + call .readR4 + ret nz + call .placeRd + call readComma + call readWord + call parseExpr + ret nz + ld a, c + ld a, 0xff + call .IX2A + ret nz + push af ; --> lvl 1 + ; let's start with the 4 lower bits + and 0xf + or c + ; We now have our LSB in A. Let's spit it now. + call ioPutB + pop af ; <-- lvl 1 + ; and now those high 4 bits + and 0xf0 + rra \ rra \ rra \ rra + ld b, a + ld a, d ; restore A + call .getUp1 + ; now that's our MSB + jr .spitMSB + .spit: ; LSB is spit *before* MSB inc hl @@ -362,6 +411,15 @@ parseInstruction: ld hl, instrUpMasks2 jp addHL +.readR4: + call .readR5 + ret nz + ; has to be in the 16-31 range + sub 0x10 + jp c, unsetZ + cp a ; ensure Z + ret + ; read a rXX argument and return register number in A. ; Set Z for success. .readR5: @@ -376,6 +434,7 @@ parseInstruction: ld a, 31 jr .IX2A + ; Put IX's LSB into A and, additionally, ensure that the new value is <= ; than what was previously in A. ; Z for success. diff --git a/tools/tests/avra/test1.asm b/tools/tests/avra/test1.asm index 64a5a30..1f292f7 100644 --- a/tools/tests/avra/test1.asm +++ b/tools/tests/avra/test1.asm @@ -7,3 +7,4 @@ breq bar asr r20 bar: brbs 6, foo +ori r22, 0x34+4 diff --git a/tools/tests/avra/test1.expected b/tools/tests/avra/test1.expected index f7f53cf..30d6657 100644 --- a/tools/tests/avra/test1.expected +++ b/tools/tests/avra/test1.expected @@ -1 +1 @@ -•ˆ•˜• πE•ήσ \ No newline at end of file +•ˆ•˜• πE•ήσhc \ No newline at end of file