浏览代码

zasm: add support for relative labels

pull/10/head
Virgil Dupras 5 年前
父节点
当前提交
878bc2919f
共有 7 个文件被更改,包括 77 次插入13 次删除
  1. +45
    -10
      apps/zasm/instr.asm
  2. +1
    -0
      apps/zasm/main.asm
  3. +11
    -0
      apps/zasm/tests/test2.asm
  4. +12
    -0
      apps/zasm/util.asm
  5. +3
    -0
      tools/emul/zasm.c
  6. +1
    -0
      tools/emul/zasm_glue.asm
  7. +4
    -3
      tools/emul/zasm_user.asm

+ 45
- 10
apps/zasm/instr.asm 查看文件

@@ -615,22 +615,57 @@ getUpcode:
ld c, 1
jr .computeBytesWritten
.withByte:
; verify that the MSB in argument is zero
inc hl
; HL points to our number (LSB), with (HL+1) being our MSB which should
; normally by zero. However, if our instruction is jr or djnz, that
; number is actually a 2-bytes address that has to be relative to PC,
; so it's a special case. Let's check for this special case.
bit 7, (ix+3)
jr z, .absoluteValue ; bit not set? regular byte value,
; Our argument is a relative address ("e" type in djnz and jr). We have
; to subtract (curOutputOffset) from it.

; First, check whether we're on first pass. If we are, skip processing
; below because not having real symbol value makes relative address
; verification falsely fail.
ld c, 2 ; this is a two bytes instruction
call zasmIsFirstPass
jr z, .computeBytesWritten

; We're on second pass
push de ; Don't let go of this, that's our dest
ld de, (curOutputOffset)
call JUMP_INTOHL
dec hl ; what we write is "e-2"
dec hl
call subDEFromHL
pop de ; Still have it? good
; HL contains our number and we'll check its bounds. If It's negative,
; H is going to be 0xff and L has to be >= 0x80. If it's positive,
; H is going to be 0 and L has to be < 0x80.
ld a, l
cp 0x80
jr c, .skipHInc ; a < 0x80, H is expected to be 0
; A being >= 0x80 is only valid in cases where HL is negative and
; within bounds. This only happens is H == 0xff. Let's increase it to 0.
inc h
.skipHInc:
; Let's write our value now even though we haven't checked our bounds
; yet. This way, we don't have to store A somewhere else.
ld (de), a
ld a, h
or a ; cp 0
jr nz, .numberTruncated ; if A is anything but zero, we're out
; of bounds.
jr .computeBytesWritten

.absoluteValue:
; verify that the MSB in argument is zero
inc hl ; MSB is 2nd byte
ld a, (hl)
dec hl ; HL now points to LSB
or a ; cp 0
jr nz, .numberTruncated
; HL points to our number
; one last thing to check. Is the 7th bit on the displacement value set?
; if yes, we have to decrease our value by 2. Uses for djnz and jr.
bit 7, (ix+3)
jr z, .skipDecrease
; Yup, it's set.
dec (hl)
dec (hl)
.skipDecrease:
ldi
ld c, 2
jr .computeBytesWritten


+ 1
- 0
apps/zasm/main.asm 查看文件

@@ -25,6 +25,7 @@
; JUMP_UPCASE
; JUMP_UNSETZ
; JUMP_INTODE
; JUMP_INTOHL
; JUMP_FINDCHAR
; JUMP_BLKSEL
; RAMSTART (where we put our variables in RAM)


+ 11
- 0
apps/zasm/tests/test2.asm 查看文件

@@ -0,0 +1,11 @@
; Test relative jumps
label1:
jp label1
jp label2
jp label2
jr label2
jr nc, label1

label2:
jr label1
jr nc, label1

+ 12
- 0
apps/zasm/util.asm 查看文件

@@ -22,6 +22,18 @@ cpHLDE:
cp e
ret ; flags are correct

; HL - DE -> HL
subDEFromHL:
push af
ld a, l
sub e
ld l, a
ld a, h
sbc d
ld h, a
pop af
ret

; Returns length of string at (HL) in A.
strlen:
push bc


+ 3
- 0
tools/emul/zasm.c 查看文件

@@ -33,6 +33,7 @@
#define STDIN_BUFSIZE 0x8000
// When defined, we dump memory instead of dumping expected stdout
//#define MEMDUMP
//#define DEBUG

static Z80Context cpu;
static uint8_t mem[0x10000];
@@ -119,7 +120,9 @@ int main()
}
#endif
fflush(stdout);
#ifdef DEBUG
fprintf(stderr, "Ended with A=%d DE=%d\n", cpu.R1.br.A, cpu.R1.wr.DE);
#endif
return 0;
}


+ 1
- 0
tools/emul/zasm_glue.asm 查看文件

@@ -12,6 +12,7 @@ jp addHL
jp upcase
jp unsetZ
jp intoDE
jp intoHL
jp findchar
jp parseHexPair
jp blkSel


+ 4
- 3
tools/emul/zasm_user.asm 查看文件

@@ -5,9 +5,10 @@ JUMP_ADDHL .equ 0x08
JUMP_UPCASE .equ 0x0b
JUMP_UNSETZ .equ 0x0e
JUMP_INTODE .equ 0x11
JUMP_FINDCHAR .equ 0x14
JUMP_PARSEHEXPAIR .equ 0x17
JUMP_BLKSEL .equ 0x1a
JUMP_INTOHL .equ 0x14
JUMP_FINDCHAR .equ 0x17
JUMP_PARSEHEXPAIR .equ 0x1a
JUMP_BLKSEL .equ 0x1d

.equ USER_CODE 0x4800
.equ RAMSTART 0x5800


正在加载...
取消
保存