1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-03 00:20:56 +11:00

Compare commits

..

No commits in common. "68ef686c3c0e1304bd871cac5fb27ac0640ba977" and "c4658591bd0b9767eb60033beeb44568e74a8666" have entirely different histories.

2 changed files with 72 additions and 70 deletions

View File

@ -248,13 +248,16 @@ parseArg:
; Returns, with Z, whether A is a groupId ; Returns, with Z, whether A is a groupId
isGroupId: isGroupId:
or a cp 0xc ; max group id + 1
jp z, unsetZ ; not a group jr nc, .notgroup ; >= 0xc? not a group
cp 0xd ; max group id + 1 cp 0
jp nc, unsetZ ; >= 0xd? not a group jr z, .notgroup ; 0? not supposed to happen. something's wrong.
; A is a group. ensure Z is set ; A is a group. ensure Z is set
cp a cp a
ret ret
.notgroup:
call unsetZ
ret
; Find argspec A in group id H. ; Find argspec A in group id H.
; Set Z according to whether we found the argspec ; Set Z according to whether we found the argspec
@ -334,7 +337,7 @@ findInGroup:
; If it's not this, then we check if it's a numerical arg. ; If it's not this, then we check if it's a numerical arg.
; If A is a group ID, we do something else: we check that (HL) exists in the ; If A is a group ID, we do something else: we check that (HL) exists in the
; groupspec (argGrpTbl). Moreover, we go and write the group's "value" (index) ; groupspec (argGrpTbl). Moreover, we go and write the group's "value" (index)
; in (HL+1). This will save us significant processing later in spitUpcode. ; in (HL+1). This will save us significant processing later in getUpcode.
; Set Z according to whether we match or not. ; Set Z according to whether we match or not.
matchArg: matchArg:
cp (hl) cp (hl)
@ -342,16 +345,11 @@ matchArg:
; not an exact match. Before we continue: is A zero? Because if it is, ; not an exact match. Before we continue: is A zero? Because if it is,
; we have to stop right here: no match possible. ; we have to stop right here: no match possible.
or a or a
jr nz, .skip ; not a zero, we can continue jr nz, .checkIfNumber ; not a zero, we can continue
; zero, stop here ; zero, stop here
cp 1 ; unset Z call unsetZ
ret ret
.skip: .checkIfNumber:
; Alright, let's start with a special case. Is it part of the special
; "BIT" group, 0xc? If yes, we actually expect a number, which will
; then be ORed like a regular group index.
cp 0xc
jr z, .expectsBIT
; not an exact match, let's check for numerical constants. ; not an exact match, let's check for numerical constants.
call upcase call upcase
call checkNOrM call checkNOrM
@ -365,21 +363,6 @@ matchArg:
cp (hl) cp (hl)
ret ; whether we match or not, the result of Z is ret ; whether we match or not, the result of Z is
; the good one. ; the good one.
.expectsBIT:
ld a, (hl)
cp 'N'
inc hl
ld a, (hl)
dec hl
cp 8
jr c, .isBit ; A < 8
; not a bit
or a ; unset Z
ret
.isBit:
cp a ; set Z
ret
.notNumber: .notNumber:
; A bit of a delicate situation here: we want A to go in H but also ; A bit of a delicate situation here: we want A to go in H but also
; (HL) to go in A. If not careful, we overwrite each other. EXX is ; (HL) to go in A. If not careful, we overwrite each other. EXX is
@ -424,8 +407,8 @@ matchPrimaryRow:
; *** Special opcodes *** ; *** Special opcodes ***
; The special upcode handling routines below all have the same signature. ; The special upcode handling routines below all have the same signature.
; Instruction row is at IX and we're expected to perform the same task as ; Instruction row is at IX and we're expected to perform the same task as
; spitUpcode. The number of bytes, however, must go in C instead of A ; getUpcode. The number of bytes, however, must go in C instead of A
; No need to preserve HL, DE, BC and IX: it's handled by spitUpcode already. ; No need to preserve HL, DE, BC and IX: it's handled by getUpcode already.
; Handle like a regular "JP (IX+d)" except that we refuse any displacement: if ; Handle like a regular "JP (IX+d)" except that we refuse any displacement: if
; a displacement is specified, we error out. ; a displacement is specified, we error out.
@ -461,6 +444,28 @@ handleBIT:
ld c, 0 ld c, 0
jp unsetZ jp unsetZ
handleBITHL:
ld b, 0b01000110
jr _handleBITHL
handleSETHL:
ld b, 0b11000110
jr _handleBITHL
handleRESHL:
ld b, 0b10000110
_handleBITHL:
call handleBIT
ret nz ; error
ld a, 0xcb ; first upcode
ld (INS_UPCODE), a
ld a, (INS_CURARG1+1) ; 0-7
rla
rla
rla
or b ; 2nd upcode
ld (INS_UPCODE+1), a
ld c, 2
ret
handleBITIX: handleBITIX:
ld a, 0xdd ld a, 0xdd
ld b, 0b01000110 ld b, 0b01000110
@ -620,9 +625,11 @@ handleLDrr:
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 to IO. ; writes the resulting upcode in INS_UPCODE. A is the number if bytes written
; A is zero, with Z set, on success. A is non-zero, with Z unset, on error. ; to INS_UPCODE.
spitUpcode: ; A is zero on error. The only thing that can go wrong in this routine is
; overflow.
getUpcode:
push ix push ix
push de push de
push hl push hl
@ -638,7 +645,7 @@ spitUpcode:
ld h, (ix+5) ld h, (ix+5)
call callHL call callHL
; We have our result written in INS_UPCODE and C is set. ; We have our result written in INS_UPCODE and C is set.
jp .writeIO 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
@ -727,7 +734,7 @@ spitUpcode:
call checknmxy call checknmxy
jr z, .withByte jr z, .withByte
; nope, no number, alright, we're finished here ; nope, no number, alright, we're finished here
jr .writeIO jr .end
.withByte: .withByte:
inc hl inc hl
; HL points to our number (LSB), with (HL+1) being our MSB which should ; HL points to our number (LSB), with (HL+1) being our MSB which should
@ -744,7 +751,7 @@ spitUpcode:
; verification falsely fail. ; verification falsely fail.
inc c ; one extra byte is written inc c ; one extra byte is written
call zasmIsFirstPass call zasmIsFirstPass
jr z, .writeIO jr z, .end
; We're on second pass ; We're on second pass
push de ; Don't let go of this, that's our dest push de ; Don't let go of this, that's our dest
@ -774,7 +781,7 @@ spitUpcode:
or a ; cp 0 or a ; cp 0
jr nz, .numberTruncated ; if A is anything but zero, we're out jr nz, .numberTruncated ; if A is anything but zero, we're out
; of bounds. ; of bounds.
jr .writeIO jr .end
.absoluteValue: .absoluteValue:
; verify that the MSB in argument is zero ; verify that the MSB in argument is zero
@ -787,7 +794,7 @@ spitUpcode:
ldi ldi
pop bc pop bc
inc c inc c
jr .writeIO jr .end
.withWord: .withWord:
inc hl ; HL now points to LSB inc hl ; HL now points to LSB
@ -798,28 +805,12 @@ spitUpcode:
pop bc pop bc
inc c ; two extra bytes are written inc c ; two extra bytes are written
inc c inc c
; to writeIO
.writeIO:
; Let's write INS_UPCODE to IO
ld b, c ; save output byte count
ld hl, INS_UPCODE
.loopWrite:
ld a, (hl)
call ioPutB
jr nz, .ioError
inc hl
djnz .loopWrite
; Z is set by INC HL
jr .end jr .end
.numberTruncated: .numberTruncated:
; Z already unset ; problem: not zero, so value is truncated. error
ld a, ERR_OVFL ld c, 0
jr .end
.ioError:
; Z already unset
ld a, SHELL_ERR_IO_ERROR
; continue to .end
.end: .end:
ld a, c
pop bc pop bc
pop hl pop hl
pop de pop de
@ -890,10 +881,26 @@ parseInstruction:
.match: .match:
; We have our matching instruction row. We're getting pretty near our ; We have our matching instruction row. We're getting pretty near our
; goal here! ; goal here!
call spitUpcode call getUpcode
jr .end ; Z and A set properly, even on error or a ; is zero?
jr z, .overflow
ld b, a ; save output byte count
ld hl, INS_UPCODE
.loopWrite:
ld a, (hl)
call ioPutB
jr nz, .ioError
inc hl
djnz .loopWrite
cp a ; ensure Z
jr .end
.ioError:
ld a, SHELL_ERR_IO_ERROR
jr .error
.overflow:
ld a, ERR_OVFL
jr .error
.badfmt: .badfmt:
; Z already unset
ld a, ERR_BAD_FMT ld a, ERR_BAD_FMT
.error: .error:
; A is set to error already ; A is set to error already
@ -976,10 +983,6 @@ argGrpCC:
argGrpABCDEHL: argGrpABCDEHL:
.db "BCDEHL_A" ; 0xb .db "BCDEHL_A" ; 0xb
; SPECIAL GROUP "BIT": 0xc
; When special group "0xc" shows up in argspec, it means: accept a number
; between 0 and 7. The value is then treated like a regular group value.
; Each row is 4 bytes wide, fill with zeroes ; Each row is 4 bytes wide, fill with zeroes
instrNames: instrNames:
.db "ADC", 0 .db "ADC", 0
@ -1085,7 +1088,7 @@ instrTBl:
.db I_AND, 'n', 0, 0, 0xe6 , 0 ; AND n .db I_AND, 'n', 0, 0, 0xe6 , 0 ; AND n
.db I_AND, 'x', 0, 0, 0xdd, 0xa6 ; AND (IX+d) .db I_AND, 'x', 0, 0, 0xdd, 0xa6 ; AND (IX+d)
.db I_AND, 'y', 0, 0, 0xfd, 0xa6 ; AND (IY+d) .db I_AND, 'y', 0, 0, 0xfd, 0xa6 ; AND (IY+d)
.db I_BIT, 0xc, 'l', 0x43, 0xcb, 0b01000110 ; BIT b, (HL) .db I_BIT, 'n', 'l', 0x20 \ .dw handleBITHL ; BIT b, (HL)
.db I_BIT, 'n', 'x', 0x20 \ .dw handleBITIX ; BIT b, (IX+d) .db I_BIT, 'n', 'x', 0x20 \ .dw handleBITIX ; BIT b, (IX+d)
.db I_BIT, 'n', 'y', 0x20 \ .dw handleBITIY ; BIT b, (IY+d) .db I_BIT, 'n', 'y', 0x20 \ .dw handleBITIY ; BIT b, (IY+d)
.db I_BIT, 'n', 0xb, 0x20 \ .dw handleBITR ; BIT b, r .db I_BIT, 'n', 0xb, 0x20 \ .dw handleBITR ; BIT b, r
@ -1198,7 +1201,7 @@ instrTBl:
.db I_PUSH,'X', 0, 0, 0xdd, 0xe5 ; PUSH IX .db I_PUSH,'X', 0, 0, 0xdd, 0xe5 ; PUSH IX
.db I_PUSH,'Y', 0, 0, 0xfd, 0xe5 ; PUSH IY .db I_PUSH,'Y', 0, 0, 0xfd, 0xe5 ; PUSH IY
.db I_PUSH,0x1, 0, 4, 0b11000101 , 0 ; PUSH qq .db I_PUSH,0x1, 0, 4, 0b11000101 , 0 ; PUSH qq
.db I_RES, 0xc, 'l', 0x43, 0xcb, 0b10000110 ; RES b, (HL) .db I_RES, 'n', 'l', 0x20 \ .dw handleRESHL ; RES b, (HL)
.db I_RES, 'n', 'x', 0x20 \ .dw handleRESIX ; RES b, (IX+d) .db I_RES, 'n', 'x', 0x20 \ .dw handleRESIX ; RES b, (IX+d)
.db I_RES, 'n', 'y', 0x20 \ .dw handleRESIY ; RES b, (IY+d) .db I_RES, 'n', 'y', 0x20 \ .dw handleRESIY ; RES b, (IY+d)
.db I_RES, 'n', 0xb, 0x20 \ .dw handleRESR ; RES b, r .db I_RES, 'n', 0xb, 0x20 \ .dw handleRESR ; RES b, r
@ -1218,7 +1221,7 @@ instrTBl:
.db I_SBC, 'A', 0xb, 0, 0b10011000 , 0 ; SBC A, r .db I_SBC, 'A', 0xb, 0, 0b10011000 , 0 ; SBC A, r
.db I_SBC,'h',0x3,0x44, 0xed, 0b01000010 ; SBC HL, ss .db I_SBC,'h',0x3,0x44, 0xed, 0b01000010 ; SBC HL, ss
.db I_SCF, 0, 0, 0, 0x37 , 0 ; SCF .db I_SCF, 0, 0, 0, 0x37 , 0 ; SCF
.db I_SET, 0xc, 'l', 0x43, 0xcb, 0b11000110 ; SET b, (HL) .db I_SET, 'n', 'l', 0x20 \ .dw handleSETHL ; SET b, (HL)
.db I_SET, 'n', 'x', 0x20 \ .dw handleSETIX ; SET b, (IX+d) .db I_SET, 'n', 'x', 0x20 \ .dw handleSETIX ; SET b, (IX+d)
.db I_SET, 'n', 'y', 0x20 \ .dw handleSETIY ; SET b, (IY+d) .db I_SET, 'n', 'y', 0x20 \ .dw handleSETIY ; SET b, (IY+d)
.db I_SET, 'n', 0xb, 0x20 \ .dw handleSETR ; SET b, r .db I_SET, 'n', 0xb, 0x20 \ .dw handleSETR ; SET b, r

View File

@ -88,9 +88,8 @@ ioGetB:
; We have newline. Increase lineno and return (the rest of the ; We have newline. Increase lineno and return (the rest of the
; processing below isn't needed. ; processing below isn't needed.
push hl push hl
ld hl, (IO_INC_LINENO) ld hl, IO_INC_LINENO
inc hl inc (hl)
ld (IO_INC_LINENO), hl
pop hl pop hl
ret ret