gunzip: Read decompressed data in blocks.

Rather than through callbacks to a writer. This makes it easier to process.

Mapped32KWriter and MappedBufferLoader now work without Writer.
7 files changed, 133 insertions(+), 179 deletions(-)

M .hgsubstate
M src/Application.asm
M src/COM.asm
M src/Mapped32KWriter.asm
M src/MappedBuffer.asm
M src/MappedBufferLoader.asm
R src/MappedWriter.asm => 
M .hgsubstate +2 -2
@@ 1,2 1,2 @@ 
-7822e6e3f2dc98efe8c571dfd73042172d492e97 lib/gunzip
-d30b04366fbd338ea986834315653980be450151 lib/neonlib
+8b931818a05f9ce3242a560ab962956232ad401f lib/gunzip
+f5d4ac3a27c5e04578db4551e52ed6f50a111448 lib/neonlib

          
M src/Application.asm +33 -20
@@ 264,7 264,7 @@ Application_IsVGZ:
 	ret
 
 ; ix = this
-Application_InflateFile:
+Application_InflateFile: PROC
 	push ix
 	call Application_GetCLI
 	call CLI_GetFileInfoBlock

          
@@ 276,9 276,18 @@ Application_InflateFile:
 	push ix
 	call FileReader_class.New
 	call FileReader_Construct
-	ld e,ixl
-	ld d,ixh
+	push ix
+	push ix
 	push ix
+	ld ix,Heap_main
+	ld bc,Decoders._size
+	call Heap_Allocate
+	ld c,e
+	ld b,d
+	pop ix
+	pop hl
+	push bc
+	ld de,Mapped32KWriter_BASE_ADDRESS
 	ld a,GZIP_CRC32 ? -1 : 0
 	call GzipArchive_class.New
 	call GzipArchive_Construct

          
@@ 290,18 299,14 @@ Application_InflateFile:
 	ld d,ixh
 	ex (sp),ix
 	push ix
-	push de
-	push ix
-	ld ix,Heap_main
-	ld bc,Decoders._size
-	call Heap_Allocate
-	ld c,e
-	ld b,d
+	ld hl,InflateLoop
+	call System_TryCall
 	pop ix
-	pop de
-	push bc
-	ld hl,GzipArchive_Extract
-	call System_TryCall
+	ex (sp),ix
+	call Mapped32KWriter_Destruct
+	call Mapped32KWriter_class.Delete
+	pop ix
+	call GzipArchive_class.Delete
 	pop de
 	push ix
 	ld ix,Heap_main

          
@@ 309,16 314,24 @@ Application_InflateFile:
 	call Heap_Free
 	pop ix
 	pop ix
-	ex (sp),ix
-	call Mapped32KWriter_Destruct
-	call Mapped32KWriter_class.Delete
-	pop ix
-	call GzipArchive_class.Delete
-	pop ix
 	call FileReader_Destruct
 	call FileReader_class.Delete
 	pop ix
 	jp System_Rethrow
+; de = mapped writer
+; ix = gzip archive
+InflateLoop:
+	push de
+	call GzipArchive_Inflate
+	ex (sp),ix
+	push af
+	call Mapped32KWriter_CopyToMappedBuffer
+	pop af
+	ex (sp),ix
+	pop de
+	jr nz,InflateLoop
+	ret
+	ENDP
 
 ; ix = this
 Application_PrintLoading:

          
M src/COM.asm +1 -2
@@ 46,7 46,6 @@ RAM: equ RAM_PAGE1
 	INCLUDE "MappedBuffer.asm"
 	INCLUDE "MappedBufferLoader.asm"
 	INCLUDE "MappedReader.asm"
-	INCLUDE "MappedWriter.asm"
 	INCLUDE "Mapped32KWriter.asm"
 
 	; gunzip

          
@@ 58,7 57,7 @@ RAM: equ RAM_PAGE1
 	INCLUDE "deflate/Branch.asm"
 	INCLUDE "deflate/HuffmanCodes.asm"
 	INCLUDE "Reader.asm"
-	INCLUDE "Writer.asm"
+	INCLUDE "BitReader.asm"
 	INCLUDE "FileReader.asm"
 
 	ENDS

          
M src/Mapped32KWriter.asm +3 -20
@@ 1,12 1,11 @@ 
 ;
-; Writer backed by a mapped buffer
+; Mapped buffer writer for gzip inflate
 ;
 Mapped32KWriter_BASE_ADDRESS: equ 4000H
 Mapped32KWriter_SEGMENT_SIZE: equ 4000H
 Mapped32KWriter_BUFFER_SIZE: equ 8000H
 
 Mapped32KWriter: MACRO
-	super: Writer
 	buffer:
 		dw 0
 	originalPage1: MapperSegment

          
@@ 23,11 22,6 @@ Mapped32KWriter_template: Mapped32KWrite
 Mapped32KWriter_Construct:
 	ld (ix + Mapped32KWriter.buffer),e
 	ld (ix + Mapped32KWriter.buffer + 1),d
-	ld hl,Mapped32KWriter_BASE_ADDRESS
-	ld bc,Mapped32KWriter_BUFFER_SIZE
-	ld de,Mapped32KWriter_Flush
-	call Writer_Construct
-
 	ld h,40H
 	call Mapper_instance.GetPH
 	ld (ix + Mapped32KWriter.originalPage1.segment),a

          
@@ 38,7 32,6 @@ Mapped32KWriter_Construct:
 	ld (ix + Mapped32KWriter.originalPage2.segment),a
 	call Memory_GetSlot
 	ld (ix + Mapped32KWriter.originalPage2.slot),a
-
 	push ix
 	call Mapped32KWriter_GetBuffer
 	call MappedBuffer_AllocateAndAddSegment

          
@@ 73,21 66,11 @@ Mapped32KWriter_GetBuffer:
 	ld ixh,d
 	ret
 
-; bc = byte count
+; hl = byte count
 ; de = buffer start
 ; ix = this
-; Modifies: af, hl
-Mapped32KWriter_Flush:
-	push bc
-	push de
-	call Mapped32KWriter_CopyToMappedBuffer
-	pop de
-	pop bc
-	ret
-
-; ix = this
 Mapped32KWriter_CopyToMappedBuffer: PROC
-	push bc
+	push hl
 	push de
 	push ix
 	call Mapped32KWriter_GetBuffer

          
M src/MappedBuffer.asm +8 -8
@@ 150,20 150,20 @@ MappedBuffer_AddSegment:
 	pop ix
 	ret
 
-; bc = size to add
+; hl = size to add
 ; ix = this
 MappedBuffer_IncreaseSize:
-	ld l,(ix + MappedBuffer.size)
-	ld h,(ix + MappedBuffer.size + 1)
-	ld e,(ix + MappedBuffer.size + 2)
-	ld d,(ix + MappedBuffer.size + 3)
+	push hl
+	ld c,(ix + MappedBuffer.size)
+	ld b,(ix + MappedBuffer.size + 1)
 	add hl,bc
 	ld (ix + MappedBuffer.size),l
 	ld (ix + MappedBuffer.size + 1),h
+	pop hl
 	ret nc
-	inc de
-	ld (ix + MappedBuffer.size + 2),e
-	ld (ix + MappedBuffer.size + 3),d
+	inc (ix + MappedBuffer.size + 2)
+	ret nz
+	inc (ix + MappedBuffer.size + 3)
 	ret
 
 ; dehl = position

          
M src/MappedBufferLoader.asm +86 -55
@@ 1,14 1,15 @@ 
 ;
 ; Buffers an entire file in memory
 ;
-MappedBufferLoader_BASE_ADDRESS: equ 8000H
+MappedBufferLoader_PAGE_START: equ 8000H
 MappedBufferLoader_PAGE_SIZE: equ 4000H
+MappedBufferLoader_PAGE_END: equ MappedBufferLoader_PAGE_START + MappedBufferLoader_PAGE_SIZE
 
 MappedBufferLoader: MACRO
 	fileHandle:
 		db 0
-	writer:
-		MappedWriter
+	buffer:
+		dw 0
 	_size:
 	ENDM
 

          
@@ 16,15 17,9 @@ MappedBufferLoader: MACRO
 ; de = mapped buffer
 ; ix = this
 MappedBufferLoader_Construct:
-	push hl
-	push ix
-	push de
-	call MappedBufferLoader_GetWriter
-	pop de
-	ld hl,MappedBufferLoader_BASE_ADDRESS
-	call MappedWriter_Construct
-	pop ix
-	pop de
+	ld (ix + MappedBufferLoader.buffer),e
+	ld (ix + MappedBufferLoader.buffer + 1),d
+	ex de,hl
 	ld a,00000001B  ; read-only
 	call DOS_OpenFileHandle
 	call DOS_TerminateIfError

          
@@ 35,67 30,103 @@ MappedBufferLoader_Construct:
 MappedBufferLoader_Destruct:
 	ld b,(ix + MappedBufferLoader.fileHandle)
 	call DOS_CloseFileHandle
-	call DOS_TerminateIfError
-	push ix
-	call MappedBufferLoader_GetWriter
-	call Writer_FinishBlock
-	pop ix
-	ret
+	jp DOS_TerminateIfError
 
-; de <- mapped writer
-; ix <- mapped writer
-MappedBufferLoader_GetWriter:
-	ld de,MappedBufferLoader.writer
-	add ix,de
+; ix = this
+; de <- buffer
+; ix <- buffer
+MappedBufferLoader_GetBuffer:
+	ld e,(ix + MappedBufferLoader.buffer)
+	ld d,(ix + MappedBufferLoader.buffer + 1)
+	ld ixl,e
+	ld ixh,d
 	ret
 
 ; ix = this
-MappedBufferLoader_Load:
-	ld h,MappedBufferLoader_BASE_ADDRESS >> 8
+MappedBufferLoader_Load: PROC
+	ld de,MappedBufferLoader_PAGE_END
+Loop:
+	ld a,d
+	cp MappedBufferLoader_PAGE_END >> 8
+	call nc,NextSegment
+	call Load
+	push af
+	push de
+	push ix
+	call MappedBufferLoader_GetBuffer
+	call MappedBuffer_IncreaseSize
+	pop ix
+	pop de
+	pop af
+	cp .EOF
+	ret z
+	call DOS_TerminateIfError
+	jr Loop
+NextSegment:
+	push ix
+	call MappedBufferLoader_GetBuffer
+	call MappedBuffer_AllocateAndAddSegment
+	ld h,MappedBufferLoader_PAGE_START >> 8
+	call MappedBuffer_SelectSegment
+	pop ix
+	ld de,MappedBufferLoader_PAGE_START
+	ret
+Load:
+	push de
+	ld h,d
 	call Memory_GetSlot
+	pop de
+	ld hl,MappedBufferLoader_PAGE_END
+	and a
+	sbc hl,de
 	ld b,a
 	ld a,(Mapper_instance.primaryMapperSlot)
 	cp b
-	jr nz,MappedBufferLoader_LoadViaBuffer
-	push ix
-	call MappedBufferLoader_GetWriter
-	call Writer_WriteBlockDirect
-	pop ix
-	ld l,c
-	ld h,b
+	jr z,MappedBufferLoader_LoadDirect
+	jr MappedBufferLoader_LoadIndirect
+	ENDP
+
+; de = destination
+; hl = byte count
+; ix = this
+; a <- error
+; de <- updated destination
+; hl <- actual byte count
+MappedBufferLoader_LoadDirect:
+	push de
 	ld b,(ix + MappedBufferLoader.fileHandle)
 	call DOS_ReadFromFileHandle
-	cp .EOF
-	ret z
-	call DOS_TerminateIfError
-	push af
-	push ix
-	call MappedBufferLoader_GetWriter
-	ld c,l
-	ld b,h
-	call Writer_Advance
-	pop ix
-	pop af
-	jr MappedBufferLoader_Load
+	pop de
+	add hl,de
+	ex de,hl
+	ret
 
 ; Load data to BASE_ADDRESS via a buffer in the primary mapper.
 ; Because DOS2 can not load directly into nonprimary mapper slots.
+; de = destination
+; hl = byte count
 ; ix = this
-MappedBufferLoader_LoadViaBuffer:
+; a <- error
+; de <- updated destination
+; hl <- actual byte count
+MappedBufferLoader_LoadIndirect: PROC
+	push de
+	ld de,READBUFFER_SIZE
+	and a
+	sbc hl,de
+	add hl,de
+	jr c,NoClamp
+	ex de,hl
+NoClamp:
 	ld de,READBUFFER
-	ld hl,READBUFFER_SIZE
 	ld b,(ix + MappedBufferLoader.fileHandle)
 	call DOS_ReadFromFileHandle
-	cp .EOF
-	ret z
-	call DOS_TerminateIfError
+	pop de
 	push af
-	push ix
-	call MappedBufferLoader_GetWriter
-	ld de,READBUFFER
 	ld c,l
 	ld b,h
-	call Writer_WriteBlock
-	pop ix
+	ld hl,READBUFFER
+	call System_FastLDIR
 	pop af
-	jr MappedBufferLoader_Load
+	ret
+	ENDP

          
R src/MappedWriter.asm =>  +0 -72
@@ 1,72 0,0 @@ 
-;
-; Writer backed by a mapped buffer
-;
-MappedWriter_SEGMENT_SIZE: equ 4000H
-
-MappedWriter: MACRO
-	super: Writer
-	buffer:
-		dw 0
-	_size:
-	ENDM
-
-; de = mapped buffer
-; hl = base address
-; ix = this
-MappedWriter_Construct:
-	ld a,l
-	and a
-	call nz,System_ThrowException
-	ld a,h
-	and 3FH
-	call nz,System_ThrowException
-	ld (ix + MappedWriter.buffer),e
-	ld (ix + MappedWriter.buffer + 1),d
-	ld bc,MappedWriter_SEGMENT_SIZE
-	ld de,MappedWriter_Flush
-	call Writer_Construct
-	jr MappedWriter_AllocateNextSegment
-
-; ix = this
-; de <- buffer
-; ix <- buffer
-MappedWriter_GetBuffer:
-	ld e,(ix + MappedWriter.buffer)
-	ld d,(ix + MappedWriter.buffer + 1)
-	ld ixl,e
-	ld ixh,d
-	ret
-
-; bc = byte count
-; de = buffer start
-; ix = this
-MappedWriter_Flush:
-	push bc
-	push de
-	push ix
-	call MappedWriter_GetBuffer
-	call MappedBuffer_IncreaseSize
-	pop ix
-	pop de
-	pop bc
-	ld l,0
-	ld h,(ix + MappedWriter.super.bufferEnd)
-	and a
-	sbc hl,de
-	call c,System_ThrowException
-	sbc hl,bc
-	call c,System_ThrowException
-	ret nz
-	jr MappedWriter_AllocateNextSegment
-
-; ix = this
-MappedWriter_AllocateNextSegment:
-	ld h,(ix + MappedWriter.super.bufferStart)
-	push ix
-	push hl
-	call MappedWriter_GetBuffer
-	call MappedBuffer_AllocateAndAddSegment
-	pop hl
-	call MappedBuffer_SelectSegment
-	pop ix
-	ret