mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 10:18:05 +11:00
zasm: add support for ".db" directive
This commit is contained in:
parent
28e1ba5e26
commit
dde5161fc1
@ -9,6 +9,27 @@ D_BAD .equ 0xff
|
|||||||
directiveNames:
|
directiveNames:
|
||||||
.db ".DB", 0
|
.db ".DB", 0
|
||||||
|
|
||||||
|
; This is a list of handlers corresponding to indexes in directiveNames
|
||||||
|
directiveHandlers:
|
||||||
|
.dw handleDB
|
||||||
|
|
||||||
|
handleDB:
|
||||||
|
push de
|
||||||
|
push hl
|
||||||
|
call toWord
|
||||||
|
ld de, scratchpad
|
||||||
|
ld a, 8
|
||||||
|
call readWord
|
||||||
|
ld hl, scratchpad
|
||||||
|
call parseNumber
|
||||||
|
ld a, ixl
|
||||||
|
ld (direcData), a
|
||||||
|
ld a, 1
|
||||||
|
pop hl
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
; Reads string in (HL) and returns the corresponding ID (D_*) in A. Sets Z if
|
; Reads string in (HL) and returns the corresponding ID (D_*) in A. Sets Z if
|
||||||
; there's a match.
|
; there's a match.
|
||||||
getDirectiveID:
|
getDirectiveID:
|
||||||
@ -22,6 +43,21 @@ getDirectiveID:
|
|||||||
pop bc
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; Parse directive specified in A (D_* const) with args in (HL) and act in
|
||||||
|
; an appropriate manner. If the directive results in writing data at its
|
||||||
|
; current location, that data is in (direcData) and A is the number of bytes
|
||||||
|
; in it.
|
||||||
parseDirective:
|
parseDirective:
|
||||||
xor a
|
push de
|
||||||
ret
|
; double A to have a proper offset in directiveHandlers
|
||||||
|
add a, a
|
||||||
|
ld de, directiveHandlers
|
||||||
|
call JUMP_ADDDE
|
||||||
|
ld ixh, d
|
||||||
|
ld ixl, e
|
||||||
|
pop de
|
||||||
|
jp (ix)
|
||||||
|
|
||||||
|
; *** Variables ***
|
||||||
|
direcData:
|
||||||
|
.fill 2
|
||||||
|
@ -8,5 +8,5 @@ libz80/libz80.o: libz80/z80.c
|
|||||||
kernel.h: glue.asm
|
kernel.h: glue.asm
|
||||||
scas -o - -I ../../../parts/z80 $< | ./bin2c.sh KERNEL | tee $@ > /dev/null
|
scas -o - -I ../../../parts/z80 $< | ./bin2c.sh KERNEL | tee $@ > /dev/null
|
||||||
|
|
||||||
zasm.h: $(addprefix ../, main.asm instr.asm tok.asm util.asm)
|
zasm.h: $(addprefix ../, main.asm instr.asm directive.asm tok.asm literal.asm util.asm)
|
||||||
scas -o - -I.. $< | ./bin2c.sh ZASM | tee $@ > /dev/null
|
scas -o - -I.. $< | ./bin2c.sh ZASM | tee $@ > /dev/null
|
||||||
|
@ -89,66 +89,6 @@ getInstID:
|
|||||||
pop bc
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
|
|
||||||
; result in A.
|
|
||||||
;
|
|
||||||
; On success, the carry flag is reset. On error, it is set.
|
|
||||||
parseDecimal:
|
|
||||||
; First, let's see if we have an easy 0-9 case
|
|
||||||
cp '0'
|
|
||||||
ret c ; if < '0', we have a problem
|
|
||||||
cp '9'+1
|
|
||||||
; We are in the 0-9 range
|
|
||||||
sub a, '0' ; C is clear
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Parses the string at (HL) and returns the 16-bit value in IX.
|
|
||||||
; As soon as the number doesn't fit 16-bit any more, parsing stops and the
|
|
||||||
; number is invalid. If the number is valid, Z is set, otherwise, unset.
|
|
||||||
parseNumber:
|
|
||||||
push hl
|
|
||||||
push de
|
|
||||||
push bc
|
|
||||||
|
|
||||||
ld ix, 0
|
|
||||||
.loop:
|
|
||||||
ld a, (hl)
|
|
||||||
cp 0
|
|
||||||
jr z, .end ; success!
|
|
||||||
call parseDecimal
|
|
||||||
jr c, .error
|
|
||||||
|
|
||||||
; Now, let's add A to IX. First, multiply by 10.
|
|
||||||
ld d, ixh ; we need a copy of the initial copy for later
|
|
||||||
ld e, ixl
|
|
||||||
add ix, ix ; x2
|
|
||||||
add ix, ix ; x4
|
|
||||||
add ix, ix ; x8
|
|
||||||
add ix, de ; x9
|
|
||||||
add ix, de ; x10
|
|
||||||
add a, ixl
|
|
||||||
jr nc, .nocarry
|
|
||||||
inc ixh
|
|
||||||
.nocarry:
|
|
||||||
ld ixl, a
|
|
||||||
|
|
||||||
; We didn't bother checking for the C flag at each step because we
|
|
||||||
; check for overflow afterwards. If ixh < d, we overflowed
|
|
||||||
ld a, ixh
|
|
||||||
cp d
|
|
||||||
jr c, .error ; carry is set? overflow
|
|
||||||
|
|
||||||
inc hl
|
|
||||||
jr .loop
|
|
||||||
|
|
||||||
.error:
|
|
||||||
call JUMP_UNSETZ
|
|
||||||
.end:
|
|
||||||
pop bc
|
|
||||||
pop de
|
|
||||||
pop hl
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Parse the string at (HL) and check if it starts with IX+, IY+, IX- or IY-.
|
; Parse the string at (HL) and check if it starts with IX+, IY+, IX- or IY-.
|
||||||
; Sets Z if yes, unset if no.
|
; Sets Z if yes, unset if no.
|
||||||
parseIXY:
|
parseIXY:
|
||||||
@ -450,13 +390,13 @@ handleJPIX:
|
|||||||
handleJPIY:
|
handleJPIY:
|
||||||
ld a, 0xfd
|
ld a, 0xfd
|
||||||
handleJPIXY:
|
handleJPIXY:
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
ld a, (curArg1+1)
|
ld a, (curArg1+1)
|
||||||
cp 0 ; numerical argument *must* be zero
|
cp 0 ; numerical argument *must* be zero
|
||||||
jr nz, .error
|
jr nz, .error
|
||||||
; ok, we're good
|
; ok, we're good
|
||||||
ld a, 0xe9 ; second upcode
|
ld a, 0xe9 ; second upcode
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld c, 2
|
ld c, 2
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
@ -481,12 +421,12 @@ handleBITHL:
|
|||||||
call handleBIT
|
call handleBIT
|
||||||
ret nz ; error
|
ret nz ; error
|
||||||
ld a, 0xcb ; first upcode
|
ld a, 0xcb ; first upcode
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
ld a, (curArg1+1) ; 0-7
|
ld a, (curArg1+1) ; 0-7
|
||||||
ld b, 3 ; displacement
|
ld b, 3 ; displacement
|
||||||
call rlaX
|
call rlaX
|
||||||
or 0b01000110 ; 2nd upcode
|
or 0b01000110 ; 2nd upcode
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld c, 2
|
ld c, 2
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -496,18 +436,18 @@ handleBITIX:
|
|||||||
handleBITIY:
|
handleBITIY:
|
||||||
ld a, 0xfd
|
ld a, 0xfd
|
||||||
handleBITIXY:
|
handleBITIXY:
|
||||||
ld (curUpcode), a ; first upcode
|
ld (instrUpcode), a ; first upcode
|
||||||
call handleBIT
|
call handleBIT
|
||||||
ret nz ; error
|
ret nz ; error
|
||||||
ld a, 0xcb ; 2nd upcode
|
ld a, 0xcb ; 2nd upcode
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld a, (curArg2+1) ; IXY displacement
|
ld a, (curArg2+1) ; IXY displacement
|
||||||
ld (curUpcode+2), a
|
ld (instrUpcode+2), a
|
||||||
ld a, (curArg1+1) ; 0-7
|
ld a, (curArg1+1) ; 0-7
|
||||||
ld b, 3 ; displacement
|
ld b, 3 ; displacement
|
||||||
call rlaX
|
call rlaX
|
||||||
or 0b01000110 ; 4th upcode
|
or 0b01000110 ; 4th upcode
|
||||||
ld (curUpcode+3), a
|
ld (instrUpcode+3), a
|
||||||
ld c, 4
|
ld c, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -519,7 +459,7 @@ handleBITR:
|
|||||||
ld c, a
|
ld c, a
|
||||||
; write first upcode
|
; write first upcode
|
||||||
ld a, 0xcb ; first upcode
|
ld a, 0xcb ; first upcode
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
; get bit value
|
; get bit value
|
||||||
ld a, (curArg1+1) ; 0-7
|
ld a, (curArg1+1) ; 0-7
|
||||||
ld b, 3 ; displacement
|
ld b, 3 ; displacement
|
||||||
@ -529,7 +469,7 @@ handleBITR:
|
|||||||
or c ; Now we have our ORed value
|
or c ; Now we have our ORed value
|
||||||
or 0b01000000 ; and with the constant value for that byte...
|
or 0b01000000 ; and with the constant value for that byte...
|
||||||
; we're good!
|
; we're good!
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld c, 2
|
ld c, 2
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -553,9 +493,9 @@ handleIM:
|
|||||||
.im2:
|
.im2:
|
||||||
ld a, 0x5e
|
ld a, 0x5e
|
||||||
.proceed:
|
.proceed:
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld a, 0xed
|
ld a, 0xed
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
ld c, 2
|
ld c, 2
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -565,13 +505,13 @@ handleLDIXn:
|
|||||||
handleLDIYn:
|
handleLDIYn:
|
||||||
ld a, 0xfd
|
ld a, 0xfd
|
||||||
handleLDIXYn:
|
handleLDIXYn:
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
ld a, 0x36 ; second upcode
|
ld a, 0x36 ; second upcode
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld a, (curArg1+1) ; IXY displacement
|
ld a, (curArg1+1) ; IXY displacement
|
||||||
ld (curUpcode+2), a
|
ld (instrUpcode+2), a
|
||||||
ld a, (curArg2+1) ; N
|
ld a, (curArg2+1) ; N
|
||||||
ld (curUpcode+3), a
|
ld (instrUpcode+3), a
|
||||||
ld c, 4
|
ld c, 4
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
@ -584,12 +524,12 @@ handleLDIXr:
|
|||||||
handleLDIYr:
|
handleLDIYr:
|
||||||
ld a, 0xfd
|
ld a, 0xfd
|
||||||
handleLDIXYr:
|
handleLDIXYr:
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
ld a, (curArg2+1) ; group value
|
ld a, (curArg2+1) ; group value
|
||||||
or 0b01110000 ; second upcode
|
or 0b01110000 ; second upcode
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
ld a, (curArg1+1) ; IXY displacement
|
ld a, (curArg1+1) ; IXY displacement
|
||||||
ld (curUpcode+2), a
|
ld (instrUpcode+2), a
|
||||||
ld c, 3
|
ld c, 3
|
||||||
ret
|
ret
|
||||||
.error:
|
.error:
|
||||||
@ -597,8 +537,8 @@ handleLDIXYr:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; Compute the upcode for argspec row at (DE) and arguments in curArg{1,2} and
|
; Compute the upcode for argspec row at (DE) and arguments in curArg{1,2} and
|
||||||
; writes the resulting upcode in curUpcode. A is the number if bytes written
|
; writes the resulting upcode in instrUpcode. A is the number if bytes written
|
||||||
; to curUpcode (can be zero if something went wrong).
|
; to instrUpcode (can be zero if something went wrong).
|
||||||
getUpcode:
|
getUpcode:
|
||||||
push ix
|
push ix
|
||||||
push de
|
push de
|
||||||
@ -615,14 +555,14 @@ getUpcode:
|
|||||||
ld l, (ix+4)
|
ld l, (ix+4)
|
||||||
ld h, (ix+5)
|
ld h, (ix+5)
|
||||||
call callHL
|
call callHL
|
||||||
; We have our result written in curUpcode and C is set.
|
; We have our result written in instrUpcode and C is set.
|
||||||
jp .end
|
jp .end
|
||||||
|
|
||||||
.normalInstr:
|
.normalInstr:
|
||||||
; we begin by writing our "base upcode", which can be one or two bytes
|
; we begin by writing our "base upcode", which can be one or two bytes
|
||||||
ld a, (ix+4) ; first upcode
|
ld a, (ix+4) ; first upcode
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
ld de, curUpcode ; from this point, DE points to "where we are"
|
ld de, instrUpcode ; from this point, DE points to "where we are"
|
||||||
; in terms of upcode writing.
|
; in terms of upcode writing.
|
||||||
inc de ; make DE point to where we should write next.
|
inc de ; make DE point to where we should write next.
|
||||||
ld a, (ix+5) ; second upcode
|
ld a, (ix+5) ; second upcode
|
||||||
@ -667,11 +607,11 @@ getUpcode:
|
|||||||
bit 6, (ix+3)
|
bit 6, (ix+3)
|
||||||
jr z, .firstUpcode ; not set: first upcode
|
jr z, .firstUpcode ; not set: first upcode
|
||||||
or (ix+5) ; second upcode
|
or (ix+5) ; second upcode
|
||||||
ld (curUpcode+1), a
|
ld (instrUpcode+1), a
|
||||||
jr .writeExtraBytes
|
jr .writeExtraBytes
|
||||||
.firstUpcode:
|
.firstUpcode:
|
||||||
or (ix+4) ; first upcode
|
or (ix+4) ; first upcode
|
||||||
ld (curUpcode), a
|
ld (instrUpcode), a
|
||||||
jr .writeExtraBytes
|
jr .writeExtraBytes
|
||||||
.writeExtraBytes:
|
.writeExtraBytes:
|
||||||
; Good, we are probably finished here for many primary opcodes. However,
|
; Good, we are probably finished here for many primary opcodes. However,
|
||||||
@ -679,7 +619,7 @@ getUpcode:
|
|||||||
; if that's the case here, we need to write it too.
|
; if that's the case here, we need to write it too.
|
||||||
; We still have our instruction row in IX and we have DE pointing to
|
; We still have our instruction row in IX and we have DE pointing to
|
||||||
; where we should write next (which could be the second or the third
|
; where we should write next (which could be the second or the third
|
||||||
; byte of curUpcode).
|
; byte of instrUpcode).
|
||||||
ld a, (ix+1) ; first argspec
|
ld a, (ix+1) ; first argspec
|
||||||
ld hl, curArg1
|
ld hl, curArg1
|
||||||
call checkNOrM
|
call checkNOrM
|
||||||
@ -724,7 +664,7 @@ getUpcode:
|
|||||||
ld c, 3
|
ld c, 3
|
||||||
jr .computeBytesWritten
|
jr .computeBytesWritten
|
||||||
.computeBytesWritten:
|
.computeBytesWritten:
|
||||||
; At this point, everything that we needed to write in curUpcode is
|
; At this point, everything that we needed to write in instrUpcode is
|
||||||
; written an C is 1 if we have no extra byte, 2 if we have an extra
|
; written an C is 1 if we have no extra byte, 2 if we have an extra
|
||||||
; byte and 3 if we have an extra word. What we need to do here is check
|
; byte and 3 if we have an extra word. What we need to do here is check
|
||||||
; if ix+5 is non-zero and increase C if it is.
|
; if ix+5 is non-zero and increase C if it is.
|
||||||
@ -784,7 +724,7 @@ processArg:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; Parse instruction specified in A (I_* const) with args in (HL) and write
|
; Parse instruction specified in A (I_* const) with args in (HL) and write
|
||||||
; resulting opcode(s) in (curUpcode). Returns the number of bytes written in A.
|
; resulting opcode(s) in (instrUpcode). Returns the number of bytes written in A.
|
||||||
parseInstruction:
|
parseInstruction:
|
||||||
push bc
|
push bc
|
||||||
push hl
|
push hl
|
||||||
@ -1119,6 +1059,6 @@ curArg1:
|
|||||||
curArg2:
|
curArg2:
|
||||||
.db 0, 0, 0
|
.db 0, 0, 0
|
||||||
|
|
||||||
curUpcode:
|
instrUpcode:
|
||||||
.db 0, 0, 0, 0
|
.db 0, 0, 0, 0
|
||||||
|
|
||||||
|
59
apps/zasm/literal.asm
Normal file
59
apps/zasm/literal.asm
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
|
||||||
|
; result in A.
|
||||||
|
;
|
||||||
|
; On success, the carry flag is reset. On error, it is set.
|
||||||
|
parseDecimal:
|
||||||
|
; First, let's see if we have an easy 0-9 case
|
||||||
|
cp '0'
|
||||||
|
ret c ; if < '0', we have a problem
|
||||||
|
cp '9'+1
|
||||||
|
; We are in the 0-9 range
|
||||||
|
sub a, '0' ; C is clear
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Parses the string at (HL) and returns the 16-bit value in IX.
|
||||||
|
; As soon as the number doesn't fit 16-bit any more, parsing stops and the
|
||||||
|
; number is invalid. If the number is valid, Z is set, otherwise, unset.
|
||||||
|
parseNumber:
|
||||||
|
push hl
|
||||||
|
push de
|
||||||
|
push bc
|
||||||
|
|
||||||
|
ld ix, 0
|
||||||
|
.loop:
|
||||||
|
ld a, (hl)
|
||||||
|
cp 0
|
||||||
|
jr z, .end ; success!
|
||||||
|
call parseDecimal
|
||||||
|
jr c, .error
|
||||||
|
|
||||||
|
; Now, let's add A to IX. First, multiply by 10.
|
||||||
|
ld d, ixh ; we need a copy of the initial copy for later
|
||||||
|
ld e, ixl
|
||||||
|
add ix, ix ; x2
|
||||||
|
add ix, ix ; x4
|
||||||
|
add ix, ix ; x8
|
||||||
|
add ix, de ; x9
|
||||||
|
add ix, de ; x10
|
||||||
|
add a, ixl
|
||||||
|
jr nc, .nocarry
|
||||||
|
inc ixh
|
||||||
|
.nocarry:
|
||||||
|
ld ixl, a
|
||||||
|
|
||||||
|
; We didn't bother checking for the C flag at each step because we
|
||||||
|
; check for overflow afterwards. If ixh < d, we overflowed
|
||||||
|
ld a, ixh
|
||||||
|
cp d
|
||||||
|
jr c, .error ; carry is set? overflow
|
||||||
|
|
||||||
|
inc hl
|
||||||
|
jr .loop
|
||||||
|
|
||||||
|
.error:
|
||||||
|
call JUMP_UNSETZ
|
||||||
|
.end:
|
||||||
|
pop bc
|
||||||
|
pop de
|
||||||
|
pop hl
|
||||||
|
ret
|
@ -20,8 +20,9 @@ main:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
#include "util.asm"
|
#include "util.asm"
|
||||||
#include "tok.asm"
|
#include "literal.asm"
|
||||||
#include "instr.asm"
|
#include "instr.asm"
|
||||||
|
#include "tok.asm"
|
||||||
#include "directive.asm"
|
#include "directive.asm"
|
||||||
|
|
||||||
; Parse line in (HL), write the resulting opcode(s) in (DE) and returns the
|
; Parse line in (HL), write the resulting opcode(s) in (DE) and returns the
|
||||||
@ -35,11 +36,11 @@ parseLine:
|
|||||||
jr nz, .error
|
jr nz, .error
|
||||||
call tokenize
|
call tokenize
|
||||||
ld a, b ; TOK_*
|
ld a, b ; TOK_*
|
||||||
cp TOK_BAD
|
|
||||||
jr z, .error
|
|
||||||
cp TOK_INSTR
|
cp TOK_INSTR
|
||||||
jr z, .instr
|
jr z, .instr
|
||||||
jr .error ; directive not supported yet
|
cp TOK_DIRECTIVE
|
||||||
|
jr z, .direc
|
||||||
|
jr .error ; token not supported
|
||||||
.instr:
|
.instr:
|
||||||
ld a, c ; I_*
|
ld a, c ; I_*
|
||||||
call parseInstruction
|
call parseInstruction
|
||||||
@ -48,7 +49,18 @@ parseLine:
|
|||||||
ld b, 0
|
ld b, 0
|
||||||
ld c, a ; written bytes
|
ld c, a ; written bytes
|
||||||
push hl
|
push hl
|
||||||
ld hl, curUpcode
|
ld hl, instrUpcode
|
||||||
|
call copy
|
||||||
|
pop hl
|
||||||
|
call JUMP_ADDDE
|
||||||
|
jr .success
|
||||||
|
.direc:
|
||||||
|
ld a, c ; D_*
|
||||||
|
call parseDirective
|
||||||
|
ld b, 0
|
||||||
|
ld c, a ; written bytes
|
||||||
|
push hl
|
||||||
|
ld hl, direcData
|
||||||
call copy
|
call copy
|
||||||
pop hl
|
pop hl
|
||||||
call JUMP_ADDDE
|
call JUMP_ADDDE
|
||||||
|
@ -2,3 +2,4 @@
|
|||||||
add a, b ; comment
|
add a, b ; comment
|
||||||
inc a ; comment
|
inc a ; comment
|
||||||
; comment
|
; comment
|
||||||
|
.db 42
|
||||||
|
@ -94,10 +94,6 @@ readWord:
|
|||||||
ld (de), a
|
ld (de), a
|
||||||
ld a, 4
|
ld a, 4
|
||||||
sub a, b
|
sub a, b
|
||||||
jr .end
|
|
||||||
.error:
|
|
||||||
xor a
|
|
||||||
ld (de), a
|
|
||||||
.end:
|
.end:
|
||||||
pop de
|
pop de
|
||||||
pop bc
|
pop bc
|
||||||
|
Loading…
Reference in New Issue
Block a user