1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-12-24 14:18:06 +11:00

zasm: add support for relative labels

This commit is contained in:
Virgil Dupras 2019-05-12 22:07:21 -04:00
parent 1e3982d3ab
commit 878bc2919f
7 changed files with 77 additions and 13 deletions

View File

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

View File

@ -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
apps/zasm/tests/test2.asm Normal file
View File

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

View File

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

View File

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

View File

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

View File

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