mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 12:08:07 +11:00
Make blockdev pointers 32 bits
This allows us to break through the 64K limit for includes CFS in zasm, a limit we were dangerously close to breaking. In fact, this commit makes us go over that limit. Right in time!
This commit is contained in:
parent
6b1679c811
commit
328f44814e
@ -33,10 +33,12 @@
|
|||||||
; Unsuccessful writes generally mean that we reached EOF.
|
; Unsuccessful writes generally mean that we reached EOF.
|
||||||
;
|
;
|
||||||
; Seek:
|
; Seek:
|
||||||
; Place device "pointer" at position dictated by HL.
|
; Place device "pointer" at position dictated by HL (low 16 bits) and DE (high
|
||||||
|
; 16 bits).
|
||||||
;
|
;
|
||||||
; Tell:
|
; Tell:
|
||||||
; Return the position of the "pointer" in HL
|
; Return the position of the "pointer" in HL (low 16 bits) and DE (high 16
|
||||||
|
; bits).
|
||||||
;
|
;
|
||||||
; All routines are expected to preserve unused registers.
|
; All routines are expected to preserve unused registers.
|
||||||
|
|
||||||
@ -197,12 +199,14 @@ _blkWrite:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; Seeks the block device in one of 5 modes, which is the A argument:
|
; Seeks the block device in one of 5 modes, which is the A argument:
|
||||||
; 0 : Move exactly to X, X being the HL argument.
|
; 0 : Move exactly to X, X being the HL/DE argument.
|
||||||
; 1 : Move forward by X bytes, X being the HL argument
|
; 1 : Move forward by X bytes, X being the HL argument (no DE)
|
||||||
; 2 : Move backwards by X bytes, X being the HL argument
|
; 2 : Move backwards by X bytes, X being the HL argument (no DE)
|
||||||
; 3 : Move to the end
|
; 3 : Move to the end
|
||||||
; 4 : Move to the beginning
|
; 4 : Move to the beginning
|
||||||
; Set position of selected device to the value specified in HL
|
|
||||||
|
; Set position of selected device to the value specified in HL (low) and DE
|
||||||
|
; (high). DE is only used for mode 0.
|
||||||
;
|
;
|
||||||
; When seeking to an out-of-bounds position, the resulting position will be
|
; When seeking to an out-of-bounds position, the resulting position will be
|
||||||
; one position ahead of the last valid position. Therefore, GetC after a seek
|
; one position ahead of the last valid position. Therefore, GetC after a seek
|
||||||
@ -214,6 +218,8 @@ blkSeek:
|
|||||||
ld ix, (BLOCKDEV_SEEK)
|
ld ix, (BLOCKDEV_SEEK)
|
||||||
ld iy, (BLOCKDEV_TELL)
|
ld iy, (BLOCKDEV_TELL)
|
||||||
_blkSeek:
|
_blkSeek:
|
||||||
|
; we preserve DE so that it's possible to call blkSeek in mode != 0
|
||||||
|
; while not discarding our current DE value.
|
||||||
push de
|
push de
|
||||||
cp BLOCKDEV_SEEK_FORWARD
|
cp BLOCKDEV_SEEK_FORWARD
|
||||||
jr z, .forward
|
jr z, .forward
|
||||||
@ -224,30 +230,41 @@ _blkSeek:
|
|||||||
cp BLOCKDEV_SEEK_END
|
cp BLOCKDEV_SEEK_END
|
||||||
jr z, .end
|
jr z, .end
|
||||||
; all other modes are considered absolute
|
; all other modes are considered absolute
|
||||||
jr .seek ; for absolute mode, HL is already correct
|
jr .seek ; for absolute mode, HL and DE are already
|
||||||
|
; correct
|
||||||
.forward:
|
.forward:
|
||||||
ex de, hl ; DE has our offset
|
push bc
|
||||||
|
push hl
|
||||||
; We want to be able to plug our own TELL function, which is why we
|
; We want to be able to plug our own TELL function, which is why we
|
||||||
; don't call blkTell directly here.
|
; don't call blkTell directly here.
|
||||||
; Calling TELL
|
; Calling TELL
|
||||||
call callIY ; HL has our curpos
|
ld de, 0 ; in case out Tell routine doesn't return DE
|
||||||
add hl, de
|
call callIY ; HL/DE now have our curpos
|
||||||
jr nc, .seek ; no carry? alright!
|
pop bc ; pop HL into BC
|
||||||
; we have carry? out of bounds, set to maximum
|
add hl, bc
|
||||||
|
pop bc ; pop orig BC back
|
||||||
|
jr nc, .seek ; no carry? let's seek.
|
||||||
|
; carry, adjust DE
|
||||||
|
inc de
|
||||||
|
jr .seek
|
||||||
.backward:
|
.backward:
|
||||||
; TODO - subtraction are more complicated...
|
; TODO - subtraction are more complicated...
|
||||||
jr .seek
|
jr .seek
|
||||||
.beginning:
|
.beginning:
|
||||||
ld hl, 0
|
ld hl, 0
|
||||||
|
ld de, 0
|
||||||
jr .seek
|
jr .seek
|
||||||
.end:
|
.end:
|
||||||
ld hl, 0xffff
|
ld hl, 0xffff
|
||||||
|
ld de, 0xffff
|
||||||
.seek:
|
.seek:
|
||||||
|
call _blkCall
|
||||||
pop de
|
pop de
|
||||||
jp _blkCall
|
ret
|
||||||
|
|
||||||
; Returns the current position of the selected device in HL.
|
; Returns the current position of the selected device in HL (low) and DE (high).
|
||||||
blkTell:
|
blkTell:
|
||||||
|
ld de, 0 ; in case device ignores DE.
|
||||||
ld ix, (BLOCKDEV_TELL)
|
ld ix, (BLOCKDEV_TELL)
|
||||||
jp _blkCall
|
jp _blkCall
|
||||||
|
|
||||||
|
@ -57,6 +57,19 @@ addHL:
|
|||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; subtract the value of A from HL
|
||||||
|
subHL:
|
||||||
|
push af
|
||||||
|
; To avoid having to swap L and A, we sub "backwards", that is, we add
|
||||||
|
; a NEGated value. This means that the carry flag is inverted
|
||||||
|
neg
|
||||||
|
add a, l
|
||||||
|
jr c, .end ; if carry, no carry. :)
|
||||||
|
dec h
|
||||||
|
.end:
|
||||||
|
ld l, a
|
||||||
|
pop af
|
||||||
|
ret
|
||||||
|
|
||||||
; Write the contents of HL in (DE)
|
; Write the contents of HL in (DE)
|
||||||
writeHLinDE:
|
writeHLinDE:
|
||||||
|
108
kernel/fs.asm
108
kernel/fs.asm
@ -85,12 +85,9 @@
|
|||||||
.equ FS_META_FSIZE_OFFSET 4
|
.equ FS_META_FSIZE_OFFSET 4
|
||||||
.equ FS_META_FNAME_OFFSET 6
|
.equ FS_META_FNAME_OFFSET 6
|
||||||
; Size in bytes of a FS handle:
|
; Size in bytes of a FS handle:
|
||||||
; * 2 bytes for current position. (absolute)
|
; * 4 bytes for starting offset of the FS block
|
||||||
; * 2 bytes for starting offset, after metadata
|
; * 2 bytes for current position relative to block's position
|
||||||
; * 2 bytes for maximum offset
|
.equ FS_HANDLE_SIZE 6
|
||||||
; * 2 bytes for file size (we could fetch it from metadata all the time, but it
|
|
||||||
; could be time consuming depending on the underlying device).
|
|
||||||
.equ FS_HANDLE_SIZE 8
|
|
||||||
.equ FS_ERR_NO_FS 0x5
|
.equ FS_ERR_NO_FS 0x5
|
||||||
.equ FS_ERR_NOT_FOUND 0x6
|
.equ FS_ERR_NOT_FOUND 0x6
|
||||||
|
|
||||||
@ -101,14 +98,17 @@
|
|||||||
.equ FS_SEEK FS_PUTC+2
|
.equ FS_SEEK FS_PUTC+2
|
||||||
.equ FS_TELL FS_SEEK+2
|
.equ FS_TELL FS_SEEK+2
|
||||||
; Offset at which our FS start on mounted device
|
; Offset at which our FS start on mounted device
|
||||||
|
; This pointer is 32 bits. 32 bits pointers are a bit awkward: first two bytes
|
||||||
|
; are high bytes *low byte first*, and then the low two bytes, same order.
|
||||||
|
; When loaded in HL/DE, the four bytes are loaded in this order: E, D, L, H
|
||||||
.equ FS_START FS_TELL+2
|
.equ FS_START FS_TELL+2
|
||||||
; Offset at which we are currently pointing to with regards to our routines
|
; Offset at which we are currently pointing to with regards to our routines
|
||||||
; below, which all assume this offset as a context. This offset is not relative
|
; below, which all assume this offset as a context. This offset is not relative
|
||||||
; to FS_START. It can be used directly with fsblkSeek.
|
; to FS_START. It can be used directly with fsblkSeek. 32 bits.
|
||||||
.equ FS_PTR FS_START+2
|
.equ FS_PTR FS_START+4
|
||||||
; This variable below contain the metadata of the last block FS_PTR was moved
|
; This variable below contain the metadata of the last block FS_PTR was moved
|
||||||
; to. We read this data in memory to avoid constant seek+read operations.
|
; to. We read this data in memory to avoid constant seek+read operations.
|
||||||
.equ FS_META FS_PTR+2
|
.equ FS_META FS_PTR+4
|
||||||
.equ FS_HANDLES FS_META+FS_METASIZE
|
.equ FS_HANDLES FS_META+FS_METASIZE
|
||||||
.equ FS_RAMEND FS_HANDLES+FS_HANDLE_COUNT*FS_HANDLE_SIZE
|
.equ FS_RAMEND FS_HANDLES+FS_HANDLE_COUNT*FS_HANDLE_SIZE
|
||||||
|
|
||||||
@ -133,10 +133,11 @@ fsBegin:
|
|||||||
push hl
|
push hl
|
||||||
ld hl, (FS_START)
|
ld hl, (FS_START)
|
||||||
ld (FS_PTR), hl
|
ld (FS_PTR), hl
|
||||||
|
ld hl, (FS_START+2)
|
||||||
|
ld (FS_PTR+2), hl
|
||||||
pop hl
|
pop hl
|
||||||
call fsReadMeta
|
call fsReadMeta
|
||||||
call fsIsValid ; sets Z
|
jp fsIsValid ; sets Z, returns
|
||||||
ret
|
|
||||||
|
|
||||||
; Change current position to the next block with metadata. If it can't (if this
|
; Change current position to the next block with metadata. If it can't (if this
|
||||||
; is the last valid block), doesn't move.
|
; is the last valid block), doesn't move.
|
||||||
@ -156,8 +157,9 @@ fsNext:
|
|||||||
call fsblkSeek
|
call fsblkSeek
|
||||||
djnz .loop
|
djnz .loop
|
||||||
; Good, were here. We're going to read meta from our current position.
|
; Good, were here. We're going to read meta from our current position.
|
||||||
call fsblkTell ; --> HL
|
call fsblkTell ; --> HL, --> DE
|
||||||
ld (FS_PTR), hl
|
ld (FS_PTR), de
|
||||||
|
ld (FS_PTR+2), hl
|
||||||
call fsReadMeta
|
call fsReadMeta
|
||||||
jr nz, .createChainEnd
|
jr nz, .createChainEnd
|
||||||
call fsIsValid
|
call fsIsValid
|
||||||
@ -226,13 +228,16 @@ fsInitMeta:
|
|||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Make sure that our underlying blockdev is correcly placed.
|
; Make sure that our underlying blockdev is correctly placed.
|
||||||
fsPlace:
|
fsPlace:
|
||||||
push af
|
push af
|
||||||
push hl
|
push hl
|
||||||
|
push de
|
||||||
xor a
|
xor a
|
||||||
ld hl, (FS_PTR)
|
ld de, (FS_PTR)
|
||||||
|
ld hl, (FS_PTR+2)
|
||||||
call fsblkSeek
|
call fsblkSeek
|
||||||
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
@ -284,7 +289,8 @@ fsAlloc:
|
|||||||
; Good, FS_META ready. Now, let's update FS_PTR because it hasn't been
|
; Good, FS_META ready. Now, let's update FS_PTR because it hasn't been
|
||||||
; changed yet.
|
; changed yet.
|
||||||
call fsblkTell
|
call fsblkTell
|
||||||
ld (FS_PTR), hl
|
ld (FS_PTR), de
|
||||||
|
ld (FS_PTR+2), hl
|
||||||
; Ok, now we can write our metadata
|
; Ok, now we can write our metadata
|
||||||
call fsWriteMeta
|
call fsWriteMeta
|
||||||
.end:
|
.end:
|
||||||
@ -361,6 +367,7 @@ fsblkSeek:
|
|||||||
jp _blkSeek
|
jp _blkSeek
|
||||||
|
|
||||||
fsblkTell:
|
fsblkTell:
|
||||||
|
ld de, 0
|
||||||
ld ix, (FS_TELL)
|
ld ix, (FS_TELL)
|
||||||
jp _blkCall
|
jp _blkCall
|
||||||
|
|
||||||
@ -368,57 +375,56 @@ fsblkTell:
|
|||||||
|
|
||||||
; Open file at current position into handle at (HL)
|
; Open file at current position into handle at (HL)
|
||||||
fsOpen:
|
fsOpen:
|
||||||
|
push bc
|
||||||
push hl
|
push hl
|
||||||
push de
|
push de
|
||||||
push af
|
push af
|
||||||
ex de, hl
|
ex de, hl
|
||||||
ld hl, (FS_PTR)
|
; Starting pos
|
||||||
ld a, FS_METASIZE
|
ld hl, FS_PTR
|
||||||
call addHL
|
ld bc, 4
|
||||||
call writeHLinDE
|
ldir
|
||||||
inc de
|
; Current pos
|
||||||
inc de
|
ld hl, FS_METASIZE
|
||||||
call writeHLinDE
|
|
||||||
inc de
|
|
||||||
inc de
|
|
||||||
; Maximum offset is starting offset + (numblocks * 0x100) - 1
|
|
||||||
ld a, (FS_META+FS_META_ALLOC_OFFSET)
|
|
||||||
; Because our blocks are exactly 0x100 in size, we simple have to
|
|
||||||
; increase the H in HL to have our result.
|
|
||||||
add a, h
|
|
||||||
ld h, a
|
|
||||||
call writeHLinDE
|
|
||||||
inc de
|
|
||||||
inc de
|
|
||||||
ld hl, (FS_META+FS_META_FSIZE_OFFSET)
|
|
||||||
call writeHLinDE
|
call writeHLinDE
|
||||||
pop af
|
pop af
|
||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
|
pop bc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Place FS blockdev at proper position for file handle in (DE).
|
; Place FS blockdev at proper position for file handle in (DE).
|
||||||
fsPlaceH:
|
fsPlaceH:
|
||||||
push af
|
push af
|
||||||
|
push bc
|
||||||
push hl
|
push hl
|
||||||
push de
|
push de
|
||||||
pop ix
|
pop ix
|
||||||
push ix
|
push ix
|
||||||
ld l, (ix)
|
ld e, (ix)
|
||||||
ld h, (ix+1)
|
ld d, (ix+1)
|
||||||
|
ld l, (ix+2)
|
||||||
|
ld h, (ix+3)
|
||||||
|
ld c, (ix+4)
|
||||||
|
ld b, (ix+5)
|
||||||
|
add hl, bc
|
||||||
|
jr nc, .nocarry
|
||||||
|
inc de
|
||||||
|
.nocarry:
|
||||||
ld a, BLOCKDEV_SEEK_ABSOLUTE
|
ld a, BLOCKDEV_SEEK_ABSOLUTE
|
||||||
call fsblkSeek
|
call fsblkSeek
|
||||||
pop ix
|
pop ix
|
||||||
pop hl
|
pop hl
|
||||||
|
pop bc
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Advance file handle in (IX) by one byte
|
; Advance file handle in (IX) by one byte
|
||||||
fsAdvanceH:
|
fsAdvanceH:
|
||||||
push af
|
push af
|
||||||
inc (ix)
|
inc (ix+4)
|
||||||
jr nz, .end
|
jr nz, .end
|
||||||
inc (ix+1)
|
inc (ix+5)
|
||||||
.end:
|
.end:
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
@ -426,6 +432,7 @@ fsAdvanceH:
|
|||||||
; Read a byte in handle at (DE), put it into A and advance the handle's
|
; Read a byte in handle at (DE), put it into A and advance the handle's
|
||||||
; position.
|
; position.
|
||||||
; Z is set on success, unset if handle is at the end of the file.
|
; Z is set on success, unset if handle is at the end of the file.
|
||||||
|
; TODO: detect end of file
|
||||||
fsGetC:
|
fsGetC:
|
||||||
push ix
|
push ix
|
||||||
call fsPlaceH
|
call fsPlaceH
|
||||||
@ -441,6 +448,7 @@ fsGetC:
|
|||||||
|
|
||||||
; Write byte A in handle (DE) and advance the handle's position.
|
; Write byte A in handle (DE) and advance the handle's position.
|
||||||
; Z is set on success, unset if handle is at the end of the file.
|
; Z is set on success, unset if handle is at the end of the file.
|
||||||
|
; TODO: detect end of block alloc
|
||||||
fsPutC:
|
fsPutC:
|
||||||
call fsPlaceH
|
call fsPlaceH
|
||||||
push ix
|
push ix
|
||||||
@ -455,15 +463,18 @@ fsPutC:
|
|||||||
; Sets Z if offset is within bounds, unsets Z if it isn't.
|
; Sets Z if offset is within bounds, unsets Z if it isn't.
|
||||||
fsSeek:
|
fsSeek:
|
||||||
push de \ pop ix
|
push de \ pop ix
|
||||||
ld (ix), l
|
ld a, FS_METASIZE
|
||||||
ld (ix+1), h
|
call addHL
|
||||||
|
ld (ix+4), l
|
||||||
|
ld (ix+5), h
|
||||||
ret
|
ret
|
||||||
|
|
||||||
fsTell:
|
fsTell:
|
||||||
push de \ pop ix
|
push de \ pop ix
|
||||||
ld l, (ix)
|
ld l, (ix+4)
|
||||||
ld h, (ix+1)
|
ld h, (ix+5)
|
||||||
ret
|
ld a, FS_METASIZE
|
||||||
|
jp subHL ; returns
|
||||||
|
|
||||||
; Mount the fs subsystem upon the currently selected blockdev at current offset.
|
; Mount the fs subsystem upon the currently selected blockdev at current offset.
|
||||||
; Verify is block is valid and error out if its not, mounting nothing.
|
; Verify is block is valid and error out if its not, mounting nothing.
|
||||||
@ -479,8 +490,10 @@ fsOn:
|
|||||||
ld bc, 8 ; we have 8 bytes to copy
|
ld bc, 8 ; we have 8 bytes to copy
|
||||||
ldir ; copy!
|
ldir ; copy!
|
||||||
call fsblkTell
|
call fsblkTell
|
||||||
ld (FS_START), hl
|
ld (FS_START), de
|
||||||
ld (FS_PTR), hl
|
ld (FS_START+2), hl
|
||||||
|
ld (FS_PTR), de
|
||||||
|
ld (FS_PTR+2), hl
|
||||||
call fsReadMeta
|
call fsReadMeta
|
||||||
jr nz, .error
|
jr nz, .error
|
||||||
call fsIsValid
|
call fsIsValid
|
||||||
@ -491,8 +504,7 @@ fsOn:
|
|||||||
.error:
|
.error:
|
||||||
; couldn't mount. Let's reset our variables.
|
; couldn't mount. Let's reset our variables.
|
||||||
xor a
|
xor a
|
||||||
ld b, 10 ; blkdev routines + FS_START which is just
|
ld b, FS_META-FS_GETC ; reset routine pointers and FS ptrs
|
||||||
; after.
|
|
||||||
ld hl, FS_GETC
|
ld hl, FS_GETC
|
||||||
call fill
|
call fill
|
||||||
|
|
||||||
|
@ -31,12 +31,13 @@
|
|||||||
#define FS_DATA_PORT 0x01
|
#define FS_DATA_PORT 0x01
|
||||||
#define FS_SEEKL_PORT 0x02
|
#define FS_SEEKL_PORT 0x02
|
||||||
#define FS_SEEKH_PORT 0x03
|
#define FS_SEEKH_PORT 0x03
|
||||||
|
#define FS_SEEKE_PORT 0x04
|
||||||
|
|
||||||
static Z80Context cpu;
|
static Z80Context cpu;
|
||||||
static uint8_t mem[0xffff] = {0};
|
static uint8_t mem[0xffff] = {0};
|
||||||
static uint8_t fsdev[0xffff] = {0};
|
static uint8_t fsdev[0x20000] = {0};
|
||||||
static uint16_t fsdev_size = 0;
|
static uint32_t fsdev_size = 0;
|
||||||
static uint16_t fsdev_ptr = 0;
|
static uint32_t fsdev_ptr = 0;
|
||||||
static int running;
|
static int running;
|
||||||
|
|
||||||
static uint8_t io_read(int unused, uint16_t addr)
|
static uint8_t io_read(int unused, uint16_t addr)
|
||||||
@ -57,7 +58,9 @@ static uint8_t io_read(int unused, uint16_t addr)
|
|||||||
} else if (addr == FS_SEEKL_PORT) {
|
} else if (addr == FS_SEEKL_PORT) {
|
||||||
return fsdev_ptr & 0xff;
|
return fsdev_ptr & 0xff;
|
||||||
} else if (addr == FS_SEEKH_PORT) {
|
} else if (addr == FS_SEEKH_PORT) {
|
||||||
return fsdev_ptr >> 8;
|
return (fsdev_ptr >> 8) & 0xff;
|
||||||
|
} else if (addr == FS_SEEKE_PORT) {
|
||||||
|
return (fsdev_ptr >> 16) & 0xff;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Out of bounds I/O read: %d\n", addr);
|
fprintf(stderr, "Out of bounds I/O read: %d\n", addr);
|
||||||
return 0;
|
return 0;
|
||||||
@ -78,9 +81,11 @@ static void io_write(int unused, uint16_t addr, uint8_t val)
|
|||||||
fsdev[fsdev_ptr++] = val;
|
fsdev[fsdev_ptr++] = val;
|
||||||
}
|
}
|
||||||
} else if (addr == FS_SEEKL_PORT) {
|
} else if (addr == FS_SEEKL_PORT) {
|
||||||
fsdev_ptr = (fsdev_ptr & 0xff00) | val;
|
fsdev_ptr = (fsdev_ptr & 0xffff00) | val;
|
||||||
} else if (addr == FS_SEEKH_PORT) {
|
} else if (addr == FS_SEEKH_PORT) {
|
||||||
fsdev_ptr = (fsdev_ptr & 0x00ff) | (val << 8);
|
fsdev_ptr = (fsdev_ptr & 0xff00ff) | (val << 8);
|
||||||
|
} else if (addr == FS_SEEKE_PORT) {
|
||||||
|
fsdev_ptr = (fsdev_ptr & 0x00ffff) | (val << 16);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Out of bounds I/O write: %d / %d\n", addr, val);
|
fprintf(stderr, "Out of bounds I/O write: %d / %d\n", addr, val);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
.equ FS_DATA_PORT 0x01
|
.equ FS_DATA_PORT 0x01
|
||||||
.equ FS_SEEKL_PORT 0x02
|
.equ FS_SEEKL_PORT 0x02
|
||||||
.equ FS_SEEKH_PORT 0x03
|
.equ FS_SEEKH_PORT 0x03
|
||||||
|
.equ FS_SEEKE_PORT 0x04
|
||||||
|
|
||||||
jp init
|
jp init
|
||||||
|
|
||||||
@ -80,6 +81,8 @@ fsdevSeek:
|
|||||||
out (FS_SEEKL_PORT), a
|
out (FS_SEEKL_PORT), a
|
||||||
ld a, h
|
ld a, h
|
||||||
out (FS_SEEKH_PORT), a
|
out (FS_SEEKH_PORT), a
|
||||||
|
ld a, e
|
||||||
|
out (FS_SEEKE_PORT), a
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -89,6 +92,8 @@ fsdevTell:
|
|||||||
ld l, a
|
ld l, a
|
||||||
in a, (FS_SEEKH_PORT)
|
in a, (FS_SEEKH_PORT)
|
||||||
ld h, a
|
ld h, a
|
||||||
|
in a, (FS_SEEKE_PORT)
|
||||||
|
ld e, a
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ fsdevPutC:
|
|||||||
|
|
||||||
fsdevSeek:
|
fsdevSeek:
|
||||||
push af
|
push af
|
||||||
|
ld a, e
|
||||||
|
out (FS_SEEK_PORT), a
|
||||||
ld a, h
|
ld a, h
|
||||||
out (FS_SEEK_PORT), a
|
out (FS_SEEK_PORT), a
|
||||||
ld a, l
|
ld a, l
|
||||||
@ -108,6 +110,8 @@ fsdevSeek:
|
|||||||
fsdevTell:
|
fsdevTell:
|
||||||
push af
|
push af
|
||||||
in a, (FS_SEEK_PORT)
|
in a, (FS_SEEK_PORT)
|
||||||
|
ld e, a
|
||||||
|
in a, (FS_SEEK_PORT)
|
||||||
ld h, a
|
ld h, a
|
||||||
in a, (FS_SEEK_PORT)
|
in a, (FS_SEEK_PORT)
|
||||||
ld l, a
|
ld l, a
|
||||||
|
Binary file not shown.
@ -47,10 +47,10 @@ static int inpt_size;
|
|||||||
static int inpt_ptr;
|
static int inpt_ptr;
|
||||||
static uint8_t middle_of_seek_tell = 0;
|
static uint8_t middle_of_seek_tell = 0;
|
||||||
|
|
||||||
static uint8_t fsdev[0xffff] = {0};
|
static uint8_t fsdev[0x20000] = {0};
|
||||||
static uint16_t fsdev_size = 0;
|
static uint32_t fsdev_size = 0;
|
||||||
static uint16_t fsdev_ptr = 0;
|
static uint32_t fsdev_ptr = 0;
|
||||||
static uint8_t fsdev_middle_of_seek_tell = 0;
|
static uint8_t fsdev_seek_tell_cnt = 0;
|
||||||
|
|
||||||
static uint8_t io_read(int unused, uint16_t addr)
|
static uint8_t io_read(int unused, uint16_t addr)
|
||||||
{
|
{
|
||||||
@ -79,15 +79,18 @@ static uint8_t io_read(int unused, uint16_t addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (addr == FS_SEEK_PORT) {
|
} else if (addr == FS_SEEK_PORT) {
|
||||||
if (fsdev_middle_of_seek_tell) {
|
if (fsdev_seek_tell_cnt == 0) {
|
||||||
fsdev_middle_of_seek_tell = 0;
|
|
||||||
return fsdev_ptr & 0xff;
|
|
||||||
} else {
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "FS tell %d\n", fsdev_ptr);
|
fprintf(stderr, "FS tell %d\n", fsdev_ptr);
|
||||||
#endif
|
#endif
|
||||||
fsdev_middle_of_seek_tell = 1;
|
fsdev_seek_tell_cnt = 1;
|
||||||
return fsdev_ptr >> 8;
|
return fsdev_ptr >> 16;
|
||||||
|
} else if (fsdev_seek_tell_cnt == 1) {
|
||||||
|
fsdev_seek_tell_cnt = 2;
|
||||||
|
return (fsdev_ptr >> 8) & 0xff;
|
||||||
|
} else {
|
||||||
|
fsdev_seek_tell_cnt = 0;
|
||||||
|
return fsdev_ptr & 0xff;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Out of bounds I/O read: %d\n", addr);
|
fprintf(stderr, "Out of bounds I/O read: %d\n", addr);
|
||||||
@ -119,15 +122,18 @@ static void io_write(int unused, uint16_t addr, uint8_t val)
|
|||||||
fsdev[fsdev_ptr++] = val;
|
fsdev[fsdev_ptr++] = val;
|
||||||
}
|
}
|
||||||
} else if (addr == FS_SEEK_PORT) {
|
} else if (addr == FS_SEEK_PORT) {
|
||||||
if (fsdev_middle_of_seek_tell) {
|
if (fsdev_seek_tell_cnt == 0) {
|
||||||
|
fsdev_ptr = val << 16;
|
||||||
|
fsdev_seek_tell_cnt = 1;
|
||||||
|
} else if (fsdev_seek_tell_cnt == 1) {
|
||||||
|
fsdev_ptr |= val << 8;
|
||||||
|
fsdev_seek_tell_cnt = 2;
|
||||||
|
} else {
|
||||||
fsdev_ptr |= val;
|
fsdev_ptr |= val;
|
||||||
fsdev_middle_of_seek_tell = 0;
|
fsdev_seek_tell_cnt = 0;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "FS seek %d\n", fsdev_ptr);
|
fprintf(stderr, "FS seek %d\n", fsdev_ptr);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
fsdev_ptr = (val << 8) & 0xff00;
|
|
||||||
fsdev_middle_of_seek_tell = 1;
|
|
||||||
}
|
}
|
||||||
} else if (addr == STDERR_PORT) {
|
} else if (addr == STDERR_PORT) {
|
||||||
fputc(val, stderr);
|
fputc(val, stderr);
|
||||||
|
56
tools/tests/unit/test_core.asm
Normal file
56
tools/tests/unit/test_core.asm
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
jp test
|
||||||
|
|
||||||
|
#include "core.asm"
|
||||||
|
|
||||||
|
testNum: .db 1
|
||||||
|
|
||||||
|
test:
|
||||||
|
ld hl, 0xffff
|
||||||
|
ld sp, hl
|
||||||
|
|
||||||
|
ld hl, 0x123
|
||||||
|
ld a, 0x25
|
||||||
|
call subHL
|
||||||
|
ld a, h
|
||||||
|
cp 0
|
||||||
|
jp nz, fail
|
||||||
|
ld a, l
|
||||||
|
cp 0xfe
|
||||||
|
jp nz, fail
|
||||||
|
call nexttest
|
||||||
|
|
||||||
|
ld hl, 0x125
|
||||||
|
ld a, 0x23
|
||||||
|
call subHL
|
||||||
|
ld a, h
|
||||||
|
cp 1
|
||||||
|
jp nz, fail
|
||||||
|
ld a, l
|
||||||
|
cp 0x02
|
||||||
|
jp nz, fail
|
||||||
|
call nexttest
|
||||||
|
|
||||||
|
ld hl, 0x125
|
||||||
|
ld a, 0x25
|
||||||
|
call subHL
|
||||||
|
ld a, h
|
||||||
|
cp 1
|
||||||
|
jp nz, fail
|
||||||
|
ld a, l
|
||||||
|
cp 0
|
||||||
|
jp nz, fail
|
||||||
|
call nexttest
|
||||||
|
|
||||||
|
; success
|
||||||
|
xor a
|
||||||
|
halt
|
||||||
|
|
||||||
|
nexttest:
|
||||||
|
ld a, (testNum)
|
||||||
|
inc a
|
||||||
|
ld (testNum), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
fail:
|
||||||
|
ld a, (testNum)
|
||||||
|
halt
|
Loading…
Reference in New Issue
Block a user