1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-26 05:48:05 +11:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Virgil Dupras
33c480a5dd avra: remove useless instrBRBits table
I had written this when trying different approaches to adding BR and
I forgot to remove it.
2019-12-14 09:41:36 -05:00
Virgil Dupras
a5efc695e9 avra: add "Rd + bit" instructions 2019-12-14 09:33:46 -05:00
Virgil Dupras
c696fcbce4 avra: add "with immediate" instructions 2019-12-14 09:05:38 -05:00
4 changed files with 126 additions and 42 deletions

View File

@ -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

View File

@ -8,11 +8,10 @@
; categories, and then alphabetically. Categories are ordered so that the 8bit
; opcodes come first, then the 16bit ones. 0xff ends the chain
instrNames:
; Branching instructions. They are all shortcuts to BRBC/BRBS. Their respective
; bits are listed in instrBRBits. These are not in alphabetical order, but
; rather in "bit order". All "bit set" instructions first (10th bit clear), then
; all "bit clear" ones (10th bit set). Inside this order, they're then in "sss"
; order (bit number alias for BRBC/BRBS)
; Branching instructions. They are all shortcuts to BRBC/BRBS. These are not in
; alphabetical order, but rather in "bit order". All "bit set" instructions
; first (10th bit clear), then all "bit clear" ones (10th bit set). Inside this
; order, they're then in "sss" order (bit number alias for BRBC/BRBS).
.db "BRCS", 0
.db "BREQ", 0
.db "BRMI", 0
@ -32,7 +31,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 +46,21 @@ 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
.equ I_BLD 38
.db "BLD", 0
.db "BST", 0
.db "SBRC", 0
.db "SBRS", 0
; no arg (from here, instrUpMasks2)
.equ I_BREAK 42
.db "BREAK", 0
.db "CLC", 0
.db "CLH", 0
@ -76,7 +88,7 @@ instrNames:
.db "SLEEP", 0
.db "WDR", 0
; Rd(5)
.equ I_ASR 57
.equ I_ASR 68
.db "ASR", 0
.db "COM", 0
.db "DEC", 0
@ -111,6 +123,20 @@ instrUpMasks1:
.db 0b00101000 ; OR
.db 0b00001000 ; SBC
.db 0b00011000 ; SUB
; Rd(4) + 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
; Rd(5) + bit: XXXXXXXd ddddXbbb: lonely bit in LSB is 0 in all cases, so we
; ignore it.
.db 0b11111000 ; BLD
.db 0b11111010 ; BST
.db 0b11111100 ; SBRC
.db 0b11111110 ; SBRS
; 16-bit constant masks associated with each instruction. In the same order as
; in instrNames
@ -158,25 +184,6 @@ instrUpMasks2:
.db 0b10010100, 0b00000010 ; SWAP
.db 0b10010010, 0b00000100 ; XCH
instrBRBits:
; 1st bit is 3rd bit of MSB and the other 3 are the lower bits of LSB
.db 0b0000 ; BRCS
.db 0b0001 ; BREQ
.db 0b0010 ; BRMI
.db 0b0011 ; BRVS
.db 0b0100 ; BRLT
.db 0b0101 ; BRHS
.db 0b0110 ; BRTS
.db 0b0111 ; BRIE
.db 0b1000 ; BRCC
.db 0b1001 ; BRNE
.db 0b1010 ; BRPL
.db 0b1011 ; BRVC
.db 0b1100 ; BRGE
.db 0b1101 ; BRHC
.db 0b1110 ; BRTC
.db 0b1111 ; BRID
; Same signature as getInstID in instr.asm
; Reads string in (HL) and returns the corresponding ID (I_*) in A. Sets Z if
; there's a match.
@ -215,24 +222,29 @@ getInstID:
parseInstruction:
; BC, during .spit, is ORred to the spitted opcode.
ld bc, 0
; Save Instr ID in D, which is less volatile than A. In almost all
; cases, we fetch the opcode constant at the end of the processing.
ld d, a
cp I_ADC
jp c, .BR
cp I_BREAK
cp I_ANDI
jr c, .spitRd5Rr5
cp I_BLD
jr c, .spitRdK8
cp I_BREAK
jr c, .spitRdBit
cp I_ASR
jr c, .spitNoArg
; spitRd5
ld d, a ; save A for later
call .readR5
ret nz
call .placeRd
ld a, d ; restore A
; continue to .spitNoArg
.spitNoArg:
call .getUp2
jr .spit
.spitRd5Rr5:
ld d, a ; save A for later
call .readR5
ret nz
call .placeRd
@ -251,10 +263,49 @@ parseInstruction:
rra \ rra \ rra
or b
ld b, a
ld a, d ; restore A
call .getUp1
; now that's our MSB
jr .spitMSB
.spitRdK8:
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
call .getUp1
jr .spitMSB
.spitRdBit:
call .readR5
ret nz
call .placeRd
call readComma
ret nz
call .readBit
ret nz
; LSB is in A and is ready to go
call ioPutB
call .getUp1
jr .spitMSB
.spit:
; LSB is spit *before* MSB
inc hl
@ -329,13 +380,8 @@ parseInstruction:
; upcode becomes 0b111101
inc b
.rdBRBS:
call readWord
call .readBit
ret nz
call parseExpr
ld a, 7
call .IX2A
ret nz
ld c, a
call readComma
ret nz
jr .spitBR2
@ -349,19 +395,30 @@ parseInstruction:
ld c, a
ret
; Fetch a 8-bit upcode specified by instr index in A and set that upcode in HL
; Fetch a 8-bit upcode specified by instr index in D and set that upcode in HL
.getUp1:
ld a, d
sub I_ADC
ld hl, instrUpMasks1
jp addHL
; Fetch a 16-bit upcode specified by instr index in A and set that upcode in HL
; Fetch a 16-bit upcode specified by instr index in D and set that upcode in HL
.getUp2:
ld a, d
sub I_BREAK
sla a ; A * 2
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 +433,18 @@ parseInstruction:
ld a, 31
jr .IX2A
.readBit:
call readWord
ret nz
call parseExpr
ld a, 7
call .IX2A
ret nz
or c
ld c, a
cp a ; ensure Z
ret
; Put IX's LSB into A and, additionally, ensure that the new value is <=
; than what was previously in A.
; Z for success.

View File

@ -7,3 +7,5 @@ breq bar
asr r20
bar:
brbs 6, foo
ori r22, 0x34+4
sbrs r1, 3

View File

@ -1 +1 @@
<08><><EFBFBD><EFBFBD><EFBFBD> <09>E<EFBFBD><45><EFBFBD>
<08><><EFBFBD><EFBFBD><EFBFBD> <09>E<EFBFBD><45><EFBFBD>hc<13>